summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-07-15 16:53:58 +0200
committerThomas Haller <thaller@redhat.com>2019-07-16 18:27:02 +0200
commit5ce589a7750cd44885f266aa381d110005141e07 (patch)
tree8225a33bf3d55d23b59350f339dab406dd7a3a82
parent050f61519ce2f767d33283474719424fa01cab9f (diff)
downloadNetworkManager-5ce589a7750cd44885f266aa381d110005141e07.tar.gz
settings: change filename for per-connection metadata (previously UUID nm-loaded symlinks)
We may want to store meta-data for a profile to disk. The immediate need are "tombstones": markers that the particular UUID is shadowed and the profile does not exist (despite being in read-only location). Change the filename of these symlinks from ".loaded-${UUID}.nmconnection" to "${UUID}.nmmeta" The leading dot is not desirable as tools tend to hide such files. Use a different scheme for the filename that does not have the leading dot. Note that nm_keyfile_utils_ignore_filename() would also ignore ".nmmeta" as not a valid keyfile. This is just what we want, and influences the choice of this file suffix. Also, "nmmeta" is a better name, because this name alludes that there is a wider use for the file: namely to have addtional per-profile metadata. That is regardless that the upcoming first use will be only to store symlinks to "/dev/null" to indicate the tombstones. Note that per-profile metadata is not new. Currently we write the files /var/lib/NetworkManager/{seen-bssids,timestamps} that have a similar purpose. Maybe the content from these files could one day be migrated to the ".nmmeta" file. The naming scheme would make it suitable.
-rw-r--r--libnm-core/nm-keyfile-internal.h4
-rw-r--r--libnm-core/nm-keyfile.c7
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-utils.c101
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-utils.h3
-rw-r--r--src/settings/plugins/keyfile/tests/test-keyfile-settings.c7
5 files changed, 68 insertions, 54 deletions
diff --git a/libnm-core/nm-keyfile-internal.h b/libnm-core/nm-keyfile-internal.h
index 941fe0a18b..47838bb639 100644
--- a/libnm-core/nm-keyfile-internal.h
+++ b/libnm-core/nm-keyfile-internal.h
@@ -176,9 +176,9 @@ gboolean _nm_keyfile_has_values (GKeyFile *keyfile);
#define NM_KEYFILE_PATH_SUFFIX_NMCONNECTION ".nmconnection"
-#define NM_KEYFILE_PATH_PREFIX_NMLOADED ".loaded-"
+#define NM_KEYFILE_PATH_SUFFIX_NMMETA ".nmmeta"
-#define NM_KEYFILE_PATH_NMLOADED_NULL "/dev/null"
+#define NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL "/dev/null"
gboolean nm_keyfile_utils_ignore_filename (const char *filename, gboolean require_extension);
diff --git a/libnm-core/nm-keyfile.c b/libnm-core/nm-keyfile.c
index 8add4bfccf..1d3f24cfd6 100644
--- a/libnm-core/nm-keyfile.c
+++ b/libnm-core/nm-keyfile.c
@@ -3981,7 +3981,7 @@ nm_keyfile_utils_ignore_filename (const char *filename, gboolean require_extensi
if (require_extension) {
if ( l <= NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)
- || !g_str_has_suffix (base, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION))
+ || !NM_STR_HAS_SUFFIX (base, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION))
return TRUE;
return FALSE;
}
@@ -3990,7 +3990,10 @@ nm_keyfile_utils_ignore_filename (const char *filename, gboolean require_extensi
if (base[l - 1] == '~')
return TRUE;
- /* Ignore temporary files */
+ /* Ignore temporary files
+ *
+ * This check is also important to ignore .nmload files (see
+ * %NM_KEYFILE_PATH_SUFFIX_NMMETA). */
if (check_mkstemp_suffix (base))
return TRUE;
diff --git a/src/settings/plugins/keyfile/nms-keyfile-utils.c b/src/settings/plugins/keyfile/nms-keyfile-utils.c
index 50e00263f7..f474181388 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-utils.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-utils.c
@@ -33,30 +33,71 @@
/*****************************************************************************/
+const char *
+nms_keyfile_loaded_uuid_is_filename (const char *filename,
+ guint *out_uuid_len)
+{
+ const char *uuid;
+ const char *s;
+ gsize len;
+
+ s = strrchr (filename, '/');
+ if (s)
+ filename = &s[1];
+
+ len = strlen (filename);
+ if ( len <= NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMMETA)
+ || memcmp (&filename[len - NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMMETA)],
+ NM_KEYFILE_PATH_SUFFIX_NMMETA,
+ NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMMETA)) != 0) {
+ /* the filename does not have the right suffix. */
+ return NULL;
+ }
+
+ len -= NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMMETA);
+
+ if (!NM_IN_SET (len, 36, 40)) {
+ /* the remaining part of the filename has not the right length to
+ * contain a UUID (according to nm_utils_is_uuid()). */
+ return NULL;
+ }
+
+ uuid = nm_strndup_a (100, filename, len, NULL);
+ if (!nm_utils_is_uuid (uuid))
+ return NULL;
+
+ NM_SET_OUT (out_uuid_len, len);
+ return filename;
+}
+
char *
nms_keyfile_loaded_uuid_filename (const char *dirname,
const char *uuid,
gboolean temporary)
{
char filename[250];
+ char *s;
nm_assert (dirname && dirname[0] == '/');
- nm_assert (uuid && nm_utils_is_uuid (uuid) && !strchr (uuid, '/'));
+ nm_assert ( nm_utils_is_uuid (uuid)
+ && !strchr (uuid, '/'));
if (g_snprintf (filename,
sizeof (filename),
- "%s%s%s%s",
- NM_KEYFILE_PATH_PREFIX_NMLOADED,
+ "%s%s%s",
uuid,
- NM_KEYFILE_PATH_SUFFIX_NMCONNECTION,
+ NM_KEYFILE_PATH_SUFFIX_NMMETA,
temporary ? "~" : "") >= sizeof (filename)) {
- /* valid uuids are limited in length. The buffer should always be large
- * enough. */
+ /* valid uuids are limited in length (nm_utils_is_uuid). The buffer should always
+ * be large enough. */
nm_assert_not_reached ();
- return NULL;
}
- return g_build_filename (dirname, filename, NULL);
+ s = g_build_filename (dirname, filename, NULL);
+
+ nm_assert (nm_keyfile_utils_ignore_filename (s, FALSE));
+
+ return s;
}
gboolean
@@ -68,48 +109,15 @@ nms_keyfile_loaded_uuid_read (const char *dirname,
struct stat *out_st)
{
const char *uuid;
- const char *tmp;
- gsize len;
+ guint uuid_len;
gs_free char *full_filename = NULL;
gs_free char *ln = NULL;
nm_assert (dirname && dirname[0] == '/');
nm_assert (filename && filename[0] && !strchr (filename, '/'));
- if (filename[0] != '.') {
- /* the hidden-uuid filename must start with '.'. That is,
- * so that it does not conflict with regular keyfiles according
- * to nm_keyfile_utils_ignore_filename(). */
- return FALSE;
- }
-
- len = strlen (filename);
- if ( len <= NM_STRLEN (NM_KEYFILE_PATH_PREFIX_NMLOADED)
- || memcmp (filename, NM_KEYFILE_PATH_PREFIX_NMLOADED, NM_STRLEN (NM_KEYFILE_PATH_PREFIX_NMLOADED)) != 0) {
- /* the filename does not have the right prefix. */
- return FALSE;
- }
-
- tmp = &filename[NM_STRLEN (NM_KEYFILE_PATH_PREFIX_NMLOADED)];
- len -= NM_STRLEN (NM_KEYFILE_PATH_PREFIX_NMLOADED);
-
- if ( len <= NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)
- || memcmp (&tmp[len - NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)],
- NM_KEYFILE_PATH_SUFFIX_NMCONNECTION,
- NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)) != 0) {
- /* the file does not have the right suffix. */
- return FALSE;
- }
- len -= NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMCONNECTION);
-
- if (!NM_IN_SET (len, 36, 40)) {
- /* the remaining part of the filename has not the right length to
- * contain a UUID (according to nm_utils_is_uuid()). */
- return FALSE;
- }
-
- uuid = nm_strndup_a (100, tmp, len, NULL);
- if (!nm_utils_is_uuid (uuid))
+ uuid = nms_keyfile_loaded_uuid_is_filename (filename, &uuid_len);
+ if (!uuid)
return FALSE;
full_filename = g_build_filename (dirname, filename, NULL);
@@ -124,7 +132,7 @@ nms_keyfile_loaded_uuid_read (const char *dirname,
if (!ln)
return FALSE;
- NM_SET_OUT (out_uuid, g_strdup (uuid));
+ NM_SET_OUT (out_uuid, g_strndup (uuid, uuid_len));
NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename));
NM_SET_OUT (out_loaded_path, g_steal_pointer (&ln));
return TRUE;
@@ -169,7 +177,8 @@ nms_keyfile_loaded_uuid_write (const char *dirname,
gs_free char *full_filename = NULL;
nm_assert (dirname && dirname[0] == '/');
- nm_assert (uuid && nm_utils_is_uuid (uuid) && !strchr (uuid, '/'));
+ nm_assert ( nm_utils_is_uuid (uuid)
+ && !strchr (uuid, '/'));
nm_assert (!loaded_path || loaded_path[0] == '/');
full_filename_tmp = nms_keyfile_loaded_uuid_filename (dirname, uuid, TRUE);
diff --git a/src/settings/plugins/keyfile/nms-keyfile-utils.h b/src/settings/plugins/keyfile/nms-keyfile-utils.h
index 8a31232d08..43748cbdbd 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-utils.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-utils.h
@@ -37,6 +37,9 @@ const char *nms_keyfile_utils_get_path (void);
/*****************************************************************************/
+const char *nms_keyfile_loaded_uuid_is_filename (const char *filename,
+ guint *out_uuid_len);
+
char *nms_keyfile_loaded_uuid_filename (const char *dirname,
const char *uuid,
gboolean temporary);
diff --git a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c
index 4d02c58b7f..0604560599 100644
--- a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c
+++ b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c
@@ -2578,14 +2578,13 @@ static void
test_loaded_uuid (void)
{
const char *uuid = "3c03fd17-ddc3-4100-a954-88b6fafff959";
- gs_free char *filename = g_strdup_printf ("%s%s%s",
- NM_KEYFILE_PATH_PREFIX_NMLOADED,
+ gs_free char *filename = g_strdup_printf ("%s%s",
uuid,
- NM_KEYFILE_PATH_SUFFIX_NMCONNECTION);
+ NM_KEYFILE_PATH_SUFFIX_NMMETA);
gs_free char *full_filename = g_strdup_printf ("%s/%s",
TEST_SCRATCH_DIR,
filename);
- const char *loaded_path0 = NM_KEYFILE_PATH_NMLOADED_NULL;
+ const char *loaded_path0 = NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL;
const char *loaded_path1 = "/some/where/but/not/scratch/dir";
const char *filename2 = "foo1";
gs_free char *loaded_path2 = g_strdup_printf ("%s/%s",