When using the virt-p2v ISO in command line mode, we did not wait for
the network to come online before starting virt-p2v. Therefore
virt-p2v could exit with an error when testing the ssh connection (or
on the other hand, it might work randomly). If the user logs in and
runs 'launch-virt-p2v' by hand, then it would usually work because the
network had been brought online in the meantime.
Fix this by waiting for NetworkManager to bring the connection online
before calling test_connection(). Note that the obvious way to fix
this (changing the systemd service to wait for network-online.target)
does *not* work - I added a comment to the service about this.
Thanks: Tingting Zheng
---
p2v/gui.c | 3 +++
p2v/kernel.c | 1 +
p2v/p2v.h | 1 +
p2v/p2v.service | 5 +++++
p2v/utils.c | 22 ++++++++++++++++++++++
5 files changed, 32 insertions(+)
diff --git a/p2v/gui.c b/p2v/gui.c
index 10d29e2..b3ad05d 100644
--- a/p2v/gui.c
+++ b/p2v/gui.c
@@ -324,8 +324,11 @@ test_connection_thread (void *data)
_("Testing the connection to the conversion server
..."));
gtk_spinner_start (GTK_SPINNER (spinner));
gdk_threads_leave ();
+
+ wait_network_online (copy);
r = test_connection (copy);
free_config (copy);
+
gdk_threads_enter ();
gtk_spinner_stop (GTK_SPINNER (spinner));
diff --git a/p2v/kernel.c b/p2v/kernel.c
index b283417..9fec47f 100644
--- a/p2v/kernel.c
+++ b/p2v/kernel.c
@@ -81,6 +81,7 @@ kernel_configuration (struct config *config, char **cmdline, int
cmdline_source)
*/
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 ();
diff --git a/p2v/p2v.h b/p2v/p2v.h
index c9cd653..34f6bcf 100644
--- a/p2v/p2v.h
+++ b/p2v/p2v.h
@@ -119,6 +119,7 @@ extern const char *get_ssh_error (void);
/* utils.c */
extern char *get_if_addr (const char *if_name);
extern char *get_if_vendor (const char *if_name, int truncate);
+extern void wait_network_online (const struct config *);
/* virt-v2v version and features (read from remote). */
extern int v2v_major;
diff --git a/p2v/p2v.service b/p2v/p2v.service
index a6b5e25..a6c4cd9 100644
--- a/p2v/p2v.service
+++ b/p2v/p2v.service
@@ -20,6 +20,11 @@
[Unit]
Description=p2v service
+# For the GUI, we cannot necessarily wait for the network to come
+# online, since that may require the "Configure Network" dialog. For
+# the command line, we would like the network to be online, but we
+# test that within virt-p2v itself. Therefore use network.target
+# here, not network-online.target.
After=network.target
[Service]
diff --git a/p2v/utils.c b/p2v/utils.c
index 0b30be3..3781a8d 100644
--- a/p2v/utils.c
+++ b/p2v/utils.c
@@ -26,6 +26,8 @@
#include <locale.h>
#include <libintl.h>
+#include "ignore-value.h"
+
#include "p2v.h"
#define CHOMP(line,len) \
@@ -134,3 +136,23 @@ get_if_vendor (const char *if_name, int truncate)
free (line);
return NULL;
}
+
+/* Wait for the network to come online, but don't error out if that
+ * fails. The caller will call test_connection immediately after this
+ * which will fail if the network didn't come online.
+ */
+
+/* XXX We could make this configurable. */
+#define NETWORK_ONLINE_COMMAND "nm-online -t 30"
+
+void
+wait_network_online (const struct config *config)
+{
+ if (config->verbose) {
+ printf ("waiting for the network to come online ...\n");
+ printf ("%s\n", NETWORK_ONLINE_COMMAND);
+ fflush (stdout);
+ }
+
+ ignore_value (system (NETWORK_ONLINE_COMMAND));
+}
--
2.5.0