|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 0 of 3] xl and hotplug: Introduce and use shutdown and reboot xm compatibility options
Tuesday, September 25, 2012, 5:29:09 PM, you wrote:
> On Tue, 2012-09-25 at 16:11 +0100, Sander Eikelenboom wrote:
>> The only relative simple implementation i thought of was direct
>> shutting down all, and when the -w parameter was set, just loop and
>> wait on events until the only running domain is domain-0.
>> Although this exactly does what has to be done, it somehow sounds a
>> bit dirty.
> I think you can allocate an array of libxl_evenable_domain_death*, of
> nr_doms in size and then as you shutdown each domain call
> libxl_evenable_domain_death for it too.
> Then you loop waiting for destroy events, calling
> libxl_evdisable_domain_death as each domain dies, while counting back
> from nr_doms until 0. When it reaches 0 everything you asked for has
> been shutdown.
> Or something like that, I've not actually implemented it ;-)
> Ian.
It's time to call defeat, without proper C skills it seems a bit too hard to
figure it out.
Can't seem to get the hang of how to keep a reference to
libxl_evgen_domain_death
and use it to check if the domid of the event is the same as that from a domain
we are waiting to shutdown.
The rest of the code doesn't give me much pointers since all commands seem to
operate on a single domid at once.
The concoction below leads to:
xl_cmdimpl.c: In function Ãshutdown_domainÃ:
xl_cmdimpl.c:2766: error: dereferencing pointer to incomplete type
--------------------------- tools/libxl/xl_cmdimpl.c ---------------------------
index 1627cac..b900811 100644
@@ -2684,67 +2684,98 @@ static void destroy_domain(uint32_t domid)
}
rc = libxl_domain_destroy(ctx, domid, 0);
if (rc) { fprintf(stderr,"destroy failed (rc=%d)\n",rc); exit(-1); }
}
-static void shutdown_domain(uint32_t domid, int wait_for_it,
- int fallback_trigger)
+static int shutdown_domain(const libxl_dominfo *dominfo, int nb_domain,
+ int wait_for_it, int fallback_trigger)
{
- int rc;
- libxl_event *event;
+ int i, rc, nb_shutdown_pending;
+ int ret = 0;
+ libxl_evgen_domain_death *domains_wait_shutdown[nb_domain];
+
+ for (i = 0; i < nb_domain; i++) {
+ uint32_t domid = dominfo[i].domid;
+ if(!libxl_domid_valid_guest(domid))
+ continue;
- rc=libxl_domain_shutdown(ctx, domid);
- if (rc == ERROR_NOPARAVIRT) {
- if (fallback_trigger) {
- fprintf(stderr, "PV control interface not available:"
- " sending ACPI power button event.\n");
- rc = libxl_send_trigger(ctx, domid, LIBXL_TRIGGER_POWER, 0);
- } else {
- fprintf(stderr, "PV control interface not available:"
- " external graceful shutdown not possible.\n");
- fprintf(stderr, "Use \"-F\" to fallback to ACPI power event.\n");
+ rc = libxl_domain_shutdown(ctx, domid);
+
+ if (rc == ERROR_NOPARAVIRT) {
+ if (fallback_trigger) {
+ fprintf(stderr, "PV control interface not available:"
+ " sending ACPI power button event.\n");
+ rc = libxl_send_trigger(ctx, domid, LIBXL_TRIGGER_POWER, 0);
+ } else {
+ fprintf(stderr, "PV control interface not available:"
+ " external graceful shutdown not possible.\n");
+ fprintf(stderr,
+ "Use \"-F\" to fallback to ACPI power event.\n");
+ }
+ }
+
+ if (rc) {
+ fprintf(stderr,"shutdown of domain %d failed (rc=%d)\n", domid,
rc);
+ ret = -1;
+ continue;
+ }
+
+ if (wait_for_it) {
+ rc = libxl_evenable_domain_death(ctx, domid, 0,
&domains_wait_shutdown[i]);
+ if (rc) {
+ fprintf(stderr,"wait for death of domain %d failed"
+ " (evgen, rc=%d)\n", domid, rc);
+ ret = -1;
+ } else {
+ nb_shutdown_pending++;
+ }
}
- }
- if (rc) {
- fprintf(stderr,"shutdown failed (rc=%d)\n",rc);exit(-1);
}
if (wait_for_it) {
- libxl_evgen_domain_death *deathw;
+ while (nb_shutdown_pending > 0) {
+ libxl_event *event;
+ rc = libxl_event_wait(ctx, &event, LIBXL_EVENTMASK_ALL, 0,0);
+ if (rc) {
+ LOG("Failed to get event (rc=%d)", rc);
+ return -1;
+ }
- rc = libxl_evenable_domain_death(ctx, domid, 0, &deathw);
- if (rc) {
- fprintf(stderr,"wait for death failed (evgen, rc=%d)\n",rc);
- exit(-1);
- }
+ uint32_t event_domid = event->domid;
+ switch (event->type) {
- for (;;) {
- rc = domain_wait_event(domid, &event);
- if (rc) exit(-1);
+ case LIBXL_EVENT_TYPE_DOMAIN_DEATH:
+ LOG("Domain %d has been destroyed", event_domid);
+ break;
- switch (event->type) {
+ case LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN:
+ LOG("Domain %d has been shut down, reason code %d %x",
+ event_domid,
+ event->u.domain_shutdown.shutdown_reason,
+ event->u.domain_shutdown.shutdown_reason);
+ break;
- case LIBXL_EVENT_TYPE_DOMAIN_DEATH:
- LOG("Domain %d has been destroyed", domid);
- goto done;
+ default:
+ continue;
+ break;
+ }
- 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;
+ for (i = 0; i < nb_domain; i++) {
+ if (!domains_wait_shutdown[i])
+ continue;
- default:
- LOG("Unexpected event type %d", event->type);
- break;
+ if (domains_wait_shutdown[i]->domid == event_domid){
+ libxl_evdisable_domain_death(ctx,
domains_wait_shutdown[i]);
+ domains_wait_shutdown[i] = NULL;
+ nb_shutdown_pending--;
+ }
}
libxl_event_free(ctx, event);
}
- done:
- libxl_event_free(ctx, event);
- libxl_evdisable_domain_death(ctx, deathw);
}
+
+ return ret;
}
static void reboot_domain(uint32_t domid, int fallback_trigger)
{
int rc;
@@ -3674,29 +3705,82 @@ int main_destroy(int argc, char **argv)
return 0;
}
int main_shutdown(int argc, char **argv)
{
+ libxl_dominfo dominfo_buf;
+ libxl_dominfo *dominfo, *dominfo_free = NULL;
+ int nb_domain, rc;
int opt;
+ int option_index = 0;
+ int all = 0;
int wait_for_it = 0;
int fallback_trigger = 0;
+ static struct option long_options[] = {
+ {"all", 0, 0, 'a'},
+ {"wait", 0, 0, 'w'},
+ {0, 0, 0, 0}
+ };
- while ((opt = def_getopt(argc, argv, "wF", "shutdown", 1)) != -1) {
+ while ((opt = getopt_long(argc, argv, "awF", long_options, &option_index))
!= -1) {
switch (opt) {
case 0: case 2:
return opt;
+ case 'a':
+ all = 1;
+ break;
case 'w':
wait_for_it = 1;
break;
case 'F':
fallback_trigger = 1;
break;
}
}
- shutdown_domain(find_domain(argv[optind]), wait_for_it, fallback_trigger);
- return 0;
+ if (!argv[optind] && !all) {
+ fprintf(stderr, "You must specify -a or a valid domain id.\n\n");
+ return opt;
+ }
+
+ if (all) {
+ dominfo = libxl_list_domain(ctx, &nb_domain);
+ if (!dominfo) {
+ fprintf(stderr, "libxl_domain_infolist failed.\n");
+ return -1;
+ }
+ dominfo_free = dominfo;
+ } else {
+ uint32_t domid = find_domain(argv[optind]);
+ if (domid == 0) {
+ fprintf(stderr, "Error: Domain-0 can't be shutdown by this
command\n");
+ return -1;
+ }
+
+ rc = libxl_domain_info(ctx, &dominfo_buf, domid);
+
+ if (rc == ERROR_INVAL) {
+ fprintf(stderr, "Error: Domain \'%s\' does not exist.\n",
+ argv[optind]);
+ return -rc;
+ }
+ if (rc) {
+ fprintf(stderr, "libxl_domain_info failed (code %d).\n", rc);
+ return -rc;
+ }
+ dominfo = &dominfo_buf;
+ nb_domain = 1;
+ }
+
+ rc = shutdown_domain(dominfo, nb_domain, wait_for_it, fallback_trigger);
+
+ if (dominfo_free)
+ libxl_dominfo_list_free(dominfo_free, nb_domain);
+ else
+ libxl_dominfo_dispose(dominfo);
+
+ return -rc;
}
int main_reboot(int argc, char **argv)
{
int opt;
Attachment:
patch.diff _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |