summaryrefslogtreecommitdiffstats
path: root/rescue
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-04-26 12:56:34 +0100
committerRichard W.M. Jones <rjones@redhat.com>2012-04-26 12:56:34 +0100
commit8cb30dc80550da06871b0becc3582b2cdc4948ae (patch)
tree863983757b96ffe866b2c44beafd6a5da634a90b /rescue
parent39d79e677b684dfd49c852ee7ce4c4bf3d5cf56f (diff)
downloadlibguestfs-8cb30dc80550da06871b0becc3582b2cdc4948ae.tar.gz
libguestfs-8cb30dc80550da06871b0becc3582b2cdc4948ae.tar.xz
libguestfs-8cb30dc80550da06871b0becc3582b2cdc4948ae.zip
rescue: Add --scratch option.
This lets you create temporary scratch disks.
Diffstat (limited to 'rescue')
-rw-r--r--rescue/virt-rescue.c106
-rwxr-xr-xrescue/virt-rescue.pod15
2 files changed, 121 insertions, 0 deletions
diff --git a/rescue/virt-rescue.c b/rescue/virt-rescue.c
index bda40c1f..684baeb9 100644
--- a/rescue/virt-rescue.c
+++ b/rescue/virt-rescue.c
@@ -36,6 +36,7 @@
#include "guestfs.h"
#include "options.h"
+static void add_scratch_disks (int n, struct drv **drvs);
static void do_suggestion (struct drv *drvs);
/* Currently open libguestfs handle. */
@@ -78,6 +79,7 @@ usage (int status)
" -m|--memsize MB Set memory size in megabytes\n"
" --network Enable network\n"
" -r|--ro Access read-only\n"
+ " --scratch[=N] Add scratch disk(s)\n"
" --selinux Enable SELinux\n"
" --smp N Enable SMP with N >= 2 virtual CPUs\n"
" --suggest Suggest mount commands for this guest\n"
@@ -118,6 +120,7 @@ main (int argc, char *argv[])
{ "network", 0, 0, 0 },
{ "ro", 0, 0, 'r' },
{ "rw", 0, 0, 'w' },
+ { "scratch", 2, 0, 0 },
{ "selinux", 0, 0, 0 },
{ "smp", 1, 0, 0 },
{ "suggest", 0, 0, 0 },
@@ -175,6 +178,25 @@ main (int argc, char *argv[])
}
} else if (STREQ (long_options[option_index].name, "suggest")) {
suggest = 1;
+ } else if (STREQ (long_options[option_index].name, "scratch")) {
+ if (!optarg || STREQ (optarg, ""))
+ add_scratch_disks (1, &drvs);
+ else {
+ int n;
+ if (sscanf (optarg, "%d", &n) != 1) {
+ fprintf (stderr,
+ _("%s: could not parse --scratch parameter '%s'\n"),
+ program_name, optarg);
+ exit (EXIT_FAILURE);
+ }
+ if (n < 1) {
+ fprintf (stderr,
+ _("%s: --scratch parameter '%s' should be >= 1\n"),
+ program_name, optarg);
+ exit (EXIT_FAILURE);
+ }
+ add_scratch_disks (n, &drvs);
+ }
} else {
fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
program_name, long_options[option_index].name, option_index);
@@ -479,6 +501,90 @@ suggest_filesystems (void)
free (fses);
}
+struct scratch_disk {
+ struct scratch_disk *next;
+ char *filename;
+};
+static struct scratch_disk *scratch_disks = NULL;
+
+static void unlink_scratch_disks (void);
+static void add_scratch_disk (struct drv **drvs);
+
+static void
+add_scratch_disks (int n, struct drv **drvs)
+{
+ while (n > 0) {
+ add_scratch_disk (drvs);
+ n--;
+ }
+}
+
+static void
+add_scratch_disk (struct drv **drvs)
+{
+ char filename_s[] = "/var/tmp/rescueXXXXXX";
+ int fd;
+ char *filename;
+ struct scratch_disk *sd;
+ struct drv *drv;
+
+ /* Create a temporary file, raw sparse format. */
+ fd = mkstemp (filename_s);
+ if (fd == -1) {
+ perror ("mkstemp: scratch disk");
+ exit (EXIT_FAILURE);
+ }
+ if (ftruncate (fd, 10737418240ULL) == -1) {
+ perror ("ftruncate: scratch disk");
+ exit (EXIT_FAILURE);
+ }
+ if (close (fd) == -1) {
+ perror ("close: scratch disk");
+ exit (EXIT_FAILURE);
+ }
+
+ filename = strdup (filename_s);
+ if (filename == NULL) {
+ perror ("malloc");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Remember this scratch disk, so we can clean it up at exit. */
+ if (scratch_disks == NULL)
+ atexit (unlink_scratch_disks);
+ sd = malloc (sizeof (struct scratch_disk));
+ if (!sd) {
+ perror ("malloc");
+ exit (EXIT_FAILURE);
+ }
+ sd->filename = filename;
+ sd->next = scratch_disks;
+ scratch_disks = sd;
+
+ /* Add the scratch disk to the drives list. */
+ drv = calloc (1, sizeof (struct drv));
+ if (!drv) {
+ perror ("malloc");
+ exit (EXIT_FAILURE);
+ }
+ drv->type = drv_a;
+ drv->nr_drives = -1;
+ drv->a.filename = filename;
+ drv->a.format = "raw";
+ drv->next = *drvs;
+ *drvs = drv;
+}
+
+/* Called atexit to unlink the scratch disks. */
+static void
+unlink_scratch_disks (void)
+{
+ while (scratch_disks) {
+ unlink (scratch_disks->filename);
+ free (scratch_disks->filename);
+ scratch_disks = scratch_disks->next;
+ }
+}
/* The following was a nice idea, but in fact it doesn't work. This is
* because qemu has some (broken) pty emulation itself.
diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod
index 9863e44a..8f9b64d0 100755
--- a/rescue/virt-rescue.pod
+++ b/rescue/virt-rescue.pod
@@ -101,6 +101,9 @@ want to partition that file (although we would recommend using
L<guestfish(1)> instead as it is more suitable for this purpose). You
can even use virt-rescue on things like SD cards.
+You can get virt-rescue to give you scratch disk(s) to play with.
+This is useful for testing out Linux utilities (see I<--scratch>).
+
Virt-rescue does not require root. You only need to run it as root if
you need root to open the disk image.
@@ -198,6 +201,18 @@ don't need write access to the disk.
See also L<guestfish(1)/OPENING DISKS FOR READ AND WRITE>.
+=item B<--scratch>
+
+=item B<--scratch=N>
+
+The I<--scratch> option adds a large scratch disk to the rescue
+appliance. I<--scratch=N> adds C<N> scratch disks. The scratch
+disk(s) are deleted automatically when virt-rescue exits.
+
+You can also mix I<-a>, I<-d> and I<--scratch> options. The scratch
+disk(s) are added to the appliance in the order they appear on the
+command line.
+
=item B<--selinux>
Enable SELinux in the rescue appliance. You should read