This patch sets cpuset.cpus to lastest for qemu driver when the driver
is being initialized, and then registers 2 cpu hotplug events handlers
for qemu driver:
- qemuNetlinkCpuHotplugHandleCallback()
- qemuNetlinkCpuHotplugRemoveCallback()
Signed-off-by: Tang Chen <tangchen(a)cn.fujitsu.com>
---
src/qemu/qemu_driver.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 53d6e5b..08f7be1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -92,6 +92,9 @@
#include "virnodesuspend.h"
#include "virtime.h"
#include "virtypedparam.h"
+#include "hotplug.h"
+#include "cgroup.h"
+#include "virnetlink.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -525,6 +528,43 @@ static void qemuDomainNetsRestart(void *payload,
virDomainObjUnlock(vm);
}
+static void
+qemuNetlinkCpuHotplugHandleCallback(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
+qemuNetlinkCpuHotplugRemoveCallback(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.");
+}
+
/**
* qemudStartup:
*
@@ -682,6 +722,30 @@ qemudStartup(int privileged) {
virStrerror(-rc, ebuf, sizeof(ebuf)));
}
+#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(qemu_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 qemu driver */
+ if (virNetlinkEventServiceIsRunning(NETLINK_KOBJECT_UEVENT)) {
+ rc = virNetlinkEventAddClient(qemuNetlinkCpuHotplugHandleCallback,
+ qemuNetlinkCpuHotplugRemoveCallback,
+ qemu_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
+
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
goto error;
}
--
1.7.10.1