diff options
author | Dan Winship <danw@gnome.org> | 2013-08-13 17:49:05 -0400 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2013-08-16 17:27:34 -0400 |
commit | 44ac1020daccfeeb1dc88566adda6e5d8bd87aea (patch) | |
tree | a0a9dff4ab0e052d8c005793711275ad9fa2e51a | |
parent | 4d8063cd788ea22ee28f35097e1350c2adac1af3 (diff) | |
download | NetworkManager-44ac1020daccfeeb1dc88566adda6e5d8bd87aea.tar.gz |
nm-online: wait for all startup-time connections, not just one
Rewrite nm-online to use libnm-glib, and change it so that it waits
until NM has finished all of its startup-time connection activation
attempts, rather than only waiting until at least one has succeeded.
In particular, this means that on multi-homed servers, the
NetworkManager-wait-online systemd service (and by extension,
network.service) will now block until *all* of the server's IP
addresses are up, which is needed for some old daemons that assume
that no network interfaces will be added after they start.
-rw-r--r-- | test/Makefile.am | 1 | ||||
-rw-r--r-- | test/nm-online.c | 124 |
2 files changed, 34 insertions, 91 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index f244f73215..19c46ec6f6 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -18,6 +18,7 @@ noinst_PROGRAMS = libnm-glib-test nm_online_SOURCES = nm-online.c nm_online_LDADD = \ + $(top_builddir)/libnm-glib/libnm-glib.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/test/nm-online.c b/test/nm-online.c index 53315a7e6d..7df66c20fa 100644 --- a/test/nm-online.c +++ b/test/nm-online.c @@ -37,78 +37,37 @@ #include <getopt.h> #include <locale.h> -#include <glib.h> #include <glib/gi18n.h> -#include <dbus/dbus.h> -#include <dbus/dbus-glib-lowlevel.h> -#include <dbus/dbus-glib.h> -#include "NetworkManager.h" -#include "nm-glib-compat.h" +#include "nm-client.h" #define PROGRESS_STEPS 15 -typedef struct +typedef struct { int value; double norm; gboolean quiet; } Timeout; -static GMainLoop *loop; - -static DBusHandlerResult -dbus_filter (DBusConnection *connection G_GNUC_UNUSED, - DBusMessage *message, - void *user_data G_GNUC_UNUSED) +static void +client_properties_changed (GObject *object, + GParamSpec *pspec, + gpointer loop) { - NMState state; - - if (!dbus_message_is_signal (message, NM_DBUS_INTERFACE, "StateChanged")) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (!dbus_message_get_args (message, NULL, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + NMClient *client = NM_CLIENT (object); - if ( state == NM_STATE_CONNECTED_LOCAL - || state == NM_STATE_CONNECTED_SITE - || state == NM_STATE_CONNECTED_GLOBAL) + if (!nm_client_get_manager_running (client)) + return; + if (!nm_client_get_startup (client)) g_main_loop_quit (loop); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static NMState -check_online (DBusConnection *connection) -{ - DBusMessage *message, *reply; - DBusError error; - dbus_uint32_t state; - - message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH, - NM_DBUS_INTERFACE, "state"); - if (!message) - exit (2); - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connection, message, - -1, &error); - dbus_message_unref (message); - if (!reply) - return NM_STATE_UNKNOWN; - - if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &state, - DBUS_TYPE_INVALID)) - exit (2); - - return state; } static gboolean handle_timeout (gpointer data) { int i = PROGRESS_STEPS; - Timeout *timeout = (Timeout *) data; + Timeout *timeout = data; if (!timeout->quiet) { g_print (_("\rConnecting")); @@ -132,19 +91,18 @@ handle_timeout (gpointer data) int main (int argc, char *argv[]) { - DBusConnection *connection; - DBusError error; - NMState state; gint t_secs = -1; gboolean exit_no_nm = FALSE; gboolean quiet = FALSE; Timeout timeout; GOptionContext *opt_ctx = NULL; gboolean success; + NMClient *client; + GMainLoop *loop; GOptionEntry options[] = { {"timeout", 't', 0, G_OPTION_ARG_INT, &t_secs, N_("Time to wait for a connection, in seconds (without the option, default value is 30)"), "<timeout>"}, - {"exit", 'x', 0, G_OPTION_ARG_NONE, &exit_no_nm, N_("Exit immediately if NetworkManager is not running or connecting"), NULL}, + {"exit", 'x', 0, G_OPTION_ARG_NONE, &exit_no_nm, N_("Exit immediately if NetworkManager is not running"), NULL}, {"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, N_("Don't print anything"), NULL}, {NULL} }; @@ -163,13 +121,14 @@ main (int argc, char *argv[]) g_option_context_add_main_entries (opt_ctx, options, NULL); g_option_context_set_summary (opt_ctx, - _("Waits for a successful connection in NetworkManager.")); + _("Waits for NetworkManager to finish activating startup network connections.")); success = g_option_context_parse (opt_ctx, &argc, &argv, NULL); g_option_context_free (opt_ctx); if (!success) { - g_warning (_("Invalid option. Please use --help to see a list of valid options.")); + g_printerr ("%s: %s\n", argv[0], + _("Invalid option. Please use --help to see a list of valid options.")); return 2; } @@ -178,51 +137,34 @@ main (int argc, char *argv[]) else timeout.value = 30; if (timeout.value < 0 || timeout.value > 3600) { - g_warning (_("Invalid option. Please use --help to see a list of valid options.")); + g_printerr ("%s: %s\n", argv[0], + _("Invalid option. Please use --help to see a list of valid options.")); return 2; } g_type_init (); loop = g_main_loop_new (NULL, FALSE); - dbus_error_init (&error); - connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); - if (connection == NULL) { - dbus_error_free (&error); - return 2; - } + client = nm_client_new (); - dbus_connection_setup_with_g_main (connection, NULL); - - if (!dbus_connection_add_filter (connection, dbus_filter, NULL, NULL)) - return 2; - - dbus_bus_add_match (connection, - "type='signal'," - "interface='" NM_DBUS_INTERFACE "'," - "sender='" NM_DBUS_SERVICE "'," - "path='" NM_DBUS_PATH "'", &error); - if (dbus_error_is_set (&error)) { - dbus_error_free (&error); - return 2; - } - - /* Check after we setup the filter to ensure that we cannot race. */ - state = check_online (connection); - if ( state == NM_STATE_CONNECTED_LOCAL - || state == NM_STATE_CONNECTED_SITE - || state == NM_STATE_CONNECTED_GLOBAL) + if (!nm_client_get_manager_running (client)) { + if (exit_no_nm) + return 1; + } else if (!nm_client_get_startup (client)) return 0; - if (exit_no_nm && (state != NM_STATE_CONNECTING)) + if (!timeout.value) return 1; - if (timeout.value) { - timeout.norm = (double) timeout.value / (double) PROGRESS_STEPS; - g_timeout_add_seconds (1, handle_timeout, &timeout); - } - timeout.quiet = quiet; + timeout.norm = (double) timeout.value / (double) PROGRESS_STEPS; + g_timeout_add_seconds (1, handle_timeout, &timeout); + + g_signal_connect (client, "notify", + G_CALLBACK (client_properties_changed), loop); g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_object_unref (client); return 0; } |