`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.
---
appliance/init | 12 +++++--
rescue/Makefile.am | 3 +-
rescue/rescue.c | 87 +++++++++++++++++++++++++++++++++++++-------------
rescue/virt-rescue.pod | 80 ++++++++++++++++++++++++++++------------------
4 files changed, 126 insertions(+), 56 deletions(-)
diff --git a/appliance/init b/appliance/init
index fa42c2b..b951857 100755
--- a/appliance/init
+++ b/appliance/init
@@ -180,6 +180,10 @@ else
# We need a daemon, even in virt-rescue.
$cmd &
+ # XXX This gives a bit of time for virt-rescue to connect to the
+ # daemon and mount any filesystems.
+ sleep 2
+
# Get name of the serial port, from console= passed by libguestfs.
guestfs_serial=$(grep -Eo 'console=[^[:space:]]+' /proc/cmdline |
sed s/console=//)
@@ -208,8 +212,12 @@ else
echo "Welcome to virt-rescue, the libguestfs rescue shell."
echo
echo "Note: The contents of / (root) are the rescue appliance."
- echo "You have to mount the guest's partitions under /sysroot"
- echo "before you can examine them."
+ if ! test -d "/sysroot/dev"; then
+ echo "You have to mount the guest's partitions under /sysroot"
+ echo "before you can examine them."
+ else
+ echo "Use 'cd /sysroot' or 'chroot /sysroot' to see guest
filesystems."
+ fi
echo
run_bash_with_ctty
echo
diff --git a/rescue/Makefile.am b/rescue/Makefile.am
index 99d4b79..c83c434 100644
--- a/rescue/Makefile.am
+++ b/rescue/Makefile.am
@@ -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 \
diff --git a/rescue/rescue.c b/rescue/rescue.c
index 556c344..fb747df 100644
--- a/rescue/rescue.c
+++ b/rescue/rescue.c
@@ -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>
@@ -36,9 +35,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"
@@ -83,7 +84,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"
@@ -112,7 +115,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 },
@@ -120,8 +123,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' },
@@ -136,13 +141,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;
@@ -193,6 +201,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)"),
@@ -211,10 +223,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':
@@ -285,7 +306,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);
@@ -329,12 +349,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
@@ -344,9 +358,41 @@ 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)
@@ -367,12 +413,9 @@ main (int argc, char *argv[])
}
/* 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));
/* Restore the tty settings when the process exits. */
atexit (restore_tty);
diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod
index b8aa326..b651f84 100644
--- a/rescue/virt-rescue.pod
+++ b/rescue/virt-rescue.pod
@@ -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>.
--
2.9.3