X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fguestfs.c;h=db6db9107c636b2a416695e0635ea7db46f428db;hp=bbbd4ea5c7b7ecbc4cfd385c415c1dd28eeaa48a;hb=10258cadd0067cb49b89faf1ce424b1c01f5a7c3;hpb=7cbb86e4c8b6b8bca8606d219c5571549ceabba6 diff --git a/src/guestfs.c b/src/guestfs.c index bbbd4ea..db6db91 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -327,6 +327,25 @@ guestfs_close (guestfs_h *g) if (g->state != CONFIG) guestfs_kill_subprocess (g); + /* Close any sockets and deregister any handlers. */ + if (g->stdout_watch >= 0) + g->main_loop->remove_handle (g->main_loop, g, g->stdout_watch); + if (g->sock_watch >= 0) + g->main_loop->remove_handle (g->main_loop, g, g->sock_watch); + g->stdout_watch = -1; + g->sock_watch = -1; + + if (g->fd[0] >= 0) + close (g->fd[0]); + if (g->fd[1] >= 0) + close (g->fd[1]); + if (g->sock >= 0) + close (g->sock); + g->fd[0] = -1; + g->fd[1] = -1; + g->sock = -1; + + /* Remove tmpfiles. */ if (g->tmpdir) { snprintf (filename, sizeof filename, "%s/sock", g->tmpdir); unlink (filename); @@ -678,6 +697,19 @@ guestfs_get_pid (guestfs_h *g) } } +struct guestfs_version * +guestfs_version (guestfs_h *g) +{ + struct guestfs_version *r; + + r = safe_malloc (g, sizeof *r); + r->major = PACKAGE_VERSION_MAJOR; + r->minor = PACKAGE_VERSION_MINOR; + r->release = PACKAGE_VERSION_RELEASE; + r->extra = safe_strdup (g, PACKAGE_VERSION_EXTRA); + return r; +} + /* Add a string to the current command line. */ static void incr_cmdline_size (guestfs_h *g) @@ -843,7 +875,8 @@ static const char *supermin_hostfiles_name = int guestfs_launch (guestfs_h *g) { - static const char *dir_template = "/tmp/libguestfsXXXXXX"; + const char *tmpdir; + char dir_template[PATH_MAX]; int r, i, pmore; size_t len; int wfd[2], rfd[2]; @@ -853,6 +886,15 @@ guestfs_launch (guestfs_h *g) char unixsock[256]; struct sockaddr_un addr; +#ifdef P_tmpdir + tmpdir = P_tmpdir; +#else + tmpdir = "/tmp"; +#endif + + tmpdir = getenv ("TMPDIR") ? : tmpdir; + snprintf (dir_template, sizeof dir_template, "%s/libguestfsXXXXXX", tmpdir); + /* Configured? */ if (!g->cmdline) { error (g, _("you must call guestfs_add_drive before guestfs_launch")); @@ -996,14 +1038,16 @@ guestfs_launch (guestfs_h *g) */ g->cmdline[0] = g->qemu; - /* Construct the -net channel parameter for qemu. */ - snprintf (vmchannel, sizeof vmchannel, - "channel,%d:unix:%s,server,nowait", - VMCHANNEL_PORT, unixsock); +#define LINUX_CMDLINE \ + "panic=1 " /* force kernel to panic if daemon exits */ \ + "console=ttyS0 " /* serial console */ \ + "udevtimeout=300 " /* good for very slow systems (RHBZ#480319) */ \ + "noapic " /* workaround for RHBZ#502058 - ok if not SMP */ \ + "acpi=off " /* we don't need ACPI, turn it off */ /* Linux kernel command line. */ snprintf (append, sizeof append, - "panic=1 console=ttyS0 guestfs=%s:%d%s%s%s", + LINUX_CMDLINE "guestfs=%s:%d%s%s%s", VMCHANNEL_ADDR, VMCHANNEL_PORT, g->verbose ? " guestfs_verbose=1" : "", g->append ? " " : "", g->append ? g->append : ""); @@ -1022,10 +1066,38 @@ guestfs_launch (guestfs_h *g) add_cmdline (g, "-nographic"); add_cmdline (g, "-serial"); add_cmdline (g, "stdio"); - add_cmdline (g, "-net"); - add_cmdline (g, vmchannel); - add_cmdline (g, "-net"); - add_cmdline (g, "user,vlan=0"); + +#if 0 + /* Doesn't work. See: + * http://lists.gnu.org/archive/html/qemu-devel/2009-07/threads.html + * Subject "guestfwd option doesn't allow supplementary ,server,nowait" + */ + if (qemu_supports (g, "guestfwd")) { + /* New-style -net user,guestfwd=... syntax for vmchannel. See: + * http://git.savannah.gnu.org/cgit/qemu.git/commit/?id=c92ef6a22d3c71538fcc48fb61ad353f7ba03b62 + */ + snprintf (vmchannel, sizeof vmchannel, + "user,vlan=0,guestfwd=tcp:%s:%d-unix:%s,server,nowait", + VMCHANNEL_ADDR, VMCHANNEL_PORT, unixsock); + + add_cmdline (g, "-net"); + add_cmdline (g, vmchannel); + } else { +#endif + /* Not guestfwd. HOPEFULLY this qemu uses the older -net channel + * syntax, or if not then we'll get a quick failure. + */ + snprintf (vmchannel, sizeof vmchannel, + "channel,%d:unix:%s,server,nowait", + VMCHANNEL_PORT, unixsock); + + add_cmdline (g, "-net"); + add_cmdline (g, vmchannel); + add_cmdline (g, "-net"); + add_cmdline (g, "user,vlan=0"); +#if 0 + } +#endif add_cmdline (g, "-net"); add_cmdline (g, "nic,model=virtio,vlan=0"); @@ -1490,44 +1562,6 @@ guestfs_end_busy (guestfs_h *g) return 0; } -/* Structure-freeing functions. These rely on the fact that the - * structure format is identical to the XDR format. See note in - * generator.ml. - */ -void -guestfs_free_int_bool (struct guestfs_int_bool *x) -{ - free (x); -} - -void -guestfs_free_lvm_pv_list (struct guestfs_lvm_pv_list *x) -{ - xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_pv_list, (char *) x); - free (x); -} - -void -guestfs_free_lvm_vg_list (struct guestfs_lvm_vg_list *x) -{ - xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_vg_list, (char *) x); - free (x); -} - -void -guestfs_free_lvm_lv_list (struct guestfs_lvm_lv_list *x) -{ - xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_lv_list, (char *) x); - free (x); -} - -void -guestfs_free_dirent_list (struct guestfs_dirent_list *x) -{ - xdr_free ((xdrproc_t) xdr_guestfs_int_dirent_list, (char *) x); - free (x); -} - /* We don't know if stdout_event or sock_read_event will be the * first to receive EOF if the qemu process dies. This function * has the common cleanup code for both. @@ -2287,6 +2321,10 @@ guestfs__receive_file_sync (guestfs_h *g, const char *filename) char fbuf[4]; uint32_t flag = GUESTFS_CANCEL_FLAG; + if (g->verbose) + fprintf (stderr, "%s: waiting for daemon to acknowledge cancellation\n", + __func__); + xdrmem_create (&xdr, fbuf, sizeof fbuf, XDR_ENCODE); xdr_uint32_t (&xdr, &flag); xdr_destroy (&xdr);