[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 |