diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index a7ffd2b7eeabb7bb2e84b800f73995bf4e98813c..9f1a3d46f1eb96481c1bc34f59906ff606edd61b 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -48,6 +48,7 @@ #include "virfile.h" #include "virkeycode.h" #include "virmacaddr.h" +#include "virstring.h" #include "virsh-domain-monitor.h" #include "virterror_internal.h" #include "virtypedparam.h" @@ -4029,19 +4030,27 @@ static const vshCmdOptDef opts_shutdown[] = { static bool cmdShutdown(vshControl *ctl, const vshCmd *cmd) { - virDomainPtr dom; - bool ret = true; + virDomainPtr dom = NULL; + bool ret = false; const char *name; const char *mode = NULL; int flags = 0; int rv; + char **modes, **tmp; if (vshCommandOptString(cmd, "mode", &mode) < 0) { vshError(ctl, "%s", _("Invalid type")); return false; } - if (mode) { + if (!(modes = virStringSplit(mode, ",", 0))) { + vshError(ctl, "%s", _("Cannot parse mode string")); + return false; + } + + tmp = modes; + while (*tmp) { + mode = *tmp; if (STREQ(mode, "acpi")) { flags |= VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN; } else if (STREQ(mode, "agent")) { @@ -4053,12 +4062,13 @@ cmdShutdown(vshControl *ctl, const vshCmd *cmd) } else { vshError(ctl, _("Unknown mode %s value, expecting " "'acpi', 'agent', 'initctl' or 'signal'"), mode); - return false; + goto cleanup; } + tmp++; } if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) - return false; + goto cleanup; if (flags) rv = virDomainShutdownFlags(dom, flags); @@ -4068,10 +4078,14 @@ cmdShutdown(vshControl *ctl, const vshCmd *cmd) vshPrint(ctl, _("Domain %s is being shutdown\n"), name); } else { vshError(ctl, _("Failed to shutdown domain %s"), name); - ret = false; + goto cleanup; } - virDomainFree(dom); + ret = true; +cleanup: + if (dom) + virDomainFree(dom); + virStringFreeList(modes); return ret; } @@ -4093,18 +4107,26 @@ static const vshCmdOptDef opts_reboot[] = { static bool cmdReboot(vshControl *ctl, const vshCmd *cmd) { - virDomainPtr dom; - bool ret = true; + virDomainPtr dom = NULL; + bool ret = false; const char *name; const char *mode = NULL; int flags = 0; + char **modes, **tmp; if (vshCommandOptString(cmd, "mode", &mode) < 0) { vshError(ctl, "%s", _("Invalid type")); return false; } - if (mode) { + if (!(modes = virStringSplit(mode, ",", 0))) { + vshError(ctl, "%s", _("Cannot parse mode string")); + return false; + } + + tmp = modes; + while (*tmp) { + mode = *tmp; if (STREQ(mode, "acpi")) { flags |= VIR_DOMAIN_REBOOT_ACPI_POWER_BTN; } else if (STREQ(mode, "agent")) { @@ -4116,21 +4138,26 @@ cmdReboot(vshControl *ctl, const vshCmd *cmd) } else { vshError(ctl, _("Unknown mode %s value, expecting " "'acpi', 'agent', 'initctl' or 'signal'"), mode); - return false; + goto cleanup; } + tmp++; } if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) - return false; + goto cleanup; if (virDomainReboot(dom, flags) == 0) { vshPrint(ctl, _("Domain %s is being rebooted\n"), name); } else { vshError(ctl, _("Failed to reboot domain %s"), name); - ret = false; + goto cleanup; } - virDomainFree(dom); + ret = true; +cleanup: + if (dom) + virDomainFree(dom); + virStringFreeList(modes); return ret; } diff --git a/tools/virsh.pod b/tools/virsh.pod index c901b11d562c7325bb2b71fcc29026abaf4650c7..7dde3df2eceacf982b43ee9296622193edca3c7c 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1137,7 +1137,7 @@ If I<--live> is specified, set scheduler information of a running guest. If I<--config> is specified, affect the next boot of a persistent guest. If I<--current> is specified, affect the current guest state. -=item B I [I<--mode acpi|agent>] +=item B I [I<--mode MODE-LIST>] Reboot a domain. This acts just as if the domain had the B command run from the console. The command returns as soon as it has @@ -1149,7 +1149,11 @@ I parameter in the domain's XML definition. By default the hypervisor will try to pick a suitable shutdown method. To specify an alternative method, the I<--mode> parameter -can specify C or C. +can specify a comma separated list which includes C, C, +C and C. The order in which drivers will try each +mode is undefined, and not related to the order specified to virsh. +For strict control over ordering, use a single mode at a time and +repeat the command. =item B I @@ -1567,7 +1571,7 @@ The I<--maximum> flag controls the maximum number of virtual cpus that can be hot-plugged the next time the domain is booted. As such, it must only be used with the I<--config> flag, and not with the I<--live> flag. -=item B I [I<--mode acpi|agent>] +=item B I [I<--mode MODE-LIST>] Gracefully shuts down a domain. This coordinates with the domain OS to perform graceful shutdown, so there is no guarantee that it will @@ -1584,7 +1588,11 @@ snapshot metadata with B. By default the hypervisor will try to pick a suitable shutdown method. To specify an alternative method, the I<--mode> parameter -can specify C or C. +can specify a comma separated list which includes C, C, +C and C. The order in which drivers will try each +mode is undefined, and not related to the order specified to virsh. +For strict control over ordering, use a single mode at a time and +repeat the command. =item B I [I<--console>] [I<--paused>] [I<--autodestroy>] [I<--bypass-cache>] [I<--force-boot>]