X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fguestfs.c;h=b30ade06e3aed24ecbca3764eb1e8a2b177603ea;hp=be7b0c794e6117b904419d31b2bf49f55e1c145a;hb=d901cc916102f1aaccfb73396b48aa303e5b8cd7;hpb=33377fc61d4356a0e83cf7ef39d545842647481c diff --git a/src/guestfs.c b/src/guestfs.c index be7b0c7..b30ade0 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -158,8 +158,9 @@ struct guestfs_h int verbose; int autosync; - const char *path; - const char *qemu; + char *path; /* Path to kernel, initrd. */ + char *qemu; /* Qemu binary. */ + char *append; /* Append to kernel command line. */ char *last_error; @@ -220,10 +221,18 @@ guestfs_create (void) g->verbose = str != NULL && strcmp (str, "1") == 0; str = getenv ("LIBGUESTFS_PATH"); - g->path = str != NULL ? str : GUESTFS_DEFAULT_PATH; + g->path = str != NULL ? strdup (str) : strdup (GUESTFS_DEFAULT_PATH); + if (!g->path) goto error; str = getenv ("LIBGUESTFS_QEMU"); - g->qemu = str != NULL ? str : QEMU; + g->qemu = str != NULL ? strdup (str) : strdup (QEMU); + if (!g->qemu) goto error; + + str = getenv ("LIBGUESTFS_APPEND"); + if (str) { + g->append = strdup (str); + if (!g->append) goto error; + } g->main_loop = guestfs_get_default_main_loop (); @@ -248,6 +257,13 @@ guestfs_create (void) fprintf (stderr, "new guestfs handle %p\n", g); return g; + + error: + free (g->path); + free (g->qemu); + free (g->append); + free (g); + return NULL; } void @@ -308,7 +324,12 @@ guestfs_close (guestfs_h *g) } /* release mutex (XXX) */ + free (g->msg_in); + free (g->msg_out); free (g->last_error); + free (g->path); + free (g->qemu); + free (g->append); free (g); } @@ -509,10 +530,12 @@ guestfs_get_autosync (guestfs_h *g) int guestfs_set_path (guestfs_h *g, const char *path) { - if (path == NULL) - g->path = GUESTFS_DEFAULT_PATH; - else - g->path = path; + free (g->path); + g->path = NULL; + + g->path = + path == NULL ? + safe_strdup (g, GUESTFS_DEFAULT_PATH) : safe_strdup (g, path); return 0; } @@ -525,10 +548,10 @@ guestfs_get_path (guestfs_h *g) int guestfs_set_qemu (guestfs_h *g, const char *qemu) { - if (qemu == NULL) - g->qemu = QEMU; - else - g->qemu = qemu; + free (g->qemu); + g->qemu = NULL; + + g->qemu = qemu == NULL ? safe_strdup (g, QEMU) : safe_strdup (g, qemu); return 0; } @@ -538,6 +561,22 @@ guestfs_get_qemu (guestfs_h *g) return g->qemu; } +int +guestfs_set_append (guestfs_h *g, const char *append) +{ + free (g->append); + g->append = NULL; + + g->append = append ? safe_strdup (g, append) : NULL; + return 0; +} + +const char * +guestfs_get_append (guestfs_h *g) +{ + return g->append; +} + /* Add a string to the current command line. */ static void incr_cmdline_size (guestfs_h *g) @@ -753,7 +792,7 @@ guestfs_launch (guestfs_h *g) /* Set up the full command line. Do this in the subprocess so we * don't need to worry about cleaning up. */ - g->cmdline[0] = (char *) g->qemu; + g->cmdline[0] = g->qemu; /* Construct the -net channel parameter for qemu. */ snprintf (vmchannel, sizeof vmchannel, @@ -762,9 +801,10 @@ guestfs_launch (guestfs_h *g) /* Linux kernel command line. */ snprintf (append, sizeof append, - "panic=1 console=ttyS0 guestfs=%s:%d%s", + "panic=1 console=ttyS0 guestfs=%s:%d%s%s%s", VMCHANNEL_ADDR, VMCHANNEL_PORT, - g->verbose ? " guestfs_verbose=1" : ""); + g->verbose ? " guestfs_verbose=1" : "", + g->append ? " " : "", g->append ? g->append : ""); snprintf (memsize_str, sizeof memsize_str, "%d", memsize); @@ -824,6 +864,11 @@ guestfs_launch (guestfs_h *g) /* Parent (library). */ g->pid = r; + free (kernel); + kernel = NULL; + free (initrd); + initrd = NULL; + /* Fork the recovery process off which will kill qemu if the parent * process fails to do so (eg. if the parent segfaults). */ @@ -899,10 +944,9 @@ guestfs_launch (guestfs_h *g) addr.sun_path[UNIX_PATH_MAX-1] = '\0'; tries = 100; + /* Always sleep at least once to give qemu a small chance to start up. */ + usleep (10000); while (tries > 0) { - /* Always sleep at least once to give qemu a small chance to start up. */ - usleep (10000); - r = connect (g->sock, (struct sockaddr *) &addr, sizeof addr); if ((r == -1 && errno == EINPROGRESS) || r == 0) goto connected; @@ -910,6 +954,7 @@ guestfs_launch (guestfs_h *g) if (errno != ENOENT) perrorf (g, "connect"); tries--; + usleep (100000); } error (g, "failed to connect to vmchannel socket"); @@ -2168,6 +2213,8 @@ select_main_loop_run (guestfs_main_loop *mlv, guestfs_h *g) xset2 = ml->xset; r = select (ml->max_fd+1, &rset2, &wset2, &xset2, NULL); if (r == -1) { + if (errno == EINTR || errno == EAGAIN) + continue; perrorf (g, "select"); ml->is_running = 0; return -1;