qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 3/3] qga: implement qmp_guest_set_vcpus() for Linux


From: Laszlo Ersek
Subject: [Qemu-devel] [PATCH 3/3] qga: implement qmp_guest_set_vcpus() for Linux with sysfs
Date: Mon, 4 Mar 2013 23:19:57 +0100

Signed-off-by: Laszlo Ersek <address@hidden>
---
 qga/commands-posix.c |   51 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index d4b6bdc..1848df8 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -40,6 +40,7 @@ extern char **environ;
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <net/if.h>
+#include <inttypes.h>
 
 #ifdef FIFREEZE
 #define CONFIG_FSFREEZE
@@ -1178,7 +1179,57 @@ GuestLogicalProcessorList *qmp_guest_get_vcpus(Error 
**errp)
 
 void qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp)
 {
+#if defined(__linux__)
+    const GuestLogicalProcessorList *entry;
+    Error *local_err = NULL;
+
+    for (entry = vcpus; local_err == NULL && entry != NULL;
+         entry = entry->next) {
+        const GuestLogicalProcessor *vcpu;
+
+        vcpu = entry->value;
+        if (vcpu->logical_id == 0) {
+            if (!vcpu->online) {
+                error_setg(&local_err,
+                           "unable to offline logical processor #0");
+            }
+        } else {
+            char *buf;
+            FILE *f;
+
+            buf = g_strdup_printf("/sys/devices/system/cpu/cpu%"PRId64
+                                  "/online", vcpu->logical_id);
+            f = fopen(buf, "r+");
+            if (f == NULL) {
+                error_setg_errno(&local_err, errno, "fopen(\"%s\", \"r+\")",
+                                 buf);
+            } else {
+                unsigned online;
+
+                if (fscanf(f, "%u", &online) != 1) {
+                    error_setg(&local_err, "failed to read or parse \"%s\"",
+                               buf);
+                } else if ((online != 0) != vcpu->online) {
+                    errno = 0;
+                    rewind(f);
+                    if (errno != 0 ||
+                        fprintf(f, "%u\n", (unsigned)vcpu->online) < 0) {
+                        error_setg_errno(&local_err, errno,
+                                         "rewind()/fprintf() on \"%s\"", buf);
+                    }
+                }
+
+                if (fclose(f) == EOF && local_err == NULL) {
+                    error_setg_errno(&local_err, errno, "fclose(\"%s\")", buf);
+                }
+            }
+            g_free(buf);
+        }
+    }
+    error_propagate(errp, local_err);
+#else
     error_set(errp, QERR_UNSUPPORTED);
+#endif
 }
 
 /* register init/cleanup routines for stateful command groups */
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]