All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub)
@ 2010-07-12 14:01 Ian Campbell
  2010-07-12 14:01 ` [PATCH 1 of 9] pygrub: introduce easier to parse output format Ian Campbell
                   ` (9 more replies)
  0 siblings, 10 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

This series adds support to libxl/xl for running a domain 0
bootloader (such as pygrub).

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1 of 9] pygrub: introduce easier to parse output format
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
@ 2010-07-12 14:01 ` Ian Campbell
  2010-07-12 14:01 ` [PATCH 2 of 9] xenconsole: do not exit if a pty device is missing Ian Campbell
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

libxl would rather like to parse the output of pygrub. Rather than
implement an SXP parser in libxl add a --output-format option to
pygrub which can select an alternative, simpler to parse,
format. Available formats are:
    sxp:	current SXP output format;
    simple:	simple key+value output with \n separating item ( for
		debugging). key and value are separated by a single
		space (and key therefore cannot contain a space);
    simple0:	as simple but with \0 as a separator;

Also add --output-directory to allow temporary files to be placed
somewhere other than /var/run/xend/boot.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r 4f194a196734 -r 988cf8dff1c0 tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub	Mon Jul 12 11:40:17 2010 +0100
+++ b/tools/pygrub/src/pygrub	Mon Jul 12 14:56:37 2010 +0100
@@ -630,16 +630,34 @@
 
     return cfg
 
+def format_sxp(kernel, ramdisk, args):
+    s = "linux (kernel %s)" % kernel
+    if ramdisk:
+        s += "(ramdisk %s)" % ramdisk
+    if args:
+        s += "(args \"%s\")" % args
+    return s
+                
+def format_simple(kernel, ramdisk, args, sep):
+    s = ("kernel %s" % kernel) + sep
+    if ramdisk:
+        s += ("ramdisk %s" % ramdisk) + sep
+    if args:
+        s += ("args %s" % args) + sep
+    s += sep
+    return s
+
 if __name__ == "__main__":
     sel = None
     
     def usage():
-        print >> sys.stderr, "Usage: %s [-q|--quiet] [-i|--interactive] [-n|--not-really] [--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=] <image>" %(sys.argv[0],)
+        print >> sys.stderr, "Usage: %s [-q|--quiet] [-i|--interactive] [-n|--not-really] [--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=] [--output-directory=] [--output-format=sxp|simple|simple0] <image>" %(sys.argv[0],)
 
     try:
         opts, args = getopt.gnu_getopt(sys.argv[1:], 'qinh::',
-                                   ["quiet", "interactive", "not-really", 
-                                    "help", "output=", "entry=", "kernel=", 
+                                   ["quiet", "interactive", "not-really", "help", 
+                                    "output=", "output-format=", "output-directory=",
+                                    "entry=", "kernel=", 
                                     "ramdisk=", "args=", "isconfig"])
     except getopt.GetoptError:
         usage()
@@ -655,6 +673,8 @@
     interactive = True
     isconfig = False
     not_really = False
+    output_format = "sxp"
+    output_directory = "/var/run/xend/boot"
 
     # what was passed in
     incfg = { "kernel": None, "ramdisk": None, "args": "" }
@@ -687,6 +707,14 @@
             interactive = False
         elif o in ("--isconfig",):
             isconfig = True
+        elif o in ("--output-format",):
+            if a not in ["sxp", "simple", "simple0"]:
+                print "unkonwn output format %s" % a
+                usage()
+                sys.exit(1)
+            output_format = a
+        elif o in ("--output-directory",):
+            output_directory = a
 
     if output is None or output == "-":
         fd = sys.stdout.fileno()
@@ -723,7 +751,7 @@
     else:
         data = fs.open_file(chosencfg["kernel"]).read()
         (tfd, bootcfg["kernel"]) = tempfile.mkstemp(prefix="boot_kernel.",
-                                                    dir="/var/run/xend/boot")
+                                                    dir=output_directory)
         os.write(tfd, data)
         os.close(tfd)
 
@@ -733,26 +761,29 @@
         else:
             data = fs.open_file(chosencfg["ramdisk"],).read()
             (tfd, bootcfg["ramdisk"]) = tempfile.mkstemp(
-                prefix="boot_ramdisk.", dir="/var/run/xend/boot")
+                prefix="boot_ramdisk.", dir=output_directory)
             os.write(tfd, data)
             os.close(tfd)
     else:
         initrd = None
 
-    sxp = "linux (kernel %s)" % bootcfg["kernel"]
-    if bootcfg["ramdisk"]:
-        sxp += "(ramdisk %s)" % bootcfg["ramdisk"]
+    args = None
     if chosencfg["args"]:
         zfsinfo = fsimage.getbootstring(fs)
-        if zfsinfo is None:
-            sxp += "(args \"%s\")" % chosencfg["args"]
-        else:
+        if zfsinfo is not None:
             e = re.compile("zfs-bootfs=[\w\-\.\:@/]+" )
             (chosencfg["args"],count) = e.subn(zfsinfo, chosencfg["args"])
             if count == 0:
                chosencfg["args"] += " -B %s" % zfsinfo
-            sxp += "(args \"%s\")" % (chosencfg["args"])
+        args = chosencfg["args"]
+
+    if output_format == "sxp":
+        ostring = format_sxp(bootcfg["kernel"], bootcfg["ramdisk"], args)
+    elif output_format == "simple":
+        ostring = format_simple(bootcfg["kernel"], bootcfg["ramdisk"], args, "\n")
+    elif output_format == "simple0":
+        ostring = format_simple(bootcfg["kernel"], bootcfg["ramdisk"], args, "\0")
 
     sys.stdout.flush()
-    os.write(fd, sxp)
+    os.write(fd, ostring)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2 of 9] xenconsole: do not exit if a pty device is missing
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
  2010-07-12 14:01 ` [PATCH 1 of 9] pygrub: introduce easier to parse output format Ian Campbell
@ 2010-07-12 14:01 ` Ian Campbell
  2010-07-12 14:01 ` [PATCH 3 of 9] libxl: add printf attribute to libxl_xs_write and fixup resulting warnings Ian Campbell
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

this can just mean we have raced with the bootloader exiting and if we
continue we will likely see the real domain console show up.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r 988cf8dff1c0 -r 24a1b866b2d1 tools/console/client/main.c
--- a/tools/console/client/main.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/console/client/main.c	Mon Jul 12 14:56:37 2010 +0100
@@ -115,6 +115,8 @@
 			 * disambiguate: just read the pty path */
 			pty_path = xs_read(xs, XBT_NULL, path, &len);
 			if (pty_path != NULL) {
+				if (access(pty_path, R_OK|W_OK) != 0)
+					continue;
 				pty_fd = open(pty_path, O_RDWR | O_NOCTTY);
 				if (pty_fd == -1) 
 					err(errno, "Could not open tty `%s'", 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3 of 9] libxl: add printf attribute to libxl_xs_write and fixup resulting warnings
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
  2010-07-12 14:01 ` [PATCH 1 of 9] pygrub: introduce easier to parse output format Ian Campbell
  2010-07-12 14:01 ` [PATCH 2 of 9] xenconsole: do not exit if a pty device is missing Ian Campbell
@ 2010-07-12 14:01 ` Ian Campbell
  2010-07-12 14:01 ` [PATCH 4 of 9] libxl: add libxl_strdup convenience function Ian Campbell
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

There is an unfortunate warning for the empty format string by default
which I workaround by adding -Wno-format-zero-length.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r 24a1b866b2d1 -r 8545cbf7f513 tools/libxl/Makefile
--- a/tools/libxl/Makefile	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/Makefile	Mon Jul 12 14:56:37 2010 +0100
@@ -11,7 +11,7 @@
 XLUMAJOR = 1.0
 XLUMINOR = 0
 
-CFLAGS += -Werror
+CFLAGS += -Werror -Wno-format-zero-length
 CFLAGS += -I. -fPIC
 CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) $(CFLAGS_libblktapctl)
 
diff -r 24a1b866b2d1 -r 8545cbf7f513 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
@@ -523,7 +523,7 @@
         path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid);
         state = libxl_xs_read(ctx, XBT_NULL, path);
         if (state != NULL && !strcmp(state, "paused")) {
-            libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "continue", strlen("continue"));
+            libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "continue");
             libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL);
         }
     }
@@ -2663,7 +2663,7 @@
     }
 
     if (domid != 0)
-        libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/static-max", dompath), "%lu", max_memkb);
+        libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/static-max", dompath), "%"PRIu32, max_memkb);
 
     return 0;
 }
@@ -2702,14 +2702,14 @@
     videoram_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/videoram", dompath));
     videoram = videoram_s ? atoi(videoram_s) : 0;
 
-    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/target", dompath), "%lu", target_memkb);
+    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/target", dompath), "%"PRIu32, target_memkb);
 
     rc = xc_domain_getinfolist(ctx->xch, domid, 1, &info);
     if (rc != 1 || info.domain != domid)
         return rc;
     xcinfo2xlinfo(&info, &ptr);
     uuid = libxl_uuid2string(ctx, ptr.uuid);
-    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/vm/%s/memory", uuid), "%lu", target_memkb / 1024);
+    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/vm/%s/memory", uuid), "%"PRIu32, target_memkb / 1024);
 
     if (enforce || !domid)
         memorykb = target_memkb;
diff -r 24a1b866b2d1 -r 8545cbf7f513 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl_dom.c	Mon Jul 12 14:56:37 2010 +0100
@@ -247,7 +247,7 @@
         return 1;
     }
     path = libxl_sprintf(si->ctx, "%s/control/shutdown", libxl_xs_get_dompath(si->ctx, si->domid));
-    libxl_xs_write(si->ctx, XBT_NULL, path, "suspend", strlen("suspend"));
+    libxl_xs_write(si->ctx, XBT_NULL, path, "suspend");
     if (si->hvm) {
         unsigned long hvm_pvdrv, hvm_s_state;
         xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_CALLBACK_IRQ, &hvm_pvdrv);
@@ -275,7 +275,7 @@
     }
     if (!strcmp(state, "suspend")) {
         XL_LOG(si->ctx, XL_LOG_ERROR, "guest didn't suspend in time");
-        libxl_xs_write(si->ctx, XBT_NULL, path, "", 1);
+        libxl_xs_write(si->ctx, XBT_NULL, path, "");
     }
     return 1;
 }
@@ -338,7 +338,7 @@
     char *filename = libxl_sprintf(ctx, "/var/lib/xen/qemu-save.%d", domid);
 
     XL_LOG(ctx, XL_LOG_DEBUG, "Saving device model state to %s", filename);
-    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "save", strlen("save"));
+    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "save");
     libxl_wait_for_device_model(ctx, domid, "paused", NULL, NULL);
 
     c = libxl_write_exactly(ctx, fd, QEMU_SIGNATURE, strlen(QEMU_SIGNATURE),
diff -r 24a1b866b2d1 -r 8545cbf7f513 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl_internal.h	Mon Jul 12 14:56:37 2010 +0100
@@ -117,7 +117,7 @@
 int libxl_xs_writev(struct libxl_ctx *ctx, xs_transaction_t t,
                     char *dir, char **kvs);
 int libxl_xs_write(struct libxl_ctx *ctx, xs_transaction_t t,
-                   char *path, char *fmt, ...);
+                   char *path, char *fmt, ...) PRINTF_ATTRIBUTE(4, 5);
 char *libxl_xs_get_dompath(struct libxl_ctx *ctx, uint32_t domid); // logs errs
 char *libxl_xs_read(struct libxl_ctx *ctx, xs_transaction_t t, char *path);
 char **libxl_xs_directory(struct libxl_ctx *ctx, xs_transaction_t t, char *path, unsigned int *nb);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4 of 9] libxl: add libxl_strdup convenience function
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
                   ` (2 preceding siblings ...)
  2010-07-12 14:01 ` [PATCH 3 of 9] libxl: add printf attribute to libxl_xs_write and fixup resulting warnings Ian Campbell
@ 2010-07-12 14:01 ` Ian Campbell
  2010-07-12 14:01 ` [PATCH 5 of 9] libxl: fix typo Ian Campbell
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Use in preference to libxl_sprintf(..., "%s", "...")

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r 8545cbf7f513 -r 6c6961e09c50 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
@@ -1339,7 +1339,7 @@
                 flexarray_set(back, boffset++, "tapdisk-params");
                 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath));
                 flexarray_set(back, boffset++, "params");
-                flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", dev));
+                flexarray_set(back, boffset++, libxl_strdup(ctx, dev));
                 backend_type = "phy";
                 device_physdisk_major_minor(dev, &major, &minor);
                 flexarray_set(back, boffset++, "physical-device");
@@ -1467,7 +1467,7 @@
                                                  nic->mac[0], nic->mac[1], nic->mac[2],
                                                  nic->mac[3], nic->mac[4], nic->mac[5]));
     flexarray_set(back, boffset++, "bridge");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", nic->bridge));
+    flexarray_set(back, boffset++, libxl_strdup(ctx, nic->bridge));
     flexarray_set(back, boffset++, "handle");
     flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->devid));
 
@@ -2020,13 +2020,13 @@
 
     info->vnc = vfb->vnc;
     if (vfb->vnclisten)
-        info->vnclisten = libxl_sprintf(ctx, "%s", vfb->vnclisten);
+        info->vnclisten = libxl_strdup(ctx, vfb->vnclisten);
     info->vncdisplay = vfb->vncdisplay;
     info->vncunused = vfb->vncunused;
     if (vfb->vncpasswd)
         info->vncpasswd = vfb->vncpasswd;
     if (vfb->keymap)
-        info->keymap = libxl_sprintf(ctx, "%s", vfb->keymap);
+        info->keymap = libxl_strdup(ctx, vfb->keymap);
     info->sdl = vfb->sdl;
     info->opengl = vfb->opengl;
     for (i = 0; i < num_console; i++) {
@@ -2782,19 +2782,19 @@
     info->xen_version_major = xen_version >> 16;
     info->xen_version_minor = xen_version & 0xFF;
     xc_version(ctx->xch, XENVER_extraversion, &u.xen_extra);
-    info->xen_version_extra = libxl_sprintf(ctx, "%s", u.xen_extra);
+    info->xen_version_extra = libxl_strdup(ctx, u.xen_extra);
 
     xc_version(ctx->xch, XENVER_compile_info, &u.xen_cc);
-    info->compiler = libxl_sprintf(ctx, "%s", u.xen_cc.compiler);
-    info->compile_by = libxl_sprintf(ctx, "%s", u.xen_cc.compile_by);
-    info->compile_domain = libxl_sprintf(ctx, "%s", u.xen_cc.compile_domain);
-    info->compile_date = libxl_sprintf(ctx, "%s", u.xen_cc.compile_date);
+    info->compiler = libxl_strdup(ctx, u.xen_cc.compiler);
+    info->compile_by = libxl_strdup(ctx, u.xen_cc.compile_by);
+    info->compile_domain = libxl_strdup(ctx, u.xen_cc.compile_domain);
+    info->compile_date = libxl_strdup(ctx, u.xen_cc.compile_date);
 
     xc_version(ctx->xch, XENVER_capabilities, &u.xen_caps);
-    info->capabilities = libxl_sprintf(ctx, "%s", u.xen_caps);
+    info->capabilities = libxl_strdup(ctx, u.xen_caps);
 
     xc_version(ctx->xch, XENVER_changeset, &u.xen_chgset);
-    info->changeset = libxl_sprintf(ctx, "%s", u.xen_chgset);
+    info->changeset = libxl_strdup(ctx, u.xen_chgset);
 
     xc_version(ctx->xch, XENVER_platform_parameters, &u.p_parms);
     info->virt_start = u.p_parms.virt_start;
@@ -2802,7 +2802,7 @@
     info->pagesize = xc_version(ctx->xch, XENVER_pagesize, NULL);
 
     xc_version(ctx->xch, XENVER_commandline, &u.xen_commandline);
-    info->commandline = libxl_sprintf(ctx, "%s", u.xen_commandline);
+    info->commandline = libxl_strdup(ctx, u.xen_commandline);
 
     return info;
 }
diff -r 8545cbf7f513 -r 6c6961e09c50 tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl_exec.c	Mon Jul 12 14:56:37 2010 +0100
@@ -100,7 +100,7 @@
     struct libxl_spawn_starting *for_spawn = starting->for_spawn;
 
     if (for_spawn) {
-        for_spawn->what = libxl_sprintf(ctx, "%s", what);
+        for_spawn->what = libxl_strdup(ctx, what);
         if (!for_spawn->what) return ERROR_NOMEM;
     }
 
diff -r 8545cbf7f513 -r 6c6961e09c50 tools/libxl/libxl_internal.c
--- a/tools/libxl/libxl_internal.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl_internal.c	Mon Jul 12 14:56:37 2010 +0100
@@ -138,10 +138,20 @@
     return s;
 }
 
+char *libxl_strdup(struct libxl_ctx *ctx, const char *c)
+{
+    char *s = strdup(c);
+
+    if (s)
+        libxl_ptr_add(ctx, s);
+
+    return s;
+}
+
 char *libxl_dirname(struct libxl_ctx *ctx, const char *s)
 {
     char *c;
-    char *ptr = libxl_sprintf(ctx, "%s", s);
+    char *ptr = libxl_strdup(ctx, s);
 
     c = strrchr(ptr, '/');
     if (!c)
diff -r 8545cbf7f513 -r 6c6961e09c50 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl_internal.h	Mon Jul 12 14:56:37 2010 +0100
@@ -111,6 +111,7 @@
 void *libxl_zalloc(struct libxl_ctx *ctx, int bytes);
 void *libxl_calloc(struct libxl_ctx *ctx, size_t nmemb, size_t size);
 char *libxl_sprintf(struct libxl_ctx *ctx, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
+char *libxl_strdup(struct libxl_ctx *ctx, const char *c);
 char *libxl_dirname(struct libxl_ctx *ctx, const char *s);
 
 char **libxl_xs_kvs_of_flexarray(struct libxl_ctx *ctx, flexarray_t *array, int length);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 5 of 9] libxl: fix typo
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
                   ` (3 preceding siblings ...)
  2010-07-12 14:01 ` [PATCH 4 of 9] libxl: add libxl_strdup convenience function Ian Campbell
@ 2010-07-12 14:01 ` Ian Campbell
  2010-07-12 14:01 ` [PATCH 6 of 9] libxl/xl: exec xenconsole in current process, defer decision to fork to caller Ian Campbell
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r 6c6961e09c50 -r 4b41b5e7532c tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl_internal.h	Mon Jul 12 14:56:37 2010 +0100
@@ -176,7 +176,7 @@
  /* higher-level double-fork and separate detach eg as for device models */
 
 struct libxl_spawn_starting {
-    /* put this in your own stateu structure as returned to application */
+    /* put this in your own status structure as returned to application */
     /* all fields are private to libxl_spawn_... */
     pid_t intermediate;
     char *what; /* malloc'd in spawn_spawn */

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 6 of 9] libxl/xl: exec xenconsole in current process, defer decision to fork to caller
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
                   ` (4 preceding siblings ...)
  2010-07-12 14:01 ` [PATCH 5 of 9] libxl: fix typo Ian Campbell
@ 2010-07-12 14:01 ` Ian Campbell
  2010-07-12 14:01 ` [PATCH 7 of 9] libxl: support mapping files rather than carrying paths around Ian Campbell
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Use this to run xenconsole as the foreground process and move the
connection to the console in the "create -c" case early enough to be
able to view output from the bootloader. This behaviour is consistent
with how both "xm console" and "xm create -c" operate.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r 4b41b5e7532c -r bcea013ddd5a tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
@@ -786,12 +786,12 @@
     return 0;
 }
 
-int libxl_console_attach(struct libxl_ctx *ctx, uint32_t domid, int cons_num)
+int libxl_console_exec(struct libxl_ctx *ctx, uint32_t domid, int cons_num)
 {
-    char *cmd = libxl_sprintf(
-        ctx, "%s/xenconsole %d --num %d",
-        libxl_private_bindir_path(), domid, cons_num);
-    return (system(cmd) != 0) ? ERROR_FAIL : 0;
+    char *p = libxl_sprintf(ctx, "%s/xenconsole", libxl_private_bindir_path());
+    char *domid_s = libxl_sprintf(ctx, "%d", domid);
+    char *cons_num_s = libxl_sprintf(ctx, "%d", cons_num);
+    return execl(p, p, domid_s, "--num", cons_num_s, (void *)NULL) == 0 ? 0 : ERROR_FAIL;
 }
 
 static char ** libxl_build_device_model_args(struct libxl_ctx *ctx,
diff -r 4b41b5e7532c -r bcea013ddd5a tools/libxl/libxl.h
--- a/tools/libxl/libxl.h	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl.h	Mon Jul 12 14:56:37 2010 +0100
@@ -358,7 +358,7 @@
 int libxl_domain_setmaxmem(struct libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb);
 int libxl_set_memory_target(struct libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce);
 
-int libxl_console_attach(struct libxl_ctx *ctx, uint32_t domid, int cons_num);
+int libxl_console_exec(struct libxl_ctx *ctx, uint32_t domid, int cons_num);
 
 int libxl_domain_info(struct libxl_ctx*, struct libxl_dominfo *info_r,
                       uint32_t domid);
diff -r 4b41b5e7532c -r bcea013ddd5a tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c	Mon Jul 12 14:56:37 2010 +0100
@@ -931,12 +931,45 @@
     return r;
 }
 
+int autoconnect_console(int cons_num)
+{
+    int status;
+    pid_t pid, r;
+
+    /*
+     * Fork for xenconsole. We exec xenconsole in the foreground
+     * process allowing it to retain the tty. xl continues in the
+     * child. The xenconsole client uses a xenstore watch to wait for
+     * the console to be setup so there is no race.
+     */
+    pid = fork();
+    if (pid < 0) {
+        perror("unable to fork xenconsole");
+        return ERROR_FAIL;
+    } else if (pid == 0)
+        return 0;
+
+    /*
+     * Catch failure of the create process.
+     */
+    sleep(1);
+    r = waitpid(pid, &status, WNOHANG);
+    if (r > 0 && WIFEXITED(status) && WEXITSTATUS(status) != 0)
+        _exit(WEXITSTATUS(status));
+
+    libxl_console_exec(&ctx, domid, cons_num);
+    /* Do not return. xl continued in child process */
+    fprintf(stderr, "Unable to attach console\n");
+    _exit(1);
+}
+
 struct domain_create {
     int debug;
     int daemonize;
     int paused;
     int dryrun;
     int quiet;
+    int console_autoconnect;
     const char *config_file;
     const char *extra_config; /* extra config string */
     const char *restore_file;
@@ -1118,6 +1151,12 @@
         perror("cannot save config file");
         ret = ERROR_FAIL;
         goto error_out;
+    }
+
+    if (dom_info->console_autoconnect) {
+        ret = autoconnect_console(0);
+        if (ret)
+            goto error_out;
     }
 
     if (!restore_file || !need_daemon) {
@@ -1467,12 +1506,6 @@
     exit(0);
 }
 
-void console(char *p, int cons_num)
-{
-    find_domain(p);
-    libxl_console_attach(&ctx, domid, cons_num);
-}
-
 void cd_insert(char *dom, char *virtdev, char *phys)
 {
     libxl_device_disk disk;
@@ -1570,7 +1603,6 @@
 int main_console(int argc, char **argv)
 {
     int opt = 0, cons_num = 0;
-    char *p = NULL;
 
     while ((opt = getopt(argc, argv, "hn:")) != -1) {
         switch (opt) {
@@ -1592,10 +1624,10 @@
         exit(2);
     }
 
-    p = argv[optind];
-
-    console(p, cons_num);
-    exit(0);
+    find_domain(argv[optind]);
+    libxl_console_exec(&ctx, domid, 0);
+    fprintf(stderr, "Unable to attach console\n");
+    return 1;
 }
 
 void pcilist(char *dom)
@@ -2672,7 +2704,6 @@
     char *filename = NULL;
     char *p, extra_config[1024];
     struct domain_create dom_info;
-    char dom[10]; /* long enough */
     int paused = 0, debug = 0, daemonize = 1, console_autoconnect = 0,
         dryrun = 0, quite = 0;
     int opt, rc;
@@ -2747,15 +2778,11 @@
     dom_info.config_file = filename;
     dom_info.extra_config = extra_config;
     dom_info.migrate_fd = -1;
+    dom_info.console_autoconnect = console_autoconnect;
 
     rc = create_domain(&dom_info);
     if (rc < 0)
         exit(-rc);
-
-    if (console_autoconnect) {
-        snprintf(dom, sizeof(dom), "%d", rc);
-        console(dom, 0);
-    }
 
     exit(0);
 }

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 7 of 9] libxl: support mapping files rather than carrying paths around
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
                   ` (5 preceding siblings ...)
  2010-07-12 14:01 ` [PATCH 6 of 9] libxl/xl: exec xenconsole in current process, defer decision to fork to caller Ian Campbell
@ 2010-07-12 14:01 ` Ian Campbell
  2010-07-12 14:01 ` [PATCH 8 of 9] libxl: add function to attach/detach a disk to/from the local VM Ian Campbell
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

This will allow us to map and then unlink the file and therefore
delete the process on process exit or explicit unmap.

Using the mmaped versions of these files required rewriting build_pv
to use the xc_dom builder functionality directly rather than through
the xc_linux_build "compatibility layer". (The status of the
xc_linux_build interface as a compatibility layer seems a bit dubious
since all existing callers use it but if anything is going to replace
it then libxl seems like the likely candidate).

I'm not thrilled with the definition of the maps lifecycle. This could
be solved by adding a helper function to explicitly free the toplevel
structure.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r bcea013ddd5a -r 2d4475143f70 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 #include <fcntl.h>
 #include <sys/select.h>
+#include <sys/mman.h>
 #include <sys/wait.h>
 #include <signal.h>
 #include <unistd.h> /* for write, unlink and close */
@@ -291,12 +292,12 @@
         vments[i++] = "image/ostype";
         vments[i++] = "linux";
         vments[i++] = "image/kernel";
-        vments[i++] = (char*) info->kernel;
+        vments[i++] = (char*) info->kernel.path;
         vments[i++] = "start_time";
         vments[i++] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
-        if (info->u.pv.ramdisk) {
+        if (info->u.pv.ramdisk.path) {
             vments[i++] = "image/ramdisk";
-            vments[i++] = (char*) info->u.pv.ramdisk;
+            vments[i++] = (char*) info->u.pv.ramdisk.path;
         }
         if (info->u.pv.cmdline) {
             vments[i++] = "image/cmdline";
@@ -305,6 +306,10 @@
     }
     ret = build_post(ctx, domid, info, state, vments, localents);
 out:
+    libxl_file_reference_unmap(ctx, &info->kernel);
+    if (!info->hvm)
+	    libxl_file_reference_unmap(ctx, &info->u.pv.ramdisk);
+
     return ret;
 }
 
@@ -338,12 +343,12 @@
         vments[i++] = "image/ostype";
         vments[i++] = "linux";
         vments[i++] = "image/kernel";
-        vments[i++] = (char*) info->kernel;
+        vments[i++] = (char*) info->kernel.path;
         vments[i++] = "start_time";
         vments[i++] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
-        if (info->u.pv.ramdisk) {
+        if (info->u.pv.ramdisk.path) {
             vments[i++] = "image/ramdisk";
-            vments[i++] = (char*) info->u.pv.ramdisk;
+            vments[i++] = (char*) info->u.pv.ramdisk.path;
         }
         if (info->u.pv.cmdline) {
             vments[i++] = "image/cmdline";
@@ -361,6 +366,10 @@
     }
 
 out:
+    libxl_file_reference_unmap(ctx, &info->kernel);
+    if (!info->hvm)
+	    libxl_file_reference_unmap(ctx, &info->u.pv.ramdisk);
+
     esave = errno;
 
     flags = fcntl(fd, F_GETFL);
@@ -1057,9 +1066,9 @@
     b_info.max_vcpus = 1;
     b_info.max_memkb = 32 * 1024;
     b_info.target_memkb = b_info.max_memkb;
-    b_info.kernel = libxl_abs_path(ctx, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path());
+    b_info.kernel.path = libxl_abs_path(ctx, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path());
     b_info.u.pv.cmdline = libxl_sprintf(ctx, " -d %d", info->domid);
-    b_info.u.pv.ramdisk = "";
+    b_info.u.pv.ramdisk.path = "";
     b_info.u.pv.features = "";
     b_info.hvm = 0;
 
@@ -3181,3 +3190,47 @@
     return rc;
 }
 
+int libxl_file_reference_map(struct libxl_ctx *ctx, libxl_file_reference *f)
+{
+	struct stat st_buf;
+	int ret, fd;
+	void *data;
+
+	if (f->mapped)
+		return 0;
+
+	fd = open(f->path, O_RDONLY);
+	if (f < 0)
+		return ERROR_FAIL;
+
+	ret = fstat(fd, &st_buf);
+	if (ret < 0)
+		goto out;
+
+	ret = -1;
+	data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+	if (data == NULL)
+		goto out;
+
+	f->mapped = 1;
+	f->data = data;
+	f->size = st_buf.st_size;
+
+	ret = 0;
+out:
+	close(fd);
+
+	return ret == 0 ? 0 : ERROR_FAIL;
+}
+
+int libxl_file_reference_unmap(struct libxl_ctx *ctx, libxl_file_reference *f)
+{
+	int ret;
+
+	if (!f->mapped)
+		return 0;
+
+	ret = munmap(f->data, f->size);
+
+	return ret == 0 ? 0 : ERROR_FAIL;
+}
diff -r bcea013ddd5a -r 2d4475143f70 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl.h	Mon Jul 12 14:56:37 2010 +0100
@@ -90,6 +90,24 @@
 } libxl_domain_create_info;
 
 typedef struct {
+    /*
+     * Path is always set if the file refernece is valid. However if
+     * mapped is true then the actual file may already be unlinked.
+     */
+    char *path;
+    int mapped;
+    void *data;
+    size_t size;
+} libxl_file_reference;
+
+/*
+ * Instances of libxl_file_reference contained in this struct which
+ * have been mapped (with libxl_file_reference_map) will be unmapped
+ * by libxl_domain_build/restore. If either of these are never called
+ * then the user is responsible for calling
+ * libxl_file_reference_unmap.
+ */
+typedef struct {
     int max_vcpus;
     int cur_vcpus;
     int tsc_mode;
@@ -98,7 +116,7 @@
     uint32_t video_memkb;
     uint32_t shadow_memkb;
     bool disable_migrate;
-    const char *kernel;
+    libxl_file_reference kernel;
     int hvm;
     union {
         struct {
@@ -115,7 +133,7 @@
         struct {
             uint32_t   slack_memkb;
             const char *cmdline;
-            const char *ramdisk;
+            libxl_file_reference ramdisk;
             const char *features;
         } pv;
     } u;
@@ -308,6 +326,9 @@
 int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req);
 int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force);
 
+int libxl_file_reference_map(struct libxl_ctx *ctx, libxl_file_reference *f);
+int libxl_file_reference_unmap(struct libxl_ctx *ctx, libxl_file_reference *f);
+
 char *libxl_uuid2string(struct libxl_ctx *ctx, uint8_t uuid[16]);
   /* 0 means ERROR_ENOMEM, which we have logged */
 
diff -r bcea013ddd5a -r 2d4475143f70 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl_dom.c	Mon Jul 12 14:56:37 2010 +0100
@@ -143,22 +143,76 @@
     int ret;
     int flags = 0;
 
+    xc_dom_loginit(ctx->xch);
+
     dom = xc_dom_allocate(ctx->xch, info->u.pv.cmdline, info->u.pv.features);
     if (!dom) {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_allocate failed");
-        return -1;
+        return ERROR_FAIL;
     }
-    ret = xc_dom_linux_build(ctx->xch, dom, domid, info->target_memkb / 1024,
-                                  info->kernel, info->u.pv.ramdisk, flags,
-                                  state->store_port, &state->store_mfn,
-                                  state->console_port, &state->console_mfn);
-    if (ret != 0) {
-        xc_dom_release(dom);
-        XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "xc_dom_linux_build failed");
-        return -2;
+
+    if (info->kernel.mapped) {
+        if ( (ret = xc_dom_kernel_mem(dom, info->kernel.data, info->kernel.size)) != 0) {
+            XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_kernel_mem failed");
+            goto out;
+        }
+    } else {
+        if ( (ret = xc_dom_kernel_file(dom, info->kernel.path)) != 0) {
+            XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_kernel_file failed");
+            goto out;
+        }
     }
+
+    if ( info->u.pv.ramdisk.path && strlen(info->u.pv.ramdisk.path) ) {
+        if (info->u.pv.ramdisk.mapped) {
+            if ( (ret = xc_dom_ramdisk_mem(dom, info->u.pv.ramdisk.data, info->u.pv.ramdisk.size)) != 0 ) {
+                XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_ramdisk_mem failed");
+                goto out;
+            }
+        } else {
+            if ( (ret = xc_dom_ramdisk_file(dom, info->u.pv.ramdisk.path)) != 0 ) {
+                XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_ramdisk_file failed");
+                goto out;
+            }
+        }
+    }
+
+    dom->flags = flags;
+    dom->console_evtchn = state->console_port;
+    dom->xenstore_evtchn = state->store_port;
+
+    if ( (ret = xc_dom_boot_xen_init(dom, ctx->xch, domid)) != 0 ) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_boot_xen_init failed");
+        goto out;
+    }
+    if ( (ret = xc_dom_parse_image(dom)) != 0 ) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_parse_image failed");
+        goto out;
+    }
+    if ( (ret = xc_dom_mem_init(dom, info->target_memkb / 1024)) != 0 ) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_mem_init failed");
+        goto out;
+    }
+    if ( (ret = xc_dom_boot_mem_init(dom)) != 0 ) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_boot_mem_init failed");
+        goto out;
+    }
+    if ( (ret = xc_dom_build_image(dom)) != 0 ) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_build_image failed");
+        goto out;
+    }
+    if ( (ret = xc_dom_boot_image(dom)) != 0 ) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_boot_image failed");
+        goto out;
+    }
+
+    state->console_mfn = xc_dom_p2m_host(dom, dom->console_pfn);
+    state->store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn);
+
+    ret = 0;
+out:
     xc_dom_release(dom);
-    return 0;
+    return ret == 0 ? 0 : ERROR_FAIL;
 }
 
 int build_hvm(struct libxl_ctx *ctx, uint32_t domid,
@@ -166,12 +220,17 @@
 {
     int ret;
 
+    if (info->kernel.mapped) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "build_hvm kernel cannot be mmapped");
+        return ERROR_INVAL;
+    }
+
     ret = xc_hvm_build_target_mem(
         ctx->xch,
         domid,
         (info->max_memkb - info->video_memkb) / 1024,
         (info->target_memkb - info->video_memkb) / 1024,
-        libxl_abs_path(ctx, (char *)info->kernel,
+        libxl_abs_path(ctx, (char *)info->kernel.path,
                        libxl_xenfirmwaredir_path()));
     if (ret) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "hvm building failed");
diff -r bcea013ddd5a -r 2d4475143f70 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c	Mon Jul 12 14:56:37 2010 +0100
@@ -196,7 +196,7 @@
     if (c_info->hvm) {
         b_info->shadow_memkb = 0; /* Set later */
         b_info->video_memkb = 8 * 1024;
-        b_info->kernel = "hvmloader";
+        b_info->kernel.path = "hvmloader";
         b_info->hvm = 1;
         b_info->u.hvm.pae = 1;
         b_info->u.hvm.apic = 1;
@@ -366,7 +366,7 @@
     printf("\t(image\n");
     if (c_info->hvm) {
         printf("\t\t(hvm\n");
-        printf("\t\t\t(loader %s)\n", b_info->kernel);
+        printf("\t\t\t(loader %s)\n", b_info->kernel.path);
         printf("\t\t\t(video_memkb %d)\n", b_info->video_memkb);
         printf("\t\t\t(shadow_memkb %d)\n", b_info->shadow_memkb);
         printf("\t\t\t(pae %d)\n", b_info->u.hvm.pae);
@@ -397,9 +397,9 @@
         printf("\t\t)\n");
     } else {
         printf("\t\t(linux %d)\n", b_info->hvm);
-        printf("\t\t\t(kernel %s)\n", b_info->kernel);
+        printf("\t\t\t(kernel %s)\n", b_info->kernel.path);
         printf("\t\t\t(cmdline %s)\n", b_info->u.pv.cmdline);
-        printf("\t\t\t(ramdisk %s)\n", b_info->u.pv.ramdisk);
+        printf("\t\t\t(ramdisk %s)\n", b_info->u.pv.ramdisk.path);
         printf("\t\t)\n");
     }
     printf("\t)\n");
@@ -563,7 +563,7 @@
         b_info->video_memkb = l * 1024;
 
     if (!xlu_cfg_get_string (config, "kernel", &buf))
-        b_info->kernel = strdup(buf);
+        b_info->kernel.path = strdup(buf);
 
     if (c_info->hvm == 1) {
         if (!xlu_cfg_get_long (config, "pae", &l))
@@ -603,7 +603,7 @@
 
         b_info->u.pv.cmdline = cmdline;
         if (!xlu_cfg_get_string (config, "ramdisk", &buf))
-            b_info->u.pv.ramdisk = strdup(buf);
+            b_info->u.pv.ramdisk.path = strdup(buf);
     }
 
     if (!xlu_cfg_get_list (config, "disk", &vbds, 0)) {
diff -r bcea013ddd5a -r 2d4475143f70 tools/ocaml/libs/xl/xl_stubs.c
--- a/tools/ocaml/libs/xl/xl_stubs.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/ocaml/libs/xl/xl_stubs.c	Mon Jul 12 14:56:37 2010 +0100
@@ -103,7 +103,7 @@
 	c_val->target_memkb = Int64_val(Field(v, 6));
 	c_val->video_memkb = Int64_val(Field(v, 7));
 	c_val->shadow_memkb = Int64_val(Field(v, 8));
-	c_val->kernel = String_val(Field(v, 9));
+	c_val->kernel.path = String_val(Field(v, 9));
 	c_val->hvm = Tag_val(Field(v, 10)) == 0;
 	infopriv = Field(Field(v, 10), 0);
 	if (c_val->hvm) {
@@ -119,7 +119,7 @@
 	} else {
 		c_val->u.pv.slack_memkb = Int64_val(Field(infopriv, 0));
 		c_val->u.pv.cmdline = String_val(Field(infopriv, 1));
-		c_val->u.pv.ramdisk = String_val(Field(infopriv, 2));
+		c_val->u.pv.ramdisk.path = String_val(Field(infopriv, 2));
 		c_val->u.pv.features = String_val(Field(infopriv, 3));
 	}

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 8 of 9] libxl: add function to attach/detach a disk to/from the local VM
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
                   ` (6 preceding siblings ...)
  2010-07-12 14:01 ` [PATCH 7 of 9] libxl: support mapping files rather than carrying paths around Ian Campbell
@ 2010-07-12 14:01 ` Ian Campbell
  2010-07-12 14:01 ` [PATCH 9 of 9] libxl/xl: support running bootloader (e.g. pygrub) in domain 0 Ian Campbell
  2010-07-13 18:23 ` [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Jackson
  9 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Useful if you need to read a guest filesystem (e.g. pygrub).

I'm not overly thrilled with the implementation WRT tap interfaces,
particularly WRT to detach. I was unable to find a way to get at the
paramters necessary to call tap_ctl_destroy so I assumed for now it
that is OK to assume that the tap device is going to be wanted for the
actual domain at some point in the immediate future and hence there is
no pressing need to destroy it.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r 2d4475143f70 -r 769e3bc13a6b tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl.c	Mon Jul 12 14:56:37 2010 +0100
@@ -1425,6 +1425,48 @@
     return libxl_device_del(ctx, &device, wait);
 }
 
+const char * libxl_device_disk_local_attach(struct libxl_ctx *ctx, libxl_device_disk *disk)
+{
+    char *dev = NULL;
+    int phystype = disk->phystype;
+    switch (phystype) {
+        case PHYSTYPE_PHY: {
+            fprintf(stderr, "attaching PHY disk %s to domain 0\n", disk->physpath);
+            dev = disk->physpath;
+            break;
+        }
+        case PHYSTYPE_FILE:
+            /* let's pretend is tap:aio for the moment */
+            phystype = PHYSTYPE_AIO;
+        case PHYSTYPE_AIO: case PHYSTYPE_QCOW: case PHYSTYPE_QCOW2: case PHYSTYPE_VHD: {
+            const char *msg;
+            if (!tap_ctl_check(&msg)) {
+                const char *type = device_disk_string_of_phystype(phystype);
+                dev = get_blktap2_device(ctx, disk->physpath, type);
+                if (!dev)
+                    dev = make_blktap2_device(ctx, disk->physpath, type);
+            }
+            break;
+        }
+        default:
+            XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", phystype);
+            break;
+    }
+    return dev;
+}
+
+int libxl_device_disk_local_detach(struct libxl_ctx *ctx, libxl_device_disk *disk)
+{
+    /* Nothing to do for PHYSTYPE_PHY. */
+
+    /*
+     * For other device types assume that the blktap2 process is
+     * needed by the soon to be started domain and do nothing.
+     */
+
+    return 0;
+}
+
 /******************************************************************************/
 int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic)
 {
diff -r 2d4475143f70 -r 769e3bc13a6b tools/libxl/libxl.h
--- a/tools/libxl/libxl.h	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl.h	Mon Jul 12 14:56:37 2010 +0100
@@ -423,6 +423,12 @@
                               libxl_device_disk *disk, libxl_diskinfo *diskinfo);
 int libxl_cdrom_insert(struct libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk);
 
+/*
+ * Make a disk available in this domain. Returns path to a device.
+ */
+const char * libxl_device_disk_local_attach(struct libxl_ctx *ctx, libxl_device_disk *disk);
+int libxl_device_disk_local_detach(struct libxl_ctx *ctx, libxl_device_disk *disk);
+
 typedef struct {
     char *backend;
     uint32_t backend_id;

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 9 of 9] libxl/xl: support running bootloader (e.g. pygrub) in domain 0
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
                   ` (7 preceding siblings ...)
  2010-07-12 14:01 ` [PATCH 8 of 9] libxl: add function to attach/detach a disk to/from the local VM Ian Campbell
@ 2010-07-12 14:01 ` Ian Campbell
  2010-07-13 18:23 ` [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Jackson
  9 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2010-07-12 14:01 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Much of the bootloader interaction (including the Solaris and NetBSD
portability bits) are translated pretty much directly from the python
in tools/python/xen/xend/XendBootloader.py

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r 769e3bc13a6b -r 5ce5fe094152 tools/libxl/Makefile
--- a/tools/libxl/Makefile	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/Makefile	Mon Jul 12 15:01:23 2010 +0100
@@ -15,9 +15,9 @@
 CFLAGS += -I. -fPIC
 CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) $(CFLAGS_libblktapctl)
 
-LIBS = $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenguest) $(LDFLAGS_libxenstore) $(LDFLAGS_libblktapctl)
+LIBS = $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenguest) $(LDFLAGS_libxenstore) $(LDFLAGS_libblktapctl) -lutil
 
-LIBXL_OBJS-y = osdeps.o libxl_paths.o
+LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o
 LIBXL_OBJS = flexarray.o libxl.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o xenguest.o libxl_utils.o $(LIBXL_OBJS-y)
 
 AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
diff -r 769e3bc13a6b -r 5ce5fe094152 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/libxl.h	Mon Jul 12 15:01:23 2010 +0100
@@ -132,7 +132,9 @@
         } hvm;
         struct {
             uint32_t   slack_memkb;
-            const char *cmdline;
+            const char *bootloader;
+            const char *bootloader_args;
+            char *cmdline;
             libxl_file_reference ramdisk;
             const char *features;
         } pv;
@@ -329,6 +331,23 @@
 int libxl_file_reference_map(struct libxl_ctx *ctx, libxl_file_reference *f);
 int libxl_file_reference_unmap(struct libxl_ctx *ctx, libxl_file_reference *f);
 
+/*
+ * Run the configured bootloader for a PV domain and update
+ * info->kernel, info->u.pv.ramdisk and info->u.pv.cmdline as
+ * appropriate (any initial values present in these fields must have
+ * been allocated with malloc).
+ *
+ * Is a NOP on non-PV domains or those with no bootloader configured.
+ *
+ * Users should call libxl_file_reference_unmap on the kernel and
+ * ramdisk to cleanup or rely on libxl_domain_{build,restore} to do
+ * it.
+ */
+int libxl_run_bootloader(struct libxl_ctx *ctx,
+                         libxl_domain_build_info *info,
+                         libxl_device_disk *disk,
+                         uint32_t domid);
+
 char *libxl_uuid2string(struct libxl_ctx *ctx, uint8_t uuid[16]);
   /* 0 means ERROR_ENOMEM, which we have logged */
 
diff -r 769e3bc13a6b -r 5ce5fe094152 tools/libxl/libxl_bootloader.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_bootloader.c	Mon Jul 12 15:01:23 2010 +0100
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Ian Campbell <ian.campbell@citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_osdeps.h"
+
+#include <string.h>
+#include <pty.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "libxl.h"
+#include "libxl_internal.h"
+
+#include "flexarray.h"
+
+#define XENCONSOLED_BUF_SIZE 16
+#define BOOTLOADER_BUF_SIZE 1024
+
+static char **make_bootloader_args(struct libxl_ctx *ctx,
+                                   libxl_domain_build_info *info,
+                                   uint32_t domid,
+                                   const char *fifo, const char *disk)
+{
+    flexarray_t *args;
+    int nr = 0;
+
+    args = flexarray_make(1, 1);
+    if (!args)
+        return NULL;
+
+    flexarray_set(args, nr++, (char *)info->u.pv.bootloader);
+
+    if (info->kernel.path)
+        flexarray_set(args, nr++, libxl_sprintf(ctx, "--kernel=%s", info->kernel.path));
+    if (info->u.pv.ramdisk.path)
+        flexarray_set(args, nr++, libxl_sprintf(ctx, "--ramdisk=%s", info->u.pv.ramdisk.path));
+    if (info->u.pv.cmdline && *info->u.pv.cmdline != '\0')
+        flexarray_set(args, nr++, libxl_sprintf(ctx, "--args=%s", info->u.pv.cmdline));
+
+    flexarray_set(args, nr++, libxl_sprintf(ctx, "--output=%s", fifo));
+    flexarray_set(args, nr++, "--output-format=simple0");
+    flexarray_set(args, nr++, libxl_sprintf(ctx, "--output-directory=%s", "/var/run/libxl/"));
+
+    if (info->u.pv.bootloader_args) {
+        char *saveptr;
+        /* Operate on a duplicate since strtok modifes the argument */
+        char *dup = libxl_strdup(ctx, info->u.pv.bootloader_args);
+        char *t = strtok_r(dup, " \t\n", &saveptr);
+        do {
+            flexarray_set(args, nr++, t);
+        } while ((t = strtok_r(NULL, " \t\n", &saveptr)));
+    }
+
+    flexarray_set(args, nr++, strdup(disk));
+
+    /* Sentinal for execv */
+    flexarray_set(args, nr++, NULL);
+
+    return (char **) flexarray_contents(args); /* Frees args */
+}
+
+static int open_xenconsoled_pty(int *master, int *slave, char *slave_path, size_t slave_path_len)
+{
+    struct termios termattr;
+    int ret;
+
+    ret = openpty(master, slave, NULL, NULL, NULL);
+    if (ret < 0)
+	    return -1;
+
+    ret = ttyname_r(*slave, slave_path, slave_path_len);
+    if (ret == -1) {
+	    close(*master);
+	    close(*slave);
+	    *master = *slave = -1;
+	    return -1;
+    }
+
+    /*
+     * On Solaris, the pty master side will get cranky if we try
+     * to write to it while there is no slave. To work around this,
+     * keep the slave descriptor open until we're done. Set it
+     * to raw terminal parameters, otherwise it will echo back
+     * characters, which will confuse the I/O loop below.
+     * Furthermore, a raw master pty device has no terminal
+     * semantics on Solaris, so don't try to set any attributes
+     * for it.
+     */
+#if !defined(__sun__) && !defined(__NetBSD__)
+    tcgetattr(*master, &termattr);
+    cfmakeraw(&termattr);
+    tcsetattr(*master, TCSANOW, &termattr);
+
+    close(*slave);
+    *slave = -1;
+#else
+    tcgetattr(*slave, &termattr);
+    cfmakeraw(&termattr);
+    tcsetattr(*slave, TCSANOW, &termattr);
+#endif
+
+    fcntl(*master, F_SETFL, O_NDELAY);
+
+    return 0;
+}
+
+static pid_t fork_exec_bootloader(int *master, char *arg0, char **args)
+{
+    struct termios termattr;
+    pid_t pid = forkpty(master, NULL, NULL, NULL);
+    if (pid == -1)
+        return -1;
+    else if (pid == 0) {
+        setenv("TERM", "vt100", 1);
+        libxl_exec(-1, -1, -1, arg0, args);
+        return -1;
+    }
+
+    /*
+     * On Solaris, the master pty side does not have terminal semantics,
+     * so don't try to set any attributes, as it will fail.
+     */
+#if !defined(__sun__)
+    tcgetattr(*master, &termattr);
+    cfmakeraw(&termattr);
+    tcsetattr(*master, TCSANOW, &termattr);
+#endif
+
+    fcntl(*master, F_SETFL, O_NDELAY);
+
+    return pid;
+}
+
+/*
+ * filedescriptors:
+ *   fifo_fd        - bootstring output from the bootloader
+ *   xenconsoled_fd - input/output from/to xenconsole
+ *   bootloader_fd  - input/output from/to pty that controls the bootloader
+ * The filedescriptors are NDELAY, so it's ok to try to read
+ * bigger chunks than may be available, to keep e.g. curses
+ * screen redraws in the bootloader efficient. xenconsoled_fd is the side that
+ * gets xenconsole input, which will be keystrokes, so a small number
+ * is sufficient. bootloader_fd is pygrub output, which will be curses screen
+ * updates, so a larger number (1024) is appropriate there.
+ *
+ * For writeable descriptors, only include them in the set for select
+ * if there is actual data to write, otherwise this would loop too fast,
+ * eating up CPU time.
+ */
+static char * bootloader_interact(struct libxl_ctx *ctx, int xenconsoled_fd, int bootloader_fd, int fifo_fd)
+{
+    int ret;
+
+    size_t nr_out = 0, size_out = 0;
+    char *output = NULL;
+
+    /* input from xenconsole. read on xenconsoled_fd write to bootloader_fd */
+    int xenconsoled_prod = 0, xenconsoled_cons = 0;
+    char xenconsoled_buf[XENCONSOLED_BUF_SIZE];
+    /* output from bootloader. read on bootloader_fd write to xenconsoled_fd */
+    int bootloader_prod = 0, bootloader_cons = 0;
+    char bootloader_buf[BOOTLOADER_BUF_SIZE];
+
+    while(1) {
+        fd_set wsel, rsel;
+        int nfds;
+
+        if (xenconsoled_prod == xenconsoled_cons)
+            xenconsoled_prod = xenconsoled_cons = 0;
+        if (bootloader_prod == bootloader_cons)
+            bootloader_prod = bootloader_cons = 0;
+
+        FD_ZERO(&rsel);
+        FD_SET(fifo_fd, &rsel);
+        nfds = fifo_fd + 1;
+        if (xenconsoled_prod == 0 || (xenconsoled_prod < BOOTLOADER_BUF_SIZE && xenconsoled_cons == 0)) {
+            FD_SET(xenconsoled_fd, &rsel);
+            nfds = xenconsoled_fd + 1 > nfds ? xenconsoled_fd + 1 : nfds;
+        }
+        if (bootloader_prod == 0 || (bootloader_prod < BOOTLOADER_BUF_SIZE && bootloader_cons == 0)) {
+            FD_SET(bootloader_fd, &rsel);
+            nfds = bootloader_fd + 1 > nfds ? bootloader_fd + 1 : nfds;
+        }
+
+        FD_ZERO(&wsel);
+        if (bootloader_prod != bootloader_cons) {
+            FD_SET(xenconsoled_fd, &wsel);
+            nfds = xenconsoled_fd + 1 > nfds ? xenconsoled_fd + 1 : nfds;
+        }
+        if (xenconsoled_prod != xenconsoled_cons) {
+            FD_SET(bootloader_fd, &wsel);
+            nfds = bootloader_fd + 1 > nfds ? bootloader_fd + 1 : nfds;
+        }
+
+        ret = select(nfds, &rsel, &wsel, NULL, NULL);
+        if (ret < 0)
+            goto out_err;
+
+        /* Input from xenconsole, read xenconsoled_fd, write bootloader_fd */
+        if (FD_ISSET(xenconsoled_fd, &rsel)) {
+            ret = read(xenconsoled_fd, &xenconsoled_buf[xenconsoled_prod], XENCONSOLED_BUF_SIZE - xenconsoled_prod);
+            if (ret < 0 && errno != EIO && errno != EAGAIN)
+                goto out_err;
+            if (ret > 0)
+                xenconsoled_prod += ret;
+        }
+        if (FD_ISSET(bootloader_fd, &wsel)) {
+            ret = write(bootloader_fd, &xenconsoled_buf[xenconsoled_cons], xenconsoled_prod - xenconsoled_cons);
+            if (ret < 0 && errno != EIO && errno != EAGAIN)
+                goto out_err;
+            if (ret > 0)
+                xenconsoled_cons += ret;
+        }
+
+        /* Input from bootloader, read bootloader_fd, write xenconsoled_fd */
+        if (FD_ISSET(bootloader_fd, &rsel)) {
+            ret = read(bootloader_fd, &bootloader_buf[bootloader_prod], BOOTLOADER_BUF_SIZE - bootloader_prod);
+            if (ret < 0 && errno != EIO && errno != EAGAIN)
+                goto out_err;
+            if (ret > 0)
+                bootloader_prod += ret;
+        }
+        if (FD_ISSET(xenconsoled_fd, &wsel)) {
+            ret = write(xenconsoled_fd, &bootloader_buf[bootloader_cons], bootloader_prod - bootloader_cons);
+            if (ret < 0 && errno != EIO && errno != EAGAIN)
+                goto out_err;
+            if (ret > 0)
+                bootloader_cons += ret;
+        }
+
+        if (FD_ISSET(fifo_fd, &rsel)) {
+            if (size_out - nr_out < 256) {
+                char *temp;
+                size_t new_size = size_out == 0 ? 32 : size_out * 2;
+
+                temp = realloc(output, new_size);
+                if (temp == NULL)
+                    goto out_err;
+                output = temp;
+                memset(output + size_out, new_size - size_out, 0);
+                size_out = new_size;
+            }
+
+            ret = read(fifo_fd, output + nr_out, size_out - nr_out);
+            if (ret > 0)
+                  nr_out += ret;
+            if (ret == 0)
+                break;
+        }
+    }
+
+    libxl_ptr_add(ctx, output);
+    return output;
+
+out_err:
+    free(output);
+    return NULL;
+}
+
+static void parse_bootloader_result(struct libxl_ctx *ctx,
+                                    libxl_domain_build_info *info,
+                                    const char *o)
+{
+    while (*o != '\0') {
+        if (strncmp("kernel ", o, strlen("kernel ")) == 0) {
+            free(info->kernel.path);
+            info->kernel.path = strdup(o + strlen("kernel "));
+            libxl_file_reference_map(ctx, &info->kernel);
+            unlink(info->kernel.path);
+        } else if (strncmp("ramdisk ", o, strlen("ramdisk ")) == 0) {
+            free(info->u.pv.ramdisk.path);
+            info->u.pv.ramdisk.path = strdup(o + strlen("ramdisk "));
+            libxl_file_reference_map(ctx, &info->u.pv.ramdisk);
+            unlink(info->u.pv.ramdisk.path);
+        } else if (strncmp("args ", o, strlen("args ")) == 0) {
+            free(info->u.pv.cmdline);
+            info->u.pv.cmdline = strdup(o + strlen("args "));
+        }
+
+        o = o + strlen(o) + 1;
+    }
+}
+
+int libxl_run_bootloader(struct libxl_ctx *ctx,
+                         libxl_domain_build_info *info,
+                         libxl_device_disk *disk,
+                         uint32_t domid)
+{
+    int ret;
+
+    char *fifo = NULL;
+    const char *diskpath = NULL;
+    char **args = NULL;
+
+    char tempdir_template[] = "/var/run/libxl/bl.XXXXXX";
+    char *tempdir;
+
+    char *dom_console_xs_path;
+    char dom_console_slave_tty_path[PATH_MAX];
+
+    int xenconsoled_fd = -1, xenconsoled_slave = -1;
+    int bootloader_fd = -1, fifo_fd = -1;
+
+    int blrc;
+    pid_t pid;
+    char *blout;
+
+    struct stat st_buf;
+
+    if (info->hvm || !info->u.pv.bootloader)
+        return 0;
+
+    if (!disk)
+        return ERROR_INVAL;
+
+    ret = mkdir("/var/run/libxl/", S_IRWXU);
+    if (ret < 0 && errno != EEXIST)
+        return ERROR_FAIL;
+
+    ret = stat("/var/run/libxl/", &st_buf);
+    if (ret < 0)
+        return ERROR_FAIL;
+
+    if (!S_ISDIR(st_buf.st_mode))
+        return ERROR_FAIL;
+
+    tempdir = mkdtemp(tempdir_template);
+    if (tempdir == NULL)
+        return ERROR_FAIL;
+
+    ret = asprintf(&fifo, "%s/fifo", tempdir);
+    if (ret < 0) {
+        ret = ERROR_FAIL;
+        fifo = NULL;
+        goto out;
+    }
+
+    ret = mkfifo(fifo, 0600);
+    if (ret < 0) {
+        ret = ERROR_FAIL;
+        goto out;
+    }
+
+    diskpath = libxl_device_disk_local_attach(ctx, disk);
+    if (!diskpath) {
+        ret = ERROR_FAIL;
+        goto out;
+    }
+
+    args = make_bootloader_args(ctx, info, domid, fifo, diskpath);
+    if (args == NULL) {
+        ret = ERROR_NOMEM;
+        goto out;
+    }
+
+    /*
+     * We need to present the bootloader's tty as a pty slave that xenconsole
+     * can access.  Since the bootloader itself needs a pty slave,
+     * we end up with a connection like this:
+     *
+     * xenconsole -- (slave pty1 master) <-> (master pty2 slave) -- bootloader
+     *
+     * where we copy characters between the two master fds, as well as
+     * listening on the bootloader's fifo for the results.
+     */
+    ret = open_xenconsoled_pty(&xenconsoled_fd, &xenconsoled_slave,
+                               &dom_console_slave_tty_path[0],
+                               sizeof(dom_console_slave_tty_path));
+    if (ret < 0) {
+        ret = ERROR_FAIL;
+        goto out;
+    }
+
+    dom_console_xs_path = libxl_sprintf(ctx, "%s/serial/0/tty", libxl_xs_get_dompath(ctx, domid));
+    libxl_xs_write(ctx, XBT_NULL, dom_console_xs_path, dom_console_slave_tty_path);
+
+    pid = fork_exec_bootloader(&bootloader_fd, (char *)info->u.pv.bootloader, args);
+    if (pid < 0) {
+        ret = ERROR_FAIL;
+        goto out;
+    }
+
+    while (1) {
+        fifo_fd = open(fifo, O_RDONLY);
+        if (fifo_fd > -1)
+            break;
+
+        if (errno == EINTR)
+            continue;
+
+        ret = ERROR_FAIL;
+        goto out;
+    }
+
+    fcntl(fifo_fd, F_SETFL, O_NDELAY);
+
+    blout = bootloader_interact(ctx, xenconsoled_fd, bootloader_fd, fifo_fd);
+    if (blout == NULL) {
+        ret = ERROR_FAIL;
+        goto out;
+    }
+
+    pid = waitpid(pid, &blrc, 0);
+    if (pid == -1 || (pid > 0 && WIFEXITED(blrc) && WEXITSTATUS(blrc) != 0)) {
+        ret = ERROR_FAIL;
+        goto out;
+    }
+
+    libxl_device_disk_local_detach(ctx, disk);
+
+    parse_bootloader_result(ctx, info, blout);
+
+    ret = 0;
+out:
+    if (fifo_fd > -1)
+        close(fifo_fd);
+    if (bootloader_fd > -1)
+        close(bootloader_fd);
+    if (xenconsoled_fd > -1)
+        close(xenconsoled_fd);
+    if (xenconsoled_slave > -1)
+        close(xenconsoled_fd);
+
+    if (fifo) {
+        unlink(fifo);
+        free(fifo);
+    }
+
+    rmdir(tempdir);
+
+    free(args);
+
+    return ret;
+}
+
diff -r 769e3bc13a6b -r 5ce5fe094152 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Mon Jul 12 14:56:37 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c	Mon Jul 12 15:01:23 2010 +0100
@@ -363,6 +363,12 @@
     printf("\t(target_memkb %d)\n", b_info->target_memkb);
     printf("\t(nomigrate %d)\n", b_info->disable_migrate);
 
+    if (!c_info->hvm && b_info->u.pv.bootloader) {
+        printf("\t(bootloader %s)\n", b_info->u.pv.bootloader);
+        if (b_info->u.pv.bootloader_args)
+            printf("\t(bootloader_args %s)\n", b_info->u.pv.bootloader_args);
+    }
+
     printf("\t(image\n");
     if (c_info->hvm) {
         printf("\t\t(hvm\n");
@@ -598,6 +604,16 @@
 
         if ((root || extra) && !cmdline) {
             fprintf(stderr, "Failed to allocate memory for cmdline\n");
+            exit(1);
+        }
+
+        if (!xlu_cfg_get_string (config, "bootloader", &buf))
+            b_info->u.pv.bootloader = strdup(buf);
+        if (!xlu_cfg_get_string (config, "bootloader_args", &buf))
+            b_info->u.pv.bootloader_args = strdup(buf);
+
+        if (!b_info->u.pv.bootloader && !b_info->kernel.path) {
+            fprintf(stderr, "Neither kernel nor bootloader specified\n");
             exit(1);
         }
 
@@ -1159,6 +1175,12 @@
             goto error_out;
     }
 
+    ret = libxl_run_bootloader(&ctx, &info2, num_disks > 0 ? &disks[0] : NULL, domid);
+    if (ret) {
+        fprintf(stderr, "failed to run bootloader: %d\n", ret);
+        goto error_out;
+    }
+
     if (!restore_file || !need_daemon) {
         if (dm_info.saved_state) {
             free(dm_info.saved_state);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub)
  2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
                   ` (8 preceding siblings ...)
  2010-07-12 14:01 ` [PATCH 9 of 9] libxl/xl: support running bootloader (e.g. pygrub) in domain 0 Ian Campbell
@ 2010-07-13 18:23 ` Ian Jackson
  2010-07-14  1:24   ` Zhigang Wang
  9 siblings, 1 reply; 12+ messages in thread
From: Ian Jackson @ 2010-07-13 18:23 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

Ian Campbell writes ("[Xen-devel] [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub)"):
> This series adds support to libxl/xl for running a domain 0
> bootloader (such as pygrub).

Does anyone have any comments on this ?  It all looks reasonable to me
but I haven't reviewed every line.  If no-one objects I will apply the
whole series tomorrow.

Ian.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub)
  2010-07-13 18:23 ` [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Jackson
@ 2010-07-14  1:24   ` Zhigang Wang
  0 siblings, 0 replies; 12+ messages in thread
From: Zhigang Wang @ 2010-07-14  1:24 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel, Ian Campbell

On 07/14/2010 02:23 AM, Ian Jackson wrote:
> Ian Campbell writes ("[Xen-devel] [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub)"):
>> This series adds support to libxl/xl for running a domain 0
>> bootloader (such as pygrub).
> 
> Does anyone have any comments on this ?  It all looks reasonable to me
> but I haven't reviewed every line.  If no-one objects I will apply the
> whole series tomorrow.
> 
> Ian.

It's really a necessary feature for xl. I'm happy to test it after you merge it.

Thanks,

Zhigang

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2010-07-14  1:24 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-12 14:01 [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Campbell
2010-07-12 14:01 ` [PATCH 1 of 9] pygrub: introduce easier to parse output format Ian Campbell
2010-07-12 14:01 ` [PATCH 2 of 9] xenconsole: do not exit if a pty device is missing Ian Campbell
2010-07-12 14:01 ` [PATCH 3 of 9] libxl: add printf attribute to libxl_xs_write and fixup resulting warnings Ian Campbell
2010-07-12 14:01 ` [PATCH 4 of 9] libxl: add libxl_strdup convenience function Ian Campbell
2010-07-12 14:01 ` [PATCH 5 of 9] libxl: fix typo Ian Campbell
2010-07-12 14:01 ` [PATCH 6 of 9] libxl/xl: exec xenconsole in current process, defer decision to fork to caller Ian Campbell
2010-07-12 14:01 ` [PATCH 7 of 9] libxl: support mapping files rather than carrying paths around Ian Campbell
2010-07-12 14:01 ` [PATCH 8 of 9] libxl: add function to attach/detach a disk to/from the local VM Ian Campbell
2010-07-12 14:01 ` [PATCH 9 of 9] libxl/xl: support running bootloader (e.g. pygrub) in domain 0 Ian Campbell
2010-07-13 18:23 ` [PATCH 0 of 9] libxl/xl: support for domain 0 bootloader (e.g. pygrub) Ian Jackson
2010-07-14  1:24   ` Zhigang Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.