Blob Blame History Raw
From fe1e9ab849a7443907dd1968b34e89c58dba91f8 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 18 Apr 2016 14:40:29 +0100
Subject: [PATCH] p2v: Allow p2v kernel options to override GUI configuration
 (RHBZ#1327488).

Allow kernel options such as p2v.o=libvirt to override internal
defaults, even for GUI configuration.

The main change is to split up the kernel conversion into two steps:
reading the kernel command line configuration, and performing the
conversion.  The kernel command line can then be read by the main
program and used to initialize the config structure for either kernel
conversion or GUI conversion.

A small adjustment is required in the test because p2v.pre no longer
runs before kernel command line parsing.  (The aim is to have
p2v.pre/post/fail still only run when doing a kernel conversion, not
in the GUI case.)

(cherry picked from commit fb74a275c1438e6e0569b7fea85d2a4841a07a4e)
---
 p2v/gui.c                    |  2 +-
 p2v/kernel.c                 | 57 +++++++++++++++++++++++++++-----------------
 p2v/main.c                   | 27 +++++++++++----------
 p2v/p2v.h                    |  5 ++--
 p2v/test-virt-p2v-cmdline.sh |  4 +---
 5 files changed, 54 insertions(+), 41 deletions(-)

diff --git a/p2v/gui.c b/p2v/gui.c
index 569a295..015fa21 100644
--- a/p2v/gui.c
+++ b/p2v/gui.c
@@ -75,7 +75,7 @@ static GtkWidget *run_dlg,
  * Note that gtk_init etc have already been called in main.
  */
 void
-gui_application (struct config *config)
+gui_conversion (struct config *config)
 {
   /* Create the dialogs. */
   create_connection_dialog (config);
diff --git a/p2v/kernel.c b/p2v/kernel.c
index e904502..6d9388b 100644
--- a/p2v/kernel.c
+++ b/p2v/kernel.c
@@ -38,18 +38,19 @@ static void notify_ui_callback (int type, const char *data);
 static void run_command (int verbose, const char *stage, const char *command);
 
 void
-kernel_configuration (struct config *config, char **cmdline, int cmdline_source)
+update_config_from_kernel_cmdline (struct config *config, char **cmdline)
 {
   const char *p;
 
-  p = get_cmdline_key (cmdline, "p2v.pre");
+  p = get_cmdline_key (cmdline, "p2v.debug");
   if (p)
-    run_command (config->verbose, "p2v.pre", p);
+    config->verbose = 1;
 
   p = get_cmdline_key (cmdline, "p2v.server");
-  assert (p); /* checked by caller */
-  free (config->server);
-  config->server = strdup (p);
+  if (p) {
+    free (config->server);
+    config->server = strdup (p);
+  }
 
   p = get_cmdline_key (cmdline, "p2v.port");
   if (p) {
@@ -83,21 +84,6 @@ kernel_configuration (struct config *config, char **cmdline, int cmdline_source)
   if (p)
     config->sudo = 1;
 
-  /* We should now be able to connect and interrogate virt-v2v
-   * on the conversion server.
-   */
-  p = get_cmdline_key (cmdline, "p2v.skip_test_connection");
-  if (!p) {
-    wait_network_online (config);
-    if (test_connection (config) == -1) {
-      const char *err = get_ssh_error ();
-
-      fprintf (stderr, "%s: error opening control connection to %s:%d: %s\n",
-               guestfs_int_program_name, config->server, config->port, err);
-      exit (EXIT_FAILURE);
-    }
-  }
-
   p = get_cmdline_key (cmdline, "p2v.name");
   if (p) {
     free (config->guestname);
@@ -207,12 +193,39 @@ kernel_configuration (struct config *config, char **cmdline, int cmdline_source)
     config->output_storage = strdup (p);
   }
 
-  /* Undocumented command line tool used for testing command line parsing. */
+  /* Undocumented command line parameter used for testing command line
+   * parsing.
+   */
   p = get_cmdline_key (cmdline, "p2v.dump_config_and_exit");
   if (p) {
     print_config (config, stdout);
     exit (EXIT_SUCCESS);
   }
+}
+
+/* Perform conversion using the kernel method. */
+void
+kernel_conversion (struct config *config, char **cmdline, int cmdline_source)
+{
+  const char *p;
+
+  /* Pre-conversion command. */
+  p = get_cmdline_key (cmdline, "p2v.pre");
+  if (p)
+    run_command (config->verbose, "p2v.pre", p);
+
+  /* Connect to and interrogate virt-v2v on the conversion server. */
+  p = get_cmdline_key (cmdline, "p2v.skip_test_connection");
+  if (!p) {
+    wait_network_online (config);
+    if (test_connection (config) == -1) {
+      const char *err = get_ssh_error ();
+
+      error (EXIT_FAILURE, 0,
+             "error opening control connection to %s:%d: %s",
+             config->server, config->port, err);
+    }
+  }
 
   /* Some disks must have been specified for conversion. */
   if (config->disks == NULL || guestfs_int_count_strings (config->disks) == 0) {
diff --git a/p2v/main.c b/p2v/main.c
index f037716..99da3e4 100644
--- a/p2v/main.c
+++ b/p2v/main.c
@@ -191,25 +191,26 @@ main (int argc, char *argv[])
 
   set_config_defaults (config);
 
-  /* If /proc/cmdline exists and contains "p2v.server=" then we enable
-   * non-interactive configuration.
-   * If /proc/cmdline contains p2v.debug then we enable verbose mode
-   * even for interactive configuration.
+  /* Parse /proc/cmdline (if it exists) or use the --cmdline parameter
+   * to initialize the configuration.  This allows defaults to be pass
+   * using the kernel command line, with additional GUI configuration
+   * later.
    */
   if (cmdline == NULL) {
     cmdline = parse_proc_cmdline ();
-    if (cmdline == NULL)
-      goto gui;
-    cmdline_source = CMDLINE_SOURCE_PROC_CMDLINE;
+    if (cmdline != NULL)
+      cmdline_source = CMDLINE_SOURCE_PROC_CMDLINE;
   }
 
-  if (get_cmdline_key (cmdline, "p2v.debug") != NULL)
-    config->verbose = 1;
+  if (cmdline)
+    update_config_from_kernel_cmdline (config, cmdline);
 
-  if (get_cmdline_key (cmdline, "p2v.server") != NULL)
-    kernel_configuration (config, cmdline, cmdline_source);
+  /* If p2v.server exists, then we use the non-interactive kernel
+   * conversion.  Otherwise we run the GUI.
+   */
+  if (config->server != NULL)
+    kernel_conversion (config, cmdline, cmdline_source);
   else {
-  gui:
     if (!gui_possible) {
       fprintf (stderr,
                _("%s: gtk_init_check returned false, indicating that\n"
@@ -217,7 +218,7 @@ main (int argc, char *argv[])
                guestfs_int_program_name);
       exit (EXIT_FAILURE);
     }
-    gui_application (config);
+    gui_conversion (config);
   }
 
   guestfs_int_free_string_list (cmdline);
diff --git a/p2v/p2v.h b/p2v/p2v.h
index 097f294..9ccaf0f 100644
--- a/p2v/p2v.h
+++ b/p2v/p2v.h
@@ -106,10 +106,11 @@ extern const char *get_cmdline_key (char **cmdline, const char *key);
 #define CMDLINE_SOURCE_PROC_CMDLINE 2 /* /proc/cmdline */
 
 /* kernel.c */
-extern void kernel_configuration (struct config *, char **cmdline, int cmdline_source);
+extern void update_config_from_kernel_cmdline (struct config *config, char **cmdline);
+extern void kernel_conversion (struct config *, char **cmdline, int cmdline_source);
 
 /* gui.c */
-extern void gui_application (struct config *);
+extern void gui_conversion (struct config *);
 
 /* conversion.c */
 extern int start_conversion (struct config *, void (*notify_ui) (int type, const char *data));
diff --git a/p2v/test-virt-p2v-cmdline.sh b/p2v/test-virt-p2v-cmdline.sh
index bdd51d3..9629a05 100755
--- a/p2v/test-virt-p2v-cmdline.sh
+++ b/p2v/test-virt-p2v-cmdline.sh
@@ -31,14 +31,12 @@ out=test-virt-p2v-cmdline.out
 rm -f $out
 
 # The Linux kernel command line.
-virt-p2v --cmdline='p2v.pre="echo 1 2 3" p2v.server=localhost p2v.port=123 p2v.username=user p2v.password=secret p2v.skip_test_connection p2v.name=test p2v.vcpus=4 p2v.memory=1G p2v.disks=sda,sdb,sdc p2v.removable=sdd p2v.interfaces=eth0,eth1 p2v.o=local p2v.oa=sparse p2v.oc=qemu:///session p2v.of=raw p2v.os=/var/tmp p2v.network=em1:wired,other p2v.dump_config_and_exit' > $out
+virt-p2v --cmdline='p2v.server=localhost p2v.port=123 p2v.username=user p2v.password=secret p2v.skip_test_connection p2v.name=test p2v.vcpus=4 p2v.memory=1G p2v.disks=sda,sdb,sdc p2v.removable=sdd p2v.interfaces=eth0,eth1 p2v.o=local p2v.oa=sparse p2v.oc=qemu:///session p2v.of=raw p2v.os=/var/tmp p2v.network=em1:wired,other p2v.dump_config_and_exit' > $out
 
 # For debugging purposes.
 cat $out
 
 # Check the output contains what we expect.
-grep "^echo 1 2 3" $out
-grep "^1 2 3" $out
 grep "^conversion server.*localhost" $out
 grep "^port.*123" $out
 grep "^username.*user" $out
-- 
2.7.4