[libvirt] [PATCH 2/3] Implementation deficiency in virInitctlSetRunLevel v2
Daniel P. Berrange
berrange at redhat.com
Thu Dec 19 16:45:00 UTC 2013
On Thu, Dec 19, 2013 at 08:07:50PM +0400, Reco wrote:
> 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;
> + }
Since this is a fairly tedious large piece of code I think it is
worth hiding it in a helper function. I'd suggest that in the
src/util/virprocess.{c,h} file we create a
typedef int (*virProcessNamespaceCallback)(pid_t pid, void *opaque);
virProcessRunInMountNamespace(pid_t pid,
virProcessNamespaceCallback cb,
void *opaque)
This lxcDomainShutdownFlags code would then use that and pass a
callback function which does the virInitctlSetRunLevel() API call.
That should reduce the code size significantly, since we also need
to fix all the other places in this file which use /proc/$PID/root.
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 :|
More information about the libvir-list
mailing list