summary refs log tree commit diff
path: root/src/main.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-10-05 22:27:18 +0200
committerMichael Biebl <biebl@debian.org>2020-10-05 22:27:18 +0200
commitaafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch)
treea2a9bb4d007339a0b1304540388230ccedac32bd /src/main.c
parente7b44ef4c80907346ec7492a09c45277459924fc (diff)
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c801
1 files changed, 431 insertions, 370 deletions
diff --git a/src/main.c b/src/main.c
index 262b6484..467a1bed 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2004 - 2017 Red Hat, Inc.
  * Copyright (C) 2005 - 2008 Novell, Inc.
@@ -37,202 +37,251 @@
 #include "nm-netns.h"
 
 #if !defined(NM_DIST_VERSION)
-# define NM_DIST_VERSION VERSION
+    #define NM_DIST_VERSION VERSION
 #endif
 
-#define NM_DEFAULT_PID_FILE          NMRUNDIR "/NetworkManager.pid"
+#define NM_DEFAULT_PID_FILE NMRUNDIR "/NetworkManager.pid"
 
 #define CONFIG_ATOMIC_SECTION_PREFIXES ((char **) NULL)
 
-static GMainLoop *main_loop = NULL;
-static gboolean configure_and_quit = FALSE;
+static GMainLoop *main_loop          = NULL;
+static gboolean   configure_and_quit = FALSE;
 
 static struct {
-	gboolean show_version;
-	gboolean print_config;
-	gboolean become_daemon;
-	gboolean g_fatal_warnings;
-	gboolean run_from_build_dir;
-	char *opt_log_level;
-	char *opt_log_domains;
-	char *pidfile;
+    gboolean show_version;
+    gboolean print_config;
+    gboolean become_daemon;
+    gboolean g_fatal_warnings;
+    gboolean run_from_build_dir;
+    char *   opt_log_level;
+    char *   opt_log_domains;
+    char *   pidfile;
 } global_opt = {
-	.become_daemon = TRUE,
+    .become_daemon = TRUE,
 };
 
 static void
-_set_g_fatal_warnings (void)
+_set_g_fatal_warnings(void)
 {
-	GLogLevelFlags fatal_mask;
+    GLogLevelFlags fatal_mask;
 
-	fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
-	fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
-	g_log_set_always_fatal (fatal_mask);
+    fatal_mask = g_log_set_always_fatal(G_LOG_FATAL_MASK);
+    fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+    g_log_set_always_fatal(fatal_mask);
 }
 
 static void
-_init_nm_debug (NMConfig *config)
+_init_nm_debug(NMConfig *config)
 {
-	gs_free char *debug = NULL;
-	enum {
-		D_RLIMIT_CORE =    (1 << 0),
-		D_FATAL_WARNINGS = (1 << 1),
-	};
-	GDebugKey keys[] = {
-		{ "RLIMIT_CORE", D_RLIMIT_CORE },
-		{ "fatal-warnings", D_FATAL_WARNINGS },
-	};
-	guint flags;
-	const char *env = getenv ("NM_DEBUG");
-
-	debug = nm_config_data_get_value (nm_config_get_data_orig (config),
-	                                  NM_CONFIG_KEYFILE_GROUP_MAIN,
-	                                  NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG,
-	                                  NM_CONFIG_GET_VALUE_NONE);
-
-	flags  = nm_utils_parse_debug_string (env, keys, G_N_ELEMENTS (keys));
-	flags |= nm_utils_parse_debug_string (debug, keys, G_N_ELEMENTS (keys));
-
-#if ! defined (__SANITIZE_ADDRESS__)
-	if (NM_FLAGS_HAS (flags, D_RLIMIT_CORE)) {
-		/* only enable this, if explicitly requested, because it might
-		 * expose sensitive data. */
-
-		struct rlimit limit = {
-			.rlim_cur = RLIM_INFINITY,
-			.rlim_max = RLIM_INFINITY,
-		};
-		setrlimit (RLIMIT_CORE, &limit);
-	}
+    gs_free char *debug = NULL;
+    enum {
+        D_RLIMIT_CORE    = (1 << 0),
+        D_FATAL_WARNINGS = (1 << 1),
+    };
+    GDebugKey keys[] = {
+        {"RLIMIT_CORE", D_RLIMIT_CORE},
+        {"fatal-warnings", D_FATAL_WARNINGS},
+    };
+    guint       flags;
+    const char *env = getenv("NM_DEBUG");
+
+    debug = nm_config_data_get_value(nm_config_get_data_orig(config),
+                                     NM_CONFIG_KEYFILE_GROUP_MAIN,
+                                     NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG,
+                                     NM_CONFIG_GET_VALUE_NONE);
+
+    flags = nm_utils_parse_debug_string(env, keys, G_N_ELEMENTS(keys));
+    flags |= nm_utils_parse_debug_string(debug, keys, G_N_ELEMENTS(keys));
+
+#if !defined(__SANITIZE_ADDRESS__)
+    if (NM_FLAGS_HAS(flags, D_RLIMIT_CORE)) {
+        /* only enable this, if explicitly requested, because it might
+         * expose sensitive data. */
+
+        struct rlimit limit = {
+            .rlim_cur = RLIM_INFINITY,
+            .rlim_max = RLIM_INFINITY,
+        };
+        setrlimit(RLIMIT_CORE, &limit);
+    }
 #endif
 
-	if (NM_FLAGS_HAS (flags, D_FATAL_WARNINGS))
-		_set_g_fatal_warnings ();
+    if (NM_FLAGS_HAS(flags, D_FATAL_WARNINGS))
+        _set_g_fatal_warnings();
 }
 
 void
-nm_main_config_reload (int signal)
+nm_main_config_reload(int signal)
 {
-	NMConfigChangeFlags reload_flags;
-
-	switch (signal) {
-	case SIGHUP:
-		reload_flags = NM_CONFIG_CHANGE_CAUSE_SIGHUP;
-		break;
-	case SIGUSR1:
-		reload_flags = NM_CONFIG_CHANGE_CAUSE_SIGUSR1;
-		break;
-	case SIGUSR2:
-		reload_flags = NM_CONFIG_CHANGE_CAUSE_SIGUSR2;
-		break;
-	default:
-		g_return_if_reached ();
-	}
-
-	nm_log_info (LOGD_CORE, "reload configuration (signal %s)...", strsignal (signal));
-
-	/* The signal handler thread is only installed after
-	 * creating NMConfig instance, and on shut down we
-	 * no longer run the mainloop (to reach this point).
-	 *
-	 * Hence, a NMConfig singleton instance must always be
-	 * available. */
-	nm_config_reload (nm_config_get (), reload_flags, TRUE);
+    NMConfigChangeFlags reload_flags;
+
+    switch (signal) {
+    case SIGHUP:
+        reload_flags = NM_CONFIG_CHANGE_CAUSE_SIGHUP;
+        break;
+    case SIGUSR1:
+        reload_flags = NM_CONFIG_CHANGE_CAUSE_SIGUSR1;
+        break;
+    case SIGUSR2:
+        reload_flags = NM_CONFIG_CHANGE_CAUSE_SIGUSR2;
+        break;
+    default:
+        g_return_if_reached();
+    }
+
+    nm_log_info(LOGD_CORE, "reload configuration (signal %s)...", strsignal(signal));
+
+    /* The signal handler thread is only installed after
+     * creating NMConfig instance, and on shut down we
+     * no longer run the mainloop (to reach this point).
+     *
+     * Hence, a NMConfig singleton instance must always be
+     * available. */
+    nm_config_reload(nm_config_get(), reload_flags, TRUE);
 }
 
 static void
-manager_configure_quit (NMManager *manager, gpointer user_data)
+manager_configure_quit(NMManager *manager, gpointer user_data)
 {
-	nm_log_info (LOGD_CORE, "quitting now that startup is complete");
-	g_main_loop_quit (main_loop);
-	configure_and_quit = TRUE;
+    nm_log_info(LOGD_CORE, "quitting now that startup is complete");
+    g_main_loop_quit(main_loop);
+    configure_and_quit = TRUE;
 }
 
 static int
-print_config (NMConfigCmdLineOptions *config_cli)
+print_config(NMConfigCmdLineOptions *config_cli)
 {
-	gs_unref_object NMConfig *config = NULL;
-	gs_free_error GError *error = NULL;
-	NMConfigData *config_data;
-	const char *const*warnings;
-
-	nm_logging_setup ("OFF", "ALL", NULL, NULL);
-
-	config = nm_config_new (config_cli, CONFIG_ATOMIC_SECTION_PREFIXES, &error);
-	if (config == NULL) {
-		fprintf (stderr, _("Failed to read configuration: %s\n"), error->message);
-		return 7;
-	}
-
-	config_data = nm_config_get_data (config);
-	fprintf (stdout, "# NetworkManager configuration: %s\n", nm_config_data_get_config_description (config_data));
-	nm_config_data_log (config_data, "", "", nm_config_get_no_auto_default_file (config), stdout);
-
-	warnings = nm_config_get_warnings (config);
-	if (warnings && warnings[0])
-		fprintf (stdout, "\n");
-	for ( ; warnings && warnings[0]; warnings++)
-		fprintf (stdout, "# WARNING: %s\n", warnings[0]);
-
-	return 0;
+    gs_unref_object NMConfig *config = NULL;
+    gs_free_error GError *error      = NULL;
+    NMConfigData *        config_data;
+    const char *const *   warnings;
+
+    nm_logging_setup("OFF", "ALL", NULL, NULL);
+
+    config = nm_config_new(config_cli, CONFIG_ATOMIC_SECTION_PREFIXES, &error);
+    if (config == NULL) {
+        fprintf(stderr, _("Failed to read configuration: %s\n"), error->message);
+        return 7;
+    }
+
+    config_data = nm_config_get_data(config);
+    fprintf(stdout,
+            "# NetworkManager configuration: %s\n",
+            nm_config_data_get_config_description(config_data));
+    nm_config_data_log(config_data, "", "", nm_config_get_no_auto_default_file(config), stdout);
+
+    warnings = nm_config_get_warnings(config);
+    if (warnings && warnings[0])
+        fprintf(stdout, "\n");
+    for (; warnings && warnings[0]; warnings++)
+        fprintf(stdout, "# WARNING: %s\n", warnings[0]);
+
+    return 0;
 }
 
 static void
-do_early_setup (int *argc, char **argv[], NMConfigCmdLineOptions *config_cli)
+do_early_setup(int *argc, char **argv[], NMConfigCmdLineOptions *config_cli)
 {
-	GOptionEntry options[] = {
-		{ "version", 'V', 0, G_OPTION_ARG_NONE, &global_opt.show_version, N_("Print NetworkManager version and exit"), NULL },
-		{ "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &global_opt.become_daemon, N_("Don't become a daemon"), NULL },
-		{ "log-level", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_level, N_("Log level: one of [%s]"), "INFO" },
-		{ "log-domains", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_domains,
-		  N_("Log domains separated by ',': any combination of [%s]"),
-		  "PLATFORM,RFKILL,WIFI" },
-		{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &global_opt.g_fatal_warnings, N_("Make all warnings fatal"), NULL },
-		{ "pid-file", 'p', 0, G_OPTION_ARG_FILENAME, &global_opt.pidfile, N_("Specify the location of a PID file"), NM_DEFAULT_PID_FILE },
-		{ "run-from-build-dir", 0, 0, G_OPTION_ARG_NONE, &global_opt.run_from_build_dir, "Run from build directory", NULL },
-		{ "print-config", 0, 0, G_OPTION_ARG_NONE, &global_opt.print_config, N_("Print NetworkManager configuration and exit"), NULL },
-		{NULL}
-	};
-
-	if (!nm_main_utils_early_setup ("NetworkManager",
-	                                argc,
-	                                argv,
-	                                options,
-	                                (void (*)(gpointer, GOptionContext *)) nm_config_cmd_line_options_add_to_entries,
-	                                config_cli,
-	                                _("NetworkManager monitors all network connections and automatically\nchooses the best connection to use.  It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with.")))
-		exit (1);
-
-	global_opt.pidfile = global_opt.pidfile ?: g_strdup(NM_DEFAULT_PID_FILE);
+    GOptionEntry options[] = {{"version",
+                               'V',
+                               0,
+                               G_OPTION_ARG_NONE,
+                               &global_opt.show_version,
+                               N_("Print NetworkManager version and exit"),
+                               NULL},
+                              {"no-daemon",
+                               'n',
+                               G_OPTION_FLAG_REVERSE,
+                               G_OPTION_ARG_NONE,
+                               &global_opt.become_daemon,
+                               N_("Don't become a daemon"),
+                               NULL},
+                              {"log-level",
+                               0,
+                               0,
+                               G_OPTION_ARG_STRING,
+                               &global_opt.opt_log_level,
+                               N_("Log level: one of [%s]"),
+                               "INFO"},
+                              {"log-domains",
+                               0,
+                               0,
+                               G_OPTION_ARG_STRING,
+                               &global_opt.opt_log_domains,
+                               N_("Log domains separated by ',': any combination of [%s]"),
+                               "PLATFORM,RFKILL,WIFI"},
+                              {"g-fatal-warnings",
+                               0,
+                               0,
+                               G_OPTION_ARG_NONE,
+                               &global_opt.g_fatal_warnings,
+                               N_("Make all warnings fatal"),
+                               NULL},
+                              {"pid-file",
+                               'p',
+                               0,
+                               G_OPTION_ARG_FILENAME,
+                               &global_opt.pidfile,
+                               N_("Specify the location of a PID file"),
+                               NM_DEFAULT_PID_FILE},
+                              {"run-from-build-dir",
+                               0,
+                               0,
+                               G_OPTION_ARG_NONE,
+                               &global_opt.run_from_build_dir,
+                               "Run from build directory",
+                               NULL},
+                              {"print-config",
+                               0,
+                               0,
+                               G_OPTION_ARG_NONE,
+                               &global_opt.print_config,
+                               N_("Print NetworkManager configuration and exit"),
+                               NULL},
+                              {NULL}};
+
+    if (!nm_main_utils_early_setup(
+            "NetworkManager",
+            argc,
+            argv,
+            options,
+            (void (*)(gpointer, GOptionContext *)) nm_config_cmd_line_options_add_to_entries,
+            config_cli,
+            _("NetworkManager monitors all network connections and automatically\nchooses the best "
+              "connection to use.  It also allows the user to\nspecify wireless access points "
+              "which wireless cards in the computer\nshould associate with.")))
+        exit(1);
+
+    global_opt.pidfile = global_opt.pidfile ?: g_strdup(NM_DEFAULT_PID_FILE);
 }
 
 static gboolean
-_dbus_manager_init (NMConfig *config)
+_dbus_manager_init(NMConfig *config)
 {
-	NMDBusManager *busmgr;
-	NMConfigConfigureAndQuitType c_a_q_type;
-
-	busmgr = nm_dbus_manager_get ();
-
-	c_a_q_type = nm_config_get_configure_and_quit (config);
-
-	if (c_a_q_type == NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED)
-		return nm_dbus_manager_acquire_bus (busmgr, TRUE);
-
-	if (c_a_q_type == NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED) {
-		/* D-Bus is useless in configure and quit mode -- we're eventually dropping
-		 * off and potential clients would have no way of knowing whether we're
-		 * finished already or didn't start yet.
-		 *
-		 * But we still create a nm_dbus_manager_get_dbus_connection() D-Bus connection
-		 * so that we can talk to other services like firewalld. */
-		return nm_dbus_manager_acquire_bus (busmgr, FALSE);
-	}
-
-	nm_assert (c_a_q_type == NM_CONFIG_CONFIGURE_AND_QUIT_INITRD);
-	/* in initrd we don't have D-Bus at all. Don't even try to get the G_BUS_TYPE_SYSTEM
-	 * connection. And of course don't claim the D-Bus name. */
-	return TRUE;
+    NMDBusManager *              busmgr;
+    NMConfigConfigureAndQuitType c_a_q_type;
+
+    busmgr = nm_dbus_manager_get();
+
+    c_a_q_type = nm_config_get_configure_and_quit(config);
+
+    if (c_a_q_type == NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED)
+        return nm_dbus_manager_acquire_bus(busmgr, TRUE);
+
+    if (c_a_q_type == NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED) {
+        /* D-Bus is useless in configure and quit mode -- we're eventually dropping
+         * off and potential clients would have no way of knowing whether we're
+         * finished already or didn't start yet.
+         *
+         * But we still create a nm_dbus_manager_get_dbus_connection() D-Bus connection
+         * so that we can talk to other services like firewalld. */
+        return nm_dbus_manager_acquire_bus(busmgr, FALSE);
+    }
+
+    nm_assert(c_a_q_type == NM_CONFIG_CONFIGURE_AND_QUIT_INITRD);
+    /* in initrd we don't have D-Bus at all. Don't even try to get the G_BUS_TYPE_SYSTEM
+     * connection. And of course don't claim the D-Bus name. */
+    return TRUE;
 }
 
 /*
@@ -240,245 +289,257 @@ _dbus_manager_init (NMConfig *config)
  *
  */
 int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
 {
-	gboolean success = FALSE;
-	NMManager *manager = NULL;
-	NMConfig *config;
-	gs_free_error GError *error = NULL;
-	gboolean wrote_pidfile = FALSE;
-	char *bad_domains = NULL;
-	NMConfigCmdLineOptions *config_cli;
-	guint sd_id = 0;
-	GError *error_invalid_logging_config = NULL;
-	const char *const *warnings;
-	int errsv;
-
-	/* Known to cause a possible deadlock upon GDBus initialization:
-	 * https://bugzilla.gnome.org/show_bug.cgi?id=674885 */
-	g_type_ensure (G_TYPE_SOCKET);
-	g_type_ensure (G_TYPE_DBUS_CONNECTION);
-	g_type_ensure (NM_TYPE_DBUS_MANAGER);
-
-	_nm_utils_is_manager_process = TRUE;
-
-	main_loop = g_main_loop_new (NULL, FALSE);
-
-	/* we determine a first-start (contrary to a restart during the same boot)
-	 * based on the existence of NM_CONFIG_DEVICE_STATE_DIR directory. */
-	config_cli = nm_config_cmd_line_options_new (!g_file_test (NM_CONFIG_DEVICE_STATE_DIR,
-	                                                           G_FILE_TEST_IS_DIR));
-
-	do_early_setup (&argc, &argv, config_cli);
-
-	if (global_opt.g_fatal_warnings)
-		_set_g_fatal_warnings ();
-
-	if (global_opt.show_version) {
-		fprintf (stdout, NM_DIST_VERSION "\n");
-		exit (0);
-	}
-
-	if (global_opt.print_config) {
-		int result;
-
-		result = print_config (config_cli);
-		nm_config_cmd_line_options_free (config_cli);
-		exit (result);
-	}
-
-	nm_main_utils_ensure_root ();
-
-	nm_main_utils_ensure_not_running_pidfile (global_opt.pidfile);
-
-	nm_main_utils_ensure_statedir ();
-	nm_main_utils_ensure_rundir ();
-
-	/* When running from the build directory, determine our build directory
-	 * base and set helper paths in the build tree */
-	if (global_opt.run_from_build_dir) {
-		char *path, *slash;
-		int g;
-
-		/* exe is <basedir>/src/.libs/lt-NetworkManager, so chop off
-		 * the last three components */
-		path = realpath ("/proc/self/exe", NULL);
-		g_assert (path != NULL);
-		for (g = 0; g < 3; ++g) {
-			slash = strrchr (path, '/');
-			g_assert (slash != NULL);
-			*slash = '\0';
-		}
-
-		/* don't free these strings, we need them for the entire
-		 * process lifetime */
-		nm_dhcp_helper_path = g_strdup_printf ("%s/src/dhcp/nm-dhcp-helper", path);
-
-		g_free (path);
-	}
-
-	if (!nm_logging_setup (global_opt.opt_log_level,
-	                       global_opt.opt_log_domains,
-	                       &bad_domains,
-	                       &error)) {
-		fprintf (stderr,
-		         _("%s.  Please use --help to see a list of valid options.\n"),
-		         error->message);
-		exit (1);
-	}
-
-	/* Read the config file and CLI overrides */
-	config = nm_config_setup (config_cli, CONFIG_ATOMIC_SECTION_PREFIXES, &error);
-	nm_config_cmd_line_options_free (config_cli);
-	config_cli = NULL;
-	if (config == NULL) {
-		fprintf (stderr, _("Failed to read configuration: %s\n"),
-		         error->message);
-		exit (1);
-	}
-
-	_init_nm_debug (config);
-
-	/* Initialize logging from config file *only* if not explicitly
-	 * specified by commandline.
-	 */
-	if (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL) {
-		if (!nm_logging_setup (nm_config_get_log_level (config),
-		                       nm_config_get_log_domains (config),
-		                       &bad_domains,
-		                       &error_invalid_logging_config)) {
-			/* ignore error, and print the failure reason below.
-			 * Likewise, print about bad_domains below. */
-		}
-	}
-
-	if (global_opt.become_daemon && !nm_config_get_is_debug (config)) {
-		if (daemon (0, 0) < 0) {
-			errsv = errno;
-			fprintf (stderr, _("Could not daemonize: %s [error %u]\n"),
-			         nm_strerror_native (errsv),
-			         errsv);
-			exit (1);
-		}
-		wrote_pidfile = nm_main_utils_write_pidfile (global_opt.pidfile);
-	}
-
-	/* Set up unix signal handling - before creating threads, but after daemonizing! */
-	nm_main_utils_setup_signals (main_loop);
-
-	{
-		gs_free char *v = NULL;
-
-		v = nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG,
-		                              NM_CONFIG_KEYFILE_GROUP_LOGGING,
-		                              NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND,
-		                              NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
-		nm_logging_init (v, nm_config_get_is_debug (config));
-	}
-
-	nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting... (%s)",
-	             nm_config_get_first_start (config) ? "for the first time" : "after a restart");
-
-	nm_log_info (LOGD_CORE, "Read config: %s", nm_config_data_get_config_description (nm_config_get_data (config)));
-	nm_config_data_log (nm_config_get_data (config), "CONFIG: ", "  ", nm_config_get_no_auto_default_file (config), NULL);
-
-	if (error_invalid_logging_config) {
-		nm_log_warn (LOGD_CORE, "config: invalid logging configuration: %s", error_invalid_logging_config->message);
-		g_clear_error (&error_invalid_logging_config);
-	}
-	if (bad_domains) {
-		nm_log_warn (LOGD_CORE, "config: invalid logging domains '%s' from %s",
-		             bad_domains,
-		             (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL)
-		               ? "config file"
-		               : "command line");
-		nm_clear_g_free (&bad_domains);
-	}
-
-	warnings = nm_config_get_warnings (config);
-	for ( ; warnings && *warnings; warnings++)
-		nm_log_warn (LOGD_CORE, "config: %s", *warnings);
-	nm_config_clear_warnings (config);
-
-	/* the first access to State causes the file to be read (and possibly print a warning) */
-	nm_config_state_get (config);
-
-	nm_log_dbg (LOGD_CORE, "WEXT support is %s",
+    gboolean      success = FALSE;
+    NMManager *   manager = NULL;
+    NMConfig *    config;
+    gs_free_error GError *  error         = NULL;
+    gboolean                wrote_pidfile = FALSE;
+    char *                  bad_domains   = NULL;
+    NMConfigCmdLineOptions *config_cli;
+    guint                   sd_id                        = 0;
+    GError *                error_invalid_logging_config = NULL;
+    const char *const *     warnings;
+    int                     errsv;
+
+    /* Known to cause a possible deadlock upon GDBus initialization:
+     * https://bugzilla.gnome.org/show_bug.cgi?id=674885 */
+    g_type_ensure(G_TYPE_SOCKET);
+    g_type_ensure(G_TYPE_DBUS_CONNECTION);
+    g_type_ensure(NM_TYPE_DBUS_MANAGER);
+
+    _nm_utils_is_manager_process = TRUE;
+
+    main_loop = g_main_loop_new(NULL, FALSE);
+
+    /* we determine a first-start (contrary to a restart during the same boot)
+     * based on the existence of NM_CONFIG_DEVICE_STATE_DIR directory. */
+    config_cli = nm_config_cmd_line_options_new(
+        !g_file_test(NM_CONFIG_DEVICE_STATE_DIR, G_FILE_TEST_IS_DIR));
+
+    do_early_setup(&argc, &argv, config_cli);
+
+    if (global_opt.g_fatal_warnings)
+        _set_g_fatal_warnings();
+
+    if (global_opt.show_version) {
+        fprintf(stdout, NM_DIST_VERSION "\n");
+        exit(0);
+    }
+
+    if (global_opt.print_config) {
+        int result;
+
+        result = print_config(config_cli);
+        nm_config_cmd_line_options_free(config_cli);
+        exit(result);
+    }
+
+    nm_main_utils_ensure_root();
+
+    nm_main_utils_ensure_not_running_pidfile(global_opt.pidfile);
+
+    nm_main_utils_ensure_statedir();
+    nm_main_utils_ensure_rundir();
+
+    /* When running from the build directory, determine our build directory
+     * base and set helper paths in the build tree */
+    if (global_opt.run_from_build_dir) {
+        char *path, *slash;
+        int   g;
+
+        /* exe is <basedir>/src/.libs/lt-NetworkManager, so chop off
+         * the last three components */
+        path = realpath("/proc/self/exe", NULL);
+        g_assert(path != NULL);
+        for (g = 0; g < 3; ++g) {
+            slash = strrchr(path, '/');
+            g_assert(slash != NULL);
+            *slash = '\0';
+        }
+
+        /* don't free these strings, we need them for the entire
+         * process lifetime */
+        nm_dhcp_helper_path = g_strdup_printf("%s/src/dhcp/nm-dhcp-helper", path);
+
+        g_free(path);
+    }
+
+    if (!nm_logging_setup(global_opt.opt_log_level,
+                          global_opt.opt_log_domains,
+                          &bad_domains,
+                          &error)) {
+        fprintf(stderr,
+                _("%s.  Please use --help to see a list of valid options.\n"),
+                error->message);
+        exit(1);
+    }
+
+    /* Read the config file and CLI overrides */
+    config = nm_config_setup(config_cli, CONFIG_ATOMIC_SECTION_PREFIXES, &error);
+    nm_config_cmd_line_options_free(config_cli);
+    config_cli = NULL;
+    if (config == NULL) {
+        fprintf(stderr, _("Failed to read configuration: %s\n"), error->message);
+        exit(1);
+    }
+
+    _init_nm_debug(config);
+
+    /* Initialize logging from config file *only* if not explicitly
+     * specified by commandline.
+     */
+    if (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL) {
+        if (!nm_logging_setup(nm_config_get_log_level(config),
+                              nm_config_get_log_domains(config),
+                              &bad_domains,
+                              &error_invalid_logging_config)) {
+            /* ignore error, and print the failure reason below.
+             * Likewise, print about bad_domains below. */
+        }
+    }
+
+    if (global_opt.become_daemon && !nm_config_get_is_debug(config)) {
+        if (daemon(0, 0) < 0) {
+            errsv = errno;
+            fprintf(stderr,
+                    _("Could not daemonize: %s [error %u]\n"),
+                    nm_strerror_native(errsv),
+                    errsv);
+            exit(1);
+        }
+        wrote_pidfile = nm_main_utils_write_pidfile(global_opt.pidfile);
+    }
+
+    /* Set up unix signal handling - before creating threads, but after daemonizing! */
+    nm_main_utils_setup_signals(main_loop);
+
+    {
+        gs_free char *v = NULL;
+
+        v = nm_config_data_get_value(NM_CONFIG_GET_DATA_ORIG,
+                                     NM_CONFIG_KEYFILE_GROUP_LOGGING,
+                                     NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND,
+                                     NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
+        nm_logging_init(v, nm_config_get_is_debug(config));
+    }
+
+    nm_log_info(LOGD_CORE,
+                "NetworkManager (version " NM_DIST_VERSION ") is starting... (%s)",
+                nm_config_get_first_start(config) ? "for the first time" : "after a restart");
+
+    nm_log_info(LOGD_CORE,
+                "Read config: %s",
+                nm_config_data_get_config_description(nm_config_get_data(config)));
+    nm_config_data_log(nm_config_get_data(config),
+                       "CONFIG: ",
+                       "  ",
+                       nm_config_get_no_auto_default_file(config),
+                       NULL);
+
+    if (error_invalid_logging_config) {
+        nm_log_warn(LOGD_CORE,
+                    "config: invalid logging configuration: %s",
+                    error_invalid_logging_config->message);
+        g_clear_error(&error_invalid_logging_config);
+    }
+    if (bad_domains) {
+        nm_log_warn(LOGD_CORE,
+                    "config: invalid logging domains '%s' from %s",
+                    bad_domains,
+                    (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL)
+                        ? "config file"
+                        : "command line");
+        nm_clear_g_free(&bad_domains);
+    }
+
+    warnings = nm_config_get_warnings(config);
+    for (; warnings && *warnings; warnings++)
+        nm_log_warn(LOGD_CORE, "config: %s", *warnings);
+    nm_config_clear_warnings(config);
+
+    /* the first access to State causes the file to be read (and possibly print a warning) */
+    nm_config_state_get(config);
+
+    nm_log_dbg(LOGD_CORE,
+               "WEXT support is %s",
 #if HAVE_WEXT
-	             "enabled"
+               "enabled"
 #else
-	             "disabled"
+               "disabled"
 #endif
-	             );
+    );
 
-	if (!_dbus_manager_init (config))
-		goto done_no_manager;
+    if (!_dbus_manager_init(config))
+        goto done_no_manager;
 
-	nm_linux_platform_setup ();
+    nm_linux_platform_setup();
 
-	NM_UTILS_KEEP_ALIVE (config, nm_netns_get (), "NMConfig-depends-on-NMNetns");
+    NM_UTILS_KEEP_ALIVE(config, nm_netns_get(), "NMConfig-depends-on-NMNetns");
 
-	nm_auth_manager_setup (nm_config_data_get_main_auth_polkit (nm_config_get_data_orig (config)));
+    nm_auth_manager_setup(nm_config_data_get_main_auth_polkit(nm_config_get_data_orig(config)));
 
-	manager = nm_manager_setup ();
+    manager = nm_manager_setup();
 
-	nm_dbus_manager_start (nm_dbus_manager_get(),
-	                       nm_manager_dbus_set_property_handle,
-	                       manager);
+    nm_dbus_manager_start(nm_dbus_manager_get(), nm_manager_dbus_set_property_handle, manager);
 
-	g_signal_connect (manager, NM_MANAGER_CONFIGURE_QUIT, G_CALLBACK (manager_configure_quit), config);
+    g_signal_connect(manager,
+                     NM_MANAGER_CONFIGURE_QUIT,
+                     G_CALLBACK(manager_configure_quit),
+                     config);
 
-	if (!nm_manager_start (manager, &error)) {
-		nm_log_err (LOGD_CORE, "failed to initialize: %s", error->message);
-		goto done;
-	}
+    if (!nm_manager_start(manager, &error)) {
+        nm_log_err(LOGD_CORE, "failed to initialize: %s", error->message);
+        goto done;
+    }
 
-	nm_platform_process_events (NM_PLATFORM_GET);
+    nm_platform_process_events(NM_PLATFORM_GET);
 
-	/* Make sure the loopback interface is up. If interface is down, we bring
-	 * it up and kernel will assign it link-local IPv4 and IPv6 addresses. If
-	 * it was already up, we assume is in clean state.
-	 *
-	 * TODO: it might be desirable to check the list of addresses and compare
-	 * it with a list of expected addresses (one of the protocol families
-	 * could be disabled). The 'lo' interface is sometimes used for assigning
-	 * global addresses so their availability doesn't depend on the state of
-	 * physical interfaces.
-	 */
-	nm_log_dbg (LOGD_CORE, "setting up local loopback");
-	nm_platform_link_set_up (NM_PLATFORM_GET, 1, NULL);
+    /* Make sure the loopback interface is up. If interface is down, we bring
+     * it up and kernel will assign it link-local IPv4 and IPv6 addresses. If
+     * it was already up, we assume is in clean state.
+     *
+     * TODO: it might be desirable to check the list of addresses and compare
+     * it with a list of expected addresses (one of the protocol families
+     * could be disabled). The 'lo' interface is sometimes used for assigning
+     * global addresses so their availability doesn't depend on the state of
+     * physical interfaces.
+     */
+    nm_log_dbg(LOGD_CORE, "setting up local loopback");
+    nm_platform_link_set_up(NM_PLATFORM_GET, 1, NULL);
 
-	success = TRUE;
+    success = TRUE;
 
-	if (configure_and_quit == FALSE) {
-		sd_id = nm_sd_event_attach_default ();
+    if (configure_and_quit == FALSE) {
+        sd_id = nm_sd_event_attach_default();
 
-		g_main_loop_run (main_loop);
-	}
+        g_main_loop_run(main_loop);
+    }
 
 done:
 
-	/* write the device-state to file. Note that we only persist the
-	 * state here. We don't bother updating the state as devices
-	 * change during regular operation. If NM is killed with SIGKILL,
-	 * it misses to update the state. */
-	nm_manager_write_device_state_all (manager);
+    /* write the device-state to file. Note that we only persist the
+     * state here. We don't bother updating the state as devices
+     * change during regular operation. If NM is killed with SIGKILL,
+     * it misses to update the state. */
+    nm_manager_write_device_state_all(manager);
 
-	nm_manager_stop (manager);
+    nm_manager_stop(manager);
 
-	nm_config_state_set (config, TRUE, TRUE);
+    nm_config_state_set(config, TRUE, TRUE);
 
-	nm_dns_manager_stop (nm_dns_manager_get ());
+    nm_dns_manager_stop(nm_dns_manager_get());
 
-	nm_settings_kf_db_write (NM_SETTINGS_GET);
+    nm_settings_kf_db_write(NM_SETTINGS_GET);
 
 done_no_manager:
-	if (global_opt.pidfile && wrote_pidfile)
-		unlink (global_opt.pidfile);
+    if (global_opt.pidfile && wrote_pidfile)
+        unlink(global_opt.pidfile);
 
-	nm_log_info (LOGD_CORE, "exiting (%s)", success ? "success" : "error");
+    nm_log_info(LOGD_CORE, "exiting (%s)", success ? "success" : "error");
 
-	nm_clear_g_source (&sd_id);
+    nm_clear_g_source(&sd_id);
 
-	exit (success ? 0 : 1);
+    exit(success ? 0 : 1);
 }