[libvirt] [PATCH v2 4/4] Register cpu hotplug netlink handler for lxc driver.

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


This patch sets cpuset.cpus to the lastest value for lxc driver when the driver
is being initialized, and registers 2 cpu hotplug handlers for lxc driver:
    - lxcNetlinkCpuHotplugHandleCallback()
    - lxcNetlinkCpuHotplugRemoveCallback()

Signed-off-by: Tang Chen <tangchen at cn.fujitsu.com>
---
 src/lxc/lxc_driver.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index ff11c2c..a2f17de 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -63,6 +63,9 @@
 #include "virtime.h"
 #include "virtypedparam.h"
 #include "viruri.h"
+#include "hotplug.h"
+#include "cgroup.h"
+#include "virnetlink.h"
 
 #define VIR_FROM_THIS VIR_FROM_LXC
 
@@ -1396,11 +1399,48 @@ error:
     return -1;
 }
 
+static void
+lxcNetlinkCpuHotplugHandleCallback(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
+lxcNetlinkCpuHotplugRemoveCallback(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.");
+}
 
 static int lxcStartup(int privileged)
 {
     char *ld;
     int rc;
+    char ebuf[1024];
 
     /* Valgrind gets very annoyed when we clone containers, so
      * disable LXC when under valgrind
@@ -1445,14 +1485,37 @@ static int lxcStartup(int privileged)
 
     rc = virCgroupForDriver("lxc", &lxc_driver->cgroup, privileged, 1);
     if (rc < 0) {
-        char buf[1024] ATTRIBUTE_UNUSED;
         VIR_DEBUG("Unable to create cgroup for LXC driver: %s",
-                  virStrerror(-rc, buf, sizeof(buf)));
+                  virStrerror(-rc, ebuf, sizeof(ebuf)));
         /* Don't abort startup. We will explicitly report to
          * the user when they try to start a VM
          */
     }
 
+#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
+     */
+    rc = virHotplugSetCpusetToLastest(lxc_driver->cgroup);
+    if (rc < 0) {
+        VIR_INFO("Unable to reset cgroup for driver: %s",
+                 virStrerror(-rc, ebuf, sizeof(ebuf)));
+    }
+
+    /* Register cpu hotplug event handler for lxc driver */
+    if (virNetlinkEventServiceIsRunning(NETLINK_KOBJECT_UEVENT)) {
+        rc = virNetlinkEventAddClient(lxcNetlinkCpuHotplugHandleCallback,
+                                      lxcNetlinkCpuHotplugRemoveCallback,
+                                      lxc_driver->cgroup, NULL,
+                                      NETLINK_KOBJECT_UEVENT);
+        if (rc < 0) {
+            VIR_INFO("Unable to register cpu hotplug event handler for driver: %s",
+                     virStrerror(-rc, ebuf, sizeof(ebuf)));
+        }
+    }
+#endif
+
     /* Call function to load lxc driver configuration information */
     if (lxcLoadDriverConfig(lxc_driver) < 0)
         goto cleanup;
-- 
1.7.10.1




More information about the libvir-list mailing list