mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
rescue: Add --scratch option.
This lets you create temporary scratch disks.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user