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.
This commit is contained in:
@@ -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
|
||||
|
@@ -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.");
|
||||
|
@@ -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",
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
109
src/nm-config.c
109
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,14 +517,47 @@ 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)
|
||||
{
|
||||
g_return_if_fail (opt_ctx);
|
||||
g_return_if_fail (cli);
|
||||
|
||||
{
|
||||
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 },
|
||||
@@ -525,7 +566,7 @@ nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli,
|
||||
{ "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 },
|
||||
{ "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. */
|
||||
@@ -535,8 +576,13 @@ nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli,
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
g_option_context_add_main_entries (opt_ctx, config_options, NULL);
|
||||
}
|
||||
g_return_if_fail (opt_ctx);
|
||||
g_return_if_fail (cli);
|
||||
|
||||
group = g_option_group_new ("nm", N_("NetworkManager options" ), N_("Show NetworkManager options"), cli, 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) {
|
||||
|
||||
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);
|
||||
}
|
||||
if (cli && cli->configure_and_quit)
|
||||
|
||||
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);
|
||||
if (cli && cli->connectivity_uri && cli->connectivity_uri[0])
|
||||
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 && cli->connectivity_interval >= 0)
|
||||
if (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])
|
||||
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);
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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 *
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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 ();
|
||||
|
Reference in New Issue
Block a user