Merge branch 'master' of git+ssh://192.168.122.1/home/rjones/d/libguestfs
[libguestfs.git] / src / guestfs.c
index 016d803..c3bce0b 100644 (file)
@@ -174,6 +174,8 @@ struct guestfs_h
   char *qemu;                  /* Qemu binary. */
   char *append;                        /* Append to kernel command line. */
 
+  int memsize;                 /* Size of RAM (megabytes). */
+
   char *last_error;
 
   /* Callbacks. */
@@ -246,6 +248,22 @@ guestfs_create (void)
     if (!g->append) goto error;
   }
 
+  /* Choose a suitable memory size.  Previously we tried to choose
+   * a minimal memory size, but this isn't really necessary since
+   * recent QEMU and KVM don't do anything nasty like locking
+   * memory into core any more.  Thus we can safely choose a
+   * large, generous amount of memory, and it'll just get swapped
+   * on smaller systems.
+   */
+  str = getenv ("LIBGUESTFS_MEMSIZE");
+  if (str) {
+    if (sscanf (str, "%d", &g->memsize) != 1 || g->memsize <= 256) {
+      fprintf (stderr, "libguestfs: non-numeric or too small value for LIBGUESTFS_MEMSIZE\n");
+      goto error;
+    }
+  } else
+    g->memsize = 500;
+
   g->main_loop = guestfs_get_default_main_loop ();
 
   /* Start with large serial numbers so they are easy to spot
@@ -386,9 +404,11 @@ guestfs_error (guestfs_h *g, const char *fs, ...)
   char *msg;
 
   va_start (args, fs);
-  vasprintf (&msg, fs, args);
+  int err = vasprintf (&msg, fs, args);
   va_end (args);
 
+  if (err < 0) return;
+
   if (g->error_cb) g->error_cb (g, g->error_cb_data, msg);
   set_last_error (g, msg);
 
@@ -597,6 +617,19 @@ guestfs_get_append (guestfs_h *g)
   return g->append;
 }
 
+int
+guestfs_set_memsize (guestfs_h *g, int memsize)
+{
+  g->memsize = memsize;
+  return 0;
+}
+
+int
+guestfs_get_memsize (guestfs_h *g)
+{
+  return g->memsize;
+}
+
 /* Add a string to the current command line. */
 static void
 incr_cmdline_size (guestfs_h *g)
@@ -675,7 +708,7 @@ guestfs_add_drive (guestfs_h *g, const char *filename)
   }
 
   /* cache=off improves reliability in the event of a host crash. */
-  snprintf (buf, len, "file=%s,cache=off", filename);
+  snprintf (buf, len, "file=%s,cache=off,if=%s", filename, DRIVE_IF);
 
   return guestfs_config (g, "-drive", buf);
 }
@@ -696,7 +729,7 @@ guestfs_add_drive_ro (guestfs_h *g, const char *filename)
     return -1;
   }
 
-  snprintf (buf, len, "file=%s,snapshot=on", filename);
+  snprintf (buf, len, "file=%s,snapshot=on,if=%s", filename, DRIVE_IF);
 
   return guestfs_config (g, "-drive", buf);
 }
@@ -763,7 +796,7 @@ int
 guestfs_launch (guestfs_h *g)
 {
   static const char *dir_template = "/tmp/libguestfsXXXXXX";
-  int r, i, pmore, memsize;
+  int r, i, pmore;
   size_t len;
   int wfd[2], rfd[2];
   int tries;
@@ -882,15 +915,6 @@ guestfs_launch (guestfs_h *g)
     goto cleanup0;
   }
 
-  /* Choose a suitable memory size.  Previously we tried to choose
-   * a minimal memory size, but this isn't really necessary since
-   * recent QEMU and KVM don't do anything nasty like locking
-   * memory into core any more.  Thus we can safely choose a
-   * large, generous amount of memory, and it'll just get swapped
-   * on smaller systems.
-   */
-  memsize = 500;
-
   /* Get qemu help text and version. */
   if (test_qemu (g) == -1)
     goto cleanup0;
@@ -936,7 +960,7 @@ guestfs_launch (guestfs_h *g)
              g->verbose ? " guestfs_verbose=1" : "",
              g->append ? " " : "", g->append ? g->append : "");
 
-    snprintf (memsize_str, sizeof memsize_str, "%d", memsize);
+    snprintf (memsize_str, sizeof memsize_str, "%d", g->memsize);
 
     add_cmdline (g, "-m");
     add_cmdline (g, memsize_str);
@@ -1449,6 +1473,13 @@ guestfs_free_lvm_lv_list (struct guestfs_lvm_lv_list *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.