Re: [PATCH v2 2/3] util: Add virGetCpuHaltPollTime and virGetDebugFsKvmValue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 7/14/21 2:28 PM, Yang Fei wrote:
> Add helper function virGetCpuHaltPollTime and virGetDebugFsKvmValue
> to obtain the halt polling time. If system mount debugfs, and the
> kernel support halt polling time statistic, it will work.
> 
> Signed-off-by: Yang Fei <yangfei85@xxxxxxxxxx>
> ---
>  src/libvirt_private.syms |  2 ++
>  src/util/virutil.c       | 78 ++++++++++++++++++++++++++++++++++++++++
>  src/util/virutil.h       |  9 +++++
>  3 files changed, 89 insertions(+)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 68e4b6aab8..f92213b8c2 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -3479,6 +3479,8 @@ virDoesUserExist;
>  virDoubleToStr;
>  virFormatIntDecimal;
>  virFormatIntPretty;
> +virGetCpuHaltPollTime;
> +virGetDebugFsKvmValue;
>  virGetDeviceID;
>  virGetDeviceUnprivSGIO;
>  virGetGroupID;
> diff --git a/src/util/virutil.c b/src/util/virutil.c
> index c0d25fe247..7e4531b4b4 100644
> --- a/src/util/virutil.c
> +++ b/src/util/virutil.c
> @@ -1959,3 +1959,81 @@ virGetValueRaw(const char *path,
>  
>      return 0;
>  }
> +
> +int
> +virGetDebugFsKvmValue(struct dirent *ent,
> +                    const char *path,
> +                    const char *filename,
> +                    unsigned long long *value)
> +{
> +    g_autofree char *valToStr = NULL;
> +    g_autofree char *valPath = NULL;
> +
> +    valPath = g_strdup_printf("%s/%s/%s", path, ent->d_name, filename);
> +
> +    if (virGetValueRaw(valPath, &valToStr) < 0) {
> +        return -1;
> +    }
> +
> +    /* 10 is a Cardinality, must be between 2 and 36 inclusive,
> +     * or special value 0. Used in fuction strtoull()
> +     */
> +    if (virStrToLong_ull(valToStr, NULL, 10, value) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Unable to parse '%s' as an integer"), valToStr);
> +        return -1;
> +    }
> +
> +    return 0;
> +}

This looks very close to what virFileReadValueUllong() does.

> +
> +int
> +virGetCpuHaltPollTime(pid_t pid,
> +                      unsigned long long *haltPollSuccess,
> +                      unsigned long long *haltPollFail)
> +{
> +    g_autofree char *pidToStr = NULL;
> +    g_autofree char *debugFsPath = NULL;
> +    g_autofree char *completePath = NULL;
> +    struct dirent *ent = NULL;
> +    DIR *dir = NULL;
> +    int ret = -1;
> +    int flag = 0;
> +
> +    if (!(debugFsPath = virFileFindMountPoint("debugfs"))) {
> +        virReportSystemError(errno, "%s",
> +                             _("unable to find debugfs mountpoint"));
> +        return ret;
> +    }

Is this something worth polluting logs with error? What if we run under
kernel that doesn't have debugfs?

> +
> +    completePath = g_strdup_printf("%s/%s", debugFsPath, "kvm");
> +    if (virDirOpen(&dir, completePath) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       "%s %s", "Can not open directory", completePath);
> +        return ret;
> +    }

virDirOpen() reports an error on failure. No need to rewrite it. And in
the light of previous comment maybe virDirOpenIfExists() instead?

> +
> +    pidToStr = g_strdup_printf("%lld%c", (unsigned long long)pid, '-');
> +    while (virDirRead(dir, &ent, NULL) > 0) {
> +        if (STRPREFIX(ent->d_name, pidToStr)) {
> +            flag = 1;
> +            break;
> +        }
> +    }
> +
> +    if (flag == 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Could not find VM(Pid %s) in '%s'"), pidToStr, completePath);
> +        goto cleanup;
> +    }

Again, not big fan. What it my domain runs TCG? Also, please rename
'flag' to something more specific, e.g. "found".

> +
> +    if (virGetDebugFsKvmValue(ent, completePath, "halt_poll_success_ns", haltPollSuccess) < 0 ||
> +        virGetDebugFsKvmValue(ent, completePath, "halt_poll_fail_ns", haltPollFail) < 0) {
> +        goto cleanup;
> +    }
> +
> +    ret = 0;
> +cleanup:
> +    closedir(dir);

Again, please make sure 'ninja test' passes. We have a syntax-check rule
that forbids direct call of closedir(). The proper way is to define dir
variable like this:

g_autoptr(DIR) dir = NULL;

> +    return ret;
> +}
> diff --git a/src/util/virutil.h b/src/util/virutil.h
> index 851b421476..00cef47208 100644
> --- a/src/util/virutil.h
> +++ b/src/util/virutil.h
> @@ -228,3 +228,12 @@ int virPipeNonBlock(int fds[2]);
>  
>  int virGetValueRaw(const char *path,
>                           char **value);
> +
> +int virGetDebugFsKvmValue(struct dirent *ent,
> +                    const char *path,
> +                    const char *filename,
> +                    unsigned long long *value);
> +
> +int virGetCpuHaltPollTime(pid_t pid,
> +                      unsigned long long *haltPollSuccess,
> +                      unsigned long long *haltPollFail);
> 

Michal




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux