qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] qga: Add 'guest-get-load' command
@ 2025-03-14 11:38 Konstantin Kostiuk
  2025-03-14 11:38 ` [PATCH 1/2] qga-win: implement a " Konstantin Kostiuk
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Konstantin Kostiuk @ 2025-03-14 11:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Daniel P . Berrangé, Michael Roth

Konstantin Kostiuk (2):
  qga-win: implement a 'guest-get-load' command
  qga: Add tests for guest-get-load command

 qga/commands-win32.c   | 140 +++++++++++++++++++++++++++++++++++++++++
 qga/guest-agent-core.h |  10 +++
 qga/main.c             |  39 ++++++++++++
 qga/meson.build        |   2 +-
 qga/qapi-schema.json   |   4 +-
 tests/unit/test-qga.c  |  17 +++++
 6 files changed, 209 insertions(+), 3 deletions(-)

--
2.48.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] qga-win: implement a 'guest-get-load' command
  2025-03-14 11:38 [PATCH 0/2] qga: Add 'guest-get-load' command Konstantin Kostiuk
@ 2025-03-14 11:38 ` Konstantin Kostiuk
  2025-03-19 15:02   ` Daniel P. Berrangé
  2025-03-14 11:38 ` [PATCH 2/2] qga: Add tests for guest-get-load command Konstantin Kostiuk
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Konstantin Kostiuk @ 2025-03-14 11:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Daniel P . Berrangé, Michael Roth

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

Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
---
 qga/commands-win32.c   | 140 +++++++++++++++++++++++++++++++++++++++++
 qga/guest-agent-core.h |  10 +++
 qga/main.c             |  39 ++++++++++++
 qga/meson.build        |   2 +-
 qga/qapi-schema.json   |   4 +-
 5 files changed, 192 insertions(+), 3 deletions(-)

diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 749fdf8895..9ded44c2f7 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -27,6 +27,7 @@
 #include <lm.h>
 #include <wtsapi32.h>
 #include <wininet.h>
+#include <pdh.h>
 
 #include "guest-agent-core.h"
 #include "vss-win32.h"
@@ -119,6 +120,28 @@ static OpenFlags guest_file_open_modes[] = {
     {"a+b", FILE_GENERIC_APPEND | GENERIC_READ, OPEN_ALWAYS  }
 };
 
+/*
+ * We use an exponentially weighted moving average, just like Unix systems do
+ * https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation
+ *
+ * These constants serve as the damping factor and are calculated with
+ * 1 / exp(sampling interval in seconds / window size in seconds)
+ *
+ * This formula comes from linux's include/linux/sched/loadavg.h
+ * https://github.com/torvalds/linux/blob/345671ea0f9258f410eb057b9ced9cefbbe5dc78/include/linux/sched/loadavg.h#L20-L23
+ */
+#define LOADAVG_FACTOR_1F  0.9200444146293232478931553241
+#define LOADAVG_FACTOR_5F  0.9834714538216174894737477501
+#define LOADAVG_FACTOR_15F 0.9944598480048967508795473394
+/*
+ * The time interval in seconds between taking load counts, same as Linux
+ */
+#define LOADAVG_SAMPLING_INTERVAL 5
+
+double load_avg_1m;
+double load_avg_5m;
+double load_avg_15m;
+
 #define debug_error(msg) do { \
     char *suffix = g_win32_error_message(GetLastError()); \
     g_debug("%s: %s", (msg), suffix); \
@@ -2448,3 +2471,120 @@ char *qga_get_host_name(Error **errp)
 
     return g_utf16_to_utf8(tmp, size, NULL, NULL, NULL);
 }
+
+
+static VOID CALLBACK load_avg_callback(PVOID hCounter, BOOLEAN timedOut)
+{
+    PDH_FMT_COUNTERVALUE displayValue;
+    double currentLoad;
+    PDH_STATUS err;
+
+    err = PdhGetFormattedCounterValue(
+        (PDH_HCOUNTER)hCounter, PDH_FMT_DOUBLE, 0, &displayValue);
+    /* Skip updating the load if we can't get the value successfully */
+    if (err != ERROR_SUCCESS) {
+        slog("PdhGetFormattedCounterValue failed to get load value with 0x%lx",
+             err);
+        return;
+    }
+    currentLoad = displayValue.doubleValue;
+
+    load_avg_1m = load_avg_1m * LOADAVG_FACTOR_1F + currentLoad * \
+        (1.0 - LOADAVG_FACTOR_1F);
+    load_avg_5m = load_avg_5m * LOADAVG_FACTOR_5F + currentLoad * \
+        (1.0 - LOADAVG_FACTOR_5F);
+    load_avg_15m = load_avg_15m * LOADAVG_FACTOR_15F + currentLoad * \
+        (1.0 - LOADAVG_FACTOR_15F);
+}
+
+static BOOL init_load_avg_counter(Error **errp)
+{
+    CONST WCHAR *szCounterPath = L"\\System\\Processor Queue Length";
+    PDH_STATUS status;
+    BOOL ret;
+    HQUERY hQuery;
+    HCOUNTER hCounter;
+    HANDLE event;
+    HANDLE waitHandle;
+
+    status = PdhOpenQueryW(NULL, 0, &hQuery);
+    if (status != ERROR_SUCCESS) {
+        /*
+         * If the function fails, the return value is a system error code or
+         * a PDH error code. error_setg_win32 cant translate PDH error code
+         * properly, so just report it as is.
+         */
+        error_setg_win32(errp, (DWORD)status,
+                         "PdhOpenQueryW failed with 0x%lx", status);
+        return FALSE;
+    }
+
+    status = PdhAddEnglishCounterW(hQuery, szCounterPath, 0, &hCounter);
+    if (status != ERROR_SUCCESS) {
+        error_setg_win32(errp, (DWORD)status,
+            "PdhAddEnglishCounterW failed with 0x%lx. Performance counters may be disabled.",
+            status);
+        PdhCloseQuery(hQuery);
+        return FALSE;
+    }
+
+    event = CreateEventW(NULL, FALSE, FALSE, L"LoadUpdateEvent");
+    if (event == NULL) {
+        error_setg_win32(errp, GetLastError(), "Create LoadUpdateEvent failed");
+        PdhCloseQuery(hQuery);
+        return FALSE;
+    }
+
+    status = PdhCollectQueryDataEx(hQuery, LOADAVG_SAMPLING_INTERVAL, event);
+    if (status != ERROR_SUCCESS) {
+        error_setg_win32(errp, (DWORD)status,
+                         "PdhCollectQueryDataEx failed with 0x%lx", status);
+        CloseHandle(event);
+        PdhCloseQuery(hQuery);
+        return FALSE;
+    }
+
+    ret = RegisterWaitForSingleObject(
+        &waitHandle,
+        event,
+        (WAITORTIMERCALLBACK)load_avg_callback,
+        (PVOID)hCounter,
+        INFINITE,
+        WT_EXECUTEDEFAULT);
+
+    if (ret == 0) {
+        error_setg_win32(errp, GetLastError(),
+                         "RegisterWaitForSingleObject failed");
+        CloseHandle(event);
+        PdhCloseQuery(hQuery);
+        return FALSE;
+    }
+
+    ga_set_load_avg_wait_handle(ga_state, waitHandle);
+    ga_set_load_avg_event(ga_state, event);
+    ga_set_load_avg_pdh_query(ga_state, hQuery);
+
+    return TRUE;
+}
+
+GuestLoadAverage *qmp_guest_get_load(Error **errp)
+{
+    if (ga_get_load_avg_pdh_query(ga_state) == NULL) {
+        /* set initial values */
+        load_avg_1m = 0;
+        load_avg_5m = 0;
+        load_avg_15m = 0;
+
+        if (init_load_avg_counter(errp) == false) {
+            return NULL;
+        }
+    }
+
+    GuestLoadAverage *ret = NULL;
+
+    ret = g_new0(GuestLoadAverage, 1);
+    ret->load1m = load_avg_1m;
+    ret->load5m = load_avg_5m;
+    ret->load15m = load_avg_15m;
+    return ret;
+}
diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
index a536d07d0d..d9f3922adf 100644
--- a/qga/guest-agent-core.h
+++ b/qga/guest-agent-core.h
@@ -13,6 +13,10 @@
 #ifndef GUEST_AGENT_CORE_H
 #define GUEST_AGENT_CORE_H
 
+#ifdef _WIN32
+#include <pdh.h>
+#endif
+
 #include "qapi/qmp-registry.h"
 #include "qga-qapi-types.h"
 
@@ -41,6 +45,12 @@ void ga_set_response_delimited(GAState *s);
 bool ga_is_frozen(GAState *s);
 void ga_set_frozen(GAState *s);
 void ga_unset_frozen(GAState *s);
+#ifdef _WIN32
+void ga_set_load_avg_event(GAState *s, HANDLE event);
+void ga_set_load_avg_wait_handle(GAState *s, HANDLE wait_handle);
+void ga_set_load_avg_pdh_query(GAState *s, HQUERY query);
+HQUERY ga_get_load_avg_pdh_query(GAState *s);
+#endif
 const char *ga_fsfreeze_hook(GAState *s);
 int64_t ga_get_fd_handle(GAState *s, Error **errp);
 int ga_parse_whence(GuestFileWhence *whence, Error **errp);
diff --git a/qga/main.c b/qga/main.c
index 72c39b042f..6c02f3ec38 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -33,6 +33,7 @@
 #include "qemu-version.h"
 #ifdef _WIN32
 #include <dbt.h>
+#include <pdh.h>
 #include "qga/service-win32.h"
 #include "qga/vss-win32.h"
 #endif
@@ -105,6 +106,9 @@ struct GAState {
     GAService service;
     HANDLE wakeup_event;
     HANDLE event_log;
+    HANDLE load_avg_wait_handle;
+    HANDLE load_avg_event;
+    HQUERY load_avg_pdh_query;
 #endif
     bool delimit_response;
     bool frozen;
@@ -582,6 +586,25 @@ const char *ga_fsfreeze_hook(GAState *s)
 }
 #endif
 
+#ifdef _WIN32
+void ga_set_load_avg_wait_handle(GAState *s, HANDLE wait_handle)
+{
+    s->load_avg_wait_handle = wait_handle;
+}
+void ga_set_load_avg_event(GAState *s, HANDLE event)
+{
+    s->load_avg_event = event;
+}
+void ga_set_load_avg_pdh_query(GAState *s, HQUERY query)
+{
+    s->load_avg_pdh_query = query;
+}
+HQUERY ga_get_load_avg_pdh_query(GAState *s)
+{
+    return s->load_avg_pdh_query;
+}
+#endif
+
 static void become_daemon(const char *pidfile)
 {
 #ifndef _WIN32
@@ -1402,6 +1425,10 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation)
     g_debug("Guest agent version %s started", QEMU_FULL_VERSION);
 
 #ifdef _WIN32
+    s->load_avg_wait_handle = INVALID_HANDLE_VALUE;
+    s->load_avg_event = INVALID_HANDLE_VALUE;
+    s->load_avg_pdh_query = NULL;
+
     s->event_log = RegisterEventSource(NULL, "qemu-ga");
     if (!s->event_log) {
         g_autofree gchar *errmsg = g_win32_error_message(GetLastError());
@@ -1506,6 +1533,18 @@ static void cleanup_agent(GAState *s)
 #ifdef _WIN32
     CloseHandle(s->wakeup_event);
     CloseHandle(s->event_log);
+
+    if (s->load_avg_wait_handle != INVALID_HANDLE_VALUE) {
+        UnregisterWait(s->load_avg_wait_handle);
+    }
+
+    if (s->load_avg_event != INVALID_HANDLE_VALUE) {
+        CloseHandle(s->load_avg_event);
+    }
+
+    if (s->load_avg_pdh_query) {
+        PdhCloseQuery(s->load_avg_pdh_query);
+    }
 #endif
     if (s->command_state) {
         ga_command_state_cleanup_all(s->command_state);
diff --git a/qga/meson.build b/qga/meson.build
index 587ec4e5e8..89a4a8f713 100644
--- a/qga/meson.build
+++ b/qga/meson.build
@@ -95,7 +95,7 @@ gen_tlb = []
 qga_libs = []
 if host_os == 'windows'
   qga_libs += ['-lws2_32', '-lwinmm', '-lpowrprof', '-lwtsapi32', '-lwininet', '-liphlpapi', '-lnetapi32',
-               '-lsetupapi', '-lcfgmgr32', '-luserenv']
+               '-lsetupapi', '-lcfgmgr32', '-luserenv', '-lpdh' ]
   if have_qga_vss
     qga_libs += ['-lole32', '-loleaut32', '-lshlwapi', '-lstdc++', '-Wl,--enable-stdcall-fixup']
     subdir('vss-win32')
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 995594aaf4..cdab3872ea 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -1863,7 +1863,7 @@
       'load5m': 'number',
       'load15m': 'number'
   },
-  'if': 'CONFIG_GETLOADAVG'
+  'if': { 'any': ['CONFIG_WIN32', 'CONFIG_GETLOADAVG'] }
 }
 
 ##
@@ -1877,7 +1877,7 @@
 ##
 { 'command': 'guest-get-load',
   'returns': 'GuestLoadAverage',
-  'if': 'CONFIG_GETLOADAVG'
+  'if': { 'any': ['CONFIG_WIN32', 'CONFIG_GETLOADAVG'] }
 }
 
 ##
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] qga: Add tests for guest-get-load command
  2025-03-14 11:38 [PATCH 0/2] qga: Add 'guest-get-load' command Konstantin Kostiuk
  2025-03-14 11:38 ` [PATCH 1/2] qga-win: implement a " Konstantin Kostiuk
@ 2025-03-14 11:38 ` Konstantin Kostiuk
  2025-03-18 13:47 ` [PATCH 0/2] qga: Add 'guest-get-load' command Dehan Meng
  2025-03-19 14:57 ` Yan Vugenfirer
  3 siblings, 0 replies; 7+ messages in thread
From: Konstantin Kostiuk @ 2025-03-14 11:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Daniel P . Berrangé, Michael Roth

Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
---
 tests/unit/test-qga.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c
index 541b08a5e7..587e30c7e4 100644
--- a/tests/unit/test-qga.c
+++ b/tests/unit/test-qga.c
@@ -332,6 +332,22 @@ static void test_qga_get_fsinfo(gconstpointer fix)
     }
 }
 
+static void test_qga_get_load(gconstpointer fix)
+{
+    const TestFixture *fixture = fix;
+    g_autoptr(QDict) ret = NULL;
+    QDict *load;
+
+    ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-load'}");
+    g_assert_nonnull(ret);
+    qmp_assert_no_error(ret);
+
+    load = qdict_get_qdict(ret, "return");
+    g_assert(qdict_haskey(load, "load1m"));
+    g_assert(qdict_haskey(load, "load5m"));
+    g_assert(qdict_haskey(load, "load15m"));
+}
+
 static void test_qga_get_memory_block_info(gconstpointer fix)
 {
     const TestFixture *fixture = fix;
@@ -1105,6 +1121,7 @@ int main(int argc, char **argv)
         g_test_add_data_func("/qga/get-vcpus", &fix, test_qga_get_vcpus);
     }
     g_test_add_data_func("/qga/get-fsinfo", &fix, test_qga_get_fsinfo);
+    g_test_add_data_func("/qga/get-load", &fix, test_qga_get_load);
     g_test_add_data_func("/qga/get-memory-block-info", &fix,
                          test_qga_get_memory_block_info);
     g_test_add_data_func("/qga/get-memory-blocks", &fix,
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] qga: Add 'guest-get-load' command
  2025-03-14 11:38 [PATCH 0/2] qga: Add 'guest-get-load' command Konstantin Kostiuk
  2025-03-14 11:38 ` [PATCH 1/2] qga-win: implement a " Konstantin Kostiuk
  2025-03-14 11:38 ` [PATCH 2/2] qga: Add tests for guest-get-load command Konstantin Kostiuk
@ 2025-03-18 13:47 ` Dehan Meng
  2025-03-19 14:57 ` Yan Vugenfirer
  3 siblings, 0 replies; 7+ messages in thread
From: Dehan Meng @ 2025-03-18 13:47 UTC (permalink / raw)
  To: Konstantin Kostiuk
  Cc: qemu-devel, Marc-André Lureau, Daniel P . Berrangé,
	Michael Roth

[-- Attachment #1: Type: text/plain, Size: 707 bytes --]

QE tested this series's patches. cpu load will be captured by the new api
'guest-get-load'.

Tested-by: Dehan Meng <demeng@redhat.com>

On Fri, Mar 14, 2025 at 7:39 PM Konstantin Kostiuk <kkostiuk@redhat.com>
wrote:

> Konstantin Kostiuk (2):
>   qga-win: implement a 'guest-get-load' command
>   qga: Add tests for guest-get-load command
>
>  qga/commands-win32.c   | 140 +++++++++++++++++++++++++++++++++++++++++
>  qga/guest-agent-core.h |  10 +++
>  qga/main.c             |  39 ++++++++++++
>  qga/meson.build        |   2 +-
>  qga/qapi-schema.json   |   4 +-
>  tests/unit/test-qga.c  |  17 +++++
>  6 files changed, 209 insertions(+), 3 deletions(-)
>
> --
> 2.48.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 1273 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] qga: Add 'guest-get-load' command
  2025-03-14 11:38 [PATCH 0/2] qga: Add 'guest-get-load' command Konstantin Kostiuk
                   ` (2 preceding siblings ...)
  2025-03-18 13:47 ` [PATCH 0/2] qga: Add 'guest-get-load' command Dehan Meng
@ 2025-03-19 14:57 ` Yan Vugenfirer
  3 siblings, 0 replies; 7+ messages in thread
From: Yan Vugenfirer @ 2025-03-19 14:57 UTC (permalink / raw)
  To: Konstantin Kostiuk
  Cc: qemu-devel, Marc-André Lureau, Daniel P . Berrangé,
	Michael Roth

Reviewed-by: Yan Vugenfirer <yvugenfi@redhat.com>


On Fri, Mar 14, 2025 at 1:40 PM Konstantin Kostiuk <kkostiuk@redhat.com> wrote:
>
> Konstantin Kostiuk (2):
>   qga-win: implement a 'guest-get-load' command
>   qga: Add tests for guest-get-load command
>
>  qga/commands-win32.c   | 140 +++++++++++++++++++++++++++++++++++++++++
>  qga/guest-agent-core.h |  10 +++
>  qga/main.c             |  39 ++++++++++++
>  qga/meson.build        |   2 +-
>  qga/qapi-schema.json   |   4 +-
>  tests/unit/test-qga.c  |  17 +++++
>  6 files changed, 209 insertions(+), 3 deletions(-)
>
> --
> 2.48.1
>
>



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] qga-win: implement a 'guest-get-load' command
  2025-03-14 11:38 ` [PATCH 1/2] qga-win: implement a " Konstantin Kostiuk
@ 2025-03-19 15:02   ` Daniel P. Berrangé
  2025-03-19 16:52     ` Konstantin Kostiuk
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel P. Berrangé @ 2025-03-19 15:02 UTC (permalink / raw)
  To: Konstantin Kostiuk; +Cc: qemu-devel, Marc-André Lureau, Michael Roth

On Fri, Mar 14, 2025 at 01:38:46PM +0200, Konstantin Kostiuk wrote:
> 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
> 
> Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
> ---
>  qga/commands-win32.c   | 140 +++++++++++++++++++++++++++++++++++++++++
>  qga/guest-agent-core.h |  10 +++
>  qga/main.c             |  39 ++++++++++++
>  qga/meson.build        |   2 +-
>  qga/qapi-schema.json   |   4 +-
>  5 files changed, 192 insertions(+), 3 deletions(-)

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


> +GuestLoadAverage *qmp_guest_get_load(Error **errp)
> +{
> +    if (ga_get_load_avg_pdh_query(ga_state) == NULL) {
> +        /* set initial values */
> +        load_avg_1m = 0;
> +        load_avg_5m = 0;
> +        load_avg_15m = 0;
> +
> +        if (init_load_avg_counter(errp) == false) {
> +            return NULL;
> +        }
> +    }

Nice idea. So we avoid running the load average logic
until such time as a mgmt app actually asks for it.

The load avg won't be very accurate initially, but
assuming any interested mgmt app will ask for this
repeatedly over the entire life of the VM, this looks
like a good mitigation.

Perhaps worth a commenting explaining why we're doing
this.


> +
> +    GuestLoadAverage *ret = NULL;
> +
> +    ret = g_new0(GuestLoadAverage, 1);
> +    ret->load1m = load_avg_1m;
> +    ret->load5m = load_avg_5m;
> +    ret->load15m = load_avg_15m;
> +    return ret;
> +}

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] qga-win: implement a 'guest-get-load' command
  2025-03-19 15:02   ` Daniel P. Berrangé
@ 2025-03-19 16:52     ` Konstantin Kostiuk
  0 siblings, 0 replies; 7+ messages in thread
From: Konstantin Kostiuk @ 2025-03-19 16:52 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: qemu-devel, Marc-André Lureau, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 2220 bytes --]

On Wed, Mar 19, 2025 at 5:02 PM Daniel P. Berrangé <berrange@redhat.com>
wrote:

> On Fri, Mar 14, 2025 at 01:38:46PM +0200, Konstantin Kostiuk wrote:
> > 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
> >
> > Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
> > ---
> >  qga/commands-win32.c   | 140 +++++++++++++++++++++++++++++++++++++++++
> >  qga/guest-agent-core.h |  10 +++
> >  qga/main.c             |  39 ++++++++++++
> >  qga/meson.build        |   2 +-
> >  qga/qapi-schema.json   |   4 +-
> >  5 files changed, 192 insertions(+), 3 deletions(-)
>
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
>
>
> > +GuestLoadAverage *qmp_guest_get_load(Error **errp)
> > +{
> > +    if (ga_get_load_avg_pdh_query(ga_state) == NULL) {
> > +        /* set initial values */
> > +        load_avg_1m = 0;
> > +        load_avg_5m = 0;
> > +        load_avg_15m = 0;
> > +
> > +        if (init_load_avg_counter(errp) == false) {
> > +            return NULL;
> > +        }
> > +    }
>
> Nice idea. So we avoid running the load average logic
> until such time as a mgmt app actually asks for it.
>
> The load avg won't be very accurate initially, but
> assuming any interested mgmt app will ask for this
> repeatedly over the entire life of the VM, this looks
> like a good mitigation.
>
> Perhaps worth a commenting explaining why we're doing
> this.
>
>
Will add comments

Also, this allows the mgmt app to capture errors in the initialization
process. Otherwise, it should somehow parse logs.


>
> > +
> > +    GuestLoadAverage *ret = NULL;
> > +
> > +    ret = g_new0(GuestLoadAverage, 1);
> > +    ret->load1m = load_avg_1m;
> > +    ret->load5m = load_avg_5m;
> > +    ret->load15m = load_avg_15m;
> > +    return ret;
> > +}
>
> With regards,
> Daniel
> --
> |: https://berrange.com      -o-
> https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-
> https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-
> https://www.instagram.com/dberrange :|
>
>

[-- Attachment #2: Type: text/html, Size: 3781 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-03-19 16:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-14 11:38 [PATCH 0/2] qga: Add 'guest-get-load' command Konstantin Kostiuk
2025-03-14 11:38 ` [PATCH 1/2] qga-win: implement a " Konstantin Kostiuk
2025-03-19 15:02   ` Daniel P. Berrangé
2025-03-19 16:52     ` Konstantin Kostiuk
2025-03-14 11:38 ` [PATCH 2/2] qga: Add tests for guest-get-load command Konstantin Kostiuk
2025-03-18 13:47 ` [PATCH 0/2] qga: Add 'guest-get-load' command Dehan Meng
2025-03-19 14:57 ` Yan Vugenfirer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).