[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2 of 5] xl: Introduce xl shutdown --all support for xm compatibility



# HG changeset patch
# User Sander Eikelenboom <linux@xxxxxxxxxxxxxx>
# Date 1346960487 -7200
# Node ID 2329dca4ef449979b1403c4bb002fcb70c578b35
# Parent  65e301c71ca41af8cf0aaea653cd9e8d08bca2f7
xl: Introduce xl shutdown --all support for xm compatibility

Based on a patch by Sander Eikelenboom

Signed-off-by: Sander Eikelenboom <linux@xxxxxxxxxxxxxx>
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>


---

Changed since v3: (ijc)
  * Rebased. -w already implemented.
  * Shutdown domains in //.

Changed since v2:
  * fix error occuring when using both -a and -w options
    * Due to mixing local and global domid variable


Changed since v1:
  * address review comments.
    * Change shutdown_domain to take domid instead of domname
    * Docs: Make it more clear -a only shuts down GUEST domains

diff -r 65e301c71ca4 -r 2329dca4ef44 docs/man/xl.pod.1
--- a/docs/man/xl.pod.1 Mon Oct 15 09:43:10 2012 +0100
+++ b/docs/man/xl.pod.1 Thu Sep 06 21:41:27 2012 +0200
@@ -527,7 +527,7 @@ List specifically for that domain. Other
 
 =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.
diff -r 65e301c71ca4 -r 2329dca4ef44 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Mon Oct 15 09:43:10 2012 +0100
+++ b/tools/libxl/xl_cmdimpl.c  Thu Sep 06 21:41:27 2012 +0200
@@ -2713,12 +2713,46 @@ static void destroy_domain(uint32_t domi
     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 dom
             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;
 }
 
diff -r 65e301c71ca4 -r 2329dca4ef44 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c Mon Oct 15 09:43:10 2012 +0100
+++ b/tools/libxl/xl_cmdtable.c Thu Sep 06 21:41:27 2012 +0200
@@ -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,

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.