Blame SOURCES/0057-rescue-Implement-m-and-i-options.patch

a30de4
From 5b0f9d72d49053d246463b7bb024f21f1c24d983 Mon Sep 17 00:00:00 2001
a30de4
From: "Richard W.M. Jones" <rjones@redhat.com>
a30de4
Date: Fri, 3 Mar 2017 13:52:31 +0000
a30de4
Subject: [PATCH] rescue: Implement -m and -i options.
a30de4
a30de4
`virt-rescue -a disk -i' does the right thing.
a30de4
a30de4
`-m' was previously an alternate form of `--memsize'.  By sniffing the
a30de4
parameter we can make `-m MB' continue to work, while also allowing
a30de4
`-m' to be used as a short form for the `--mount' option.
a30de4
a30de4
This also removes most of the description of `--suggest' from the man
a30de4
page, since it is no longer needed.
a30de4
a30de4
(cherry picked from commit 33d2ae796119ae5dd38e2afcbf1ba4216bd99846)
a30de4
---
a30de4
 appliance/init         | 12 +++++--
a30de4
 rescue/Makefile.am     |  3 +-
a30de4
 rescue/rescue.c        | 87 +++++++++++++++++++++++++++++++++++++-------------
a30de4
 rescue/virt-rescue.pod | 80 ++++++++++++++++++++++++++++------------------
a30de4
 4 files changed, 126 insertions(+), 56 deletions(-)
a30de4
a30de4
diff --git a/appliance/init b/appliance/init
a30de4
index ea763c2d3..4133de434 100755
a30de4
--- a/appliance/init
a30de4
+++ b/appliance/init
a30de4
@@ -181,6 +181,10 @@ else
a30de4
     # We need a daemon, even in virt-rescue.
a30de4
     $cmd &
a30de4
 
a30de4
+    # XXX This gives a bit of time for virt-rescue to connect to the
a30de4
+    # daemon and mount any filesystems.
a30de4
+    sleep 2
a30de4
+
a30de4
     # Get name of the serial port, from console= passed by libguestfs.
a30de4
     # XXX Consider using /proc/consoles
a30de4
     guestfs_serial=$(grep -Eo 'console=[^[:space:]]+' /proc/cmdline |
a30de4
@@ -210,8 +214,12 @@ else
a30de4
     echo "Welcome to virt-rescue, the libguestfs rescue shell."
a30de4
     echo
a30de4
     echo "Note: The contents of / (root) are the rescue appliance."
a30de4
-    echo "You have to mount the guest's partitions under /sysroot"
a30de4
-    echo "before you can examine them."
a30de4
+    if ! test -d "/sysroot/dev"; then
a30de4
+        echo "You have to mount the guest's partitions under /sysroot"
a30de4
+        echo "before you can examine them."
a30de4
+    else
a30de4
+        echo "Use 'cd /sysroot' or 'chroot /sysroot' to see guest filesystems."
a30de4
+    fi
a30de4
     echo
a30de4
     run_bash_with_ctty
a30de4
     echo
a30de4
diff --git a/rescue/Makefile.am b/rescue/Makefile.am
a30de4
index 99d4b79ae..c83c43458 100644
a30de4
--- a/rescue/Makefile.am
a30de4
+++ b/rescue/Makefile.am
a30de4
@@ -35,7 +35,7 @@ virt_rescue_CPPFLAGS = \
a30de4
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
a30de4
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
a30de4
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
a30de4
-	-I$(top_srcdir)/fish \
a30de4
+	-I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \
a30de4
 	-I$(srcdir)/../gnulib/lib -I../gnulib/lib
a30de4
 
a30de4
 virt_rescue_CFLAGS = \
a30de4
@@ -43,6 +43,7 @@ virt_rescue_CFLAGS = \
a30de4
 	$(LIBXML2_CFLAGS)
a30de4
 
a30de4
 virt_rescue_LDADD = \
a30de4
+	$(top_builddir)/common/windows/libwindows.la \
a30de4
 	$(top_builddir)/common/options/liboptions.la \
a30de4
 	$(top_builddir)/common/utils/libutils.la \
a30de4
 	$(top_builddir)/lib/libguestfs.la \
a30de4
diff --git a/rescue/rescue.c b/rescue/rescue.c
a30de4
index b145dcd40..2b461378d 100644
a30de4
--- a/rescue/rescue.c
a30de4
+++ b/rescue/rescue.c
a30de4
@@ -23,7 +23,6 @@
a30de4
 #include <string.h>
a30de4
 #include <inttypes.h>
a30de4
 #include <unistd.h>
a30de4
-#include <fcntl.h>
a30de4
 #include <getopt.h>
a30de4
 #include <errno.h>
a30de4
 #include <error.h>
a30de4
@@ -37,9 +36,11 @@
a30de4
 #include "full-write.h"
a30de4
 #include "getprogname.h"
a30de4
 #include "ignore-value.h"
a30de4
+#include "nonblocking.h"
a30de4
 #include "xvasprintf.h"
a30de4
 
a30de4
 #include "guestfs.h"
a30de4
+#include "windows.h"
a30de4
 #include "options.h"
a30de4
 #include "display-options.h"
a30de4
 
a30de4
@@ -87,7 +88,9 @@ usage (int status)
a30de4
               "  -d|--domain guest    Add disks from libvirt guest\n"
a30de4
               "  --format[=raw|..]    Force disk format for -a option\n"
a30de4
               "  --help               Display brief help\n"
a30de4
-              "  -m|--memsize MB      Set memory size in megabytes\n"
a30de4
+              "  -i|--inspector       Automatically mount filesystems\n"
a30de4
+              "  -m|--mount dev[:mnt[:opts[:fstype]] Mount dev on mnt (if omitted, /)\n"
a30de4
+              "  --memsize MB         Set memory size in megabytes\n"
a30de4
               "  --network            Enable network\n"
a30de4
               "  -r|--ro              Access read-only\n"
a30de4
               "  --scratch[=N]        Add scratch disk(s)\n"
a30de4
@@ -116,7 +119,7 @@ main (int argc, char *argv[])
a30de4
 
a30de4
   enum { HELP_OPTION = CHAR_MAX + 1 };
a30de4
 
a30de4
-  static const char options[] = "a:c:d:m:rvVwx";
a30de4
+  static const char options[] = "a:c:d:im:rvVwx";
a30de4
   static const struct option long_options[] = {
a30de4
     { "add", 1, 0, 'a' },
a30de4
     { "append", 1, 0, 0 },
a30de4
@@ -124,8 +127,10 @@ main (int argc, char *argv[])
a30de4
     { "domain", 1, 0, 'd' },
a30de4
     { "format", 2, 0, 0 },
a30de4
     { "help", 0, 0, HELP_OPTION },
a30de4
+    { "inspector", 0, 0, 'i' },
a30de4
     { "long-options", 0, 0, 0 },
a30de4
-    { "memsize", 1, 0, 'm' },
a30de4
+    { "mount", 1, 0, 'm' },
a30de4
+    { "memsize", 1, 0, 0 },
a30de4
     { "network", 0, 0, 0 },
a30de4
     { "ro", 0, 0, 'r' },
a30de4
     { "rw", 0, 0, 'w' },
a30de4
@@ -140,13 +145,16 @@ main (int argc, char *argv[])
a30de4
   };
a30de4
   struct drv *drvs = NULL;
a30de4
   struct drv *drv;
a30de4
+  struct mp *mps = NULL;
a30de4
+  struct mp *mp;
a30de4
+  char *p;
a30de4
   const char *format = NULL;
a30de4
   bool format_consumed = true;
a30de4
   int c;
a30de4
   int option_index;
a30de4
   int network = 0;
a30de4
   const char *append = NULL;
a30de4
-  int memsize = 0;
a30de4
+  int memsize = 0, m;
a30de4
   int smp = 0;
a30de4
   int suggest = 0;
a30de4
   char *append_full;
a30de4
@@ -196,6 +204,10 @@ main (int argc, char *argv[])
a30de4
                    _("--scratch parameter '%s' should be >= 1"), optarg);
a30de4
           add_scratch_disks (n, &drvs);
a30de4
         }
a30de4
+      } else if (STREQ (long_options[option_index].name, "memsize")) {
a30de4
+        if (sscanf (optarg, "%d", &memsize) != 1)
a30de4
+          error (EXIT_FAILURE, 0,
a30de4
+                 _("could not parse memory size '%s'"), optarg);
a30de4
       } else
a30de4
         error (EXIT_FAILURE, 0,
a30de4
                _("unknown long option: %s (%d)"),
a30de4
@@ -214,10 +226,19 @@ main (int argc, char *argv[])
a30de4
       OPTION_d;
a30de4
       break;
a30de4
 
a30de4
+    case 'i':
a30de4
+      OPTION_i;
a30de4
+      break;
a30de4
+
a30de4
     case 'm':
a30de4
-      if (sscanf (optarg, "%d", &memsize) != 1)
a30de4
-        error (EXIT_FAILURE, 0,
a30de4
-               _("could not parse memory size '%s'"), optarg);
a30de4
+      /* For backwards compatibility with virt-rescue <= 1.36, we
a30de4
+       * must handle -m <number> as a synonym for --memsize.
a30de4
+       */
a30de4
+      if (sscanf (optarg, "%d", &m) == 1)
a30de4
+        memsize = m;
a30de4
+      else {
a30de4
+        OPTION_m;
a30de4
+      }
a30de4
       break;
a30de4
 
a30de4
     case 'r':
a30de4
@@ -288,7 +309,6 @@ main (int argc, char *argv[])
a30de4
    * options parsing code.  Assert here that they have known-good
a30de4
    * values.
a30de4
    */
a30de4
-  assert (inspector == 0);
a30de4
   assert (keys_from_stdin == 0);
a30de4
   assert (echo_keys == 0);
a30de4
   assert (live == 0);
a30de4
@@ -332,12 +352,6 @@ main (int argc, char *argv[])
a30de4
     exit (EXIT_FAILURE);
a30de4
   free (append_full);
a30de4
 
a30de4
-  /* Add drives. */
a30de4
-  add_drives (drvs);
a30de4
-
a30de4
-  /* Free up data structures, no longer needed after this point. */
a30de4
-  free_drives (drvs);
a30de4
-
a30de4
   /* Add an event handler to print "log messages".  These will be the
a30de4
    * output of the appliance console during launch and shutdown.
a30de4
    * After launch, we will read the console messages directly from the
a30de4
@@ -347,21 +361,50 @@ main (int argc, char *argv[])
a30de4
                                   GUESTFS_EVENT_APPLIANCE, 0, NULL) == -1)
a30de4
     exit (EXIT_FAILURE);
a30de4
 
a30de4
-  /* Run the appliance. */
a30de4
+  /* Do the guest drives and mountpoints. */
a30de4
+  add_drives (drvs);
a30de4
   if (guestfs_launch (g) == -1)
a30de4
     exit (EXIT_FAILURE);
a30de4
+  if (inspector)
a30de4
+    inspect_mount ();
a30de4
+  mount_mps (mps);
a30de4
+
a30de4
+  free_drives (drvs);
a30de4
+  free_mps (mps);
a30de4
+
a30de4
+  /* Also bind-mount /dev etc under /sysroot, if -i was given. */
a30de4
+  if (inspector) {
a30de4
+    CLEANUP_FREE_STRING_LIST char **roots;
a30de4
+    int windows;
a30de4
+
a30de4
+    roots = guestfs_inspect_get_roots (g);
a30de4
+    windows = roots && roots[0] && is_windows (g, roots[0]);
a30de4
+    if (!windows) {
a30de4
+      const char *cmd[5] = { "mount", "--rbind", NULL, NULL, NULL };
a30de4
+      char *r;
a30de4
+
a30de4
+      cmd[2] = "/dev"; cmd[3] = "/sysroot/dev";
a30de4
+      r = guestfs_debug (g, "sh", (char **) cmd);
a30de4
+      free (r);
a30de4
+
a30de4
+      cmd[2] = "/proc"; cmd[3] = "/sysroot/proc";
a30de4
+      r = guestfs_debug (g, "sh", (char **) cmd);
a30de4
+      free (r);
a30de4
+
a30de4
+      cmd[2] = "/sys"; cmd[3] = "/sysroot/sys";
a30de4
+      r = guestfs_debug (g, "sh", (char **) cmd);
a30de4
+      free (r);
a30de4
+    }
a30de4
+  }
a30de4
 
a30de4
   sock = guestfs_internal_get_console_socket (g);
a30de4
   if (sock == -1)
a30de4
     exit (EXIT_FAILURE);
a30de4
 
a30de4
   /* Try to set all sockets to non-blocking. */
a30de4
-  if (fcntl (STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1)
a30de4
-    perror ("could not set stdin to non-blocking");
a30de4
-  if (fcntl (STDOUT_FILENO, F_SETFL, O_NONBLOCK) == -1)
a30de4
-    perror ("could not set stdout to non-blocking");
a30de4
-  if (fcntl (sock, F_SETFL, O_NONBLOCK) == -1)
a30de4
-    perror ("could not set console socket to non-blocking");
a30de4
+  ignore_value (set_nonblocking_flag (STDIN_FILENO, 1));
a30de4
+  ignore_value (set_nonblocking_flag (STDOUT_FILENO, 1));
a30de4
+  ignore_value (set_nonblocking_flag (sock, 1));
a30de4
 
a30de4
   /* Save the initial state of the tty so we always have the original
a30de4
    * state to go back to.
a30de4
diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod
a30de4
index b8aa32637..b651f84e7 100644
a30de4
--- a/rescue/virt-rescue.pod
a30de4
+++ b/rescue/virt-rescue.pod
a30de4
@@ -6,9 +6,7 @@ virt-rescue - Run a rescue shell on a virtual machine
a30de4
 
a30de4
  virt-rescue [--options] -d domname
a30de4
 
a30de4
- virt-rescue [--options] -a disk.img [-a disk.img ...]
a30de4
-
a30de4
- virt-rescue --suggest (-d domname | -a disk.img ...)
a30de4
+ virt-rescue [--options] -a disk.img [-a disk.img ...] [-i]
a30de4
 
a30de4
 Old style:
a30de4
 
a30de4
@@ -26,13 +24,13 @@ machine or disk image.
a30de4
 You can run virt-rescue on any virtual machine known to libvirt, or
a30de4
 directly on disk image(s):
a30de4
 
a30de4
- virt-rescue -d GuestName
a30de4
+ virt-rescue -d GuestName -i
a30de4
 
a30de4
- virt-rescue --ro -a /path/to/disk.img
a30de4
+ virt-rescue --ro -a /path/to/disk.img -i
a30de4
 
a30de4
  virt-rescue -a /dev/sdc
a30de4
 
a30de4
-For live VMs you I<must> use the --ro option.
a30de4
+For live VMs you I<must> use the I<--ro> option.
a30de4
 
a30de4
 When you run virt-rescue on a virtual machine or disk image, you are
a30de4
 placed in an interactive bash shell where you can use many ordinary
a30de4
@@ -41,26 +39,10 @@ rescue appliance.  You must mount the virtual machine's filesystems by
a30de4
 hand.  There is an empty directory called F</sysroot> where you can
a30de4
 mount filesystems.
a30de4
 
a30de4
-You can get virt-rescue to suggest mount commands for you by using the
a30de4
-I<--suggest> option (in another terminal):
a30de4
-
a30de4
- $ virt-rescue --suggest -d Fedora15
a30de4
- Inspecting the virtual machine or disk image ...
a30de4
- 
a30de4
- This disk contains one or more operating systems.  You can use these
a30de4
- mount commands in virt-rescue (at the ><rescue> prompt) to mount the
a30de4
- filesystems.
a30de4
- 
a30de4
- # /dev/vg_f15x32/lv_root is the root of a linux operating system
a30de4
- # type: linux, distro: fedora, version: 15.0
a30de4
- # Fedora release 15 (Lovelock)
a30de4
- 
a30de4
- mount /dev/vg_f15x32/lv_root /sysroot/
a30de4
- mount /dev/vda1 /sysroot/boot
a30de4
- mount --bind /dev /sysroot/dev
a30de4
- mount --bind /dev/pts /sysroot/dev/pts
a30de4
- mount --bind /proc /sysroot/proc
a30de4
- mount --bind /sys /sysroot/sys
a30de4
+To automatically mount the virtual machine's filesystems under
a30de4
+F</sysroot> use the I<-i> option.  This uses libguestfs inspection to
a30de4
+find the filesystems and mount them in the right place.  You can also
a30de4
+mount filesystems individually using the I<-m> option.
a30de4
 
a30de4
 Another way is to list the logical volumes (with L<lvs(8)>) and
a30de4
 partitions (with L<parted(8)>) and mount them by hand:
a30de4
@@ -170,7 +152,15 @@ If you have untrusted raw-format guest disk images, you should use
a30de4
 this option to specify the disk format.  This avoids a possible
a30de4
 security problem with malicious guests (CVE-2010-3851).
a30de4
 
a30de4
-=item B<-m> MB
a30de4
+=item B<-i>
a30de4
+
a30de4
+=item B<--inspector>
a30de4
+
a30de4
+Using L<virt-inspector(1)> code, inspect the disks looking for
a30de4
+an operating system and mount filesystems as they would be
a30de4
+mounted on the real virtual machine.
a30de4
+
a30de4
+The filesystems are mounted on F</sysroot> in the rescue environment.
a30de4
 
a30de4
 =item B<--memsize> MB
a30de4
 
a30de4
@@ -179,6 +169,33 @@ default is set by libguestfs and is small but adequate for running
a30de4
 system tools.  The occasional program might need more memory.  The
a30de4
 parameter is specified in megabytes.
a30de4
 
a30de4
+=item B<-m> dev[:mountpoint[:options[:fstype]]]
a30de4
+
a30de4
+=item B<--mount> dev[:mountpoint[:options[:fstype]]]
a30de4
+
a30de4
+Mount the named partition or logical volume on the given mountpoint
a30de4
+B<in the guest> (this has nothing to do with mountpoints in the host).
a30de4
+
a30de4
+If the mountpoint is omitted, it defaults to F.  You have to mount
a30de4
+something on F.
a30de4
+
a30de4
+The filesystems are mounted under F</sysroot> in the rescue environment.
a30de4
+
a30de4
+The third (and rarely used) part of the mount parameter is the list of
a30de4
+mount options used to mount the underlying filesystem.  If this is not
a30de4
+given, then the mount options are either the empty string or C<ro>
a30de4
+(the latter if the I<--ro> flag is used).  By specifying the mount
a30de4
+options, you override this default choice.  Probably the only time you
a30de4
+would use this is to enable ACLs and/or extended attributes if the
a30de4
+filesystem can support them:
a30de4
+
a30de4
+ -m /dev/sda1:/:acl,user_xattr
a30de4
+
a30de4
+The fourth part of the parameter is the filesystem driver to use, such
a30de4
+as C<ext3> or C<ntfs>. This is rarely needed, but can be useful if
a30de4
+multiple drivers are valid for a filesystem (eg: C<ext2> and C<ext3>),
a30de4
+or if libguestfs misidentifies a filesystem.
a30de4
+
a30de4
 =item B<--network>
a30de4
 
a30de4
 Enable QEMU user networking in the guest.  See L</NETWORK>.
a30de4
@@ -217,9 +234,10 @@ Enable N E<ge> 2 virtual CPUs in the rescue appliance.
a30de4
 
a30de4
 =item B<--suggest>
a30de4
 
a30de4
-Inspect the disk image and suggest what mount commands should be used
a30de4
-to mount the disks.  You should use the I<--suggest> option in a
a30de4
-second terminal, then paste the commands into another virt-rescue.
a30de4
+This option was used in older versions of virt-rescue to suggest what
a30de4
+commands you could use to mount filesystems under F</sysroot>.  For
a30de4
+the current version of virt-rescue, it is easier to use the I<-i>
a30de4
+option instead.
a30de4
 
a30de4
 This option implies I<--ro> and is safe to use even if the guest is up
a30de4
 or if another virt-rescue is running.
a30de4
@@ -240,7 +258,7 @@ Display version number and exit.
a30de4
 
a30de4
 =item B<--rw>
a30de4
 
a30de4
-This changes the I<-a> and I<-d> options so that disks are
a30de4
+This changes the I<-a>, I<-d> and I<-m> options so that disks are
a30de4
 added and mounts are done read-write.
a30de4
 
a30de4
 See L<guestfish(1)/OPENING DISKS FOR READ AND WRITE>.
a30de4
-- 
a30de4
2.14.3
a30de4