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@xxxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list