summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2018-01-30 18:01:18 +0100
committerLubomir Rintel <lkundrak@v3.sk>2018-09-18 17:40:47 +0200
commitc263f5355cbd86da75aaa161987fee8b59cb8c8b (patch)
tree656cb2e83328a09375ce34fa32ed8b852d5e4338
parente03d9ad1e0c67e0ba1e3b12f213bfc963ebce196 (diff)
downloadNetworkManager-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.c19
-rw-r--r--src/dhcp/nm-dhcp-manager.c2
-rw-r--r--src/dhcp/nm-dhcp-systemd.c29
-rw-r--r--src/nm-config.c151
-rw-r--r--src/nm-config.h9
-rw-r--r--src/nm-iface-helper.c4
-rw-r--r--src/nm-manager.c2
-rw-r--r--src/settings/nm-settings-connection.c2
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 ();