guestfs: fix typo in my recent change
[libguestfs.git] / src / guestfs.c
index 350d848..40e702e 100644 (file)
@@ -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);
@@ -421,19 +440,21 @@ guestfs_perrorf (guestfs_h *g, const char *fs, ...)
 {
   va_list args;
   char *msg;
-  int err = errno;
+  int errnum = errno;
 
   va_start (args, fs);
-  vasprintf (&msg, fs, args);
+  int err = vasprintf (&msg, fs, args);
   va_end (args);
 
+  if (err < 0) return;
+
 #ifndef _GNU_SOURCE
   char buf[256];
-  strerror_r (err, buf, sizeof buf);
+  strerror_r (errnum, buf, sizeof buf);
 #else
   char _buf[256];
   char *buf;
-  buf = strerror_r (err, _buf, sizeof _buf);
+  buf = strerror_r (errnum, _buf, sizeof _buf);
 #endif
 
   msg = safe_realloc (g, msg, strlen (msg) + 2 + strlen (buf) + 1);
@@ -667,6 +688,30 @@ guestfs_get_memsize (guestfs_h *g)
   return g->memsize;
 }
 
+int
+guestfs_get_pid (guestfs_h *g)
+{
+  if (g->pid > 0)
+    return g->pid;
+  else {
+    error (g, "get_pid: no qemu subprocess");
+    return -1;
+  }
+}
+
+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)
@@ -832,7 +877,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];
@@ -842,6 +888,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"));
@@ -985,14 +1040,18 @@ 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 */           \
+    "cgroup_disable=memory " /* saves us about 5 MB of RAM */           \
+    "selinux=0 "       /* SELinux is messed up if there's no policy */
 
     /* 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 : "");
@@ -1011,10 +1070,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");
 
@@ -1479,44 +1566,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.
@@ -2276,6 +2325,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);