[libvirt] [PATCH v2 2/4] Register cpu hotplug netlink handler for libvirtd.

Tang Chen tangchen at cn.fujitsu.com
Tue Sep 4 08:45:18 UTC 2012


This patch first sets cpuset.cpus to lastest value for libvirtd,
and then registers 2 callback for cpu hotplug event for libvirtd:
    - daemonNetlinkCpuHotplugHandleCallback()
    - daemonNetlinkCpuHotplugRemoveCallback()

Signed-off-by: Tang Chen <tangchen at cn.fujitsu.com>
---
 daemon/libvirtd.c        |   62 ++++++++++++++++++++++++++++++++++++++++++++++
 src/libvirt_private.syms |    1 +
 src/util/cgroup.c        |    6 ++---
 src/util/cgroup.h        |    4 +++
 4 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 6973df6..b612231 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -56,6 +56,8 @@
 #include "uuid.h"
 #include "viraudit.h"
 #include "locking/lock_manager.h"
+#include "cgroup.h"
+#include "hotplug.h"
 
 #ifdef WITH_DRIVER_MODULES
 # include "driver.h"
@@ -935,6 +937,43 @@ enum {
     OPT_VERSION = 129
 };
 
+static void
+daemonNetlinkCpuHotplugHandleCallback(unsigned char *msg,
+                                      int length,
+                                      struct sockaddr_nl *peer ATTRIBUTE_UNUSED,
+                                      bool *handled ATTRIBUTE_UNUSED,
+                                      void *opaque)
+{
+    virCgroupPtr cgroup = NULL;
+
+    /* opaque is a cgroup identifier pointing to libvirt root cgroup. */
+    if (!opaque) {
+        virReportSystemError(EINVAL,
+                             "%s",
+                             _("invalid argument"));
+        return;
+    }
+
+    cgroup = (virCgroupPtr)opaque;
+
+    if (virHotplugUpdateCgroupCpuset(msg, length, cgroup) < 0) {
+        virReportSystemError(errno,
+                             "%s",
+                             _("Unable to update cpuset in cgroup"));
+    }
+
+    return;
+}
+
+static void
+daemonNetlinkCpuHotplugRemoveCallback(int watch ATTRIBUTE_UNUSED,
+                                      const virMacAddrPtr macaddr ATTRIBUTE_UNUSED,
+                                      void *opaque ATTRIBUTE_UNUSED)
+{
+    /* For now, nothing to do. */
+    VIR_INFO("CPU hotplug netlink handler has been removed.");
+}
+
 #define MAX_LISTEN 5
 int main(int argc, char **argv) {
     virNetServerPtr srv = NULL;
@@ -954,6 +993,7 @@ int main(int argc, char **argv) {
     bool implicit_conf = false;
     char *run_dir = NULL;
     mode_t old_umask;
+    virCgroupPtr rootgrp = NULL;
 
     struct option opts[] = {
         { "verbose", no_argument, &verbose, 1},
@@ -1327,11 +1367,32 @@ int main(int argc, char **argv) {
 #endif
 
 #if defined(__linux__) && defined(NETLINK_KOBJECT_UEVENT)
+    /**
+     * If we had ever missed any cpu hotplug event, we need to update
+     * cpuset.cpus to the lastest value
+     */
+    if (virCgroupAppRoot(privileged, &rootgrp, 0) != 0 ||
+        virHotplugSetCpusetToLastest(rootgrp) < 0) {
+        ret = VIR_DAEMON_ERR_INIT;
+        goto cleanup;
+    }
+
     /* Register the netlink event service for NETLINK_KOBJECT_UEVENT */
     if (virNetlinkEventServiceStart(NETLINK_KOBJECT_UEVENT, 1) < 0) {
         ret = VIR_DAEMON_ERR_NETWORK;
         goto cleanup;
     }
+
+    /* Register cpu hotplug event handler for libvirtd */
+    if (virNetlinkEventServiceIsRunning(NETLINK_KOBJECT_UEVENT)) {
+        if (virNetlinkEventAddClient(daemonNetlinkCpuHotplugHandleCallback,
+                                     daemonNetlinkCpuHotplugRemoveCallback,
+                                     rootgrp, NULL,
+                                     NETLINK_KOBJECT_UEVENT) < 0) {
+            ret = VIR_DAEMON_ERR_NETWORK;
+            goto cleanup;
+        }
+    }
 #endif
 
     /* Run event loop. */
@@ -1362,6 +1423,7 @@ cleanup:
     if (pid_file_fd != -1)
         virPidFileReleasePath(pid_file, pid_file_fd);
 
+    virCgroupFree(&rootgrp);
     VIR_FREE(sock_file);
     VIR_FREE(sock_file_ro);
     VIR_FREE(pid_file);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 2ff7e0e..752e3b0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -64,6 +64,7 @@ virCgroupAddTaskController;
 virCgroupAllowDevice;
 virCgroupAllowDeviceMajor;
 virCgroupAllowDevicePath;
+virCgroupAppRoot;
 virCgroupControllerTypeFromString;
 virCgroupControllerTypeToString;
 virCgroupDenyAllDevices;
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index 393d439..a1b21de 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -641,9 +641,9 @@ err:
     return rc;
 }
 
-static int virCgroupAppRoot(int privileged,
-                            virCgroupPtr *group,
-                            int create)
+int virCgroupAppRoot(int privileged,
+                     virCgroupPtr *group,
+                     int create)
 {
     virCgroupPtr rootgrp = NULL;
     int rc;
diff --git a/src/util/cgroup.h b/src/util/cgroup.h
index e294495..f31346c 100644
--- a/src/util/cgroup.h
+++ b/src/util/cgroup.h
@@ -44,6 +44,10 @@ enum {
 
 VIR_ENUM_DECL(virCgroupController);
 
+int virCgroupAppRoot(int privileged,
+                     virCgroupPtr *group,
+                     int create);
+
 int virCgroupForDriver(const char *name,
                        virCgroupPtr *group,
                        int privileged,
-- 
1.7.10.1




More information about the libvir-list mailing list