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
This commit is contained in:
@@ -34,7 +34,9 @@
|
|||||||
#include <glib-unix.h>
|
#include <glib-unix.h>
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
|
|
||||||
|
#include "gsystem-local-alloc.h"
|
||||||
#include "main-utils.h"
|
#include "main-utils.h"
|
||||||
|
#include "NetworkManagerUtils.h"
|
||||||
#include "nm-logging.h"
|
#include "nm-logging.h"
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -108,72 +110,82 @@ nm_main_utils_write_pidfile (const char *pidfile)
|
|||||||
return success;
|
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
|
* @pidfile: the pid file
|
||||||
* @name: the process name
|
|
||||||
*
|
*
|
||||||
* Checks whether the pidfile already exists and contains PID of a running
|
* Checks whether the pidfile already exists and contains PID of a running
|
||||||
* process.
|
* process.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the specified pidfile already exists and contains the PID
|
* Exits with code 1 if a conflicting process is running.
|
||||||
* of a running process named @name, or %FALSE if not
|
|
||||||
*/
|
*/
|
||||||
gboolean
|
void
|
||||||
nm_main_utils_check_pidfile (const char *pidfile, const char *name)
|
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;
|
gsize len = 0;
|
||||||
glong pid;
|
glong pid;
|
||||||
char *proc_cmdline = NULL;
|
|
||||||
gboolean nm_running = FALSE;
|
|
||||||
const char *process_name;
|
const char *process_name;
|
||||||
|
const char *prgname = g_get_prgname ();
|
||||||
|
|
||||||
/* Setup runtime directory */
|
g_return_if_fail (prgname);
|
||||||
if (g_mkdir_with_parents (NMRUNDIR, 0755) != 0) {
|
|
||||||
nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMRUNDIR, strerror (errno));
|
if (!pidfile || !*pidfile)
|
||||||
exit (1);
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_file_get_contents (pidfile, &contents, &len, NULL))
|
if (!g_file_get_contents (pidfile, &contents, &len, NULL))
|
||||||
return FALSE;
|
return;
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
goto done;
|
return;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
pid = strtol (contents, NULL, 10);
|
pid = strtol (contents, NULL, 10);
|
||||||
if (pid <= 0 || pid > 65536 || errno)
|
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);
|
proc_cmdline = g_strdup_printf ("/proc/%ld/cmdline", pid);
|
||||||
if (!g_file_get_contents (proc_cmdline, &contents, &len, NULL))
|
if (!g_file_get_contents (proc_cmdline, &contents, &len, NULL))
|
||||||
goto done;
|
return;
|
||||||
|
|
||||||
process_name = strrchr (contents, '/');
|
process_name = strrchr (contents, '/');
|
||||||
if (process_name)
|
if (process_name)
|
||||||
process_name++;
|
process_name++;
|
||||||
else
|
else
|
||||||
process_name = contents;
|
process_name = contents;
|
||||||
if (strcmp (process_name, name) == 0) {
|
if (strcmp (process_name, prgname) == 0) {
|
||||||
/* Check that the process exists */
|
/* Check that the process exists */
|
||||||
if (kill (pid, 0) == 0) {
|
if (kill (pid, 0) == 0) {
|
||||||
fprintf (stderr, _("%s is already running (pid %ld)\n"), name, pid);
|
fprintf (stderr, _("%s is already running (pid %ld)\n"), prgname, pid);
|
||||||
nm_running = TRUE;
|
exit (1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
void
|
||||||
g_free (proc_cmdline);
|
nm_main_utils_ensure_root ()
|
||||||
g_free (contents);
|
{
|
||||||
return nm_running;
|
if (getuid () != 0) {
|
||||||
|
fprintf (stderr, _("You must be root to run %s!\n"), str_if_set (g_get_prgname (), ""));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nm_main_utils_early_setup (const char *progname,
|
nm_main_utils_early_setup (const char *progname,
|
||||||
char **argv[],
|
|
||||||
int *argc,
|
int *argc,
|
||||||
|
char **argv[],
|
||||||
GOptionEntry *options,
|
GOptionEntry *options,
|
||||||
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
|
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
|
||||||
gpointer option_context_hook_data,
|
gpointer option_context_hook_data,
|
||||||
@@ -183,6 +195,8 @@ nm_main_utils_early_setup (const char *progname,
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
int i;
|
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
|
/* 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
|
* session bus to contact the remote service, and NM shouldn't ever be
|
||||||
@@ -201,17 +215,17 @@ nm_main_utils_early_setup (const char *progname,
|
|||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
textdomain (GETTEXT_PACKAGE);
|
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++) {
|
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 ());
|
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 ());
|
options[i].description = g_strdup_printf (options[i].description, nm_logging_all_domains_to_string ());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse options */
|
/* Parse options */
|
||||||
opt_ctx = g_option_context_new (NULL);
|
opt_ctx = g_option_context_new (NULL);
|
||||||
@@ -231,6 +245,15 @@ nm_main_utils_early_setup (const char *progname,
|
|||||||
}
|
}
|
||||||
g_option_context_free (opt_ctx);
|
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;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,15 +23,19 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
void nm_main_utils_ensure_root (void);
|
||||||
|
|
||||||
void nm_main_utils_setup_signals (GMainLoop *main_loop);
|
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_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,
|
gboolean nm_main_utils_early_setup (const char *progname,
|
||||||
char **argv[],
|
|
||||||
int *argc,
|
int *argc,
|
||||||
|
char **argv[],
|
||||||
GOptionEntry *options,
|
GOptionEntry *options,
|
||||||
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
|
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
|
||||||
gpointer option_context_hook_data,
|
gpointer option_context_hook_data,
|
||||||
|
218
src/main.c
218
src/main.c
@@ -67,6 +67,20 @@
|
|||||||
static GMainLoop *main_loop = NULL;
|
static GMainLoop *main_loop = NULL;
|
||||||
static gboolean configure_and_quit = FALSE;
|
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
|
static gboolean
|
||||||
parse_state_file (const char *filename,
|
parse_state_file (const char *filename,
|
||||||
gboolean *net_enabled,
|
gboolean *net_enabled,
|
||||||
@@ -197,6 +211,37 @@ manager_configure_quit (NMManager *manager, gpointer user_data)
|
|||||||
configure_and_quit = TRUE;
|
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
|
* main
|
||||||
*
|
*
|
||||||
@@ -204,75 +249,55 @@ manager_configure_quit (NMManager *manager, gpointer user_data)
|
|||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
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 wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE;
|
||||||
gboolean success, show_version = FALSE;
|
gboolean success = FALSE;
|
||||||
NMManager *manager = NULL;
|
NMManager *manager = NULL;
|
||||||
gs_unref_object NMSettings *settings = NULL;
|
gs_unref_object NMSettings *settings = NULL;
|
||||||
gs_unref_object NMConfig *config = NULL;
|
NMConfig *config;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gboolean wrote_pidfile = FALSE;
|
gboolean wrote_pidfile = FALSE;
|
||||||
char *bad_domains = NULL;
|
char *bad_domains = NULL;
|
||||||
NMConfigCmdLineOptions *config_cli;
|
NMConfigCmdLineOptions *config_cli;
|
||||||
|
|
||||||
GOptionEntry options[] = {
|
#if !GLIB_CHECK_VERSION (2, 35, 0)
|
||||||
{ "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL },
|
g_type_init ();
|
||||||
{ "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &become_daemon, N_("Don't become a daemon"), NULL },
|
#endif
|
||||||
{ "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}
|
|
||||||
};
|
|
||||||
|
|
||||||
_nm_utils_is_manager_process = TRUE;
|
_nm_utils_is_manager_process = TRUE;
|
||||||
|
|
||||||
main_loop = g_main_loop_new (NULL, FALSE);
|
main_loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
config_cli = nm_config_cmd_line_options_new ();
|
config_cli = nm_config_cmd_line_options_new ();
|
||||||
if (!nm_main_utils_early_setup ("NetworkManager",
|
do_early_setup (&argc, &argv, config_cli);
|
||||||
&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);
|
|
||||||
|
|
||||||
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");
|
fprintf (stdout, NM_DIST_VERSION "\n");
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nm_logging_setup (opt_log_level,
|
nm_main_utils_ensure_root ();
|
||||||
opt_log_domains,
|
|
||||||
&bad_domains,
|
nm_main_utils_ensure_not_running_pidfile (global_opt.pidfile);
|
||||||
&error)) {
|
|
||||||
fprintf (stderr,
|
/* Ensure state directory exists */
|
||||||
_("%s. Please use --help to see a list of valid options.\n"),
|
if (g_mkdir_with_parents (NMSTATEDIR, 0755) != 0) {
|
||||||
error->message);
|
fprintf (stderr, "Cannot create '%s': %s", NMSTATEDIR, strerror (errno));
|
||||||
exit (1);
|
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
|
/* When running from the build directory, determine our build directory
|
||||||
* base and set helper paths in the build tree */
|
* base and set helper paths in the build tree */
|
||||||
if (run_from_build_dir) {
|
if (global_opt.run_from_build_dir) {
|
||||||
char *path, *slash;
|
char *path, *slash;
|
||||||
int g;
|
int g;
|
||||||
|
|
||||||
@@ -294,19 +319,21 @@ main (int argc, char *argv[])
|
|||||||
g_free (path);
|
g_free (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure state directory exists */
|
if (!nm_logging_setup (global_opt.opt_log_level,
|
||||||
if (g_mkdir_with_parents (NMSTATEDIR, 0755) != 0) {
|
global_opt.opt_log_domains,
|
||||||
nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMSTATEDIR, strerror (errno));
|
&bad_domains,
|
||||||
|
&error)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s. Please use --help to see a list of valid options.\n"),
|
||||||
|
error->message);
|
||||||
exit (1);
|
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 */
|
/* Read the config file and CLI overrides */
|
||||||
config = nm_config_setup (config_cli, &error);
|
config = nm_config_setup (config_cli, &error);
|
||||||
nm_config_cmd_line_options_free (config_cli);
|
nm_config_cmd_line_options_free (config_cli);
|
||||||
@@ -318,10 +345,12 @@ main (int argc, char *argv[])
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_init_nm_debug (nm_config_get_debug (config));
|
||||||
|
|
||||||
/* Initialize logging from config file *only* if not explicitly
|
/* Initialize logging from config file *only* if not explicitly
|
||||||
* specified by commandline.
|
* 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),
|
if (!nm_logging_setup (nm_config_get_log_level (config),
|
||||||
nm_config_get_log_domains (config),
|
nm_config_get_log_domains (config),
|
||||||
&bad_domains,
|
&bad_domains,
|
||||||
@@ -337,17 +366,7 @@ main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse the state file */
|
if (global_opt.become_daemon && !global_opt.debug) {
|
||||||
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 (daemon (0, 0) < 0) {
|
if (daemon (0, 0) < 0) {
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
|
|
||||||
@@ -357,27 +376,25 @@ main (int argc, char *argv[])
|
|||||||
saved_errno);
|
saved_errno);
|
||||||
exit (1);
|
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! */
|
/* Set up unix signal handling - before creating threads, but after daemonizing! */
|
||||||
nm_main_utils_setup_signals (main_loop);
|
nm_main_utils_setup_signals (main_loop);
|
||||||
|
|
||||||
if (g_fatal_warnings) {
|
nm_logging_syslog_openlog (global_opt.debug);
|
||||||
GLogLevelFlags fatal_mask;
|
|
||||||
|
|
||||||
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
|
nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting...");
|
||||||
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
|
|
||||||
g_log_set_always_fatal (fatal_mask);
|
/* 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);
|
||||||
nm_logging_syslog_openlog (debug);
|
|
||||||
|
|
||||||
#if !GLIB_CHECK_VERSION (2, 35, 0)
|
|
||||||
g_type_init ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dbus_threads_init_default ();
|
dbus_threads_init_default ();
|
||||||
|
|
||||||
@@ -386,9 +403,6 @@ main (int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
dbus_glib_global_set_disable_legacy_property_access ();
|
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, "Read config: %s", nm_config_data_get_config_description (nm_config_get_data (config)));
|
||||||
nm_log_info (LOGD_CORE, "WEXT support is %s",
|
nm_log_info (LOGD_CORE, "WEXT support is %s",
|
||||||
#if HAVE_WEXT
|
#if HAVE_WEXT
|
||||||
@@ -398,6 +412,21 @@ main (int argc, char *argv[])
|
|||||||
#endif
|
#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 */
|
/* Set up platform interaction layer */
|
||||||
nm_linux_platform_setup ();
|
nm_linux_platform_setup ();
|
||||||
|
|
||||||
@@ -413,7 +442,7 @@ main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
manager = nm_manager_new (settings,
|
manager = nm_manager_new (settings,
|
||||||
state_file,
|
global_opt.state_file,
|
||||||
net_enabled,
|
net_enabled,
|
||||||
wifi_enabled,
|
wifi_enabled,
|
||||||
wwan_enabled,
|
wwan_enabled,
|
||||||
@@ -425,21 +454,6 @@ main (int argc, char *argv[])
|
|||||||
goto done;
|
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);
|
g_signal_connect (manager, NM_MANAGER_CONFIGURE_QUIT, G_CALLBACK (manager_configure_quit), config);
|
||||||
|
|
||||||
nm_manager_start (manager);
|
nm_manager_start (manager);
|
||||||
@@ -469,8 +483,8 @@ done:
|
|||||||
|
|
||||||
nm_logging_syslog_closelog ();
|
nm_logging_syslog_closelog ();
|
||||||
|
|
||||||
if (pidfile && wrote_pidfile)
|
if (global_opt.pidfile && wrote_pidfile)
|
||||||
unlink (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");
|
||||||
exit (success ? 0 : 1);
|
exit (success ? 0 : 1);
|
||||||
|
@@ -34,6 +34,10 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <signal.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 "gsystem-local-alloc.h"
|
||||||
#include "NetworkManagerUtils.h"
|
#include "NetworkManagerUtils.h"
|
||||||
#include "nm-linux-platform.h"
|
#include "nm-linux-platform.h"
|
||||||
@@ -51,13 +55,32 @@
|
|||||||
#define NMIH_PID_FILE_FMT NMRUNDIR "/nm-iface-helper-%d.pid"
|
#define NMIH_PID_FILE_FMT NMRUNDIR "/nm-iface-helper-%d.pid"
|
||||||
|
|
||||||
static GMainLoop *main_loop = NULL;
|
static GMainLoop *main_loop = NULL;
|
||||||
static char *ifname = NULL;
|
|
||||||
static int ifindex = -1;
|
static int ifindex = -1;
|
||||||
static gboolean slaac_required = FALSE;
|
|
||||||
static gboolean dhcp4_required = FALSE;
|
static struct {
|
||||||
static int tempaddr = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
gboolean slaac;
|
||||||
static guint32 priority_v4 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4;
|
gboolean show_version;
|
||||||
static guint32 priority_v6 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6;
|
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
|
static void
|
||||||
dhcp4_state_changed (NMDhcpClient *client,
|
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));
|
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) {
|
switch (state) {
|
||||||
case NM_DHCP_STATE_BOUND:
|
case NM_DHCP_STATE_BOUND:
|
||||||
@@ -81,8 +104,8 @@ dhcp4_state_changed (NMDhcpClient *client,
|
|||||||
nm_ip4_config_subtract (existing, last_config);
|
nm_ip4_config_subtract (existing, last_config);
|
||||||
|
|
||||||
nm_ip4_config_merge (existing, ip4_config);
|
nm_ip4_config_merge (existing, ip4_config);
|
||||||
if (!nm_ip4_config_commit (existing, ifindex, priority_v4))
|
if (!nm_ip4_config_commit (existing, ifindex, global_opt.priority_v4))
|
||||||
nm_log_warn (LOGD_DHCP4, "(%s): failed to apply DHCPv4 config", ifname);
|
nm_log_warn (LOGD_DHCP4, "(%s): failed to apply DHCPv4 config", global_opt.ifname);
|
||||||
|
|
||||||
if (last_config) {
|
if (last_config) {
|
||||||
g_object_unref (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_TIMEOUT:
|
||||||
case NM_DHCP_STATE_DONE:
|
case NM_DHCP_STATE_DONE:
|
||||||
case NM_DHCP_STATE_FAIL:
|
case NM_DHCP_STATE_FAIL:
|
||||||
if (dhcp4_required) {
|
if (global_opt.dhcp4_required) {
|
||||||
nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed, quitting...", ifname);
|
nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed, quitting...", global_opt.ifname);
|
||||||
g_main_loop_quit (main_loop);
|
g_main_loop_quit (main_loop);
|
||||||
} else
|
} 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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -128,8 +151,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
|
|||||||
|
|
||||||
if (system_support)
|
if (system_support)
|
||||||
ifa_flags = IFA_F_NOPREFIXROUTE;
|
ifa_flags = IFA_F_NOPREFIXROUTE;
|
||||||
if (tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR
|
if (global_opt.tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR
|
||||||
|| tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_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. */
|
/* without system_support, this flag will be ignored. Still set it, doesn't seem to do any harm. */
|
||||||
ifa_flags |= IFA_F_MANAGETEMPADDR;
|
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.plen = discovered_route->plen;
|
||||||
route.gateway = discovered_route->gateway;
|
route.gateway = discovered_route->gateway;
|
||||||
route.source = NM_IP_CONFIG_SOURCE_RDISC;
|
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);
|
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];
|
char val[16];
|
||||||
|
|
||||||
g_snprintf (val, sizeof (val), "%d", rdisc->hop_limit);
|
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) {
|
if (changed & NM_RDISC_CONFIG_MTU) {
|
||||||
char val[16];
|
char val[16];
|
||||||
|
|
||||||
g_snprintf (val, sizeof (val), "%d", rdisc->mtu);
|
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)
|
if (last_config)
|
||||||
nm_ip6_config_subtract (existing, last_config);
|
nm_ip6_config_subtract (existing, last_config);
|
||||||
|
|
||||||
nm_ip6_config_merge (existing, ip6_config);
|
nm_ip6_config_merge (existing, ip6_config);
|
||||||
if (!nm_ip6_config_commit (existing, ifindex))
|
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) {
|
if (last_config) {
|
||||||
g_object_unref (last_config);
|
g_object_unref (last_config);
|
||||||
@@ -238,11 +261,11 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
|
|||||||
static void
|
static void
|
||||||
rdisc_ra_timeout (NMRDisc *rdisc, gpointer user_data)
|
rdisc_ra_timeout (NMRDisc *rdisc, gpointer user_data)
|
||||||
{
|
{
|
||||||
if (slaac_required) {
|
if (global_opt.slaac_required) {
|
||||||
nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed, quitting...", ifname);
|
nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed, quitting...", global_opt.ifname);
|
||||||
g_main_loop_quit (main_loop);
|
g_main_loop_quit (main_loop);
|
||||||
} else
|
} 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
|
static gboolean
|
||||||
@@ -260,15 +283,63 @@ setup_signals (void)
|
|||||||
g_unix_signal_add (SIGTERM, quit_handler, NULL);
|
g_unix_signal_add (SIGTERM, quit_handler, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_early_setup (int *argc, char **argv[])
|
||||||
|
{
|
||||||
|
gint64 priority64_v4 = -1;
|
||||||
|
gint64 priority64_v6 = -1;
|
||||||
|
GOptionEntry options[] = {
|
||||||
|
/* Interface/IP config */
|
||||||
|
{ "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, &global_opt.iid_str, N_("Hex-encoded Interface Identifier"), N_("") },
|
||||||
|
|
||||||
|
/* Logging/debugging */
|
||||||
|
{ "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, &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",
|
||||||
|
argc,
|
||||||
|
argv,
|
||||||
|
options,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
_("nm-iface-helper is a small, standalone process that manages a single network interface.")))
|
||||||
|
exit (1);
|
||||||
|
|
||||||
|
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
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *opt_log_level = NULL;
|
char *bad_domains = 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;
|
GError *error = NULL;
|
||||||
gboolean wrote_pidfile = FALSE;
|
gboolean wrote_pidfile = FALSE;
|
||||||
gs_free char *pidfile = NULL;
|
gs_free char *pidfile = NULL;
|
||||||
@@ -278,59 +349,47 @@ main (int argc, char *argv[])
|
|||||||
size_t hwaddr_len = 0;
|
size_t hwaddr_len = 0;
|
||||||
gconstpointer tmp;
|
gconstpointer tmp;
|
||||||
gs_free NMUtilsIPv6IfaceId *iid = NULL;
|
gs_free NMUtilsIPv6IfaceId *iid = NULL;
|
||||||
gint64 priority64_v4 = -1;
|
|
||||||
gint64 priority64_v6 = -1;
|
|
||||||
|
|
||||||
GOptionEntry options[] = {
|
#if !GLIB_CHECK_VERSION (2, 35, 0)
|
||||||
/* Interface/IP config */
|
g_type_init ();
|
||||||
{ "ifname", 'i', 0, G_OPTION_ARG_STRING, &ifname, N_("The interface to manage"), N_("eth0") },
|
#endif
|
||||||
{ "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") },
|
|
||||||
{ "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_("") },
|
|
||||||
|
|
||||||
/* 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,
|
|
||||||
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 },
|
|
||||||
{NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
setpgid (getpid (), getpid ());
|
setpgid (getpid (), getpid ());
|
||||||
|
|
||||||
if (!nm_main_utils_early_setup ("nm-iface-helper",
|
do_early_setup (&argc, &argv);
|
||||||
&argv,
|
|
||||||
&argc,
|
|
||||||
options,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
_("nm-iface-helper is a small, standalone process that manages a single network interface.")))
|
|
||||||
exit (1);
|
|
||||||
|
|
||||||
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");
|
fprintf (stdout, NM_DIST_VERSION "\n");
|
||||||
exit (0);
|
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"));
|
fprintf (stderr, _("An interface name and UUID are required\n"));
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nm_logging_setup (opt_log_level,
|
ifindex = if_nametoindex (global_opt.ifname);
|
||||||
opt_log_domains,
|
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,
|
&bad_domains,
|
||||||
&error)) {
|
&error)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@@ -344,14 +403,7 @@ main (int argc, char *argv[])
|
|||||||
g_clear_pointer (&bad_domains, g_free);
|
g_clear_pointer (&bad_domains, g_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
pidfile = g_strdup_printf (NMIH_PID_FILE_FMT, ifindex);
|
if (global_opt.become_daemon && !global_opt.debug) {
|
||||||
g_assert (pidfile);
|
|
||||||
|
|
||||||
/* check pid file */
|
|
||||||
if (nm_main_utils_check_pidfile (pidfile, "nm-iface-helper"))
|
|
||||||
exit (1);
|
|
||||||
|
|
||||||
if (become_daemon && !debug) {
|
|
||||||
if (daemon (0, 0) < 0) {
|
if (daemon (0, 0) < 0) {
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
|
|
||||||
@@ -369,70 +421,46 @@ main (int argc, char *argv[])
|
|||||||
main_loop = g_main_loop_new (NULL, FALSE);
|
main_loop = g_main_loop_new (NULL, FALSE);
|
||||||
setup_signals ();
|
setup_signals ();
|
||||||
|
|
||||||
if (g_fatal_warnings) {
|
nm_logging_syslog_openlog (global_opt.debug);
|
||||||
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_log_info (LOGD_CORE, "nm-iface-helper (version " NM_DIST_VERSION ") is starting...");
|
nm_log_info (LOGD_CORE, "nm-iface-helper (version " NM_DIST_VERSION ") is starting...");
|
||||||
|
|
||||||
/* Set up platform interaction layer */
|
/* Set up platform interaction layer */
|
||||||
nm_linux_platform_setup ();
|
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);
|
tmp = nm_platform_link_get_address (ifindex, &hwaddr_len);
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
hwaddr = g_byte_array_sized_new (hwaddr_len);
|
hwaddr = g_byte_array_sized_new (hwaddr_len);
|
||||||
g_byte_array_append (hwaddr, tmp, hwaddr_len);
|
g_byte_array_append (hwaddr, tmp, hwaddr_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iid_str) {
|
if (global_opt.iid_str) {
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
gsize ignored = 0;
|
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)) {
|
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);
|
exit (1);
|
||||||
}
|
}
|
||||||
iid = g_bytes_unref_to_data (bytes, &ignored);
|
iid = g_bytes_unref_to_data (bytes, &ignored);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority64_v4 >= 0 && priority64_v4 <= G_MAXUINT32)
|
if (global_opt.dhcp4_address) {
|
||||||
priority_v4 = (guint32) priority64_v4;
|
nm_platform_sysctl_set (nm_utils_ip4_property_path (global_opt.ifname, "promote_secondaries"), "1");
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
|
dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
|
||||||
ifname,
|
global_opt.ifname,
|
||||||
ifindex,
|
ifindex,
|
||||||
hwaddr,
|
hwaddr,
|
||||||
uuid,
|
global_opt.uuid,
|
||||||
priority_v4,
|
global_opt.priority_v4,
|
||||||
!!dhcp4_hostname,
|
!!global_opt.dhcp4_hostname,
|
||||||
dhcp4_hostname,
|
global_opt.dhcp4_hostname,
|
||||||
dhcp4_clientid,
|
global_opt.dhcp4_clientid,
|
||||||
45,
|
45,
|
||||||
NULL,
|
NULL,
|
||||||
dhcp4_address);
|
global_opt.dhcp4_address);
|
||||||
g_assert (dhcp4_client);
|
g_assert (dhcp4_client);
|
||||||
g_signal_connect (dhcp4_client,
|
g_signal_connect (dhcp4_client,
|
||||||
NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
|
NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
|
||||||
@@ -440,19 +468,19 @@ main (int argc, char *argv[])
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slaac) {
|
if (global_opt.slaac) {
|
||||||
nm_platform_link_set_user_ipv6ll_enabled (ifindex, TRUE);
|
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);
|
g_assert (rdisc);
|
||||||
|
|
||||||
if (iid)
|
if (iid)
|
||||||
nm_rdisc_set_iid (rdisc, *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 (global_opt.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 (global_opt.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 (global_opt.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_rtr_pref"), "0");
|
||||||
|
|
||||||
g_signal_connect (rdisc,
|
g_signal_connect (rdisc,
|
||||||
NM_RDISC_CONFIG_CHANGED,
|
NM_RDISC_CONFIG_CHANGED,
|
||||||
|
Reference in New Issue
Block a user