|
|
a30de4 |
From 50e044064b4388f11912d96d2eb52aea1b292734 Mon Sep 17 00:00:00 2001
|
|
|
a30de4 |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
a30de4 |
Date: Sat, 4 Mar 2017 11:47:59 +0000
|
|
|
a30de4 |
Subject: [PATCH] rescue: Implement escape sequences.
|
|
|
a30de4 |
|
|
|
a30de4 |
This implements a few useful escape sequences:
|
|
|
a30de4 |
|
|
|
a30de4 |
><rescue> ^]?
|
|
|
a30de4 |
virt-rescue escape sequences:
|
|
|
a30de4 |
^] ? - print this message
|
|
|
a30de4 |
^] h - print this message
|
|
|
a30de4 |
^] q - quit virt-rescue
|
|
|
a30de4 |
^] s - sync the filesystems
|
|
|
a30de4 |
^] u - unmount filesystems
|
|
|
a30de4 |
^] x - quit virt-rescue
|
|
|
a30de4 |
^] z - suspend virt-rescue
|
|
|
a30de4 |
to pass the escape key through to the rescue shell, type it twice
|
|
|
a30de4 |
|
|
|
a30de4 |
^]i
|
|
|
a30de4 |
|
|
|
a30de4 |
root device: /dev/sda3
|
|
|
a30de4 |
product name: Fedora 25 (Twenty Five)
|
|
|
a30de4 |
type: linux
|
|
|
a30de4 |
distro: fedora
|
|
|
a30de4 |
|
|
|
a30de4 |
^]z
|
|
|
a30de4 |
[3]+ Stopped ./run virt-rescue --scratch
|
|
|
a30de4 |
$ fg
|
|
|
a30de4 |
|
|
|
a30de4 |
><rescue> ^]u
|
|
|
a30de4 |
|
|
|
a30de4 |
unmounting filesystems ...
|
|
|
a30de4 |
[ 21.158558] XFS (sda3): Unmounting Filesystem
|
|
|
a30de4 |
|
|
|
a30de4 |
(cherry picked from commit 3637c42f4e521eb647d7dfae7f48eb1689d0af54)
|
|
|
a30de4 |
---
|
|
|
a30de4 |
rescue/Makefile.am | 4 +-
|
|
|
a30de4 |
rescue/escape.c | 302 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
a30de4 |
rescue/rescue.c | 30 ++++-
|
|
|
a30de4 |
rescue/rescue.h | 47 ++++++++
|
|
|
a30de4 |
rescue/virt-rescue.pod | 74 ++++++++++++
|
|
|
a30de4 |
5 files changed, 454 insertions(+), 3 deletions(-)
|
|
|
a30de4 |
create mode 100644 rescue/escape.c
|
|
|
a30de4 |
create mode 100644 rescue/rescue.h
|
|
|
a30de4 |
|
|
|
a30de4 |
diff --git a/rescue/Makefile.am b/rescue/Makefile.am
|
|
|
a30de4 |
index c83c43458..eb60bafa4 100644
|
|
|
a30de4 |
--- a/rescue/Makefile.am
|
|
|
a30de4 |
+++ b/rescue/Makefile.am
|
|
|
a30de4 |
@@ -26,7 +26,9 @@ EXTRA_DIST = \
|
|
|
a30de4 |
bin_PROGRAMS = virt-rescue
|
|
|
a30de4 |
|
|
|
a30de4 |
virt_rescue_SOURCES = \
|
|
|
a30de4 |
- rescue.c
|
|
|
a30de4 |
+ escape.c \
|
|
|
a30de4 |
+ rescue.c \
|
|
|
a30de4 |
+ rescue.h
|
|
|
a30de4 |
|
|
|
a30de4 |
virt_rescue_CPPFLAGS = \
|
|
|
a30de4 |
-DGUESTFS_WARN_DEPRECATED=1 \
|
|
|
a30de4 |
diff --git a/rescue/escape.c b/rescue/escape.c
|
|
|
a30de4 |
new file mode 100644
|
|
|
a30de4 |
index 000000000..f7f7d84c4
|
|
|
a30de4 |
--- /dev/null
|
|
|
a30de4 |
+++ b/rescue/escape.c
|
|
|
a30de4 |
@@ -0,0 +1,302 @@
|
|
|
a30de4 |
+/* virt-rescue
|
|
|
a30de4 |
+ * Copyright (C) 2010-2017 Red Hat Inc.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
a30de4 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
a30de4 |
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
a30de4 |
+ * (at your option) any later version.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
a30de4 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
a30de4 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
a30de4 |
+ * GNU General Public License for more details.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * You should have received a copy of the GNU General Public License
|
|
|
a30de4 |
+ * along with this program; if not, write to the Free Software
|
|
|
a30de4 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
a30de4 |
+ */
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+#include <config.h>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+#include <stdio.h>
|
|
|
a30de4 |
+#include <stdlib.h>
|
|
|
a30de4 |
+#include <stdbool.h>
|
|
|
a30de4 |
+#include <string.h>
|
|
|
a30de4 |
+#include <unistd.h>
|
|
|
a30de4 |
+#include <signal.h>
|
|
|
a30de4 |
+#include <locale.h>
|
|
|
a30de4 |
+#include <libintl.h>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+#include "c-ctype.h"
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+#include "guestfs.h"
|
|
|
a30de4 |
+#include "guestfs-internal-frontend.h"
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+#include "rescue.h"
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+static void print_help (void);
|
|
|
a30de4 |
+static void print_inspector (void);
|
|
|
a30de4 |
+static void crlf (void);
|
|
|
a30de4 |
+static void print_escape_key (void);
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+/* Parse the -e parameter from the command line. */
|
|
|
a30de4 |
+int
|
|
|
a30de4 |
+parse_escape_key (const char *arg)
|
|
|
a30de4 |
+{
|
|
|
a30de4 |
+ size_t len;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ if (STREQ (arg, "none"))
|
|
|
a30de4 |
+ return 0;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ len = strlen (arg);
|
|
|
a30de4 |
+ if (arg == 0)
|
|
|
a30de4 |
+ return -1;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ switch (arg[0]) {
|
|
|
a30de4 |
+ case '^':
|
|
|
a30de4 |
+ if (len == 2 &&
|
|
|
a30de4 |
+ ((arg[1] >= 'a' && arg[1] <= 'z') ||
|
|
|
a30de4 |
+ (arg[1] >= 'A' && arg[1] <= '_'))) {
|
|
|
a30de4 |
+ return c_toupper (arg[1]) - '@';
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+ else
|
|
|
a30de4 |
+ return -1;
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ return -1;
|
|
|
a30de4 |
+}
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+/* Print one-line end user description of the escape key.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * This is printed when virt-rescue starts.
|
|
|
a30de4 |
+ */
|
|
|
a30de4 |
+void
|
|
|
a30de4 |
+print_escape_key_help (void)
|
|
|
a30de4 |
+{
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+ /* Difficult to translate this string. XXX */
|
|
|
a30de4 |
+ printf ("The virt-rescue escape key is ‘");
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf ("’. Type ‘");
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf (" h’ for help.");
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+}
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+void
|
|
|
a30de4 |
+init_escape_state (struct escape_state *state)
|
|
|
a30de4 |
+{
|
|
|
a30de4 |
+ state->in_escape = false;
|
|
|
a30de4 |
+}
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+/* Process escapes in the tty input buffer.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * This function has a state parameter so that we can handle an escape
|
|
|
a30de4 |
+ * sequence split over the end of the buffer.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * Escape sequences are removed from the buffer.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * Returns true iff virt-rescue should exit.
|
|
|
a30de4 |
+ */
|
|
|
a30de4 |
+bool
|
|
|
a30de4 |
+process_escapes (struct escape_state *state, char *buf, size_t *len)
|
|
|
a30de4 |
+{
|
|
|
a30de4 |
+ size_t i;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ for (i = 0; i < *len; ++i) {
|
|
|
a30de4 |
+#define DROP_CURRENT_CHAR() \
|
|
|
a30de4 |
+ memmove (&buf[i], &buf[i+1], --(*len))
|
|
|
a30de4 |
+#define PRINT_ESC() \
|
|
|
a30de4 |
+ do { print_escape_key (); putchar (buf[i]); crlf (); } while (0)
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ if (!state->in_escape) {
|
|
|
a30de4 |
+ if (buf[i] == escape_key) {
|
|
|
a30de4 |
+ /* Drop the escape key from the buffer and go to escape mode. */
|
|
|
a30de4 |
+ DROP_CURRENT_CHAR ();
|
|
|
a30de4 |
+ state->in_escape = true;
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+ else /* in escape sequence */ {
|
|
|
a30de4 |
+ if (buf[i] == escape_key) /* ^] ^] means send ^] to rescue shell */
|
|
|
a30de4 |
+ state->in_escape = false;
|
|
|
a30de4 |
+ else {
|
|
|
a30de4 |
+ switch (buf[i]) {
|
|
|
a30de4 |
+ case '?': case 'h':
|
|
|
a30de4 |
+ PRINT_ESC ();
|
|
|
a30de4 |
+ print_help ();
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ case 'i':
|
|
|
a30de4 |
+ PRINT_ESC ();
|
|
|
a30de4 |
+ print_inspector ();
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ case 'q': case 'x':
|
|
|
a30de4 |
+ PRINT_ESC ();
|
|
|
a30de4 |
+ return true /* exit virt-rescue at once */;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ case 's':
|
|
|
a30de4 |
+ PRINT_ESC ();
|
|
|
a30de4 |
+ printf (_("attempting to sync filesystems ..."));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+ guestfs_sync (g);
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ case 'u':
|
|
|
a30de4 |
+ PRINT_ESC ();
|
|
|
a30de4 |
+ printf (_("unmounting filesystems ..."));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+ guestfs_umount_all (g);
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ case 'z':
|
|
|
a30de4 |
+ PRINT_ESC ();
|
|
|
a30de4 |
+ raise (SIGTSTP);
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ default:
|
|
|
a30de4 |
+ /* Any unrecognized escape sequence will be dropped. We
|
|
|
a30de4 |
+ * could be obnoxious and ring the bell, but I hate it when
|
|
|
a30de4 |
+ * programs do that.
|
|
|
a30de4 |
+ */
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ /* Drop the escape key and return to non-escape mode. */
|
|
|
a30de4 |
+ DROP_CURRENT_CHAR ();
|
|
|
a30de4 |
+ state->in_escape = false;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ /* The output is line buffered, this is just to make sure
|
|
|
a30de4 |
+ * everything gets written to stdout before we continue
|
|
|
a30de4 |
+ * writing to STDOUT_FILENO.
|
|
|
a30de4 |
+ */
|
|
|
a30de4 |
+ fflush (stdout);
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+ } /* in escape sequence */
|
|
|
a30de4 |
+ } /* for */
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ return false /* don't exit */;
|
|
|
a30de4 |
+}
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+/* This is called when the user types ^] h */
|
|
|
a30de4 |
+static void
|
|
|
a30de4 |
+print_help (void)
|
|
|
a30de4 |
+{
|
|
|
a30de4 |
+ printf (_("virt-rescue escape sequences:"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ putchar (' ');
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf (_(" ? - print this message"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ putchar (' ');
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf (_(" h - print this message"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ if (inspector) {
|
|
|
a30de4 |
+ putchar (' ');
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf (_(" i - print inspection data"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ putchar (' ');
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf (_(" q - quit virt-rescue"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ putchar (' ');
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf (_(" s - sync the filesystems"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ putchar (' ');
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf (_(" u - unmount filesystems"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ putchar (' ');
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf (_(" x - quit virt-rescue"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ putchar (' ');
|
|
|
a30de4 |
+ print_escape_key ();
|
|
|
a30de4 |
+ printf (_(" z - suspend virt-rescue"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ printf (_("to pass the escape key through to the rescue shell, type it twice"));
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+}
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+/* This is called when the user types ^] i */
|
|
|
a30de4 |
+static void
|
|
|
a30de4 |
+print_inspector (void)
|
|
|
a30de4 |
+{
|
|
|
a30de4 |
+ CLEANUP_FREE_STRING_LIST char **roots;
|
|
|
a30de4 |
+ size_t i;
|
|
|
a30de4 |
+ const char *root;
|
|
|
a30de4 |
+ char *str;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ if (inspector) {
|
|
|
a30de4 |
+ roots = guestfs_inspect_get_roots (g);
|
|
|
a30de4 |
+ if (roots) {
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+ for (i = 0; roots[i] != NULL; ++i) {
|
|
|
a30de4 |
+ root = roots[i];
|
|
|
a30de4 |
+ printf (_("root device: %s"), root);
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ str = guestfs_inspect_get_product_name (g, root);
|
|
|
a30de4 |
+ if (str) {
|
|
|
a30de4 |
+ printf (_(" product name: %s"), str);
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+ free (str);
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ str = guestfs_inspect_get_type (g, root);
|
|
|
a30de4 |
+ if (str) {
|
|
|
a30de4 |
+ printf (_(" type: %s"), str);
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+ free (str);
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ str = guestfs_inspect_get_distro (g, root);
|
|
|
a30de4 |
+ if (str) {
|
|
|
a30de4 |
+ printf (_(" distro: %s"), str);
|
|
|
a30de4 |
+ crlf ();
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+ free (str);
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+}
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+/* Because the terminal is in raw mode, we have to send CR LF instead
|
|
|
a30de4 |
+ * of printing just \n.
|
|
|
a30de4 |
+ */
|
|
|
a30de4 |
+static void
|
|
|
a30de4 |
+crlf (void)
|
|
|
a30de4 |
+{
|
|
|
a30de4 |
+ putchar ('\r');
|
|
|
a30de4 |
+ putchar ('\n');
|
|
|
a30de4 |
+}
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+static void
|
|
|
a30de4 |
+print_escape_key (void)
|
|
|
a30de4 |
+{
|
|
|
a30de4 |
+ switch (escape_key) {
|
|
|
a30de4 |
+ case 0:
|
|
|
a30de4 |
+ printf ("none");
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+ case '\x1'...'\x1f':
|
|
|
a30de4 |
+ putchar ('^');
|
|
|
a30de4 |
+ putchar (escape_key + '@');
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+ default:
|
|
|
a30de4 |
+ abort ();
|
|
|
a30de4 |
+ }
|
|
|
a30de4 |
+}
|
|
|
a30de4 |
diff --git a/rescue/rescue.c b/rescue/rescue.c
|
|
|
a30de4 |
index 2b461378d..5281b1161 100644
|
|
|
a30de4 |
--- a/rescue/rescue.c
|
|
|
a30de4 |
+++ b/rescue/rescue.c
|
|
|
a30de4 |
@@ -1,5 +1,5 @@
|
|
|
a30de4 |
/* virt-rescue
|
|
|
a30de4 |
- * Copyright (C) 2010-2012 Red Hat Inc.
|
|
|
a30de4 |
+ * Copyright (C) 2010-2017 Red Hat Inc.
|
|
|
a30de4 |
*
|
|
|
a30de4 |
* This program is free software; you can redistribute it and/or modify
|
|
|
a30de4 |
* it under the terms of the GNU General Public License as published by
|
|
|
a30de4 |
@@ -40,10 +40,14 @@
|
|
|
a30de4 |
#include "xvasprintf.h"
|
|
|
a30de4 |
|
|
|
a30de4 |
#include "guestfs.h"
|
|
|
a30de4 |
+#include "guestfs-internal-frontend.h"
|
|
|
a30de4 |
+
|
|
|
a30de4 |
#include "windows.h"
|
|
|
a30de4 |
#include "options.h"
|
|
|
a30de4 |
#include "display-options.h"
|
|
|
a30de4 |
|
|
|
a30de4 |
+#include "rescue.h"
|
|
|
a30de4 |
+
|
|
|
a30de4 |
static void log_message_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len);
|
|
|
a30de4 |
static void do_rescue (int sock);
|
|
|
a30de4 |
static void raw_tty (void);
|
|
|
a30de4 |
@@ -65,6 +69,7 @@ const char *libvirt_uri = NULL;
|
|
|
a30de4 |
int inspector = 0;
|
|
|
a30de4 |
int in_guestfish = 0;
|
|
|
a30de4 |
int in_virt_rescue = 1;
|
|
|
a30de4 |
+int escape_key = '\x1d'; /* ^] */
|
|
|
a30de4 |
|
|
|
a30de4 |
/* Old terminal settings. */
|
|
|
a30de4 |
static struct termios old_termios;
|
|
|
a30de4 |
@@ -86,6 +91,7 @@ usage (int status)
|
|
|
a30de4 |
" --append kernelopts Append kernel options\n"
|
|
|
a30de4 |
" -c|--connect uri Specify libvirt URI for -d option\n"
|
|
|
a30de4 |
" -d|--domain guest Add disks from libvirt guest\n"
|
|
|
a30de4 |
+ " -e ^x|none Set or disable escape key (default ^])\n"
|
|
|
a30de4 |
" --format[=raw|..] Force disk format for -a option\n"
|
|
|
a30de4 |
" --help Display brief help\n"
|
|
|
a30de4 |
" -i|--inspector Automatically mount filesystems\n"
|
|
|
a30de4 |
@@ -119,7 +125,7 @@ main (int argc, char *argv[])
|
|
|
a30de4 |
|
|
|
a30de4 |
enum { HELP_OPTION = CHAR_MAX + 1 };
|
|
|
a30de4 |
|
|
|
a30de4 |
- static const char options[] = "a:c:d:im:rvVwx";
|
|
|
a30de4 |
+ static const char options[] = "a:c:d:e:im:rvVwx";
|
|
|
a30de4 |
static const struct option long_options[] = {
|
|
|
a30de4 |
{ "add", 1, 0, 'a' },
|
|
|
a30de4 |
{ "append", 1, 0, 0 },
|
|
|
a30de4 |
@@ -226,6 +232,12 @@ main (int argc, char *argv[])
|
|
|
a30de4 |
OPTION_d;
|
|
|
a30de4 |
break;
|
|
|
a30de4 |
|
|
|
a30de4 |
+ case 'e':
|
|
|
a30de4 |
+ escape_key = parse_escape_key (optarg);
|
|
|
a30de4 |
+ if (escape_key == -1)
|
|
|
a30de4 |
+ error (EXIT_FAILURE, 0, _("unrecognized escape key: %s"), optarg);
|
|
|
a30de4 |
+ break;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
case 'i':
|
|
|
a30de4 |
OPTION_i;
|
|
|
a30de4 |
break;
|
|
|
a30de4 |
@@ -428,6 +440,10 @@ main (int argc, char *argv[])
|
|
|
a30de4 |
signal (SIGTSTP, tstp_handler);
|
|
|
a30de4 |
signal (SIGCONT, cont_handler);
|
|
|
a30de4 |
|
|
|
a30de4 |
+ /* Print the escape key if set. */
|
|
|
a30de4 |
+ if (escape_key > 0)
|
|
|
a30de4 |
+ print_escape_key_help ();
|
|
|
a30de4 |
+
|
|
|
a30de4 |
do_rescue (sock);
|
|
|
a30de4 |
|
|
|
a30de4 |
restore_tty ();
|
|
|
a30de4 |
@@ -478,6 +494,9 @@ do_rescue (int sock)
|
|
|
a30de4 |
{
|
|
|
a30de4 |
size_t rlen = 0;
|
|
|
a30de4 |
size_t wlen = 0;
|
|
|
a30de4 |
+ struct escape_state escape_state;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ init_escape_state (&escape_state);
|
|
|
a30de4 |
|
|
|
a30de4 |
while (sock >= 0 || rlen > 0) {
|
|
|
a30de4 |
struct pollfd fds[3];
|
|
|
a30de4 |
@@ -534,6 +553,13 @@ do_rescue (int sock)
|
|
|
a30de4 |
}
|
|
|
a30de4 |
if (n > 0)
|
|
|
a30de4 |
wlen += n;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+ /* Process escape sequences in the tty input. If the function
|
|
|
a30de4 |
+ * returns true, then we exit the loop causing virt-rescue to
|
|
|
a30de4 |
+ * exit.
|
|
|
a30de4 |
+ */
|
|
|
a30de4 |
+ if (escape_key > 0 && process_escapes (&escape_state, wbuf, &wlen))
|
|
|
a30de4 |
+ return;
|
|
|
a30de4 |
}
|
|
|
a30de4 |
|
|
|
a30de4 |
/* Log message from appliance. */
|
|
|
a30de4 |
diff --git a/rescue/rescue.h b/rescue/rescue.h
|
|
|
a30de4 |
new file mode 100644
|
|
|
a30de4 |
index 000000000..ccffb5eb3
|
|
|
a30de4 |
--- /dev/null
|
|
|
a30de4 |
+++ b/rescue/rescue.h
|
|
|
a30de4 |
@@ -0,0 +1,47 @@
|
|
|
a30de4 |
+/* virt-rescue
|
|
|
a30de4 |
+ * Copyright (C) 2010-2017 Red Hat Inc.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
a30de4 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
a30de4 |
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
a30de4 |
+ * (at your option) any later version.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
a30de4 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
a30de4 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
a30de4 |
+ * GNU General Public License for more details.
|
|
|
a30de4 |
+ *
|
|
|
a30de4 |
+ * You should have received a copy of the GNU General Public License
|
|
|
a30de4 |
+ * along with this program; if not, write to the Free Software
|
|
|
a30de4 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
a30de4 |
+ */
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+#ifndef RESCUE_H
|
|
|
a30de4 |
+#define RESCUE_H
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+#include <stdbool.h>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+#include "guestfs.h"
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+extern guestfs_h *g;
|
|
|
a30de4 |
+extern int read_only;
|
|
|
a30de4 |
+extern int live;
|
|
|
a30de4 |
+extern int verbose;
|
|
|
a30de4 |
+extern int keys_from_stdin;
|
|
|
a30de4 |
+extern int echo_keys;
|
|
|
a30de4 |
+extern const char *libvirt_uri;
|
|
|
a30de4 |
+extern int inspector;
|
|
|
a30de4 |
+extern int in_guestfish;
|
|
|
a30de4 |
+extern int in_virt_rescue;
|
|
|
a30de4 |
+extern int escape_key;
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+/* escape.c */
|
|
|
a30de4 |
+struct escape_state {
|
|
|
a30de4 |
+ bool in_escape;
|
|
|
a30de4 |
+};
|
|
|
a30de4 |
+extern void init_escape_state (struct escape_state *state);
|
|
|
a30de4 |
+extern bool process_escapes (struct escape_state *state, char *buf, size_t *len);
|
|
|
a30de4 |
+extern int parse_escape_key (const char *);
|
|
|
a30de4 |
+extern void print_escape_key_help (void);
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+#endif /* RESCUE_H */
|
|
|
a30de4 |
diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod
|
|
|
a30de4 |
index b651f84e7..bd6f954e9 100644
|
|
|
a30de4 |
--- a/rescue/virt-rescue.pod
|
|
|
a30de4 |
+++ b/rescue/virt-rescue.pod
|
|
|
a30de4 |
@@ -128,6 +128,29 @@ not used at all.
|
|
|
a30de4 |
Add all the disks from the named libvirt guest. Domain UUIDs can be
|
|
|
a30de4 |
used instead of names.
|
|
|
a30de4 |
|
|
|
a30de4 |
+=item B<-e none>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Disable the escape key.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item B<-e> KEY
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Set the escape key to the given key sequence. The default is C<^]>.
|
|
|
a30de4 |
+To specify the escape key you can use:
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=over 4
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^x>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Control key + C<x> key.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<none>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+I<-e none> means there is no escape key, escapes are disabled.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=back
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+See L</ESCAPE KEY> below for further information.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
=item B<--format=raw|qcow2|..>
|
|
|
a30de4 |
|
|
|
a30de4 |
=item B<--format>
|
|
|
a30de4 |
@@ -321,6 +344,57 @@ See L<bash(1)> for more details.
|
|
|
a30de4 |
|
|
|
a30de4 |
=back
|
|
|
a30de4 |
|
|
|
a30de4 |
+=head1 ESCAPE KEY
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Virt-rescue supports various keyboard escape sequences which are
|
|
|
a30de4 |
+entered by pressing C<^]> (Control key + C<]> key).
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+You can change the escape key using the I<-e> option on the command
|
|
|
a30de4 |
+line (see above), and you can disable escapes completely using
|
|
|
a30de4 |
+I<-e none>. The rest of this section assumes the default escape key.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+The following escapes can be used:
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=over 4
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^] ?>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^] h>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Prints a brief help text about escape sequences.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^] i>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Prints brief libguestfs inspection information for the guest. This
|
|
|
a30de4 |
+only works if you used I<-i> on the virt-rescue command line.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^] q>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^] x>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Quits virt-rescue immediately.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^] s>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Synchronize the filesystems (sync).
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^] u>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Unmounts all the filesystems, except for the root (appliance)
|
|
|
a30de4 |
+filesystems.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^] z>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Suspend virt-rescue (like pressing C<^Z> except that it affects
|
|
|
a30de4 |
+virt-rescue rather than the program inside the rescue shell).
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=item C<^] ^]>
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+Sends the literal character C<^]> (ASCII 0x1d) through to the rescue
|
|
|
a30de4 |
+shell.
|
|
|
a30de4 |
+
|
|
|
a30de4 |
+=back
|
|
|
a30de4 |
+
|
|
|
a30de4 |
=head1 CAPTURING CORE DUMPS
|
|
|
a30de4 |
|
|
|
a30de4 |
If you are testing a tool inside virt-rescue and the tool (B<not>
|
|
|
a30de4 |
--
|
|
|
a30de4 |
2.14.3
|
|
|
a30de4 |
|