[libvirt] [PATCH v2 2/2] lxc: properly clean up qemu-nbd
Add the qemu-nbd tasks to the container cgroup to make sure those will be killed when the container is stopped. In order to reliably get the qemu-nbd tasks PIDs, we use /sys/devices/virtual/block/DEV/pid as qemu-nbd is daemonizing itself. --- src/lxc/lxc_controller.c | 56 1 file changed, 56 insertions(+) diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index efbe71f..9b6f0c8 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -107,6 +107,9 @@ struct _virLXCController { pid_t initpid; +size_t nnbdpids; +pid_t *nbdpids; + size_t nveths; char **veths; @@ -283,6 +286,8 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl) virObjectUnref(ctrl-server); virLXCControllerFreeFuse(ctrl); +VIR_FREE(ctrl-nbdpids); + virCgroupFree(ctrl-cgroup); /* This must always be the last thing to be closed */ @@ -525,6 +530,38 @@ static int virLXCControllerSetupNBDDeviceDisk(virDomainDiskDefPtr disk) return 0; } +static int virLXCControllerAppendNBDPids(virLXCControllerPtr ctrl, + const char *dev) +{ +char *pidpath = NULL; +pid_t *pids; +size_t npids; +size_t i; +int ret = -1; +pid_t pid; + +if (!STRPREFIX(dev, /dev/) || +virAsprintf(pidpath, /sys/devices/virtual/block/%s/pid, dev + 5) 0) +goto cleanup; + +if (virPidFileReadPath(pidpath, pid) 0) +goto cleanup; + +if (virProcessGetPids(pid, npids, pids) 0) +goto cleanup; + +for (i = 0; i npids; i++) { +if (VIR_APPEND_ELEMENT(ctrl-nbdpids, ctrl-nnbdpids, pids[i]) 0) +goto cleanup; +} + +ret = 0; + + cleanup: +VIR_FREE(pids); +VIR_FREE(pidpath); +return ret; +} static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) { @@ -570,6 +607,12 @@ static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) } else if (fs-fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_NBD) { if (virLXCControllerSetupNBDDeviceFS(fs) 0) goto cleanup; + +/* The NBD device will be cleaned up while the cgroup will end. + * For this we need to remember the qemu-nbd pid and add it to + * the cgroup*/ +if (virLXCControllerAppendNBDPids(ctrl, fs-src) 0) +goto cleanup; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(fs driver %s is not supported), @@ -629,6 +672,12 @@ static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) } if (virLXCControllerSetupNBDDeviceDisk(disk) 0) goto cleanup; + +/* The NBD device will be cleaned up while the cgroup will end. + * For this we need to remember the qemu-nbd pid and add it to + * the cgroup*/ +if (virLXCControllerAppendNBDPids(ctrl, virDomainDiskGetSource(disk)) 0) +goto cleanup; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(disk driver %s is not supported), @@ -781,6 +830,7 @@ static int virLXCControllerSetupCgroupLimits(virLXCControllerPtr ctrl) virBitmapPtr auto_nodeset = NULL; int ret = -1; virBitmapPtr nodeset = NULL; +size_t i; VIR_DEBUG(Setting up cgroup resource limits); @@ -798,6 +848,12 @@ static int virLXCControllerSetupCgroupLimits(virLXCControllerPtr ctrl) if (virCgroupAddTask(ctrl-cgroup, getpid()) 0) goto cleanup; +/* Add all qemu-nbd tasks to the cgroup */ +for (i = 0; i ctrl-nnbdpids; i++) { +if (virCgroupAddTask(ctrl-cgroup, ctrl-nbdpids[i]) 0) +goto cleanup; +} + if (virLXCCgroupSetup(ctrl-def, ctrl-cgroup, nodeset) 0) goto cleanup; -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/2] lxc: properly clean up qemu-nbd
On Tue, Jun 16, 2015 at 11:18:49AM +0200, Cédric Bosdonnat wrote: Add the qemu-nbd tasks to the container cgroup to make sure those will be killed when the container is stopped. In order to reliably get the qemu-nbd tasks PIDs, we use /sys/devices/virtual/block/DEV/pid as qemu-nbd is daemonizing itself. --- src/lxc/lxc_controller.c | 56 1 file changed, 56 insertions(+) ACK Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 2/2] lxc: properly clean up qemu-nbd
Add the qemu-nbd tasks to the container cgroup to make sure those will be killed when the container is stopped. In order to reliably get the qemu-nbd tasks PIDs, we use /sys/devices/virtual/block/DEV/pid as qemu-nbd is daemonizing itself. --- src/lxc/lxc_controller.c | 56 1 file changed, 56 insertions(+) diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index efbe71f..9b6f0c8 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -107,6 +107,9 @@ struct _virLXCController { pid_t initpid; +size_t nnbdpids; +pid_t *nbdpids; + size_t nveths; char **veths; @@ -283,6 +286,8 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl) virObjectUnref(ctrl-server); virLXCControllerFreeFuse(ctrl); +VIR_FREE(ctrl-nbdpids); + virCgroupFree(ctrl-cgroup); /* This must always be the last thing to be closed */ @@ -525,6 +530,38 @@ static int virLXCControllerSetupNBDDeviceDisk(virDomainDiskDefPtr disk) return 0; } +static int virLXCControllerAppendNBDPids(virLXCControllerPtr ctrl, + const char *dev) +{ +char *pidpath = NULL; +pid_t *pids; +size_t npids; +size_t i; +int ret = -1; +pid_t pid; + +if (!STRPREFIX(dev, /dev/) || +virAsprintf(pidpath, /sys/devices/virtual/block/%s/pid, dev + 5) 0) +goto cleanup; + +if (virPidFileReadPath(pidpath, pid) 0) +goto cleanup; + +if (virProcessGetPids(pid, npids, pids) 0) +goto cleanup; + +for (i = 0; i npids; i++) { +if (VIR_APPEND_ELEMENT(ctrl-nbdpids, ctrl-nnbdpids, pids[i]) 0) +goto cleanup; +} + +ret = 0; + + cleanup: +VIR_FREE(pids); +VIR_FREE(pidpath); +return ret; +} static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) { @@ -570,6 +607,12 @@ static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) } else if (fs-fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_NBD) { if (virLXCControllerSetupNBDDeviceFS(fs) 0) goto cleanup; + +/* The NBD device will be cleaned up while the cgroup will end. + * For this we need to remember the qemu-nbd pid and add it to + * the cgroup*/ +if (virLXCControllerAppendNBDPids(ctrl, fs-src) 0) +goto cleanup; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(fs driver %s is not supported), @@ -629,6 +672,12 @@ static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) } if (virLXCControllerSetupNBDDeviceDisk(disk) 0) goto cleanup; + +/* The NBD device will be cleaned up while the cgroup will end. + * For this we need to remember the qemu-nbd pid and add it to + * the cgroup*/ +if (virLXCControllerAppendNBDPids(ctrl, virDomainDiskGetSource(disk)) 0) +goto cleanup; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(disk driver %s is not supported), @@ -781,6 +830,7 @@ static int virLXCControllerSetupCgroupLimits(virLXCControllerPtr ctrl) virBitmapPtr auto_nodeset = NULL; int ret = -1; virBitmapPtr nodeset = NULL; +size_t i; VIR_DEBUG(Setting up cgroup resource limits); @@ -798,6 +848,12 @@ static int virLXCControllerSetupCgroupLimits(virLXCControllerPtr ctrl) if (virCgroupAddTask(ctrl-cgroup, getpid()) 0) goto cleanup; +/* Add all qemu-nbd tasks to the cgroup */ +for (i = 0; i ctrl-nnbdpids; i++) { +if (virCgroupAddTask(ctrl-cgroup, ctrl-nbdpids[i]) 0) +goto cleanup; +} + if (virLXCCgroupSetup(ctrl-def, ctrl-cgroup, nodeset) 0) goto cleanup; -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list