settings: support storing "shadowed-storage" to [.nmmeta] section for keyfiles in /run
When we make runtime only changes, we may leave the profile in persistent storage and store a overlay profile in /run. However, in various cases we need to remember the original path. Add code to store and retrieve that path from the keyfile. Note that this data is written inside the keyfile in /run. That is because this piece of information really depends on that particular keyfile, and not on the profile/UUID. That is why we write it to the [.nmmeta] section of the keyfile and not to the .nmmeta file (which is per-UUID). This patch only adds the backend to write and load the setting from disk. It's not yet used.
This commit is contained in:
@@ -174,6 +174,8 @@ gboolean _nm_keyfile_has_values (GKeyFile *keyfile);
|
|||||||
#define NM_KEYFILE_GROUP_NMMETA ".nmmeta"
|
#define NM_KEYFILE_GROUP_NMMETA ".nmmeta"
|
||||||
#define NM_KEYFILE_KEY_NMMETA_NM_GENERATED "nm-generated"
|
#define NM_KEYFILE_KEY_NMMETA_NM_GENERATED "nm-generated"
|
||||||
#define NM_KEYFILE_KEY_NMMETA_VOLATILE "volatile"
|
#define NM_KEYFILE_KEY_NMMETA_VOLATILE "volatile"
|
||||||
|
#define NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE "shadowed-storage"
|
||||||
|
#define NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED "shadowed-owned"
|
||||||
|
|
||||||
#define NM_KEYFILE_PATH_NAME_LIB NMLIBDIR "/system-connections"
|
#define NM_KEYFILE_PATH_NAME_LIB NMLIBDIR "/system-connections"
|
||||||
#define NM_KEYFILE_PATH_NAME_ETC_DEFAULT NMCONFDIR "/system-connections"
|
#define NM_KEYFILE_PATH_NAME_ETC_DEFAULT NMCONFDIR "/system-connections"
|
||||||
|
@@ -1284,6 +1284,8 @@ _add_connection_to_first_plugin (NMSettings *self,
|
|||||||
gboolean in_memory,
|
gboolean in_memory,
|
||||||
gboolean is_nm_generated,
|
gboolean is_nm_generated,
|
||||||
gboolean is_volatile,
|
gboolean is_volatile,
|
||||||
|
const char *shadowed_storage,
|
||||||
|
gboolean shadowed_owned,
|
||||||
NMSettingsStorage **out_new_storage,
|
NMSettingsStorage **out_new_storage,
|
||||||
NMConnection **out_new_connection,
|
NMConnection **out_new_connection,
|
||||||
GError **error)
|
GError **error)
|
||||||
@@ -1311,9 +1313,11 @@ _add_connection_to_first_plugin (NMSettings *self,
|
|||||||
if (plugin == (NMSettingsPlugin *) priv->keyfile_plugin) {
|
if (plugin == (NMSettingsPlugin *) priv->keyfile_plugin) {
|
||||||
success = nms_keyfile_plugin_add_connection (priv->keyfile_plugin,
|
success = nms_keyfile_plugin_add_connection (priv->keyfile_plugin,
|
||||||
new_connection,
|
new_connection,
|
||||||
|
in_memory,
|
||||||
is_nm_generated,
|
is_nm_generated,
|
||||||
is_volatile,
|
is_volatile,
|
||||||
in_memory,
|
shadowed_storage,
|
||||||
|
shadowed_owned,
|
||||||
&storage,
|
&storage,
|
||||||
&connection_to_add,
|
&connection_to_add,
|
||||||
&add_error);
|
&add_error);
|
||||||
@@ -1457,6 +1461,8 @@ nm_settings_add_connection (NMSettings *self,
|
|||||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)),
|
| NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)),
|
||||||
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED),
|
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED),
|
||||||
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE),
|
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE),
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
&new_storage,
|
&new_storage,
|
||||||
&new_connection,
|
&new_connection,
|
||||||
&local)) {
|
&local)) {
|
||||||
@@ -1538,6 +1544,8 @@ nm_settings_update_connection (NMSettings *self,
|
|||||||
gboolean cur_in_memory;
|
gboolean cur_in_memory;
|
||||||
gboolean new_in_memory;
|
gboolean new_in_memory;
|
||||||
const char *uuid;
|
const char *uuid;
|
||||||
|
const char *shadowed_storage;
|
||||||
|
gboolean shadowed_owned;
|
||||||
|
|
||||||
g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
|
g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
|
||||||
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn), FALSE);
|
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn), FALSE);
|
||||||
@@ -1659,6 +1667,9 @@ nm_settings_update_connection (NMSettings *self,
|
|||||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE);
|
| NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: set and handle shadowed-storages. */
|
||||||
|
shadowed_storage = NULL;
|
||||||
|
shadowed_owned = FALSE;
|
||||||
|
|
||||||
if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST) {
|
if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST) {
|
||||||
new_storage = g_object_ref (cur_storage);
|
new_storage = g_object_ref (cur_storage);
|
||||||
@@ -1688,6 +1699,8 @@ nm_settings_update_connection (NMSettings *self,
|
|||||||
new_in_memory,
|
new_in_memory,
|
||||||
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED),
|
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED),
|
||||||
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE),
|
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE),
|
||||||
|
shadowed_storage,
|
||||||
|
shadowed_owned,
|
||||||
&new_storage,
|
&new_storage,
|
||||||
&new_connection,
|
&new_connection,
|
||||||
&local);
|
&local);
|
||||||
@@ -1701,6 +1714,8 @@ nm_settings_update_connection (NMSettings *self,
|
|||||||
connection,
|
connection,
|
||||||
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED),
|
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED),
|
||||||
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE),
|
NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE),
|
||||||
|
shadowed_storage,
|
||||||
|
shadowed_owned,
|
||||||
NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_FORCE_RENAME),
|
NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_FORCE_RENAME),
|
||||||
&new_storage,
|
&new_storage,
|
||||||
&new_connection,
|
&new_connection,
|
||||||
|
@@ -216,13 +216,22 @@ _read_from_file (const char *full_filename,
|
|||||||
struct stat *out_stat,
|
struct stat *out_stat,
|
||||||
NMTernary *out_is_nm_generated,
|
NMTernary *out_is_nm_generated,
|
||||||
NMTernary *out_is_volatile,
|
NMTernary *out_is_volatile,
|
||||||
|
char **out_shadowed_storage,
|
||||||
|
NMTernary *out_shadowed_owned,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
|
|
||||||
nm_assert (full_filename && full_filename[0] == '/');
|
nm_assert (full_filename && full_filename[0] == '/');
|
||||||
|
|
||||||
connection = nms_keyfile_reader_from_file (full_filename, plugin_dir, out_stat, out_is_nm_generated, out_is_volatile, error);
|
connection = nms_keyfile_reader_from_file (full_filename,
|
||||||
|
plugin_dir,
|
||||||
|
out_stat,
|
||||||
|
out_is_nm_generated,
|
||||||
|
out_is_volatile,
|
||||||
|
out_shadowed_storage,
|
||||||
|
out_shadowed_owned,
|
||||||
|
error);
|
||||||
|
|
||||||
nm_assert (!connection || (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS));
|
nm_assert (!connection || (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS));
|
||||||
nm_assert (!connection || nm_utils_is_uuid (nm_connection_get_uuid (connection)));
|
nm_assert (!connection || nm_utils_is_uuid (nm_connection_get_uuid (connection)));
|
||||||
@@ -291,6 +300,8 @@ _load_file (NMSKeyfilePlugin *self,
|
|||||||
gs_unref_object NMConnection *connection = NULL;
|
gs_unref_object NMConnection *connection = NULL;
|
||||||
NMTernary is_volatile_opt;
|
NMTernary is_volatile_opt;
|
||||||
NMTernary is_nm_generated_opt;
|
NMTernary is_nm_generated_opt;
|
||||||
|
NMTernary shadowed_owned_opt;
|
||||||
|
gs_free char *shadowed_storage = NULL;
|
||||||
gs_free_error GError *local = NULL;
|
gs_free_error GError *local = NULL;
|
||||||
gs_free char *full_filename = NULL;
|
gs_free char *full_filename = NULL;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@@ -350,6 +361,8 @@ _load_file (NMSKeyfilePlugin *self,
|
|||||||
&st,
|
&st,
|
||||||
&is_nm_generated_opt,
|
&is_nm_generated_opt,
|
||||||
&is_volatile_opt,
|
&is_volatile_opt,
|
||||||
|
&shadowed_storage,
|
||||||
|
&shadowed_owned_opt,
|
||||||
&local);
|
&local);
|
||||||
if (!connection) {
|
if (!connection) {
|
||||||
if (error)
|
if (error)
|
||||||
@@ -365,6 +378,8 @@ _load_file (NMSKeyfilePlugin *self,
|
|||||||
storage_type,
|
storage_type,
|
||||||
is_nm_generated_opt,
|
is_nm_generated_opt,
|
||||||
is_volatile_opt,
|
is_volatile_opt,
|
||||||
|
shadowed_storage,
|
||||||
|
shadowed_owned_opt,
|
||||||
&st.st_mtim);
|
&st.st_mtim);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,9 +740,11 @@ load_connections (NMSettingsPlugin *plugin,
|
|||||||
gboolean
|
gboolean
|
||||||
nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
|
nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
|
||||||
NMConnection *connection,
|
NMConnection *connection,
|
||||||
|
gboolean in_memory,
|
||||||
gboolean is_nm_generated,
|
gboolean is_nm_generated,
|
||||||
gboolean is_volatile,
|
gboolean is_volatile,
|
||||||
gboolean in_memory,
|
const char *shadowed_storage,
|
||||||
|
gboolean shadowed_owned,
|
||||||
NMSettingsStorage **out_storage,
|
NMSettingsStorage **out_storage,
|
||||||
NMConnection **out_connection,
|
NMConnection **out_connection,
|
||||||
GError **error)
|
GError **error)
|
||||||
@@ -747,8 +764,16 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
|
|||||||
nm_assert (out_storage && !*out_storage);
|
nm_assert (out_storage && !*out_storage);
|
||||||
nm_assert (out_connection && !*out_connection);
|
nm_assert (out_connection && !*out_connection);
|
||||||
|
|
||||||
|
nm_assert ( in_memory
|
||||||
|
|| ( !is_nm_generated
|
||||||
|
&& !is_volatile
|
||||||
|
&& !shadowed_storage
|
||||||
|
&& !shadowed_owned));
|
||||||
|
|
||||||
uuid = nm_connection_get_uuid (connection);
|
uuid = nm_connection_get_uuid (connection);
|
||||||
|
|
||||||
|
/* Note that even if the caller requests persistent storage, we may switch to in-memory, if
|
||||||
|
* no /etc directory is configured. */
|
||||||
storage_type = !in_memory && priv->dirname_etc
|
storage_type = !in_memory && priv->dirname_etc
|
||||||
? NMS_KEYFILE_STORAGE_TYPE_ETC
|
? NMS_KEYFILE_STORAGE_TYPE_ETC
|
||||||
: NMS_KEYFILE_STORAGE_TYPE_RUN;
|
: NMS_KEYFILE_STORAGE_TYPE_RUN;
|
||||||
@@ -756,6 +781,8 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
|
|||||||
if (!nms_keyfile_writer_connection (connection,
|
if (!nms_keyfile_writer_connection (connection,
|
||||||
is_nm_generated,
|
is_nm_generated,
|
||||||
is_volatile,
|
is_volatile,
|
||||||
|
shadowed_storage,
|
||||||
|
shadowed_owned,
|
||||||
storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC
|
storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC
|
||||||
? priv->dirname_etc
|
? priv->dirname_etc
|
||||||
: priv->dirname_run,
|
: priv->dirname_run,
|
||||||
@@ -787,11 +814,12 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
|
|||||||
nm_assert (full_filename && full_filename[0] == '/');
|
nm_assert (full_filename && full_filename[0] == '/');
|
||||||
nm_assert (!nm_sett_util_storages_lookup_by_filename (&priv->storages, full_filename));
|
nm_assert (!nm_sett_util_storages_lookup_by_filename (&priv->storages, full_filename));
|
||||||
|
|
||||||
_LOGT ("commit: %s (%s) added as \"%s\"%s",
|
_LOGT ("commit: %s (%s) added as \"%s\"%s%s%s%s",
|
||||||
uuid,
|
uuid,
|
||||||
nm_connection_get_id (connection),
|
nm_connection_get_id (connection),
|
||||||
full_filename,
|
full_filename,
|
||||||
_extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile));
|
_extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile),
|
||||||
|
NM_PRINT_FMT_QUOTED (shadowed_storage, " (shadows \"", shadowed_storage, shadowed_owned ? "\", owned)" : "\")", ""));
|
||||||
|
|
||||||
storage = nms_keyfile_storage_new_connection (self,
|
storage = nms_keyfile_storage_new_connection (self,
|
||||||
g_steal_pointer (&reread),
|
g_steal_pointer (&reread),
|
||||||
@@ -799,6 +827,8 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
|
|||||||
storage_type,
|
storage_type,
|
||||||
is_nm_generated ? NM_TERNARY_TRUE : NM_TERNARY_FALSE,
|
is_nm_generated ? NM_TERNARY_TRUE : NM_TERNARY_FALSE,
|
||||||
is_volatile ? NM_TERNARY_TRUE : NM_TERNARY_FALSE,
|
is_volatile ? NM_TERNARY_TRUE : NM_TERNARY_FALSE,
|
||||||
|
shadowed_storage,
|
||||||
|
shadowed_owned ? NM_TERNARY_TRUE : NM_TERNARY_FALSE,
|
||||||
nm_sett_util_stat_mtime (full_filename, FALSE, &mtime));
|
nm_sett_util_stat_mtime (full_filename, FALSE, &mtime));
|
||||||
|
|
||||||
nm_sett_util_storages_add_take (&priv->storages, g_object_ref (storage));
|
nm_sett_util_storages_add_take (&priv->storages, g_object_ref (storage));
|
||||||
@@ -821,6 +851,8 @@ add_connection (NMSettingsPlugin *plugin,
|
|||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
out_storage,
|
out_storage,
|
||||||
out_connection,
|
out_connection,
|
||||||
error);
|
error);
|
||||||
@@ -832,6 +864,8 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
|
|||||||
NMConnection *connection,
|
NMConnection *connection,
|
||||||
gboolean is_nm_generated,
|
gboolean is_nm_generated,
|
||||||
gboolean is_volatile,
|
gboolean is_volatile,
|
||||||
|
const char *shadowed_storage,
|
||||||
|
gboolean shadowed_owned,
|
||||||
gboolean force_rename,
|
gboolean force_rename,
|
||||||
NMSettingsStorage **out_storage,
|
NMSettingsStorage **out_storage,
|
||||||
NMConnection **out_connection,
|
NMConnection **out_connection,
|
||||||
@@ -847,6 +881,7 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
|
|||||||
const char *previous_filename;
|
const char *previous_filename;
|
||||||
gboolean reread_same;
|
gboolean reread_same;
|
||||||
const char *uuid;
|
const char *uuid;
|
||||||
|
char strbuf[100];
|
||||||
|
|
||||||
_nm_assert_storage (self, storage, TRUE);
|
_nm_assert_storage (self, storage, TRUE);
|
||||||
nm_assert (NM_IS_CONNECTION (connection));
|
nm_assert (NM_IS_CONNECTION (connection));
|
||||||
@@ -855,11 +890,15 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
|
|||||||
nm_assert (!error || !*error);
|
nm_assert (!error || !*error);
|
||||||
nm_assert (NM_IN_SET (storage->storage_type, NMS_KEYFILE_STORAGE_TYPE_ETC,
|
nm_assert (NM_IN_SET (storage->storage_type, NMS_KEYFILE_STORAGE_TYPE_ETC,
|
||||||
NMS_KEYFILE_STORAGE_TYPE_RUN));
|
NMS_KEYFILE_STORAGE_TYPE_RUN));
|
||||||
nm_assert ( (!is_nm_generated && !is_volatile)
|
nm_assert (!storage->is_meta_data);
|
||||||
|| storage->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN);
|
nm_assert ( storage->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN
|
||||||
|
|| ( !is_nm_generated
|
||||||
|
&& !is_volatile
|
||||||
|
&& !shadowed_storage
|
||||||
|
&& !shadowed_owned));
|
||||||
|
nm_assert (!shadowed_owned || shadowed_storage);
|
||||||
nm_assert ( priv->dirname_etc
|
nm_assert ( priv->dirname_etc
|
||||||
|| storage->storage_type != NMS_KEYFILE_STORAGE_TYPE_ETC);
|
|| storage->storage_type != NMS_KEYFILE_STORAGE_TYPE_ETC);
|
||||||
nm_assert (!storage->is_meta_data);
|
|
||||||
|
|
||||||
previous_filename = nms_keyfile_storage_get_filename (storage);
|
previous_filename = nms_keyfile_storage_get_filename (storage);
|
||||||
uuid = nms_keyfile_storage_get_uuid (storage);
|
uuid = nms_keyfile_storage_get_uuid (storage);
|
||||||
@@ -867,6 +906,8 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
|
|||||||
if (!nms_keyfile_writer_connection (connection,
|
if (!nms_keyfile_writer_connection (connection,
|
||||||
is_nm_generated,
|
is_nm_generated,
|
||||||
is_volatile,
|
is_volatile,
|
||||||
|
shadowed_storage,
|
||||||
|
shadowed_owned,
|
||||||
storage->storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC
|
storage->storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC
|
||||||
? priv->dirname_etc
|
? priv->dirname_etc
|
||||||
: priv->dirname_run,
|
: priv->dirname_run,
|
||||||
@@ -899,14 +940,17 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
|
|||||||
nm_assert (_nm_connection_verify (reread, NULL) == NM_SETTING_VERIFY_SUCCESS);
|
nm_assert (_nm_connection_verify (reread, NULL) == NM_SETTING_VERIFY_SUCCESS);
|
||||||
nm_assert (nm_streq (nm_connection_get_uuid (reread), uuid));
|
nm_assert (nm_streq (nm_connection_get_uuid (reread), uuid));
|
||||||
|
|
||||||
_LOGT ("commit: \"%s\": profile %s (%s) written",
|
_LOGT ("commit: \"%s\": profile %s (%s) written%s%s%s%s",
|
||||||
full_filename,
|
full_filename,
|
||||||
uuid,
|
uuid,
|
||||||
nm_connection_get_id (connection));
|
nm_connection_get_id (connection),
|
||||||
|
_extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile),
|
||||||
|
NM_PRINT_FMT_QUOTED (shadowed_storage, shadowed_owned ? " (owns \"" : " (shadows \"", shadowed_storage, "\")", ""));
|
||||||
|
|
||||||
storage->u.conn_data.is_nm_generated = is_nm_generated;
|
storage->u.conn_data.is_nm_generated = is_nm_generated;
|
||||||
storage->u.conn_data.is_volatile = is_volatile;
|
storage->u.conn_data.is_volatile = is_volatile;
|
||||||
storage->u.conn_data.stat_mtime = *nm_sett_util_stat_mtime (full_filename, FALSE, &mtime);
|
storage->u.conn_data.stat_mtime = *nm_sett_util_stat_mtime (full_filename, FALSE, &mtime);
|
||||||
|
storage->u.conn_data.shadowed_owned = shadowed_owned;
|
||||||
|
|
||||||
*out_storage = g_object_ref (NM_SETTINGS_STORAGE (storage));
|
*out_storage = g_object_ref (NM_SETTINGS_STORAGE (storage));
|
||||||
*out_connection = g_steal_pointer (&reread);
|
*out_connection = g_steal_pointer (&reread);
|
||||||
@@ -926,6 +970,8 @@ update_connection (NMSettingsPlugin *plugin,
|
|||||||
connection,
|
connection,
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
out_storage,
|
out_storage,
|
||||||
out_connection,
|
out_connection,
|
||||||
|
@@ -42,9 +42,11 @@ NMSKeyfilePlugin *nms_keyfile_plugin_new (void);
|
|||||||
|
|
||||||
gboolean nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
|
gboolean nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
|
||||||
NMConnection *connection,
|
NMConnection *connection,
|
||||||
|
gboolean in_memory,
|
||||||
gboolean is_nm_generated,
|
gboolean is_nm_generated,
|
||||||
gboolean is_volatile,
|
gboolean is_volatile,
|
||||||
gboolean in_memory,
|
const char *shadowed_storage,
|
||||||
|
gboolean shadowed_owned,
|
||||||
NMSettingsStorage **out_storage,
|
NMSettingsStorage **out_storage,
|
||||||
NMConnection **out_connection,
|
NMConnection **out_connection,
|
||||||
GError **error);
|
GError **error);
|
||||||
@@ -54,6 +56,8 @@ gboolean nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
|
|||||||
NMConnection *connection,
|
NMConnection *connection,
|
||||||
gboolean is_nm_generated,
|
gboolean is_nm_generated,
|
||||||
gboolean is_volatile,
|
gboolean is_volatile,
|
||||||
|
const char *shadowed_storage,
|
||||||
|
gboolean shadowed_owned,
|
||||||
gboolean force_rename,
|
gboolean force_rename,
|
||||||
NMSettingsStorage **out_storage,
|
NMSettingsStorage **out_storage,
|
||||||
NMConnection **out_connection,
|
NMConnection **out_connection,
|
||||||
|
@@ -164,6 +164,8 @@ nms_keyfile_reader_from_file (const char *full_filename,
|
|||||||
struct stat *out_stat,
|
struct stat *out_stat,
|
||||||
NMTernary *out_is_nm_generated,
|
NMTernary *out_is_nm_generated,
|
||||||
NMTernary *out_is_volatile,
|
NMTernary *out_is_volatile,
|
||||||
|
char **out_shadowed_storage,
|
||||||
|
NMTernary *out_shadowed_owned,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gs_unref_keyfile GKeyFile *key_file = NULL;
|
gs_unref_keyfile GKeyFile *key_file = NULL;
|
||||||
@@ -210,6 +212,16 @@ nms_keyfile_reader_from_file (const char *full_filename,
|
|||||||
NM_KEYFILE_KEY_NMMETA_VOLATILE,
|
NM_KEYFILE_KEY_NMMETA_VOLATILE,
|
||||||
NM_TERNARY_DEFAULT));
|
NM_TERNARY_DEFAULT));
|
||||||
|
|
||||||
|
NM_SET_OUT (out_shadowed_storage, g_key_file_get_string (key_file,
|
||||||
|
NM_KEYFILE_GROUP_NMMETA,
|
||||||
|
NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE,
|
||||||
|
NULL));
|
||||||
|
|
||||||
|
NM_SET_OUT (out_shadowed_owned, nm_key_file_get_boolean (key_file,
|
||||||
|
NM_KEYFILE_GROUP_NMMETA,
|
||||||
|
NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED,
|
||||||
|
NM_TERNARY_DEFAULT));
|
||||||
|
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -37,6 +37,8 @@ NMConnection *nms_keyfile_reader_from_file (const char *full_filename,
|
|||||||
struct stat *out_stat,
|
struct stat *out_stat,
|
||||||
NMTernary *out_is_nm_generated,
|
NMTernary *out_is_nm_generated,
|
||||||
NMTernary *out_is_volatile,
|
NMTernary *out_is_volatile,
|
||||||
|
char **out_shadowed_storage,
|
||||||
|
NMTernary *out_shadowed_owned,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
#endif /* __NMS_KEYFILE_READER_H__ */
|
#endif /* __NMS_KEYFILE_READER_H__ */
|
||||||
|
@@ -50,10 +50,13 @@ nms_keyfile_storage_copy_content (NMSKeyfileStorage *dst,
|
|||||||
dst->u.meta_data = src->u.meta_data;
|
dst->u.meta_data = src->u.meta_data;
|
||||||
else {
|
else {
|
||||||
gs_unref_object NMConnection *connection_to_free = NULL;
|
gs_unref_object NMConnection *connection_to_free = NULL;
|
||||||
|
gs_free char *shadowed_storage_to_free = NULL;
|
||||||
|
|
||||||
connection_to_free = g_steal_pointer (&dst->u.conn_data.connection);
|
connection_to_free = g_steal_pointer (&dst->u.conn_data.connection);
|
||||||
|
shadowed_storage_to_free = g_steal_pointer (&dst->u.conn_data.shadowed_storage);
|
||||||
dst->u.conn_data = src->u.conn_data;
|
dst->u.conn_data = src->u.conn_data;
|
||||||
nm_g_object_ref (dst->u.conn_data.connection);
|
nm_g_object_ref (dst->u.conn_data.connection);
|
||||||
|
dst->u.conn_data.shadowed_storage = g_strdup (dst->u.conn_data.shadowed_storage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,6 +162,8 @@ nms_keyfile_storage_new_connection (NMSKeyfilePlugin *plugin,
|
|||||||
NMSKeyfileStorageType storage_type,
|
NMSKeyfileStorageType storage_type,
|
||||||
NMTernary is_nm_generated_opt,
|
NMTernary is_nm_generated_opt,
|
||||||
NMTernary is_volatile_opt,
|
NMTernary is_volatile_opt,
|
||||||
|
const char *shadowed_storage,
|
||||||
|
NMTernary shadowed_owned_opt,
|
||||||
const struct timespec *stat_mtime)
|
const struct timespec *stat_mtime)
|
||||||
{
|
{
|
||||||
NMSKeyfileStorage *self;
|
NMSKeyfileStorage *self;
|
||||||
@@ -175,12 +180,16 @@ nms_keyfile_storage_new_connection (NMSKeyfilePlugin *plugin,
|
|||||||
|
|
||||||
self->u.conn_data.connection = connection_take; /* take reference. */
|
self->u.conn_data.connection = connection_take; /* take reference. */
|
||||||
|
|
||||||
|
self->u.conn_data.shadowed_storage = g_strdup (shadowed_storage);
|
||||||
|
|
||||||
if (stat_mtime)
|
if (stat_mtime)
|
||||||
self->u.conn_data.stat_mtime = *stat_mtime;
|
self->u.conn_data.stat_mtime = *stat_mtime;
|
||||||
|
|
||||||
if (storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) {
|
if (storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) {
|
||||||
self->u.conn_data.is_nm_generated = (is_nm_generated_opt == NM_TERNARY_TRUE);
|
self->u.conn_data.is_nm_generated = (is_nm_generated_opt == NM_TERNARY_TRUE);
|
||||||
self->u.conn_data.is_volatile = (is_volatile_opt == NM_TERNARY_TRUE);
|
self->u.conn_data.is_volatile = (is_volatile_opt == NM_TERNARY_TRUE);
|
||||||
|
self->u.conn_data.shadowed_owned = shadowed_storage
|
||||||
|
&& (shadowed_owned_opt == NM_TERNARY_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -191,8 +200,11 @@ _storage_clear (NMSKeyfileStorage *self)
|
|||||||
{
|
{
|
||||||
c_list_unlink (&self->parent._storage_lst);
|
c_list_unlink (&self->parent._storage_lst);
|
||||||
c_list_unlink (&self->parent._storage_by_uuid_lst);
|
c_list_unlink (&self->parent._storage_by_uuid_lst);
|
||||||
if (!self->is_meta_data)
|
if (!self->is_meta_data) {
|
||||||
g_clear_object (&self->u.conn_data.connection);
|
g_clear_object (&self->u.conn_data.connection);
|
||||||
|
nm_clear_g_free (&self->u.conn_data.shadowed_storage);
|
||||||
|
self->u.conn_data.shadowed_owned = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -51,6 +51,19 @@ typedef struct {
|
|||||||
struct {
|
struct {
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
|
|
||||||
|
/* when we move a profile from permanent storage to unsaved (/run), then
|
||||||
|
* we may leave the profile on disk (depending on options for Update2()).
|
||||||
|
*
|
||||||
|
* Later, when we save the profile again to disk, we want to re-use that filename.
|
||||||
|
* Likewise, we delete the (now in-memory) profile, we may want to also delete
|
||||||
|
* the original filename.
|
||||||
|
*
|
||||||
|
* This is the original filename, and we store it inside [.nmmeta] in the
|
||||||
|
* keyfile in /run. Note that we don't store this in the .nmmeta file, because
|
||||||
|
* the information is tied to the particular keyfile in /run, not to all UUIDs
|
||||||
|
* in general. */
|
||||||
|
char *shadowed_storage;
|
||||||
|
|
||||||
/* the timestamp (stat's mtime) of the keyfile. For meta-data this
|
/* the timestamp (stat's mtime) of the keyfile. For meta-data this
|
||||||
* is irrelevant. The purpose is that if the same storage type (directory) has
|
* is irrelevant. The purpose is that if the same storage type (directory) has
|
||||||
* multiple files with the same UUID, then the newer file gets preferred. */
|
* multiple files with the same UUID, then the newer file gets preferred. */
|
||||||
@@ -66,6 +79,11 @@ typedef struct {
|
|||||||
bool is_nm_generated:1;
|
bool is_nm_generated:1;
|
||||||
bool is_volatile:1;
|
bool is_volatile:1;
|
||||||
|
|
||||||
|
/* if shadowed_storage is set, then this flag indicates whether the file
|
||||||
|
* is owned. The difference comes into play when deleting the in-memory,
|
||||||
|
* shadowing profile: a owned profile will also be deleted. */
|
||||||
|
bool shadowed_owned:1;
|
||||||
|
|
||||||
} conn_data;
|
} conn_data;
|
||||||
|
|
||||||
/* the content from the .nmmeta file. Note that the nmmeta file has the UUID
|
/* the content from the .nmmeta file. Note that the nmmeta file has the UUID
|
||||||
@@ -106,6 +124,8 @@ NMSKeyfileStorage *nms_keyfile_storage_new_connection (struct _NMSKeyfilePlugin
|
|||||||
NMSKeyfileStorageType storage_type,
|
NMSKeyfileStorageType storage_type,
|
||||||
NMTernary is_nm_generated_opt,
|
NMTernary is_nm_generated_opt,
|
||||||
NMTernary is_volatile_opt,
|
NMTernary is_volatile_opt,
|
||||||
|
const char *shadowed_storage,
|
||||||
|
NMTernary shadowed_owned_opt,
|
||||||
const struct timespec *stat_mtime);
|
const struct timespec *stat_mtime);
|
||||||
|
|
||||||
void nms_keyfile_storage_destroy (NMSKeyfileStorage *storage);
|
void nms_keyfile_storage_destroy (NMSKeyfileStorage *storage);
|
||||||
@@ -188,6 +208,46 @@ nm_settings_storage_is_meta_data_alive (const NMSettingsStorage *storage)
|
|||||||
return meta_data;
|
return meta_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char *
|
||||||
|
nm_settings_storage_get_shadowed_storage (const NMSettingsStorage *storage,
|
||||||
|
gboolean *out_shadowed_owned)
|
||||||
|
{
|
||||||
|
if (NMS_IS_KEYFILE_STORAGE (storage)) {
|
||||||
|
const NMSKeyfileStorage *self = (const NMSKeyfileStorage *) storage;
|
||||||
|
|
||||||
|
if (self->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) {
|
||||||
|
if (!self->is_meta_data) {
|
||||||
|
if (self->u.conn_data.shadowed_storage) {
|
||||||
|
NM_SET_OUT (out_shadowed_owned, self->u.conn_data.shadowed_owned);
|
||||||
|
return self->u.conn_data.shadowed_storage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NM_SET_OUT (out_shadowed_owned, FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const char *
|
||||||
|
nm_settings_storage_get_filename_for_shadowed_storage (const NMSettingsStorage *storage)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (storage), NULL);
|
||||||
|
|
||||||
|
if (!storage->_filename)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (NMS_IS_KEYFILE_STORAGE (storage)) {
|
||||||
|
const NMSKeyfileStorage *self = (const NMSKeyfileStorage *) storage;
|
||||||
|
|
||||||
|
if ( self->is_meta_data
|
||||||
|
|| self->storage_type != NMS_KEYFILE_STORAGE_TYPE_ETC)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return storage->_filename;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
enum _NMSettingsConnectionIntFlags;
|
enum _NMSettingsConnectionIntFlags;
|
||||||
|
@@ -170,6 +170,8 @@ static gboolean
|
|||||||
_internal_write_connection (NMConnection *connection,
|
_internal_write_connection (NMConnection *connection,
|
||||||
gboolean is_nm_generated,
|
gboolean is_nm_generated,
|
||||||
gboolean is_volatile,
|
gboolean is_volatile,
|
||||||
|
const char *shadowed_storage,
|
||||||
|
gboolean shadowed_owned,
|
||||||
const char *keyfile_dir,
|
const char *keyfile_dir,
|
||||||
const char *profile_dir,
|
const char *profile_dir,
|
||||||
gboolean with_extension,
|
gboolean with_extension,
|
||||||
@@ -201,6 +203,8 @@ _internal_write_connection (NMConnection *connection,
|
|||||||
|
|
||||||
nm_assert (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS);
|
nm_assert (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS);
|
||||||
|
|
||||||
|
nm_assert (!shadowed_owned || shadowed_storage);
|
||||||
|
|
||||||
rename = force_rename
|
rename = force_rename
|
||||||
|| existing_path_read_only
|
|| existing_path_read_only
|
||||||
|| ( existing_path
|
|| ( existing_path
|
||||||
@@ -229,6 +233,20 @@ _internal_write_connection (NMConnection *connection,
|
|||||||
TRUE);
|
TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shadowed_storage) {
|
||||||
|
g_key_file_set_string (kf_file,
|
||||||
|
NM_KEYFILE_GROUP_NMMETA,
|
||||||
|
NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE,
|
||||||
|
shadowed_storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shadowed_owned) {
|
||||||
|
g_key_file_set_boolean (kf_file,
|
||||||
|
NM_KEYFILE_GROUP_NMMETA,
|
||||||
|
NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
kf_content_buf = g_key_file_to_data (kf_file, &kf_content_len, error);
|
kf_content_buf = g_key_file_to_data (kf_file, &kf_content_len, error);
|
||||||
if (!kf_content_buf)
|
if (!kf_content_buf)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -356,6 +374,8 @@ gboolean
|
|||||||
nms_keyfile_writer_connection (NMConnection *connection,
|
nms_keyfile_writer_connection (NMConnection *connection,
|
||||||
gboolean is_nm_generated,
|
gboolean is_nm_generated,
|
||||||
gboolean is_volatile,
|
gboolean is_volatile,
|
||||||
|
const char *shadowed_storage,
|
||||||
|
gboolean shadowed_owned,
|
||||||
const char *keyfile_dir,
|
const char *keyfile_dir,
|
||||||
const char *profile_dir,
|
const char *profile_dir,
|
||||||
const char *existing_path,
|
const char *existing_path,
|
||||||
@@ -371,6 +391,8 @@ nms_keyfile_writer_connection (NMConnection *connection,
|
|||||||
return _internal_write_connection (connection,
|
return _internal_write_connection (connection,
|
||||||
is_nm_generated,
|
is_nm_generated,
|
||||||
is_volatile,
|
is_volatile,
|
||||||
|
shadowed_storage,
|
||||||
|
shadowed_owned,
|
||||||
keyfile_dir,
|
keyfile_dir,
|
||||||
profile_dir,
|
profile_dir,
|
||||||
TRUE,
|
TRUE,
|
||||||
@@ -400,6 +422,8 @@ nms_keyfile_writer_test_connection (NMConnection *connection,
|
|||||||
return _internal_write_connection (connection,
|
return _internal_write_connection (connection,
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
keyfile_dir,
|
keyfile_dir,
|
||||||
keyfile_dir,
|
keyfile_dir,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
@@ -29,6 +29,8 @@ typedef gboolean (*NMSKeyfileWriterAllowFilenameCb) (const char *check_filename,
|
|||||||
gboolean nms_keyfile_writer_connection (NMConnection *connection,
|
gboolean nms_keyfile_writer_connection (NMConnection *connection,
|
||||||
gboolean is_nm_generated,
|
gboolean is_nm_generated,
|
||||||
gboolean is_volatile,
|
gboolean is_volatile,
|
||||||
|
const char *shadowed_storage,
|
||||||
|
gboolean shadowed_owned,
|
||||||
const char *keyfile_dir,
|
const char *keyfile_dir,
|
||||||
const char *profile_dir,
|
const char *profile_dir,
|
||||||
const char *existing_path,
|
const char *existing_path,
|
||||||
|
@@ -75,6 +75,8 @@ check_ip_route (NMSettingIPConfig *config, int idx, const char *destination, int
|
|||||||
NULL, \
|
NULL, \
|
||||||
NULL, \
|
NULL, \
|
||||||
NULL, \
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
(nmtst_get_rand_uint32 () % 2) ? &_error : NULL); \
|
(nmtst_get_rand_uint32 () % 2) ? &_error : NULL); \
|
||||||
nmtst_assert_success (_connection, _error); \
|
nmtst_assert_success (_connection, _error); \
|
||||||
nmtst_assert_connection_verifies_without_normalization (_connection); \
|
nmtst_assert_connection_verifies_without_normalization (_connection); \
|
||||||
|
Reference in New Issue
Block a user