From aa4619337ccc0b171a3a4d17540da89429243c36 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Wed, 18 Dec 2013 19:00:32 +0100 Subject: [PATCH] lxcDomainShutdownFlags: Cleanup @flags usage Currently, the @flags usage is a bit unclear at first sight to say the least. There's no need for such unclear code especially when we can borrow the working code from qemuDomainShutdownFlags(). In addition, this fixes one bug too. If user requested both VIR_DOMAIN_SHUTDOWN_INITCTL and VIR_DOMAIN_SHUTDOWN_SIGNAL at the same time, he is basically saying: 'Use the force Luke! If initctl fails try sending a signal.' But with the current code we don't do that. If initctl fails for some reason (e.g. inability to write to /dev/initctl) we don't try sending any signal but fail immediately. To make things worse, making a domain shutdown with bare _SIGNAL was working by blind chance of a @rc variable being placed at correct place on the stack so its initial value was zero. Signed-off-by: Michal Privoznik --- src/lxc/lxc_driver.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index e5298d1498..77b25d4946 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2701,7 +2701,8 @@ lxcDomainShutdownFlags(virDomainPtr dom, virDomainObjPtr vm; char *vroot = NULL; int ret = -1; - int rc; + int rc = 0; + bool useInitctl = false, initctlRequested, signalRequested; virCheckFlags(VIR_DOMAIN_SHUTDOWN_INITCTL | VIR_DOMAIN_SHUTDOWN_SIGNAL, -1); @@ -2730,25 +2731,24 @@ lxcDomainShutdownFlags(virDomainPtr dom, (unsigned long long)priv->initpid) < 0) goto cleanup; - if (flags == 0 || - (flags & VIR_DOMAIN_SHUTDOWN_INITCTL)) { - if ((rc = virInitctlSetRunLevel(VIR_INITCTL_RUNLEVEL_POWEROFF, - vroot)) < 0) { + initctlRequested = flags & VIR_DOMAIN_SHUTDOWN_INITCTL; + signalRequested = flags & VIR_DOMAIN_SHUTDOWN_SIGNAL; + + if (initctlRequested || !flags) + useInitctl = true; + + if (useInitctl) { + rc = virInitctlSetRunLevel(VIR_INITCTL_RUNLEVEL_POWEROFF, vroot); + if (rc < 0 && !signalRequested) goto cleanup; - } - if (rc == 0 && flags != 0 && - ((flags & ~VIR_DOMAIN_SHUTDOWN_INITCTL) == 0)) { + if (rc == 0 && !signalRequested) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("Container does not provide an initctl pipe")); goto cleanup; } - } else { - rc = 0; } - if (rc == 0 && - (flags == 0 || - (flags & VIR_DOMAIN_SHUTDOWN_SIGNAL))) { + if (rc == 0 && !useInitctl) { if (kill(priv->initpid, SIGTERM) < 0 && errno != ESRCH) { virReportSystemError(errno,