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(a)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