X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fguestfs.c;h=ec7473ea55e509eb037e64ae66af1734fe00a90b;hp=17d812acd0c5a6c0567803c351323b6d3e0a19b0;hb=8b217a87bf9175e7e02a5913e5617e0d12dfd09c;hpb=62b322872543c2ec069ac4fb0103ab758f587cef diff --git a/src/guestfs.c b/src/guestfs.c index 17d812a..ec7473e 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -85,8 +85,8 @@ static void close_handles (void); #define UNIX_PATH_MAX 108 /* Also in guestfsd.c */ -#define GUESTFWD_PORT 6666 #define GUESTFWD_ADDR "10.0.2.4" +#define GUESTFWD_PORT "6666" /* GuestFS handle and connection. */ enum state { CONFIG, LAUNCHING, READY, BUSY, NO_HANDLE }; @@ -984,6 +984,7 @@ guestfs__launch (guestfs_h *g) if (r == 0) { /* Child (qemu). */ char buf[256]; + const char *vmchannel = NULL; /* Set up the full command line. Do this in the subprocess so we * don't need to worry about cleaning up. @@ -1026,8 +1027,8 @@ guestfs__launch (guestfs_h *g) snprintf (buf, sizeof buf, "user,vlan=0,net=10.0.2.0/8," - "guestfwd=tcp:%s:%d-chardev:guestfsvmc", - GUESTFWD_ADDR, GUESTFWD_PORT); + "guestfwd=tcp:" GUESTFWD_ADDR ":" GUESTFWD_PORT + "-chardev:guestfsvmc"); add_cmdline (g, "-net"); add_cmdline (g, buf); @@ -1036,7 +1037,7 @@ guestfs__launch (guestfs_h *g) * syntax, or if not then we'll get a quick failure. */ snprintf (buf, sizeof buf, - "channel,%d:unix:%s,server,nowait", GUESTFWD_PORT, unixsock); + "channel," GUESTFWD_PORT ":unix:%s,server,nowait", unixsock); add_cmdline (g, "-net"); add_cmdline (g, buf); @@ -1045,6 +1046,7 @@ guestfs__launch (guestfs_h *g) } add_cmdline (g, "-net"); add_cmdline (g, "nic,model=" NET_IF ",vlan=0"); + vmchannel = "guestfs_vmchannel=tcp:" GUESTFWD_ADDR ":" GUESTFWD_PORT " "; #define LINUX_CMDLINE \ "panic=1 " /* force kernel to panic if daemon exits */ \ @@ -1058,10 +1060,12 @@ guestfs__launch (guestfs_h *g) snprintf (buf, sizeof buf, LINUX_CMDLINE "%s" /* (selinux) */ + "%s" /* (vmchannel) */ "%s" /* (verbose) */ "%s", /* (append) */ g->selinux ? "selinux=1 enforcing=0 " : "selinux=0 ", - g->verbose ? "guestfs_verbose=1 " : " ", + vmchannel ? vmchannel : "", + g->verbose ? "guestfs_verbose=1 " : "", g->append ? g->append : ""); add_cmdline (g, "-kernel"); @@ -1208,6 +1212,32 @@ guestfs__launch (guestfs_h *g) connected: g->state = LAUNCHING; + + /* Wait for qemu to start and to connect back to us via vmchannel and + * send the GUESTFS_LAUNCH_FLAG message. + */ + uint32_t size; + void *buf = NULL; + r = recv_from_daemon (g, &size, &buf); + free (buf); + + if (r == -1) return -1; + + if (size != GUESTFS_LAUNCH_FLAG) { + error (g, _("guestfs_launch failed, see earlier error messages")); + goto cleanup2; + } + + /* This is possible in some really strange situations, such as + * guestfsd starts up OK but then qemu immediately exits. Check for + * it because the caller is probably expecting to be able to send + * commands after this function returns. + */ + if (g->state != READY) { + error (g, _("qemu launched and contacted daemon, but state != READY")); + goto cleanup2; + } + return 0; cleanup2: @@ -1381,45 +1411,17 @@ qemu_supports (guestfs_h *g, const char *option) return g->qemu_help && strstr (g->qemu_help, option) != NULL; } +/* You had to call this function after launch in versions <= 1.0.70, + * but it is now a no-op. + */ int guestfs__wait_ready (guestfs_h *g) { - int r; - uint32_t size; - void *buf = NULL; - - if (g->state == READY) return 0; - - if (g->state == BUSY) { - error (g, _("qemu has finished launching already")); - return -1; - } - - if (g->state != LAUNCHING) { + if (g->state != READY) { error (g, _("qemu has not been launched yet")); return -1; } - r = recv_from_daemon (g, &size, &buf); - free (buf); - - if (r == -1) return -1; - - if (size != GUESTFS_LAUNCH_FLAG) { - error (g, _("guestfs_wait_ready failed, see earlier error messages")); - return -1; - } - - /* This is possible in some really strange situations, such as - * guestfsd starts up OK but then qemu immediately exits. Check for - * it because the caller is probably expecting to be able to send - * commands after this function returns. - */ - if (g->state != READY) { - error (g, _("qemu launched and contacted daemon, but state != READY")); - return -1; - } - return 0; }