diff mbox series

qga: implement a 'guest-get-load' command

Message ID 20241202121927.864335-1-berrange@redhat.com (mailing list archive)
State New, archived
Headers show
Series qga: implement a 'guest-get-load' command | expand

Commit Message

Daniel P. Berrangé Dec. 2, 2024, 12:19 p.m. UTC
Provide a way to report the process load average, via a new
'guest-get-load' command.

This is only implemented for POSIX platforms providing 'getloadavg'.

Example illustrated with qmp-shell:

(QEMU) guest-get-load
{
    "return": {
        "load15m": 1.546875,
        "load1m": 1.669921875,
        "load5m": 1.9306640625
    }
}

Windows has no native equivalent API, but it would be possible to
simulate it as illustrated here (BSD-3-Clause):

  https://github.com/giampaolo/psutil/pull/1485

This is left as an exercise for future contributors.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 meson.build          |  1 +
 qga/commands-posix.c | 20 ++++++++++++++++++++
 qga/qapi-schema.json | 37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+)

Comments

Konstantin Kostiuk Dec. 4, 2024, 9:29 a.m. UTC | #1
Reviewed-by: Konstantin Kostiuk <kkostiuk@redhat.com>

On Mon, Dec 2, 2024 at 2:19 PM Daniel P. Berrangé <berrange@redhat.com>
wrote:

> Provide a way to report the process load average, via a new
> 'guest-get-load' command.
>
> This is only implemented for POSIX platforms providing 'getloadavg'.
>
> Example illustrated with qmp-shell:
>
> (QEMU) guest-get-load
> {
>     "return": {
>         "load15m": 1.546875,
>         "load1m": 1.669921875,
>         "load5m": 1.9306640625
>     }
> }
>
> Windows has no native equivalent API, but it would be possible to
> simulate it as illustrated here (BSD-3-Clause):
>
>   https://github.com/giampaolo/psutil/pull/1485
>
> This is left as an exercise for future contributors.
>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>  meson.build          |  1 +
>  qga/commands-posix.c | 20 ++++++++++++++++++++
>  qga/qapi-schema.json | 37 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 58 insertions(+)
>
> diff --git a/meson.build b/meson.build
> index a290dbfa33..9c65e56fff 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -2619,6 +2619,7 @@ config_host_data.set('CONFIG_SETNS',
> cc.has_function('setns') and cc.has_functio
>  config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
>  config_host_data.set('CONFIG_SYNC_FILE_RANGE',
> cc.has_function('sync_file_range'))
>  config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
> +config_host_data.set('CONFIG_GETLOADAVG', cc.has_function('getloadavg'))
>  config_host_data.set('HAVE_COPY_FILE_RANGE',
> cc.has_function('copy_file_range'))
>  config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
>  config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index 636307bedf..6e3c15f539 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -1368,3 +1368,23 @@ char *qga_get_host_name(Error **errp)
>
>      return g_steal_pointer(&hostname);
>  }
> +
> +#ifdef CONFIG_GETLOADAVG
> +GuestLoadAverage *qmp_guest_get_load(Error **errp)
> +{
> +    double loadavg[3];
> +    GuestLoadAverage *ret = NULL;
> +
> +    if (getloadavg(loadavg, G_N_ELEMENTS(loadavg)) < 0) {
> +        error_setg_errno(errp, errno,
> +                         "cannot query load average");
> +        return NULL;
> +    }
> +
> +    ret = g_new0(GuestLoadAverage, 1);
> +    ret->load1m = loadavg[0];
> +    ret->load5m = loadavg[1];
> +    ret->load15m = loadavg[2];
> +    return ret;
> +}
> +#endif
> diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
> index 0537bb7886..995594aaf4 100644
> --- a/qga/qapi-schema.json
> +++ b/qga/qapi-schema.json
> @@ -1843,6 +1843,43 @@
>    'if': 'CONFIG_LINUX'
>  }
>
> +
> +##
> +# @GuestLoadAverage:
> +#
> +# Statistics about process load information
> +#
> +# @load1m: 1-minute load avage
> +#
> +# @load5m: 5-minute load avage
> +#
> +# @load15m: 15-minute load avage
> +#
> +# Since: 10.0
> +##
> +{ 'struct': 'GuestLoadAverage',
> +  'data': {
> +      'load1m': 'number',
> +      'load5m': 'number',
> +      'load15m': 'number'
> +  },
> +  'if': 'CONFIG_GETLOADAVG'
> +}
> +
> +##
> +# @guest-get-load:
> +#
> +# Retrieve CPU process load information
> +#
> +# Returns: load information
> +#
> +# Since: 10.0
> +##
> +{ 'command': 'guest-get-load',
> +  'returns': 'GuestLoadAverage',
> +  'if': 'CONFIG_GETLOADAVG'
> +}
> +
>  ##
>  # @GuestNetworkRoute:
>  #
> --
> 2.46.0
>
>
diff mbox series

Patch

diff --git a/meson.build b/meson.build
index a290dbfa33..9c65e56fff 100644
--- a/meson.build
+++ b/meson.build
@@ -2619,6 +2619,7 @@  config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_functio
 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
+config_host_data.set('CONFIG_GETLOADAVG', cc.has_function('getloadavg'))
 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 636307bedf..6e3c15f539 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1368,3 +1368,23 @@  char *qga_get_host_name(Error **errp)
 
     return g_steal_pointer(&hostname);
 }
+
+#ifdef CONFIG_GETLOADAVG
+GuestLoadAverage *qmp_guest_get_load(Error **errp)
+{
+    double loadavg[3];
+    GuestLoadAverage *ret = NULL;
+
+    if (getloadavg(loadavg, G_N_ELEMENTS(loadavg)) < 0) {
+        error_setg_errno(errp, errno,
+                         "cannot query load average");
+        return NULL;
+    }
+
+    ret = g_new0(GuestLoadAverage, 1);
+    ret->load1m = loadavg[0];
+    ret->load5m = loadavg[1];
+    ret->load15m = loadavg[2];
+    return ret;
+}
+#endif
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 0537bb7886..995594aaf4 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -1843,6 +1843,43 @@ 
   'if': 'CONFIG_LINUX'
 }
 
+
+##
+# @GuestLoadAverage:
+#
+# Statistics about process load information
+#
+# @load1m: 1-minute load avage
+#
+# @load5m: 5-minute load avage
+#
+# @load15m: 15-minute load avage
+#
+# Since: 10.0
+##
+{ 'struct': 'GuestLoadAverage',
+  'data': {
+      'load1m': 'number',
+      'load5m': 'number',
+      'load15m': 'number'
+  },
+  'if': 'CONFIG_GETLOADAVG'
+}
+
+##
+# @guest-get-load:
+#
+# Retrieve CPU process load information
+#
+# Returns: load information
+#
+# Since: 10.0
+##
+{ 'command': 'guest-get-load',
+  'returns': 'GuestLoadAverage',
+  'if': 'CONFIG_GETLOADAVG'
+}
+
 ##
 # @GuestNetworkRoute:
 #