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