Blob Blame History Raw
From eaffd8105fcd164616aad47cea2b2bf56686acfa Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 19 Jul 2013 14:09:56 +0100
Subject: [PATCH] New API: add-drive-scratch.

This adds a temporary scratch drive to the handle.

(cherry picked from commit 1b11a83d5248511abbf86775601eb6e25a36c1ee)
---
 generator/actions.ml | 15 +++++++++++++++
 gobject/Makefile.inc |  2 ++
 po/POTFILES          |  1 +
 src/drives.c         | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 71 insertions(+)

diff --git a/generator/actions.ml b/generator/actions.ml
index d30aec8..eb09aa7 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -2954,6 +2954,21 @@ it is set to the empty string (but never C<NULL>)." };
     longdesc = "\
 Get the program name.  See C<guestfs_set_program>." };
 
+  { defaults with
+    name = "add_drive_scratch";
+    style = RErr, [Int64 "size"], [OString "name"; OString "label"];
+    blocking = false;
+    fish_alias = ["scratch"];
+    shortdesc = "add a temporary scratch drive";
+    longdesc = "\
+This command adds a temporary scratch drive to the handle.  The
+C<size> parameter is the virtual size (in bytes).  The scratch
+drive is blank initially (all reads return zeroes until you start
+writing to it).  The drive is deleted when the handle is closed.
+
+The optional arguments C<name> and C<label> are passed through to
+C<guestfs_add_drive>." };
+
 ]
 
 (* daemon_functions are any functions which cause some action
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index 69f7215..17da527 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -51,6 +51,7 @@ guestfs_gobject_headers= \
   include/guestfs-gobject/optargs-inspect_get_icon.h \
   include/guestfs-gobject/optargs-mount_local.h \
   include/guestfs-gobject/optargs-umount_local.h \
+  include/guestfs-gobject/optargs-add_drive_scratch.h \
   include/guestfs-gobject/optargs-is_file.h \
   include/guestfs-gobject/optargs-is_dir.h \
   include/guestfs-gobject/optargs-umount.h \
@@ -123,6 +124,7 @@ guestfs_gobject_sources= \
   src/optargs-inspect_get_icon.c \
   src/optargs-mount_local.c \
   src/optargs-umount_local.c \
+  src/optargs-add_drive_scratch.c \
   src/optargs-is_file.c \
   src/optargs-is_dir.c \
   src/optargs-umount.c \
diff --git a/po/POTFILES b/po/POTFILES
index bc4be6f..e2e63a2 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -150,6 +150,7 @@ fuse/guestunmount.c
 fuse/test-guestunmount-fd.c
 gobject/src/optargs-add_domain.c
 gobject/src/optargs-add_drive.c
+gobject/src/optargs-add_drive_scratch.c
 gobject/src/optargs-btrfs_filesystem_resize.c
 gobject/src/optargs-btrfs_fsck.c
 gobject/src/optargs-compress_device_out.c
diff --git a/src/drives.c b/src/drives.c
index df6f7e0..3854961 100644
--- a/src/drives.c
+++ b/src/drives.c
@@ -33,6 +33,7 @@
 #include <netdb.h>
 #include <arpa/inet.h>
 #include <assert.h>
+#include <sys/types.h>
 
 #include <pcre.h>
 
@@ -1072,6 +1073,58 @@ guestfs__add_drive_ro_with_if (guestfs_h *g, const char *filename,
 }
 
 int
+guestfs__add_drive_scratch (guestfs_h *g, int64_t size,
+                                 const struct guestfs_add_drive_scratch_argv *optargs)
+{
+  struct guestfs_add_drive_opts_argv add_drive_optargs;
+  CLEANUP_FREE char *filename = NULL;
+  int fd;
+
+  /* Some parameters we always set. */
+  add_drive_optargs.bitmask = GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK;
+  add_drive_optargs.format = "raw";
+
+  /* Copy the optional arguments through to guestfs_add_drive_opts. */
+  if (optargs->bitmask & GUESTFS_ADD_DRIVE_SCRATCH_NAME_BITMASK) {
+    add_drive_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_NAME_BITMASK;
+    add_drive_optargs.name = optargs->name;
+  }
+  if (optargs->bitmask & GUESTFS_ADD_DRIVE_SCRATCH_LABEL_BITMASK) {
+    add_drive_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_LABEL_BITMASK;
+    add_drive_optargs.label = optargs->label;
+  }
+
+  /* Create the temporary file.  We don't have to worry about cleanup
+   * because everything in g->tmpdir is 'rm -rf'd when the handle is
+   * closed.
+   */
+  if (guestfs___lazy_make_tmpdir (g) == -1)
+    return -1;
+  filename = safe_asprintf (g, "%s/scratch.%d", g->tmpdir, ++g->unique);
+
+  /* Create a raw format temporary disk. */
+  fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, 0600);
+  if (fd == -1) {
+    perrorf (g, "open: %s", filename);
+    return -1;
+  }
+
+  if (ftruncate (fd, size) == -1) {
+    perrorf (g, "ftruncate: %s", filename);
+    close (fd);
+    return -1;
+  }
+
+  if (close (fd) == -1) {
+    perrorf (g, "close: %s", filename);
+    return -1;
+  }
+
+  /* Call guestfs_add_drive_opts to add the drive. */
+  return guestfs_add_drive_opts_argv (g, filename, &add_drive_optargs);
+}
+
+int
 guestfs__add_cdrom (guestfs_h *g, const char *filename)
 {
   if (strchr (filename, ':') != NULL) {
-- 
1.8.3.1