summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-03-20 11:43:40 +0100
committerThomas Haller <thaller@redhat.com>2015-03-20 11:45:11 +0100
commit6ce7b7df96e5a53b4e43a687dfedd8ae8a383fa0 (patch)
tree6f96429869e93a9525525d2676059a2a64f93403
parentb8a2f42a38219b4e1f9c87a78f68d5551e1d6c08 (diff)
parent21562052ec6d5a044003d222bf5b12da4475f9d2 (diff)
downloadNetworkManager-6ce7b7df96e5a53b4e43a687dfedd8ae8a383fa0.tar.gz
core: merge branch 'th/main-order-bgo746254'
Some refactoring of the main() functions for NetworkManager and nm-iface-helper. Most notably, start the D-Bus service earlier so that NetworkManager starts faster. https://bugzilla.gnome.org/show_bug.cgi?id=746254
-rw-r--r--src/main-utils.c93
-rw-r--r--src/main-utils.h8
-rw-r--r--src/main.c218
-rw-r--r--src/nm-iface-helper.c254
4 files changed, 321 insertions, 252 deletions
diff --git a/src/main-utils.c b/src/main-utils.c
index 164dc84a99..1d899587ec 100644
--- a/src/main-utils.c
+++ b/src/main-utils.c
@@ -34,7 +34,9 @@
#include <glib-unix.h>
#include <gmodule.h>
+#include "gsystem-local-alloc.h"
#include "main-utils.h"
+#include "NetworkManagerUtils.h"
#include "nm-logging.h"
static gboolean
@@ -108,72 +110,82 @@ nm_main_utils_write_pidfile (const char *pidfile)
return success;
}
+void
+nm_main_utils_ensure_rundir ()
+{
+ /* Setup runtime directory */
+ if (g_mkdir_with_parents (NMRUNDIR, 0755) != 0) {
+ fprintf (stderr, _("Cannot create '%s': %s"), NMRUNDIR, strerror (errno));
+ exit (1);
+ }
+}
+
/**
- * nm_main_utils_check_pidfile:
+ * nm_main_utils_ensure_not_running_pidfile:
* @pidfile: the pid file
- * @name: the process name
*
* Checks whether the pidfile already exists and contains PID of a running
* process.
*
- * Returns: %TRUE if the specified pidfile already exists and contains the PID
- * of a running process named @name, or %FALSE if not
+ * Exits with code 1 if a conflicting process is running.
*/
-gboolean
-nm_main_utils_check_pidfile (const char *pidfile, const char *name)
+void
+nm_main_utils_ensure_not_running_pidfile (const char *pidfile)
{
- char *contents = NULL;
+ gs_free char *contents = NULL;
+ gs_free char *proc_cmdline = NULL;
gsize len = 0;
glong pid;
- char *proc_cmdline = NULL;
- gboolean nm_running = FALSE;
const char *process_name;
+ const char *prgname = g_get_prgname ();
- /* Setup runtime directory */
- if (g_mkdir_with_parents (NMRUNDIR, 0755) != 0) {
- nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMRUNDIR, strerror (errno));
- exit (1);
- }
+ g_return_if_fail (prgname);
- if (!g_file_get_contents (pidfile, &contents, &len, NULL))
- return FALSE;
+ if (!pidfile || !*pidfile)
+ return;
+ if (!g_file_get_contents (pidfile, &contents, &len, NULL))
+ return;
if (len <= 0)
- goto done;
+ return;
errno = 0;
pid = strtol (contents, NULL, 10);
if (pid <= 0 || pid > 65536 || errno)
- goto done;
+ return;
- g_free (contents);
+ g_clear_pointer (&contents, g_free);
proc_cmdline = g_strdup_printf ("/proc/%ld/cmdline", pid);
if (!g_file_get_contents (proc_cmdline, &contents, &len, NULL))
- goto done;
+ return;
process_name = strrchr (contents, '/');
if (process_name)
process_name++;
else
process_name = contents;
- if (strcmp (process_name, name) == 0) {
+ if (strcmp (process_name, prgname) == 0) {
/* Check that the process exists */
if (kill (pid, 0) == 0) {
- fprintf (stderr, _("%s is already running (pid %ld)\n"), name, pid);
- nm_running = TRUE;
+ fprintf (stderr, _("%s is already running (pid %ld)\n"), prgname, pid);
+ exit (1);
}
}
+}
-done:
- g_free (proc_cmdline);
- g_free (contents);
- return nm_running;
+void
+nm_main_utils_ensure_root ()
+{
+ if (getuid () != 0) {
+ fprintf (stderr, _("You must be root to run %s!\n"), str_if_set (g_get_prgname (), ""));
+ exit (1);
+ }
}
gboolean
nm_main_utils_early_setup (const char *progname,
- char **argv[],
int *argc,
+ char **argv[],
GOptionEntry *options,
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
gpointer option_context_hook_data,
@@ -183,6 +195,8 @@ nm_main_utils_early_setup (const char *progname,
GError *error = NULL;
gboolean success = FALSE;
int i;
+ const char *opt_fmt_log_level = NULL, *opt_fmt_log_domains = NULL;
+ const char **opt_loc_log_level = NULL, **opt_loc_log_domains = NULL;
/* Make GIO ignore the remote VFS service; otherwise it tries to use the
* session bus to contact the remote service, and NM shouldn't ever be
@@ -201,16 +215,16 @@ nm_main_utils_early_setup (const char *progname,
setlocale (LC_ALL, "");
textdomain (GETTEXT_PACKAGE);
- if (getuid () != 0) {
- fprintf (stderr, _("You must be root to run %s!\n"), progname);
- exit (1);
- }
-
for (i = 0; options[i].long_name; i++) {
- if (!strcmp (options[i].long_name, "log-level"))
+ if (!strcmp (options[i].long_name, "log-level")) {
+ opt_fmt_log_level = options[i].description;
+ opt_loc_log_level = &options[i].description;
options[i].description = g_strdup_printf (options[i].description, nm_logging_all_levels_to_string ());
- else if (!strcmp (options[i].long_name, "log-domains"))
+ } else if (!strcmp (options[i].long_name, "log-domains")) {
+ opt_fmt_log_domains = options[i].description;
+ opt_loc_log_domains = &options[i].description;
options[i].description = g_strdup_printf (options[i].description, nm_logging_all_domains_to_string ());
+ }
}
/* Parse options */
@@ -231,6 +245,15 @@ nm_main_utils_early_setup (const char *progname,
}
g_option_context_free (opt_ctx);
+ if (opt_loc_log_level) {
+ g_free ((char *) *opt_loc_log_level);
+ *opt_loc_log_level = opt_fmt_log_level;
+ }
+ if (opt_loc_log_domains) {
+ g_free ((char *) *opt_loc_log_domains);
+ *opt_loc_log_domains = opt_fmt_log_domains;
+ }
+
return success;
}
diff --git a/src/main-utils.h b/src/main-utils.h
index 9b29866be0..7adfa94940 100644
--- a/src/main-utils.h
+++ b/src/main-utils.h
@@ -23,15 +23,19 @@
#include <glib.h>
+void nm_main_utils_ensure_root (void);
+
void nm_main_utils_setup_signals (GMainLoop *main_loop);
+void nm_main_utils_ensure_rundir (void);
+
gboolean nm_main_utils_write_pidfile (const char *pidfile);
-gboolean nm_main_utils_check_pidfile (const char *pidfile, const char *name);
+void nm_main_utils_ensure_not_running_pidfile (const char *pidfile);
gboolean nm_main_utils_early_setup (const char *progname,
- char **argv[],
int *argc,
+ char **argv[],
GOptionEntry *options,
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
gpointer option_context_hook_data,
diff --git a/src/main.c b/src/main.c
index 3df3e11eb4..2648a08f41 100644
--- a/src/main.c
+++ b/src/main.c
@@ -67,6 +67,20 @@
static GMainLoop *main_loop = NULL;
static gboolean configure_and_quit = FALSE;
+static struct {
+ gboolean show_version;
+ gboolean become_daemon;
+ gboolean debug;
+ gboolean g_fatal_warnings;
+ gboolean run_from_build_dir;
+ char *opt_log_level;
+ char *opt_log_domains;
+ char *pidfile;
+ char *state_file;
+} global_opt = {
+ .become_daemon = TRUE,
+};
+
static gboolean
parse_state_file (const char *filename,
gboolean *net_enabled,
@@ -197,6 +211,37 @@ manager_configure_quit (NMManager *manager, gpointer user_data)
configure_and_quit = TRUE;
}
+static void
+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 },
+ { "debug", 'd', 0, G_OPTION_ARG_NONE, &global_opt.debug, N_("Don't become a daemon, and log to stderr"), 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"), N_("filename") },
+ { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &global_opt.state_file, N_("State file location"), N_("/path/to/state.file") },
+ { "run-from-build-dir", 0, 0, G_OPTION_ARG_NONE, &global_opt.run_from_build_dir, "Run from build directory", 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 ? global_opt.pidfile : g_strdup (NM_DEFAULT_PID_FILE);
+ global_opt.state_file = global_opt.state_file ? global_opt.state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE);
+}
+
/*
* main
*
@@ -204,75 +249,55 @@ manager_configure_quit (NMManager *manager, gpointer user_data)
int
main (int argc, char *argv[])
{
- char *opt_log_level = NULL;
- char *opt_log_domains = NULL;
- gboolean become_daemon = TRUE, run_from_build_dir = FALSE;
- gboolean debug = FALSE;
- gboolean g_fatal_warnings = FALSE;
- gs_free char *pidfile = NULL;
- gs_free char *state_file = NULL;
gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE;
- gboolean success, show_version = FALSE;
+ gboolean success = FALSE;
NMManager *manager = NULL;
gs_unref_object NMSettings *settings = NULL;
- gs_unref_object NMConfig *config = NULL;
+ NMConfig *config;
GError *error = NULL;
gboolean wrote_pidfile = FALSE;
char *bad_domains = NULL;
NMConfigCmdLineOptions *config_cli;
- GOptionEntry options[] = {
- { "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL },
- { "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &become_daemon, N_("Don't become a daemon"), NULL },
- { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, N_("Don't become a daemon, and log to stderr"), NULL },
- { "log-level", 0, 0, G_OPTION_ARG_STRING, &opt_log_level, N_("Log level: one of [%s]"), "INFO" },
- { "log-domains", 0, 0, G_OPTION_ARG_STRING, &opt_log_domains,
- N_("Log domains separated by ',': any combination of [%s]"),
- "PLATFORM,RFKILL,WIFI" },
- { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, N_("Make all warnings fatal"), NULL },
- { "pid-file", 'p', 0, G_OPTION_ARG_FILENAME, &pidfile, N_("Specify the location of a PID file"), N_("filename") },
- { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &state_file, N_("State file location"), N_("/path/to/state.file") },
- { "run-from-build-dir", 0, 0, G_OPTION_ARG_NONE, &run_from_build_dir, "Run from build directory", NULL },
- {NULL}
- };
+#if !GLIB_CHECK_VERSION (2, 35, 0)
+ g_type_init ();
+#endif
_nm_utils_is_manager_process = TRUE;
main_loop = g_main_loop_new (NULL, FALSE);
config_cli = nm_config_cmd_line_options_new ();
- if (!nm_main_utils_early_setup ("NetworkManager",
- &argv,
- &argc,
- 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);
+ do_early_setup (&argc, &argv, config_cli);
- if (show_version) {
+ if (global_opt.g_fatal_warnings) {
+ 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);
+ }
+
+ if (global_opt.show_version) {
fprintf (stdout, NM_DIST_VERSION "\n");
exit (0);
}
- if (!nm_logging_setup (opt_log_level,
- opt_log_domains,
- &bad_domains,
- &error)) {
- fprintf (stderr,
- _("%s. Please use --help to see a list of valid options.\n"),
- error->message);
+ nm_main_utils_ensure_root ();
+
+ nm_main_utils_ensure_not_running_pidfile (global_opt.pidfile);
+
+ /* Ensure state directory exists */
+ if (g_mkdir_with_parents (NMSTATEDIR, 0755) != 0) {
+ fprintf (stderr, "Cannot create '%s': %s", NMSTATEDIR, strerror (errno));
exit (1);
- } else if (bad_domains) {
- fprintf (stderr,
- _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"),
- bad_domains);
- g_clear_pointer (&bad_domains, g_free);
}
+ 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 (run_from_build_dir) {
+ if (global_opt.run_from_build_dir) {
char *path, *slash;
int g;
@@ -294,19 +319,21 @@ main (int argc, char *argv[])
g_free (path);
}
- /* Ensure state directory exists */
- if (g_mkdir_with_parents (NMSTATEDIR, 0755) != 0) {
- nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMSTATEDIR, strerror (errno));
+ 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);
+ } else if (bad_domains) {
+ fprintf (stderr,
+ _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"),
+ bad_domains);
+ g_clear_pointer (&bad_domains, g_free);
}
- pidfile = pidfile ? pidfile : g_strdup (NM_DEFAULT_PID_FILE);
- state_file = state_file ? state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE);
-
- /* check pid file */
- if (nm_main_utils_check_pidfile (pidfile, "NetworkManager"))
- exit (1);
-
/* Read the config file and CLI overrides */
config = nm_config_setup (config_cli, &error);
nm_config_cmd_line_options_free (config_cli);
@@ -318,10 +345,12 @@ main (int argc, char *argv[])
exit (1);
}
+ _init_nm_debug (nm_config_get_debug (config));
+
/* Initialize logging from config file *only* if not explicitly
* specified by commandline.
*/
- if (opt_log_level == NULL && opt_log_domains == NULL) {
+ 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,
@@ -337,17 +366,7 @@ main (int argc, char *argv[])
}
}
- /* Parse the state file */
- if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) {
- fprintf (stderr, _("State file %s parsing failed: (%d) %s\n"),
- state_file,
- error ? error->code : -1,
- (error && error->message) ? error->message : _("unknown"));
- /* Not a hard failure */
- }
- g_clear_error (&error);
-
- if (become_daemon && !debug) {
+ if (global_opt.become_daemon && !global_opt.debug) {
if (daemon (0, 0) < 0) {
int saved_errno;
@@ -357,27 +376,25 @@ main (int argc, char *argv[])
saved_errno);
exit (1);
}
- wrote_pidfile = nm_main_utils_write_pidfile (pidfile);
+ wrote_pidfile = nm_main_utils_write_pidfile (global_opt.pidfile);
}
- _init_nm_debug (nm_config_get_debug (config));
-
/* Set up unix signal handling - before creating threads, but after daemonizing! */
nm_main_utils_setup_signals (main_loop);
- if (g_fatal_warnings) {
- 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);
- }
+ nm_logging_syslog_openlog (global_opt.debug);
- nm_logging_syslog_openlog (debug);
+ nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting...");
-#if !GLIB_CHECK_VERSION (2, 35, 0)
- g_type_init ();
-#endif
+ /* Parse the state file */
+ if (!parse_state_file (global_opt.state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) {
+ nm_log_err (LOGD_CORE, "State file %s parsing failed: (%d) %s",
+ global_opt.state_file,
+ error ? error->code : -1,
+ (error && error->message) ? error->message : _("unknown"));
+ /* Not a hard failure */
+ }
+ g_clear_error (&error);
dbus_threads_init_default ();
@@ -386,9 +403,6 @@ main (int argc, char *argv[])
*/
dbus_glib_global_set_disable_legacy_property_access ();
- nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting...");
- success = FALSE;
-
nm_log_info (LOGD_CORE, "Read config: %s", nm_config_data_get_config_description (nm_config_get_data (config)));
nm_log_info (LOGD_CORE, "WEXT support is %s",
#if HAVE_WEXT
@@ -398,6 +412,21 @@ main (int argc, char *argv[])
#endif
);
+ if (!nm_dbus_manager_get_connection (nm_dbus_manager_get ())) {
+#if HAVE_DBUS_GLIB_100
+ nm_log_warn (LOGD_CORE, "Failed to connect to D-Bus; only private bus is available");
+#else
+ nm_log_err (LOGD_CORE, "Failed to connect to D-Bus, exiting...");
+ goto done;
+#endif
+ } else {
+ /* Start our DBus service */
+ if (!nm_dbus_manager_start_service (nm_dbus_manager_get ())) {
+ nm_log_err (LOGD_CORE, "failed to start the dbus service.");
+ goto done;
+ }
+ }
+
/* Set up platform interaction layer */
nm_linux_platform_setup ();
@@ -413,7 +442,7 @@ main (int argc, char *argv[])
}
manager = nm_manager_new (settings,
- state_file,
+ global_opt.state_file,
net_enabled,
wifi_enabled,
wwan_enabled,
@@ -425,21 +454,6 @@ main (int argc, char *argv[])
goto done;
}
- if (!nm_dbus_manager_get_connection (nm_dbus_manager_get ())) {
-#if HAVE_DBUS_GLIB_100
- nm_log_warn (LOGD_CORE, "Failed to connect to D-Bus; only private bus is available");
-#else
- nm_log_err (LOGD_CORE, "Failed to connect to D-Bus, exiting...");
- goto done;
-#endif
- } else {
- /* Start our DBus service */
- if (!nm_dbus_manager_start_service (nm_dbus_manager_get ())) {
- nm_log_err (LOGD_CORE, "failed to start the dbus service.");
- goto done;
- }
- }
-
g_signal_connect (manager, NM_MANAGER_CONFIGURE_QUIT, G_CALLBACK (manager_configure_quit), config);
nm_manager_start (manager);
@@ -469,8 +483,8 @@ done:
nm_logging_syslog_closelog ();
- if (pidfile && wrote_pidfile)
- unlink (pidfile);
+ if (global_opt.pidfile && wrote_pidfile)
+ unlink (global_opt.pidfile);
nm_log_info (LOGD_CORE, "exiting (%s)", success ? "success" : "error");
exit (success ? 0 : 1);
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index 49eda87718..95fffa7a02 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -34,6 +34,10 @@
#include <sys/stat.h>
#include <signal.h>
+/* Cannot include <net/if.h> due to conflict with <linux/if.h>.
+ * Forward declare if_nametoindex. */
+extern unsigned int if_nametoindex (const char *__ifname);
+
#include "gsystem-local-alloc.h"
#include "NetworkManagerUtils.h"
#include "nm-linux-platform.h"
@@ -51,13 +55,32 @@
#define NMIH_PID_FILE_FMT NMRUNDIR "/nm-iface-helper-%d.pid"
static GMainLoop *main_loop = NULL;
-static char *ifname = NULL;
static int ifindex = -1;
-static gboolean slaac_required = FALSE;
-static gboolean dhcp4_required = FALSE;
-static int tempaddr = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
-static guint32 priority_v4 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4;
-static guint32 priority_v6 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6;
+
+static struct {
+ gboolean slaac;
+ gboolean show_version;
+ gboolean become_daemon;
+ gboolean debug;
+ gboolean g_fatal_warnings;
+ gboolean slaac_required;
+ gboolean dhcp4_required;
+ int tempaddr;
+ char *ifname;
+ char *uuid;
+ char *dhcp4_address;
+ char *dhcp4_clientid;
+ char *dhcp4_hostname;
+ char *iid_str;
+ char *opt_log_level;
+ char *opt_log_domains;
+ guint32 priority_v4;
+ guint32 priority_v6;
+} global_opt = {
+ .tempaddr = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
+ .priority_v4 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4,
+ .priority_v6 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6,
+};
static void
dhcp4_state_changed (NMDhcpClient *client,
@@ -71,7 +94,7 @@ dhcp4_state_changed (NMDhcpClient *client,
g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config));
- nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d", ifname, state);
+ nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d", global_opt.ifname, state);
switch (state) {
case NM_DHCP_STATE_BOUND:
@@ -81,8 +104,8 @@ dhcp4_state_changed (NMDhcpClient *client,
nm_ip4_config_subtract (existing, last_config);
nm_ip4_config_merge (existing, ip4_config);
- if (!nm_ip4_config_commit (existing, ifindex, priority_v4))
- nm_log_warn (LOGD_DHCP4, "(%s): failed to apply DHCPv4 config", ifname);
+ if (!nm_ip4_config_commit (existing, ifindex, global_opt.priority_v4))
+ nm_log_warn (LOGD_DHCP4, "(%s): failed to apply DHCPv4 config", global_opt.ifname);
if (last_config) {
g_object_unref (last_config);
@@ -93,11 +116,11 @@ dhcp4_state_changed (NMDhcpClient *client,
case NM_DHCP_STATE_TIMEOUT:
case NM_DHCP_STATE_DONE:
case NM_DHCP_STATE_FAIL:
- if (dhcp4_required) {
- nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed, quitting...", ifname);
+ if (global_opt.dhcp4_required) {
+ nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed, quitting...", global_opt.ifname);
g_main_loop_quit (main_loop);
} else
- nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed", ifname);
+ nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed", global_opt.ifname);
break;
default:
break;
@@ -128,8 +151,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
if (system_support)
ifa_flags = IFA_F_NOPREFIXROUTE;
- if (tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR
- || tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)
+ if (global_opt.tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR
+ || global_opt.tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)
{
/* without system_support, this flag will be ignored. Still set it, doesn't seem to do any harm. */
ifa_flags |= IFA_F_MANAGETEMPADDR;
@@ -193,7 +216,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
route.plen = discovered_route->plen;
route.gateway = discovered_route->gateway;
route.source = NM_IP_CONFIG_SOURCE_RDISC;
- route.metric = priority_v6;
+ route.metric = global_opt.priority_v6;
nm_ip6_config_add_route (ip6_config, &route);
}
@@ -210,23 +233,23 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
char val[16];
g_snprintf (val, sizeof (val), "%d", rdisc->hop_limit);
- nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "hop_limit"), val);
+ nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "hop_limit"), val);
}
if (changed & NM_RDISC_CONFIG_MTU) {
char val[16];
g_snprintf (val, sizeof (val), "%d", rdisc->mtu);
- nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "mtu"), val);
+ nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "mtu"), val);
}
- existing = nm_ip6_config_capture (ifindex, FALSE, tempaddr);
+ existing = nm_ip6_config_capture (ifindex, FALSE, global_opt.tempaddr);
if (last_config)
nm_ip6_config_subtract (existing, last_config);
nm_ip6_config_merge (existing, ip6_config);
if (!nm_ip6_config_commit (existing, ifindex))
- nm_log_warn (LOGD_IP6, "(%s): failed to apply IPv6 config", ifname);
+ nm_log_warn (LOGD_IP6, "(%s): failed to apply IPv6 config", global_opt.ifname);
if (last_config) {
g_object_unref (last_config);
@@ -238,11 +261,11 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
static void
rdisc_ra_timeout (NMRDisc *rdisc, gpointer user_data)
{
- if (slaac_required) {
- nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed, quitting...", ifname);
+ if (global_opt.slaac_required) {
+ nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed, quitting...", global_opt.ifname);
g_main_loop_quit (main_loop);
} else
- nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed", ifname);
+ nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed", global_opt.ifname);
}
static gboolean
@@ -260,77 +283,113 @@ setup_signals (void)
g_unix_signal_add (SIGTERM, quit_handler, NULL);
}
-int
-main (int argc, char *argv[])
+static void
+do_early_setup (int *argc, char **argv[])
{
- char *opt_log_level = NULL;
- char *opt_log_domains = NULL;
- gboolean debug = FALSE, g_fatal_warnings = FALSE, become_daemon = FALSE;
- gboolean show_version = FALSE, slaac = FALSE;
- char *bad_domains = NULL, *dhcp4_hostname = NULL, *uuid = NULL;
- char *iid_str = NULL, *dhcp4_clientid = NULL, *dhcp4_address = NULL;
- GError *error = NULL;
- gboolean wrote_pidfile = FALSE;
- gs_free char *pidfile = NULL;
- gs_unref_object NMDhcpClient *dhcp4_client = NULL;
- gs_unref_object NMRDisc *rdisc = NULL;
- GByteArray *hwaddr = NULL;
- size_t hwaddr_len = 0;
- gconstpointer tmp;
- gs_free NMUtilsIPv6IfaceId *iid = NULL;
gint64 priority64_v4 = -1;
gint64 priority64_v6 = -1;
-
GOptionEntry options[] = {
/* Interface/IP config */
- { "ifname", 'i', 0, G_OPTION_ARG_STRING, &ifname, N_("The interface to manage"), N_("eth0") },
- { "uuid", 'u', 0, G_OPTION_ARG_STRING, &uuid, N_("Connection UUID"), N_("661e8cd0-b618-46b8-9dc9-31a52baaa16b") },
- { "slaac", 's', 0, G_OPTION_ARG_NONE, &slaac, N_("Whether to manage IPv6 SLAAC"), NULL },
- { "slaac-required", '6', 0, G_OPTION_ARG_NONE, &slaac_required, N_("Whether SLAAC must be successful"), NULL },
- { "slaac-tempaddr", 't', 0, G_OPTION_ARG_INT, &tempaddr, N_("Use an IPv6 temporary privacy address"), NULL },
- { "dhcp4", 'd', 0, G_OPTION_ARG_STRING, &dhcp4_address, N_("Current DHCPv4 address"), NULL },
- { "dhcp4-required", '4', 0, G_OPTION_ARG_NONE, &dhcp4_required, N_("Whether DHCPv4 must be successful"), NULL },
- { "dhcp4-clientid", 'c', 0, G_OPTION_ARG_STRING, &dhcp4_clientid, N_("Hex-encoded DHCPv4 client ID"), NULL },
- { "dhcp4-hostname", 'h', 0, G_OPTION_ARG_STRING, &dhcp4_hostname, N_("Hostname to send to DHCP server"), N_("barbar") },
+ { "ifname", 'i', 0, G_OPTION_ARG_STRING, &global_opt.ifname, N_("The interface to manage"), N_("eth0") },
+ { "uuid", 'u', 0, G_OPTION_ARG_STRING, &global_opt.uuid, N_("Connection UUID"), N_("661e8cd0-b618-46b8-9dc9-31a52baaa16b") },
+ { "slaac", 's', 0, G_OPTION_ARG_NONE, &global_opt.slaac, N_("Whether to manage IPv6 SLAAC"), NULL },
+ { "slaac-required", '6', 0, G_OPTION_ARG_NONE, &global_opt.slaac_required, N_("Whether SLAAC must be successful"), NULL },
+ { "slaac-tempaddr", 't', 0, G_OPTION_ARG_INT, &global_opt.tempaddr, N_("Use an IPv6 temporary privacy address"), NULL },
+ { "dhcp4", 'd', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_address, N_("Current DHCPv4 address"), NULL },
+ { "dhcp4-required", '4', 0, G_OPTION_ARG_NONE, &global_opt.dhcp4_required, N_("Whether DHCPv4 must be successful"), NULL },
+ { "dhcp4-clientid", 'c', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_clientid, N_("Hex-encoded DHCPv4 client ID"), NULL },
+ { "dhcp4-hostname", 'h', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_hostname, N_("Hostname to send to DHCP server"), N_("barbar") },
{ "priority4", '\0', 0, G_OPTION_ARG_INT64, &priority64_v4, N_("Route priority for IPv4"), N_("0") },
{ "priority6", '\0', 0, G_OPTION_ARG_INT64, &priority64_v6, N_("Route priority for IPv6"), N_("1024") },
- { "iid", 'e', 0, G_OPTION_ARG_STRING, &iid_str, N_("Hex-encoded Interface Identifier"), N_("") },
+ { "iid", 'e', 0, G_OPTION_ARG_STRING, &global_opt.iid_str, N_("Hex-encoded Interface Identifier"), N_("") },
/* Logging/debugging */
- { "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL },
- { "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &become_daemon, N_("Don't become a daemon"), NULL },
- { "debug", 'b', 0, G_OPTION_ARG_NONE, &debug, N_("Don't become a daemon, and log to stderr"), NULL },
- { "log-level", 0, 0, G_OPTION_ARG_STRING, &opt_log_level, N_("Log level: one of [%s]"), "INFO" },
- { "log-domains", 0, 0, G_OPTION_ARG_STRING, &opt_log_domains,
+ { "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 },
+ { "debug", 'b', 0, G_OPTION_ARG_NONE, &global_opt.debug, N_("Don't become a daemon, and log to stderr"), 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, &g_fatal_warnings, N_("Make all warnings fatal"), NULL },
+ { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &global_opt.g_fatal_warnings, N_("Make all warnings fatal"), NULL },
{NULL}
};
+#if !GLIB_CHECK_VERSION (2, 35, 0)
+ g_type_init ();
+#endif
+
setpgid (getpid (), getpid ());
if (!nm_main_utils_early_setup ("nm-iface-helper",
- &argv,
- &argc,
+ argc,
+ argv,
options,
NULL,
NULL,
_("nm-iface-helper is a small, standalone process that manages a single network interface.")))
exit (1);
- if (show_version) {
+ if (priority64_v4 >= 0 && priority64_v4 <= G_MAXUINT32)
+ global_opt.priority_v4 = (guint32) priority64_v4;
+ if (priority64_v6 >= 0 && priority64_v6 <= G_MAXUINT32)
+ global_opt.priority_v6 = (guint32) priority64_v6;
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *bad_domains = NULL;
+ GError *error = NULL;
+ gboolean wrote_pidfile = FALSE;
+ gs_free char *pidfile = NULL;
+ gs_unref_object NMDhcpClient *dhcp4_client = NULL;
+ gs_unref_object NMRDisc *rdisc = NULL;
+ GByteArray *hwaddr = NULL;
+ size_t hwaddr_len = 0;
+ gconstpointer tmp;
+ gs_free NMUtilsIPv6IfaceId *iid = NULL;
+
+#if !GLIB_CHECK_VERSION (2, 35, 0)
+ g_type_init ();
+#endif
+
+ setpgid (getpid (), getpid ());
+
+ do_early_setup (&argc, &argv);
+
+ if (global_opt.g_fatal_warnings) {
+ 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);
+ }
+
+ if (global_opt.show_version) {
fprintf (stdout, NM_DIST_VERSION "\n");
exit (0);
}
- if (!ifname || !uuid) {
+ nm_main_utils_ensure_root ();
+
+ if (!global_opt.ifname || !global_opt.uuid) {
fprintf (stderr, _("An interface name and UUID are required\n"));
exit (1);
}
- if (!nm_logging_setup (opt_log_level,
- opt_log_domains,
+ ifindex = if_nametoindex (global_opt.ifname);
+ if (ifindex <= 0) {
+ fprintf (stderr, _("Failed to find interface index for %s (%s)\n"), global_opt.ifname, strerror (errno));
+ exit (1);
+ }
+ pidfile = g_strdup_printf (NMIH_PID_FILE_FMT, ifindex);
+ nm_main_utils_ensure_not_running_pidfile (pidfile);
+
+ nm_main_utils_ensure_rundir ();
+
+ if (!nm_logging_setup (global_opt.opt_log_level,
+ global_opt.opt_log_domains,
&bad_domains,
&error)) {
fprintf (stderr,
@@ -344,14 +403,7 @@ main (int argc, char *argv[])
g_clear_pointer (&bad_domains, g_free);
}
- pidfile = g_strdup_printf (NMIH_PID_FILE_FMT, ifindex);
- g_assert (pidfile);
-
- /* check pid file */
- if (nm_main_utils_check_pidfile (pidfile, "nm-iface-helper"))
- exit (1);
-
- if (become_daemon && !debug) {
+ if (global_opt.become_daemon && !global_opt.debug) {
if (daemon (0, 0) < 0) {
int saved_errno;
@@ -369,70 +421,46 @@ main (int argc, char *argv[])
main_loop = g_main_loop_new (NULL, FALSE);
setup_signals ();
- if (g_fatal_warnings) {
- 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);
- }
-
- nm_logging_syslog_openlog (debug);
-
-#if !GLIB_CHECK_VERSION (2, 35, 0)
- g_type_init ();
-#endif
+ nm_logging_syslog_openlog (global_opt.debug);
nm_log_info (LOGD_CORE, "nm-iface-helper (version " NM_DIST_VERSION ") is starting...");
/* Set up platform interaction layer */
nm_linux_platform_setup ();
- ifindex = nm_platform_link_get_ifindex (ifname);
- if (ifindex <= 0) {
- fprintf (stderr, _("Failed to find interface index for %s\n"), ifname);
- exit (1);
- }
-
tmp = nm_platform_link_get_address (ifindex, &hwaddr_len);
if (tmp) {
hwaddr = g_byte_array_sized_new (hwaddr_len);
g_byte_array_append (hwaddr, tmp, hwaddr_len);
}
- if (iid_str) {
+ if (global_opt.iid_str) {
GBytes *bytes;
gsize ignored = 0;
- bytes = nm_utils_hexstr2bin (iid_str);
+ bytes = nm_utils_hexstr2bin (global_opt.iid_str);
if (!bytes || g_bytes_get_size (bytes) != sizeof (*iid)) {
- fprintf (stderr, _("(%s): Invalid IID %s\n"), ifname, iid_str);
+ fprintf (stderr, _("(%s): Invalid IID %s\n"), global_opt.ifname, global_opt.iid_str);
exit (1);
}
iid = g_bytes_unref_to_data (bytes, &ignored);
}
- if (priority64_v4 >= 0 && priority64_v4 <= G_MAXUINT32)
- priority_v4 = (guint32) priority64_v4;
-
- if (priority64_v6 >= 0 && priority64_v6 <= G_MAXUINT32)
- priority_v6 = (guint32) priority64_v6;
-
- if (dhcp4_address) {
- nm_platform_sysctl_set (nm_utils_ip4_property_path (ifname, "promote_secondaries"), "1");
+ if (global_opt.dhcp4_address) {
+ nm_platform_sysctl_set (nm_utils_ip4_property_path (global_opt.ifname, "promote_secondaries"), "1");
dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
- ifname,
+ global_opt.ifname,
ifindex,
hwaddr,
- uuid,
- priority_v4,
- !!dhcp4_hostname,
- dhcp4_hostname,
- dhcp4_clientid,
+ global_opt.uuid,
+ global_opt.priority_v4,
+ !!global_opt.dhcp4_hostname,
+ global_opt.dhcp4_hostname,
+ global_opt.dhcp4_clientid,
45,
NULL,
- dhcp4_address);
+ global_opt.dhcp4_address);
g_assert (dhcp4_client);
g_signal_connect (dhcp4_client,
NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
@@ -440,19 +468,19 @@ main (int argc, char *argv[])
NULL);
}
- if (slaac) {
+ if (global_opt.slaac) {
nm_platform_link_set_user_ipv6ll_enabled (ifindex, TRUE);
- rdisc = nm_lndp_rdisc_new (ifindex, ifname);
+ rdisc = nm_lndp_rdisc_new (ifindex, global_opt.ifname);
g_assert (rdisc);
if (iid)
nm_rdisc_set_iid (rdisc, *iid);
- nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra"), "1");
- nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra_defrtr"), "0");
- nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra_pinfo"), "0");
- nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra_rtr_pref"), "0");
+ nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra"), "1");
+ nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_defrtr"), "0");
+ nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_pinfo"), "0");
+ nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_rtr_pref"), "0");
g_signal_connect (rdisc,
NM_RDISC_CONFIG_CHANGED,