summary refs log tree commit diff
path: root/src/settings/plugins/keyfile/nms-keyfile-storage.h
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2019-07-31 10:51:42 +0200
committerMichael Biebl <biebl@debian.org>2019-07-31 10:51:42 +0200
commit2e5fa45ddfbb5cffa1e78221f1cea706e2f298af (patch)
tree86f69d36c56de3074280456eddc854a780b8e04b /src/settings/plugins/keyfile/nms-keyfile-storage.h
parent85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (diff)
New upstream version 1.19.90 upstream/1.19.90
Diffstat (limited to 'src/settings/plugins/keyfile/nms-keyfile-storage.h')
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-storage.h264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/settings/plugins/keyfile/nms-keyfile-storage.h b/src/settings/plugins/keyfile/nms-keyfile-storage.h
new file mode 100644
index 00000000..2252b47b
--- /dev/null
+++ b/src/settings/plugins/keyfile/nms-keyfile-storage.h
@@ -0,0 +1,264 @@
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ */
+
+#ifndef __NMS_KEYFILE_STORAGE_H__
+#define __NMS_KEYFILE_STORAGE_H__
+
+#include "c-list/src/c-list.h"
+#include "settings/nm-settings-storage.h"
+#include "nms-keyfile-utils.h"
+
+/*****************************************************************************/
+
+#define NMS_TYPE_KEYFILE_STORAGE            (nms_keyfile_storage_get_type ())
+#define NMS_KEYFILE_STORAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_KEYFILE_STORAGE, NMSKeyfileStorage))
+#define NMS_KEYFILE_STORAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_KEYFILE_STORAGE, NMSKeyfileStorageClass))
+#define NMS_IS_KEYFILE_STORAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_KEYFILE_STORAGE))
+#define NMS_IS_KEYFILE_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_KEYFILE_STORAGE))
+#define NMS_KEYFILE_STORAGE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_KEYFILE_STORAGE, NMSKeyfileStorageClass))
+
+typedef struct {
+	/* whether this is a tombstone to hide a UUID (via symlink to /dev/null). */
+	char *shadowed_storage;
+	bool is_tombstone:1;
+} NMSettingsMetaData;
+
+typedef struct {
+	NMSettingsStorage parent;
+
+	/* The connection. Note that there are tombstones (loaded-uuid files to /dev/null)
+	 * that don't have a connection.
+	 *
+	 * Also, we don't actually remember the loaded connection after returning it
+	 * to NMSettings. So, also for regular storages (non-tombstones) this field
+	 * is often cleared. */
+	union {
+		struct {
+			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
+			 * 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. */
+			struct timespec stat_mtime;
+
+			/* these flags are only relevant for storages with %NMS_KEYFILE_STORAGE_TYPE_RUN
+			 * (and non-metadata). This is to persist and reload these settings flags to
+			 * /run.
+			 *
+			 * Note that these flags are not stored in as meta-data. The reason is that meta-data
+			 * is per UUID. But these flags are only relevant for a particular keyfile on disk.
+			 * That is, it must be tied to the actual keyfile, and not to the UUID. */
+			bool is_nm_generated: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;
+
+		/* the content from the .nmmeta file. Note that the nmmeta file has the UUID
+		 * in the filename, that means there can be only two variants of this file:
+		 * in /etc and in /run. As such, this is really meta-data about the entire profile
+		 * (the UUID), and not about the individual keyfile. */
+		NMSettingsMetaData meta_data;
+
+	} u;
+
+	/* The storage type. This is directly related to the filename. Since
+	 * the filename cannot change, this value is unchanging. */
+	const NMSKeyfileStorageType storage_type;
+
+	/* whether union "u" has meta_data or conn_data. Since the type of the storage
+	 * depends on the (immutable) filename, this is also const. */
+	const bool is_meta_data;
+
+	/* this flag is only used during reload to mark and prune old entries. */
+	bool is_dirty:1;
+
+} NMSKeyfileStorage;
+
+typedef struct _NMSKeyfileStorageClass NMSKeyfileStorageClass;
+
+GType nms_keyfile_storage_get_type (void);
+
+struct _NMSKeyfilePlugin;
+
+NMSKeyfileStorage *nms_keyfile_storage_new_tombstone (struct _NMSKeyfilePlugin *self,
+                                                      const char *uuid,
+                                                      const char *filename,
+                                                      NMSKeyfileStorageType storage_type,
+                                                      const char *shadowed_storage);
+
+NMSKeyfileStorage *nms_keyfile_storage_new_connection (struct _NMSKeyfilePlugin *self,
+                                                       NMConnection *connection_take /* pass reference */,
+                                                       const char *filename,
+                                                       NMSKeyfileStorageType storage_type,
+                                                       NMTernary is_nm_generated_opt,
+                                                       NMTernary is_volatile_opt,
+                                                       const char *shadowed_storage,
+                                                       NMTernary shadowed_owned_opt,
+                                                       const struct timespec *stat_mtime);
+
+void nms_keyfile_storage_destroy (NMSKeyfileStorage *storage);
+
+/*****************************************************************************/
+
+void nms_keyfile_storage_copy_content (NMSKeyfileStorage *dst,
+                                       const NMSKeyfileStorage *src);
+
+NMConnection *nms_keyfile_storage_steal_connection (NMSKeyfileStorage *storage);
+
+/*****************************************************************************/
+
+static inline const char *
+nms_keyfile_storage_get_uuid (const NMSKeyfileStorage *self)
+{
+	return nm_settings_storage_get_uuid ((const NMSettingsStorage *) self);
+}
+
+static inline const char *
+nms_keyfile_storage_get_filename (const NMSKeyfileStorage *self)
+{
+	return nm_settings_storage_get_filename ((const NMSettingsStorage *) self);
+}
+
+/*****************************************************************************/
+
+static inline gboolean
+nm_settings_storage_is_keyfile_run (const NMSettingsStorage *self)
+{
+	return    NMS_IS_KEYFILE_STORAGE (self)
+	       && (((NMSKeyfileStorage *) self)->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN);
+}
+
+static inline gboolean
+nm_settings_storage_is_keyfile_lib (const NMSettingsStorage *self)
+{
+	return    NMS_IS_KEYFILE_STORAGE (self)
+	       && (((NMSKeyfileStorage *) self)->storage_type >= NMS_KEYFILE_STORAGE_TYPE_LIB_BASE);
+}
+
+static inline const NMSettingsMetaData *
+nm_settings_storage_is_meta_data (const NMSettingsStorage *storage)
+{
+	const NMSKeyfileStorage *self;
+
+	if (!NMS_IS_KEYFILE_STORAGE (storage))
+		return NULL;
+
+	self = (NMSKeyfileStorage *) storage;
+
+	if (!self->is_meta_data)
+		return NULL;
+
+	return &self->u.meta_data;
+}
+
+static inline const NMSettingsMetaData *
+nm_settings_storage_is_meta_data_alive (const NMSettingsStorage *storage)
+{
+	const NMSettingsMetaData *meta_data;
+
+	meta_data = nm_settings_storage_is_meta_data (storage);
+
+	if (!meta_data)
+		return NULL;
+
+	/* Regular (all other) storages are alive as long as they report a NMConnection, and
+	 * they will be dropped, once they have no more connection.
+	 *
+	 * Meta-data storages are special: they never report a NMConnection.
+	 * So, a meta-data storage is alive as long as it is tracked by the
+	 * settings plugin.
+	 *
+	 * This function is used to ckeck for that. */
+
+	if (c_list_is_empty (&storage->_storage_lst))
+		return NULL;
+
+	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;
+				}
+			} else {
+				NM_SET_OUT (out_shadowed_owned, FALSE);
+				return self->u.meta_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;
+
+void nm_settings_storage_load_sett_flags (NMSettingsStorage *self,
+                                          enum _NMSettingsConnectionIntFlags *sett_flags,
+                                          enum _NMSettingsConnectionIntFlags *sett_mask);
+
+#endif /* __NMS_KEYFILE_STORAGE_H__ */