rescue: Implement -m and -i options.

`virt-rescue -a disk -i' does the right thing.

`-m' was previously an alternate form of `--memsize'.  By sniffing the
parameter we can make `-m MB' continue to work, while also allowing
`-m' to be used as a short form for the `--mount' option.

This also removes most of the description of `--suggest' from the man
page, since it is no longer needed.
This commit is contained in:
Richard W.M. Jones
2017-03-03 13:52:31 +00:00
parent 32d6080144
commit 33d2ae7961
4 changed files with 126 additions and 56 deletions

View File

@@ -35,7 +35,7 @@ virt_rescue_CPPFLAGS = \
-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
-I$(top_srcdir)/lib -I$(top_builddir)/lib \
-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
-I$(top_srcdir)/fish \
-I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \
-I$(srcdir)/../gnulib/lib -I../gnulib/lib
virt_rescue_CFLAGS = \
@@ -43,6 +43,7 @@ virt_rescue_CFLAGS = \
$(LIBXML2_CFLAGS)
virt_rescue_LDADD = \
$(top_builddir)/common/windows/libwindows.la \
$(top_builddir)/common/options/liboptions.la \
$(top_builddir)/common/utils/libutils.la \
$(top_builddir)/lib/libguestfs.la \

View File

@@ -23,7 +23,6 @@
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
#include <errno.h>
#include <error.h>
@@ -37,9 +36,11 @@
#include "full-write.h"
#include "getprogname.h"
#include "ignore-value.h"
#include "nonblocking.h"
#include "xvasprintf.h"
#include "guestfs.h"
#include "windows.h"
#include "options.h"
#include "display-options.h"
@@ -87,7 +88,9 @@ usage (int status)
" -d|--domain guest Add disks from libvirt guest\n"
" --format[=raw|..] Force disk format for -a option\n"
" --help Display brief help\n"
" -m|--memsize MB Set memory size in megabytes\n"
" -i|--inspector Automatically mount filesystems\n"
" -m|--mount dev[:mnt[:opts[:fstype]] Mount dev on mnt (if omitted, /)\n"
" --memsize MB Set memory size in megabytes\n"
" --network Enable network\n"
" -r|--ro Access read-only\n"
" --scratch[=N] Add scratch disk(s)\n"
@@ -116,7 +119,7 @@ main (int argc, char *argv[])
enum { HELP_OPTION = CHAR_MAX + 1 };
static const char options[] = "a:c:d:m:rvVwx";
static const char options[] = "a:c:d:im:rvVwx";
static const struct option long_options[] = {
{ "add", 1, 0, 'a' },
{ "append", 1, 0, 0 },
@@ -124,8 +127,10 @@ main (int argc, char *argv[])
{ "domain", 1, 0, 'd' },
{ "format", 2, 0, 0 },
{ "help", 0, 0, HELP_OPTION },
{ "inspector", 0, 0, 'i' },
{ "long-options", 0, 0, 0 },
{ "memsize", 1, 0, 'm' },
{ "mount", 1, 0, 'm' },
{ "memsize", 1, 0, 0 },
{ "network", 0, 0, 0 },
{ "ro", 0, 0, 'r' },
{ "rw", 0, 0, 'w' },
@@ -140,13 +145,16 @@ main (int argc, char *argv[])
};
struct drv *drvs = NULL;
struct drv *drv;
struct mp *mps = NULL;
struct mp *mp;
char *p;
const char *format = NULL;
bool format_consumed = true;
int c;
int option_index;
int network = 0;
const char *append = NULL;
int memsize = 0;
int memsize = 0, m;
int smp = 0;
int suggest = 0;
char *append_full;
@@ -196,6 +204,10 @@ main (int argc, char *argv[])
_("--scratch parameter '%s' should be >= 1"), optarg);
add_scratch_disks (n, &drvs);
}
} else if (STREQ (long_options[option_index].name, "memsize")) {
if (sscanf (optarg, "%d", &memsize) != 1)
error (EXIT_FAILURE, 0,
_("could not parse memory size '%s'"), optarg);
} else
error (EXIT_FAILURE, 0,
_("unknown long option: %s (%d)"),
@@ -214,10 +226,19 @@ main (int argc, char *argv[])
OPTION_d;
break;
case 'i':
OPTION_i;
break;
case 'm':
if (sscanf (optarg, "%d", &memsize) != 1)
error (EXIT_FAILURE, 0,
_("could not parse memory size '%s'"), optarg);
/* For backwards compatibility with virt-rescue <= 1.36, we
* must handle -m <number> as a synonym for --memsize.
*/
if (sscanf (optarg, "%d", &m) == 1)
memsize = m;
else {
OPTION_m;
}
break;
case 'r':
@@ -288,7 +309,6 @@ main (int argc, char *argv[])
* options parsing code. Assert here that they have known-good
* values.
*/
assert (inspector == 0);
assert (keys_from_stdin == 0);
assert (echo_keys == 0);
assert (live == 0);
@@ -332,12 +352,6 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
free (append_full);
/* Add drives. */
add_drives (drvs, 'a');
/* Free up data structures, no longer needed after this point. */
free_drives (drvs);
/* Add an event handler to print "log messages". These will be the
* output of the appliance console during launch and shutdown.
* After launch, we will read the console messages directly from the
@@ -347,21 +361,50 @@ main (int argc, char *argv[])
GUESTFS_EVENT_APPLIANCE, 0, NULL) == -1)
exit (EXIT_FAILURE);
/* Run the appliance. */
/* Do the guest drives and mountpoints. */
add_drives (drvs, 'a');
if (guestfs_launch (g) == -1)
exit (EXIT_FAILURE);
if (inspector)
inspect_mount ();
mount_mps (mps);
free_drives (drvs);
free_mps (mps);
/* Also bind-mount /dev etc under /sysroot, if -i was given. */
if (inspector) {
CLEANUP_FREE_STRING_LIST char **roots;
int windows;
roots = guestfs_inspect_get_roots (g);
windows = roots && roots[0] && is_windows (g, roots[0]);
if (!windows) {
const char *cmd[5] = { "mount", "--rbind", NULL, NULL, NULL };
char *r;
cmd[2] = "/dev"; cmd[3] = "/sysroot/dev";
r = guestfs_debug (g, "sh", (char **) cmd);
free (r);
cmd[2] = "/proc"; cmd[3] = "/sysroot/proc";
r = guestfs_debug (g, "sh", (char **) cmd);
free (r);
cmd[2] = "/sys"; cmd[3] = "/sysroot/sys";
r = guestfs_debug (g, "sh", (char **) cmd);
free (r);
}
}
sock = guestfs_internal_get_console_socket (g);
if (sock == -1)
exit (EXIT_FAILURE);
/* Try to set all sockets to non-blocking. */
if (fcntl (STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1)
perror ("could not set stdin to non-blocking");
if (fcntl (STDOUT_FILENO, F_SETFL, O_NONBLOCK) == -1)
perror ("could not set stdout to non-blocking");
if (fcntl (sock, F_SETFL, O_NONBLOCK) == -1)
perror ("could not set console socket to non-blocking");
ignore_value (set_nonblocking_flag (STDIN_FILENO, 1));
ignore_value (set_nonblocking_flag (STDOUT_FILENO, 1));
ignore_value (set_nonblocking_flag (sock, 1));
/* Save the initial state of the tty so we always have the original
* state to go back to.

View File

@@ -6,9 +6,7 @@ virt-rescue - Run a rescue shell on a virtual machine
virt-rescue [--options] -d domname
virt-rescue [--options] -a disk.img [-a disk.img ...]
virt-rescue --suggest (-d domname | -a disk.img ...)
virt-rescue [--options] -a disk.img [-a disk.img ...] [-i]
Old style:
@@ -26,13 +24,13 @@ machine or disk image.
You can run virt-rescue on any virtual machine known to libvirt, or
directly on disk image(s):
virt-rescue -d GuestName
virt-rescue -d GuestName -i
virt-rescue --ro -a /path/to/disk.img
virt-rescue --ro -a /path/to/disk.img -i
virt-rescue -a /dev/sdc
For live VMs you I<must> use the --ro option.
For live VMs you I<must> use the I<--ro> option.
When you run virt-rescue on a virtual machine or disk image, you are
placed in an interactive bash shell where you can use many ordinary
@@ -41,26 +39,10 @@ rescue appliance. You must mount the virtual machine's filesystems by
hand. There is an empty directory called F</sysroot> where you can
mount filesystems.
You can get virt-rescue to suggest mount commands for you by using the
I<--suggest> option (in another terminal):
$ virt-rescue --suggest -d Fedora15
Inspecting the virtual machine or disk image ...
This disk contains one or more operating systems. You can use these
mount commands in virt-rescue (at the ><rescue> prompt) to mount the
filesystems.
# /dev/vg_f15x32/lv_root is the root of a linux operating system
# type: linux, distro: fedora, version: 15.0
# Fedora release 15 (Lovelock)
mount /dev/vg_f15x32/lv_root /sysroot/
mount /dev/vda1 /sysroot/boot
mount --bind /dev /sysroot/dev
mount --bind /dev/pts /sysroot/dev/pts
mount --bind /proc /sysroot/proc
mount --bind /sys /sysroot/sys
To automatically mount the virtual machine's filesystems under
F</sysroot> use the I<-i> option. This uses libguestfs inspection to
find the filesystems and mount them in the right place. You can also
mount filesystems individually using the I<-m> option.
Another way is to list the logical volumes (with L<lvs(8)>) and
partitions (with L<parted(8)>) and mount them by hand:
@@ -170,7 +152,15 @@ 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<-m> MB
=item B<-i>
=item B<--inspector>
Using L<virt-inspector(1)> code, inspect the disks looking for
an operating system and mount filesystems as they would be
mounted on the real virtual machine.
The filesystems are mounted on F</sysroot> in the rescue environment.
=item B<--memsize> MB
@@ -179,6 +169,33 @@ default is set by libguestfs and is small but adequate for running
system tools. The occasional program might need more memory. The
parameter is specified in megabytes.
=item B<-m> dev[:mountpoint[:options[:fstype]]]
=item B<--mount> dev[:mountpoint[:options[:fstype]]]
Mount the named partition or logical volume on the given mountpoint
B<in the guest> (this has nothing to do with mountpoints in the host).
If the mountpoint is omitted, it defaults to F</>. You have to mount
something on F</>.
The filesystems are mounted under F</sysroot> in the rescue environment.
The third (and rarely used) part of the mount parameter is the list of
mount options used to mount the underlying filesystem. If this is not
given, then the mount options are either the empty string or C<ro>
(the latter if the I<--ro> flag is used). By specifying the mount
options, you override this default choice. Probably the only time you
would use this is to enable ACLs and/or extended attributes if the
filesystem can support them:
-m /dev/sda1:/:acl,user_xattr
The fourth part of the parameter is the filesystem driver to use, such
as C<ext3> or C<ntfs>. This is rarely needed, but can be useful if
multiple drivers are valid for a filesystem (eg: C<ext2> and C<ext3>),
or if libguestfs misidentifies a filesystem.
=item B<--network>
Enable QEMU user networking in the guest. See L</NETWORK>.
@@ -217,9 +234,10 @@ Enable N E<ge> 2 virtual CPUs in the rescue appliance.
=item B<--suggest>
Inspect the disk image and suggest what mount commands should be used
to mount the disks. You should use the I<--suggest> option in a
second terminal, then paste the commands into another virt-rescue.
This option was used in older versions of virt-rescue to suggest what
commands you could use to mount filesystems under F</sysroot>. For
the current version of virt-rescue, it is easier to use the I<-i>
option instead.
This option implies I<--ro> and is safe to use even if the guest is up
or if another virt-rescue is running.
@@ -240,7 +258,7 @@ Display version number and exit.
=item B<--rw>
This changes the I<-a> and I<-d> options so that disks are
This changes the I<-a>, I<-d> and I<-m> options so that disks are
added and mounts are done read-write.
See L<guestfish(1)/OPENING DISKS FOR READ AND WRITE>.