Allow comma separated list of shutdown/reboot modes with virsh

The shutdown and reboot commands in virsh allow a comma
separated list of mode values

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2012-11-30 15:30:05 +00:00
parent 76c1fd33c8
commit cef78ed84a
2 changed files with 53 additions and 18 deletions

View File

@ -48,6 +48,7 @@
#include "virfile.h" #include "virfile.h"
#include "virkeycode.h" #include "virkeycode.h"
#include "virmacaddr.h" #include "virmacaddr.h"
#include "virstring.h"
#include "virsh-domain-monitor.h" #include "virsh-domain-monitor.h"
#include "virterror_internal.h" #include "virterror_internal.h"
#include "virtypedparam.h" #include "virtypedparam.h"
@ -4029,19 +4030,27 @@ static const vshCmdOptDef opts_shutdown[] = {
static bool static bool
cmdShutdown(vshControl *ctl, const vshCmd *cmd) cmdShutdown(vshControl *ctl, const vshCmd *cmd)
{ {
virDomainPtr dom; virDomainPtr dom = NULL;
bool ret = true; bool ret = false;
const char *name; const char *name;
const char *mode = NULL; const char *mode = NULL;
int flags = 0; int flags = 0;
int rv; int rv;
char **modes, **tmp;
if (vshCommandOptString(cmd, "mode", &mode) < 0) { if (vshCommandOptString(cmd, "mode", &mode) < 0) {
vshError(ctl, "%s", _("Invalid type")); vshError(ctl, "%s", _("Invalid type"));
return false; 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")) { if (STREQ(mode, "acpi")) {
flags |= VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN; flags |= VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN;
} else if (STREQ(mode, "agent")) { } else if (STREQ(mode, "agent")) {
@ -4053,12 +4062,13 @@ cmdShutdown(vshControl *ctl, const vshCmd *cmd)
} else { } else {
vshError(ctl, _("Unknown mode %s value, expecting " vshError(ctl, _("Unknown mode %s value, expecting "
"'acpi', 'agent', 'initctl' or 'signal'"), mode); "'acpi', 'agent', 'initctl' or 'signal'"), mode);
return false; goto cleanup;
} }
tmp++;
} }
if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
return false; goto cleanup;
if (flags) if (flags)
rv = virDomainShutdownFlags(dom, flags); rv = virDomainShutdownFlags(dom, flags);
@ -4068,10 +4078,14 @@ cmdShutdown(vshControl *ctl, const vshCmd *cmd)
vshPrint(ctl, _("Domain %s is being shutdown\n"), name); vshPrint(ctl, _("Domain %s is being shutdown\n"), name);
} else { } else {
vshError(ctl, _("Failed to shutdown domain %s"), name); 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; return ret;
} }
@ -4093,18 +4107,26 @@ static const vshCmdOptDef opts_reboot[] = {
static bool static bool
cmdReboot(vshControl *ctl, const vshCmd *cmd) cmdReboot(vshControl *ctl, const vshCmd *cmd)
{ {
virDomainPtr dom; virDomainPtr dom = NULL;
bool ret = true; bool ret = false;
const char *name; const char *name;
const char *mode = NULL; const char *mode = NULL;
int flags = 0; int flags = 0;
char **modes, **tmp;
if (vshCommandOptString(cmd, "mode", &mode) < 0) { if (vshCommandOptString(cmd, "mode", &mode) < 0) {
vshError(ctl, "%s", _("Invalid type")); vshError(ctl, "%s", _("Invalid type"));
return false; 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")) { if (STREQ(mode, "acpi")) {
flags |= VIR_DOMAIN_REBOOT_ACPI_POWER_BTN; flags |= VIR_DOMAIN_REBOOT_ACPI_POWER_BTN;
} else if (STREQ(mode, "agent")) { } else if (STREQ(mode, "agent")) {
@ -4116,21 +4138,26 @@ cmdReboot(vshControl *ctl, const vshCmd *cmd)
} else { } else {
vshError(ctl, _("Unknown mode %s value, expecting " vshError(ctl, _("Unknown mode %s value, expecting "
"'acpi', 'agent', 'initctl' or 'signal'"), mode); "'acpi', 'agent', 'initctl' or 'signal'"), mode);
return false; goto cleanup;
} }
tmp++;
} }
if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
return false; goto cleanup;
if (virDomainReboot(dom, flags) == 0) { if (virDomainReboot(dom, flags) == 0) {
vshPrint(ctl, _("Domain %s is being rebooted\n"), name); vshPrint(ctl, _("Domain %s is being rebooted\n"), name);
} else { } else {
vshError(ctl, _("Failed to reboot domain %s"), name); 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; return ret;
} }

View File

@ -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<--config> is specified, affect the next boot of a persistent guest.
If I<--current> is specified, affect the current guest state. If I<--current> is specified, affect the current guest state.
=item B<reboot> I<domain> [I<--mode acpi|agent>] =item B<reboot> I<domain> [I<--mode MODE-LIST>]
Reboot a domain. This acts just as if the domain had the B<reboot> Reboot a domain. This acts just as if the domain had the B<reboot>
command run from the console. The command returns as soon as it has command run from the console. The command returns as soon as it has
@ -1149,7 +1149,11 @@ I<on_reboot> parameter in the domain's XML definition.
By default the hypervisor will try to pick a suitable shutdown By default the hypervisor will try to pick a suitable shutdown
method. To specify an alternative method, the I<--mode> parameter method. To specify an alternative method, the I<--mode> parameter
can specify C<acpi> or C<agent>. can specify a comma separated list which includes C<acpi>, C<agent>,
C<initctl> and C<signal>. 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<reset> I<domain> =item B<reset> I<domain>
@ -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 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. used with the I<--config> flag, and not with the I<--live> flag.
=item B<shutdown> I<domain> [I<--mode acpi|agent>] =item B<shutdown> I<domain> [I<--mode MODE-LIST>]
Gracefully shuts down a domain. This coordinates with the domain OS Gracefully shuts down a domain. This coordinates with the domain OS
to perform graceful shutdown, so there is no guarantee that it will to perform graceful shutdown, so there is no guarantee that it will
@ -1584,7 +1588,11 @@ snapshot metadata with B<snapshot-create>.
By default the hypervisor will try to pick a suitable shutdown By default the hypervisor will try to pick a suitable shutdown
method. To specify an alternative method, the I<--mode> parameter method. To specify an alternative method, the I<--mode> parameter
can specify C<acpi> or C<agent>. can specify a comma separated list which includes C<acpi>, C<agent>,
C<initctl> and C<signal>. 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<start> I<domain-name-or-uuid> [I<--console>] [I<--paused>] =item B<start> I<domain-name-or-uuid> [I<--console>] [I<--paused>]
[I<--autodestroy>] [I<--bypass-cache>] [I<--force-boot>] [I<--autodestroy>] [I<--bypass-cache>] [I<--force-boot>]