xl: Introduce xl shutdown --all support for xm compatibility

Based on a patch by Sander Eikelenboom

Signed-off-by: Sander Eikelenboom <linux@eikelenboom.it>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
[ ijc -- fixed sizeof(foo) vs sizeof(*foo) issue pointed out by Ian J ]
Committed-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Ian Campbell committed 2012-10-18 09:35:10 +01:00
1 parent b3b123b5a9
commit 710820bc4e
3 files changed
+94 -39

No files matched your search

+6 -1
View File
@@ -527,7 +527,7 @@ List specifically for that domain. Otherwise, list for all domains.
=back
=item B<shutdown> [I<OPTIONS>] I<domain-id>
=item B<shutdown> [I<OPTIONS>] I<-a|domain-id>
Gracefully shuts down a domain. This coordinates with the domain OS
to perform graceful shutdown, so there is no guarantee that it will
@@ -550,6 +550,11 @@ B<OPTIONS>
=over 4
=item B<-a>, B<--all>
Shutdown all guest domains. Often used when doing a complete shutdown
of a Xen system.
=item B<-w>, B<--wait>
Wait for the domain to complete shutdown before returning.
+85 -36
View File
@@ -2713,12 +2713,46 @@ static void destroy_domain(uint32_t domid)
if (rc) { fprintf(stderr,"destroy failed (rc=%d)\n",rc); exit(-1); }
}
static void shutdown_domain(uint32_t domid, int wait_for_it,
static void wait_for_domain_deaths(libxl_evgen_domain_death **deathws, int nr)
{
int rc, count = 0;
LOG("Waiting for %d domains to shutdown", nr);
while(1 && count < nr) {
libxl_event *event;
rc = libxl_event_wait(ctx, &event, LIBXL_EVENTMASK_ALL, 0,0);
if (rc) {
LOG("Failed to get event, quitting (rc=%d)", rc);
exit(-1);
}
switch (event->type) {
case LIBXL_EVENT_TYPE_DOMAIN_DEATH:
LOG("Domain %d has been destroyed", event->domid);
libxl_evdisable_domain_death(ctx, deathws[event->for_user]);
count++;
break;
case LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN:
LOG("Domain %d has been shut down, reason code %d",
event->domid, event->u.domain_shutdown.shutdown_reason);
libxl_evdisable_domain_death(ctx, deathws[event->for_user]);
count++;
break;
default:
LOG("Unexpected event type %d", event->type);
break;
}
libxl_event_free(ctx, event);
}
}
static void shutdown_domain(uint32_t domid,
libxl_evgen_domain_death **deathw,
libxl_ev_user for_user,
int fallback_trigger)
{
int rc;
libxl_event *event;
fprintf(stderr, "Shutting down domain %d\n", domid);
rc=libxl_domain_shutdown(ctx, domid);
if (rc == ERROR_NOPARAVIRT) {
if (fallback_trigger) {
@@ -2731,44 +2765,19 @@ static void shutdown_domain(uint32_t domid, int wait_for_it,
fprintf(stderr, "Use \"-F\" to fallback to ACPI power event.\n");
}
}
if (rc) {
fprintf(stderr,"shutdown failed (rc=%d)\n",rc);exit(-1);
}
if (wait_for_it) {
libxl_evgen_domain_death *deathw;
rc = libxl_evenable_domain_death(ctx, domid, 0, &deathw);
if (deathw) {
rc = libxl_evenable_domain_death(ctx, domid, for_user, deathw);
if (rc) {
fprintf(stderr,"wait for death failed (evgen, rc=%d)\n",rc);
exit(-1);
}
for (;;) {
rc = domain_wait_event(domid, &event);
if (rc) exit(-1);
switch (event->type) {
case LIBXL_EVENT_TYPE_DOMAIN_DEATH:
LOG("Domain %d has been destroyed", domid);
goto done;
case LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN:
LOG("Domain %d has been shut down, reason code %d %x", domid,
event->u.domain_shutdown.shutdown_reason,
event->u.domain_shutdown.shutdown_reason);
goto done;
default:
LOG("Unexpected event type %d", event->type);
break;
}
libxl_event_free(ctx, event);
}
done:
libxl_event_free(ctx, event);
libxl_evdisable_domain_death(ctx, deathw);
printf("Waiting for domain %d death %p %"PRIx64"\n",
domid, *deathw, for_user);
}
}
@@ -3706,18 +3715,21 @@ int main_destroy(int argc, char **argv)
int main_shutdown(int argc, char **argv)
{
int opt;
int wait_for_it = 0;
int opt, i, nb_domain;
int wait_for_it = 0, all =0;
int fallback_trigger = 0;
static struct option long_options[] = {
{"all", 0, 0, 'a'},
{"wait", 0, 0, 'w'},
{0, 0, 0, 0}
};
while ((opt = getopt_long(argc, argv, "wF", long_options, NULL)) != -1) {
while ((opt = getopt_long(argc, argv, "awF", long_options, NULL)) != -1) {
switch (opt) {
case 0: case 2:
return opt;
case 'a':
all = 1;
case 'w':
wait_for_it = 1;
break;
@@ -3727,7 +3739,44 @@ int main_shutdown(int argc, char **argv)
}
}
shutdown_domain(find_domain(argv[optind]), wait_for_it, fallback_trigger);
if (!argv[optind] && !all) {
fprintf(stderr, "You must specify -a or a domain id.\n\n");
return opt;
}
if (all) {
libxl_dominfo *dominfo;
libxl_evgen_domain_death **deathws = NULL;
if (!(dominfo = libxl_list_domain(ctx, &nb_domain))) {
fprintf(stderr, "libxl_list_domain failed.\n");
return -1;
}
if (wait_for_it)
deathws = calloc(nb_domain, sizeof(*deathws));
for (i = 0; i<nb_domain; i++) {
if (dominfo[i].domid == 0)
continue;
shutdown_domain(dominfo[i].domid,
deathws ? &deathws[i] : NULL, i,
fallback_trigger);
}
wait_for_domain_deaths(deathws, nb_domain - 1 /* not dom 0 */);
libxl_dominfo_list_free(dominfo, nb_domain);
} else {
libxl_evgen_domain_death *deathw = NULL;
uint32_t domid = find_domain(argv[optind]);
shutdown_domain(domid, wait_for_it ? &deathw : NULL, 0,
fallback_trigger);
if (wait_for_it)
wait_for_domain_deaths(&deathw, 1);
}
return 0;
}
+3 -2
View File
@@ -60,11 +60,12 @@ struct cmd_spec cmd_table[] = {
{ "shutdown",
&main_shutdown, 0, 1,
"Issue a shutdown signal to a domain",
"[options] <Domain>",
"[options] <-a|Domain>",
"-a, --all Shutdown all guest domains.\n"
"-h Print this help.\n"
"-F Fallback to ACPI power event for HVM guests with\n"
" no PV drivers.\n"
"-w, --wait Wait for guest to shutdown.\n"
"-w, --wait Wait for guest(s) to shutdown.\n"
},
{ "reboot",
&main_reboot, 0, 1,
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.