[Libguestfs] [PATCH 3/5] p2v: Move nbd_local_port to nbd.c.

Richard W.M. Jones rjones at redhat.com
Fri Feb 3 14:21:16 UTC 2017


In preparation for using socket activation, move the nbd_local_port
global inside nbd.c and make it private.

This is largely code motion.  However I rearranged the order in which
the ssh data connection and the NBD server are started up.  Previously
the ssh connection was made first, and the NBD server was then
started.  Now the NBD server starts first.  This happens so that nbd.c
can choose the local port, and when we implement socket activation it
will allow nbd.c to open the socket and choose a free port too.
---
 p2v/conversion.c | 69 ++++++++++++++++++++++++++++++++------------------------
 p2v/main.c       | 13 -----------
 p2v/nbd.c        | 28 ++++++++++++++++++++---
 p2v/p2v.h        |  9 ++------
 p2v/ssh.c        |  6 ++---
 5 files changed, 68 insertions(+), 57 deletions(-)

diff --git a/p2v/conversion.c b/p2v/conversion.c
index 44a3c58..26d321f 100644
--- a/p2v/conversion.c
+++ b/p2v/conversion.c
@@ -86,7 +86,6 @@ xmlBufferDetach (xmlBufferPtr buf)
 struct data_conn {
   mexp_h *h;                /* miniexpect handle to ssh */
   pid_t nbd_pid;            /* NBD server PID */
-  int nbd_local_port;       /* local NBD port on physical machine */
   int nbd_remote_port;      /* remote NBD port on conversion server */
 };
 
@@ -231,33 +230,14 @@ start_conversion (struct config *config,
   for (i = 0; config->disks[i] != NULL; ++i) {
     data_conns[i].h = NULL;
     data_conns[i].nbd_pid = 0;
-    data_conns[i].nbd_local_port = -1;
     data_conns[i].nbd_remote_port = -1;
   }
 
   /* Start the data connections and NBD server processes, one per disk. */
   for (i = 0; config->disks[i] != NULL; ++i) {
+    int nbd_local_port;
     CLEANUP_FREE char *device = NULL;
 
-    if (notify_ui) {
-      CLEANUP_FREE char *msg;
-      if (asprintf (&msg,
-                    _("Opening data connection for %s ..."),
-                    config->disks[i]) == -1)
-        error (EXIT_FAILURE, errno, "asprintf");
-      notify_ui (NOTIFY_STATUS, msg);
-    }
-
-    data_conns[i].h = open_data_connection (config,
-                                            &data_conns[i].nbd_local_port,
-                                            &data_conns[i].nbd_remote_port);
-    if (data_conns[i].h == NULL) {
-      const char *err = get_ssh_error ();
-
-      set_conversion_error ("could not open data connection over SSH to the conversion server: %s", err);
-      goto out;
-    }
-
     if (config->disks[i][0] == '/') {
       device = strdup (config->disks[i]);
       if (!device) {
@@ -272,26 +252,55 @@ start_conversion (struct config *config,
       exit (EXIT_FAILURE);
     }
 
-#if DEBUG_STDERR
-    fprintf (stderr,
-             "%s: data connection for %s: SSH remote port %d, local port %d\n",
-             getprogname (), device,
-             data_conns[i].nbd_remote_port, data_conns[i].nbd_local_port);
-#endif
+    if (notify_ui) {
+      CLEANUP_FREE char *msg;
+      if (asprintf (&msg,
+                    _("Starting local NBD server for %s ..."),
+                    config->disks[i]) == -1)
+        error (EXIT_FAILURE, errno, "asprintf");
+      notify_ui (NOTIFY_STATUS, msg);
+    }
 
     /* Start NBD server listening on the given port number. */
-    data_conns[i].nbd_pid =
-      start_nbd_server (data_conns[i].nbd_local_port, device);
+    data_conns[i].nbd_pid = start_nbd_server (&nbd_local_port, device);
     if (data_conns[i].nbd_pid == 0) {
       set_conversion_error ("NBD server error: %s", get_nbd_error ());
       goto out;
     }
 
     /* Wait for NBD server to start up and listen. */
-    if (wait_for_nbd_server_to_start (data_conns[i].nbd_local_port) == -1) {
+    if (wait_for_nbd_server_to_start (nbd_local_port) == -1) {
       set_conversion_error ("NBD server error: %s", get_nbd_error ());
       goto out;
     }
+
+    if (notify_ui) {
+      CLEANUP_FREE char *msg;
+      if (asprintf (&msg,
+                    _("Opening data connection for %s ..."),
+                    config->disks[i]) == -1)
+        error (EXIT_FAILURE, errno, "asprintf");
+      notify_ui (NOTIFY_STATUS, msg);
+    }
+
+    /* Open the SSH data connection, with reverse port forwarding
+     * back to the NBD server.
+     */
+    data_conns[i].h = open_data_connection (config, nbd_local_port,
+                                            &data_conns[i].nbd_remote_port);
+    if (data_conns[i].h == NULL) {
+      const char *err = get_ssh_error ();
+
+      set_conversion_error ("could not open data connection over SSH to the conversion server: %s", err);
+      goto out;
+    }
+
+#if DEBUG_STDERR
+    fprintf (stderr,
+             "%s: data connection for %s: SSH remote port %d, local port %d\n",
+             getprogname (), device,
+             data_conns[i].nbd_remote_port, nbd_local_port);
+#endif
   }
 
   /* Create a remote directory name which will be used for libvirt
diff --git a/p2v/main.c b/p2v/main.c
index d1eece6..42d3bbb 100644
--- a/p2v/main.c
+++ b/p2v/main.c
@@ -51,7 +51,6 @@ char **all_disks;
 char **all_removable;
 char **all_interfaces;
 int is_iso_environment = 0;
-int nbd_local_port;
 int feature_colours_option = 0;
 int force_colour = 0;
 static const char *test_disk = NULL;
@@ -224,18 +223,6 @@ main (int argc, char *argv[])
     usage (EXIT_FAILURE);
   }
 
-  if (is_iso_environment)
-    /* The p2v ISO should allow us to open up just about any port, so
-     * we can fix a port number in that case.  Using a predictable
-     * port number in this case should avoid rare errors if the port
-     * colides with another (ie. it'll either always fail or never
-     * fail).
-     */
-    nbd_local_port = 50123;
-  else
-    /* When testing on the local machine, choose a random port. */
-    nbd_local_port = 50000 + (random () % 10000);
-
   test_nbd_servers ();
 
   set_config_defaults (config);
diff --git a/p2v/nbd.c b/p2v/nbd.c
index ce90361..ed6f9a1 100644
--- a/p2v/nbd.c
+++ b/p2v/nbd.c
@@ -45,6 +45,11 @@
 /* How long to wait for the NBD server to start (seconds). */
 #define WAIT_NBD_TIMEOUT 10
 
+/* The local port that the NBD server listens on (incremented for
+ * each server which is started).
+ */
+static int nbd_local_port;
+
 /* List of servers specified by the --nbd option. */
 enum nbd_server {
   /* 0 is reserved for "end of list" */
@@ -150,6 +155,19 @@ test_nbd_servers (void)
   int r;
   const enum nbd_server *servers;
 
+  /* Initialize nbd_local_port. */
+  if (is_iso_environment)
+    /* The p2v ISO should allow us to open up just about any port, so
+     * we can fix a port number in that case.  Using a predictable
+     * port number in this case should avoid rare errors if the port
+     * colides with another (ie. it'll either always fail or never
+     * fail).
+     */
+    nbd_local_port = 50123;
+  else
+    /* When testing on the local machine, choose a random port. */
+    nbd_local_port = 50000 + (random () % 10000);
+
   if (cmdline_servers != NULL)
     servers = cmdline_servers;
   else
@@ -211,14 +229,18 @@ test_nbd_servers (void)
  * Returns the process ID (E<gt> 0) or C<0> if there is an error.
  */
 pid_t
-start_nbd_server (int port, const char *device)
+start_nbd_server (int *port, const char *device)
 {
+  /* Choose a local port. */
+  *port = nbd_local_port;
+  nbd_local_port++;
+
   switch (use_server) {
   case QEMU_NBD:
-    return start_qemu_nbd (port, device);
+    return start_qemu_nbd (*port, device);
 
   case NBDKIT:
-    return start_nbdkit (port, device);
+    return start_nbdkit (*port, device);
 
   default:
     abort ();
diff --git a/p2v/p2v.h b/p2v/p2v.h
index 800862d..1cde808 100644
--- a/p2v/p2v.h
+++ b/p2v/p2v.h
@@ -52,11 +52,6 @@ extern char **all_interfaces;
  */
 extern int is_iso_environment;
 
-/* The local port that the NBD server listens on (incremented for
- * each server which is started).
- */
-extern int nbd_local_port;
-
 /* True if virt-v2v supports the --colours option. */
 extern int feature_colours_option;
 
@@ -130,7 +125,7 @@ extern int inhibit_power_saving (void);
 
 /* ssh.c */
 extern int test_connection (struct config *);
-extern mexp_h *open_data_connection (struct config *, int *local_port, int *remote_port);
+extern mexp_h *open_data_connection (struct config *, int local_port, int *remote_port);
 extern mexp_h *start_remote_connection (struct config *, const char *remote_dir);
 extern const char *get_ssh_error (void);
 extern int scp_file (struct config *config, const char *localfile, const char *remotefile);
@@ -138,7 +133,7 @@ extern int scp_file (struct config *config, const char *localfile, const char *r
 /* nbd.c */
 extern void set_nbd_option (const char *opt);
 extern void test_nbd_servers (void);
-extern pid_t start_nbd_server (int nbd_local_port, const char *device);
+extern pid_t start_nbd_server (int *nbd_local_port, const char *device);
 extern int wait_for_nbd_server_to_start (int nbd_local_port);
 const char *get_nbd_error (void);
 
diff --git a/p2v/ssh.c b/p2v/ssh.c
index 4c1d64c..d29aa40 100644
--- a/p2v/ssh.c
+++ b/p2v/ssh.c
@@ -1039,7 +1039,7 @@ compatible_version (const char *v2v_version)
 }
 
 mexp_h *
-open_data_connection (struct config *config, int *local_port, int *remote_port)
+open_data_connection (struct config *config, int local_port, int *remote_port)
 {
   mexp_h *h;
   char remote_arg[32];
@@ -1052,9 +1052,7 @@ open_data_connection (struct config *config, int *local_port, int *remote_port)
   const int ovecsize = 12;
   int ovector[ovecsize];
 
-  snprintf (remote_arg, sizeof remote_arg, "0:localhost:%d", nbd_local_port);
-  *local_port = nbd_local_port;
-  nbd_local_port++;
+  snprintf (remote_arg, sizeof remote_arg, "0:localhost:%d", local_port);
 
   h = start_ssh (0, config, (char **) extra_args, 0);
   if (h == NULL)
-- 
2.9.3




More information about the Libguestfs mailing list