|
|
151578 |
From 0a3e771414378057d0e838c6a45d2f840ff7a8af Mon Sep 17 00:00:00 2001
|
|
|
151578 |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
151578 |
Date: Sat, 4 Mar 2017 15:35:09 +0000
|
|
|
151578 |
Subject: [PATCH] rescue: Move --suggest code to separate file.
|
|
|
151578 |
|
|
|
151578 |
Just code motion.
|
|
|
151578 |
|
|
|
151578 |
(cherry picked from commit 5ea17e97e4413c3db4449ded72b9677cce09444f)
|
|
|
151578 |
---
|
|
|
151578 |
rescue/Makefile.am | 3 +-
|
|
|
151578 |
rescue/rescue.c | 144 -------------------------------------------
|
|
|
151578 |
rescue/rescue.h | 5 ++
|
|
|
151578 |
rescue/suggest.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
151578 |
4 files changed, 182 insertions(+), 145 deletions(-)
|
|
|
151578 |
create mode 100644 rescue/suggest.c
|
|
|
151578 |
|
|
|
151578 |
diff --git a/rescue/Makefile.am b/rescue/Makefile.am
|
|
|
151578 |
index eb60bafa4..d478c8e3d 100644
|
|
|
151578 |
--- a/rescue/Makefile.am
|
|
|
151578 |
+++ b/rescue/Makefile.am
|
|
|
151578 |
@@ -28,7 +28,8 @@ bin_PROGRAMS = virt-rescue
|
|
|
151578 |
virt_rescue_SOURCES = \
|
|
|
151578 |
escape.c \
|
|
|
151578 |
rescue.c \
|
|
|
151578 |
- rescue.h
|
|
|
151578 |
+ rescue.h \
|
|
|
151578 |
+ suggest.c
|
|
|
151578 |
|
|
|
151578 |
virt_rescue_CPPFLAGS = \
|
|
|
151578 |
-DGUESTFS_WARN_DEPRECATED=1 \
|
|
|
151578 |
diff --git a/rescue/rescue.c b/rescue/rescue.c
|
|
|
151578 |
index 5281b1161..a1aac53e4 100644
|
|
|
151578 |
--- a/rescue/rescue.c
|
|
|
151578 |
+++ b/rescue/rescue.c
|
|
|
151578 |
@@ -55,7 +55,6 @@ static void restore_tty (void);
|
|
|
151578 |
static void tstp_handler (int sig);
|
|
|
151578 |
static void cont_handler (int sig);
|
|
|
151578 |
static void add_scratch_disks (int n, struct drv **drvs);
|
|
|
151578 |
-static void do_suggestion (struct drv *drvs);
|
|
|
151578 |
|
|
|
151578 |
/* Currently open libguestfs handle. */
|
|
|
151578 |
guestfs_h *g;
|
|
|
151578 |
@@ -654,149 +653,6 @@ cont_handler (int sig)
|
|
|
151578 |
raw_tty ();
|
|
|
151578 |
}
|
|
|
151578 |
|
|
|
151578 |
-static void suggest_filesystems (void);
|
|
|
151578 |
-
|
|
|
151578 |
-static int
|
|
|
151578 |
-compare_keys_len (const void *p1, const void *p2)
|
|
|
151578 |
-{
|
|
|
151578 |
- const char *key1 = * (char * const *) p1;
|
|
|
151578 |
- const char *key2 = * (char * const *) p2;
|
|
|
151578 |
- return strlen (key1) - strlen (key2);
|
|
|
151578 |
-}
|
|
|
151578 |
-
|
|
|
151578 |
-/* virt-rescue --suggest flag does a kind of inspection on the
|
|
|
151578 |
- * drives and suggests mount commands that you should use.
|
|
|
151578 |
- */
|
|
|
151578 |
-static void
|
|
|
151578 |
-do_suggestion (struct drv *drvs)
|
|
|
151578 |
-{
|
|
|
151578 |
- CLEANUP_FREE_STRING_LIST char **roots = NULL;
|
|
|
151578 |
- size_t i;
|
|
|
151578 |
-
|
|
|
151578 |
- /* For inspection, force add_drives to add the drives read-only. */
|
|
|
151578 |
- read_only = 1;
|
|
|
151578 |
-
|
|
|
151578 |
- /* Add drives. */
|
|
|
151578 |
- add_drives (drvs);
|
|
|
151578 |
-
|
|
|
151578 |
- /* Free up data structures, no longer needed after this point. */
|
|
|
151578 |
- free_drives (drvs);
|
|
|
151578 |
-
|
|
|
151578 |
- printf (_("Inspecting the virtual machine or disk image ...\n\n"));
|
|
|
151578 |
- fflush (stdout);
|
|
|
151578 |
-
|
|
|
151578 |
- if (guestfs_launch (g) == -1)
|
|
|
151578 |
- exit (EXIT_FAILURE);
|
|
|
151578 |
-
|
|
|
151578 |
- /* Don't use inspect_mount, since for virt-rescue we should allow
|
|
|
151578 |
- * arbitrary disks and disks with more than one OS on them. Let's
|
|
|
151578 |
- * do this using the basic API instead.
|
|
|
151578 |
- */
|
|
|
151578 |
- roots = guestfs_inspect_os (g);
|
|
|
151578 |
- if (roots == NULL)
|
|
|
151578 |
- exit (EXIT_FAILURE);
|
|
|
151578 |
-
|
|
|
151578 |
- if (roots[0] == NULL) {
|
|
|
151578 |
- suggest_filesystems ();
|
|
|
151578 |
- return;
|
|
|
151578 |
- }
|
|
|
151578 |
-
|
|
|
151578 |
- printf (_("This disk contains one or more operating systems. You can use these mount\n"
|
|
|
151578 |
- "commands in virt-rescue (at the ><rescue> prompt) to mount the filesystems.\n\n"));
|
|
|
151578 |
-
|
|
|
151578 |
- for (i = 0; roots[i] != NULL; ++i) {
|
|
|
151578 |
- CLEANUP_FREE_STRING_LIST char **mps = NULL;
|
|
|
151578 |
- CLEANUP_FREE char *type = NULL, *distro = NULL, *product_name = NULL;
|
|
|
151578 |
- int major, minor;
|
|
|
151578 |
- size_t j;
|
|
|
151578 |
-
|
|
|
151578 |
- type = guestfs_inspect_get_type (g, roots[i]);
|
|
|
151578 |
- distro = guestfs_inspect_get_distro (g, roots[i]);
|
|
|
151578 |
- product_name = guestfs_inspect_get_product_name (g, roots[i]);
|
|
|
151578 |
- major = guestfs_inspect_get_major_version (g, roots[i]);
|
|
|
151578 |
- minor = guestfs_inspect_get_minor_version (g, roots[i]);
|
|
|
151578 |
-
|
|
|
151578 |
- printf (_("# %s is the root of a %s operating system\n"
|
|
|
151578 |
- "# type: %s, distro: %s, version: %d.%d\n"
|
|
|
151578 |
- "# %s\n\n"),
|
|
|
151578 |
- roots[i], type ? : "unknown",
|
|
|
151578 |
- type ? : "unknown", distro ? : "unknown", major, minor,
|
|
|
151578 |
- product_name ? : "");
|
|
|
151578 |
-
|
|
|
151578 |
- mps = guestfs_inspect_get_mountpoints (g, roots[i]);
|
|
|
151578 |
- if (mps == NULL)
|
|
|
151578 |
- exit (EXIT_FAILURE);
|
|
|
151578 |
-
|
|
|
151578 |
- /* Sort by key length, shortest key first, so that we end up
|
|
|
151578 |
- * mounting the filesystems in the correct order.
|
|
|
151578 |
- */
|
|
|
151578 |
- qsort (mps, guestfs_int_count_strings (mps) / 2, 2 * sizeof (char *),
|
|
|
151578 |
- compare_keys_len);
|
|
|
151578 |
-
|
|
|
151578 |
- for (j = 0; mps[j] != NULL; j += 2)
|
|
|
151578 |
- printf ("mount %s /sysroot%s\n", mps[j+1], mps[j]);
|
|
|
151578 |
-
|
|
|
151578 |
- /* If it's Linux, print the bind-mounts and a chroot command. */
|
|
|
151578 |
- if (type && STREQ (type, "linux")) {
|
|
|
151578 |
- printf ("mount --rbind /dev /sysroot/dev\n");
|
|
|
151578 |
- printf ("mount --rbind /proc /sysroot/proc\n");
|
|
|
151578 |
- printf ("mount --rbind /sys /sysroot/sys\n");
|
|
|
151578 |
- printf ("\n");
|
|
|
151578 |
- printf ("cd /sysroot\n");
|
|
|
151578 |
- printf ("chroot /sysroot\n");
|
|
|
151578 |
- }
|
|
|
151578 |
-
|
|
|
151578 |
- printf ("\n");
|
|
|
151578 |
- }
|
|
|
151578 |
-}
|
|
|
151578 |
-
|
|
|
151578 |
-/* Inspection failed, so it doesn't contain any OS that we recognise.
|
|
|
151578 |
- * However there might still be filesystems so print some suggestions
|
|
|
151578 |
- * for those.
|
|
|
151578 |
- */
|
|
|
151578 |
-static void
|
|
|
151578 |
-suggest_filesystems (void)
|
|
|
151578 |
-{
|
|
|
151578 |
- size_t i, count;
|
|
|
151578 |
-
|
|
|
151578 |
- CLEANUP_FREE_STRING_LIST char **fses = guestfs_list_filesystems (g);
|
|
|
151578 |
- if (fses == NULL)
|
|
|
151578 |
- exit (EXIT_FAILURE);
|
|
|
151578 |
-
|
|
|
151578 |
- /* Count how many are not swap or unknown. Possibly we should try
|
|
|
151578 |
- * mounting to see which are mountable, but that has a high
|
|
|
151578 |
- * probability of breaking.
|
|
|
151578 |
- */
|
|
|
151578 |
-#define TEST_MOUNTABLE(fs) STRNEQ ((fs), "swap") && STRNEQ ((fs), "unknown")
|
|
|
151578 |
- count = 0;
|
|
|
151578 |
- for (i = 0; fses[i] != NULL; i += 2) {
|
|
|
151578 |
- if (TEST_MOUNTABLE (fses[i+1]))
|
|
|
151578 |
- count++;
|
|
|
151578 |
- }
|
|
|
151578 |
-
|
|
|
151578 |
- if (count == 0) {
|
|
|
151578 |
- printf (_("This disk contains no mountable filesystems that we recognize.\n\n"
|
|
|
151578 |
- "However you can still use virt-rescue on the disk image, to try to mount\n"
|
|
|
151578 |
- "filesystems that are not recognized by libguestfs, or to create partitions,\n"
|
|
|
151578 |
- "logical volumes and filesystems on a blank disk.\n"));
|
|
|
151578 |
- return;
|
|
|
151578 |
- }
|
|
|
151578 |
-
|
|
|
151578 |
- printf (_("This disk contains one or more filesystems, but we don't recognize any\n"
|
|
|
151578 |
- "operating system. You can use these mount commands in virt-rescue (at the\n"
|
|
|
151578 |
- "><rescue> prompt) to mount these filesystems.\n\n"));
|
|
|
151578 |
-
|
|
|
151578 |
- for (i = 0; fses[i] != NULL; i += 2) {
|
|
|
151578 |
- printf (_("# %s has type '%s'\n"), fses[i], fses[i+1]);
|
|
|
151578 |
-
|
|
|
151578 |
- if (TEST_MOUNTABLE (fses[i+1]))
|
|
|
151578 |
- printf ("mount %s /sysroot\n", fses[i]);
|
|
|
151578 |
-
|
|
|
151578 |
- printf ("\n");
|
|
|
151578 |
- }
|
|
|
151578 |
-#undef TEST_MOUNTABLE
|
|
|
151578 |
-}
|
|
|
151578 |
-
|
|
|
151578 |
static void add_scratch_disk (struct drv **drvs);
|
|
|
151578 |
|
|
|
151578 |
static void
|
|
|
151578 |
diff --git a/rescue/rescue.h b/rescue/rescue.h
|
|
|
151578 |
index ccffb5eb3..4f5a04a71 100644
|
|
|
151578 |
--- a/rescue/rescue.h
|
|
|
151578 |
+++ b/rescue/rescue.h
|
|
|
151578 |
@@ -23,6 +23,8 @@
|
|
|
151578 |
|
|
|
151578 |
#include "guestfs.h"
|
|
|
151578 |
|
|
|
151578 |
+#include "options.h"
|
|
|
151578 |
+
|
|
|
151578 |
extern guestfs_h *g;
|
|
|
151578 |
extern int read_only;
|
|
|
151578 |
extern int live;
|
|
|
151578 |
@@ -44,4 +46,7 @@ extern bool process_escapes (struct escape_state *state, char *buf, size_t *len)
|
|
|
151578 |
extern int parse_escape_key (const char *);
|
|
|
151578 |
extern void print_escape_key_help (void);
|
|
|
151578 |
|
|
|
151578 |
+/* suggest.c */
|
|
|
151578 |
+extern void do_suggestion (struct drv *drvs);
|
|
|
151578 |
+
|
|
|
151578 |
#endif /* RESCUE_H */
|
|
|
151578 |
diff --git a/rescue/suggest.c b/rescue/suggest.c
|
|
|
151578 |
new file mode 100644
|
|
|
151578 |
index 000000000..13141ccc2
|
|
|
151578 |
--- /dev/null
|
|
|
151578 |
+++ b/rescue/suggest.c
|
|
|
151578 |
@@ -0,0 +1,175 @@
|
|
|
151578 |
+/* virt-rescue
|
|
|
151578 |
+ * Copyright (C) 2010-2017 Red Hat Inc.
|
|
|
151578 |
+ *
|
|
|
151578 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
151578 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
151578 |
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
151578 |
+ * (at your option) any later version.
|
|
|
151578 |
+ *
|
|
|
151578 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
151578 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
151578 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
151578 |
+ * GNU General Public License for more details.
|
|
|
151578 |
+ *
|
|
|
151578 |
+ * You should have received a copy of the GNU General Public License
|
|
|
151578 |
+ * along with this program; if not, write to the Free Software
|
|
|
151578 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
151578 |
+ */
|
|
|
151578 |
+
|
|
|
151578 |
+#include <config.h>
|
|
|
151578 |
+
|
|
|
151578 |
+#include <stdio.h>
|
|
|
151578 |
+#include <stdlib.h>
|
|
|
151578 |
+#include <string.h>
|
|
|
151578 |
+#include <locale.h>
|
|
|
151578 |
+#include <libintl.h>
|
|
|
151578 |
+
|
|
|
151578 |
+#include "guestfs.h"
|
|
|
151578 |
+#include "guestfs-internal-frontend.h"
|
|
|
151578 |
+
|
|
|
151578 |
+#include "options.h"
|
|
|
151578 |
+
|
|
|
151578 |
+#include "rescue.h"
|
|
|
151578 |
+
|
|
|
151578 |
+static void suggest_filesystems (void);
|
|
|
151578 |
+
|
|
|
151578 |
+static int
|
|
|
151578 |
+compare_keys_len (const void *p1, const void *p2)
|
|
|
151578 |
+{
|
|
|
151578 |
+ const char *key1 = * (char * const *) p1;
|
|
|
151578 |
+ const char *key2 = * (char * const *) p2;
|
|
|
151578 |
+ return strlen (key1) - strlen (key2);
|
|
|
151578 |
+}
|
|
|
151578 |
+
|
|
|
151578 |
+/* virt-rescue --suggest flag does a kind of inspection on the
|
|
|
151578 |
+ * drives and suggests mount commands that you should use.
|
|
|
151578 |
+ */
|
|
|
151578 |
+void
|
|
|
151578 |
+do_suggestion (struct drv *drvs)
|
|
|
151578 |
+{
|
|
|
151578 |
+ CLEANUP_FREE_STRING_LIST char **roots = NULL;
|
|
|
151578 |
+ size_t i;
|
|
|
151578 |
+
|
|
|
151578 |
+ /* For inspection, force add_drives to add the drives read-only. */
|
|
|
151578 |
+ read_only = 1;
|
|
|
151578 |
+
|
|
|
151578 |
+ /* Add drives. */
|
|
|
151578 |
+ add_drives (drvs);
|
|
|
151578 |
+
|
|
|
151578 |
+ /* Free up data structures, no longer needed after this point. */
|
|
|
151578 |
+ free_drives (drvs);
|
|
|
151578 |
+
|
|
|
151578 |
+ printf (_("Inspecting the virtual machine or disk image ...\n\n"));
|
|
|
151578 |
+ fflush (stdout);
|
|
|
151578 |
+
|
|
|
151578 |
+ if (guestfs_launch (g) == -1)
|
|
|
151578 |
+ exit (EXIT_FAILURE);
|
|
|
151578 |
+
|
|
|
151578 |
+ /* Don't use inspect_mount, since for virt-rescue we should allow
|
|
|
151578 |
+ * arbitrary disks and disks with more than one OS on them. Let's
|
|
|
151578 |
+ * do this using the basic API instead.
|
|
|
151578 |
+ */
|
|
|
151578 |
+ roots = guestfs_inspect_os (g);
|
|
|
151578 |
+ if (roots == NULL)
|
|
|
151578 |
+ exit (EXIT_FAILURE);
|
|
|
151578 |
+
|
|
|
151578 |
+ if (roots[0] == NULL) {
|
|
|
151578 |
+ suggest_filesystems ();
|
|
|
151578 |
+ return;
|
|
|
151578 |
+ }
|
|
|
151578 |
+
|
|
|
151578 |
+ printf (_("This disk contains one or more operating systems. You can use these mount\n"
|
|
|
151578 |
+ "commands in virt-rescue (at the ><rescue> prompt) to mount the filesystems.\n\n"));
|
|
|
151578 |
+
|
|
|
151578 |
+ for (i = 0; roots[i] != NULL; ++i) {
|
|
|
151578 |
+ CLEANUP_FREE_STRING_LIST char **mps = NULL;
|
|
|
151578 |
+ CLEANUP_FREE char *type = NULL, *distro = NULL, *product_name = NULL;
|
|
|
151578 |
+ int major, minor;
|
|
|
151578 |
+ size_t j;
|
|
|
151578 |
+
|
|
|
151578 |
+ type = guestfs_inspect_get_type (g, roots[i]);
|
|
|
151578 |
+ distro = guestfs_inspect_get_distro (g, roots[i]);
|
|
|
151578 |
+ product_name = guestfs_inspect_get_product_name (g, roots[i]);
|
|
|
151578 |
+ major = guestfs_inspect_get_major_version (g, roots[i]);
|
|
|
151578 |
+ minor = guestfs_inspect_get_minor_version (g, roots[i]);
|
|
|
151578 |
+
|
|
|
151578 |
+ printf (_("# %s is the root of a %s operating system\n"
|
|
|
151578 |
+ "# type: %s, distro: %s, version: %d.%d\n"
|
|
|
151578 |
+ "# %s\n\n"),
|
|
|
151578 |
+ roots[i], type ? : "unknown",
|
|
|
151578 |
+ type ? : "unknown", distro ? : "unknown", major, minor,
|
|
|
151578 |
+ product_name ? : "");
|
|
|
151578 |
+
|
|
|
151578 |
+ mps = guestfs_inspect_get_mountpoints (g, roots[i]);
|
|
|
151578 |
+ if (mps == NULL)
|
|
|
151578 |
+ exit (EXIT_FAILURE);
|
|
|
151578 |
+
|
|
|
151578 |
+ /* Sort by key length, shortest key first, so that we end up
|
|
|
151578 |
+ * mounting the filesystems in the correct order.
|
|
|
151578 |
+ */
|
|
|
151578 |
+ qsort (mps, guestfs_int_count_strings (mps) / 2, 2 * sizeof (char *),
|
|
|
151578 |
+ compare_keys_len);
|
|
|
151578 |
+
|
|
|
151578 |
+ for (j = 0; mps[j] != NULL; j += 2)
|
|
|
151578 |
+ printf ("mount %s /sysroot%s\n", mps[j+1], mps[j]);
|
|
|
151578 |
+
|
|
|
151578 |
+ /* If it's Linux, print the bind-mounts and a chroot command. */
|
|
|
151578 |
+ if (type && STREQ (type, "linux")) {
|
|
|
151578 |
+ printf ("mount --rbind /dev /sysroot/dev\n");
|
|
|
151578 |
+ printf ("mount --rbind /proc /sysroot/proc\n");
|
|
|
151578 |
+ printf ("mount --rbind /sys /sysroot/sys\n");
|
|
|
151578 |
+ printf ("\n");
|
|
|
151578 |
+ printf ("cd /sysroot\n");
|
|
|
151578 |
+ printf ("chroot /sysroot\n");
|
|
|
151578 |
+ }
|
|
|
151578 |
+
|
|
|
151578 |
+ printf ("\n");
|
|
|
151578 |
+ }
|
|
|
151578 |
+}
|
|
|
151578 |
+
|
|
|
151578 |
+/* Inspection failed, so it doesn't contain any OS that we recognise.
|
|
|
151578 |
+ * However there might still be filesystems so print some suggestions
|
|
|
151578 |
+ * for those.
|
|
|
151578 |
+ */
|
|
|
151578 |
+static void
|
|
|
151578 |
+suggest_filesystems (void)
|
|
|
151578 |
+{
|
|
|
151578 |
+ size_t i, count;
|
|
|
151578 |
+
|
|
|
151578 |
+ CLEANUP_FREE_STRING_LIST char **fses = guestfs_list_filesystems (g);
|
|
|
151578 |
+ if (fses == NULL)
|
|
|
151578 |
+ exit (EXIT_FAILURE);
|
|
|
151578 |
+
|
|
|
151578 |
+ /* Count how many are not swap or unknown. Possibly we should try
|
|
|
151578 |
+ * mounting to see which are mountable, but that has a high
|
|
|
151578 |
+ * probability of breaking.
|
|
|
151578 |
+ */
|
|
|
151578 |
+#define TEST_MOUNTABLE(fs) STRNEQ ((fs), "swap") && STRNEQ ((fs), "unknown")
|
|
|
151578 |
+ count = 0;
|
|
|
151578 |
+ for (i = 0; fses[i] != NULL; i += 2) {
|
|
|
151578 |
+ if (TEST_MOUNTABLE (fses[i+1]))
|
|
|
151578 |
+ count++;
|
|
|
151578 |
+ }
|
|
|
151578 |
+
|
|
|
151578 |
+ if (count == 0) {
|
|
|
151578 |
+ printf (_("This disk contains no mountable filesystems that we recognize.\n\n"
|
|
|
151578 |
+ "However you can still use virt-rescue on the disk image, to try to mount\n"
|
|
|
151578 |
+ "filesystems that are not recognized by libguestfs, or to create partitions,\n"
|
|
|
151578 |
+ "logical volumes and filesystems on a blank disk.\n"));
|
|
|
151578 |
+ return;
|
|
|
151578 |
+ }
|
|
|
151578 |
+
|
|
|
151578 |
+ printf (_("This disk contains one or more filesystems, but we don't recognize any\n"
|
|
|
151578 |
+ "operating system. You can use these mount commands in virt-rescue (at the\n"
|
|
|
151578 |
+ "><rescue> prompt) to mount these filesystems.\n\n"));
|
|
|
151578 |
+
|
|
|
151578 |
+ for (i = 0; fses[i] != NULL; i += 2) {
|
|
|
151578 |
+ printf (_("# %s has type '%s'\n"), fses[i], fses[i+1]);
|
|
|
151578 |
+
|
|
|
151578 |
+ if (TEST_MOUNTABLE (fses[i+1]))
|
|
|
151578 |
+ printf ("mount %s /sysroot\n", fses[i]);
|
|
|
151578 |
+
|
|
|
151578 |
+ printf ("\n");
|
|
|
151578 |
+ }
|
|
|
151578 |
+#undef TEST_MOUNTABLE
|
|
|
151578 |
+}
|
|
|
151578 |
--
|
|
|
151578 |
2.14.3
|
|
|
151578 |
|