diff options
author | Thomas Haller <thaller@redhat.com> | 2019-07-15 16:53:58 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-07-16 18:27:02 +0200 |
commit | 5ce589a7750cd44885f266aa381d110005141e07 (patch) | |
tree | 8225a33bf3d55d23b59350f339dab406dd7a3a82 | |
parent | 050f61519ce2f767d33283474719424fa01cab9f (diff) | |
download | NetworkManager-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.h | 4 | ||||
-rw-r--r-- | libnm-core/nm-keyfile.c | 7 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/nms-keyfile-utils.c | 101 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/nms-keyfile-utils.h | 3 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/tests/test-keyfile-settings.c | 7 |
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", |