mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
New tool: virt-format: erase and make blank disks.
This tool allows you to easily reformat a disk, creating a blank disk with optional partition, LVM and empty filesystem.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -1018,6 +1018,7 @@ AC_CONFIG_FILES([Makefile
|
||||
erlang/examples/Makefile
|
||||
examples/Makefile
|
||||
fish/Makefile
|
||||
format/Makefile
|
||||
fuse/Makefile
|
||||
generator/Makefile
|
||||
gnulib/lib/Makefile
|
||||
|
||||
78
format/Makefile.am
Normal file
78
format/Makefile.am
Normal file
@@ -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
|
||||
456
format/format.c
Normal file
456
format/format.c
Normal file
@@ -0,0 +1,456 @@
|
||||
/* 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;
|
||||
int ret;
|
||||
|
||||
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)) {
|
||||
ret = 1; /* which means, reopen the handle and retry */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
/* Free device list. */
|
||||
for (i = 0; devices[i] != NULL; ++i)
|
||||
free (devices[i]);
|
||||
free (devices);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
207
format/virt-format.pod
Executable file
207
format/virt-format.pod
Executable file
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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)>,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)>,
|
||||
|
||||
Reference in New Issue
Block a user