This is the same as the previous patch, but the partition type is now chosen automatically from mbr or gpt, unless the user expresses a preference. https://gb.redhat.com/archives/libguestfs/2012-January/msg00136.html Rich.
Richard W.M. Jones
2012-Jan-17 18:57 UTC
[Libguestfs] [PATCH 1/2] fish options parsing: Allow add_drives to be called multiple times.
From: "Richard W.M. Jones" <rjones at redhat.com> Don't leak old drv->device when add_drives is called multiple times. --- fish/options.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/fish/options.c b/fish/options.c index 48c8e1c..f652389 100644 --- a/fish/options.c +++ b/fish/options.c @@ -43,6 +43,9 @@ add_drives (struct drv *drv, char next_drive) if (drv) { next_drive = add_drives (drv->next, next_drive); + free (drv->device); + drv->device = NULL; + if (asprintf (&drv->device, "/dev/sd%c", next_drive) == -1) { perror ("asprintf"); exit (EXIT_FAILURE); -- 1.7.6
Richard W.M. Jones
2012-Jan-17 18:57 UTC
[Libguestfs] [PATCH 2/2] New tool: virt-format: erase and make blank disks.
From: "Richard W.M. Jones" <rjones at redhat.com> This tool allows you to easily reformat a disk, creating a blank disk with optional partition, LVM and empty filesystem. --- .gitignore | 4 + Makefile.am | 3 +- configure.ac | 1 + format/Makefile.am | 78 ++++++++ format/format.c | 450 +++++++++++++++++++++++++++++++++++++++++++++++ format/virt-format.pod | 207 ++++++++++++++++++++++ po/POTFILES.in | 1 + src/guestfs.pod | 5 + tests/extra/Makefile.am | 1 + tools/virt-make-fs | 3 + 10 files changed, 752 insertions(+), 1 deletions(-) create mode 100644 format/Makefile.am create mode 100644 format/format.c create mode 100755 format/virt-format.pod diff --git a/.gitignore b/.gitignore index 0611975..36411aa 100644 --- a/.gitignore +++ b/.gitignore @@ -105,6 +105,9 @@ fish/virt-copy-in.1 fish/virt-copy-out.1 fish/virt-tar-in.1 fish/virt-tar-out.1 +format/stamp-virt-format.pod +format/virt-format +format/virt-format.1 fuse/guestmount fuse/guestmount.1 fuse/stamp-guestmount.pod @@ -145,6 +148,7 @@ html/virt-copy-out.1.html html/virt-df.1.html html/virt-edit.1.html html/virt-filesystems.1.html +html/virt-format.1.html html/virt-inspector.1.html html/virt-list-filesystems.1.html html/virt-list-partitions.1.html diff --git a/Makefile.am b/Makefile.am index d14cc12..22ae04e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -52,7 +52,7 @@ SUBDIRS += test-tool SUBDIRS += fish # virt-tools in C. -SUBDIRS += align cat df edit inspector rescue +SUBDIRS += align cat df edit format inspector rescue # Language bindings. if HAVE_PERL @@ -187,6 +187,7 @@ HTMLFILES = \ html/virt-df.1.html \ html/virt-edit.1.html \ html/virt-filesystems.1.html \ + html/virt-format.1.html \ html/virt-inspector.1.html \ html/virt-list-filesystems.1.html \ html/virt-list-partitions.1.html \ diff --git a/configure.ac b/configure.ac index d8abf71..fa97479 100644 --- a/configure.ac +++ b/configure.ac @@ -1018,6 +1018,7 @@ AC_CONFIG_FILES([Makefile erlang/examples/Makefile examples/Makefile fish/Makefile + format/Makefile fuse/Makefile generator/Makefile gnulib/lib/Makefile diff --git a/format/Makefile.am b/format/Makefile.am new file mode 100644 index 0000000..b3ff216 --- /dev/null +++ b/format/Makefile.am @@ -0,0 +1,78 @@ +# libguestfs virt format tool +# Copyright (C) 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +include $(top_srcdir)/subdir-rules.mk + +EXTRA_DIST = \ + virt-format.pod + +CLEANFILES = stamp-virt-format.pod + +bin_PROGRAMS = virt-format + +SHARED_SOURCE_FILES = \ + ../fish/config.c \ + ../fish/inspect.c \ + ../fish/keys.c \ + ../fish/options.h \ + ../fish/options.c \ + ../fish/virt.c + +virt_format_SOURCES = \ + $(SHARED_SOURCE_FILES) \ + format.c + +virt_format_CFLAGS = \ + -DGUESTFS_WARN_DEPRECATED=1 \ + -I$(top_srcdir)/src -I$(top_builddir)/src \ + -I$(top_srcdir)/fish \ + -I$(srcdir)/../gnulib/lib -I../gnulib/lib \ + -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ + $(LIBCONFIG_CFLAGS) \ + $(LIBVIRT_CFLAGS) + +virt_format_LDADD = \ + $(LIBCONFIG_LIBS) \ + $(top_builddir)/src/libguestfs.la \ + ../gnulib/lib/libgnu.la \ + $(LIBVIRT_LIBS) + +# Manual pages and HTML files for the website. +man_MANS = virt-format.1 +noinst_DATA = $(top_builddir)/html/virt-format.1.html + +virt-format.1 $(top_builddir)/html/virt-format.1.html: stamp-virt-format.pod + +stamp-virt-format.pod: virt-format.pod + $(top_builddir)/podwrapper.sh \ + --man virt-format.1 \ + --html $(top_builddir)/html/virt-format.1.html \ + $< + touch $@ + +# Tests. + +# random_val := $(shell awk 'BEGIN{srand(); print 1+int(255*rand())}' < /dev/null) + +# TESTS_ENVIRONMENT = \ +# MALLOC_PERTURB_=$(random_val) \ +# LD_LIBRARY_PATH=$(top_builddir)/src/.libs \ +# LIBGUESTFS_PATH=$(top_builddir)/appliance \ +# TMPDIR=$(top_builddir) + +# TESTS = test-virt-format.sh diff --git a/format/format.c b/format/format.c new file mode 100644 index 0000000..c701bf7 --- /dev/null +++ b/format/format.c @@ -0,0 +1,450 @@ +/* virt-format + * Copyright (C) 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <inttypes.h> +#include <unistd.h> +#include <getopt.h> +#include <locale.h> +#include <assert.h> +#include <libintl.h> + +#include "progname.h" +#include "c-ctype.h" + +#include "guestfs.h" +#include "options.h" + +/* These globals are shared with options.c. */ +guestfs_h *g; + +int read_only = 0; +int live = 0; +int verbose = 0; +int keys_from_stdin = 0; +int echo_keys = 0; +int inspector = 0; +const char *libvirt_uri = NULL; + +static const char *filesystem = NULL; +static const char *vg = NULL, *lv = NULL; +static const char *partition = "DEFAULT"; +static int wipe = 0; + +static void parse_vg_lv (const char *lvm); +static int do_format (void); +static int do_rescan (char **devices); + +static inline char * +bad_cast (char const *s) +{ + return (char *) s; +} + +static void __attribute__((noreturn)) +usage (int status) +{ + char *warning + _("IMPORTANT NOTE: This program ERASES ALL DATA on disks."); + + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n%s\n"), + program_name, warning); + else { + fprintf (stdout, + _("%s: erase and make a blank disk\n" + "Copyright (C) 2012 Red Hat Inc.\n" + "\n" + "%s\n" + "\n" + "Usage:\n" + " %s [--options] -a disk.img [-a disk.img ...]\n" + "Options:\n" + " -a|--add image Add image\n" + " --filesystem=.. Create empty filesystem\n" + " --format[=raw|..] Force disk format for -a option\n" + " --help Display brief help\n" + " --lvm=.. Create Linux LVM2 logical volume\n" + " --partition=.. Create / set partition type\n" + " -v|--verbose Verbose messages\n" + " -V|--version Display version and exit\n" + " --wipe Write zeroes over whole disk\n" + " -x Trace libguestfs API calls\n" + "For more information, see the manpage %s(1).\n" + "\n" + "%s\n\n"), + program_name, warning, program_name, program_name, + warning); + } + exit (status); +} + +int +main (int argc, char *argv[]) +{ + /* Set global program name that is not polluted with libtool artifacts. */ + set_program_name (argv[0]); + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEBASEDIR); + textdomain (PACKAGE); + + enum { HELP_OPTION = CHAR_MAX + 1 }; + + static const char *options = "a:c:d:qvVx"; + static const struct option long_options[] = { + { "add", 1, 0, 'a' }, + { "filesystem", 1, 0, 0 }, + { "format", 2, 0, 0 }, + { "help", 0, 0, HELP_OPTION }, + { "lvm", 2, 0, 0 }, + { "partition", 2, 0, 0 }, + { "verbose", 0, 0, 'v' }, + { "version", 0, 0, 'V' }, + { "wipe", 0, 0, 0 }, + { 0, 0, 0, 0 } + }; + struct drv *drvs = NULL; + struct drv *drv; + const char *format = NULL; + int c; + int option_index; + int retry, retries; + + g = guestfs_create (); + if (g == NULL) { + fprintf (stderr, _("guestfs_create: failed to create handle\n")); + exit (EXIT_FAILURE); + } + + argv[0] = bad_cast (program_name); + + for (;;) { + c = getopt_long (argc, argv, options, long_options, &option_index); + if (c == -1) break; + + switch (c) { + case 0: /* options which are long only */ + if (STREQ (long_options[option_index].name, "format")) { + if (!optarg || STREQ (optarg, "")) + format = NULL; + else + format = optarg; + } else if (STREQ (long_options[option_index].name, "filesystem")) { + if (STREQ (optarg, "none")) + filesystem = NULL; + else if (optarg[0] == '-') { /* eg: --filesystem --lvm */ + fprintf (stderr, _("%s: no filesystem was specified\n"), + program_name); + exit (EXIT_FAILURE); + } else + filesystem = optarg; + } else if (STREQ (long_options[option_index].name, "lvm")) { + if (vg || lv) { + fprintf (stderr, + _("%s: --lvm option cannot be given multiple times\n"), + program_name); + exit (EXIT_FAILURE); + } + if (optarg == NULL) { + vg = strdup ("VG"); + lv = strdup ("LV"); + if (!vg || !lv) { perror ("strdup"); exit (EXIT_FAILURE); } + } + else if (STREQ (optarg, "none")) + vg = lv = NULL; + else + parse_vg_lv (optarg); + } else if (STREQ (long_options[option_index].name, "partition")) { + if (optarg == NULL) + partition = "DEFAULT"; + else if (STREQ (optarg, "none")) + partition = NULL; + else + partition = optarg; + } else if (STREQ (long_options[option_index].name, "wipe")) { + wipe = 1; + } else { + fprintf (stderr, _("%s: unknown long option: %s (%d)\n"), + program_name, long_options[option_index].name, option_index); + exit (EXIT_FAILURE); + } + break; + + case 'a': + OPTION_a; + break; + + case 'v': + OPTION_v; + break; + + case 'V': + OPTION_V; + break; + + case 'x': + OPTION_x; + break; + + case HELP_OPTION: + usage (EXIT_SUCCESS); + + default: + usage (EXIT_FAILURE); + } + } + + /* These are really constants, but they have to be variables for the + * options parsing code. Assert here that they have known-good + * values. + */ + assert (read_only == 0); + assert (inspector == 0); + assert (live == 0); + + /* Must be no extra arguments on the command line. */ + if (optind != argc) + usage (EXIT_FAILURE); + + /* The user didn't specify any drives to format. */ + if (drvs == NULL) + usage (EXIT_FAILURE); + + /* Because the libguestfs kernel can get stuck rereading the + * partition table after things have been erased, we sometimes need + * to completely restart the guest. Hence this complex retry logic. + */ + for (retries = 0; retries <= 1; ++retries) { + /* Add domains/drives from the command line (for a single guest). */ + add_drives (drvs, 'a'); + + if (guestfs_launch (g) == -1) + exit (EXIT_FAILURE); + + /* Perform the format. */ + retry = do_format (); + if (!retry) + break; + + if (retries == 0) { + /* We're going to silently retry, after reopening the connection. */ + guestfs_h *g2; + + g2 = guestfs_create (); + guestfs_set_verbose (g2, guestfs_get_verbose (g)); + guestfs_set_trace (g2, guestfs_get_trace (g)); + + guestfs_close (g); + g = g2; + } + else { + /* Failed. */ + fprintf (stderr, + _("%s: failed to rescan the disks after two attempts. This\n" + "may mean there is some sort of partition table or disk\n" + "data which we are unable to remove. If you think this\n" + "is a bug, please file a bug at http://libguestfs.org/\n"), + program_name); + exit (EXIT_FAILURE); + } + } + + /* Free up data structures. */ + free_drives (drvs); + + guestfs_close (g); + + exit (EXIT_SUCCESS); +} + +/* Parse lvm string of the form "/dev/VG/LV" or "VG/LV". + * This sets the global variables 'vg' and 'lv', or exits on failure. + */ +static void +parse_vg_lv (const char *lvm) +{ + size_t i; + + if (STRPREFIX (lvm, "/dev/")) + lvm += 5; + + i = strcspn (lvm, "/"); + if (lvm[i]) { + vg = strndup (lvm, i); + lv = strdup (lvm + i + 1); + + if (!vg || !lv) { + perror ("strdup"); + exit (EXIT_FAILURE); + } + } else { + cannot_parse: + fprintf (stderr, _("%s: cannot parse --lvm option (%s)\n"), + program_name, lvm); + exit (EXIT_FAILURE); + } + + if (strchr (vg, '/') || strchr (lv, '/')) + goto cannot_parse; +} + +/* Returns 0 on success, 1 if we need to retry. */ +static int +do_format (void) +{ + char **devices; + size_t i, pass; + + devices = guestfs_list_devices (g); + if (devices == NULL) + exit (EXIT_FAILURE); + + /* Erase the disks. */ + if (!wipe) { + char **parts; + + /* No wipe, but get rid of LVM metadata by erasing each partition. */ + parts = guestfs_list_partitions (g); + if (parts == NULL) + exit (EXIT_FAILURE); + + for (i = 0; parts[i] != NULL; ++i) { + if (guestfs_zero (g, parts[i]) == -1) + exit (EXIT_FAILURE); + free (parts[i]); + } + free (parts); + + /* Then erase the partition table on each device. */ + for (i = 0; devices[i] != NULL; ++i) { + if (guestfs_zero (g, devices[i]) == -1) + exit (EXIT_FAILURE); + } + } + else /* wipe */ { + for (i = 0; devices[i] != NULL; ++i) { + if (guestfs_zero_device (g, devices[i]) == -1) + exit (EXIT_FAILURE); + } + } + + if (do_rescan (devices)) + return 1; /* which means, reopen the handle and retry */ + + /* Format each disk. */ + for (i = 0; devices[i] != NULL; ++i) { + char *dev = devices[i]; + int free_dev = 0; + + if (partition) { + const char *ptype = partition; + int64_t dev_size; + + /* If partition has the magic value "DEFAULT", choose either MBR or GPT.*/ + if (STREQ (partition, "DEFAULT")) { + dev_size = guestfs_blockdev_getsize64 (g, devices[i]); + if (dev_size == -1) + exit (EXIT_FAILURE); + ptype = dev_size < INT64_C(2)*1024*1024*1024*1024 ? "mbr" : "gpt"; + } + + if (guestfs_part_disk (g, devices[i], ptype) == -1) + exit (EXIT_FAILURE); + if (asprintf (&dev, "%s1", devices[i]) == -1) { + perror ("asprintf"); + exit (EXIT_FAILURE); + } + free_dev = 1; + } + + if (vg && lv) { + char *devs[2] = { dev, NULL }; + + if (guestfs_pvcreate (g, dev) == -1) + exit (EXIT_FAILURE); + + if (guestfs_vgcreate (g, vg, devs) == -1) + exit (EXIT_FAILURE); + + if (guestfs_lvcreate (g, lv, vg, 32) == -1) /* 32 MB is smallest LV */ + exit (EXIT_FAILURE); + + if (free_dev) + free (dev); + if (asprintf (&dev, "/dev/%s/%s", vg, lv) == -1) { + perror ("asprintf"); + exit (EXIT_FAILURE); + } + free_dev = 1; + + if (guestfs_lvresize_free (g, dev, 100) == -1) + exit (EXIT_FAILURE); + } + + if (filesystem) { + if (guestfs_mkfs_opts (g, filesystem, dev, -1) == -1) + exit (EXIT_FAILURE); + } + + if (free_dev) + free (dev); + } + + if (guestfs_sync (g) == -1) + exit (EXIT_FAILURE); + + /* Free device list. */ + for (i = 0; devices[i] != NULL; ++i) + free (devices[i]); + free (devices); + + return 0; +} + +/* Rescan everything so the kernel knows that there are no partition + * tables, VGs etc. Returns 0 on success, 1 if we need to retry. + */ +static int +do_rescan (char **devices) +{ + size_t i; + int errors = 0; + guestfs_error_handler_cb old_error_cb; + void *old_error_data; + + old_error_cb = guestfs_get_error_handler (g, &old_error_data); + guestfs_set_error_handler (g, NULL, NULL); + + for (i = 0; devices[i] != NULL; ++i) { + if (guestfs_blockdev_rereadpt (g, devices[i]) == -1) + errors++; + } + + if (guestfs_vgscan (g) == -1) + errors++; + + guestfs_set_error_handler (g, old_error_cb, old_error_data); + + return errors ? 1 : 0; +} diff --git a/format/virt-format.pod b/format/virt-format.pod new file mode 100755 index 0000000..0b9c52b --- /dev/null +++ b/format/virt-format.pod @@ -0,0 +1,207 @@ +=encoding utf8 + +=head1 NAME + +virt-format - Erase and make a blank disk + +=head1 SYNOPSIS + + virt-format [--options] -a disk.img [-a disk.img ...] + +=head1 DESCRIPTION + +Virt-format takes an existing disk file (or it can be a host +partition, LV etc), B<erases all data on it>, and formats it as a +blank disk. It can optionally create partition tables, empty +filesystems, logical volumes and more. + +To create a disk containing data, you may be better to use +L<virt-make-fs(1)>. If you are creating a blank disk to use in +L<guestfish(1)>, you should instead use the guestfish I<-N> option. + +Normal usage would be something like this: + + virt-format -a disk.qcow + +or this: + + virt-format -a /dev/VG/LV + +C<disk.qcow> or C</dev/VG/LV> must exist already. B<Any data on these +disks will be erased by these commands>. These commands will create a +single empty partition covering the whole disk, with no filesystem +inside it. + +Additional parameters can be used to control the creation of +partitions, filesystems, etc. The most commonly used options are: + +=over 4 + +=item I<--filesystem=[ext3|ntfs|vfat|...]> + +Create an empty filesystem (C<ext3>, C<ntfs> etc) inside the partition. + +=item I<--lvm[=/dev/VG/LV]> + +Create a Linux LVM2 logical volume on the disk. When used with +I<--filesystem>, the filesystem is created inside the LV. + +=back + +For more information about these and other options, see +L</OPTIONS> below. + +The format of the disk is normally auto-detected, but you can also +force it by using the I<--format> option (q.v.). In situations where +you do not trust the existing content of the disk, then it is +advisable to use this option to avoid possible exploits. + +=head1 OPTIONS + +=over 4 + +=item B<--help> + +Display brief help. + +=item B<-a> file + +=item B<--add> file + +Add I<file>, a disk image, host partition, LV, external USB disk, etc. + +The format of the disk image is auto-detected. To override this and +force a particular format use the I<--format=..> option. + +B<Any existing data on the disk is erased.> + +=item B<--filesystem=ext3|ntfs|vfat|...> + +Create an empty filesystem of the specified type. Many filesystem +types are supported by libguestfs. + +=item B<--filesystem=none> + +Create no filesystem. This is the default. + +=item B<--format=raw|qcow2|..> + +=item B<--format> + +The default for the I<-a> option is to auto-detect the format of the +disk image. Using this forces the disk format for I<-a> options which +follow on the command line. Using I<--format> with no argument +switches back to auto-detection for subsequent I<-a> options. + +For example: + + virt-format --format=raw -a disk.img + +forces raw format (no auto-detection) for C<disk.img>. + + virt-format --format=raw -a disk.img --format -a another.img + +forces raw format (no auto-detection) for C<disk.img> and reverts to +auto-detection for C<another.img>. + +If you have untrusted raw-format guest disk images, you should use +this option to specify the disk format. This avoids a possible +security problem with malicious guests (CVE-2010-3851). + +=item B<--lvm=/dev/I<VG>/I<LV>> + +Create a Linux LVM2 logical volume called C</dev/I<VG>/I<LV>>. You +can change the name of the volume group and logical volume. + +=item B<--lvm> + +Create a Linux LVM2 logical volume with the default name +(C</dev/VG/LV>). + +=item B<--lvm=none> + +Create no logical volume. This is the default. + +=item B<--partition> + +Create either an MBR or GPT partition covering the whole disk. MBR is +chosen if the disk size is E<lt> 2 TB, GPT if E<ge> 2 TB. + +This is the default. + +=item B<--partition=gpt> + +Create a GPT partition. + +=item B<--partition=mbr> + +Create an MBR partition. + +=item B<--partition=none> + +Create no partition table. Note that Windows may not be able to see +these disks. + +=item B<-v> + +=item B<--verbose> + +Enable verbose messages for debugging. + +=item B<-V> + +=item B<--version> + +Display version number and exit. + +=item B<--wipe> + +Normally virt-format does not wipe data from the disk (because that +takes a long time). Thus if there is data on the disk, it is only +hidden and partially overwritten by virt-format, and it might be +recovered by disk editing tools. + +If you use this option, virt-format writes zeroes over the whole disk +so that previous data is not recoverable. + +=item B<-x> + +Enable tracing of libguestfs API calls. + +=back + +=head1 EXIT STATUS + +This program returns C<0> on success, or C<1> on failure. + +=head1 SEE ALSO + +L<guestfs(3)>, +L<guestfish(1)>, +L<virt-filesystems(1)>, +L<virt-make-fs(1)>, +L<virt-rescue(1)>, +L<virt-resize(1)>, +L<http://libguestfs.org/>. + +=head1 AUTHOR + +Richard W.M. Jones L<http://people.redhat.com/~rjones/> + +=head1 COPYRIGHT + +Copyright (C) 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff --git a/po/POTFILES.in b/po/POTFILES.in index 380a3c7..84972db 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -124,6 +124,7 @@ fish/supported.c fish/tilde.c fish/time.c fish/virt.c +format/format.c fuse/dircache.c fuse/guestmount.c inspector/virt-inspector.c diff --git a/src/guestfs.pod b/src/guestfs.pod index f7740b6..55f6e7f 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -2955,6 +2955,10 @@ L<guestfish(1)>, the command-line shell, and various shell scripts built on top such as L<virt-copy-in(1)>, L<virt-copy-out(1)>, L<virt-tar-in(1)>, L<virt-tar-out(1)>. +=item C<format> + +L<virt-format(1)> command and documentation. + =item C<fuse> L<guestmount(1)>, FUSE (userspace filesystem) built on top of libguestfs. @@ -3271,6 +3275,7 @@ L<virt-copy-out(1)>, L<virt-df(1)>, L<virt-edit(1)>, L<virt-filesystems(1)>, +L<virt-format(1)>, L<virt-inspector(1)>, L<virt-list-filesystems(1)>, L<virt-list-partitions(1)>, diff --git a/tests/extra/Makefile.am b/tests/extra/Makefile.am index 8f34958..83abc65 100644 --- a/tests/extra/Makefile.am +++ b/tests/extra/Makefile.am @@ -102,6 +102,7 @@ test-prerequisites: test-tools-null: $(RUN_VG) ../../fish/guestfish -N part exit $(RUN_VG) ../../align/virt-alignment-scan -a test1.img >/dev/null + $(RUN_VG) ../../format/virt-format -a test1.img >/dev/null rm test1.img $(RUN_VG) ../../cat/virt-filesystems -a /dev/null >/dev/null $(RUN_VG) ../../cat/virt-filesystems -a /dev/null --all --long -h --uuid >/dev/null diff --git a/tools/virt-make-fs b/tools/virt-make-fs index d4e231b..3afbb43 100755 --- a/tools/virt-make-fs +++ b/tools/virt-make-fs @@ -54,6 +54,8 @@ which can be useful if you want to attach these filesystems to existing virtual machines (eg. to import large amounts of read-only data to a VM). +To create blank disks, use L<virt-format(1)>. + Basic usage is: virt-make-fs input output.img @@ -557,6 +559,7 @@ manual page L<sh(1)> for details. =head1 SEE ALSO L<guestfish(1)>, +L<virt-format(1)>, L<virt-resize(1)>, L<virt-tar-in(1)>, L<mkisofs(1)>, -- 1.7.6