fish: Add -N option for making prepared disk images.

Previously you might have typed:

$ guestfish
><fs> alloc test1.img 100M
><fs> run
><fs> part-disk /dev/sda mbr
><fs> mkfs ext4 /dev/sda1

now you can do the same with:

$ guestfish -N fs:ext4

Some tests have also been updated to use this new
functionality.
This commit is contained in:
Richard Jones
2010-04-22 10:42:58 +01:00
parent 89486c50ea
commit 4a9b979a31
17 changed files with 536 additions and 156 deletions

10
TODO
View File

@@ -212,16 +212,6 @@ ntfsclone
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
---------------

View File

@@ -45,6 +45,7 @@ guestfish_SOURCES = \
glob.c \
lcd.c \
more.c \
prep.c \
rc.c \
reopen.c \
tilde.c \

View File

@@ -28,88 +28,47 @@
#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)
if (alloc_disk (argv[0], argv[1], 1, 0) == -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]);
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
if (close (fd) == -1) {
perror (argv[0]);
unlink (argv[0]);
return -1;
}
if (guestfs_add_drive (g, argv[0]) == -1) {
unlink (argv[0]);
return -1;
}
return 0;
}
int
do_sparse (const char *cmd, int argc, char *argv[])
{
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 (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
alloc_disk (const char *filename, const char *size_str, int add, int sparse)
{
off_t size;
int fd;
char c = 0;
if (parse_size (size_str, &size) == -1)
return -1;
if (!guestfs_is_config (g)) {
@@ -117,35 +76,67 @@ do_sparse (const char *cmd, int argc, char *argv[])
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);
if (write (fd, &c, 1) != 1) {
perror ("write");
close (fd);
unlink (argv[0]);
return -1;
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 (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;

View File

@@ -42,18 +42,21 @@
#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);
@@ -119,6 +122,7 @@ usage (int status)
" --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"
@@ -147,7 +151,7 @@ main (int argc, char *argv[])
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' },
@@ -156,6 +160,7 @@ main (int argc, char *argv[])
{ "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 },
@@ -174,6 +179,8 @@ main (int argc, char *argv[])
int inspector = 0;
int option_index;
struct sigaction sa;
char next_drive = 'a';
int next_prepared_drive = 1;
initialize_readline ();
@@ -259,6 +266,36 @@ main (int argc, char *argv[])
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;
@@ -342,8 +379,8 @@ main (int argc, char *argv[])
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);
}
@@ -396,9 +433,12 @@ main (int argc, char *argv[])
/* 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);
}
@@ -495,7 +535,8 @@ add_drives (struct drv *drv)
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);
@@ -504,6 +545,15 @@ add_drives (struct drv *drv)
}
}
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)
{

View File

@@ -85,6 +85,8 @@ extern char *complete_dest_paths_generator (const char *text, int state);
/* 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[]);
@@ -101,6 +103,14 @@ extern int do_glob (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[],

View File

@@ -75,14 +75,25 @@ in the virtual machine:
=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`
@@ -159,9 +170,9 @@ Typical usage is either:
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)>.
@@ -191,6 +202,13 @@ or you can use the L<virt-list-filesystems(1)> program.
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
@@ -205,6 +223,9 @@ The option must always be used if the disk image or virtual machine
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>.
@@ -486,6 +507,51 @@ user ID of the process, and C<$PID> is the process ID of the server.
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

305
fish/prep.c Normal file
View File

@@ -0,0 +1,305 @@
/* 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);
}

View File

@@ -76,6 +76,7 @@ fish/fish.c
fish/glob.c
fish/lcd.c
fish/more.c
fish/prep.c
fish/rc.c
fish/reopen.c
fish/tilde.c

View File

@@ -23,12 +23,7 @@ set -e
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/

View File

@@ -28,12 +28,7 @@ set -e
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

View File

@@ -49,13 +49,7 @@ get-memsize
-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

View File

@@ -24,9 +24,7 @@ set -e
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

View File

@@ -32,7 +32,7 @@ export LIBGUESTFS_DEBUG=1
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

View File

@@ -22,16 +22,9 @@
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"
@@ -40,4 +33,4 @@ echo "Expect: write: /test: No space left on device"
ping-daemon
EOF
rm -f test.img
rm -f test1.img

View File

@@ -20,12 +20,9 @@
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
@@ -38,4 +35,4 @@ run
ping-daemon
EOF
rm -f test.img
rm -f test1.img

View File

@@ -20,12 +20,9 @@
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) &
@@ -38,4 +35,4 @@ run
ping-daemon
EOF
rm -f test.pid test.img
rm -f test.pid test1.img

View File

@@ -20,12 +20,9 @@
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
@@ -39,4 +36,4 @@ run
ping-daemon
EOF
rm -f test.pid test.img
rm -f test.pid test1.img