Useful imaging tool:
http://man.linux-ntfs.org/ntfsclone.8.html
-Standard images
----------------
-
-Equip guestfish with some standard images that it can load
-quickly, eg:
-
- load ext2
-
-Maybe it's better to create these on the fly?
-
virt-rescue pty
---------------
glob.c \
lcd.c \
more.c \
+ prep.c \
rc.c \
reopen.c \
tilde.c \
#include "fish.h"
-static int parse_size (const char *str, off_t *size_rtn);
-
int
do_alloc (const char *cmd, int argc, char *argv[])
{
- off_t size;
- int fd;
-
if (argc != 2) {
fprintf (stderr, _("use 'alloc file size' to create an image\n"));
return -1;
}
- if (parse_size (argv[1], &size) == -1)
- return -1;
-
- if (!guestfs_is_config (g)) {
- fprintf (stderr, _("can't allocate or add disks after launching\n"));
- return -1;
- }
-
- fd = open (argv[0], O_WRONLY|O_CREAT|O_NOCTTY|O_TRUNC, 0666);
- if (fd == -1) {
- perror (argv[0]);
+ if (alloc_disk (argv[0], argv[1], 1, 0) == -1)
return -1;
- }
-#ifdef HAVE_POSIX_FALLOCATE
- int err = posix_fallocate (fd, 0, size);
- if (err != 0) {
- errno = err;
- perror ("fallocate");
- close (fd);
- unlink (argv[0]);
- return -1;
- }
-#else
- /* Slow emulation of posix_fallocate on platforms which don't have it. */
- char buffer[BUFSIZ];
- memset (buffer, 0, sizeof buffer);
-
- size_t remaining = size;
- while (remaining > 0) {
- size_t n = remaining > sizeof buffer ? sizeof buffer : remaining;
- ssize_t r = write (fd, buffer, n);
- if (r == -1) {
- perror ("write");
- close (fd);
- unlink (argv[0]);
- return -1;
- }
- remaining -= r;
- }
-#endif
+ return 0;
+}
- if (close (fd) == -1) {
- perror (argv[0]);
- unlink (argv[0]);
+int
+do_sparse (const char *cmd, int argc, char *argv[])
+{
+ if (argc != 2) {
+ fprintf (stderr, _("use 'sparse file size' to create a sparse image\n"));
return -1;
}
- if (guestfs_add_drive (g, argv[0]) == -1) {
- unlink (argv[0]);
+ if (alloc_disk (argv[0], argv[1], 1, 1) == -1)
return -1;
- }
return 0;
}
+static int parse_size (const char *str, off_t *size_rtn);
+
+/* This is the underlying allocation function. It's called from
+ * a few other places in guestfish.
+ */
int
-do_sparse (const char *cmd, int argc, char *argv[])
+alloc_disk (const char *filename, const char *size_str, int add, int sparse)
{
off_t size;
int fd;
char c = 0;
- if (argc != 2) {
- fprintf (stderr, _("use 'sparse file size' to create a sparse image\n"));
- return -1;
- }
-
- if (parse_size (argv[1], &size) == -1)
+ if (parse_size (size_str, &size) == -1)
return -1;
if (!guestfs_is_config (g)) {
return -1;
}
- fd = open (argv[0], O_WRONLY|O_CREAT|O_NOCTTY|O_TRUNC, 0666);
+ fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_TRUNC, 0666);
if (fd == -1) {
- perror (argv[0]);
+ perror (filename);
return -1;
}
- if (lseek (fd, size-1, SEEK_SET) == (off_t) -1) {
- perror ("lseek");
- close (fd);
- unlink (argv[0]);
- return -1;
- }
+ if (!sparse) { /* Not sparse */
+#ifdef HAVE_POSIX_FALLOCATE
+ int err = posix_fallocate (fd, 0, size);
+ if (err != 0) {
+ errno = err;
+ perror ("fallocate");
+ close (fd);
+ unlink (filename);
+ return -1;
+ }
+#else
+ /* Slow emulation of posix_fallocate on platforms which don't have it. */
+ char buffer[BUFSIZ];
+ memset (buffer, 0, sizeof buffer);
+
+ size_t remaining = size;
+ while (remaining > 0) {
+ size_t n = remaining > sizeof buffer ? sizeof buffer : remaining;
+ ssize_t r = write (fd, buffer, n);
+ if (r == -1) {
+ perror ("write");
+ close (fd);
+ unlink (filename);
+ return -1;
+ }
+ remaining -= r;
+ }
+#endif
+ } else { /* Sparse */
+ if (lseek (fd, size-1, SEEK_SET) == (off_t) -1) {
+ perror ("lseek");
+ close (fd);
+ unlink (filename);
+ return -1;
+ }
- if (write (fd, &c, 1) != 1) {
- perror ("write");
- close (fd);
- unlink (argv[0]);
- return -1;
+ if (write (fd, &c, 1) != 1) {
+ perror ("write");
+ close (fd);
+ unlink (filename);
+ return -1;
+ }
}
if (close (fd) == -1) {
- perror (argv[0]);
- unlink (argv[0]);
+ perror (filename);
+ unlink (filename);
return -1;
}
- if (guestfs_add_drive (g, argv[0]) == -1) {
- unlink (argv[0]);
- return -1;
+ if (add) {
+ if (guestfs_add_drive (g, filename) == -1) {
+ unlink (filename);
+ return -1;
+ }
}
return 0;
#include "closeout.h"
#include "progname.h"
+struct drv {
+ struct drv *next;
+ char *filename; /* disk filename (for -a or -N options) */
+ prep_data *data; /* prepared type (for -N option only) */
+ char *device; /* device inside the appliance */
+};
+
struct mp {
struct mp *next;
char *device;
char *mountpoint;
};
-struct drv {
- struct drv *next;
- char *filename;
-};
-
static void add_drives (struct drv *drv);
+static void prepare_drives (struct drv *drv);
static void mount_mps (struct mp *mp);
static void interactive (void);
static void shell_script (void);
" --listen Listen for remote commands\n"
" -m|--mount dev[:mnt] Mount dev on mnt (if omitted, /)\n"
" -n|--no-sync Don't autosync\n"
+ " -N|--new type Create prepared disk (test1.img, ...)\n"
" --remote[=pid] Send commands to remote %s\n"
" -r|--ro Mount read-only\n"
" --selinux Enable SELinux support\n"
enum { HELP_OPTION = CHAR_MAX + 1 };
- static const char *options = "a:Df:h::im:nrv?Vx";
+ static const char *options = "a:Df:h::im:nN:rv?Vx";
static const struct option long_options[] = {
{ "add", 1, 0, 'a' },
{ "cmd-help", 2, 0, 'h' },
{ "inspector", 0, 0, 'i' },
{ "listen", 0, 0, 0 },
{ "mount", 1, 0, 'm' },
+ { "new", 1, 0, 'N' },
{ "no-dest-paths", 0, 0, 'D' },
{ "no-sync", 0, 0, 'n' },
{ "remote", 2, 0, 0 },
int inspector = 0;
int option_index;
struct sigaction sa;
+ char next_drive = 'a';
+ int next_prepared_drive = 1;
initialize_readline ();
exit (EXIT_FAILURE);
}
drv->filename = optarg;
+ drv->data = NULL;
+ /* We could fill the device field in, but in fact we
+ * only use it for the -N option at present.
+ */
+ drv->device = NULL;
+ drv->next = drvs;
+ drvs = drv;
+ next_drive++;
+ break;
+
+ case 'N':
+ if (STRCASEEQ (optarg, "list")) {
+ list_prepared_drives ();
+ exit (EXIT_SUCCESS);
+ }
+ drv = malloc (sizeof (struct drv));
+ if (!drv) {
+ perror ("malloc");
+ exit (EXIT_FAILURE);
+ }
+ if (asprintf (&drv->filename, "test%d.img",
+ next_prepared_drive++) == -1) {
+ perror ("asprintf");
+ exit (EXIT_FAILURE);
+ }
+ drv->data = create_prepared_file (optarg, drv->filename);
+ if (asprintf (&drv->device, "/dev/sd%c", next_drive++) == -1) {
+ perror ("asprintf");
+ exit (EXIT_FAILURE);
+ }
drv->next = drvs;
drvs = drv;
break;
if (drvs || mps || remote_control_listen || remote_control ||
guestfs_get_selinux (g)) {
- fprintf (stderr, _("%s: cannot use -i option with -a, -m,"
- " --listen, --remote or --selinux\n"),
+ fprintf (stderr, _("%s: cannot use -i option with -a, -m, -N, "
+ "--listen, --remote or --selinux\n"),
program_name);
exit (EXIT_FAILURE);
}
/* If we've got drives to add, add them now. */
add_drives (drvs);
- /* If we've got mountpoints, we must launch the guest and mount them. */
- if (mps != NULL) {
+ /* If we've got mountpoints or prepared drives, we must launch the
+ * guest and mount them.
+ */
+ if (next_prepared_drive > 1 || mps != NULL) {
if (launch (g) == -1) exit (EXIT_FAILURE);
+ prepare_drives (drvs);
mount_mps (mps);
}
if (drv) {
add_drives (drv->next);
- if (!read_only)
+
+ if (drv->data /* -N option is not affected by --ro */ || !read_only)
r = guestfs_add_drive (g, drv->filename);
else
r = guestfs_add_drive_ro (g, drv->filename);
}
static void
+prepare_drives (struct drv *drv)
+{
+ if (drv) {
+ prepare_drives (drv->next);
+ prepare_drive (drv->filename, drv->data, drv->device);
+ }
+}
+
+static void
interactive (void)
{
script (1);
/* in alloc.c */
extern int do_alloc (const char *cmd, int argc, char *argv[]);
extern int do_sparse (const char *cmd, int argc, char *argv[]);
+extern int alloc_disk (const char *filename, const char *size,
+ int add, int sparse);
/* in echo.c */
extern int do_echo (const char *cmd, int argc, char *argv[]);
/* in more.c */
extern int do_more (const char *cmd, int argc, char *argv[]);
+/* in prep.c */
+typedef struct prep_data prep_data;
+extern void list_prepared_drives (void);
+extern prep_data *create_prepared_file (const char *type_string,
+ const char *filename);
+extern void prepare_drive (const char *filename, prep_data *data,
+ const char *device);
+
/* in rc.c (remote control) */
extern void rc_listen (void) __attribute__((noreturn));
extern int rc_remote (int pid, const char *cmd, int argc, char *argv[],
=head2 As a script interpreter
-Create a 50MB disk containing an ext2-formatted partition:
+Create a 100MB disk containing an ext2-formatted partition:
#!/usr/bin/guestfish -f
- alloc /tmp/output.img 50M
+ sparse test1.img 100M
run
part-disk /dev/sda mbr
mkfs ext2 /dev/sda1
+=head2 Start with a prepared disk
+
+An alternate way to create a 100MB disk called C<test1.img> containing
+a single ext2-formatted partition:
+
+ guestfish -N fs
+
+To list what is available do:
+
+ guestfish -N list | less
+
=head2 Remote control
eval `guestfish --listen --ro`
guestfish -i /dev/Guests/MyGuest
-You cannot use I<-a>, I<-m>, I<--listen>, I<--remote> or I<--selinux>
-in conjunction with this option, and options other than I<--ro> might
-not behave correctly.
+You cannot use I<-a>, I<-m>, I<-N>, I<--listen>, I<--remote> or
+I<--selinux> in conjunction with this option, and options other than
+I<--ro> might not behave correctly.
See also: L<virt-inspector(1)>.
Disable autosync. This is enabled by default. See the discussion
of autosync in the L<guestfs(3)> manpage.
+=item B<-N type> | B<--new type> | B<-N list>
+
+Prepare a fresh disk image formatted as "type". This is an
+alternative to the I<-a> option: whereas I<-a> adds an existing disk,
+I<-N> creates a preformatted disk with a filesystem and adds it.
+See L</PREPARED DISK IMAGES> below.
+
=item B<--remote[=pid]>
Send remote commands to C<$GUESTFISH_PID> or C<pid>. See section
might be running, and is generally recommended in cases where you
don't need write access to the disk.
+Note that prepared disk images created with I<-N> are not affected by
+the I<--ro> option.
+
=item B<--selinux>
Enable SELinux support for the guest. See L<guestfs(3)/SELINUX>.
Guestfish client and server versions must match exactly.
+=head1 PREPARED DISK IMAGES
+
+Use the I<-N type> or I<--new type> parameter to select one of a set
+of preformatted disk images that guestfish can make for you to save
+typing. This is particularly useful for testing purposes. This
+option is used instead of the I<-a> option, and like I<-a> can appear
+multiple times (and can be mixed with I<-a>).
+
+The new disk is called C<test1.img> for the first I<-N>, C<test2.img>
+for the second and so on. Existing files in the current directory are
+not overwritten, so you may need to do C<rm -f test1.img>.
+
+The type briefly describes how the disk should be sized, partitioned,
+how filesystem(s) should be created, and how content should be added.
+Optionally the type can be followed by extra parameters, separated by
+C<:> (colon) characters. For example, I<-N fs> creates a default
+100MB, sparsely-allocated disk, containing a single partition, with
+the partition formatted as ext2. I<-N fs:ext4:1G> is the same, but
+for an ext4 filesystem on a 1GB disk instead.
+
+To list the available types and any extra parameters they take, run:
+
+ guestfish -N list | less
+
+Note that the prepared filesystem is not mounted. You would usually
+have to use the C<mount /dev/sda1 /> command or add the
+I<-m /dev/sda1> option.
+
+If any I<-N> or I<--new> options are given, the guest is automatically
+launched.
+
+=head2 EXAMPLES
+
+Create a 100MB disk with an ext4-formatted partition:
+
+ guestfish -N fs:ext4
+
+Create a 32MB disk with a VFAT-formatted partition, and mount it:
+
+ guestfish -N fs:vfat:32M -m /dev/sda1
+
+Create a blank 200MB disk:
+
+ guestfish -N disk:200M
+
=head1 UPLOADING AND DOWNLOADING FILES
For commands such as C<upload>, C<download>, C<tar-in>, C<tar-out> and
--- /dev/null
+/* guestfish - the filesystem interactive shell
+ * Copyright (C) 2010 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "fish.h"
+
+static prep_data *parse_type_string (const char *type_string);
+static void prep_error (prep_data *data, const char *filename, const char *fs, ...) __attribute__((noreturn, format (printf,3,4)));
+
+struct prep {
+ const char *name; /* eg. "fs" */
+
+ size_t nr_params; /* optional parameters */
+ struct param *params;
+
+ const char *shortdesc; /* short description */
+ const char *longdesc; /* long description */
+
+ /* functions to implement it */
+ void (*prelaunch) (const char *filename, prep_data *);
+ void (*postlaunch) (const char *filename, prep_data *, const char *device);
+};
+
+struct param {
+ const char *pname; /* parameter name */
+ const char *pdefault; /* parameter default */
+ const char *pdesc; /* parameter description */
+};
+
+static void prelaunch_disk (const char *filename, prep_data *data);
+static struct param disk_params[] = {
+ { "size", "100M", "the size of the disk image" },
+};
+
+static void prelaunch_part (const char *filename, prep_data *data);
+static void postlaunch_part (const char *filename, prep_data *data, const char *device);
+static struct param part_params[] = {
+ { "size", "100M", "the size of the disk image" },
+ { "partition", "mbr", "partition table type" },
+};
+
+static void prelaunch_fs (const char *filename, prep_data *data);
+static void postlaunch_fs (const char *filename, prep_data *data, const char *device);
+static struct param fs_params[] = {
+ { "filesystem", "ext2", "the type of filesystem to use" },
+ { "size", "100M", "the size of the disk image" },
+ { "partition", "mbr", "partition table type" },
+};
+
+static const struct prep preps[] = {
+ { "disk",
+ 1, disk_params,
+ "create a blank disk",
+ "\
+ Create a blank disk, size 100MB (by default).\n\
+\n\
+ The default size can be changed by supplying an optional parameter.",
+ prelaunch_disk, NULL
+ },
+ { "part",
+ 2, part_params,
+ "create a partitioned disk",
+ "\
+ Create a disk with a single partition. By default the size of the disk\n\
+ is 100MB (the available space in the partition will be a tiny bit smaller)\n\
+ and the partition table will be MBR (old DOS-style).\n\
+\n\
+ These defaults can be changed by supplying optional parameters.",
+ prelaunch_part, postlaunch_part
+ },
+ { "fs",
+ 3, fs_params,
+ "create a filesystem",
+ "\
+ Create a disk with a single partition, with the partition containing\n\
+ an empty filesystem. This defaults to creating a 100MB disk (the available\n\
+ space in the filesystem will be a tiny bit smaller) with an MBR (old\n\
+ DOS-style) partition table and an ext2 filesystem.\n\
+\n\
+ These defaults can be changed by supplying optional parameters.",
+ prelaunch_fs, postlaunch_fs
+ },
+};
+
+void
+list_prepared_drives (void)
+{
+ size_t i, j;
+
+ printf (_("List of available prepared disk images:\n\n"));
+
+ for (i = 0; i < sizeof preps / sizeof preps[0]; ++i) {
+ printf (_("\
+guestfish -N %-16s %s\n\
+\n\
+%s\n"),
+ preps[i].name, preps[i].shortdesc, preps[i].longdesc);
+
+ if (preps[i].nr_params > 0) {
+ printf ("\n");
+ printf (_(" Optional parameters:\n"));
+ printf (" -N %s", preps[i].name);
+ for (j = 0; j < preps[i].nr_params; ++j)
+ printf (":<%s>", preps[i].params[j].pname);
+ printf ("\n");
+ for (j = 0; j < preps[i].nr_params; ++j) {
+ printf (" ");
+ printf (_("<%s> %s (default: %s)\n"),
+ preps[i].params[j].pname,
+ preps[i].params[j].pdesc,
+ preps[i].params[j].pdefault);
+ }
+ }
+
+ printf ("\n");
+ }
+
+ printf (_("\
+Prepared disk images are written to file \"test1.img\" in the local\n\
+directory. (\"test2.img\" etc if -N option is given multiple times).\n\
+For more information see the guestfish(1) manual.\n"));
+}
+
+struct prep_data {
+ const struct prep *prep;
+ const char *orig_type_string;
+ const char **params;
+};
+
+/* Parse the type string (from the command line) and create the output
+ * file 'filename'. This is called before launch. Return the opaque
+ * prep_data which will be passed back to us in prepare_drive below.
+ */
+prep_data *
+create_prepared_file (const char *type_string, const char *filename)
+{
+ if (access (filename, F_OK) == 0) {
+ fprintf (stderr, _("guestfish: file '%s' exists and the '-N' option will not overwrite it\n"),
+ filename);
+ exit (EXIT_FAILURE);
+ }
+
+ prep_data *data = parse_type_string (type_string);
+ if (data->prep->prelaunch)
+ data->prep->prelaunch (filename, data);
+ return data;
+}
+
+static prep_data *
+parse_type_string (const char *type_string)
+{
+ size_t i;
+
+ /* Match on the type part (without parameters). */
+ size_t len = strcspn (type_string, ":");
+ for (i = 0; i < sizeof preps / sizeof preps[0]; ++i)
+ if (STRCASEEQLEN (type_string, preps[i].name, len))
+ break;
+
+ if (preps[i].name == NULL) {
+ fprintf (stderr, _("\
+guestfish: -N parameter '%s': no such prepared disk image known.\n\
+Use 'guestfish -N list' to list possible values for the -N parameter.\n"),
+ type_string);
+ exit (EXIT_FAILURE);
+ }
+
+ prep_data *data = malloc (sizeof *data);
+ if (data == NULL) {
+ perror ("malloc");
+ exit (EXIT_FAILURE);
+ }
+ data->prep = &preps[i];
+ data->orig_type_string = type_string;
+
+ /* Set up the optional parameters to all-defaults. */
+ data->params = malloc (data->prep->nr_params * sizeof (char *));
+ if (data->params == NULL) {
+ perror ("malloc");
+ exit (EXIT_FAILURE);
+ }
+
+ for (i = 0; i < data->prep->nr_params; ++i)
+ data->params[i] = data->prep->params[i].pdefault;
+
+ /* Parse the optional parameters. */
+ const char *p = type_string + len;
+ if (*p) p++; /* skip colon char */
+
+ i = 0;
+ while (*p) {
+ len = strcspn (p, ":");
+ data->params[i] = strndup (p, len);
+ if (data->params[i] == NULL) {
+ perror ("strndup");
+ exit (EXIT_FAILURE);
+ }
+
+ p += len;
+ if (*p) p++; /* skip colon char */
+ i++;
+ }
+
+ return data;
+}
+
+/* Prepare a drive. The appliance has been launched, and 'device' is
+ * the libguestfs device. 'data' is the requested type. 'filename'
+ * is just used for error messages.
+ */
+void
+prepare_drive (const char *filename, prep_data *data,
+ const char *device)
+{
+ if (data->prep->postlaunch)
+ data->prep->postlaunch (filename, data, device);
+}
+
+static void
+prep_error (prep_data *data, const char *filename, const char *fs, ...)
+{
+ fprintf (stderr,
+ _("guestfish: error creating prepared disk image '%s' on '%s': "),
+ data->orig_type_string, filename);
+
+ va_list args;
+ va_start (args, fs);
+ vfprintf (stderr, fs, args);
+ va_end (args);
+
+ fprintf (stderr, "\n");
+
+ exit (EXIT_FAILURE);
+}
+
+static void
+prelaunch_disk (const char *filename, prep_data *data)
+{
+ if (alloc_disk (filename, data->params[0], 0, 1) == -1)
+ prep_error (data, filename, _("failed to allocate disk"));
+}
+
+static void
+prelaunch_part (const char *filename, prep_data *data)
+{
+ if (alloc_disk (filename, data->params[0], 0, 1) == -1)
+ prep_error (data, filename, _("failed to allocate disk"));
+}
+
+static void
+postlaunch_part (const char *filename, prep_data *data, const char *device)
+{
+ if (guestfs_part_disk (g, device, data->params[2]) == -1)
+ prep_error (data, filename, _("failed to partition disk: %s"),
+ guestfs_last_error (g));
+}
+
+static void
+prelaunch_fs (const char *filename, prep_data *data)
+{
+ if (alloc_disk (filename, data->params[1], 0, 1) == -1)
+ prep_error (data, filename, _("failed to allocate disk"));
+}
+
+static void
+postlaunch_fs (const char *filename, prep_data *data, const char *device)
+{
+ if (guestfs_part_disk (g, device, data->params[2]) == -1)
+ prep_error (data, filename, _("failed to partition disk: %s"),
+ guestfs_last_error (g));
+
+ char *part;
+ if (asprintf (&part, "%s1", device) == -1) {
+ perror ("asprintf");
+ exit (EXIT_FAILURE);
+ }
+
+ if (guestfs_mkfs (g, data->params[0], part) == -1)
+ prep_error (data, filename, _("failed to create filesystem (%s): %s"),
+ data->params[0], guestfs_last_error (g));
+
+ free (part);
+}
fish/glob.c
fish/lcd.c
fish/more.c
+fish/prep.c
fish/rc.c
fish/reopen.c
fish/tilde.c
rm -f test1.img
-../fish/guestfish <<EOF
-sparse test1.img 10M
-launch
-part-disk /dev/sda mbr
-mkfs ext2 /dev/sda1
-mount-options "" /dev/sda1 /
+../fish/guestfish -N fs -m /dev/sda1 <<EOF
ll /../dev/console
ll /../dev/full
ll /../dev/mapper/
rm -f test1.img
-../fish/guestfish <<EOF
-sparse test1.img 10M
-run
-part-disk /dev/sda mbr
-mkfs ext2 /dev/sda1
-mount-options "" /dev/sda1 /
+../fish/guestfish -N fs -m /dev/sda1 <<EOF
mkdir /dev
-command /ignore-this-error
unmount-all
-set-memsize 123L
EOF
-../fish/guestfish >> test.out 2>> test.err <<EOF
-alloc test1.img 10M
-run
-part-disk /dev/sda mbr
-mkfs ext2 /dev/sda1
-mount /dev/sda1 /
-
+../fish/guestfish -N fs -m /dev/sda1 >> test.out 2>> test.err <<EOF
touch /test
# truncate-size takes an Int64 argument
rm -f test1.img
-../fish/guestfish <<EOF
-alloc test1.img 10M
-run
+../fish/guestfish -N disk <<EOF
-upload $srcdir/rhbz576879.sh /test.sh
# Shouldn't lose synchronization, so next command should work:
ping-daemon
for i in $(seq 1 $n); do
echo Test boot $i of $n ...
- ../fish/guestfish sparse test1.img 500M : run
+ ../fish/guestfish -N disk </dev/null
done
rm test1.img
set -e
-rm -f test.img
-
-../fish/guestfish <<'EOF'
-alloc test.img 10M
-run
-
-part-disk /dev/sda mbr
-mkfs ext2 /dev/sda1
-mount-options "" /dev/sda1 /
+rm -f test1.img
+../fish/guestfish -N fs -m /dev/sda1 <<'EOF'
# Upload image, daemon should cancel because the image is too large
# to upload into itself.
echo "Expect: write: /test: No space left on device"
ping-daemon
EOF
-rm -f test.img
+rm -f test1.img
set -e
-rm -f test.img
-
-../fish/guestfish <<'EOF'
-alloc test.img 10M
-run
+rm -f test1.img
+../fish/guestfish -N disk <<'EOF'
# Kill the subprocess.
kill-subprocess
ping-daemon
EOF
-rm -f test.img
+rm -f test1.img
set -e
-rm -f test.pid test.img
-
-../fish/guestfish <<'EOF'
-alloc test.img 10M
-run
+rm -f test.pid test1.img
+../fish/guestfish -N disk <<'EOF'
# Kill the subprocess after a short wait.
pid | cat > test.pid
! sleep 2 ; kill $(cat test.pid) &
ping-daemon
EOF
-rm -f test.pid test.img
+rm -f test.pid test1.img
set -e
-rm -f test.pid test.img
-
-../fish/guestfish <<'EOF'
-alloc test.img 10M
-run
+rm -f test.pid test1.img
+../fish/guestfish -N disk <<'EOF'
# Kill subprocess.
pid | cat > test.pid
! kill $(cat test.pid) ; sleep 2
ping-daemon
EOF
-rm -f test.pid test.img
+rm -f test.pid test1.img