diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2018-01-30 18:01:18 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2018-09-18 17:40:47 +0200 |
commit | c263f5355cbd86da75aaa161987fee8b59cb8c8b (patch) | |
tree | 656cb2e83328a09375ce34fa32ed8b852d5e4338 | |
parent | e03d9ad1e0c67e0ba1e3b12f213bfc963ebce196 (diff) | |
download | NetworkManager-c263f5355cbd86da75aaa161987fee8b59cb8c8b.tar.gz |
config: add --configure-and-quit=initrd mode
We need a mode that:
* doesn't leave processes behind
* doesn't force an internal dhclient
* doesn't auto-generate default connections
* doesn't write out files into libdir, only /run
The original configure-and-quit mode doesn't really fit the initrd use. But
it's proobably not a good idea to just change its behavior.
-rw-r--r-- | src/dhcp/nm-dhcp-dhclient.c | 19 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-manager.c | 2 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-systemd.c | 29 | ||||
-rw-r--r-- | src/nm-config.c | 151 | ||||
-rw-r--r-- | src/nm-config.h | 9 | ||||
-rw-r--r-- | src/nm-iface-helper.c | 4 | ||||
-rw-r--r-- | src/nm-manager.c | 2 | ||||
-rw-r--r-- | src/settings/nm-settings-connection.c | 2 |
8 files changed, 169 insertions, 49 deletions
diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c index 46d2339bf2..4a93617819 100644 --- a/src/dhcp/nm-dhcp-dhclient.c +++ b/src/dhcp/nm-dhcp-dhclient.c @@ -41,6 +41,7 @@ #include "nm-utils/nm-dedup-multi.h" #include "nm-utils.h" +#include "nm-config.h" #include "nm-dhcp-dhclient-utils.h" #include "nm-dhcp-manager.h" #include "NetworkManagerUtils.h" @@ -120,8 +121,20 @@ get_dhclient_leasefile (int addr_family, const char *uuid, char **out_preferred_path) { + char *rundir_path; char *path; + /* First, see if the lease file is in /run */ + rundir_path = g_strdup_printf (NMRUNDIR "/dhclient%s-%s-%s.lease", + _addr_family_to_path_part (addr_family), + uuid, + iface); + + if (g_file_test (rundir_path, G_FILE_TEST_EXISTS)) { + NM_SET_OUT (out_preferred_path, g_strdup (rundir_path)); + return rundir_path; + } + /* /var/lib/NetworkManager is the preferred leasefile path */ path = g_strdup_printf (NMSTATEDIR "/dhclient%s-%s-%s.lease", _addr_family_to_path_part (addr_family), @@ -133,6 +146,12 @@ get_dhclient_leasefile (int addr_family, return path; } + if (nm_config_get_configure_and_quit (nm_config_get ()) == NM_CONFIG_CONFIGURE_AND_QUIT_INITRD) { + g_free (path); + path = rundir_path; + } else { + g_free (rundir_path); + } NM_SET_OUT (out_preferred_path, g_steal_pointer (&path)); /* If the leasefile we're looking for doesn't exist yet in the new location diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index 6c71af9d0b..5ae16d721a 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -413,7 +413,7 @@ nm_dhcp_manager_init (NMDhcpManager *self) NM_CONFIG_KEYFILE_KEY_MAIN_DHCP, NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY); client = client_free; - if (nm_config_get_configure_and_quit (config)) { + if (nm_config_get_configure_and_quit (config) == NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED) { client_factory = &_nm_dhcp_client_factory_internal; if (client && !nm_streq (client, client_factory->name)) nm_log_info (LOGD_DHCP, "dhcp-init: Using internal DHCP client since configure-and-quit is set."); diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index c31b9c6174..30f5131586 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -32,6 +32,7 @@ #include "nm-utils/unaligned.h" #include "nm-utils.h" +#include "nm-config.h" #include "nm-dhcp-utils.h" #include "NetworkManagerUtils.h" #include "platform/nm-platform.h" @@ -453,10 +454,30 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx, static char * get_leasefile_path (int addr_family, const char *iface, const char *uuid) { - return g_strdup_printf (NMSTATEDIR "/internal%s-%s-%s.lease", - addr_family == AF_INET6 ? "6" : "", - uuid, - iface); + char *rundir_path; + char *statedir_path; + + rundir_path = g_strdup_printf (NMRUNDIR "/internal%s-%s-%s.lease", + addr_family == AF_INET6 ? "6" : "", + uuid, + iface); + + if (g_file_test (rundir_path, G_FILE_TEST_EXISTS)) + return rundir_path; + + statedir_path = g_strdup_printf (NMSTATEDIR "/internal%s-%s-%s.lease", + addr_family == AF_INET6 ? "6" : "", + uuid, + iface); + + if ( g_file_test (statedir_path, G_FILE_TEST_EXISTS) + || nm_config_get_configure_and_quit (nm_config_get ()) != NM_CONFIG_CONFIGURE_AND_QUIT_INITRD) { + g_free (rundir_path); + return statedir_path; + } else { + g_free (statedir_path); + return rundir_path; + } } /*****************************************************************************/ diff --git a/src/nm-config.c b/src/nm-config.c index f21eb8777c..0be5b15fbd 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -51,7 +51,8 @@ struct NMConfigCmdLineOptions { char *state_file; char *no_auto_default_file; char *plugins; - gboolean configure_and_quit; + NMConfigConfigureAndQuitType configure_and_quit; + gboolean is_debug; char *connectivity_uri; @@ -105,7 +106,7 @@ typedef struct { char *log_level; char *log_domains; - gboolean configure_and_quit; + NMConfigConfigureAndQuitType configure_and_quit; char **atomic_section_prefixes; @@ -323,7 +324,7 @@ nm_config_get_log_domains (NMConfig *config) return NM_CONFIG_GET_PRIVATE (config)->log_domains; } -gboolean +NMConfigConfigureAndQuitType nm_config_get_configure_and_quit (NMConfig *config) { return NM_CONFIG_GET_PRIVATE (config)->configure_and_quit; @@ -392,9 +393,16 @@ no_auto_default_to_file (const char *no_auto_default_file, const char *const*no_ gboolean nm_config_get_no_auto_default_for_device (NMConfig *self, NMDevice *device) { + NMConfigPrivate *priv; + g_return_val_if_fail (NM_IS_CONFIG (self), FALSE); - return nm_config_data_get_no_auto_default_for_device (NM_CONFIG_GET_PRIVATE (self)->config_data, device); + priv = NM_CONFIG_GET_PRIVATE (self); + + if (priv->configure_and_quit == NM_CONFIG_CONFIGURE_AND_QUIT_INITRD) + return TRUE; + + return nm_config_data_get_no_auto_default_for_device (priv->config_data, device); } void @@ -457,7 +465,7 @@ _nm_config_cmd_line_options_clear (NMConfigCmdLineOptions *cli) g_clear_pointer (&cli->intern_config_file, g_free); g_clear_pointer (&cli->state_file, g_free); g_clear_pointer (&cli->plugins, g_free); - cli->configure_and_quit = FALSE; + cli->configure_and_quit = NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED; cli->is_debug = FALSE; g_clear_pointer (&cli->connectivity_uri, g_free); g_clear_pointer (&cli->connectivity_response, g_free); @@ -509,34 +517,72 @@ nm_config_cmd_line_options_free (NMConfigCmdLineOptions *cli) g_free (cli); } +static NMConfigConfigureAndQuitType +string_to_configure_and_quit (const char *value, GError **error) +{ + NMConfigConfigureAndQuitType ret; + + if (value == NULL) + return NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED; + + if (strcmp (value, "initrd") == 0) + return NM_CONFIG_CONFIGURE_AND_QUIT_INITRD; + + ret = nm_config_parse_boolean (value, NM_CONFIG_CONFIGURE_AND_QUIT_INVALID); + if (ret == NM_CONFIG_CONFIGURE_AND_QUIT_INVALID) + g_set_error (error, 1, 0, N_("'%s' is not valid"), value); + + return ret; +} + +static gboolean +parse_configure_and_quit (const char *option_name, const char *value, gpointer user_data, GError **error) +{ + NMConfigCmdLineOptions *cli = user_data; + + if (value == NULL) + cli->configure_and_quit = NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED; + else + cli->configure_and_quit = string_to_configure_and_quit (value, error); + + if (cli->configure_and_quit == NM_CONFIG_CONFIGURE_AND_QUIT_INVALID) { + g_prefix_error (error, N_("Bad '%s' option: "), option_name); + return FALSE; + } + + return TRUE; +} + void nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli, GOptionContext *opt_ctx) { + GOptionGroup *group; + GOptionEntry config_options[] = { + { "config", 0, 0, G_OPTION_ARG_FILENAME, &cli->config_main_file, N_("Config file location"), DEFAULT_CONFIG_MAIN_FILE }, + { "config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli->config_dir, N_("Config directory location"), DEFAULT_CONFIG_DIR }, + { "system-config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli->system_config_dir, N_("System config directory location"), DEFAULT_SYSTEM_CONFIG_DIR }, + { "intern-config", 0, 0, G_OPTION_ARG_FILENAME, &cli->intern_config_file, N_("Internal config file location"), DEFAULT_INTERN_CONFIG_FILE }, + { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &cli->state_file, N_("State file location"), DEFAULT_STATE_FILE }, + { "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli->no_auto_default_file, N_("State file for no-auto-default devices"), DEFAULT_NO_AUTO_DEFAULT_FILE }, + { "plugins", 0, 0, G_OPTION_ARG_STRING, &cli->plugins, N_("List of plugins separated by ','"), NM_CONFIG_DEFAULT_MAIN_PLUGINS }, + { "configure-and-quit", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, parse_configure_and_quit, N_("Quit after initial configuration"), NULL }, + { "debug", 'd', 0, G_OPTION_ARG_NONE, &cli->is_debug, N_("Don't become a daemon, and log to stderr"), NULL }, + + /* These three are hidden for now, and should eventually just go away. */ + { "connectivity-uri", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli->connectivity_uri, N_("An http(s) address for checking internet connectivity"), "http://example.com" }, + { "connectivity-interval", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_INT, &cli->connectivity_interval, N_("The interval between connectivity checks (in seconds)"), G_STRINGIFY (NM_CONFIG_DEFAULT_CONNECTIVITY_INTERVAL) }, + { "connectivity-response", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli->connectivity_response, N_("The expected start of the response"), NM_CONFIG_DEFAULT_CONNECTIVITY_RESPONSE }, + { 0 }, + }; + g_return_if_fail (opt_ctx); g_return_if_fail (cli); - { - GOptionEntry config_options[] = { - { "config", 0, 0, G_OPTION_ARG_FILENAME, &cli->config_main_file, N_("Config file location"), DEFAULT_CONFIG_MAIN_FILE }, - { "config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli->config_dir, N_("Config directory location"), DEFAULT_CONFIG_DIR }, - { "system-config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli->system_config_dir, N_("System config directory location"), DEFAULT_SYSTEM_CONFIG_DIR }, - { "intern-config", 0, 0, G_OPTION_ARG_FILENAME, &cli->intern_config_file, N_("Internal config file location"), DEFAULT_INTERN_CONFIG_FILE }, - { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &cli->state_file, N_("State file location"), DEFAULT_STATE_FILE }, - { "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli->no_auto_default_file, N_("State file for no-auto-default devices"), DEFAULT_NO_AUTO_DEFAULT_FILE }, - { "plugins", 0, 0, G_OPTION_ARG_STRING, &cli->plugins, N_("List of plugins separated by ','"), NM_CONFIG_DEFAULT_MAIN_PLUGINS }, - { "configure-and-quit", 0, 0, G_OPTION_ARG_NONE, &cli->configure_and_quit, N_("Quit after initial configuration"), NULL }, - { "debug", 'd', 0, G_OPTION_ARG_NONE, &cli->is_debug, N_("Don't become a daemon, and log to stderr"), NULL }, - - /* These three are hidden for now, and should eventually just go away. */ - { "connectivity-uri", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli->connectivity_uri, N_("An http(s) address for checking internet connectivity"), "http://example.com" }, - { "connectivity-interval", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_INT, &cli->connectivity_interval, N_("The interval between connectivity checks (in seconds)"), G_STRINGIFY (NM_CONFIG_DEFAULT_CONNECTIVITY_INTERVAL) }, - { "connectivity-response", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli->connectivity_response, N_("The expected start of the response"), NM_CONFIG_DEFAULT_CONNECTIVITY_RESPONSE }, - { 0 }, - }; + group = g_option_group_new ("nm", N_("NetworkManager options" ), N_("Show NetworkManager options"), cli, NULL); - g_option_context_add_main_entries (opt_ctx, config_options, NULL); - } + g_option_group_add_entries (group, config_options); + g_option_context_add_group (opt_ctx, group); } /*****************************************************************************/ @@ -1046,19 +1092,36 @@ read_entire_config (const NMConfigCmdLineOptions *cli, /* Merge settings from command line. They overwrite everything read from * config files. */ - if (cli && cli->plugins) { - /* plugins is a string list. Set the value directly, so the user has to do proper escaping - * on the command line. */ - g_key_file_set_value (keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", cli->plugins); - } - if (cli && cli->configure_and_quit) - g_key_file_set_boolean (keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "configure-and-quit", TRUE); - if (cli && cli->connectivity_uri && cli->connectivity_uri[0]) - g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "uri", cli->connectivity_uri); - if (cli && cli->connectivity_interval >= 0) - g_key_file_set_integer (keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "interval", cli->connectivity_interval); - if (cli && cli->connectivity_response && cli->connectivity_response[0]) - g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "response", cli->connectivity_response); + + if (cli) { + if (cli->plugins) { + /* plugins is a string list. Set the value directly, so the user has to do proper escaping + * on the command line. */ + g_key_file_set_value (keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", cli->plugins); + } + + switch (cli->configure_and_quit) { + case NM_CONFIG_CONFIGURE_AND_QUIT_INVALID: + g_assert_not_reached (); + break; + case NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED: + /* do nothing */ + break; + case NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED: + g_key_file_set_boolean (keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "configure-and-quit", TRUE); + break; + case NM_CONFIG_CONFIGURE_AND_QUIT_INITRD: + g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "configure-and-quit", "initrd"); + break; + } + + if (cli->connectivity_uri && cli->connectivity_uri[0]) + g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "uri", cli->connectivity_uri); + if (cli->connectivity_interval >= 0) + g_key_file_set_integer (keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "interval", cli->connectivity_interval); + if (cli->connectivity_response && cli->connectivity_response[0]) + g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "response", cli->connectivity_response); + } if (out_config_description) { GString *str; @@ -1837,6 +1900,9 @@ state_write (NMConfig *self) GString *str; GError *error = NULL; + if (priv->configure_and_quit != NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED) + return; + filename = state_get_filename (&priv->cli); if (!filename) { @@ -2495,6 +2561,7 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) char *config_main_file = NULL; char *config_description = NULL; gs_strfreev char **no_auto_default = NULL; + gs_free char *configure_and_quit = NULL; gboolean intern_config_needs_rewrite; const char *s; @@ -2541,7 +2608,10 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) priv->log_level = nm_strstrip (g_key_file_get_string (keyfile, NM_CONFIG_KEYFILE_GROUP_LOGGING, "level", NULL)); priv->log_domains = nm_strstrip (g_key_file_get_string (keyfile, NM_CONFIG_KEYFILE_GROUP_LOGGING, "domains", NULL)); - priv->configure_and_quit = nm_config_keyfile_get_boolean (keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "configure-and-quit", FALSE); + configure_and_quit = nm_strstrip (g_key_file_get_string (keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "configure-and-quit", NULL)); + priv->configure_and_quit = string_to_configure_and_quit (configure_and_quit, error); + if (priv->configure_and_quit == NM_CONFIG_CONFIGURE_AND_QUIT_INVALID) + return FALSE; no_auto_default = no_auto_default_from_file (priv->no_auto_default_file); @@ -2549,7 +2619,8 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) keyfile, (const char *const*) priv->atomic_section_prefixes, &intern_config_needs_rewrite); - if (intern_config_needs_rewrite) { + if ( intern_config_needs_rewrite + && priv->configure_and_quit == NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED) { intern_config_write (priv->intern_config_file, keyfile_intern, keyfile, (const char *const*) priv->atomic_section_prefixes, NULL); } diff --git a/src/nm-config.h b/src/nm-config.h index d05b4ecf64..c65572ce3f 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -101,6 +101,13 @@ typedef enum { NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED, } NMConfigRunStatePropertyType; +typedef enum { + NM_CONFIG_CONFIGURE_AND_QUIT_INVALID = -1, + NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED = FALSE, + NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED = TRUE, + NM_CONFIG_CONFIGURE_AND_QUIT_INITRD, +} NMConfigConfigureAndQuitType; + typedef struct { bool net_enabled; bool wifi_enabled; @@ -127,7 +134,7 @@ NMConfigData *nm_config_get_data_orig (NMConfig *config); gboolean nm_config_get_monitor_connection_files (NMConfig *config); const char *nm_config_get_log_level (NMConfig *config); const char *nm_config_get_log_domains (NMConfig *config); -gboolean nm_config_get_configure_and_quit (NMConfig *config); +NMConfigConfigureAndQuitType nm_config_get_configure_and_quit (NMConfig *config); gboolean nm_config_get_is_debug (NMConfig *config); gboolean nm_config_get_first_start (NMConfig *config); diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 805c6e4fd2..6ae2b9d2f7 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -627,10 +627,10 @@ nm_config_data_get_value (const NMConfigData *config_data, const char *group, co return NULL; } -gboolean +NMConfigConfigureAndQuitType nm_config_get_configure_and_quit (NMConfig *config) { - return TRUE; + return NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED; } NMDBusManager * diff --git a/src/nm-manager.c b/src/nm-manager.c index 6dfbb48f87..160ec92b14 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1632,7 +1632,7 @@ remove_device (NMManager *self, nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_REMOVED); nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, TRUE, NM_DEVICE_STATE_REASON_REMOVED); } - } else if (quitting && nm_config_get_configure_and_quit (priv->config)) { + } else if (quitting && nm_config_get_configure_and_quit (priv->config) == NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED) { nm_device_spawn_iface_helper (device); } } diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 248bf811f7..912949a28a 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -2510,6 +2510,8 @@ nm_settings_connection_update_timestamp (NMSettingsConnection *self, if (flush_to_disk == FALSE) return; + if (nm_config_get_configure_and_quit (nm_config_get ()) == NM_CONFIG_CONFIGURE_AND_QUIT_INITRD) + return; /* Save timestamp to timestamps database file */ timestamps_file = g_key_file_new (); |