mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-03 05:50:12 +01:00
keyfile: write in-memory connections to /run
This is useful for in-memory connections to persist NetworkManager restarts (as opposed to machine restarts). Perhaps most improtantly, this allows generating in-memory connections outside NetworkManager, e.g. passing configuration from early boot firmware in initrd. Note that this does *not* aspire to do more than it says on the tin: Notably, it doesn't touch the problem of provisioning connections in multiple persistent connection directories and thus doesn't have to deal with the problem of deleting or overlaying the connections tha (rh #772414) deals with.
This commit is contained in:
parent
e98ebc7e3b
commit
ce4dbd7daf
5 changed files with 73 additions and 38 deletions
|
|
@ -66,6 +66,7 @@ commit_changes (NMSettingsConnection *connection,
|
|||
nm_assert (!out_logmsg_change || !*out_logmsg_change);
|
||||
|
||||
if (!nms_keyfile_writer_connection (new_connection,
|
||||
TRUE,
|
||||
nm_settings_connection_get_filename (connection),
|
||||
NM_FLAGS_ALL (commit_reason, NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION
|
||||
| NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED),
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ update_connection (NMSKeyfilePlugin *self,
|
|||
NMSKeyfileConnection *connection_by_uuid;
|
||||
GError *local = NULL;
|
||||
const char *uuid;
|
||||
int dir_len;
|
||||
|
||||
g_return_val_if_fail (!source || NM_IS_CONNECTION (source), NULL);
|
||||
g_return_val_if_fail (full_path || source, NULL);
|
||||
|
|
@ -178,6 +179,22 @@ update_connection (NMSKeyfilePlugin *self,
|
|||
if (full_path)
|
||||
_LOGD ("loading from file \"%s\"...", full_path);
|
||||
|
||||
if (g_str_has_prefix (full_path, nms_keyfile_utils_get_path ())) {
|
||||
dir_len = strlen (nms_keyfile_utils_get_path ());
|
||||
} else if (g_str_has_prefix (full_path, NM_CONFIG_KEYFILE_PATH_IN_MEMORY)) {
|
||||
dir_len = NM_STRLEN (NM_CONFIG_KEYFILE_PATH_IN_MEMORY);
|
||||
} else {
|
||||
/* Just make sure the file name is not going go pass the following check. */
|
||||
dir_len = strlen (full_path);
|
||||
}
|
||||
|
||||
if ( full_path[dir_len] != '/'
|
||||
|| strchr (full_path + dir_len + 1, '/') != NULL) {
|
||||
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
|
||||
"File not in recognized system-connections directory");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
connection_new = nms_keyfile_connection_new (source, full_path, &local);
|
||||
if (!connection_new) {
|
||||
/* Error; remove the connection */
|
||||
|
|
@ -410,14 +427,34 @@ _sort_paths (const char **f1, const char **f2, GHashTable *paths)
|
|||
return strcmp (*f1, *f2);
|
||||
}
|
||||
|
||||
static void
|
||||
_read_dir (GPtrArray *filenames, const char *path)
|
||||
{
|
||||
GDir *dir;
|
||||
const char *item;
|
||||
GError *error = NULL;
|
||||
|
||||
dir = g_dir_open (path, 0, &error);
|
||||
if (!dir) {
|
||||
_LOGD ("cannot read directory '%s': %s", path, error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((item = g_dir_read_name (dir))) {
|
||||
if (nms_keyfile_utils_should_ignore_file (item))
|
||||
continue;
|
||||
g_ptr_array_add (filenames, g_build_filename (path, item, NULL));
|
||||
}
|
||||
g_dir_close (dir);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
read_connections (NMSettingsPlugin *config)
|
||||
{
|
||||
NMSKeyfilePlugin *self = NMS_KEYFILE_PLUGIN (config);
|
||||
NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self);
|
||||
GDir *dir;
|
||||
GError *error = NULL;
|
||||
const char *item;
|
||||
GHashTable *alive_connections;
|
||||
GHashTableIter iter;
|
||||
NMSKeyfileConnection *connection;
|
||||
|
|
@ -426,25 +463,13 @@ read_connections (NMSettingsPlugin *config)
|
|||
GPtrArray *filenames;
|
||||
GHashTable *paths;
|
||||
|
||||
dir = g_dir_open (nms_keyfile_utils_get_path (), 0, &error);
|
||||
if (!dir) {
|
||||
_LOGW ("cannot read directory '%s': %s",
|
||||
nms_keyfile_utils_get_path (),
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
filenames = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
_read_dir (filenames, NM_CONFIG_KEYFILE_PATH_IN_MEMORY);
|
||||
_read_dir (filenames, nms_keyfile_utils_get_path ());
|
||||
|
||||
alive_connections = g_hash_table_new (nm_direct_hash, NULL);
|
||||
|
||||
filenames = g_ptr_array_new_with_free_func (g_free);
|
||||
while ((item = g_dir_read_name (dir))) {
|
||||
if (nms_keyfile_utils_should_ignore_file (item))
|
||||
continue;
|
||||
g_ptr_array_add (filenames, g_build_filename (nms_keyfile_utils_get_path (), item, NULL));
|
||||
}
|
||||
g_dir_close (dir);
|
||||
|
||||
/* While reloading, we don't replace connections that we already loaded while
|
||||
* iterating over the files.
|
||||
*
|
||||
|
|
@ -501,14 +526,8 @@ load_connection (NMSettingsPlugin *config,
|
|||
{
|
||||
NMSKeyfilePlugin *self = NMS_KEYFILE_PLUGIN ((NMSKeyfilePlugin *) config);
|
||||
NMSKeyfileConnection *connection;
|
||||
int dir_len = strlen (nms_keyfile_utils_get_path ());
|
||||
|
||||
if ( strncmp (filename, nms_keyfile_utils_get_path (), dir_len) != 0
|
||||
|| filename[dir_len] != '/'
|
||||
|| strchr (filename + dir_len + 1, '/') != NULL)
|
||||
return FALSE;
|
||||
|
||||
if (nms_keyfile_utils_should_ignore_file (filename + dir_len + 1))
|
||||
if (nms_keyfile_utils_should_ignore_file (filename))
|
||||
return FALSE;
|
||||
|
||||
connection = update_connection (self, NULL, filename, find_by_path (self, filename), TRUE, NULL, NULL);
|
||||
|
|
@ -532,16 +551,16 @@ add_connection (NMSettingsPlugin *config,
|
|||
gs_free char *path = NULL;
|
||||
gs_unref_object NMConnection *reread = NULL;
|
||||
|
||||
if (save_to_disk) {
|
||||
if (!nms_keyfile_writer_connection (connection,
|
||||
NULL,
|
||||
FALSE,
|
||||
&path,
|
||||
&reread,
|
||||
NULL,
|
||||
error))
|
||||
return NULL;
|
||||
}
|
||||
if (!nms_keyfile_writer_connection (connection,
|
||||
save_to_disk,
|
||||
NULL,
|
||||
FALSE,
|
||||
&path,
|
||||
&reread,
|
||||
NULL,
|
||||
error))
|
||||
return NULL;
|
||||
|
||||
return NM_SETTINGS_CONNECTION (update_connection (self, reread ?: connection, path, NULL, FALSE, NULL, error));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
#define NM_CONFIG_KEYFILE_PATH_IN_MEMORY NMRUNDIR "/system-connections"
|
||||
|
||||
#define NMS_KEYFILE_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory")
|
||||
#define NMS_KEYFILE_CONNECTION_LOG_FMT "%s (%s,\"%s\")"
|
||||
#define NMS_KEYFILE_CONNECTION_LOG_ARG(con) NMS_KEYFILE_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_settings_connection_get_uuid ((NMSettingsConnection *) (con)), nm_settings_connection_get_id ((NMSettingsConnection *) (con))
|
||||
|
|
|
|||
|
|
@ -189,10 +189,14 @@ _internal_write_connection (NMConnection *connection,
|
|||
WriteInfo info = { 0 };
|
||||
GError *local_err = NULL;
|
||||
int errsv;
|
||||
gboolean rename = force_rename;
|
||||
|
||||
g_return_val_if_fail (!out_path || !*out_path, FALSE);
|
||||
g_return_val_if_fail (keyfile_dir && keyfile_dir[0] == '/', FALSE);
|
||||
|
||||
if (existing_path && !g_str_has_prefix (existing_path, keyfile_dir))
|
||||
rename = TRUE;
|
||||
|
||||
switch (_nm_connection_verify (connection, error)) {
|
||||
case NM_SETTING_VERIFY_NORMALIZABLE:
|
||||
nm_assert_not_reached ();
|
||||
|
|
@ -221,7 +225,7 @@ _internal_write_connection (NMConnection *connection,
|
|||
/* If we have existing file path, use it. Else generate one from
|
||||
* connection's ID.
|
||||
*/
|
||||
if (existing_path != NULL && !force_rename) {
|
||||
if (existing_path != NULL && !rename) {
|
||||
path = g_strdup (existing_path);
|
||||
} else {
|
||||
char *filename_escaped = nms_keyfile_utils_escape_filename (id);
|
||||
|
|
@ -337,6 +341,7 @@ _internal_write_connection (NMConnection *connection,
|
|||
|
||||
gboolean
|
||||
nms_keyfile_writer_connection (NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
const char *existing_path,
|
||||
gboolean force_rename,
|
||||
char **out_path,
|
||||
|
|
@ -344,8 +349,15 @@ nms_keyfile_writer_connection (NMConnection *connection,
|
|||
gboolean *out_reread_same,
|
||||
GError **error)
|
||||
{
|
||||
const char *keyfile_dir;
|
||||
|
||||
if (save_to_disk)
|
||||
keyfile_dir = nms_keyfile_utils_get_path ();
|
||||
else
|
||||
keyfile_dir = NM_CONFIG_KEYFILE_PATH_IN_MEMORY;
|
||||
|
||||
return _internal_write_connection (connection,
|
||||
nms_keyfile_utils_get_path (),
|
||||
keyfile_dir,
|
||||
0, 0,
|
||||
existing_path,
|
||||
force_rename,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "nm-connection.h"
|
||||
|
||||
gboolean nms_keyfile_writer_connection (NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
const char *existing_path,
|
||||
gboolean force_rename,
|
||||
char **out_path,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue