Implement fork & setns for lxcDomainShutdownFlags --- src/lxc/lxc_driver.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index c499182..9d200b2 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2619,6 +2619,50 @@ lxcDomainShutdownFlags(virDomainPtr dom, goto cleanup; } +#ifdef HAVE_SETNS + if (flags == 0 || flags & VIR_DOMAIN_SHUTDOWN_INITCTL) { + int pid = -1; + int status = -1; + int mfd = -1; + + if (virAsprintf(&vroot, "/proc/%llu/ns/mnt", + (unsigned long long)priv->initpid) < 0) { + goto cleanup; + } + + if ((mfd = open(vroot, O_RDONLY)) < 0) { + virReportSystemError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("Kernel does not provide mount namespace")); + goto cleanup; + } + + switch (pid = fork()) { + case 0: + if (setns(mfd, 0) == -1) { + exit(-1); + } + rc = virInitctlSetRunLevel(VIR_INITCTL_RUNLEVEL_POWEROFF, NULL); + exit(rc); + break; + case -1: + virReportSystemError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Fork failed")); + goto cleanup; + default: + if (waitpid(pid, &status, 0) < 0 || status < 0) { + virReportSystemError(errno, + _("Sending shutdown failed with status %i"), + status); + rc = 0; + } else { + rc = status; + } + close(mfd); + } + } else { + rc = 0; + } +#else if (virAsprintf(&vroot, "/proc/%llu/root", (unsigned long long)priv->initpid) < 0) goto cleanup; @@ -2638,6 +2682,7 @@ lxcDomainShutdownFlags(virDomainPtr dom, } else { rc = 0; } +#endif if (rc == 0 && (flags == 0 || -- 1.7.10.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list