mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 10:40:08 +01:00
settings: merge branch 'th/settings-delegate-storage'
https://bugzilla.redhat.com/show_bug.cgi?id=1674545 https://bugzilla.gnome.org/show_bug.cgi?id=772414 https://bugzilla.gnome.org/show_bug.cgi?id=744711 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/189
This commit is contained in:
commit
f1d24f5df2
63 changed files with 6700 additions and 3510 deletions
18
Makefile.am
18
Makefile.am
|
|
@ -2094,13 +2094,17 @@ src_libNetworkManager_la_SOURCES = \
|
|||
src/settings/nm-secret-agent.h \
|
||||
src/settings/nm-settings-connection.c \
|
||||
src/settings/nm-settings-connection.h \
|
||||
src/settings/nm-settings-storage.c \
|
||||
src/settings/nm-settings-storage.h \
|
||||
src/settings/nm-settings-plugin.c \
|
||||
src/settings/nm-settings-plugin.h \
|
||||
src/settings/nm-settings.c \
|
||||
src/settings/nm-settings.h \
|
||||
src/settings/nm-settings-utils.c \
|
||||
src/settings/nm-settings-utils.h \
|
||||
\
|
||||
src/settings/plugins/keyfile/nms-keyfile-connection.c \
|
||||
src/settings/plugins/keyfile/nms-keyfile-connection.h \
|
||||
src/settings/plugins/keyfile/nms-keyfile-storage.c \
|
||||
src/settings/plugins/keyfile/nms-keyfile-storage.h \
|
||||
src/settings/plugins/keyfile/nms-keyfile-plugin.c \
|
||||
src/settings/plugins/keyfile/nms-keyfile-plugin.h \
|
||||
src/settings/plugins/keyfile/nms-keyfile-reader.c \
|
||||
|
|
@ -2819,10 +2823,11 @@ $(src_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_OBJECTS): $(libnm_core_l
|
|||
###############################################################################
|
||||
|
||||
src_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_SOURCES = \
|
||||
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c \
|
||||
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.h \
|
||||
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c \
|
||||
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h \
|
||||
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c \
|
||||
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h
|
||||
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h \
|
||||
$(NULL)
|
||||
|
||||
src_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS = $(src_cppflags_base)
|
||||
|
||||
|
|
@ -3135,8 +3140,6 @@ src_settings_plugins_ifupdown_libnms_ifupdown_core_la_LIBADD = \
|
|||
$(NULL)
|
||||
|
||||
src_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_SOURCES = \
|
||||
src/settings/plugins/ifupdown/nms-ifupdown-connection.c \
|
||||
src/settings/plugins/ifupdown/nms-ifupdown-connection.h \
|
||||
src/settings/plugins/ifupdown/nms-ifupdown-plugin.c \
|
||||
src/settings/plugins/ifupdown/nms-ifupdown-plugin.h \
|
||||
$(NULL)
|
||||
|
|
@ -4834,6 +4837,7 @@ install-data-hook: $(install_data_hook)
|
|||
$(mkinstalldirs) -m 0755 $(DESTDIR)$(nmconfdir)/dnsmasq-shared.d
|
||||
$(mkinstalldirs) -m 0755 $(DESTDIR)$(nmlibdir)/conf.d
|
||||
$(mkinstalldirs) -m 0755 $(DESTDIR)$(nmlibdir)/VPN
|
||||
$(mkinstalldirs) -m 0755 $(DESTDIR)$(nmlibdir)/system-connections
|
||||
$(mkinstalldirs) -m 0700 $(DESTDIR)$(nmstatedir)
|
||||
$(mkinstalldirs) -m 0755 $(DESTDIR)$(plugindir)
|
||||
|
||||
|
|
|
|||
|
|
@ -847,6 +847,7 @@ fi
|
|||
%dir %{nmlibdir}
|
||||
%dir %{nmlibdir}/conf.d
|
||||
%dir %{nmlibdir}/VPN
|
||||
%dir %{nmlibdir}/system-connections
|
||||
%{_mandir}/man1/*
|
||||
%{_mandir}/man5/*
|
||||
%{_mandir}/man7/nmcli-examples.7*
|
||||
|
|
|
|||
|
|
@ -56,9 +56,7 @@
|
|||
does not start the network connection unless (1) device is idle and able
|
||||
to connect to the network described by the new connection, and (2) the
|
||||
connection is allowed to be started automatically. Use the 'Save' method
|
||||
on the connection to save these changes to disk. Note that unsaved changes
|
||||
will be lost if the connection is reloaded from disk (either automatically
|
||||
on file change or due to an explicit ReloadConnections call).
|
||||
on the connection to save these changes to disk.
|
||||
-->
|
||||
<method name="AddConnectionUnsaved">
|
||||
<arg name="connection" type="a{sa{sv}}" direction="in"/>
|
||||
|
|
|
|||
|
|
@ -1811,6 +1811,9 @@ const char _nmtst_connection_unchanging_user_data = 0;
|
|||
void
|
||||
nmtst_connection_assert_unchanging (NMConnection *connection)
|
||||
{
|
||||
if (!connection)
|
||||
return;
|
||||
|
||||
nm_assert (NM_IS_CONNECTION (connection));
|
||||
|
||||
if (g_signal_handler_find (connection,
|
||||
|
|
|
|||
|
|
@ -1014,6 +1014,9 @@ typedef enum { /*< flags >*/
|
|||
* is not deleted but merely the connection is decoupled from the file
|
||||
* on disk. If you later delete an in-memory connection, the connection
|
||||
* on disk will be deleted as well.
|
||||
* Note: with 1.20, this flag is no longer implemented because in-memory connections
|
||||
* are also persisted under /run. For the moment, this behaves the same as
|
||||
* @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED.
|
||||
* @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED: this is like @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY,
|
||||
* but if the connection has a corresponding file on disk, the association between
|
||||
* the connection and the file is forgotten but the file is not modified.
|
||||
|
|
|
|||
|
|
@ -162,6 +162,8 @@ GKeyFile *nm_keyfile_write (NMConnection *connection,
|
|||
char *nm_keyfile_plugin_kf_get_string (GKeyFile *kf, const char *group, const char *key, GError **error);
|
||||
void nm_keyfile_plugin_kf_set_string (GKeyFile *kf, const char *group, const char *key, const char *value);
|
||||
|
||||
int nm_key_file_get_boolean (GKeyFile *kf, const char *group, const char *key, int default_value);
|
||||
|
||||
void _nm_keyfile_copy (GKeyFile *dst, GKeyFile *src);
|
||||
gboolean _nm_keyfile_a_contains_all_in_b (GKeyFile *kf_a, GKeyFile *kf_b);
|
||||
gboolean _nm_keyfile_equals (GKeyFile *kf_a, GKeyFile *kf_b, gboolean consider_order);
|
||||
|
|
@ -169,14 +171,19 @@ gboolean _nm_keyfile_has_values (GKeyFile *keyfile);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_KEYFILE_GROUP_NMMETA ".nmmeta"
|
||||
#define NM_KEYFILE_KEY_NMMETA_NM_GENERATED "nm-generated"
|
||||
#define NM_KEYFILE_KEY_NMMETA_VOLATILE "volatile"
|
||||
|
||||
#define NM_KEYFILE_PATH_NAME_LIB NMLIBDIR "/system-connections"
|
||||
#define NM_KEYFILE_PATH_NAME_ETC_DEFAULT NMCONFDIR "/system-connections"
|
||||
#define NM_KEYFILE_PATH_NAME_RUN NMRUNDIR "/system-connections"
|
||||
#define NM_KEYFILE_PATH_NAME_RUN NMRUNDIR "/system-connections"
|
||||
|
||||
#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);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,43 @@
|
|||
#include "nm-setting-wireless.h"
|
||||
#include "nm-setting-wireless-security.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_key_file_get_boolean:
|
||||
* @kf: the #GKeyFile
|
||||
* @group: the group
|
||||
* @key: the key
|
||||
* @default_value: the default value if the value is set or not parsable as a boolean.
|
||||
*
|
||||
* Replacement for g_key_file_get_boolean() (which uses g_key_file_parse_value_as_boolean()).
|
||||
* g_key_file_get_boolean() seems odd to me, because it accepts trailing ASCII whitespace,
|
||||
* but not leading.
|
||||
* This uses _nm_utils_ascii_str_to_bool(), which accepts trailing and leading whitespace,
|
||||
* case-insensitive words, and also strings like "on" and "off".
|
||||
* _nm_utils_ascii_str_to_bool() is our way to parse booleans from string, and we should
|
||||
* use that one consistently.
|
||||
*
|
||||
* Also, it doesn't have g_key_file_get_boolean()'s odd API to require an error argument
|
||||
* to detect parsing failures.
|
||||
*
|
||||
* Returns: either %TRUE or %FALSE if the key exists and is parsable as a boolean.
|
||||
* Otherwise, @default_value.
|
||||
*/
|
||||
int
|
||||
nm_key_file_get_boolean (GKeyFile *kf, const char *group, const char *key, int default_value)
|
||||
{
|
||||
gs_free char *value = NULL;
|
||||
|
||||
value = g_key_file_get_value (kf, group, key, NULL);
|
||||
|
||||
if (!value)
|
||||
return default_value;
|
||||
return _nm_utils_ascii_str_to_bool (value, default_value);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
const char *setting;
|
||||
const char *alias;
|
||||
|
|
|
|||
|
|
@ -3537,7 +3537,9 @@ nm_keyfile_read (GKeyFile *keyfile,
|
|||
vpn_secrets = TRUE;
|
||||
} else if (NM_STR_HAS_PREFIX (groups[i], NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER))
|
||||
_read_setting_wireguard_peer (&info);
|
||||
else
|
||||
else if (nm_streq (groups[i], NM_KEYFILE_GROUP_NMMETA)) {
|
||||
/* pass */
|
||||
} else
|
||||
_read_setting (&info);
|
||||
|
||||
info.group = NULL;
|
||||
|
|
@ -3981,7 +3983,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 +3992,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1657,11 +1657,13 @@ static inline char *
|
|||
_nm_strndup_a_step (char *s, const char *str, gsize len)
|
||||
{
|
||||
NM_PRAGMA_WARNING_DISABLE ("-Wstringop-truncation");
|
||||
NM_PRAGMA_WARNING_DISABLE ("-Wstringop-overflow");
|
||||
if (len > 0)
|
||||
strncpy (s, str, len);
|
||||
s[len] = '\0';
|
||||
return s;
|
||||
NM_PRAGMA_WARNING_REENABLE;
|
||||
NM_PRAGMA_WARNING_REENABLE;
|
||||
}
|
||||
|
||||
/* Similar to g_strndup(), however, if the string (including the terminating
|
||||
|
|
|
|||
|
|
@ -235,15 +235,17 @@ pan_connection_check_create (NMBluezDevice *self)
|
|||
* which then already finds the suitable connection in priv->connections. This is confusing,
|
||||
* so block the signal. check_emit_usable will succeed after this function call returns. */
|
||||
g_signal_handlers_block_by_func (priv->settings, cp_connection_added, self);
|
||||
added = nm_settings_add_connection (priv->settings, connection, FALSE, &error);
|
||||
nm_settings_add_connection (priv->settings,
|
||||
connection,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED,
|
||||
&added,
|
||||
&error);
|
||||
g_signal_handlers_unblock_by_func (priv->settings, cp_connection_added, self);
|
||||
|
||||
if (added) {
|
||||
nm_assert (!g_slist_find (priv->connections, added));
|
||||
nm_assert (connection_compatible (self, added));
|
||||
|
||||
nm_settings_connection_set_flags (added, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, TRUE);
|
||||
|
||||
priv->connections = g_slist_prepend (priv->connections, g_object_ref (added));
|
||||
priv->pan_connection = added;
|
||||
nm_log_dbg (LOGD_BT, "bluez[%s] added new Bluetooth connection for NAP device: '%s' (%s)", priv->path, id, uuid);
|
||||
|
|
@ -392,7 +394,7 @@ cp_connection_removed (NMSettings *settings,
|
|||
static void
|
||||
cp_connection_updated (NMSettings *settings,
|
||||
NMSettingsConnection *sett_conn,
|
||||
gboolean by_user,
|
||||
guint update_reason_u,
|
||||
NMBluezDevice *self)
|
||||
{
|
||||
if (_internal_track_connection (self, sett_conn,
|
||||
|
|
@ -1225,7 +1227,7 @@ dispose (GObject *object)
|
|||
if (to_delete) {
|
||||
nm_log_dbg (LOGD_BT, "bluez[%s] removing Bluetooth connection for NAP device: '%s' (%s)", priv->path,
|
||||
nm_settings_connection_get_id (to_delete), nm_settings_connection_get_uuid (to_delete));
|
||||
nm_settings_connection_delete (to_delete, NULL);
|
||||
nm_settings_connection_delete (to_delete, FALSE);
|
||||
g_object_unref (to_delete);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11507,7 +11507,7 @@ check_and_reapply_connection (NMDevice *self,
|
|||
|| !nm_streq0 (nm_setting_connection_get_stable_id (s_con_a), nm_setting_connection_get_stable_id (s_con_n))) {
|
||||
connection_clean_free = nm_simple_connection_new_clone (connection);
|
||||
connection_clean = connection_clean_free;
|
||||
s_con_n = nm_connection_get_setting_connection (connection);
|
||||
s_con_n = nm_connection_get_setting_connection (connection_clean);
|
||||
g_object_set (s_con_n,
|
||||
NM_SETTING_CONNECTION_ID, nm_setting_connection_get_id (s_con_a),
|
||||
NM_SETTING_CONNECTION_UUID, nm_setting_connection_get_uuid (s_con_a),
|
||||
|
|
@ -12404,16 +12404,28 @@ nm_device_set_ip_config (NMDevice *self,
|
|||
|
||||
if ( nm_device_sys_iface_state_is_external (self)
|
||||
&& (settings_connection = nm_device_get_settings_connection (self))
|
||||
&& NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection),
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)
|
||||
&& NM_FLAGS_ALL (nm_settings_connection_get_flags (settings_connection),
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)
|
||||
&& nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request.obj)) == NM_ACTIVATION_TYPE_EXTERNAL) {
|
||||
g_object_freeze_notify (G_OBJECT (settings_connection));
|
||||
/* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */
|
||||
nm_connection_add_setting (nm_settings_connection_get_connection (settings_connection),
|
||||
gs_unref_object NMConnection *new_connection = NULL;
|
||||
|
||||
new_connection = nm_simple_connection_new_clone (nm_settings_connection_get_connection (settings_connection));
|
||||
|
||||
nm_connection_add_setting (new_connection,
|
||||
IS_IPv4
|
||||
? nm_ip4_config_create_setting (priv->ip_config_4)
|
||||
: nm_ip6_config_create_setting (priv->ip_config_6));
|
||||
g_object_thaw_notify (G_OBJECT (settings_connection));
|
||||
|
||||
nm_settings_connection_update (settings_connection,
|
||||
new_connection,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE,
|
||||
"update-external",
|
||||
NULL);
|
||||
}
|
||||
|
||||
nm_device_queue_recheck_assume (self);
|
||||
|
|
@ -14365,7 +14377,7 @@ cp_connection_added (NMSettings *settings, NMSettingsConnection *sett_conn, gpoi
|
|||
}
|
||||
|
||||
static void
|
||||
cp_connection_updated (NMSettings *settings, NMSettingsConnection *sett_conn, gboolean by_user, gpointer user_data)
|
||||
cp_connection_updated (NMSettings *settings, NMSettingsConnection *sett_conn, guint update_reason_u, gpointer user_data)
|
||||
{
|
||||
cp_connection_added_or_updated (user_data, sett_conn);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1760,9 +1760,10 @@ supplicant_iface_wps_credentials_cb (NMSupplicantInterface *iface,
|
|||
}
|
||||
if (secrets) {
|
||||
if (nm_settings_connection_new_secrets (nm_act_request_get_settings_connection (req),
|
||||
nm_act_request_get_applied_connection (req),
|
||||
NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
|
||||
secrets, &error)) {
|
||||
nm_act_request_get_applied_connection (req),
|
||||
NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
|
||||
secrets,
|
||||
&error)) {
|
||||
wifi_secrets_cancel (self);
|
||||
nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -469,19 +469,18 @@ mirror_8021x_connection (NMIwdManager *self,
|
|||
if (!nm_connection_normalize (connection, NULL, NULL, NULL))
|
||||
return NULL;
|
||||
|
||||
settings_connection = nm_settings_add_connection (priv->settings, connection,
|
||||
FALSE, &error);
|
||||
if (!settings_connection) {
|
||||
if (!nm_settings_add_connection (priv->settings,
|
||||
connection,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED,
|
||||
&settings_connection,
|
||||
&error)) {
|
||||
_LOGW ("failed to add a mirror NMConnection for IWD's Known Network '%s': %s",
|
||||
name, error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nm_settings_connection_set_flags (settings_connection,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED |
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED,
|
||||
TRUE);
|
||||
return settings_connection;
|
||||
}
|
||||
|
||||
|
|
@ -498,7 +497,7 @@ mirror_8021x_connection_take_and_delete (NMSettingsConnection *sett_conn)
|
|||
/* If connection has not been saved since we created it
|
||||
* in interface_added it too can be removed now. */
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED))
|
||||
nm_settings_connection_delete (sett_conn, NULL);
|
||||
nm_settings_connection_delete (sett_conn, FALSE);
|
||||
|
||||
g_object_unref (sett_conn);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ sources = files(
|
|||
'dnsmasq/nm-dnsmasq-manager.c',
|
||||
'dnsmasq/nm-dnsmasq-utils.c',
|
||||
'ppp/nm-ppp-manager-call.c',
|
||||
'settings/plugins/keyfile/nms-keyfile-connection.c',
|
||||
'settings/plugins/keyfile/nms-keyfile-storage.c',
|
||||
'settings/plugins/keyfile/nms-keyfile-plugin.c',
|
||||
'settings/plugins/keyfile/nms-keyfile-reader.c',
|
||||
'settings/plugins/keyfile/nms-keyfile-utils.c',
|
||||
|
|
@ -113,6 +113,8 @@ sources = files(
|
|||
'settings/nm-settings.c',
|
||||
'settings/nm-settings-connection.c',
|
||||
'settings/nm-settings-plugin.c',
|
||||
'settings/nm-settings-storage.c',
|
||||
'settings/nm-settings-utils.c',
|
||||
'supplicant/nm-supplicant-config.c',
|
||||
'supplicant/nm-supplicant-interface.c',
|
||||
'supplicant/nm-supplicant-manager.c',
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ NM_UTILS_FLAGS2STR_DEFINE_STATIC (_state_flags_to_string, NMActivationStateFlags
|
|||
|
||||
static void
|
||||
_settings_connection_updated (NMSettingsConnection *sett_conn,
|
||||
gboolean by_user,
|
||||
guint update_reason_u,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMActiveConnection *self = user_data;
|
||||
|
|
@ -522,8 +522,9 @@ nm_active_connection_clear_secrets (NMActiveConnection *self)
|
|||
if (nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection.obj,
|
||||
priv->applied_connection,
|
||||
NM_SETTING_COMPARE_FLAG_NONE)) {
|
||||
/* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */
|
||||
nm_connection_clear_secrets (nm_settings_connection_get_connection (priv->settings_connection.obj));
|
||||
nm_settings_connection_clear_secrets (priv->settings_connection.obj,
|
||||
FALSE,
|
||||
FALSE);
|
||||
}
|
||||
nm_connection_clear_secrets (priv->applied_connection);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,9 +184,15 @@ nm_audit_log (NMAuditManager *self, GPtrArray *fields, const char *file,
|
|||
}
|
||||
|
||||
static void
|
||||
_audit_log_helper (NMAuditManager *self, GPtrArray *fields, const char *file,
|
||||
guint line, const char *func, const char *op, gboolean result,
|
||||
gpointer subject_context, const char *reason)
|
||||
_audit_log_helper (NMAuditManager *self,
|
||||
GPtrArray *fields,
|
||||
const char *file,
|
||||
guint line,
|
||||
const char *func,
|
||||
const char *op,
|
||||
gboolean result,
|
||||
gpointer subject_context,
|
||||
const char *reason)
|
||||
{
|
||||
AuditField op_field = { }, pid_field = { }, uid_field = { };
|
||||
AuditField result_field = { }, reason_field = { };
|
||||
|
|
@ -246,9 +252,16 @@ nm_audit_manager_audit_enabled (NMAuditManager *self)
|
|||
}
|
||||
|
||||
void
|
||||
_nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, guint line,
|
||||
const char *func, const char *op, NMSettingsConnection *connection,
|
||||
gboolean result, const char *args, gpointer subject_context, const char *reason)
|
||||
_nm_audit_manager_log_connection_op (NMAuditManager *self,
|
||||
const char *file,
|
||||
guint line,
|
||||
const char *func,
|
||||
const char *op,
|
||||
NMSettingsConnection *connection,
|
||||
gboolean result,
|
||||
const char *args,
|
||||
gpointer subject_context,
|
||||
const char *reason)
|
||||
{
|
||||
gs_unref_ptrarray GPtrArray *fields = NULL;
|
||||
AuditField uuid_field = { }, name_field = { }, args_field = { };
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ typedef struct _NMAuditManagerClass NMAuditManagerClass;
|
|||
#define NM_AUDIT_OP_CONN_DEACTIVATE "connection-deactivate"
|
||||
#define NM_AUDIT_OP_CONN_CLEAR_SECRETS "connection-clear-secrets"
|
||||
|
||||
#define NM_AUDIT_OP_CONNS_RELOAD "connections-reload"
|
||||
#define NM_AUDIT_OP_CONNS_LOAD "connections-load"
|
||||
|
||||
#define NM_AUDIT_OP_RELOAD "reload"
|
||||
#define NM_AUDIT_OP_SLEEP_CONTROL "sleep-control"
|
||||
#define NM_AUDIT_OP_NET_CONTROL "networking-control"
|
||||
|
|
|
|||
|
|
@ -217,19 +217,35 @@ restore_and_activate_connection (NMCheckpoint *self,
|
|||
gs_unref_object NMAuthSubject *subject = NULL;
|
||||
GError *local_error = NULL;
|
||||
gboolean need_update, need_activation;
|
||||
NMSettingsConnectionPersistMode persist_mode;
|
||||
NMSettingsConnectionIntFlags sett_flags;
|
||||
NMSettingsConnectionIntFlags sett_mask;
|
||||
|
||||
connection = find_settings_connection (self,
|
||||
dev_checkpoint,
|
||||
&need_update,
|
||||
&need_activation);
|
||||
|
||||
/* FIXME: we need to ensure to re-create/update the profile for the
|
||||
* same settings plugin. E.g. if it was a keyfile in /run or /etc,
|
||||
* it must be again. If it was previously handled by a certain settings plugin,
|
||||
* so it must again.
|
||||
*
|
||||
* FIXME: preserve and restore the right settings flags (volatile, nm-generated). */
|
||||
sett_flags = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE;
|
||||
sett_mask = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE;
|
||||
|
||||
if (connection) {
|
||||
if (need_update) {
|
||||
_LOGD ("rollback: updating connection %s",
|
||||
nm_settings_connection_get_uuid (connection));
|
||||
persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP;
|
||||
nm_settings_connection_update (connection,
|
||||
dev_checkpoint->settings_connection,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
|
||||
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
|
||||
persist_mode,
|
||||
sett_flags,
|
||||
sett_mask,
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE,
|
||||
"checkpoint-rollback",
|
||||
NULL);
|
||||
}
|
||||
|
|
@ -238,11 +254,13 @@ restore_and_activate_connection (NMCheckpoint *self,
|
|||
_LOGD ("rollback: adding connection %s again",
|
||||
nm_connection_get_uuid (dev_checkpoint->settings_connection));
|
||||
|
||||
connection = nm_settings_add_connection (NM_SETTINGS_GET,
|
||||
dev_checkpoint->settings_connection,
|
||||
TRUE,
|
||||
&local_error);
|
||||
if (!connection) {
|
||||
persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK;
|
||||
if (!nm_settings_add_connection (NM_SETTINGS_GET,
|
||||
dev_checkpoint->settings_connection,
|
||||
persist_mode,
|
||||
sett_flags,
|
||||
&connection,
|
||||
&local_error)) {
|
||||
_LOGD ("rollback: connection add failure: %s", local_error->message);
|
||||
g_clear_error (&local_error);
|
||||
return FALSE;
|
||||
|
|
@ -428,7 +446,7 @@ next_dev:
|
|||
nm_settings_connection_get_uuid (con))) {
|
||||
_LOGD ("rollback: deleting new connection %s",
|
||||
nm_settings_connection_get_uuid (con));
|
||||
nm_settings_connection_delete (con, NULL);
|
||||
nm_settings_connection_delete (con, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
114
src/nm-manager.c
114
src/nm-manager.c
|
|
@ -94,7 +94,8 @@ typedef struct {
|
|||
struct {
|
||||
GDBusMethodInvocation *invocation;
|
||||
NMConnection *connection;
|
||||
NMSettingsConnectionPersistMode persist;
|
||||
NMSettingsConnectionPersistMode persist_mode;
|
||||
bool is_volatile:1;
|
||||
} add_and_activate;
|
||||
};
|
||||
} ac_auth;
|
||||
|
|
@ -378,7 +379,8 @@ static void _add_and_activate_auth_done (NMManager *self,
|
|||
NMActiveConnection *active,
|
||||
NMConnection *connection,
|
||||
GDBusMethodInvocation *invocation,
|
||||
NMSettingsConnectionPersistMode persist,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
gboolean is_volatile,
|
||||
gboolean success,
|
||||
const char *error_desc);
|
||||
static void _activation_auth_done (NMManager *self,
|
||||
|
|
@ -495,7 +497,8 @@ _async_op_data_new_ac_auth_add_and_activate (NMManager *self,
|
|||
NMActiveConnection *active_take,
|
||||
GDBusMethodInvocation *invocation_take,
|
||||
NMConnection *connection_take,
|
||||
NMSettingsConnectionPersistMode persist)
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
gboolean is_volatile)
|
||||
{
|
||||
AsyncOpData *async_op_data;
|
||||
|
||||
|
|
@ -508,7 +511,8 @@ _async_op_data_new_ac_auth_add_and_activate (NMManager *self,
|
|||
async_op_data->ac_auth.active = active_take;
|
||||
async_op_data->ac_auth.add_and_activate.invocation = invocation_take;
|
||||
async_op_data->ac_auth.add_and_activate.connection = connection_take;
|
||||
async_op_data->ac_auth.add_and_activate.persist = persist;
|
||||
async_op_data->ac_auth.add_and_activate.persist_mode = persist_mode;
|
||||
async_op_data->ac_auth.add_and_activate.is_volatile = is_volatile;
|
||||
c_list_link_tail (&NM_MANAGER_GET_PRIVATE (self)->async_op_lst_head, &async_op_data->async_op_lst);
|
||||
return async_op_data;
|
||||
}
|
||||
|
|
@ -550,7 +554,8 @@ _async_op_complete_ac_auth_cb (NMActiveConnection *active,
|
|||
async_op_data->ac_auth.active,
|
||||
async_op_data->ac_auth.add_and_activate.connection,
|
||||
async_op_data->ac_auth.add_and_activate.invocation,
|
||||
async_op_data->ac_auth.add_and_activate.persist,
|
||||
async_op_data->ac_auth.add_and_activate.persist_mode,
|
||||
async_op_data->ac_auth.add_and_activate.is_volatile,
|
||||
success,
|
||||
error_desc);
|
||||
g_object_unref (async_op_data->ac_auth.add_and_activate.connection);
|
||||
|
|
@ -831,7 +836,7 @@ _delete_volatile_connection_do (NMManager *self,
|
|||
|
||||
_LOGD (LOGD_DEVICE, "volatile connection disconnected. Deleting connection '%s' (%s)",
|
||||
nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
|
||||
nm_settings_connection_delete (connection, NULL);
|
||||
nm_settings_connection_delete (connection, FALSE);
|
||||
}
|
||||
|
||||
/* Returns: whether to notify D-Bus of the removal or not */
|
||||
|
|
@ -2140,7 +2145,7 @@ connection_added_cb (NMSettings *settings,
|
|||
static void
|
||||
connection_updated_cb (NMSettings *settings,
|
||||
NMSettingsConnection *sett_conn,
|
||||
gboolean by_user,
|
||||
guint update_reason_u,
|
||||
NMManager *self)
|
||||
{
|
||||
connection_changed_on_idle (self, sett_conn);
|
||||
|
|
@ -2660,8 +2665,13 @@ get_existing_connection (NMManager *self,
|
|||
|
||||
nm_device_assume_state_reset (device);
|
||||
|
||||
added = nm_settings_add_connection (priv->settings, connection, FALSE, &error);
|
||||
if (!added) {
|
||||
if (!nm_settings_add_connection (priv->settings,
|
||||
connection,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED,
|
||||
&added,
|
||||
&error)) {
|
||||
_LOG2W (LOGD_SETTINGS, device, "assume: failure to save generated connection '%s': %s",
|
||||
nm_connection_get_id (connection),
|
||||
error->message);
|
||||
|
|
@ -2669,10 +2679,6 @@ get_existing_connection (NMManager *self,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
nm_settings_connection_set_flags (added,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED |
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE,
|
||||
TRUE);
|
||||
NM_SET_OUT (out_generated, TRUE);
|
||||
return added;
|
||||
}
|
||||
|
|
@ -2774,7 +2780,7 @@ recheck_assume_connection (NMManager *self,
|
|||
|
||||
if (generated) {
|
||||
_LOG2D (LOGD_DEVICE, device, "assume: deleting generated connection after assuming failed");
|
||||
nm_settings_connection_delete (sett_conn, NULL);
|
||||
nm_settings_connection_delete (sett_conn, FALSE);
|
||||
} else {
|
||||
if (nm_device_sys_iface_state_get (device) == NM_DEVICE_SYS_IFACE_STATE_ASSUME)
|
||||
nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
|
||||
|
|
@ -5315,14 +5321,11 @@ activation_add_done (NMSettings *settings,
|
|||
NMManager *self;
|
||||
gs_unref_object NMActiveConnection *active = NULL;
|
||||
gs_free_error GError *local = NULL;
|
||||
gpointer persist_ptr;
|
||||
NMSettingsConnectionPersistMode persist;
|
||||
gpointer async_op_type_ptr;
|
||||
AsyncOpType async_op_type;
|
||||
GVariant *result_floating;
|
||||
|
||||
nm_utils_user_data_unpack (user_data, &self, &active, &persist_ptr, &async_op_type_ptr);
|
||||
persist = GPOINTER_TO_INT (persist_ptr);
|
||||
nm_utils_user_data_unpack (user_data, &self, &active, &async_op_type_ptr);
|
||||
async_op_type = GPOINTER_TO_INT (async_op_type_ptr);
|
||||
|
||||
if (error)
|
||||
|
|
@ -5330,17 +5333,8 @@ activation_add_done (NMSettings *settings,
|
|||
|
||||
nm_active_connection_set_settings_connection (active, new_connection);
|
||||
|
||||
if (!_internal_activate_generic (self, active, &local)) {
|
||||
error = local;
|
||||
if (!_internal_activate_generic (self, active, &local))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nm_settings_connection_update (new_connection,
|
||||
NULL,
|
||||
persist,
|
||||
NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
|
||||
"add-and-activate",
|
||||
NULL);
|
||||
|
||||
if (async_op_type == ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE) {
|
||||
result_floating = g_variant_new ("(oo)",
|
||||
|
|
@ -5363,13 +5357,17 @@ activation_add_done (NMSettings *settings,
|
|||
return;
|
||||
|
||||
fail:
|
||||
nm_assert (error);
|
||||
if (local) {
|
||||
nm_assert (!error);
|
||||
error = local;
|
||||
} else
|
||||
nm_assert (error);
|
||||
|
||||
nm_active_connection_set_state_fail (active,
|
||||
NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN,
|
||||
error->message);
|
||||
if (new_connection)
|
||||
nm_settings_connection_delete (new_connection, NULL);
|
||||
nm_settings_connection_delete (new_connection, FALSE);
|
||||
g_dbus_method_invocation_return_gerror (context, error);
|
||||
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
|
||||
NULL,
|
||||
|
|
@ -5385,7 +5383,8 @@ _add_and_activate_auth_done (NMManager *self,
|
|||
NMActiveConnection *active,
|
||||
NMConnection *connection,
|
||||
GDBusMethodInvocation *invocation,
|
||||
NMSettingsConnectionPersistMode persist,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
gboolean is_volatile,
|
||||
gboolean success,
|
||||
const char *error_desc)
|
||||
{
|
||||
|
|
@ -5413,13 +5412,15 @@ _add_and_activate_auth_done (NMManager *self,
|
|||
* shutdown. */
|
||||
nm_settings_add_connection_dbus (priv->settings,
|
||||
connection,
|
||||
FALSE,
|
||||
persist_mode,
|
||||
( is_volatile
|
||||
? NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
|
||||
: NM_SETTINGS_CONNECTION_INT_FLAGS_NONE),
|
||||
nm_active_connection_get_subject (active),
|
||||
invocation,
|
||||
activation_add_done,
|
||||
nm_utils_user_data_pack (self,
|
||||
g_object_ref (active),
|
||||
GINT_TO_POINTER (persist),
|
||||
GINT_TO_POINTER (async_op_type)));
|
||||
}
|
||||
|
||||
|
|
@ -5445,7 +5446,8 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
|
|||
const char *device_path;
|
||||
const char *specific_object_path;
|
||||
gs_free NMConnection **conns = NULL;
|
||||
NMSettingsConnectionPersistMode persist = NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK;
|
||||
NMSettingsConnectionPersistMode persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK;
|
||||
gboolean is_volatile = FALSE;
|
||||
gboolean bind_dbus_client = FALSE;
|
||||
AsyncOpType async_op_type;
|
||||
|
||||
|
|
@ -5474,13 +5476,17 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
|
|||
&& g_variant_is_of_type (option_value, G_VARIANT_TYPE_STRING)) {
|
||||
s = g_variant_get_string (option_value, NULL);
|
||||
|
||||
if (nm_streq (s, "volatile"))
|
||||
persist = NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_ONLY;
|
||||
else if (nm_streq (s, "memory"))
|
||||
persist = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY;
|
||||
else if (nm_streq (s, "disk"))
|
||||
persist = NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK;
|
||||
else {
|
||||
is_volatile = FALSE;
|
||||
persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK;
|
||||
|
||||
if (nm_streq (s, "volatile")) {
|
||||
persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY;
|
||||
is_volatile = TRUE;
|
||||
} else if (nm_streq (s, "memory"))
|
||||
persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY;
|
||||
else if (nm_streq (s, "disk")) {
|
||||
/* pass */
|
||||
} else {
|
||||
error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_INVALID_ARGUMENTS,
|
||||
"Option \"persist\" must be one of \"volatile\", \"memory\" or \"disk\"");
|
||||
|
|
@ -5599,7 +5605,8 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
|
|||
active,
|
||||
invocation,
|
||||
incompl_conn,
|
||||
persist));
|
||||
persist_mode,
|
||||
is_volatile));
|
||||
|
||||
/* we passed the pointers on to _async_op_data_new_ac_auth_add_and_activate() */
|
||||
g_steal_pointer (&incompl_conn);
|
||||
|
|
@ -6549,8 +6556,9 @@ nm_manager_start (NMManager *self, GError **error)
|
|||
gs_free NMSettingsConnection **connections = NULL;
|
||||
guint i;
|
||||
|
||||
if (!nm_settings_start (priv->settings, error))
|
||||
return FALSE;
|
||||
nm_device_factory_manager_load_factories (_register_device_factory, self);
|
||||
|
||||
nm_device_factory_manager_for_each_factory (start_factory, NULL);
|
||||
|
||||
/* Set initial radio enabled/disabled state */
|
||||
for (i = 0; i < RFKILL_TYPE_MAX; i++) {
|
||||
|
|
@ -6573,16 +6581,15 @@ nm_manager_start (NMManager *self, GError **error)
|
|||
manager_update_radio_enabled (self, rstate, enabled);
|
||||
}
|
||||
|
||||
/* Log overall networking status - enabled/disabled */
|
||||
_LOGI (LOGD_CORE, "Networking is %s by state file",
|
||||
priv->net_enabled ? "enabled" : "disabled");
|
||||
|
||||
system_unmanaged_devices_changed_cb (priv->settings, NULL, self);
|
||||
|
||||
hostname_changed_cb (priv->hostname_manager, NULL, self);
|
||||
|
||||
/* Start device factories */
|
||||
nm_device_factory_manager_load_factories (_register_device_factory, self);
|
||||
nm_device_factory_manager_for_each_factory (start_factory, NULL);
|
||||
if (!nm_settings_start (priv->settings, error))
|
||||
return FALSE;
|
||||
|
||||
nm_platform_process_events (priv->platform);
|
||||
|
||||
|
|
@ -6596,10 +6603,11 @@ nm_manager_start (NMManager *self, GError **error)
|
|||
/* Load VPN plugins */
|
||||
priv->vpn_manager = g_object_ref (nm_vpn_manager_get ());
|
||||
|
||||
/* Connections added before the manager is started do not emit
|
||||
* connection-added signals thus devices have to be created manually.
|
||||
*/
|
||||
_LOGD (LOGD_CORE, "creating virtual devices...");
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
|
||||
G_CALLBACK (connection_added_cb), self);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
|
||||
G_CALLBACK (connection_updated_cb), self);
|
||||
connections = nm_settings_get_connections_clone (priv->settings, NULL,
|
||||
NULL, NULL,
|
||||
nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL);
|
||||
|
|
@ -7334,10 +7342,6 @@ constructed (GObject *object)
|
|||
G_CALLBACK (settings_startup_complete_changed), self);
|
||||
g_signal_connect (priv->settings, "notify::" NM_SETTINGS_UNMANAGED_SPECS,
|
||||
G_CALLBACK (system_unmanaged_devices_changed_cb), self);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
|
||||
G_CALLBACK (connection_added_cb), self);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
|
||||
G_CALLBACK (connection_updated_cb), self);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED, G_CALLBACK (connection_flags_changed), self);
|
||||
|
||||
priv->hostname_manager = g_object_ref (nm_hostname_manager_get ());
|
||||
|
|
|
|||
|
|
@ -1846,8 +1846,7 @@ device_state_changed (NMDevice *device,
|
|||
}
|
||||
}
|
||||
|
||||
/* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */
|
||||
nm_connection_clear_secrets (nm_settings_connection_get_connection (sett_conn));
|
||||
nm_settings_connection_clear_secrets (sett_conn, FALSE, FALSE);
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
|
|
@ -1858,9 +1857,7 @@ device_state_changed (NMDevice *device,
|
|||
/* And clear secrets so they will always be requested from the
|
||||
* settings service when the next connection is made.
|
||||
*/
|
||||
|
||||
/* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */
|
||||
nm_connection_clear_secrets (nm_settings_connection_get_connection (sett_conn));
|
||||
nm_settings_connection_clear_secrets (sett_conn, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/* Add device's new IPv4 and IPv6 configs to DNS */
|
||||
|
|
@ -2399,29 +2396,22 @@ dns_config_changed (NMDnsManager *dns_manager, gpointer user_data)
|
|||
static void
|
||||
connection_updated (NMSettings *settings,
|
||||
NMSettingsConnection *connection,
|
||||
gboolean by_user,
|
||||
guint update_reason_u,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMPolicyPrivate *priv = user_data;
|
||||
NMPolicy *self = _PRIV_TO_SELF (priv);
|
||||
const CList *tmp_lst;
|
||||
NMDevice *device = NULL;
|
||||
NMDevice *dev;
|
||||
NMSettingsConnectionUpdateReason update_reason = update_reason_u;
|
||||
|
||||
if (NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL)) {
|
||||
const CList *tmp_lst;
|
||||
NMDevice *device;
|
||||
|
||||
if (by_user) {
|
||||
/* find device with given connection */
|
||||
nm_manager_for_each_device (priv->manager, dev, tmp_lst) {
|
||||
if (nm_device_get_settings_connection (dev) == connection) {
|
||||
device = dev;
|
||||
break;
|
||||
}
|
||||
nm_manager_for_each_device (priv->manager, device, tmp_lst) {
|
||||
if (nm_device_get_settings_connection (device) == connection)
|
||||
nm_device_reapply_settings_immediately (device);
|
||||
}
|
||||
|
||||
if (device)
|
||||
nm_device_reapply_settings_immediately (device);
|
||||
|
||||
/* Reset auto retries back to default since connection was updated */
|
||||
nm_settings_connection_autoconnect_retries_reset (connection);
|
||||
}
|
||||
|
||||
schedule_activate_all (self);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -21,11 +21,78 @@
|
|||
#ifndef __NETWORKMANAGER_SETTINGS_CONNECTION_H__
|
||||
#define __NETWORKMANAGER_SETTINGS_CONNECTION_H__
|
||||
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include "nm-dbus-object.h"
|
||||
#include "nm-connection.h"
|
||||
|
||||
#include "nm-settings-storage.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE = 0,
|
||||
|
||||
/* with persist-mode != NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, and
|
||||
* update tries to update the profile on disk (which can always fail).
|
||||
* In some cases we want to ignore such failure and proceed. For example,
|
||||
* when we receive secrets from a secret-agent, we want to update the connection
|
||||
* at all cost and ignore failures to write them to disk. */
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE = (1u << 0),
|
||||
|
||||
/* When updating the profile, force renaming the file on disk. That matters
|
||||
* only for keyfile plugin. Keyfile prefers a filename based on connection.id.
|
||||
* When the connection.id changes we might want to rename the file on disk
|
||||
* (that is, don't overwrite the existing file, but delete it and write it
|
||||
* with the new name).
|
||||
* This flag forces such rename. */
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_FORCE_RENAME = (1u << 1),
|
||||
|
||||
/* Usually, changing a profile that is currently active does not immediately
|
||||
* reapply the changes. The exception are connection.zone and connection.metered
|
||||
* properties. When this flag is set, then these two properties are reapplied
|
||||
* right away. */
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL = (1u << 2),
|
||||
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS = (1u << 3),
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS = (1u << 4),
|
||||
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS = (1u << 5),
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS = (1u << 6),
|
||||
|
||||
/* if a profile was greated as default-wired connection for a device, then
|
||||
* when the user modifies it via D-Bus, the profile should become persisted
|
||||
* to disk and it the purpose why the profile was created should be forgotten. */
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_DEFAULT_WIRED = (1u << 7),
|
||||
|
||||
} NMSettingsConnectionUpdateReason;
|
||||
|
||||
typedef enum {
|
||||
|
||||
/* if the profile is in-memory, update it in-memory and keep it.
|
||||
* if the profile is on-disk, update it on-disk, and keep it. */
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
|
||||
|
||||
/* persist to disk. If the profile is currenly in-memory, remove
|
||||
* it from /run. */
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
|
||||
|
||||
/* persist to /run (in-memory). If the profile is currently on disk,
|
||||
* delete it from disk. */
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
||||
|
||||
/* persist to /run (in-memory). If the profile is currently on disk,
|
||||
* forget about it, but don't delete it from disk. */
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED,
|
||||
|
||||
/* this only updates the connection in-memory. Note that "in-memory" above
|
||||
* means to write to keyfile in /run. This really means to not notify the
|
||||
* settings plugin about the change. */
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST,
|
||||
|
||||
} NMSettingsConnectionPersistMode;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ())
|
||||
#define NM_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnection))
|
||||
#define NM_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass))
|
||||
|
|
@ -33,7 +100,6 @@
|
|||
#define NM_IS_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS_CONNECTION))
|
||||
#define NM_SETTINGS_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass))
|
||||
|
||||
#define NM_SETTINGS_CONNECTION_REMOVED "removed"
|
||||
#define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets"
|
||||
#define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets"
|
||||
#define NM_SETTINGS_CONNECTION_UPDATED_INTERNAL "updated-internal"
|
||||
|
|
@ -44,9 +110,6 @@
|
|||
#define NM_SETTINGS_CONNECTION_FLAGS "flags"
|
||||
#define NM_SETTINGS_CONNECTION_FILENAME "filename"
|
||||
|
||||
/* Internal properties */
|
||||
#define NM_SETTINGS_CONNECTION_READY "ready"
|
||||
|
||||
/**
|
||||
* NMSettingsConnectionIntFlags:
|
||||
* @NM_SETTINGS_CONNECTION_INT_FLAGS_NONE: no flag set
|
||||
|
|
@ -61,38 +124,37 @@
|
|||
* currently active but cleanup on disconnect.
|
||||
* See also #NM_SETTINGS_CONNECTION_FLAG_VOLATILE.
|
||||
* @NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE: The connection is visible
|
||||
* @NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK: the entire enum is
|
||||
* @_NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK: the entire enum is
|
||||
* internal, however, parts of it is public API as #NMSettingsConnectionFlags.
|
||||
* This mask, are the public flags.
|
||||
* @NM_SETTINGS_CONNECTION_INT_FLAGS_ALL: special mask, for all known flags
|
||||
* @_NM_SETTINGS_CONNECTION_INT_FLAGS_ALL: special mask, for all known flags
|
||||
*
|
||||
* #NMSettingsConnection flags.
|
||||
**/
|
||||
typedef enum {
|
||||
typedef enum _NMSettingsConnectionIntFlags {
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NONE = 0,
|
||||
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED = NM_SETTINGS_CONNECTION_FLAG_UNSAVED,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED = NM_SETTINGS_CONNECTION_FLAG_NM_GENERATED,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE = NM_SETTINGS_CONNECTION_FLAG_VOLATILE,
|
||||
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE = (1LL << 3),
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE = 0x08,
|
||||
|
||||
__NM_SETTINGS_CONNECTION_INT_FLAGS_LAST,
|
||||
_NM_SETTINGS_CONNECTION_INT_FLAGS_LAST,
|
||||
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK = 0
|
||||
_NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK = 0
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
|
||||
| 0,
|
||||
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_INT_FLAGS_LAST - 1) << 1) - 1,
|
||||
} NMSettingsConnectionIntFlags;
|
||||
_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK = 0
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
|
||||
| 0,
|
||||
|
||||
typedef enum {
|
||||
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE = 0,
|
||||
NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION = (1LL << 0),
|
||||
NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED = (1LL << 1),
|
||||
} NMSettingsConnectionCommitReason;
|
||||
_NM_SETTINGS_CONNECTION_INT_FLAGS_ALL = ((_NM_SETTINGS_CONNECTION_INT_FLAGS_LAST - 1) << 1) - 1,
|
||||
} NMSettingsConnectionIntFlags;
|
||||
|
||||
typedef enum {
|
||||
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE = 0,
|
||||
|
|
@ -106,7 +168,6 @@ typedef enum {
|
|||
| NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS),
|
||||
} NMSettingsAutoconnectBlockedReason;
|
||||
|
||||
struct _NMSettingsConnectionCallId;
|
||||
typedef struct _NMSettingsConnectionCallId NMSettingsConnectionCallId;
|
||||
|
||||
typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass;
|
||||
|
|
@ -115,62 +176,48 @@ struct _NMSettingsConnectionPrivate;
|
|||
|
||||
struct _NMSettingsConnection {
|
||||
NMDBusObject parent;
|
||||
struct _NMSettingsConnectionPrivate *_priv;
|
||||
CList _connections_lst;
|
||||
};
|
||||
|
||||
struct _NMSettingsConnectionClass {
|
||||
NMDBusObjectClass parent;
|
||||
|
||||
gboolean (*commit_changes) (NMSettingsConnection *self,
|
||||
NMConnection *new_connection,
|
||||
NMSettingsConnectionCommitReason commit_reason,
|
||||
NMConnection **out_reread_connection,
|
||||
char **out_logmsg_change,
|
||||
GError **error);
|
||||
|
||||
gboolean (*delete) (NMSettingsConnection *self,
|
||||
GError **error);
|
||||
struct _NMSettingsConnectionPrivate *_priv;
|
||||
};
|
||||
|
||||
GType nm_settings_connection_get_type (void);
|
||||
|
||||
NMSettingsConnection *nm_settings_connection_new (void);
|
||||
|
||||
NMConnection *nm_settings_connection_get_connection (NMSettingsConnection *self);
|
||||
|
||||
void _nm_settings_connection_set_connection (NMSettingsConnection *self,
|
||||
NMConnection *new_connection,
|
||||
NMConnection **out_old_connection,
|
||||
NMSettingsConnectionUpdateReason update_reason);
|
||||
|
||||
NMSettingsStorage *nm_settings_connection_get_storage (NMSettingsConnection *self);
|
||||
|
||||
void _nm_settings_connection_set_storage (NMSettingsConnection *self,
|
||||
NMSettingsStorage *storage);
|
||||
|
||||
gboolean nm_settings_connection_still_valid (NMSettingsConnection *self);
|
||||
|
||||
const char *nm_settings_connection_get_filename (NMSettingsConnection *self);
|
||||
|
||||
guint64 nm_settings_connection_get_last_secret_agent_version_id (NMSettingsConnection *self);
|
||||
|
||||
gboolean nm_settings_connection_has_unmodified_applied_connection (NMSettingsConnection *self,
|
||||
NMConnection *applied_connection,
|
||||
NMSettingCompareFlags compare_flage);
|
||||
|
||||
typedef enum {
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
|
||||
|
||||
/* like KEEP, but always clears the UNSAVED flag */
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
|
||||
|
||||
/* unsaved, only sets the unsaved flag, but it doesn't touch
|
||||
* the NM_GENERATED nor VOLATILE flag. */
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED,
|
||||
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_DETACHED,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_ONLY,
|
||||
} NMSettingsConnectionPersistMode;
|
||||
|
||||
gboolean nm_settings_connection_update (NMSettingsConnection *self,
|
||||
NMConnection *new_connection,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
NMSettingsConnectionCommitReason commit_reason,
|
||||
const char *log_diff_name,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_settings_connection_delete (NMSettingsConnection *self,
|
||||
gboolean nm_settings_connection_update (NMSettingsConnection *self,
|
||||
NMConnection *new_connection,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
NMSettingsConnectionIntFlags sett_flags,
|
||||
NMSettingsConnectionIntFlags sett_mask,
|
||||
NMSettingsConnectionUpdateReason update_reason,
|
||||
const char *log_context_name,
|
||||
GError **error);
|
||||
|
||||
void nm_settings_connection_delete (NMSettingsConnection *self,
|
||||
gboolean allow_add_to_no_auto_default);
|
||||
|
||||
typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *self,
|
||||
NMSettingsConnectionCallId *call_id,
|
||||
const char *agent_username,
|
||||
|
|
@ -196,21 +243,44 @@ NMSettingsConnectionCallId *nm_settings_connection_get_secrets (NMSettingsConnec
|
|||
void nm_settings_connection_cancel_secrets (NMSettingsConnection *self,
|
||||
NMSettingsConnectionCallId *call_id);
|
||||
|
||||
void nm_settings_connection_recheck_visibility (NMSettingsConnection *self);
|
||||
void nm_settings_connection_clear_secrets (NMSettingsConnection *self,
|
||||
gboolean clear_cached_system_secrets,
|
||||
gboolean persist);
|
||||
|
||||
gboolean nm_settings_connection_check_visibility (NMSettingsConnection *self,
|
||||
NMSessionMonitor *session_monitor);
|
||||
|
||||
gboolean nm_settings_connection_check_permission (NMSettingsConnection *self,
|
||||
const char *permission);
|
||||
|
||||
void nm_settings_connection_added (NMSettingsConnection *self);
|
||||
/*****************************************************************************/
|
||||
|
||||
void nm_settings_connection_signal_remove (NMSettingsConnection *self);
|
||||
NMDevice *nm_settings_connection_default_wired_get_device (NMSettingsConnection *self);
|
||||
void nm_settings_connection_default_wired_set_device (NMSettingsConnection *self,
|
||||
NMDevice *device);
|
||||
|
||||
gboolean nm_settings_connection_get_unsaved (NMSettingsConnection *self);
|
||||
/*****************************************************************************/
|
||||
|
||||
NMSettingsConnectionIntFlags nm_settings_connection_get_flags (NMSettingsConnection *self);
|
||||
NMSettingsConnectionIntFlags nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionIntFlags flags, gboolean set);
|
||||
|
||||
static inline gboolean
|
||||
nm_settings_connection_get_unsaved (NMSettingsConnection *self)
|
||||
{
|
||||
return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED);
|
||||
}
|
||||
|
||||
NMSettingsConnectionIntFlags nm_settings_connection_set_flags_full (NMSettingsConnection *self, NMSettingsConnectionIntFlags mask, NMSettingsConnectionIntFlags value);
|
||||
|
||||
static inline NMSettingsConnectionIntFlags
|
||||
nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionIntFlags flags, gboolean set)
|
||||
{
|
||||
return nm_settings_connection_set_flags_full (self,
|
||||
flags,
|
||||
set ? flags : NM_SETTINGS_CONNECTION_INT_FLAGS_NONE);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int nm_settings_connection_cmp_timestamp (NMSettingsConnection *ac, NMSettingsConnection *ab);
|
||||
int nm_settings_connection_cmp_timestamp_p_with_data (gconstpointer pa, gconstpointer pb, gpointer user_data);
|
||||
int nm_settings_connection_cmp_autoconnect_priority (NMSettingsConnection *a, NMSettingsConnection *b);
|
||||
|
|
@ -218,9 +288,9 @@ int nm_settings_connection_cmp_autoconnect_priority_p_with_data (gconstpointer p
|
|||
|
||||
struct _NMKeyFileDB;
|
||||
|
||||
void nm_settings_connection_register_kf_dbs (NMSettingsConnection *self,
|
||||
struct _NMKeyFileDB *kf_db_timestamps,
|
||||
struct _NMKeyFileDB *kf_db_seen_bssids);
|
||||
void _nm_settings_connection_register_kf_dbs (NMSettingsConnection *self,
|
||||
struct _NMKeyFileDB *kf_db_timestamps,
|
||||
struct _NMKeyFileDB *kf_db_seen_bssids);
|
||||
|
||||
gboolean nm_settings_connection_get_timestamp (NMSettingsConnection *self,
|
||||
guint64 *out_timestamp);
|
||||
|
|
@ -259,14 +329,6 @@ nm_settings_connection_autoconnect_blocked_reason_set (NMSettingsConnection *sel
|
|||
|
||||
gboolean nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self);
|
||||
|
||||
gboolean nm_settings_connection_get_ready (NMSettingsConnection *self);
|
||||
void nm_settings_connection_set_ready (NMSettingsConnection *self,
|
||||
gboolean ready);
|
||||
|
||||
void nm_settings_connection_set_filename (NMSettingsConnection *self,
|
||||
const char *filename);
|
||||
const char *nm_settings_connection_get_filename (NMSettingsConnection *self);
|
||||
|
||||
const char *nm_settings_connection_get_id (NMSettingsConnection *connection);
|
||||
const char *nm_settings_connection_get_uuid (NMSettingsConnection *connection);
|
||||
const char *nm_settings_connection_get_connection_type (NMSettingsConnection *connection);
|
||||
|
|
@ -276,4 +338,14 @@ const char *nm_settings_connection_get_connection_type (NMSettingsConnection *co
|
|||
NMConnection **nm_settings_connections_array_to_connections (NMSettingsConnection *const*connections,
|
||||
gssize n_connections);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void _nm_settings_connection_emit_dbus_signal_updated (NMSettingsConnection *self);
|
||||
void _nm_settings_connection_emit_dbus_signal_removed (NMSettingsConnection *self);
|
||||
|
||||
void _nm_settings_connection_emit_signal_updated_internal (NMSettingsConnection *self,
|
||||
NMSettingsConnectionUpdateReason update_reason);
|
||||
|
||||
void _nm_settings_connection_cleanup_after_remove (NMSettingsConnection *self);
|
||||
|
||||
#endif /* __NETWORKMANAGER_SETTINGS_CONNECTION_H__ */
|
||||
|
|
|
|||
|
|
@ -22,12 +22,14 @@
|
|||
|
||||
#include "nm-settings-plugin.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
#include "nm-settings-connection.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
enum {
|
||||
CONNECTION_ADDED,
|
||||
UNMANAGED_SPECS_CHANGED,
|
||||
UNRECOGNIZED_SPECS_CHANGED,
|
||||
|
||||
|
|
@ -40,105 +42,202 @@ G_DEFINE_TYPE (NMSettingsPlugin, nm_settings_plugin, G_TYPE_OBJECT)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
GSList *
|
||||
nm_settings_plugin_get_connections (NMSettingsPlugin *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL);
|
||||
|
||||
if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_connections)
|
||||
return NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_connections (self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_settings_plugin_load_connection (NMSettingsPlugin *self,
|
||||
const char *filename)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), FALSE);
|
||||
|
||||
if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->load_connection)
|
||||
return NM_SETTINGS_PLUGIN_GET_CLASS (self)->load_connection (self, filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nm_settings_plugin_reload_connections (NMSettingsPlugin *self)
|
||||
{
|
||||
g_return_if_fail (NM_IS_SETTINGS_PLUGIN (self));
|
||||
|
||||
if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->reload_connections)
|
||||
NM_SETTINGS_PLUGIN_GET_CLASS (self)->reload_connections (self);
|
||||
}
|
||||
|
||||
GSList *
|
||||
nm_settings_plugin_get_unmanaged_specs (NMSettingsPlugin *self)
|
||||
{
|
||||
NMSettingsPluginClass *klass;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL);
|
||||
|
||||
if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_unmanaged_specs)
|
||||
return NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_unmanaged_specs (self);
|
||||
return NULL;
|
||||
klass = NM_SETTINGS_PLUGIN_GET_CLASS (self);
|
||||
if (!klass->get_unmanaged_specs)
|
||||
return NULL;
|
||||
return klass->get_unmanaged_specs (self);
|
||||
}
|
||||
|
||||
GSList *
|
||||
nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *self)
|
||||
{
|
||||
NMSettingsPluginClass *klass;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL);
|
||||
|
||||
if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_unrecognized_specs)
|
||||
return NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_unrecognized_specs (self);
|
||||
return NULL;
|
||||
klass = NM_SETTINGS_PLUGIN_GET_CLASS (self);
|
||||
if (!klass->get_unrecognized_specs)
|
||||
return NULL;
|
||||
return klass->get_unrecognized_specs (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_settings_plugin_add_connection:
|
||||
* @self: the #NMSettingsPlugin
|
||||
* @connection: the source connection to create a plugin-specific
|
||||
* #NMSettingsConnection from
|
||||
* @save_to_disk: %TRUE to save the connection to disk immediately, %FALSE to
|
||||
* not save to disk
|
||||
* @error: on return, a location to store any errors that may occur
|
||||
*
|
||||
* Creates a new #NMSettingsConnection for the given source @connection. If the
|
||||
* plugin cannot handle the given connection type, it should return %NULL and
|
||||
* set @error. The plugin owns the returned object and the caller must reference
|
||||
* the object if it wishes to continue using it.
|
||||
*
|
||||
* Returns: the new #NMSettingsConnection or %NULL
|
||||
*/
|
||||
NMSettingsConnection *
|
||||
void
|
||||
nm_settings_plugin_reload_connections (NMSettingsPlugin *self,
|
||||
NMSettingsPluginConnectionLoadCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSettingsPluginClass *klass;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTINGS_PLUGIN (self));
|
||||
g_return_if_fail (callback);
|
||||
|
||||
klass = NM_SETTINGS_PLUGIN_GET_CLASS (self);
|
||||
if (klass->reload_connections)
|
||||
klass->reload_connections (self, callback, user_data);
|
||||
}
|
||||
|
||||
NMSettingsPluginConnectionLoadEntry *
|
||||
nm_settings_plugin_create_connection_load_entries (const char *const*filenames,
|
||||
gsize *out_len)
|
||||
{
|
||||
NMSettingsPluginConnectionLoadEntry *entries;
|
||||
gsize len;
|
||||
gsize i;
|
||||
|
||||
len = NM_PTRARRAY_LEN (filenames);
|
||||
if (len == 0) {
|
||||
*out_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entries = g_new (NMSettingsPluginConnectionLoadEntry, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
entries[i] = (NMSettingsPluginConnectionLoadEntry) {
|
||||
.filename = filenames[i],
|
||||
.error = NULL,
|
||||
.handled = FALSE,
|
||||
};
|
||||
}
|
||||
|
||||
*out_len = len;
|
||||
return entries;
|
||||
}
|
||||
|
||||
void
|
||||
nm_settings_plugin_load_connections (NMSettingsPlugin *self,
|
||||
NMSettingsPluginConnectionLoadEntry *entries,
|
||||
gsize n_entries,
|
||||
NMSettingsPluginConnectionLoadCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSettingsPluginClass *klass;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTINGS_PLUGIN (self));
|
||||
|
||||
klass = NM_SETTINGS_PLUGIN_GET_CLASS (self);
|
||||
if (klass->load_connections)
|
||||
klass->load_connections (self, entries, n_entries, callback, user_data);
|
||||
}
|
||||
|
||||
void
|
||||
nm_settings_plugin_load_connections_done (NMSettingsPlugin *self)
|
||||
{
|
||||
NMSettingsPluginClass *klass;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTINGS_PLUGIN (self));
|
||||
|
||||
klass = NM_SETTINGS_PLUGIN_GET_CLASS (self);
|
||||
if (klass->load_connections_done)
|
||||
klass->load_connections_done (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_settings_plugin_add_connection (NMSettingsPlugin *self,
|
||||
NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
NMSettingsStorage **out_storage,
|
||||
NMConnection **out_connection,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingsPluginClass *klass;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), FALSE);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
|
||||
|
||||
#if NM_MORE_ASSERTS > 5
|
||||
nm_assert (nm_connection_verify (connection, NULL));
|
||||
#endif
|
||||
|
||||
NM_SET_OUT (out_storage, NULL);
|
||||
NM_SET_OUT (out_connection, NULL);
|
||||
|
||||
klass = NM_SETTINGS_PLUGIN_GET_CLASS (self);
|
||||
if (!klass->add_connection) {
|
||||
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED,
|
||||
"Plugin does not support adding connections");
|
||||
return NULL;
|
||||
"settings plugin does not support adding connections");
|
||||
return FALSE;
|
||||
}
|
||||
return klass->add_connection (self,
|
||||
connection,
|
||||
out_storage,
|
||||
out_connection,
|
||||
error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_settings_plugin_update_connection (NMSettingsPlugin *self,
|
||||
NMSettingsStorage *storage,
|
||||
NMConnection *connection,
|
||||
NMSettingsStorage **out_storage,
|
||||
NMConnection **out_connection,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingsPluginClass *klass = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), FALSE);
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (storage), FALSE);
|
||||
g_return_val_if_fail (nm_settings_storage_get_plugin (storage) == self, FALSE);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
|
||||
|
||||
#if NM_MORE_ASSERTS > 5
|
||||
nm_assert (nm_connection_verify (connection, NULL));
|
||||
nm_assert (nm_streq (nm_connection_get_uuid (connection), nm_settings_storage_get_uuid (storage)));
|
||||
#endif
|
||||
|
||||
klass = NM_SETTINGS_PLUGIN_GET_CLASS (self);
|
||||
|
||||
NM_SET_OUT (out_storage, NULL);
|
||||
NM_SET_OUT (out_connection, NULL);
|
||||
|
||||
if (!klass->update_connection) {
|
||||
g_set_error (error,
|
||||
NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_NOT_SUPPORTED,
|
||||
"settings plugin does not support modifying connections");
|
||||
return FALSE;
|
||||
}
|
||||
return klass->update_connection (self,
|
||||
storage,
|
||||
connection,
|
||||
out_storage,
|
||||
out_connection,
|
||||
error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_settings_plugin_delete_connection (NMSettingsPlugin *self,
|
||||
NMSettingsStorage *storage,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingsPluginClass *klass = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), FALSE);
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (storage), FALSE);
|
||||
g_return_val_if_fail (nm_settings_storage_get_plugin (storage) == self, FALSE);
|
||||
|
||||
klass = NM_SETTINGS_PLUGIN_GET_CLASS (self);
|
||||
|
||||
if (!klass->delete_connection) {
|
||||
g_set_error (error,
|
||||
NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_NOT_SUPPORTED,
|
||||
"settings plugin does not support deleting connections");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return klass->add_connection (self, connection, save_to_disk, error);
|
||||
return klass->delete_connection (self,
|
||||
storage,
|
||||
error);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
_nm_settings_plugin_emit_signal_connection_added (NMSettingsPlugin *self,
|
||||
NMSettingsConnection *sett_conn)
|
||||
{
|
||||
nm_assert (NM_IS_SETTINGS_PLUGIN (self));
|
||||
nm_assert (NM_IS_SETTINGS_CONNECTION (sett_conn));
|
||||
|
||||
g_signal_emit (self, signals[CONNECTION_ADDED], 0, sett_conn);
|
||||
}
|
||||
|
||||
void
|
||||
_nm_settings_plugin_emit_signal_unmanaged_specs_changed (NMSettingsPlugin *self)
|
||||
{
|
||||
|
|
@ -167,15 +266,6 @@ nm_settings_plugin_class_init (NMSettingsPluginClass *klass)
|
|||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
signals[CONNECTION_ADDED] =
|
||||
g_signal_new (NM_SETTINGS_PLUGIN_CONNECTION_ADDED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
NM_TYPE_SETTINGS_CONNECTION);
|
||||
|
||||
signals[UNMANAGED_SPECS_CHANGED] =
|
||||
g_signal_new (NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
|
|
|
|||
|
|
@ -23,6 +23,21 @@
|
|||
|
||||
#include "nm-connection.h"
|
||||
|
||||
#include "nm-settings-storage.h"
|
||||
|
||||
typedef struct _NMSettingsPlugin NMSettingsPlugin;
|
||||
|
||||
typedef void (*NMSettingsPluginConnectionLoadCallback) (NMSettingsPlugin *self,
|
||||
NMSettingsStorage *storage,
|
||||
NMConnection *connection,
|
||||
gpointer user_data);
|
||||
|
||||
typedef struct {
|
||||
const char *filename;
|
||||
GError *error;
|
||||
bool handled:1;
|
||||
} NMSettingsPluginConnectionLoadEntry;
|
||||
|
||||
#define NM_TYPE_SETTINGS_PLUGIN (nm_settings_plugin_get_type ())
|
||||
#define NM_SETTINGS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPlugin))
|
||||
#define NM_SETTINGS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPluginClass))
|
||||
|
|
@ -32,32 +47,14 @@
|
|||
|
||||
#define NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED "unmanaged-specs-changed"
|
||||
#define NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED "unrecognized-specs-changed"
|
||||
#define NM_SETTINGS_PLUGIN_CONNECTION_ADDED "connection-added"
|
||||
|
||||
typedef struct {
|
||||
struct _NMSettingsPlugin {
|
||||
GObject parent;
|
||||
} NMSettingsPlugin;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
|
||||
/* Returns a GSList of NMSettingsConnection objects that represent
|
||||
* connections the plugin knows about. The returned list is freed by the
|
||||
* system settings service.
|
||||
*/
|
||||
GSList * (*get_connections) (NMSettingsPlugin *plugin);
|
||||
|
||||
/* Requests that the plugin load/reload a single connection, if it
|
||||
* recognizes the filename. Returns success or failure.
|
||||
*/
|
||||
gboolean (*load_connection) (NMSettingsPlugin *plugin,
|
||||
const char *filename);
|
||||
|
||||
/* Requests that the plugin reload all connection files from disk,
|
||||
* and emit signals reflecting new, changed, and removed connections.
|
||||
*/
|
||||
void (*reload_connections) (NMSettingsPlugin *plugin);
|
||||
|
||||
/*
|
||||
* Return a string list of specifications of devices which NetworkManager
|
||||
* should not manage. Returned list will be freed by the system settings
|
||||
|
|
@ -67,7 +64,7 @@ typedef struct {
|
|||
* Each string in the list must be in one of the formats recognized by
|
||||
* nm_device_spec_match_list().
|
||||
*/
|
||||
GSList * (*get_unmanaged_specs) (NMSettingsPlugin *plugin);
|
||||
GSList * (*get_unmanaged_specs) (NMSettingsPlugin *self);
|
||||
|
||||
/*
|
||||
* Return a string list of specifications of devices for which at least
|
||||
|
|
@ -79,49 +76,131 @@ typedef struct {
|
|||
* Each string in the list must be in one of the formats recognized by
|
||||
* nm_device_spec_match_list().
|
||||
*/
|
||||
GSList * (*get_unrecognized_specs) (NMSettingsPlugin *plugin);
|
||||
GSList * (*get_unrecognized_specs) (NMSettingsPlugin *self);
|
||||
|
||||
/*
|
||||
* Initialize the plugin-specific connection and return a new
|
||||
* NMSettingsConnection subclass that contains the same settings as the
|
||||
* original connection. The connection should only be saved to backing
|
||||
* storage if @save_to_disk is TRUE. The returned object is owned by the
|
||||
* plugin and must be referenced by the owner if necessary.
|
||||
/* Requests that the plugin load/reload a set of filenames.
|
||||
*/
|
||||
NMSettingsConnection * (*add_connection) (NMSettingsPlugin *plugin,
|
||||
NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
GError **error);
|
||||
void (*load_connections) (NMSettingsPlugin *self,
|
||||
NMSettingsPluginConnectionLoadEntry *entries,
|
||||
gsize n_entries,
|
||||
NMSettingsPluginConnectionLoadCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
/* Requests that the plugin reload all connection files from disk,
|
||||
* and emit signals reflecting new, changed, and removed connections.
|
||||
*/
|
||||
void (*reload_connections) (NMSettingsPlugin *self,
|
||||
NMSettingsPluginConnectionLoadCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void (*load_connections_done) (NMSettingsPlugin *self);
|
||||
|
||||
gboolean (*add_connection) (NMSettingsPlugin *self,
|
||||
NMConnection *connection,
|
||||
NMSettingsStorage **out_storage,
|
||||
NMConnection **out_connection,
|
||||
GError **error);
|
||||
|
||||
gboolean (*update_connection) (NMSettingsPlugin *self,
|
||||
NMSettingsStorage *storage,
|
||||
NMConnection *connection,
|
||||
NMSettingsStorage **out_storage,
|
||||
NMConnection **out_connection,
|
||||
GError **error);
|
||||
|
||||
gboolean (*delete_connection) (NMSettingsPlugin *self,
|
||||
NMSettingsStorage *storage,
|
||||
GError **error);
|
||||
|
||||
const char *plugin_name;
|
||||
|
||||
} NMSettingsPluginClass;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
GType nm_settings_plugin_get_type (void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_SETTINGS_STORAGE_PRINT_FMT \
|
||||
NM_HASH_OBFUSCATE_PTR_FMT"/%s"
|
||||
|
||||
#define NM_SETTINGS_STORAGE_PRINT_ARG(storage) \
|
||||
NM_HASH_OBFUSCATE_PTR (storage), \
|
||||
nm_settings_plugin_get_plugin_name (nm_settings_storage_get_plugin (storage))
|
||||
|
||||
static inline const char *
|
||||
nm_settings_plugin_get_plugin_name (NMSettingsPlugin *self)
|
||||
{
|
||||
NMSettingsPluginClass *klass;
|
||||
|
||||
nm_assert (NM_SETTINGS_PLUGIN (self));
|
||||
|
||||
klass = NM_SETTINGS_PLUGIN_GET_CLASS (self);
|
||||
|
||||
nm_assert (klass && klass->plugin_name && strlen (klass->plugin_name) > 0);
|
||||
|
||||
return klass->plugin_name;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
GSList *nm_settings_plugin_get_unmanaged_specs (NMSettingsPlugin *self);
|
||||
GSList *nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *self);
|
||||
|
||||
void nm_settings_plugin_reload_connections (NMSettingsPlugin *self,
|
||||
NMSettingsPluginConnectionLoadCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
NMSettingsPluginConnectionLoadEntry *nm_settings_plugin_create_connection_load_entries (const char *const*filenames,
|
||||
gsize *out_len);
|
||||
|
||||
void nm_settings_plugin_load_connections (NMSettingsPlugin *self,
|
||||
NMSettingsPluginConnectionLoadEntry *entries,
|
||||
gsize n_entries,
|
||||
NMSettingsPluginConnectionLoadCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void nm_settings_plugin_load_connections_done (NMSettingsPlugin *self);
|
||||
|
||||
gboolean nm_settings_plugin_add_connection (NMSettingsPlugin *self,
|
||||
NMConnection *connection,
|
||||
NMSettingsStorage **out_storage,
|
||||
NMConnection **out_connection,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_settings_plugin_update_connection (NMSettingsPlugin *self,
|
||||
NMSettingsStorage *storage,
|
||||
NMConnection *connection,
|
||||
NMSettingsStorage **out_storage,
|
||||
NMConnection **out_connection,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_settings_plugin_delete_connection (NMSettingsPlugin *self,
|
||||
NMSettingsStorage *storage,
|
||||
GError **error);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef NMSettingsPlugin *(*NMSettingsPluginFactoryFunc) (void);
|
||||
|
||||
/* Plugin's factory function that returns a #NMSettingsPlugin */
|
||||
NMSettingsPlugin *nm_settings_plugin_factory (void);
|
||||
|
||||
GSList *nm_settings_plugin_get_connections (NMSettingsPlugin *plugin);
|
||||
/*****************************************************************************
|
||||
* Internal API
|
||||
*****************************************************************************/
|
||||
|
||||
gboolean nm_settings_plugin_load_connection (NMSettingsPlugin *plugin,
|
||||
const char *filename);
|
||||
void nm_settings_plugin_reload_connections (NMSettingsPlugin *plugin);
|
||||
void _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NMSettingsPlugin *self);
|
||||
|
||||
GSList *nm_settings_plugin_get_unmanaged_specs (NMSettingsPlugin *plugin);
|
||||
GSList *nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *plugin);
|
||||
void _nm_settings_plugin_emit_signal_unrecognized_specs_changed (NMSettingsPlugin *self);
|
||||
|
||||
NMSettingsConnection *nm_settings_plugin_add_connection (NMSettingsPlugin *plugin,
|
||||
NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
GError **error);
|
||||
/*****************************************************************************/
|
||||
|
||||
/* internal API */
|
||||
/* forward declare this function from NMSettings. It's used by the ifcfg-rh plugin,
|
||||
* but that shouldn't include all "nm-settings.h" header. */
|
||||
NMSettings *nm_settings_get (void);
|
||||
|
||||
void _nm_settings_plugin_emit_signal_connection_added (NMSettingsPlugin *plugin,
|
||||
NMSettingsConnection *sett_conn);
|
||||
|
||||
void _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NMSettingsPlugin *plugin);
|
||||
|
||||
void _nm_settings_plugin_emit_signal_unrecognized_specs_changed (NMSettingsPlugin *plugin);
|
||||
const char *nm_settings_get_dbus_path_for_uuid (NMSettings *self,
|
||||
const char *uuid);
|
||||
|
||||
#endif /* __NM_SETTINGS_PLUGIN_H__ */
|
||||
|
|
|
|||
197
src/settings/nm-settings-storage.c
Normal file
197
src/settings/nm-settings-storage.c
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-settings-storage.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "nm-settings-plugin.h"
|
||||
|
||||
#include "settings/plugins/keyfile/nms-keyfile-storage.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
nm_settings_storage_cmp (NMSettingsStorage *a,
|
||||
NMSettingsStorage *b,
|
||||
const GSList *plugin_list)
|
||||
{
|
||||
NMSettingsStorageClass *klass;
|
||||
NMSettingsPlugin *plugin_a;
|
||||
NMSettingsPlugin *plugin_b;
|
||||
|
||||
/* Sort by priority.
|
||||
*
|
||||
* If a > b (by priority), we return a positive number (as one
|
||||
* would expect by a cmp() function). */
|
||||
|
||||
nm_assert (NM_IS_SETTINGS_STORAGE (a));
|
||||
nm_assert (NM_IS_SETTINGS_STORAGE (b));
|
||||
nm_assert (a != b);
|
||||
nm_assert (nm_streq (nm_settings_storage_get_uuid (a), nm_settings_storage_get_uuid (b)));
|
||||
|
||||
/* in-memory has always higher priority */
|
||||
NM_CMP_DIRECT (nm_settings_storage_is_keyfile_run (a),
|
||||
nm_settings_storage_is_keyfile_run (b));
|
||||
|
||||
plugin_a = nm_settings_storage_get_plugin (a);
|
||||
plugin_b = nm_settings_storage_get_plugin (b);
|
||||
|
||||
if (plugin_a != plugin_b) {
|
||||
int idx_a = g_slist_index ((GSList *) plugin_list, plugin_a);
|
||||
int idx_b = g_slist_index ((GSList *) plugin_list, plugin_b);
|
||||
|
||||
/* the plugins must be found in the list. */
|
||||
nm_assert (idx_a >= 0);
|
||||
nm_assert (idx_b >= 0);
|
||||
nm_assert (idx_a != idx_b);
|
||||
|
||||
/* plugins that appear first in @plugin_list have higher priority.
|
||||
* That means: smaller index -> higher priority. Reverse sort. */
|
||||
NM_CMP_DIRECT (idx_b, idx_a);
|
||||
|
||||
/* undecided. We really don't expect unknown plugins here. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
klass = NM_SETTINGS_STORAGE_GET_CLASS (a);
|
||||
|
||||
if (klass != NM_SETTINGS_STORAGE_GET_CLASS (b)) {
|
||||
/* one plugin must return storages of the same type. Otherwise, it's
|
||||
* unclear how cmp_fcn() should compare them. */
|
||||
nm_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (klass->cmp_fcn)
|
||||
NM_CMP_RETURN (klass->cmp_fcn (a, b));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
||||
PROP_PLUGIN,
|
||||
PROP_UUID,
|
||||
PROP_FILENAME,
|
||||
);
|
||||
|
||||
G_DEFINE_TYPE (NMSettingsStorage, nm_settings_storage, G_TYPE_OBJECT)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMSettingsStorage *self = NM_SETTINGS_STORAGE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PLUGIN:
|
||||
/* construct-only */
|
||||
self->_plugin = g_object_ref (g_value_get_object (value));
|
||||
nm_assert (NM_IS_SETTINGS_PLUGIN (self->_plugin));
|
||||
break;
|
||||
case PROP_UUID:
|
||||
/* construct-only */
|
||||
self->_uuid = g_value_dup_string (value);
|
||||
nm_assert (!self->_uuid || nm_utils_is_uuid (self->_uuid));
|
||||
break;
|
||||
case PROP_FILENAME:
|
||||
/* construct-only */
|
||||
self->_filename = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_settings_storage_init (NMSettingsStorage *self)
|
||||
{
|
||||
c_list_init (&self->_storage_lst);
|
||||
c_list_init (&self->_storage_by_uuid_lst);
|
||||
}
|
||||
|
||||
NMSettingsStorage *
|
||||
nm_settings_storage_new (NMSettingsPlugin *plugin,
|
||||
const char *uuid,
|
||||
const char *filename)
|
||||
{
|
||||
nm_assert (NM_IS_SETTINGS_PLUGIN (plugin));
|
||||
nm_assert (nm_utils_is_uuid (uuid));
|
||||
|
||||
return g_object_new (NM_TYPE_SETTINGS_STORAGE,
|
||||
NM_SETTINGS_STORAGE_PLUGIN, plugin,
|
||||
NM_SETTINGS_STORAGE_UUID, uuid,
|
||||
NM_SETTINGS_STORAGE_FILENAME, filename,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMSettingsStorage *self = NM_SETTINGS_STORAGE (object);
|
||||
|
||||
c_list_unlink_stale (&self->_storage_lst);
|
||||
c_list_unlink_stale (&self->_storage_by_uuid_lst);
|
||||
|
||||
g_object_unref (self->_plugin);
|
||||
g_free (self->_uuid);
|
||||
g_free (self->_filename);
|
||||
|
||||
G_OBJECT_CLASS (nm_settings_storage_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_settings_storage_class_init (NMSettingsStorageClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = set_property;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
obj_properties[PROP_PLUGIN] =
|
||||
g_param_spec_object (NM_SETTINGS_STORAGE_PLUGIN, "", "",
|
||||
NM_TYPE_SETTINGS_PLUGIN,
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_properties[PROP_UUID] =
|
||||
g_param_spec_string (NM_SETTINGS_STORAGE_UUID, "", "",
|
||||
NULL,
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_properties[PROP_FILENAME] =
|
||||
g_param_spec_string (NM_SETTINGS_STORAGE_FILENAME, "", "",
|
||||
NULL,
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
}
|
||||
122
src/settings/nm-settings-storage.h
Normal file
122
src/settings/nm-settings-storage.h
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_SETTINGS_STORAGE_H__
|
||||
#define __NM_SETTINGS_STORAGE_H__
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "c-list/src/c-list.h"
|
||||
|
||||
#define NM_TYPE_SETTINGS_STORAGE (nm_settings_storage_get_type ())
|
||||
#define NM_SETTINGS_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_STORAGE, NMSettingsStorage))
|
||||
#define NM_SETTINGS_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_STORAGE, NMSettingsStorageClass))
|
||||
#define NM_IS_SETTINGS_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_STORAGE))
|
||||
#define NM_IS_SETTINGS_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS_STORAGE))
|
||||
#define NM_SETTINGS_STORAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_STORAGE, NMSettingsStorageClass))
|
||||
|
||||
#define NM_SETTINGS_STORAGE_PLUGIN "plugin"
|
||||
#define NM_SETTINGS_STORAGE_UUID "uuid"
|
||||
#define NM_SETTINGS_STORAGE_FILENAME "filename"
|
||||
|
||||
struct _NMSettingsPlugin;
|
||||
|
||||
typedef struct NMSettingsStorage {
|
||||
GObject parent;
|
||||
struct _NMSettingsPlugin *_plugin;
|
||||
char *_uuid;
|
||||
char *_filename;
|
||||
CList _storage_lst;
|
||||
CList _storage_by_uuid_lst;
|
||||
} NMSettingsStorage;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
|
||||
int (*cmp_fcn) (NMSettingsStorage *a,
|
||||
NMSettingsStorage *b);
|
||||
|
||||
} NMSettingsStorageClass;
|
||||
|
||||
GType nm_settings_storage_get_type (void);
|
||||
|
||||
NMSettingsStorage *nm_settings_storage_new (struct _NMSettingsPlugin *plugin,
|
||||
const char *uuid,
|
||||
const char *filename);
|
||||
|
||||
static inline struct _NMSettingsPlugin *
|
||||
nm_settings_storage_get_plugin (const NMSettingsStorage *self)
|
||||
{
|
||||
GType nm_settings_plugin_get_type (void);
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (self), NULL);
|
||||
|
||||
nm_assert (G_TYPE_CHECK_INSTANCE_TYPE (self->_plugin, nm_settings_plugin_get_type ()));
|
||||
return self->_plugin;
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
nm_settings_storage_get_uuid (const NMSettingsStorage *self)
|
||||
{
|
||||
gboolean nm_utils_is_uuid (const char *str);
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (self), NULL);
|
||||
|
||||
nm_assert (nm_utils_is_uuid (self->_uuid));
|
||||
return self->_uuid;
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
nm_settings_storage_get_uuid_opt (const NMSettingsStorage *self)
|
||||
{
|
||||
gboolean nm_utils_is_uuid (const char *str);
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (self), NULL);
|
||||
|
||||
nm_assert (!self->_uuid || nm_utils_is_uuid (self->_uuid));
|
||||
return self->_uuid;
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
nm_settings_storage_get_filename (const NMSettingsStorage *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (self), NULL);
|
||||
|
||||
return self->_filename;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define nm_assert_valid_settings_storage(plugin, storage) \
|
||||
G_STMT_START { \
|
||||
NMSettingsPlugin *const _plugin = (plugin); \
|
||||
NMSettingsStorage *const _storage = (storage); \
|
||||
\
|
||||
nm_assert (!_plugin || NM_IS_SETTINGS_PLUGIN (_plugin)); \
|
||||
nm_assert (NM_IS_SETTINGS_STORAGE (_storage)); \
|
||||
nm_assert (!_plugin || nm_settings_storage_get_plugin (_storage) == _plugin); \
|
||||
} G_STMT_END
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int nm_settings_storage_cmp (NMSettingsStorage *sd_a,
|
||||
NMSettingsStorage *sd_b,
|
||||
const GSList *plugin_list);
|
||||
|
||||
#endif /* __NM_SETTINGS_STORAGE_H__ */
|
||||
175
src/settings/nm-settings-utils.c
Normal file
175
src/settings/nm-settings-utils.c
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/* 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) 2019 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-settings-utils.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nm-settings-plugin.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const struct timespec *
|
||||
nm_sett_util_stat_mtime (const char *filename,
|
||||
gboolean do_lstat,
|
||||
struct timespec *out_val)
|
||||
{
|
||||
struct stat st;
|
||||
struct timeval now_tv;
|
||||
|
||||
if (filename) {
|
||||
if (do_lstat) {
|
||||
if (lstat (filename, &st) == 0) {
|
||||
*out_val = st.st_mtim;
|
||||
return out_val;
|
||||
}
|
||||
} else {
|
||||
if (stat (filename, &st) == 0) {
|
||||
*out_val = st.st_mtim;
|
||||
return out_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gettimeofday (&now_tv, NULL) == 0) {
|
||||
*out_val = (struct timespec) {
|
||||
.tv_sec = now_tv.tv_sec,
|
||||
.tv_nsec = now_tv.tv_usec * 1000u,
|
||||
};
|
||||
return out_val;
|
||||
}
|
||||
|
||||
*out_val = (struct timespec) { };
|
||||
return out_val;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_sett_util_allow_filename_cb (const char *filename,
|
||||
gpointer user_data)
|
||||
{
|
||||
const NMSettUtilAllowFilenameData *allow_filename_data = user_data;
|
||||
|
||||
if ( allow_filename_data->allowed_filename
|
||||
&& nm_streq (allow_filename_data->allowed_filename, filename))
|
||||
return TRUE;
|
||||
|
||||
return !g_hash_table_contains (allow_filename_data->idx_by_filename, filename);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_sett_util_storage_by_uuid_head_destroy (NMSettUtilStorageByUuidHead *sbuh)
|
||||
{
|
||||
CList *iter;
|
||||
|
||||
while ((iter = c_list_first (&sbuh->_storage_by_uuid_lst_head)))
|
||||
c_list_unlink (iter);
|
||||
g_free (sbuh);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_sett_util_storages_clear (NMSettUtilStorages *storages)
|
||||
{
|
||||
nm_clear_pointer (&storages->idx_by_uuid, g_hash_table_destroy);
|
||||
nm_clear_pointer (&storages->idx_by_filename, g_hash_table_destroy);
|
||||
nm_assert (c_list_is_empty (&storages->_storage_lst_head));
|
||||
}
|
||||
|
||||
void
|
||||
nm_sett_util_storages_add_take (NMSettUtilStorages *storages,
|
||||
gpointer storage_take_p /* NMSettingsStorage *, take reference */)
|
||||
{
|
||||
NMSettingsStorage *storage_take = storage_take_p;
|
||||
NMSettUtilStorageByUuidHead *sbuh;
|
||||
const char *uuid;
|
||||
|
||||
nm_assert (storage_take);
|
||||
nm_assert (c_list_is_empty (&storage_take->_storage_lst));
|
||||
nm_assert (c_list_is_empty (&storage_take->_storage_by_uuid_lst));
|
||||
nm_assert (nm_settings_storage_get_filename (storage_take));
|
||||
|
||||
if (!g_hash_table_replace (storages->idx_by_filename,
|
||||
(char *) nm_settings_storage_get_filename (storage_take),
|
||||
storage_take /* takes ownership of reference. */))
|
||||
nm_assert_not_reached ();
|
||||
|
||||
uuid = nm_settings_storage_get_uuid_opt (storage_take);
|
||||
|
||||
if (uuid) {
|
||||
sbuh = nm_sett_util_storages_lookup_by_uuid (storages, uuid);
|
||||
if (!sbuh) {
|
||||
gsize l = strlen (uuid) + 1;
|
||||
|
||||
sbuh = g_malloc (sizeof (NMSettUtilStorageByUuidHead) + l);
|
||||
sbuh->uuid = sbuh->uuid_data;
|
||||
c_list_init (&sbuh->_storage_by_uuid_lst_head);
|
||||
memcpy (sbuh->uuid_data, uuid, l);
|
||||
g_hash_table_add (storages->idx_by_uuid, sbuh);
|
||||
}
|
||||
c_list_link_tail (&sbuh->_storage_by_uuid_lst_head, &storage_take->_storage_by_uuid_lst);
|
||||
}
|
||||
|
||||
c_list_link_tail (&storages->_storage_lst_head, &storage_take->_storage_lst);
|
||||
}
|
||||
|
||||
gpointer /* NMSettingsStorage * */
|
||||
nm_sett_util_storages_steal (NMSettUtilStorages *storages,
|
||||
gpointer storage_p /* NMSettingsStorage **/)
|
||||
{
|
||||
NMSettingsStorage *storage = storage_p;
|
||||
NMSettUtilStorageByUuidHead *sbuh;
|
||||
const char *uuid;
|
||||
|
||||
nm_assert (storage);
|
||||
nm_assert (nm_sett_util_storages_lookup_by_filename (storages, nm_settings_storage_get_filename (storage)) == storage);
|
||||
nm_assert (c_list_contains (&storages->_storage_lst_head, &storage->_storage_lst));
|
||||
|
||||
uuid = nm_settings_storage_get_uuid_opt (storage);
|
||||
|
||||
if (!uuid) {
|
||||
nm_assert (c_list_is_empty (&storage->_storage_by_uuid_lst));
|
||||
} else {
|
||||
nm_assert (!c_list_is_empty (&storage->_storage_by_uuid_lst));
|
||||
|
||||
sbuh = nm_sett_util_storages_lookup_by_uuid (storages, uuid);
|
||||
|
||||
nm_assert (sbuh);
|
||||
nm_assert (c_list_contains (&sbuh->_storage_by_uuid_lst_head, &storage->_storage_by_uuid_lst));
|
||||
c_list_unlink (&storage->_storage_by_uuid_lst);
|
||||
|
||||
if (c_list_is_empty (&sbuh->_storage_by_uuid_lst_head))
|
||||
g_hash_table_remove (storages->idx_by_uuid, sbuh);
|
||||
}
|
||||
|
||||
c_list_unlink (&storage->_storage_lst);
|
||||
|
||||
g_hash_table_steal (storages->idx_by_filename, nm_settings_storage_get_filename (storage));
|
||||
|
||||
return storage;
|
||||
}
|
||||
110
src/settings/nm-settings-utils.h
Normal file
110
src/settings/nm-settings-utils.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2019 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_SETTINGS_UTILS_H__
|
||||
#define __NM_SETTINGS_UTILS_H__
|
||||
|
||||
#include "nm-settings-storage.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct timespec;
|
||||
|
||||
const struct timespec *nm_sett_util_stat_mtime (const char *filename,
|
||||
gboolean do_lstat,
|
||||
struct timespec *out_val);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
const char *uuid;
|
||||
|
||||
CList _storage_by_uuid_lst_head;
|
||||
|
||||
char uuid_data[];
|
||||
} NMSettUtilStorageByUuidHead;
|
||||
|
||||
typedef struct {
|
||||
CList _storage_lst_head;
|
||||
GHashTable *idx_by_filename;
|
||||
GHashTable *idx_by_uuid;
|
||||
} NMSettUtilStorages;
|
||||
|
||||
void nm_sett_util_storage_by_uuid_head_destroy (NMSettUtilStorageByUuidHead *sbuh);
|
||||
|
||||
#define NM_SETT_UTIL_STORAGES_INIT(storages, storage_destroy_fcn) \
|
||||
{ \
|
||||
._storage_lst_head = C_LIST_INIT (((storages)._storage_lst_head)), \
|
||||
.idx_by_filename = g_hash_table_new_full (nm_str_hash, \
|
||||
g_str_equal, \
|
||||
NULL, \
|
||||
(GDestroyNotify) storage_destroy_fcn), \
|
||||
.idx_by_uuid = g_hash_table_new_full (nm_pstr_hash, \
|
||||
nm_pstr_equal, \
|
||||
NULL, \
|
||||
(GDestroyNotify) nm_sett_util_storage_by_uuid_head_destroy), \
|
||||
}
|
||||
|
||||
void nm_sett_util_storages_clear (NMSettUtilStorages *storages);
|
||||
|
||||
#define nm_auto_clear_sett_util_storages nm_auto(nm_sett_util_storages_clear)
|
||||
|
||||
void nm_sett_util_storages_add_take (NMSettUtilStorages *storages,
|
||||
gpointer storage_take_p);
|
||||
|
||||
gpointer nm_sett_util_storages_steal (NMSettUtilStorages *storages,
|
||||
gpointer storage_p);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline gpointer /* NMSettingsStorage * */
|
||||
nm_sett_util_storages_lookup_by_filename (NMSettUtilStorages *storages,
|
||||
const char *filename)
|
||||
{
|
||||
nm_assert (filename);
|
||||
|
||||
return g_hash_table_lookup (storages->idx_by_filename, filename);
|
||||
}
|
||||
|
||||
static inline NMSettUtilStorageByUuidHead *
|
||||
nm_sett_util_storages_lookup_by_uuid (NMSettUtilStorages *storages,
|
||||
const char *uuid)
|
||||
{
|
||||
nm_assert (uuid);
|
||||
|
||||
return g_hash_table_lookup (storages->idx_by_uuid, &uuid);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
GHashTable *idx_by_filename;
|
||||
const char *allowed_filename;
|
||||
} NMSettUtilAllowFilenameData;
|
||||
|
||||
#define NM_SETT_UTIL_ALLOW_FILENAME_DATA(_storages, _allowed_filename) \
|
||||
(&((NMSettUtilAllowFilenameData) { \
|
||||
.idx_by_filename = (_storages)->idx_by_filename, \
|
||||
.allowed_filename = (_allowed_filename), \
|
||||
}))
|
||||
|
||||
gboolean nm_sett_util_allow_filename_cb (const char *filename,
|
||||
gpointer user_data);
|
||||
|
||||
#endif /* __NM_SETTINGS_UTILS_H__ */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include "nm-connection.h"
|
||||
|
||||
#include "nm-settings-connection.h"
|
||||
|
||||
#define NM_TYPE_SETTINGS (nm_settings_get_type ())
|
||||
#define NM_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS, NMSettings))
|
||||
#define NM_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS, NMSettingsClass))
|
||||
|
|
@ -67,6 +69,7 @@ NMSettings *nm_settings_get (void);
|
|||
#define NM_SETTINGS_GET (nm_settings_get ())
|
||||
|
||||
NMSettings *nm_settings_new (void);
|
||||
|
||||
gboolean nm_settings_start (NMSettings *self, GError **error);
|
||||
|
||||
typedef void (*NMSettingsAddCallback) (NMSettings *settings,
|
||||
|
|
@ -78,7 +81,8 @@ typedef void (*NMSettingsAddCallback) (NMSettings *settings,
|
|||
|
||||
void nm_settings_add_connection_dbus (NMSettings *self,
|
||||
NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
NMSettingsConnectionIntFlags sett_flags,
|
||||
NMAuthSubject *subject,
|
||||
GDBusMethodInvocation *context,
|
||||
NMSettingsAddCallback callback,
|
||||
|
|
@ -93,16 +97,36 @@ NMSettingsConnection **nm_settings_get_connections_clone (NMSettings *self,
|
|||
GCompareDataFunc sort_compare_func,
|
||||
gpointer sort_data);
|
||||
|
||||
NMSettingsConnection *nm_settings_add_connection (NMSettings *settings,
|
||||
NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
GError **error);
|
||||
gboolean nm_settings_add_connection (NMSettings *settings,
|
||||
NMConnection *connection,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
NMSettingsConnectionIntFlags sett_flags,
|
||||
NMSettingsConnection **out_sett_conn,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_settings_update_connection (NMSettings *self,
|
||||
NMSettingsConnection *sett_conn,
|
||||
NMConnection *new_connection,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
NMSettingsConnectionIntFlags sett_flags,
|
||||
NMSettingsConnectionIntFlags sett_mask,
|
||||
NMSettingsConnectionUpdateReason update_reason,
|
||||
const char *log_context_name,
|
||||
GError **error);
|
||||
|
||||
void nm_settings_delete_connection (NMSettings *self,
|
||||
NMSettingsConnection *sett_conn,
|
||||
gboolean allow_add_to_no_auto_default);
|
||||
|
||||
NMSettingsConnection *nm_settings_get_connection_by_path (NMSettings *settings,
|
||||
const char *path);
|
||||
|
||||
NMSettingsConnection *nm_settings_get_connection_by_uuid (NMSettings *settings,
|
||||
const char *uuid);
|
||||
|
||||
const char *nm_settings_get_dbus_path_for_uuid (NMSettings *self,
|
||||
const char *uuid);
|
||||
|
||||
gboolean nm_settings_has_connection (NMSettings *self, NMSettingsConnection *connection);
|
||||
|
||||
const GSList *nm_settings_get_unmanaged_specs (NMSettings *self);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ libnms_ifcfg_rh_core = static_library(
|
|||
dependencies: deps,
|
||||
)
|
||||
|
||||
sources = [dbus_sources] + core_sources + files('nms-ifcfg-rh-connection.c', 'nms-ifcfg-rh-plugin.c')
|
||||
sources = [dbus_sources] + core_sources + files('nms-ifcfg-rh-storage.c', 'nms-ifcfg-rh-plugin.c')
|
||||
|
||||
libnm_settings_plugin_ifcfg_rh = shared_module(
|
||||
'nm-settings-plugin-ifcfg-rh',
|
||||
|
|
|
|||
|
|
@ -1,400 +0,0 @@
|
|||
/* NetworkManager system settings service
|
||||
*
|
||||
* 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) 2008 - 2011 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nms-ifcfg-rh-connection.h"
|
||||
|
||||
#include <sys/inotify.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "nm-dbus-interface.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-wired.h"
|
||||
#include "nm-setting-wireless.h"
|
||||
#include "nm-setting-gsm.h"
|
||||
#include "nm-setting-cdma.h"
|
||||
#include "nm-setting-pppoe.h"
|
||||
#include "nm-setting-wireless-security.h"
|
||||
#include "nm-setting-8021x.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "nm-config.h"
|
||||
|
||||
#include "nms-ifcfg-rh-common.h"
|
||||
#include "nms-ifcfg-rh-reader.h"
|
||||
#include "nms-ifcfg-rh-writer.h"
|
||||
#include "nms-ifcfg-rh-utils.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
||||
PROP_UNMANAGED_SPEC,
|
||||
PROP_UNRECOGNIZED_SPEC,
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
char *unmanaged_spec;
|
||||
char *unrecognized_spec;
|
||||
|
||||
gulong devtimeout_link_changed_handler;
|
||||
guint devtimeout_timeout_id;
|
||||
} NMIfcfgConnectionPrivate;
|
||||
|
||||
struct _NMIfcfgConnection {
|
||||
NMSettingsConnection parent;
|
||||
NMIfcfgConnectionPrivate _priv;
|
||||
};
|
||||
|
||||
struct _NMIfcfgConnectionClass {
|
||||
NMSettingsConnectionClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SETTINGS_CONNECTION)
|
||||
|
||||
#define NM_IFCFG_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMIfcfgConnection, NM_IS_IFCFG_CONNECTION)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
devtimeout_ready (gpointer user_data)
|
||||
{
|
||||
NMIfcfgConnection *self = user_data;
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
priv->devtimeout_timeout_id = 0;
|
||||
nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
link_changed (NMPlatform *platform, int obj_type_i, int ifindex, const NMPlatformLink *link,
|
||||
int change_type_i,
|
||||
NMConnection *self)
|
||||
{
|
||||
const NMPlatformSignalChangeType change_type = change_type_i;
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE ((NMIfcfgConnection *) self);
|
||||
const char *ifname;
|
||||
|
||||
ifname = nm_connection_get_interface_name (self);
|
||||
if (g_strcmp0 (link->name, ifname) != 0)
|
||||
return;
|
||||
|
||||
if (change_type == NM_PLATFORM_SIGNAL_REMOVED)
|
||||
return;
|
||||
|
||||
nm_log_info (LOGD_SETTINGS, "Device %s appeared; connection '%s' now ready",
|
||||
ifname, nm_connection_get_id (self));
|
||||
|
||||
g_signal_handler_disconnect (platform, priv->devtimeout_link_changed_handler);
|
||||
priv->devtimeout_link_changed_handler = 0;
|
||||
g_source_remove (priv->devtimeout_timeout_id);
|
||||
|
||||
/* Don't declare the connection ready right away, since NMManager may not have
|
||||
* started processing the device yet.
|
||||
*/
|
||||
priv->devtimeout_timeout_id = g_idle_add (devtimeout_ready, self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
devtimeout_expired (gpointer user_data)
|
||||
{
|
||||
NMIfcfgConnection *self = user_data;
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
nm_log_info (LOGD_SETTINGS, "Device for connection '%s' did not appear before timeout",
|
||||
nm_settings_connection_get_id (NM_SETTINGS_CONNECTION (self)));
|
||||
|
||||
g_signal_handler_disconnect (NM_PLATFORM_GET, priv->devtimeout_link_changed_handler);
|
||||
priv->devtimeout_link_changed_handler = 0;
|
||||
priv->devtimeout_timeout_id = 0;
|
||||
|
||||
nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ifcfg_connection_check_devtimeout (NMIfcfgConnection *self)
|
||||
{
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
|
||||
NMSettingConnection *s_con;
|
||||
const char *ifname;
|
||||
const char *filename;
|
||||
guint devtimeout;
|
||||
const NMPlatformLink *pllink;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (self)));
|
||||
|
||||
if (!nm_setting_connection_get_autoconnect (s_con))
|
||||
return;
|
||||
ifname = nm_setting_connection_get_interface_name (s_con);
|
||||
if (!ifname)
|
||||
return;
|
||||
filename = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (self));
|
||||
if (!filename)
|
||||
return;
|
||||
|
||||
pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, ifname);
|
||||
if (pllink && pllink->initialized)
|
||||
return;
|
||||
|
||||
devtimeout = devtimeout_from_file (filename);
|
||||
if (!devtimeout)
|
||||
return;
|
||||
|
||||
/* ONBOOT=yes, DEVICE and DEVTIMEOUT are set, but device is not present */
|
||||
nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), FALSE);
|
||||
|
||||
nm_log_info (LOGD_SETTINGS, "Waiting %u seconds for %s to appear for connection '%s'",
|
||||
devtimeout, ifname, nm_settings_connection_get_id (NM_SETTINGS_CONNECTION (self)));
|
||||
|
||||
priv->devtimeout_link_changed_handler =
|
||||
g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_LINK_CHANGED,
|
||||
G_CALLBACK (link_changed), self);
|
||||
priv->devtimeout_timeout_id = g_timeout_add_seconds (devtimeout, devtimeout_expired, self);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
|
||||
|
||||
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unmanaged_spec;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_ifcfg_connection_get_unrecognized_spec (NMIfcfgConnection *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
|
||||
|
||||
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unrecognized_spec;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
commit_changes (NMSettingsConnection *connection,
|
||||
NMConnection *new_connection,
|
||||
NMSettingsConnectionCommitReason commit_reason,
|
||||
NMConnection **out_reread_connection,
|
||||
char **out_logmsg_change,
|
||||
GError **error)
|
||||
{
|
||||
const char *filename;
|
||||
gs_unref_object NMConnection *reread = NULL;
|
||||
gboolean reread_same = TRUE;
|
||||
const char *operation_message;
|
||||
gs_free char *ifcfg_path = NULL;
|
||||
|
||||
nm_assert (out_reread_connection && !*out_reread_connection);
|
||||
nm_assert (!out_logmsg_change || !*out_logmsg_change);
|
||||
|
||||
filename = nm_settings_connection_get_filename (connection);
|
||||
if (!nms_ifcfg_rh_writer_write_connection (new_connection,
|
||||
IFCFG_DIR,
|
||||
filename,
|
||||
NULL,
|
||||
NULL,
|
||||
&ifcfg_path,
|
||||
&reread,
|
||||
&reread_same,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
nm_assert ((!filename && ifcfg_path) || (filename && !ifcfg_path));
|
||||
if (ifcfg_path) {
|
||||
nm_settings_connection_set_filename (connection, ifcfg_path);
|
||||
operation_message = "persist";
|
||||
} else
|
||||
operation_message = "update";
|
||||
|
||||
if (reread && !reread_same)
|
||||
*out_reread_connection = g_steal_pointer (&reread);
|
||||
|
||||
NM_SET_OUT (out_logmsg_change,
|
||||
g_strdup_printf ("ifcfg-rh: %s %s",
|
||||
operation_message, filename));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
delete (NMSettingsConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
const char *filename;
|
||||
|
||||
filename = nm_settings_connection_get_filename (connection);
|
||||
if (filename) {
|
||||
gs_free char *keyfile = utils_get_keys_path (filename);
|
||||
gs_free char *routefile = utils_get_route_path (filename);
|
||||
gs_free char *route6file = utils_get_route6_path (filename);
|
||||
|
||||
g_unlink (filename);
|
||||
if (keyfile)
|
||||
g_unlink (keyfile);
|
||||
if (routefile)
|
||||
g_unlink (routefile);
|
||||
if (route6file)
|
||||
g_unlink (route6file);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE ((NMIfcfgConnection *) object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_UNMANAGED_SPEC:
|
||||
g_value_set_string (value, priv->unmanaged_spec);
|
||||
break;
|
||||
case PROP_UNRECOGNIZED_SPEC:
|
||||
g_value_set_string (value, priv->unrecognized_spec);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE ((NMIfcfgConnection *) object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_UNMANAGED_SPEC:
|
||||
priv->unmanaged_spec = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_UNRECOGNIZED_SPEC:
|
||||
priv->unrecognized_spec = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_ifcfg_connection_init (NMIfcfgConnection *self)
|
||||
{
|
||||
}
|
||||
|
||||
NMIfcfgConnection *
|
||||
nm_ifcfg_connection_new (NMConnection *source,
|
||||
const char *full_path,
|
||||
GError **error,
|
||||
gboolean *out_ignore_error)
|
||||
{
|
||||
GObject *object;
|
||||
NMConnection *tmp;
|
||||
char *unhandled_spec = NULL;
|
||||
const char *unmanaged_spec = NULL, *unrecognized_spec = NULL;
|
||||
|
||||
g_assert (source || full_path);
|
||||
|
||||
if (out_ignore_error)
|
||||
*out_ignore_error = FALSE;
|
||||
|
||||
/* If we're given a connection already, prefer that instead of re-reading */
|
||||
if (source)
|
||||
tmp = g_object_ref (source);
|
||||
else {
|
||||
tmp = connection_from_file (full_path,
|
||||
&unhandled_spec,
|
||||
error,
|
||||
out_ignore_error);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (unhandled_spec && g_str_has_prefix (unhandled_spec, "unmanaged:"))
|
||||
unmanaged_spec = unhandled_spec + strlen ("unmanaged:");
|
||||
else if (unhandled_spec && g_str_has_prefix (unhandled_spec, "unrecognized:"))
|
||||
unrecognized_spec = unhandled_spec + strlen ("unrecognized:");
|
||||
|
||||
object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION,
|
||||
NM_SETTINGS_CONNECTION_FILENAME, full_path,
|
||||
NM_IFCFG_CONNECTION_UNMANAGED_SPEC, unmanaged_spec,
|
||||
NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, unrecognized_spec,
|
||||
NULL);
|
||||
/* Update our settings with what was read from the file */
|
||||
if (nm_settings_connection_update (NM_SETTINGS_CONNECTION (object),
|
||||
tmp,
|
||||
full_path
|
||||
? NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED
|
||||
: NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED,
|
||||
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
|
||||
NULL,
|
||||
error))
|
||||
nm_ifcfg_connection_check_devtimeout (NM_IFCFG_CONNECTION (object));
|
||||
else
|
||||
g_clear_object (&object);
|
||||
|
||||
g_object_unref (tmp);
|
||||
g_free (unhandled_spec);
|
||||
return (NMIfcfgConnection *) object;
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE ((NMIfcfgConnection *) object);
|
||||
|
||||
nm_clear_g_signal_handler (NM_PLATFORM_GET, &priv->devtimeout_link_changed_handler);
|
||||
nm_clear_g_source (&priv->devtimeout_timeout_id);
|
||||
|
||||
g_clear_pointer (&priv->unmanaged_spec, g_free);
|
||||
g_clear_pointer (&priv->unrecognized_spec, g_free);
|
||||
|
||||
G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (ifcfg_connection_class);
|
||||
NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifcfg_connection_class);
|
||||
|
||||
object_class->set_property = set_property;
|
||||
object_class->get_property = get_property;
|
||||
object_class->dispose = dispose;
|
||||
|
||||
settings_class->delete = delete;
|
||||
settings_class->commit_changes = commit_changes;
|
||||
|
||||
obj_properties[PROP_UNMANAGED_SPEC] =
|
||||
g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED_SPEC, "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_properties[PROP_UNRECOGNIZED_SPEC] =
|
||||
g_param_spec_string (NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* NetworkManager system settings service
|
||||
*
|
||||
* 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) 2008 - 2011 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NETWORKMANAGER_IFCFG_CONNECTION_H__
|
||||
#define __NETWORKMANAGER_IFCFG_CONNECTION_H__
|
||||
|
||||
#include "nm-dbus-interface.h"
|
||||
#include "settings/nm-settings-connection.h"
|
||||
|
||||
#define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ())
|
||||
#define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection))
|
||||
#define NM_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass))
|
||||
#define NM_IS_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFCFG_CONNECTION))
|
||||
#define NM_IS_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IFCFG_CONNECTION))
|
||||
#define NM_IFCFG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass))
|
||||
|
||||
#define NM_IFCFG_CONNECTION_UNMANAGED_SPEC "unmanaged-spec"
|
||||
#define NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC "unrecognized-spec"
|
||||
|
||||
typedef struct _NMIfcfgConnection NMIfcfgConnection;
|
||||
typedef struct _NMIfcfgConnectionClass NMIfcfgConnectionClass;
|
||||
|
||||
GType nm_ifcfg_connection_get_type (void);
|
||||
|
||||
NMIfcfgConnection *nm_ifcfg_connection_new (NMConnection *source,
|
||||
const char *full_path,
|
||||
GError **error,
|
||||
gboolean *out_ignore_error);
|
||||
|
||||
const char *nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self);
|
||||
const char *nm_ifcfg_connection_get_unrecognized_spec (NMIfcfgConnection *self);
|
||||
|
||||
gboolean nm_ifcfg_connection_update (NMIfcfgConnection *self,
|
||||
GHashTable *new_settings,
|
||||
GError **error);
|
||||
|
||||
#endif /* __NETWORKMANAGER_IFCFG_CONNECTION_H__ */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -20,19 +20,19 @@
|
|||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _PLUGIN_H_
|
||||
#define _PLUGIN_H_
|
||||
#ifndef __NMS_IFCFG_RH_PLUGIN_H__
|
||||
#define __NMS_IFCFG_RH_PLUGIN_H__
|
||||
|
||||
#define SETTINGS_TYPE_PLUGIN_IFCFG (settings_plugin_ifcfg_get_type ())
|
||||
#define SETTINGS_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_IFCFG, SettingsPluginIfcfg))
|
||||
#define SETTINGS_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_IFCFG, SettingsPluginIfcfgClass))
|
||||
#define SETTINGS_IS_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SETTINGS_TYPE_PLUGIN_IFCFG))
|
||||
#define SETTINGS_IS_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SETTINGS_TYPE_PLUGIN_IFCFG))
|
||||
#define SETTINGS_PLUGIN_IFCFG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SETTINGS_TYPE_PLUGIN_IFCFG, SettingsPluginIfcfgClass))
|
||||
#define NMS_TYPE_IFCFG_RH_PLUGIN (nms_ifcfg_rh_plugin_get_type ())
|
||||
#define NMS_IFCFG_RH_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_IFCFG_RH_PLUGIN, NMSIfcfgRHPlugin))
|
||||
#define NMS_IFCFG_RH_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_IFCFG_RH_PLUGIN, NMSIfcfgRHPluginClass))
|
||||
#define NMS_IS_IFCFG_RH_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_IFCFG_RH_PLUGIN))
|
||||
#define NMS_IS_IFCFG_RH_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_IFCFG_RH_PLUGIN))
|
||||
#define NMS_IFCFG_RH_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_IFCFG_RH_PLUGIN, NMSIfcfgRHPluginClass))
|
||||
|
||||
typedef struct _SettingsPluginIfcfg SettingsPluginIfcfg;
|
||||
typedef struct _SettingsPluginIfcfgClass SettingsPluginIfcfgClass;
|
||||
typedef struct _NMSIfcfgRHPlugin NMSIfcfgRHPlugin;
|
||||
typedef struct _NMSIfcfgRHPluginClass NMSIfcfgRHPluginClass;
|
||||
|
||||
GType settings_plugin_ifcfg_get_type (void);
|
||||
GType nms_ifcfg_rh_plugin_get_type (void);
|
||||
|
||||
#endif /* _PLUGIN_H_ */
|
||||
#endif /* __NMS_IFCFG_RH_PLUGIN_H__ */
|
||||
|
|
|
|||
|
|
@ -6028,20 +6028,3 @@ nmtst_connection_from_file (const char *filename,
|
|||
error,
|
||||
NULL);
|
||||
}
|
||||
|
||||
guint
|
||||
devtimeout_from_file (const char *filename)
|
||||
{
|
||||
shvarFile *ifcfg;
|
||||
guint devtimeout;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, 0);
|
||||
|
||||
ifcfg = svOpenFile (filename, NULL);
|
||||
if (!ifcfg)
|
||||
return 0;
|
||||
|
||||
devtimeout = svGetValueInt64 (ifcfg, "DEVTIMEOUT", 10, 0, G_MAXUINT, 0);
|
||||
svCloseFile (ifcfg);
|
||||
return devtimeout;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
* Copyright (C) 2008 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __READER_H__
|
||||
#define __READER_H__
|
||||
#ifndef __NMS_IFCFG_RH_READER_H__
|
||||
#define __NMS_IFCFG_RH_READER_H__
|
||||
|
||||
#include "nm-connection.h"
|
||||
|
||||
|
|
@ -27,12 +27,10 @@ NMConnection *connection_from_file (const char *filename,
|
|||
GError **error,
|
||||
gboolean *out_ignore_error);
|
||||
|
||||
guint devtimeout_from_file (const char *filename);
|
||||
|
||||
NMConnection *nmtst_connection_from_file (const char *filename,
|
||||
const char *network_file,
|
||||
const char *test_type,
|
||||
char **out_unhandled,
|
||||
GError **error);
|
||||
|
||||
#endif /* __READER_H__ */
|
||||
#endif /* __NMS_IFCFG_RH_READER_H__ */
|
||||
|
|
|
|||
198
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c
Normal file
198
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/* NetworkManager
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nms-ifcfg-rh-storage.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-connection.h"
|
||||
#include "nms-ifcfg-rh-plugin.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NMSIfcfgRHStorageClass {
|
||||
NMSettingsStorageClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NMSIfcfgRHStorage, nms_ifcfg_rh_storage, NM_TYPE_SETTINGS_STORAGE)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nms_ifcfg_rh_storage_equal_type (const NMSIfcfgRHStorage *self_a,
|
||||
const NMSIfcfgRHStorage *self_b)
|
||||
{
|
||||
return (self_a == self_b)
|
||||
|| ( self_a
|
||||
&& self_b
|
||||
&& nm_streq0 (nms_ifcfg_rh_storage_get_uuid_opt (self_a),
|
||||
nms_ifcfg_rh_storage_get_uuid_opt (self_b))
|
||||
&& nm_streq0 (self_a->unmanaged_spec,
|
||||
self_b->unmanaged_spec)
|
||||
&& nm_streq0 (self_a->unrecognized_spec,
|
||||
self_b->unrecognized_spec));
|
||||
}
|
||||
|
||||
void
|
||||
nms_ifcfg_rh_storage_copy_content (NMSIfcfgRHStorage *dst,
|
||||
const NMSIfcfgRHStorage *src)
|
||||
{
|
||||
nm_assert (src != dst);
|
||||
nm_assert (src && dst);
|
||||
nm_assert (nms_ifcfg_rh_storage_equal_type (dst, src));
|
||||
nm_assert ( nms_ifcfg_rh_storage_get_filename (dst)
|
||||
&& nm_streq (nms_ifcfg_rh_storage_get_filename (dst),
|
||||
nms_ifcfg_rh_storage_get_filename (src)));
|
||||
|
||||
nm_g_object_ref_set (&dst->connection, src->connection);
|
||||
g_free (dst->unmanaged_spec);
|
||||
g_free (dst->unrecognized_spec);
|
||||
dst->unmanaged_spec = g_strdup (src->unmanaged_spec);
|
||||
dst->unrecognized_spec = g_strdup (src->unrecognized_spec);
|
||||
dst->stat_mtime = src->stat_mtime;
|
||||
}
|
||||
|
||||
NMConnection *
|
||||
nms_ifcfg_rh_storage_steal_connection (NMSIfcfgRHStorage *self)
|
||||
{
|
||||
nm_assert (NMS_IS_IFCFG_RH_STORAGE (self));
|
||||
|
||||
return g_steal_pointer (&self->connection);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
cmp_fcn (const NMSIfcfgRHStorage *a,
|
||||
const NMSIfcfgRHStorage *b)
|
||||
{
|
||||
nm_assert (NMS_IS_IFCFG_RH_STORAGE (a));
|
||||
nm_assert (NMS_IS_IFCFG_RH_STORAGE (b));
|
||||
nm_assert (a != b);
|
||||
|
||||
/* newer files are more important. */
|
||||
NM_CMP_FIELD (b, a, stat_mtime.tv_sec);
|
||||
NM_CMP_FIELD (b, a, stat_mtime.tv_nsec);
|
||||
|
||||
NM_CMP_DIRECT_STRCMP (nms_ifcfg_rh_storage_get_filename (a), nms_ifcfg_rh_storage_get_filename (b));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nms_ifcfg_rh_storage_init (NMSIfcfgRHStorage *self)
|
||||
{
|
||||
}
|
||||
|
||||
static NMSIfcfgRHStorage *
|
||||
_storage_new (NMSIfcfgRHPlugin *plugin,
|
||||
const char *uuid,
|
||||
const char *filename)
|
||||
{
|
||||
nm_assert (NMS_IS_IFCFG_RH_PLUGIN (plugin));
|
||||
nm_assert (!uuid || nm_utils_is_uuid (uuid));
|
||||
nm_assert (filename && filename[0] == '/');
|
||||
|
||||
return g_object_new (NMS_TYPE_IFCFG_RH_STORAGE,
|
||||
NM_SETTINGS_STORAGE_PLUGIN, plugin,
|
||||
NM_SETTINGS_STORAGE_UUID, uuid,
|
||||
NM_SETTINGS_STORAGE_FILENAME, filename,
|
||||
NULL);
|
||||
}
|
||||
|
||||
NMSIfcfgRHStorage *
|
||||
nms_ifcfg_rh_storage_new_connection (NMSIfcfgRHPlugin *plugin,
|
||||
const char *filename,
|
||||
NMConnection *connection_take,
|
||||
const struct timespec *mtime)
|
||||
{
|
||||
NMSIfcfgRHStorage *self;
|
||||
|
||||
nm_assert (NM_IS_CONNECTION (connection_take));
|
||||
nm_assert (_nm_connection_verify (connection_take, NULL) == NM_SETTING_VERIFY_SUCCESS);
|
||||
nmtst_connection_assert_unchanging (connection_take);
|
||||
|
||||
self = _storage_new (plugin,
|
||||
nm_connection_get_uuid (connection_take),
|
||||
filename);
|
||||
self->connection = connection_take;
|
||||
if (mtime)
|
||||
self->stat_mtime = *mtime;
|
||||
return self;
|
||||
}
|
||||
|
||||
NMSIfcfgRHStorage *
|
||||
nms_ifcfg_rh_storage_new_unhandled (NMSIfcfgRHPlugin *plugin,
|
||||
const char *filename,
|
||||
const char *unmanaged_spec,
|
||||
const char *unrecognized_spec)
|
||||
{
|
||||
NMSIfcfgRHStorage *self;
|
||||
|
||||
nm_assert (unmanaged_spec || unrecognized_spec);
|
||||
|
||||
self = _storage_new (plugin,
|
||||
NULL,
|
||||
filename);
|
||||
self->unmanaged_spec = g_strdup (unmanaged_spec);
|
||||
self->unrecognized_spec = g_strdup (unrecognized_spec);
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
_storage_clear (NMSIfcfgRHStorage *self)
|
||||
{
|
||||
c_list_unlink (&self->parent._storage_lst);
|
||||
c_list_unlink (&self->parent._storage_by_uuid_lst);
|
||||
nm_clear_g_free (&self->unmanaged_spec);
|
||||
nm_clear_g_free (&self->unrecognized_spec);
|
||||
g_clear_object (&self->connection);
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMSIfcfgRHStorage *self = NMS_IFCFG_RH_STORAGE (object);
|
||||
|
||||
_storage_clear (self);
|
||||
|
||||
G_OBJECT_CLASS (nms_ifcfg_rh_storage_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
void
|
||||
nms_ifcfg_rh_storage_destroy (NMSIfcfgRHStorage *self)
|
||||
{
|
||||
_storage_clear (self);
|
||||
g_object_unref (self);
|
||||
}
|
||||
|
||||
static void
|
||||
nms_ifcfg_rh_storage_class_init (NMSIfcfgRHStorageClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
NMSettingsStorageClass *storage_class = NM_SETTINGS_STORAGE_CLASS (klass);
|
||||
|
||||
object_class->dispose = dispose;
|
||||
|
||||
storage_class->cmp_fcn = (int (*) (NMSettingsStorage *, NMSettingsStorage *)) cmp_fcn;
|
||||
}
|
||||
93
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h
Normal file
93
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/* NetworkManager
|
||||
*
|
||||
* 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) 2019 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NMS_IFCFG_RH_STORAGE_H__
|
||||
#define __NMS_IFCFG_RH_STORAGE_H__
|
||||
|
||||
#include "c-list/src/c-list.h"
|
||||
#include "settings/nm-settings-storage.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NMS_TYPE_IFCFG_RH_STORAGE (nms_ifcfg_rh_storage_get_type ())
|
||||
#define NMS_IFCFG_RH_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_IFCFG_RH_STORAGE, NMSIfcfgRHStorage))
|
||||
#define NMS_IFCFG_RH_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_IFCFG_RH_STORAGE, NMSIfcfgRHStorageClass))
|
||||
#define NMS_IS_IFCFG_RH_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_IFCFG_RH_STORAGE))
|
||||
#define NMS_IS_IFCFG_RH_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_IFCFG_RH_STORAGE))
|
||||
#define NMS_IFCFG_RH_STORAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_IFCFG_RH_STORAGE, NMSIfcfgRHStorageClass))
|
||||
|
||||
typedef struct {
|
||||
NMSettingsStorage parent;
|
||||
|
||||
NMConnection *connection;
|
||||
|
||||
char *unmanaged_spec;
|
||||
char *unrecognized_spec;
|
||||
|
||||
/* The timestamp (stat's mtime) of the file. Newer files have
|
||||
* higher priority. */
|
||||
struct timespec stat_mtime;
|
||||
|
||||
bool dirty:1;
|
||||
|
||||
} NMSIfcfgRHStorage;
|
||||
|
||||
typedef struct _NMSIfcfgRHStorageClass NMSIfcfgRHStorageClass;
|
||||
|
||||
GType nms_ifcfg_rh_storage_get_type (void);
|
||||
|
||||
struct _NMSIfcfgRHPlugin;
|
||||
|
||||
NMSIfcfgRHStorage *nms_ifcfg_rh_storage_new_connection (struct _NMSIfcfgRHPlugin *plugin,
|
||||
const char *filename,
|
||||
NMConnection *connection_take,
|
||||
const struct timespec *mtime);
|
||||
|
||||
NMSIfcfgRHStorage *nms_ifcfg_rh_storage_new_unhandled (struct _NMSIfcfgRHPlugin *plugin,
|
||||
const char *filename,
|
||||
const char *unmanaged_spec,
|
||||
const char *unrecognized_spec);
|
||||
|
||||
void nms_ifcfg_rh_storage_destroy (NMSIfcfgRHStorage *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean nms_ifcfg_rh_storage_equal_type (const NMSIfcfgRHStorage *self_a,
|
||||
const NMSIfcfgRHStorage *self_b);
|
||||
|
||||
void nms_ifcfg_rh_storage_copy_content (NMSIfcfgRHStorage *dst,
|
||||
const NMSIfcfgRHStorage *src);
|
||||
|
||||
NMConnection *nms_ifcfg_rh_storage_steal_connection (NMSIfcfgRHStorage *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline const char *
|
||||
nms_ifcfg_rh_storage_get_uuid_opt (const NMSIfcfgRHStorage *self)
|
||||
{
|
||||
return nm_settings_storage_get_uuid_opt ((const NMSettingsStorage *) self);
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
nms_ifcfg_rh_storage_get_filename (const NMSIfcfgRHStorage *self)
|
||||
{
|
||||
return nm_settings_storage_get_filename ((const NMSettingsStorage *) self);
|
||||
}
|
||||
|
||||
#endif /* __NMS_IFCFG_RH_STORAGE_H__ */
|
||||
|
|
@ -28,6 +28,32 @@
|
|||
|
||||
#include "nms-ifcfg-rh-common.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nms_ifcfg_rh_util_parse_unhandled_spec (const char *unhandled_spec,
|
||||
const char **out_unmanaged_spec,
|
||||
const char **out_unrecognized_spec)
|
||||
{
|
||||
if (unhandled_spec) {
|
||||
if (NM_STR_HAS_PREFIX (unhandled_spec, "unmanaged:")) {
|
||||
NM_SET_OUT (out_unmanaged_spec, &unhandled_spec[NM_STRLEN ("unmanaged:")]);
|
||||
NM_SET_OUT (out_unrecognized_spec, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
if (NM_STR_HAS_PREFIX (unhandled_spec, "unrecognized:")) {
|
||||
NM_SET_OUT (out_unmanaged_spec, NULL);
|
||||
NM_SET_OUT (out_unrecognized_spec, &unhandled_spec[NM_STRLEN ("unrecognized:")]);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
NM_SET_OUT (out_unmanaged_spec, NULL);
|
||||
NM_SET_OUT (out_unrecognized_spec, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Check ';[a-fA-F0-9]{8}' file suffix used for temporary files by rpm when
|
||||
* installing packages.
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@
|
|||
|
||||
#include "shvar.h"
|
||||
|
||||
gboolean nms_ifcfg_rh_util_parse_unhandled_spec (const char *unhandled_spec,
|
||||
const char **out_unmanaged_spec,
|
||||
const char **out_unrecognized_spec);
|
||||
|
||||
#define NM_IFCFG_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory")
|
||||
#define NM_IFCFG_CONNECTION_LOG_FMT "%s (%s,\"%s\")"
|
||||
#define NM_IFCFG_CONNECTION_LOG_ARG(con) NM_IFCFG_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_settings_connection_get_uuid ((NMSettingsConnection *) (con)), nm_settings_connection_get_id ((NMSettingsConnection *) (con))
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ libnms_ifupdown_core = static_library(
|
|||
)
|
||||
|
||||
sources = files(
|
||||
'nms-ifupdown-connection.c',
|
||||
'nms-ifupdown-plugin.c',
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
/* NetworkManager system settings service (ifupdown)
|
||||
*
|
||||
* Alexander Sack <asac@ubuntu.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* (C) Copyright 2007,2008 Canonical Ltd.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nms-ifupdown-connection.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "nm-dbus-interface.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-setting-wireless-security.h"
|
||||
#include "settings/nm-settings-connection.h"
|
||||
#include "settings/nm-settings-plugin.h"
|
||||
|
||||
#include "nms-ifupdown-parser.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NMIfupdownConnection {
|
||||
NMSettingsConnection parent;
|
||||
};
|
||||
|
||||
struct _NMIfupdownConnectionClass {
|
||||
NMSettingsConnectionClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SETTINGS_CONNECTION)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NMLOG_PREFIX_NAME "ifupdown"
|
||||
#define _NMLOG_DOMAIN LOGD_SETTINGS
|
||||
#define _NMLOG(level, ...) \
|
||||
nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \
|
||||
"%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
|
||||
_NMLOG_PREFIX_NAME": " \
|
||||
_NM_UTILS_MACRO_REST (__VA_ARGS__))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_ifupdown_connection_init (NMIfupdownConnection *connection)
|
||||
{
|
||||
}
|
||||
|
||||
NMIfupdownConnection *
|
||||
nm_ifupdown_connection_new (if_block *block)
|
||||
{
|
||||
NMIfupdownConnection *connection;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (block != NULL, NULL);
|
||||
|
||||
connection = g_object_new (NM_TYPE_IFUPDOWN_CONNECTION, NULL);
|
||||
|
||||
/* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */
|
||||
if (!ifupdown_update_connection_from_if_block (nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (connection)),
|
||||
block,
|
||||
&error)) {
|
||||
_LOGW ("invalid connection read from /etc/network/interfaces: %s",
|
||||
error->message);
|
||||
g_object_unref (connection);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connection_class)
|
||||
{
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/* NetworkManager system settings service (ifupdown)
|
||||
*
|
||||
* Alexander Sack <asac@ubuntu.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* (C) Copyright 2008 Canonical Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __NETWORKMANAGER_IFUPDOWN_CONNECTION_H__
|
||||
#define __NETWORKMANAGER_IFUPDOWN_CONNECTION_H__
|
||||
|
||||
#include "settings/nm-settings-connection.h"
|
||||
|
||||
#include "nms-ifupdown-interface-parser.h"
|
||||
|
||||
#define NM_TYPE_IFUPDOWN_CONNECTION (nm_ifupdown_connection_get_type ())
|
||||
#define NM_IFUPDOWN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnection))
|
||||
#define NM_IFUPDOWN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionClass))
|
||||
#define NM_IS_IFUPDOWN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFUPDOWN_CONNECTION))
|
||||
#define NM_IS_IFUPDOWN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IFUPDOWN_CONNECTION))
|
||||
#define NM_IFUPDOWN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionClass))
|
||||
|
||||
typedef struct _NMIfupdownConnection NMIfupdownConnection;
|
||||
typedef struct _NMIfupdownConnectionClass NMIfupdownConnectionClass;
|
||||
|
||||
GType nm_ifupdown_connection_get_type (void);
|
||||
|
||||
NMIfupdownConnection *nm_ifupdown_connection_new (if_block *block);
|
||||
|
||||
#endif /* __NETWORKMANAGER_IFUPDOWN_CONNECTION_H__ */
|
||||
|
|
@ -651,22 +651,21 @@ update_ip6_setting_from_if_block (NMConnection *connection,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ifupdown_update_connection_from_if_block (NMConnection *connection,
|
||||
if_block *block,
|
||||
GError **error)
|
||||
NMConnection *
|
||||
ifupdown_new_connection_from_if_block (if_block *block,
|
||||
gboolean autoconnect,
|
||||
GError **error)
|
||||
{
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
const char *type;
|
||||
gs_free char *idstr = NULL;
|
||||
gs_free char *uuid = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
gboolean success = FALSE;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
if (!s_con) {
|
||||
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_con));
|
||||
}
|
||||
connection = nm_simple_connection_new ();
|
||||
|
||||
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_con));
|
||||
|
||||
type = _ifupdownplugin_guess_connection_type (block);
|
||||
idstr = g_strconcat ("Ifupdown (", block->name, ")", NULL);
|
||||
|
|
@ -678,10 +677,10 @@ ifupdown_update_connection_from_if_block (NMConnection *connection,
|
|||
NM_SETTING_CONNECTION_ID, idstr,
|
||||
NM_SETTING_CONNECTION_UUID, uuid,
|
||||
NM_SETTING_CONNECTION_READ_ONLY, TRUE,
|
||||
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
|
||||
NM_SETTING_CONNECTION_AUTOCONNECT, (gboolean) (!!autoconnect),
|
||||
NULL);
|
||||
|
||||
_LOGI ("update_connection_setting_from_if_block: name:%s, type:%s, id:%s, uuid: %s",
|
||||
_LOGD ("update_connection_setting_from_if_block: name:%s, type:%s, id:%s, uuid: %s",
|
||||
block->name, type, idstr, nm_setting_connection_get_uuid (s_con));
|
||||
|
||||
if (nm_streq (type, NM_SETTING_WIRED_SETTING_NAME))
|
||||
|
|
@ -691,13 +690,16 @@ ifupdown_update_connection_from_if_block (NMConnection *connection,
|
|||
update_wireless_security_setting_from_if_block (connection, block);
|
||||
}
|
||||
|
||||
if (ifparser_haskey (block, "inet6"))
|
||||
success = update_ip6_setting_from_if_block (connection, block, error);
|
||||
else
|
||||
success = update_ip4_setting_from_if_block (connection, block, error);
|
||||
if (ifparser_haskey (block, "inet6")) {
|
||||
if (!update_ip6_setting_from_if_block (connection, block, error))
|
||||
return FALSE;
|
||||
} else {
|
||||
if (!update_ip4_setting_from_if_block (connection, block, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (success == TRUE)
|
||||
success = nm_connection_verify (connection, error);
|
||||
if (!nm_connection_normalize (connection, NULL, NULL, error))
|
||||
return NULL;
|
||||
|
||||
return success;
|
||||
return g_steal_pointer (&connection);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,16 +19,14 @@
|
|||
* (C) Copyright 2008 Canonical Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __PARSER_H__
|
||||
#define __PARSER_H__
|
||||
#ifndef __NMS_IFUPDOWN_PARSER_H__
|
||||
#define __NMS_IFUPDOWN_PARSER_H__
|
||||
|
||||
#include "nm-connection.h"
|
||||
|
||||
#include "nms-ifupdown-interface-parser.h"
|
||||
|
||||
gboolean
|
||||
ifupdown_update_connection_from_if_block (NMConnection *connection,
|
||||
if_block *block,
|
||||
GError **error);
|
||||
NMConnection *ifupdown_new_connection_from_if_block (if_block *block,
|
||||
gboolean autoconnect,
|
||||
GError **error);
|
||||
|
||||
#endif /* __PARSER_H__ */
|
||||
#endif /* __NMS_IFUPDOWN_PARSER_H__ */
|
||||
|
|
|
|||
|
|
@ -24,23 +24,12 @@
|
|||
|
||||
#include "nms-ifupdown-plugin.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-dbus-interface.h"
|
||||
#include "settings/nm-settings-plugin.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
#include "nm-setting-wireless.h"
|
||||
#include "nm-setting-wired.h"
|
||||
#include "nm-setting-ppp.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-config.h"
|
||||
#include "settings/nm-settings-plugin.h"
|
||||
#include "settings/nm-settings-storage.h"
|
||||
|
||||
#include "nms-ifupdown-interface-parser.h"
|
||||
#include "nms-ifupdown-connection.h"
|
||||
#include "nms-ifupdown-parser.h"
|
||||
|
||||
#define ENI_INTERFACES_FILE "/etc/network/interfaces"
|
||||
|
|
@ -49,29 +38,36 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
NMConnection *connection;
|
||||
NMSettingsStorage *storage;
|
||||
} StorageData;
|
||||
|
||||
typedef struct {
|
||||
/* Stores an entry for blocks/interfaces read from /e/n/i and (if exists)
|
||||
* the NMIfupdownConnection associated with the block.
|
||||
* the StorageData associated with the block.
|
||||
*/
|
||||
GHashTable *eni_ifaces;
|
||||
|
||||
bool ifupdown_managed:1;
|
||||
|
||||
bool initialized:1;
|
||||
} SettingsPluginIfupdownPrivate;
|
||||
|
||||
struct _SettingsPluginIfupdown {
|
||||
bool already_reloaded:1;
|
||||
} NMSIfupdownPluginPrivate;
|
||||
|
||||
struct _NMSIfupdownPlugin {
|
||||
NMSettingsPlugin parent;
|
||||
SettingsPluginIfupdownPrivate _priv;
|
||||
NMSIfupdownPluginPrivate _priv;
|
||||
};
|
||||
|
||||
struct _SettingsPluginIfupdownClass {
|
||||
struct _NMSIfupdownPluginClass {
|
||||
NMSettingsPluginClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (SettingsPluginIfupdown, settings_plugin_ifupdown, NM_TYPE_SETTINGS_PLUGIN)
|
||||
G_DEFINE_TYPE (NMSIfupdownPlugin, nms_ifupdown_plugin, NM_TYPE_SETTINGS_PLUGIN)
|
||||
|
||||
#define SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, SettingsPluginIfupdown, SETTINGS_IS_PLUGIN_IFUPDOWN)
|
||||
#define NMS_IFUPDOWN_PLUGIN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSIfupdownPlugin, NMS_IS_IFUPDOWN_PLUGIN)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -85,53 +81,143 @@ G_DEFINE_TYPE (SettingsPluginIfupdown, settings_plugin_ifupdown, NM_TYPE_SETTING
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void initialize (SettingsPluginIfupdown *self);
|
||||
static GHashTable *load_eni_ifaces (NMSIfupdownPlugin *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Returns the plugins currently known list of connections. The returned
|
||||
* list is freed by the system settings service.
|
||||
*/
|
||||
static GSList*
|
||||
get_connections (NMSettingsPlugin *plugin)
|
||||
static void
|
||||
_storage_data_destroy (StorageData *sd)
|
||||
{
|
||||
SettingsPluginIfupdown *self = SETTINGS_PLUGIN_IFUPDOWN (plugin);
|
||||
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
|
||||
GSList *list = NULL;
|
||||
GHashTableIter iter;
|
||||
void *value;
|
||||
|
||||
if (G_UNLIKELY (!priv->initialized))
|
||||
initialize (self);
|
||||
|
||||
if (!priv->ifupdown_managed) {
|
||||
_LOGD ("get_connections: not connections due to managed=false");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->eni_ifaces);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value)) {
|
||||
if (value)
|
||||
list = g_slist_prepend (list, value);
|
||||
}
|
||||
|
||||
_LOGD ("get_connections: %u connections", g_slist_length (list));
|
||||
return list;
|
||||
nm_g_object_unref (sd->connection);
|
||||
nm_g_object_unref (sd->storage);
|
||||
g_slice_free (StorageData, sd);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
initialize (NMSIfupdownPlugin *self)
|
||||
{
|
||||
NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE (self);
|
||||
gboolean ifupdown_managed;
|
||||
|
||||
nm_assert (!priv->initialized);
|
||||
|
||||
priv->initialized = TRUE;
|
||||
|
||||
ifupdown_managed = nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG,
|
||||
NM_CONFIG_KEYFILE_GROUP_IFUPDOWN,
|
||||
NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED,
|
||||
!IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT);
|
||||
_LOGI ("management mode: %s", ifupdown_managed ? "managed" : "unmanaged");
|
||||
priv->ifupdown_managed = ifupdown_managed;
|
||||
|
||||
priv->eni_ifaces = load_eni_ifaces (self);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_connections (NMSettingsPlugin *plugin,
|
||||
NMSettingsPluginConnectionLoadCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSIfupdownPlugin *self = NMS_IFUPDOWN_PLUGIN (plugin);
|
||||
NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE (self);
|
||||
gs_unref_hashtable GHashTable *eni_ifaces_old = NULL;
|
||||
GHashTableIter iter;
|
||||
StorageData *sd;
|
||||
StorageData *sd2;
|
||||
const char *block_name;
|
||||
|
||||
if (!priv->initialized)
|
||||
initialize (self);
|
||||
else if (!priv->already_reloaded) {
|
||||
/* This is the first call to reload, but we are already initialized.
|
||||
*
|
||||
* This happens because during start NMSettings first queries unmanaged-specs,
|
||||
* and then issues a reload call right away.
|
||||
*
|
||||
* On future reloads, we really want to load /e/n/i again. */
|
||||
priv->already_reloaded = TRUE;
|
||||
} else {
|
||||
eni_ifaces_old = priv->eni_ifaces;
|
||||
priv->eni_ifaces = load_eni_ifaces (self);
|
||||
|
||||
g_hash_table_iter_init (&iter, eni_ifaces_old);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &block_name, (gpointer *) &sd)) {
|
||||
if (!sd)
|
||||
continue;
|
||||
|
||||
sd2 = g_hash_table_lookup (priv->eni_ifaces, block_name);
|
||||
if (!sd2)
|
||||
continue;
|
||||
|
||||
nm_assert (nm_streq (nm_settings_storage_get_uuid (sd->storage), nm_settings_storage_get_uuid (sd2->storage)));
|
||||
nm_g_object_ref_set (&sd2->storage, sd->storage);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
}
|
||||
|
||||
if (!priv->ifupdown_managed)
|
||||
_LOGD ("load: no connections due to managed=false");
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->eni_ifaces);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &sd)) {
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
|
||||
if (!sd)
|
||||
continue;
|
||||
|
||||
connection = g_steal_pointer (&sd->connection);
|
||||
|
||||
if (!priv->ifupdown_managed)
|
||||
continue;
|
||||
|
||||
_LOGD ("load: %s (%s)",
|
||||
nm_settings_storage_get_uuid (sd->storage),
|
||||
nm_connection_get_id (connection));
|
||||
callback (plugin,
|
||||
sd->storage,
|
||||
connection,
|
||||
user_data);
|
||||
}
|
||||
if ( eni_ifaces_old
|
||||
&& priv->ifupdown_managed) {
|
||||
g_hash_table_iter_init (&iter, eni_ifaces_old);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &sd)) {
|
||||
if (!sd)
|
||||
continue;
|
||||
_LOGD ("unload: %s",
|
||||
nm_settings_storage_get_uuid (sd->storage));
|
||||
callback (plugin,
|
||||
sd->storage,
|
||||
NULL,
|
||||
user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static GSList *
|
||||
_unmanaged_specs (GHashTable *eni_ifaces)
|
||||
{
|
||||
gs_free const char **keys = NULL;
|
||||
GSList *specs = NULL;
|
||||
guint i, len;
|
||||
|
||||
keys = nm_utils_strdict_get_keys (eni_ifaces, TRUE, &len);
|
||||
for (i = len; i > 0; ) {
|
||||
i--;
|
||||
specs = g_slist_prepend (specs, g_strdup_printf ("interface-name:=%s", keys[i]));
|
||||
}
|
||||
return specs;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a list of device specifications which NetworkManager should not
|
||||
* manage. Returned list will be freed by the system settings service, and
|
||||
* each element must be allocated using g_malloc() or its variants.
|
||||
*/
|
||||
static GSList*
|
||||
get_unmanaged_specs (NMSettingsPlugin *plugin)
|
||||
{
|
||||
SettingsPluginIfupdown *self = SETTINGS_PLUGIN_IFUPDOWN (plugin);
|
||||
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
|
||||
GSList *specs = NULL;
|
||||
GHashTableIter iter;
|
||||
const char *iface;
|
||||
NMSIfupdownPlugin *self = NMS_IFUPDOWN_PLUGIN (plugin);
|
||||
NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE (self);
|
||||
|
||||
if (G_UNLIKELY (!priv->initialized))
|
||||
initialize (self);
|
||||
|
|
@ -142,40 +228,46 @@ get_unmanaged_specs (NMSettingsPlugin *plugin)
|
|||
_LOGD ("unmanaged-specs: unmanaged devices count %u",
|
||||
g_hash_table_size (priv->eni_ifaces));
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->eni_ifaces);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &iface, NULL))
|
||||
specs = g_slist_append (specs, g_strdup_printf ("interface-name:=%s", iface));
|
||||
return specs;
|
||||
return _unmanaged_specs (priv->eni_ifaces);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
initialize (SettingsPluginIfupdown *self)
|
||||
static GHashTable *
|
||||
load_eni_ifaces (NMSIfupdownPlugin *self)
|
||||
{
|
||||
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
|
||||
gs_unref_hashtable GHashTable *eni_ifaces = NULL;
|
||||
gs_unref_hashtable GHashTable *auto_ifaces = NULL;
|
||||
nm_auto_ifparser if_parser *parser = NULL;
|
||||
if_block *block;
|
||||
GHashTableIter con_iter;
|
||||
const char *block_name;
|
||||
NMIfupdownConnection *conn;
|
||||
StorageData *sd;
|
||||
|
||||
nm_assert (!priv->initialized);
|
||||
priv->initialized = TRUE;
|
||||
eni_ifaces = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) _storage_data_destroy);
|
||||
|
||||
parser = ifparser_parse (ENI_INTERFACES_FILE, 0);
|
||||
|
||||
c_list_for_each_entry (block, &parser->block_lst_head, block_lst) {
|
||||
|
||||
if (NM_IN_STRSET (block->type, "auto", "allow-hotplug")) {
|
||||
if (NM_IN_STRSET (block->type, "auto",
|
||||
"allow-hotplug")) {
|
||||
if (!auto_ifaces)
|
||||
auto_ifaces = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL);
|
||||
g_hash_table_add (auto_ifaces, g_strdup (block->name));
|
||||
continue;
|
||||
auto_ifaces = g_hash_table_new (nm_str_hash, g_str_equal);
|
||||
g_hash_table_add (auto_ifaces, (char *) block->name);
|
||||
}
|
||||
}
|
||||
|
||||
c_list_for_each_entry (block, &parser->block_lst_head, block_lst) {
|
||||
|
||||
if (NM_IN_STRSET (block->type, "auto",
|
||||
"allow-hotplug"))
|
||||
continue;
|
||||
|
||||
if (nm_streq (block->type, "iface")) {
|
||||
gs_free_error GError *local = NULL;
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
gs_unref_object NMSettingsStorage *storage = NULL;
|
||||
const char *uuid = NULL;
|
||||
StorageData *sd_repl;
|
||||
|
||||
/* Bridge configuration */
|
||||
if (g_str_has_prefix (block->name, "br")) {
|
||||
/* Try to find bridge ports */
|
||||
|
|
@ -208,13 +300,13 @@ initialize (SettingsPluginIfupdown *self)
|
|||
if (nm_streq (token, "none"))
|
||||
continue;
|
||||
if (state == 0) {
|
||||
conn = g_hash_table_lookup (priv->eni_ifaces, block->name);
|
||||
if (!conn) {
|
||||
sd = g_hash_table_lookup (eni_ifaces, block->name);
|
||||
if (!sd) {
|
||||
_LOGD ("parse: adding bridge port \"%s\"", token);
|
||||
g_hash_table_insert (priv->eni_ifaces, g_strdup (token), NULL);
|
||||
g_hash_table_insert (eni_ifaces, g_strdup (token), NULL);
|
||||
} else {
|
||||
_LOGD ("parse: adding bridge port \"%s\" (have connection %s)", token,
|
||||
nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (conn)));
|
||||
nm_settings_storage_get_uuid (sd->storage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -226,106 +318,91 @@ initialize (SettingsPluginIfupdown *self)
|
|||
if (nm_streq (block->name, "lo"))
|
||||
continue;
|
||||
|
||||
/* Remove any connection for this block that was previously found */
|
||||
conn = g_hash_table_lookup (priv->eni_ifaces, block->name);
|
||||
if (conn) {
|
||||
sd_repl = g_hash_table_lookup (eni_ifaces, block->name);
|
||||
if (sd_repl) {
|
||||
storage = g_steal_pointer (&sd_repl->storage);
|
||||
_LOGD ("parse: replace connection \"%s\" (%s)",
|
||||
block->name,
|
||||
nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (conn)));
|
||||
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (conn), NULL);
|
||||
g_hash_table_remove (priv->eni_ifaces, block->name);
|
||||
nm_settings_storage_get_uuid (sd_repl->storage));
|
||||
g_hash_table_remove (eni_ifaces, block->name);
|
||||
}
|
||||
|
||||
/* add the new connection */
|
||||
conn = nm_ifupdown_connection_new (block);
|
||||
if (conn) {
|
||||
_LOGD ("parse: adding connection \"%s\" (%s)", block->name,
|
||||
nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (conn)));
|
||||
} else
|
||||
_LOGD ("parse: adding place holder for connection \"%s\"", block->name);
|
||||
g_hash_table_insert (priv->eni_ifaces, g_strdup (block->name), conn);
|
||||
connection = ifupdown_new_connection_from_if_block (block,
|
||||
auto_ifaces
|
||||
&& g_hash_table_contains (auto_ifaces, block->name),
|
||||
&local);
|
||||
|
||||
if (!connection) {
|
||||
_LOGD ("parse: adding place holder for \"%s\"%s%s%s",
|
||||
block->name,
|
||||
NM_PRINT_FMT_QUOTED (local, " (", local->message, ")", ""));
|
||||
sd = NULL;
|
||||
} else {
|
||||
|
||||
nmtst_connection_assert_unchanging (connection);
|
||||
uuid = nm_connection_get_uuid (connection);
|
||||
|
||||
if (!storage)
|
||||
storage = nm_settings_storage_new (NM_SETTINGS_PLUGIN (self), uuid, NULL);
|
||||
|
||||
sd = g_slice_new (StorageData);
|
||||
*sd = (StorageData) {
|
||||
.connection = g_steal_pointer (&connection),
|
||||
.storage = g_steal_pointer (&storage),
|
||||
};
|
||||
_LOGD ("parse: adding connection \"%s\" (%s)", block->name, uuid);
|
||||
}
|
||||
|
||||
g_hash_table_replace (eni_ifaces, g_strdup (block->name), sd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nm_streq (block->type, "mapping")) {
|
||||
conn = g_hash_table_lookup (priv->eni_ifaces, block->name);
|
||||
if (!conn) {
|
||||
sd = g_hash_table_lookup (eni_ifaces, block->name);
|
||||
if (!sd) {
|
||||
_LOGD ("parse: adding mapping \"%s\"", block->name);
|
||||
g_hash_table_insert (priv->eni_ifaces, g_strdup (block->name), NULL);
|
||||
g_hash_table_insert (eni_ifaces, g_strdup (block->name), NULL);
|
||||
} else {
|
||||
_LOGD ("parse: adding mapping \"%s\" (have connection %s)", block->name,
|
||||
nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (conn)));
|
||||
nm_settings_storage_get_uuid (sd->storage));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make 'auto' interfaces autoconnect=TRUE */
|
||||
g_hash_table_iter_init (&con_iter, priv->eni_ifaces);
|
||||
while (g_hash_table_iter_next (&con_iter, (gpointer) &block_name, (gpointer) &conn)) {
|
||||
NMSettingConnection *setting;
|
||||
nm_clear_pointer (&auto_ifaces, g_hash_table_destroy);
|
||||
|
||||
if ( !conn
|
||||
|| !auto_ifaces
|
||||
|| !g_hash_table_contains (auto_ifaces, block_name))
|
||||
continue;
|
||||
|
||||
/* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */
|
||||
setting = nm_connection_get_setting_connection (nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (conn)));
|
||||
g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL);
|
||||
}
|
||||
|
||||
/* Check the config file to find out whether to manage interfaces */
|
||||
priv->ifupdown_managed = nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG,
|
||||
NM_CONFIG_KEYFILE_GROUP_IFUPDOWN,
|
||||
NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED,
|
||||
!IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT);
|
||||
_LOGI ("management mode: %s", priv->ifupdown_managed ? "managed" : "unmanaged");
|
||||
|
||||
/* Now if we're running in managed mode, let NM know there are new connections */
|
||||
if (priv->ifupdown_managed) {
|
||||
GHashTableIter iter;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->eni_ifaces);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &conn)) {
|
||||
if (conn) {
|
||||
_nm_settings_plugin_emit_signal_connection_added (NM_SETTINGS_PLUGIN (self),
|
||||
NM_SETTINGS_CONNECTION (conn));
|
||||
}
|
||||
}
|
||||
}
|
||||
return g_steal_pointer (&eni_ifaces);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
settings_plugin_ifupdown_init (SettingsPluginIfupdown *self)
|
||||
nms_ifupdown_plugin_init (NMSIfupdownPlugin *self)
|
||||
{
|
||||
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
|
||||
|
||||
priv->eni_ifaces = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
SettingsPluginIfupdown *plugin = SETTINGS_PLUGIN_IFUPDOWN (object);
|
||||
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (plugin);
|
||||
NMSIfupdownPlugin *plugin = NMS_IFUPDOWN_PLUGIN (object);
|
||||
NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE (plugin);
|
||||
|
||||
g_clear_pointer (&priv->eni_ifaces, g_hash_table_destroy);
|
||||
|
||||
G_OBJECT_CLASS (settings_plugin_ifupdown_parent_class)->dispose (object);
|
||||
G_OBJECT_CLASS (nms_ifupdown_plugin_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_plugin_ifupdown_class_init (SettingsPluginIfupdownClass *klass)
|
||||
nms_ifupdown_plugin_class_init (NMSIfupdownPluginClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS (klass);
|
||||
|
||||
object_class->dispose = dispose;
|
||||
|
||||
plugin_class->get_connections = get_connections;
|
||||
plugin_class->plugin_name = "ifupdown";
|
||||
plugin_class->reload_connections = reload_connections;
|
||||
plugin_class->get_unmanaged_specs = get_unmanaged_specs;
|
||||
}
|
||||
|
||||
|
|
@ -334,5 +411,5 @@ settings_plugin_ifupdown_class_init (SettingsPluginIfupdownClass *klass)
|
|||
G_MODULE_EXPORT NMSettingsPlugin *
|
||||
nm_settings_plugin_factory (void)
|
||||
{
|
||||
return g_object_new (SETTINGS_TYPE_PLUGIN_IFUPDOWN, NULL);
|
||||
return g_object_new (NMS_TYPE_IFUPDOWN_PLUGIN, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,21 +19,21 @@
|
|||
* (C) Copyright 2008 Canonical Ltd.
|
||||
*/
|
||||
|
||||
#ifndef _PLUGIN_H_
|
||||
#define _PLUGIN_H_
|
||||
#ifndef __NMS_IFUPDOWN_PLUGIN_H__
|
||||
#define __NMS_IFUPDOWN_PLUGIN_H__
|
||||
|
||||
#define PLUGIN_NAME "ifupdown"
|
||||
|
||||
#define SETTINGS_TYPE_PLUGIN_IFUPDOWN (settings_plugin_ifupdown_get_type ())
|
||||
#define SETTINGS_PLUGIN_IFUPDOWN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_IFUPDOWN, SettingsPluginIfupdown))
|
||||
#define SETTINGS_PLUGIN_IFUPDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_IFUPDOWN, SettingsPluginIfupdownClass))
|
||||
#define SETTINGS_IS_PLUGIN_IFUPDOWN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SETTINGS_TYPE_PLUGIN_IFUPDOWN))
|
||||
#define SETTINGS_IS_PLUGIN_IFUPDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SETTINGS_TYPE_PLUGIN_IFUPDOWN))
|
||||
#define SETTINGS_PLUGIN_IFUPDOWN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SETTINGS_TYPE_PLUGIN_IFUPDOWN, SettingsPluginIfupdownClass))
|
||||
#define NMS_TYPE_IFUPDOWN_PLUGIN (nms_ifupdown_plugin_get_type ())
|
||||
#define NMS_IFUPDOWN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_IFUPDOWN_PLUGIN, NMSIfupdownPlugin))
|
||||
#define NMS_IFUPDOWN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_IFUPDOWN_PLUGIN, NMSIfupdownPluginClass))
|
||||
#define NMS_IS_IFUPDOWN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_IFUPDOWN_PLUGIN))
|
||||
#define NMS_IS_IFUPDOWN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_IFUPDOWN_PLUGIN))
|
||||
#define NMS_IFUPDOWN_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_IFUPDOWN_PLUGIN, NMSIfupdownPluginClass))
|
||||
|
||||
typedef struct _SettingsPluginIfupdown SettingsPluginIfupdown;
|
||||
typedef struct _SettingsPluginIfupdownClass SettingsPluginIfupdownClass;
|
||||
typedef struct _NMSIfupdownPlugin NMSIfupdownPlugin;
|
||||
typedef struct _NMSIfupdownPluginClass NMSIfupdownPluginClass;
|
||||
|
||||
GType settings_plugin_ifupdown_get_type (void);
|
||||
GType nms_ifupdown_plugin_get_type (void);
|
||||
|
||||
#endif /* _PLUGIN_H_ */
|
||||
#endif /* __NMS_IFUPDOWN_PLUGIN_H__ */
|
||||
|
|
|
|||
|
|
@ -30,6 +30,29 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _connection_from_if_block(block) \
|
||||
({ \
|
||||
NMConnection *_con; \
|
||||
if_block *_block = (block); \
|
||||
GError *_local = NULL; \
|
||||
\
|
||||
g_assert (_block); \
|
||||
_con = ifupdown_new_connection_from_if_block (_block, FALSE, &_local); \
|
||||
nmtst_assert_success (NM_IS_CONNECTION (_con), _local); \
|
||||
nmtst_assert_connection_verifies_without_normalization (_con); \
|
||||
_con; \
|
||||
})
|
||||
|
||||
#define _connection_first_from_parser(parser) \
|
||||
({ \
|
||||
if_parser *_parser = (parser); \
|
||||
\
|
||||
g_assert (_parser); \
|
||||
_connection_from_if_block (ifparser_getfirst (_parser)); \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
char *key;
|
||||
char *data;
|
||||
|
|
@ -452,26 +475,14 @@ test16_missing_newline (void)
|
|||
static void
|
||||
test17_read_static_ipv4 (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingIPConfig *s_ip4;
|
||||
NMSettingWired *s_wired;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
NMIPAddress *ip4_addr;
|
||||
if_block *block = NULL;
|
||||
nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test17-wired-static-verify-ip4");
|
||||
|
||||
block = ifparser_getfirst (parser);
|
||||
connection = nm_simple_connection_new();
|
||||
g_assert (connection);
|
||||
|
||||
ifupdown_update_connection_from_if_block (connection, block, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
connection = _connection_first_from_parser (parser);
|
||||
|
||||
/* ===== CONNECTION SETTING ===== */
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
|
|
@ -500,32 +511,19 @@ test17_read_static_ipv4 (void)
|
|||
g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip4), ==, 2);
|
||||
g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 0), ==, "example.com");
|
||||
g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 1), ==, "foo.example.com");
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
test18_read_static_ipv6 (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingIPConfig *s_ip6;
|
||||
NMSettingWired *s_wired;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
NMIPAddress *ip6_addr;
|
||||
if_block *block = NULL;
|
||||
nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test18-wired-static-verify-ip6");
|
||||
|
||||
block = ifparser_getfirst (parser);
|
||||
connection = nm_simple_connection_new();
|
||||
g_assert (connection);
|
||||
ifupdown_update_connection_from_if_block (connection, block, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
connection = _connection_first_from_parser (parser);
|
||||
|
||||
/* ===== CONNECTION SETTING ===== */
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
|
|
@ -554,30 +552,17 @@ test18_read_static_ipv6 (void)
|
|||
g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip6), ==, 2);
|
||||
g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 0), ==, "example.com");
|
||||
g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 1), ==, "foo.example.com");
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
test19_read_static_ipv4_plen (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
NMSettingIPConfig *s_ip4;
|
||||
GError *error = NULL;
|
||||
NMIPAddress *ip4_addr;
|
||||
if_block *block = NULL;
|
||||
gboolean success;
|
||||
nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test19-wired-static-verify-ip4-plen");
|
||||
|
||||
block = ifparser_getfirst (parser);
|
||||
connection = nm_simple_connection_new();
|
||||
g_assert (connection);
|
||||
ifupdown_update_connection_from_if_block (connection, block, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
connection = _connection_first_from_parser (parser);
|
||||
|
||||
/* ===== IPv4 SETTING ===== */
|
||||
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
||||
|
|
@ -588,8 +573,6 @@ test19_read_static_ipv4_plen (void)
|
|||
g_assert (ip4_addr != NULL);
|
||||
g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "10.0.0.3");
|
||||
g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8);
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -670,4 +653,3 @@ main (int argc, char **argv)
|
|||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,187 +0,0 @@
|
|||
/* 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) 2008 Novell, Inc.
|
||||
* Copyright (C) 2008 - 2012 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nms-keyfile-connection.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "nm-dbus-interface.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-utils.h"
|
||||
|
||||
#include "settings/nm-settings-plugin.h"
|
||||
|
||||
#include "nms-keyfile-reader.h"
|
||||
#include "nms-keyfile-writer.h"
|
||||
#include "nms-keyfile-utils.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NMSKeyfileConnection {
|
||||
NMSettingsConnection parent;
|
||||
};
|
||||
|
||||
struct _NMSKeyfileConnectionClass {
|
||||
NMSettingsConnectionClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NMSKeyfileConnection, nms_keyfile_connection, NM_TYPE_SETTINGS_CONNECTION)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
commit_changes (NMSettingsConnection *connection,
|
||||
NMConnection *new_connection,
|
||||
NMSettingsConnectionCommitReason commit_reason,
|
||||
NMConnection **out_reread_connection,
|
||||
char **out_logmsg_change,
|
||||
GError **error)
|
||||
{
|
||||
gs_free char *path = NULL;
|
||||
gs_unref_object NMConnection *reread = NULL;
|
||||
gboolean reread_same = FALSE;
|
||||
|
||||
nm_assert (out_reread_connection && !*out_reread_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),
|
||||
NULL,
|
||||
NULL,
|
||||
&path,
|
||||
&reread,
|
||||
&reread_same,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
if (!nm_streq0 (path, nm_settings_connection_get_filename (connection))) {
|
||||
gs_free char *old_path = g_strdup (nm_settings_connection_get_filename (connection));
|
||||
|
||||
nm_settings_connection_set_filename (connection, path);
|
||||
if (old_path) {
|
||||
NM_SET_OUT (out_logmsg_change,
|
||||
g_strdup_printf ("keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and rename from \"%s\"",
|
||||
NMS_KEYFILE_CONNECTION_LOG_ARG (connection),
|
||||
old_path));
|
||||
} else {
|
||||
NM_SET_OUT (out_logmsg_change,
|
||||
g_strdup_printf ("keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and persist connection",
|
||||
NMS_KEYFILE_CONNECTION_LOG_ARG (connection)));
|
||||
}
|
||||
} else {
|
||||
NM_SET_OUT (out_logmsg_change,
|
||||
g_strdup_printf ("keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT,
|
||||
NMS_KEYFILE_CONNECTION_LOG_ARG (connection)));
|
||||
}
|
||||
|
||||
if (reread && !reread_same)
|
||||
*out_reread_connection = g_steal_pointer (&reread);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
delete (NMSettingsConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
const char *path;
|
||||
|
||||
path = nm_settings_connection_get_filename (connection);
|
||||
if (path)
|
||||
g_unlink (path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nms_keyfile_connection_init (NMSKeyfileConnection *connection)
|
||||
{
|
||||
}
|
||||
|
||||
NMSKeyfileConnection *
|
||||
nms_keyfile_connection_new (NMConnection *source,
|
||||
const char *full_path,
|
||||
const char *profile_dir,
|
||||
GError **error)
|
||||
{
|
||||
GObject *object;
|
||||
NMConnection *tmp;
|
||||
const char *uuid;
|
||||
gboolean update_unsaved = TRUE;
|
||||
|
||||
nm_assert (source || full_path);
|
||||
nm_assert (!full_path || full_path[0] == '/');
|
||||
nm_assert (!profile_dir || profile_dir[0] == '/');
|
||||
|
||||
/* If we're given a connection already, prefer that instead of re-reading */
|
||||
if (source)
|
||||
tmp = g_object_ref (source);
|
||||
else {
|
||||
tmp = nms_keyfile_reader_from_file (full_path, profile_dir, error);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
uuid = nm_connection_get_uuid (tmp);
|
||||
if (!uuid) {
|
||||
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
||||
"Connection in file %s had no UUID", full_path);
|
||||
g_object_unref (tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If we just read the connection from disk, it's clearly not Unsaved */
|
||||
update_unsaved = FALSE;
|
||||
}
|
||||
|
||||
object = g_object_new (NMS_TYPE_KEYFILE_CONNECTION,
|
||||
NM_SETTINGS_CONNECTION_FILENAME, full_path,
|
||||
NULL);
|
||||
|
||||
/* Update our settings with what was read from the file */
|
||||
if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (object),
|
||||
tmp,
|
||||
update_unsaved
|
||||
? NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED
|
||||
: NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED,
|
||||
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
|
||||
NULL,
|
||||
error)) {
|
||||
g_object_unref (object);
|
||||
object = NULL;
|
||||
}
|
||||
|
||||
g_object_unref (tmp);
|
||||
return (NMSKeyfileConnection *) object;
|
||||
}
|
||||
|
||||
static void
|
||||
nms_keyfile_connection_class_init (NMSKeyfileConnectionClass *keyfile_connection_class)
|
||||
{
|
||||
NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (keyfile_connection_class);
|
||||
|
||||
settings_class->commit_changes = commit_changes;
|
||||
settings_class->delete = delete;
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/* 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) 2008 Novell, Inc.
|
||||
* Copyright (C) 2008 - 2012 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NMS_KEYFILE_CONNECTION_H__
|
||||
#define __NMS_KEYFILE_CONNECTION_H__
|
||||
|
||||
#include "settings/nm-settings-connection.h"
|
||||
|
||||
#define NMS_TYPE_KEYFILE_CONNECTION (nms_keyfile_connection_get_type ())
|
||||
#define NMS_KEYFILE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_KEYFILE_CONNECTION, NMSKeyfileConnection))
|
||||
#define NMS_KEYFILE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_KEYFILE_CONNECTION, NMSKeyfileConnectionClass))
|
||||
#define NMS_IS_KEYFILE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_KEYFILE_CONNECTION))
|
||||
#define NMS_IS_KEYFILE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_KEYFILE_CONNECTION))
|
||||
#define NMS_KEYFILE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_KEYFILE_CONNECTION, NMSKeyfileConnectionClass))
|
||||
|
||||
typedef struct _NMSKeyfileConnection NMSKeyfileConnection;
|
||||
typedef struct _NMSKeyfileConnectionClass NMSKeyfileConnectionClass;
|
||||
|
||||
GType nms_keyfile_connection_get_type (void);
|
||||
|
||||
NMSKeyfileConnection *nms_keyfile_connection_new (NMConnection *source,
|
||||
const char *full_path,
|
||||
const char *profile_dir,
|
||||
GError **error);
|
||||
|
||||
#endif /* __NMS_KEYFILE_CONNECTION_H__ */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -21,6 +21,11 @@
|
|||
#ifndef __NMS_KEYFILE_PLUGIN_H__
|
||||
#define __NMS_KEYFILE_PLUGIN_H__
|
||||
|
||||
#include "settings/nm-settings-plugin.h"
|
||||
#include "settings/nm-settings-storage.h"
|
||||
|
||||
#include "nms-keyfile-utils.h"
|
||||
|
||||
#define NMS_TYPE_KEYFILE_PLUGIN (nms_keyfile_plugin_get_type ())
|
||||
#define NMS_KEYFILE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_KEYFILE_PLUGIN, NMSKeyfilePlugin))
|
||||
#define NMS_KEYFILE_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_KEYFILE_PLUGIN, NMSKeyfilePluginClass))
|
||||
|
|
@ -35,4 +40,31 @@ GType nms_keyfile_plugin_get_type (void);
|
|||
|
||||
NMSKeyfilePlugin *nms_keyfile_plugin_new (void);
|
||||
|
||||
gboolean nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
|
||||
NMConnection *connection,
|
||||
gboolean is_nm_generated,
|
||||
gboolean is_volatile,
|
||||
gboolean in_memory,
|
||||
NMSettingsStorage **out_storage,
|
||||
NMConnection **out_connection,
|
||||
GError **error);
|
||||
|
||||
gboolean nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
|
||||
NMSettingsStorage *storage,
|
||||
NMConnection *connection,
|
||||
gboolean is_nm_generated,
|
||||
gboolean is_volatile,
|
||||
gboolean force_rename,
|
||||
NMSettingsStorage **out_storage,
|
||||
NMConnection **out_connection,
|
||||
GError **error);
|
||||
|
||||
gboolean nms_keyfile_plugin_set_nmmeta_tombstone (NMSKeyfilePlugin *self,
|
||||
gboolean simulate,
|
||||
const char *uuid,
|
||||
gboolean in_memory,
|
||||
gboolean set,
|
||||
NMSettingsStorage **out_storage,
|
||||
gboolean *out_hard_failure);
|
||||
|
||||
#endif /* __NMS_KEYFILE_PLUGIN_H__ */
|
||||
|
|
|
|||
|
|
@ -161,6 +161,9 @@ nms_keyfile_reader_from_keyfile (GKeyFile *key_file,
|
|||
NMConnection *
|
||||
nms_keyfile_reader_from_file (const char *full_filename,
|
||||
const char *profile_dir,
|
||||
struct stat *out_stat,
|
||||
NMTernary *out_is_nm_generated,
|
||||
NMTernary *out_is_volatile,
|
||||
GError **error)
|
||||
{
|
||||
gs_unref_keyfile GKeyFile *key_file = NULL;
|
||||
|
|
@ -170,9 +173,12 @@ nms_keyfile_reader_from_file (const char *full_filename,
|
|||
nm_assert (full_filename && full_filename[0] == '/');
|
||||
nm_assert (!profile_dir || profile_dir[0] == '/');
|
||||
|
||||
NM_SET_OUT (out_is_nm_generated, NM_TERNARY_DEFAULT);
|
||||
NM_SET_OUT (out_is_volatile, NM_TERNARY_DEFAULT);
|
||||
|
||||
if (!nms_keyfile_utils_check_file_permissions (NMS_KEYFILE_FILETYPE_KEYFILE,
|
||||
full_filename,
|
||||
NULL,
|
||||
out_stat,
|
||||
error))
|
||||
return NULL;
|
||||
|
||||
|
|
@ -194,6 +200,16 @@ nms_keyfile_reader_from_file (const char *full_filename,
|
|||
connection = NULL;
|
||||
}
|
||||
|
||||
NM_SET_OUT (out_is_nm_generated, nm_key_file_get_boolean (key_file,
|
||||
NM_KEYFILE_GROUP_NMMETA,
|
||||
NM_KEYFILE_KEY_NMMETA_NM_GENERATED,
|
||||
NM_TERNARY_DEFAULT));
|
||||
|
||||
NM_SET_OUT (out_is_volatile, nm_key_file_get_boolean (key_file,
|
||||
NM_KEYFILE_GROUP_NMMETA,
|
||||
NM_KEYFILE_KEY_NMMETA_VOLATILE,
|
||||
NM_TERNARY_DEFAULT));
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,8 +30,13 @@ NMConnection *nms_keyfile_reader_from_keyfile (GKeyFile *key_file,
|
|||
gboolean verbose,
|
||||
GError **error);
|
||||
|
||||
struct stat;
|
||||
|
||||
NMConnection *nms_keyfile_reader_from_file (const char *full_filename,
|
||||
const char *profile_dir,
|
||||
struct stat *out_stat,
|
||||
NMTernary *out_is_nm_generated,
|
||||
NMTernary *out_is_volatile,
|
||||
GError **error);
|
||||
|
||||
#endif /* __NMS_KEYFILE_READER_H__ */
|
||||
|
|
|
|||
236
src/settings/plugins/keyfile/nms-keyfile-storage.c
Normal file
236
src/settings/plugins/keyfile/nms-keyfile-storage.c
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nms-keyfile-storage.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nms-keyfile-plugin.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NMSKeyfileStorageClass {
|
||||
NMSettingsStorageClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NMSKeyfileStorage, nms_keyfile_storage, NM_TYPE_SETTINGS_STORAGE)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nms_keyfile_storage_copy_content (NMSKeyfileStorage *dst,
|
||||
const NMSKeyfileStorage *src)
|
||||
{
|
||||
nm_assert (src != dst);
|
||||
nm_assert (nm_streq (nms_keyfile_storage_get_uuid (dst), nms_keyfile_storage_get_uuid (src)));
|
||||
nm_assert (nms_keyfile_storage_get_filename (dst) && nm_streq (nms_keyfile_storage_get_filename (dst), nms_keyfile_storage_get_filename (src)));
|
||||
|
||||
nm_g_object_ref_set (&dst->connection, src->connection);
|
||||
dst->storage_type = src->storage_type;
|
||||
dst->stat_mtime = src->stat_mtime;
|
||||
dst->is_nm_generated = src->is_nm_generated;
|
||||
dst->is_volatile = src->is_volatile;
|
||||
dst->is_tombstone = src->is_tombstone;
|
||||
}
|
||||
|
||||
NMConnection *
|
||||
nms_keyfile_storage_steal_connection (NMSKeyfileStorage *self)
|
||||
{
|
||||
nm_assert (NMS_IS_KEYFILE_STORAGE (self));
|
||||
nm_assert (NM_IS_CONNECTION (self->connection));
|
||||
|
||||
return g_steal_pointer (&self->connection);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
cmp_fcn (const NMSKeyfileStorage *a,
|
||||
const NMSKeyfileStorage *b)
|
||||
{
|
||||
nm_assert (NMS_IS_KEYFILE_STORAGE (a));
|
||||
nm_assert (NMS_IS_KEYFILE_STORAGE (b));
|
||||
nm_assert (a != b);
|
||||
|
||||
/* sort by storage-type, which also has a numeric value according to their
|
||||
* (inverse) priority. */
|
||||
NM_CMP_FIELD_UNSAFE (b, a, storage_type);
|
||||
|
||||
/* tombstones are more important. */
|
||||
nm_assert (a->is_tombstone == nm_settings_storage_is_keyfile_tombstone (NM_SETTINGS_STORAGE (a)));
|
||||
nm_assert (b->is_tombstone == nm_settings_storage_is_keyfile_tombstone (NM_SETTINGS_STORAGE (b)));
|
||||
NM_CMP_FIELD_UNSAFE (a, b, is_tombstone);
|
||||
|
||||
/* newer files are more important. */
|
||||
NM_CMP_FIELD (b, a, stat_mtime.tv_sec);
|
||||
NM_CMP_FIELD (b, a, stat_mtime.tv_nsec);
|
||||
|
||||
NM_CMP_DIRECT_STRCMP (nms_keyfile_storage_get_filename (a), nms_keyfile_storage_get_filename (b));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nms_keyfile_storage_init (NMSKeyfileStorage *self)
|
||||
{
|
||||
}
|
||||
|
||||
static NMSKeyfileStorage *
|
||||
_storage_new (NMSKeyfilePlugin *plugin,
|
||||
const char *uuid,
|
||||
const char *filename)
|
||||
{
|
||||
nm_assert (NMS_IS_KEYFILE_PLUGIN (plugin));
|
||||
nm_assert (nm_utils_is_uuid (uuid));
|
||||
nm_assert (filename && filename[0] == '/');
|
||||
|
||||
return g_object_new (NMS_TYPE_KEYFILE_STORAGE,
|
||||
NM_SETTINGS_STORAGE_PLUGIN, plugin,
|
||||
NM_SETTINGS_STORAGE_UUID, uuid,
|
||||
NM_SETTINGS_STORAGE_FILENAME, filename,
|
||||
NULL);
|
||||
}
|
||||
|
||||
NMSKeyfileStorage *
|
||||
nms_keyfile_storage_new_tombstone (NMSKeyfilePlugin *plugin,
|
||||
const char *uuid,
|
||||
const char *filename,
|
||||
NMSKeyfileStorageType storage_type)
|
||||
{
|
||||
NMSKeyfileStorage *self;
|
||||
|
||||
nm_assert (nm_utils_is_uuid (uuid));
|
||||
nm_assert (filename && filename[0] == '/');
|
||||
nm_assert (nms_keyfile_nmmeta_check_filename (filename, NULL));
|
||||
nm_assert (NM_IN_SET (storage_type, NMS_KEYFILE_STORAGE_TYPE_ETC,
|
||||
NMS_KEYFILE_STORAGE_TYPE_RUN));
|
||||
|
||||
self = _storage_new (plugin, uuid, filename);
|
||||
|
||||
self->is_tombstone = TRUE;
|
||||
|
||||
self->storage_type = storage_type;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
NMSKeyfileStorage *
|
||||
nms_keyfile_storage_new_connection (NMSKeyfilePlugin *plugin,
|
||||
NMConnection *connection_take /* pass reference */,
|
||||
const char *filename,
|
||||
NMSKeyfileStorageType storage_type,
|
||||
NMTernary is_nm_generated_opt,
|
||||
NMTernary is_volatile_opt,
|
||||
const struct timespec *stat_mtime)
|
||||
{
|
||||
NMSKeyfileStorage *self;
|
||||
|
||||
nm_assert (NMS_IS_KEYFILE_PLUGIN (plugin));
|
||||
nm_assert (NM_IS_CONNECTION (connection_take));
|
||||
nm_assert (_nm_connection_verify (connection_take, NULL) == NM_SETTING_VERIFY_SUCCESS);
|
||||
nm_assert (filename && filename[0] == '/');
|
||||
nm_assert ( storage_type >= NMS_KEYFILE_STORAGE_TYPE_RUN
|
||||
&& storage_type <= _NMS_KEYFILE_STORAGE_TYPE_LIB_LAST);
|
||||
nmtst_connection_assert_unchanging (connection_take);
|
||||
|
||||
self = _storage_new (plugin, nm_connection_get_uuid (connection_take), filename);
|
||||
|
||||
self->connection = connection_take; /* take reference. */
|
||||
|
||||
if (storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) {
|
||||
self->is_nm_generated = (is_nm_generated_opt == NM_TERNARY_TRUE);
|
||||
self->is_volatile = (is_volatile_opt == NM_TERNARY_TRUE);
|
||||
}
|
||||
|
||||
if (stat_mtime)
|
||||
self->stat_mtime = *stat_mtime;
|
||||
|
||||
self->storage_type = storage_type;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
_storage_clear (NMSKeyfileStorage *self)
|
||||
{
|
||||
c_list_unlink (&self->parent._storage_lst);
|
||||
c_list_unlink (&self->parent._storage_by_uuid_lst);
|
||||
g_clear_object (&self->connection);
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMSKeyfileStorage *self = NMS_KEYFILE_STORAGE (object);
|
||||
|
||||
_storage_clear (self);
|
||||
|
||||
G_OBJECT_CLASS (nms_keyfile_storage_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
void
|
||||
nms_keyfile_storage_destroy (NMSKeyfileStorage *self)
|
||||
{
|
||||
_storage_clear (self);
|
||||
g_object_unref (self);
|
||||
}
|
||||
|
||||
static void
|
||||
nms_keyfile_storage_class_init (NMSKeyfileStorageClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
NMSettingsStorageClass *storage_class = NM_SETTINGS_STORAGE_CLASS (klass);
|
||||
|
||||
object_class->dispose = dispose;
|
||||
|
||||
storage_class->cmp_fcn = (int (*) (NMSettingsStorage *, NMSettingsStorage *)) cmp_fcn;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "settings/nm-settings-connection.h"
|
||||
|
||||
void
|
||||
nm_settings_storage_load_sett_flags (NMSettingsStorage *self,
|
||||
NMSettingsConnectionIntFlags *sett_flags,
|
||||
NMSettingsConnectionIntFlags *sett_mask)
|
||||
{
|
||||
NMSKeyfileStorage *s;
|
||||
|
||||
*sett_flags = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE;
|
||||
*sett_mask = NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE;
|
||||
|
||||
if (!NMS_IS_KEYFILE_STORAGE (self))
|
||||
return;
|
||||
|
||||
s = NMS_KEYFILE_STORAGE (self);
|
||||
if (s->storage_type != NMS_KEYFILE_STORAGE_TYPE_RUN)
|
||||
return;
|
||||
|
||||
if (s->is_nm_generated)
|
||||
*sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED;
|
||||
|
||||
if (s->is_volatile)
|
||||
*sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE;
|
||||
}
|
||||
157
src/settings/plugins/keyfile/nms-keyfile-storage.h
Normal file
157
src/settings/plugins/keyfile/nms-keyfile-storage.h
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/* 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 {
|
||||
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. */
|
||||
NMConnection *connection;
|
||||
|
||||
NMSKeyfileStorageType storage_type;
|
||||
|
||||
/* the timestamp (stat's mtime) of the keyfile. For tombstones 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-tombstones). This is to persist and reload these settings flags to
|
||||
* /run. */
|
||||
bool is_nm_generated:1;
|
||||
bool is_volatile:1;
|
||||
|
||||
/* whether this is a tombstone to hide a UUID (via the loaded uuid symlinks).
|
||||
* If this is falls, the storage contains a profile, though note that
|
||||
* the connection field will be cleared when it's not used. So, a non-tombstone
|
||||
* has a connection in principle, but the connection field may still be %NULL.
|
||||
*
|
||||
* Note that a tombstone instance doesn't have a connection, but NMSettings
|
||||
* considers it alive because is_tombstone is %TRUE. That means, once a tombstone
|
||||
* gets removed, this flag is cleared. Then the storage instance has no connnection
|
||||
* and is no longer a tombstone, and NMSettings considers it ready for deletion.
|
||||
*/
|
||||
bool is_tombstone:1;
|
||||
|
||||
/* this flag is only used during reload to mark and prune old entries. */
|
||||
bool 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);
|
||||
|
||||
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 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 gboolean
|
||||
nm_settings_storage_is_keyfile_tombstone (const NMSettingsStorage *self)
|
||||
{
|
||||
/* Only keyfile storage supports tombstones. They indicate that a uuid
|
||||
* is shadowed via a symlink to /dev/null.
|
||||
*
|
||||
* Note that tombstones don't have a NMConnection instead they shadow
|
||||
* a UUID. As such, NMSettings considers them alive also if they have
|
||||
* not profile. That means, when a tombstone gets removed for good,
|
||||
* the is_tombstone must be cleared (so that it becomes truly dead). */
|
||||
return NMS_IS_KEYFILE_STORAGE (self)
|
||||
&& ((NMSKeyfileStorage *) self)->is_tombstone;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
enum _NMSettingsConnectionIntFlags;
|
||||
|
||||
void nm_settings_storage_load_sett_flags (NMSettingsStorage *self,
|
||||
enum _NMSettingsConnectionIntFlags *sett_flags,
|
||||
enum _NMSettingsConnectionIntFlags *sett_mask);
|
||||
|
||||
#endif /* __NMS_KEYFILE_STORAGE_H__ */
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2010 Red Hat, Inc.
|
||||
* (C) Copyright 2010 - 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
|
@ -33,89 +33,98 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
char *
|
||||
nms_keyfile_loaded_uuid_filename (const char *dirname,
|
||||
const char *uuid,
|
||||
gboolean temporary)
|
||||
const char *
|
||||
nms_keyfile_nmmeta_check_filename (const char *filename,
|
||||
guint *out_uuid_len)
|
||||
{
|
||||
char filename[250];
|
||||
const char *uuid;
|
||||
const char *s;
|
||||
gsize len;
|
||||
|
||||
nm_assert (dirname && dirname[0] == '/');
|
||||
nm_assert (uuid && nm_utils_is_uuid (uuid) && !strchr (uuid, '/'));
|
||||
s = strrchr (filename, '/');
|
||||
if (s)
|
||||
filename = &s[1];
|
||||
|
||||
if (g_snprintf (filename,
|
||||
sizeof (filename),
|
||||
"%s%s%s%s",
|
||||
NM_KEYFILE_PATH_PREFIX_NMLOADED,
|
||||
uuid,
|
||||
NM_KEYFILE_PATH_SUFFIX_NMCONNECTION,
|
||||
temporary ? "~" : "") >= sizeof (filename)) {
|
||||
/* valid uuids are limited in length. The buffer should always be large
|
||||
* enough. */
|
||||
nm_assert_not_reached ();
|
||||
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;
|
||||
}
|
||||
|
||||
return g_build_filename (dirname, filename, 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_nmmeta_filename (const char *dirname,
|
||||
const char *uuid,
|
||||
gboolean temporary)
|
||||
{
|
||||
char filename[250];
|
||||
char *s;
|
||||
|
||||
nm_assert (dirname && dirname[0] == '/');
|
||||
nm_assert ( nm_utils_is_uuid (uuid)
|
||||
&& !strchr (uuid, '/'));
|
||||
|
||||
if (g_snprintf (filename,
|
||||
sizeof (filename),
|
||||
"%s%s%s",
|
||||
uuid,
|
||||
NM_KEYFILE_PATH_SUFFIX_NMMETA,
|
||||
temporary ? "~" : "") >= sizeof (filename)) {
|
||||
/* valid uuids are limited in length (nm_utils_is_uuid). The buffer should always
|
||||
* be large enough. */
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
|
||||
s = g_build_filename (dirname, filename, NULL);
|
||||
|
||||
nm_assert (nm_keyfile_utils_ignore_filename (s, FALSE));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nms_keyfile_loaded_uuid_read (const char *dirname,
|
||||
const char *filename,
|
||||
char **out_full_filename,
|
||||
char **out_uuid,
|
||||
char **out_loaded_path)
|
||||
nms_keyfile_nmmeta_read (const char *dirname,
|
||||
const char *filename,
|
||||
char **out_full_filename,
|
||||
char **out_uuid,
|
||||
char **out_loaded_path,
|
||||
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_nmmeta_check_filename (filename, &uuid_len);
|
||||
if (!uuid)
|
||||
return FALSE;
|
||||
|
||||
full_filename = g_build_filename (dirname, filename, NULL);
|
||||
|
||||
if (!nms_keyfile_utils_check_file_permissions (NMS_KEYFILE_FILETYPE_NMLOADED,
|
||||
full_filename,
|
||||
NULL,
|
||||
out_st,
|
||||
NULL))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -123,18 +132,18 @@ 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;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nms_keyfile_loaded_uuid_read_from_file (const char *full_filename,
|
||||
char **out_dirname,
|
||||
char **out_filename,
|
||||
char **out_uuid,
|
||||
char **out_loaded_path)
|
||||
nms_keyfile_nmmeta_read_from_file (const char *full_filename,
|
||||
char **out_dirname,
|
||||
char **out_filename,
|
||||
char **out_uuid,
|
||||
char **out_loaded_path)
|
||||
{
|
||||
gs_free char *dirname = NULL;
|
||||
gs_free char *filename = NULL;
|
||||
|
|
@ -144,11 +153,12 @@ nms_keyfile_loaded_uuid_read_from_file (const char *full_filename,
|
|||
filename = g_path_get_basename (full_filename);
|
||||
dirname = g_path_get_dirname (full_filename);
|
||||
|
||||
if (!nms_keyfile_loaded_uuid_read (dirname,
|
||||
filename,
|
||||
NULL,
|
||||
out_uuid,
|
||||
out_loaded_path))
|
||||
if (!nms_keyfile_nmmeta_read (dirname,
|
||||
filename,
|
||||
NULL,
|
||||
out_uuid,
|
||||
out_loaded_path,
|
||||
NULL))
|
||||
return FALSE;
|
||||
|
||||
NM_SET_OUT (out_dirname, g_steal_pointer (&dirname));
|
||||
|
|
@ -157,20 +167,21 @@ nms_keyfile_loaded_uuid_read_from_file (const char *full_filename,
|
|||
}
|
||||
|
||||
gboolean
|
||||
nms_keyfile_loaded_uuid_write (const char *dirname,
|
||||
const char *uuid,
|
||||
const char *loaded_path,
|
||||
gboolean allow_relative,
|
||||
char **out_full_filename)
|
||||
nms_keyfile_nmmeta_write (const char *dirname,
|
||||
const char *uuid,
|
||||
const char *loaded_path,
|
||||
gboolean allow_relative,
|
||||
char **out_full_filename)
|
||||
{
|
||||
gs_free char *full_filename_tmp = NULL;
|
||||
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);
|
||||
full_filename_tmp = nms_keyfile_nmmeta_filename (dirname, uuid, TRUE);
|
||||
|
||||
nm_assert (g_str_has_suffix (full_filename_tmp, "~"));
|
||||
nm_assert (nm_utils_file_is_in_path (full_filename_tmp, dirname));
|
||||
|
|
@ -294,22 +305,3 @@ nms_keyfile_utils_check_file_permissions (NMSKeyfileFiletype filetype,
|
|||
NM_SET_OUT (out_st, st);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *
|
||||
nms_keyfile_utils_get_path (void)
|
||||
{
|
||||
static char *path = NULL;
|
||||
|
||||
if (G_UNLIKELY (!path)) {
|
||||
path = nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG,
|
||||
NM_CONFIG_KEYFILE_GROUP_KEYFILE,
|
||||
NM_CONFIG_KEYFILE_KEY_KEYFILE_PATH,
|
||||
NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
|
||||
if (!path)
|
||||
path = g_strdup (""NM_KEYFILE_PATH_NAME_ETC_DEFAULT"");
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2010-2016 Red Hat, Inc.
|
||||
* (C) Copyright 2010 - 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NMS_KEYFILE_UTILS_H__
|
||||
|
|
@ -22,42 +22,53 @@
|
|||
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
#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))
|
||||
#define NMS_KEYFILE_CONNECTION_LOG_FMTD "%s (%s,\"%s\",%p)"
|
||||
#define NMS_KEYFILE_CONNECTION_LOG_ARGD(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)), (con)
|
||||
|
||||
typedef enum {
|
||||
NMS_KEYFILE_FILETYPE_KEYFILE,
|
||||
NMS_KEYFILE_FILETYPE_NMLOADED,
|
||||
} NMSKeyfileFiletype;
|
||||
|
||||
const char *nms_keyfile_utils_get_path (void);
|
||||
typedef enum {
|
||||
NMS_KEYFILE_STORAGE_TYPE_RUN = 1, /* read-write, runtime only, e.g. /run */
|
||||
NMS_KEYFILE_STORAGE_TYPE_ETC = 2, /* read-write, persistent, e.g. /etc */
|
||||
NMS_KEYFILE_STORAGE_TYPE_LIB_BASE = 3, /* read-only, e.g. /usr/lib */
|
||||
|
||||
_NMS_KEYFILE_STORAGE_TYPE_LIB_LAST = 1000,
|
||||
} NMSKeyfileStorageType;
|
||||
|
||||
static inline NMSKeyfileStorageType
|
||||
NMS_KEYFILE_STORAGE_TYPE_LIB (guint run_idx)
|
||||
{
|
||||
nm_assert (run_idx <= (_NMS_KEYFILE_STORAGE_TYPE_LIB_LAST - NMS_KEYFILE_STORAGE_TYPE_LIB_BASE));
|
||||
return NMS_KEYFILE_STORAGE_TYPE_LIB_BASE + run_idx;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
char *nms_keyfile_loaded_uuid_filename (const char *dirname,
|
||||
const char *uuid,
|
||||
gboolean temporary);
|
||||
const char *nms_keyfile_nmmeta_check_filename (const char *filename,
|
||||
guint *out_uuid_len);
|
||||
|
||||
gboolean nms_keyfile_loaded_uuid_read (const char *dirname,
|
||||
const char *filename,
|
||||
char **out_full_filename,
|
||||
char **out_uuid,
|
||||
char **out_loaded_path);
|
||||
char *nms_keyfile_nmmeta_filename (const char *dirname,
|
||||
const char *uuid,
|
||||
gboolean temporary);
|
||||
|
||||
gboolean nms_keyfile_loaded_uuid_read_from_file (const char *full_filename,
|
||||
char **out_dirname,
|
||||
char **out_filename,
|
||||
char **out_uuid,
|
||||
char **out_loaded_path);
|
||||
gboolean nms_keyfile_nmmeta_read (const char *dirname,
|
||||
const char *filename,
|
||||
char **out_full_filename,
|
||||
char **out_uuid,
|
||||
char **out_loaded_path,
|
||||
struct stat *out_st);
|
||||
|
||||
gboolean nms_keyfile_loaded_uuid_write (const char *dirname,
|
||||
const char *uuid,
|
||||
const char *loaded_path,
|
||||
gboolean allow_relative,
|
||||
char **out_full_filename);
|
||||
gboolean nms_keyfile_nmmeta_read_from_file (const char *full_filename,
|
||||
char **out_dirname,
|
||||
char **out_filename,
|
||||
char **out_uuid,
|
||||
char **out_loaded_path);
|
||||
|
||||
gboolean nms_keyfile_nmmeta_write (const char *dirname,
|
||||
const char *uuid,
|
||||
const char *loaded_path,
|
||||
gboolean allow_relative,
|
||||
char **out_full_filename);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -168,6 +168,8 @@ _handler_write (NMConnection *connection,
|
|||
|
||||
static gboolean
|
||||
_internal_write_connection (NMConnection *connection,
|
||||
gboolean is_nm_generated,
|
||||
gboolean is_volatile,
|
||||
const char *keyfile_dir,
|
||||
const char *profile_dir,
|
||||
gboolean with_extension,
|
||||
|
|
@ -212,6 +214,21 @@ _internal_write_connection (NMConnection *connection,
|
|||
kf_file = nm_keyfile_write (connection, _handler_write, &info, error);
|
||||
if (!kf_file)
|
||||
return FALSE;
|
||||
|
||||
if (is_nm_generated) {
|
||||
g_key_file_set_boolean (kf_file,
|
||||
NM_KEYFILE_GROUP_NMMETA,
|
||||
NM_KEYFILE_KEY_NMMETA_NM_GENERATED,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
if (is_volatile) {
|
||||
g_key_file_set_boolean (kf_file,
|
||||
NM_KEYFILE_GROUP_NMMETA,
|
||||
NM_KEYFILE_KEY_NMMETA_VOLATILE,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
kf_content_buf = g_key_file_to_data (kf_file, &kf_content_len, error);
|
||||
if (!kf_content_buf)
|
||||
return FALSE;
|
||||
|
|
@ -337,8 +354,12 @@ _internal_write_connection (NMConnection *connection,
|
|||
|
||||
gboolean
|
||||
nms_keyfile_writer_connection (NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
gboolean is_nm_generated,
|
||||
gboolean is_volatile,
|
||||
const char *keyfile_dir,
|
||||
const char *profile_dir,
|
||||
const char *existing_path,
|
||||
gboolean existing_path_read_only,
|
||||
gboolean force_rename,
|
||||
NMSKeyfileWriterAllowFilenameCb allow_filename_cb,
|
||||
gpointer allow_filename_user_data,
|
||||
|
|
@ -347,21 +368,16 @@ 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_KEYFILE_PATH_NAME_RUN;
|
||||
|
||||
return _internal_write_connection (connection,
|
||||
is_nm_generated,
|
||||
is_volatile,
|
||||
keyfile_dir,
|
||||
nms_keyfile_utils_get_path (),
|
||||
profile_dir,
|
||||
TRUE,
|
||||
0,
|
||||
0,
|
||||
existing_path,
|
||||
FALSE,
|
||||
existing_path_read_only,
|
||||
force_rename,
|
||||
allow_filename_cb,
|
||||
allow_filename_user_data,
|
||||
|
|
@ -382,6 +398,8 @@ nms_keyfile_writer_test_connection (NMConnection *connection,
|
|||
GError **error)
|
||||
{
|
||||
return _internal_write_connection (connection,
|
||||
FALSE,
|
||||
FALSE,
|
||||
keyfile_dir,
|
||||
keyfile_dir,
|
||||
FALSE,
|
||||
|
|
|
|||
|
|
@ -27,8 +27,12 @@ typedef gboolean (*NMSKeyfileWriterAllowFilenameCb) (const char *check_filename,
|
|||
gpointer allow_filename_user_data);
|
||||
|
||||
gboolean nms_keyfile_writer_connection (NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
gboolean is_nm_generated,
|
||||
gboolean is_volatile,
|
||||
const char *keyfile_dir,
|
||||
const char *profile_dir,
|
||||
const char *existing_path,
|
||||
gboolean existing_path_read_only,
|
||||
gboolean force_rename,
|
||||
NMSKeyfileWriterAllowFilenameCb allow_filename_cb,
|
||||
gpointer allow_filename_user_data,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@ check_ip_route (NMSettingIPConfig *config, int idx, const char *destination, int
|
|||
g_assert (full_filename && full_filename[0] == '/'); \
|
||||
\
|
||||
_connection = nms_keyfile_reader_from_file (full_filename, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
(nmtst_get_rand_uint32 () % 2) ? &_error : NULL); \
|
||||
nmtst_assert_success (_connection, _error); \
|
||||
|
|
@ -2507,14 +2510,14 @@ test_nm_keyfile_plugin_utils_escape_filename (void)
|
|||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_assert_keyfile_loaded_uuid (const char *dirname,
|
||||
const char *uuid,
|
||||
const char *loaded_path,
|
||||
gboolean allow_relative,
|
||||
const char *exp_full_filename,
|
||||
const char *exp_uuid,
|
||||
const char *exp_symlink_target,
|
||||
const char *exp_loaded_path)
|
||||
_assert_keyfile_nmmeta (const char *dirname,
|
||||
const char *uuid,
|
||||
const char *loaded_path,
|
||||
gboolean allow_relative,
|
||||
const char *exp_full_filename,
|
||||
const char *exp_uuid,
|
||||
const char *exp_symlink_target,
|
||||
const char *exp_loaded_path)
|
||||
{
|
||||
gs_free char *full_filename = NULL;
|
||||
gs_free char *symlink_target = NULL;
|
||||
|
|
@ -2533,12 +2536,12 @@ _assert_keyfile_loaded_uuid (const char *dirname,
|
|||
|
||||
filename = g_path_get_basename (exp_full_filename);
|
||||
|
||||
full_filename = nms_keyfile_loaded_uuid_filename (dirname, uuid, FALSE);
|
||||
full_filename = nms_keyfile_nmmeta_filename (dirname, uuid, FALSE);
|
||||
g_assert_cmpstr (full_filename, ==, full_filename);
|
||||
nm_clear_g_free (&full_filename);
|
||||
|
||||
|
||||
g_assert (nms_keyfile_loaded_uuid_write (dirname, uuid, loaded_path, allow_relative, &full_filename));
|
||||
g_assert (nms_keyfile_nmmeta_write (dirname, uuid, loaded_path, allow_relative, &full_filename));
|
||||
g_assert_cmpstr (full_filename, ==, exp_full_filename);
|
||||
nm_clear_g_free (&full_filename);
|
||||
|
||||
|
|
@ -2550,7 +2553,7 @@ _assert_keyfile_loaded_uuid (const char *dirname,
|
|||
g_assert_cmpstr (symlink_target, ==, exp_symlink_target);
|
||||
|
||||
|
||||
success = nms_keyfile_loaded_uuid_read (dirname, filename, &full_filename, &uuid2, &loaded_path2);
|
||||
success = nms_keyfile_nmmeta_read (dirname, filename, &full_filename, &uuid2, &loaded_path2, NULL);
|
||||
g_assert_cmpint (!!exp_uuid, ==, success);
|
||||
if (success)
|
||||
g_assert_cmpstr (full_filename, ==, exp_full_filename);
|
||||
|
|
@ -2561,7 +2564,7 @@ _assert_keyfile_loaded_uuid (const char *dirname,
|
|||
g_assert_cmpstr (loaded_path2, ==, exp_loaded_path);
|
||||
|
||||
|
||||
success = nms_keyfile_loaded_uuid_read_from_file (exp_full_filename, &dirname3, &filename3, &uuid3, &loaded_path3);
|
||||
success = nms_keyfile_nmmeta_read_from_file (exp_full_filename, &dirname3, &filename3, &uuid3, &loaded_path3);
|
||||
g_assert_cmpint (!!exp_uuid, ==, success);
|
||||
if (success) {
|
||||
g_assert_cmpstr (dirname3, ==, dirname);
|
||||
|
|
@ -2575,34 +2578,33 @@ _assert_keyfile_loaded_uuid (const char *dirname,
|
|||
}
|
||||
|
||||
static void
|
||||
test_loaded_uuid (void)
|
||||
test_nmmeta (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",
|
||||
TEST_SCRATCH_DIR,
|
||||
filename2);
|
||||
|
||||
_assert_keyfile_loaded_uuid (TEST_SCRATCH_DIR, uuid, NULL, FALSE, full_filename, NULL, NULL, NULL);
|
||||
_assert_keyfile_loaded_uuid (TEST_SCRATCH_DIR, uuid, NULL, TRUE, full_filename, NULL, NULL, NULL);
|
||||
_assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, NULL, FALSE, full_filename, NULL, NULL, NULL);
|
||||
_assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, NULL, TRUE, full_filename, NULL, NULL, NULL);
|
||||
|
||||
_assert_keyfile_loaded_uuid (TEST_SCRATCH_DIR, uuid, loaded_path0, FALSE, full_filename, uuid, loaded_path0, loaded_path0);
|
||||
_assert_keyfile_loaded_uuid (TEST_SCRATCH_DIR, uuid, loaded_path0, TRUE, full_filename, uuid, loaded_path0, loaded_path0);
|
||||
_assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path0, FALSE, full_filename, uuid, loaded_path0, loaded_path0);
|
||||
_assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path0, TRUE, full_filename, uuid, loaded_path0, loaded_path0);
|
||||
|
||||
_assert_keyfile_loaded_uuid (TEST_SCRATCH_DIR, uuid, loaded_path1, FALSE, full_filename, uuid, loaded_path1, loaded_path1);
|
||||
_assert_keyfile_loaded_uuid (TEST_SCRATCH_DIR, uuid, loaded_path1, TRUE, full_filename, uuid, loaded_path1, loaded_path1);
|
||||
_assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path1, FALSE, full_filename, uuid, loaded_path1, loaded_path1);
|
||||
_assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path1, TRUE, full_filename, uuid, loaded_path1, loaded_path1);
|
||||
|
||||
_assert_keyfile_loaded_uuid (TEST_SCRATCH_DIR, uuid, loaded_path2, FALSE, full_filename, uuid, loaded_path2, loaded_path2);
|
||||
_assert_keyfile_loaded_uuid (TEST_SCRATCH_DIR, uuid, loaded_path2, TRUE, full_filename, uuid, filename2, loaded_path2);
|
||||
_assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path2, FALSE, full_filename, uuid, loaded_path2, loaded_path2);
|
||||
_assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path2, TRUE, full_filename, uuid, filename2, loaded_path2);
|
||||
|
||||
(void) unlink (full_filename);
|
||||
}
|
||||
|
|
@ -2696,7 +2698,7 @@ int main (int argc, char **argv)
|
|||
|
||||
g_test_add_func ("/keyfile/test_nm_keyfile_plugin_utils_escape_filename", test_nm_keyfile_plugin_utils_escape_filename);
|
||||
|
||||
g_test_add_func ("/keyfile/test_loaded_uuid", test_loaded_uuid);
|
||||
g_test_add_func ("/keyfile/test_nmmeta", test_nmmeta);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ for dir in "${pkgconfdir}/conf.d" \
|
|||
"${pkglibdir}/dispatcher.d/no-wait.d" \
|
||||
"${pkglibdir}/dispatcher.d/pre-down.d" \
|
||||
"${pkglibdir}/dispatcher.d/pre-up.d" \
|
||||
"${pkglibdir}/system-connections" \
|
||||
"${pkglibdir}/VPN"; do
|
||||
mkdir -p "${DESTDIR}${dir}"
|
||||
chmod 0755 "${DESTDIR}${dir}"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue