config: merge branch 'th/nm-config-intern-bgo750558'

Add write support to NMConfig.

Also, add a new configuration directory /usr/lib/NetworkManager/conf.d/
which allows us to install configuration snippets under /usr, instead
of /etc.

https://bugzilla.gnome.org/show_bug.cgi?id=738853
https://bugzilla.gnome.org/show_bug.cgi?id=750558
This commit is contained in:
Thomas Haller 2015-07-02 16:02:36 +02:00
commit 05db3ee08a
14 changed files with 1503 additions and 188 deletions

View file

@ -78,6 +78,7 @@ AC_SUBST(runstatedir)
# NetworkManager paths # NetworkManager paths
AC_SUBST(nmbinary, "$sbindir/$PACKAGE", [NetworkManager binary executable]) AC_SUBST(nmbinary, "$sbindir/$PACKAGE", [NetworkManager binary executable])
AC_SUBST(nmconfdir, "$sysconfdir/$PACKAGE", [NetworkManager configuration directory]) AC_SUBST(nmconfdir, "$sysconfdir/$PACKAGE", [NetworkManager configuration directory])
AC_SUBST(nmlibdir, "$libdir/$PACKAGE", [NetworkManager library directory])
AC_SUBST(nmdatadir, "$datadir/$PACKAGE", [NetworkManager shared data directory]) AC_SUBST(nmdatadir, "$datadir/$PACKAGE", [NetworkManager shared data directory])
AC_SUBST(nmstatedir, "$localstatedir/lib/$PACKAGE", [NetworkManager persistent state directory]) AC_SUBST(nmstatedir, "$localstatedir/lib/$PACKAGE", [NetworkManager persistent state directory])
AC_SUBST(nmrundir, "$runstatedir/$PACKAGE", [NetworkManager runtime state directory]) AC_SUBST(nmrundir, "$runstatedir/$PACKAGE", [NetworkManager runtime state directory])
@ -125,6 +126,11 @@ test "$enable_ifnet" = "yes" && distro_plugins="$distro_plugins,ifn
distro_plugins="${distro_plugins#,}" distro_plugins="${distro_plugins#,}"
AC_DEFINE_UNQUOTED(CONFIG_PLUGINS_DEFAULT, "$config_plugins_default", [Default configuration option for main.plugins setting]) AC_DEFINE_UNQUOTED(CONFIG_PLUGINS_DEFAULT, "$config_plugins_default", [Default configuration option for main.plugins setting])
if test "${enable_config_plugin_ibft}" = yes; then
AC_DEFINE(WITH_SETTINGS_PLUGIN_IBFT, 1, [Whether compilation of ibft setting plugin is enabled])
else
AC_DEFINE(WITH_SETTINGS_PLUGIN_IBFT, 0, [Whether compilation of ibft setting plugin is enabled])
fi
if test "$enable_ifcfg_rh" = "yes"; then if test "$enable_ifcfg_rh" = "yes"; then
DISTRO_NETWORK_SERVICE=network.service DISTRO_NETWORK_SERVICE=network.service
@ -1065,6 +1071,7 @@ echo " exec_prefix: $exec_prefix"
echo " systemdunitdir: $with_systemdsystemunitdir" echo " systemdunitdir: $with_systemdsystemunitdir"
echo " nmbinary: $nmbinary" echo " nmbinary: $nmbinary"
echo " nmconfdir: $nmconfdir" echo " nmconfdir: $nmconfdir"
echo " nmlibdir: $nmlibdir"
echo " nmdatadir: $nmdatadir" echo " nmdatadir: $nmdatadir"
echo " nmstatedir: $nmstatedir" echo " nmstatedir: $nmstatedir"
echo " nmrundir: $nmrundir" echo " nmrundir: $nmrundir"

View file

@ -2,14 +2,24 @@
# #
# See "man 5 NetworkManager.conf" for details. # See "man 5 NetworkManager.conf" for details.
# #
# The directory /usr/lib/NetworkManager/conf.d/ can contain additional configuration
# snippets installed by packages. These files are read before NetworkManager.conf
# and have thus lowest priority.
# The directory /etc/NetworkManager/conf.d/ can contain additional configuration # The directory /etc/NetworkManager/conf.d/ can contain additional configuration
# snippets that are installed by some packages. Those snippets override the # snippets. Those snippets override the settings from this main file.
# settings from this main file. #
# To override a configuration from a conf.d/ snippet, add another configuration # The files within one conf.d/ directory are read in asciibetical order.
# with a name sorted lastly (such as 99-my.conf). #
# If /etc/NetworkManager/conf.d/ contains a file with the same name as
# /usr/lib/NetworkManager/conf.d/, the latter file is shadowed and thus ignored.
# Hence, to disable loading a file from /usr/lib/NetworkManager/conf.d/ you can
# put an empty file with the same name.
#
# If two files define the same key, the one that is read afterwards will overwrite
# the previous one.
[main] [main]
plugins=ifcfg-rh,ibft #plugins=ifcfg-rh,ibft
[logging] [logging]
#level=DEBUG #level=DEBUG

View file

@ -34,6 +34,7 @@
%define systemd_dir %{_prefix}/lib/systemd/system %define systemd_dir %{_prefix}/lib/systemd/system
%define udev_dir %{_prefix}/lib/udev %define udev_dir %{_prefix}/lib/udev
%define nmlibdir %{_prefix}/lib/%{name}
%global with_adsl 1 %global with_adsl 1
%global with_bluetooth 1 %global with_bluetooth 1
@ -83,8 +84,7 @@ URL: http://www.gnome.org/projects/NetworkManager/
Source: __SOURCE1__ Source: __SOURCE1__
Source1: NetworkManager.conf Source1: NetworkManager.conf
Source2: 00-server.conf Source2: 00-server.conf
Source3: 10-ibft-plugin.conf Source3: 20-connectivity-fedora.conf
Source4: 20-connectivity-fedora.conf
#Patch1: 0001-some.patch #Patch1: 0001-some.patch
@ -443,9 +443,9 @@ make install DESTDIR=$RPM_BUILD_ROOT
%{__cp} %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/ %{__cp} %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/conf.d mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/conf.d
%{__cp} %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/conf.d mkdir -p $RPM_BUILD_ROOT%{nmlibdir}/conf.d
%{__cp} %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/conf.d %{__cp} %{SOURCE2} $RPM_BUILD_ROOT%{nmlibdir}/conf.d/
%{__cp} %{SOURCE4} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/conf.d %{__cp} %{SOURCE3} $RPM_BUILD_ROOT%{nmlibdir}/conf.d/
# create a VPN directory # create a VPN directory
%{__mkdir_p} $RPM_BUILD_ROOT%{_sysconfdir}/NetworkManager/VPN %{__mkdir_p} $RPM_BUILD_ROOT%{_sysconfdir}/NetworkManager/VPN
@ -543,7 +543,8 @@ fi
%endif %endif
%dir %{_sysconfdir}/%{name} %dir %{_sysconfdir}/%{name}
%dir %{_sysconfdir}/%{name}/conf.d %dir %{_sysconfdir}/%{name}/conf.d
%config %{_sysconfdir}/%{name}/conf.d/10-ibft-plugin.conf %dir %{nmlibdir}
%dir %{nmlibdir}/conf.d
%{_mandir}/man1/* %{_mandir}/man1/*
%{_mandir}/man5/* %{_mandir}/man5/*
%{_mandir}/man8/* %{_mandir}/man8/*
@ -660,15 +661,15 @@ fi
%files config-connectivity-fedora %files config-connectivity-fedora
%defattr(-,root,root,0755) %defattr(-,root,root,0755)
%dir %{_sysconfdir}/%{name} %dir %{nmlibdir}
%dir %{_sysconfdir}/%{name}/conf.d %dir %{nmlibdir}/conf.d
%config(noreplace) %{_sysconfdir}/%{name}/conf.d/20-connectivity-fedora.conf %{nmlibdir}/conf.d/20-connectivity-fedora.conf
%files config-server %files config-server
%defattr(-,root,root,0755) %defattr(-,root,root,0755)
%dir %{_sysconfdir}/%{name} %dir %{nmlibdir}
%dir %{_sysconfdir}/%{name}/conf.d %dir %{nmlibdir}/conf.d
%config(noreplace) %{_sysconfdir}/%{name}/conf.d/00-server.conf %{nmlibdir}/conf.d/00-server.conf
%if 0%{?with_nmtui} %if 0%{?with_nmtui}
%files tui %files tui

View file

@ -73,7 +73,6 @@ SOURCE="$(abs_path "$SOURCE" "$(ls -1 "$GITDIR/NetworkManager-$VERSION"*.tar* 2>
[[ -f "$SOURCE" ]] || die "could not find source ${_SOURCE:-$GITDIR/NetworkManager-$VERSION*.tar*} . Did you execute \`make dist\`? Otherwise set \$SOURCE variable" [[ -f "$SOURCE" ]] || die "could not find source ${_SOURCE:-$GITDIR/NetworkManager-$VERSION*.tar*} . Did you execute \`make dist\`? Otherwise set \$SOURCE variable"
SOURCE_NETWORKMANAGER_CONF="$(abs_path "$SOURCE_NETWORKMANAGER_CONF" "$SCRIPTDIR/NetworkManager.conf")" SOURCE_NETWORKMANAGER_CONF="$(abs_path "$SOURCE_NETWORKMANAGER_CONF" "$SCRIPTDIR/NetworkManager.conf")"
SOURCE_CONFIG_SERVER="$(abs_path "$SOURCE_CONFIG_SERVER" "$SCRIPTDIR/00-server.conf")" SOURCE_CONFIG_SERVER="$(abs_path "$SOURCE_CONFIG_SERVER" "$SCRIPTDIR/00-server.conf")"
SOURCE_CONFIG_IBFT_PLUGIN="$(abs_path "$SOURCE_CONFIG_IBFT_PLUGIN" "$SCRIPTDIR/10-ibft-plugin.conf")"
SOURCE_CONFIG_CONNECTIVITY_FEDORA="$(abs_path "$SOURCE_CONFIG_CONNECTIVITY_FEDORA" "$SCRIPTDIR/20-connectivity-fedora.conf")" SOURCE_CONFIG_CONNECTIVITY_FEDORA="$(abs_path "$SOURCE_CONFIG_CONNECTIVITY_FEDORA" "$SCRIPTDIR/20-connectivity-fedora.conf")"
TEMP="$(mktemp -d "$SCRIPTDIR/NetworkManager.$DATE.XXXXXX")" TEMP="$(mktemp -d "$SCRIPTDIR/NetworkManager.$DATE.XXXXXX")"
@ -88,7 +87,6 @@ LOG "SPECFILE=$SPECFILE"
LOG "SOURCE=$SOURCE" LOG "SOURCE=$SOURCE"
LOG "SOURCE_NETWORKMANAGER_CONF=$SOURCE_NETWORKMANAGER_CONF" LOG "SOURCE_NETWORKMANAGER_CONF=$SOURCE_NETWORKMANAGER_CONF"
LOG "SOURCE_CONFIG_SERVER=$SOURCE_CONFIG_SERVER" LOG "SOURCE_CONFIG_SERVER=$SOURCE_CONFIG_SERVER"
LOG "SOURCE_CONFIG_IBFT_PLUGIN=$SOURCE_CONFIG_IBFT_PLUGIN"
LOG "SOURCE_CONFIG_CONNECTIVITY_FEDORA=$SOURCE_CONFIG_CONNECTIVITY_FEDORA" LOG "SOURCE_CONFIG_CONNECTIVITY_FEDORA=$SOURCE_CONFIG_CONNECTIVITY_FEDORA"
LOG "BASEDIR=$TEMP" LOG "BASEDIR=$TEMP"
@ -102,7 +100,6 @@ mkdir -p "$TEMP/SOURCES/" "$TEMP/SPECS/" || die "error creating SPECS directoy"
cp "$SOURCE" "$TEMP/SOURCES/" || die "Could not copy source $SOURCE to $TEMP/SOURCES" cp "$SOURCE" "$TEMP/SOURCES/" || die "Could not copy source $SOURCE to $TEMP/SOURCES"
cp "$SOURCE_NETWORKMANAGER_CONF" "$TEMP/SOURCES/NetworkManager.conf" || die "Could not copy source $SOURCE_NETWORKMANAGER_CONF to $TEMP/SOURCES" cp "$SOURCE_NETWORKMANAGER_CONF" "$TEMP/SOURCES/NetworkManager.conf" || die "Could not copy source $SOURCE_NETWORKMANAGER_CONF to $TEMP/SOURCES"
cp "$SOURCE_CONFIG_SERVER" "$TEMP/SOURCES/00-server.conf" || die "Could not copy source $SOURCE_CONFIG_SERVER to $TEMP/SOURCES" cp "$SOURCE_CONFIG_SERVER" "$TEMP/SOURCES/00-server.conf" || die "Could not copy source $SOURCE_CONFIG_SERVER to $TEMP/SOURCES"
cp "$SOURCE_CONFIG_IBFT_PLUGIN" "$TEMP/SOURCES/10-ibft-plugin.conf" || die "Could not copy source $SOURCE_CONFIG_IBFT_PLUGIN to $TEMP/SOURCES"
cp "$SOURCE_CONFIG_CONNECTIVITY_FEDORA" "$TEMP/SOURCES/20-connectivity-fedora.conf" || die "Could not copy source $SOURCE_CONFIG_CONNECTIVITY_FEDORA to $TEMP/SOURCES" cp "$SOURCE_CONFIG_CONNECTIVITY_FEDORA" "$TEMP/SOURCES/20-connectivity-fedora.conf" || die "Could not copy source $SOURCE_CONFIG_CONNECTIVITY_FEDORA to $TEMP/SOURCES"
write_changelog write_changelog

View file

@ -27,23 +27,39 @@ Copyright 2010 - 2014 Red Hat, Inc.
<refsynopsisdiv> <refsynopsisdiv>
<para><filename>/etc/NetworkManager/NetworkManager.conf</filename>, <para><filename>/etc/NetworkManager/NetworkManager.conf</filename>,
<filename>/etc/NetworkManager/conf.d/<replaceable>name</replaceable>.conf</filename> <filename>/etc/NetworkManager/conf.d/<replaceable>name</replaceable>.conf</filename>,
<filename>/usr/lib/NetworkManager/conf.d/<replaceable>name</replaceable>.conf</filename>,
<filename>/var/lib/NetworkManager/NetworkManager-intern.conf</filename>
</para> </para>
</refsynopsisdiv> </refsynopsisdiv>
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para>This is a configuration file for NetworkManager. It is used <para><literal>NetworkManager.conf</literal> is the configuration file for NetworkManager. It is used
to set up various aspects of NetworkManager's behavior. The to set up various aspects of NetworkManager's behavior. The
location of the file may be changed through use of the location of the main file and configuration directories may be changed
<option>--config</option> argument for NetworkManager. through use of the <option>--config</option>, <option>--config-dir</option>,
<option>--system-config-dir</option>, and <option>--intern-config</option>
argument for NetworkManager, respectively.
</para> </para>
<para>If a default <literal>NetworkManager.conf</literal> is <para>If a default <literal>NetworkManager.conf</literal> is
provided by your distribution's packages, you should not modify provided by your distribution's packages, you should not modify
it, since your changes may get overwritten by package it, since your changes may get overwritten by package
updates. Instead, you can add additional <literal>.conf</literal> updates. Instead, you can add additional <literal>.conf</literal>
files to the <literal>conf.d</literal> directory. These will be read in order, files to the <literal>/etc/NetworkManager/conf.d</literal> directory.
with later files overriding earlier ones. These will be read in order, with later files overriding earlier ones.
Packages might install further configuration snippets to <literal>/usr/lib/NetworkManager/conf.d</literal>.
This directory is parsed first, even before <literal>NetworkManager.conf</literal>.
The loading of a file <literal>/usr/lib/NetworkManager/conf.d/<replaceable>name</replaceable>.conf</literal>
can be prevented by adding a file <literal>/etc/NetworkManager/conf.d/<replaceable>name</replaceable>.conf</literal>.
In this case, the file from the etc configuration shadows the file from the
system configuration directory.
</para>
<para>
NetworkManager can overwrite certain user configuration options via D-Bus or other internal
operations. In this case it writes those changes to <literal>/var/lib/NetworkManager/NetworkManager-intern.conf</literal>.
This file is not intended to be modified by the user, but it is read last and can shadow
user configuration from <literal>NetworkManager.conf</literal>.
</para> </para>
</refsect1> </refsect1>
@ -625,6 +641,9 @@ ipv6.ip6-privacy=1
<filename>/etc/sysconfig/network-scripts/ifcfg-*</filename> <filename>/etc/sysconfig/network-scripts/ifcfg-*</filename>
files. It currently supports reading Ethernet, Wi-Fi, files. It currently supports reading Ethernet, Wi-Fi,
InfiniBand, VLAN, Bond, Bridge, and Team connections. InfiniBand, VLAN, Bond, Bridge, and Team connections.
Enabling <literal>ifcfg-rh</literal> implicitly enables
<literal>ibft</literal> plugin, if it is available.
This can be disabled by adding <literal>no-ibft</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -658,12 +677,16 @@ ipv6.ip6-privacy=1
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>ibft</varname></term> <term><varname>ibft</varname>, <varname>no-ibft</varname></term>
<listitem> <listitem>
<para> <para>
This plugin allows to read iBFT configuration (iSCSI Boot Firmware Table). This plugin allows to read iBFT configuration (iSCSI Boot Firmware Table).
The configuration is read using /sbin/iscsiadm. Users are expected to The configuration is read using /sbin/iscsiadm. Users are expected to
configure iBFT connections via the firmware interfaces. configure iBFT connections via the firmware interfaces.
If ibft support is available, it is automatically enabled after
<literal>ifcfg-rh</literal>. This can be disabled by <literal>no-ibft</literal>.
You can also explicitly specify <literal>ibft</literal> to load the
plugin without <literal>ifcfg-rh</literal> or to change the plugin order.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View file

@ -428,6 +428,7 @@ AM_CPPFLAGS += \
-DNMPLUGINDIR=\"$(pkglibdir)\" \ -DNMPLUGINDIR=\"$(pkglibdir)\" \
-DNMRUNDIR=\"$(nmrundir)\" \ -DNMRUNDIR=\"$(nmrundir)\" \
-DNMSTATEDIR=\"$(nmstatedir)\" \ -DNMSTATEDIR=\"$(nmstatedir)\" \
-DNMLIBDIR=\"$(nmlibdir)\" \
\ \
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \ -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \

View file

@ -3323,7 +3323,7 @@ ip4_config_merge_and_apply (NMDevice *self,
if ( !priv->default_route.v4_configure_first_time if ( !priv->default_route.v4_configure_first_time
&& !nm_device_uses_assumed_connection (self) && !nm_device_uses_assumed_connection (self)
&& connection_is_never_default) { && connection_is_never_default) {
/* If the connection is explicitly configured as never-default, we enforce the (absense of the) /* If the connection is explicitly configured as never-default, we enforce the (absence of the)
* default-route only once. That allows the user to configure a connection as never-default, * default-route only once. That allows the user to configure a connection as never-default,
* but he can add default routes externally (via a dispatcher script) and NM will not interfere. */ * but he can add default routes externally (via a dispatcher script) and NM will not interfere. */
goto END_ADD_DEFAULT_ROUTE; goto END_ADD_DEFAULT_ROUTE;

View file

@ -343,7 +343,7 @@ main (int argc, char *argv[])
} }
/* Read the config file and CLI overrides */ /* Read the config file and CLI overrides */
config = nm_config_setup (config_cli, &error); config = nm_config_setup (config_cli, NULL, &error);
nm_config_cmd_line_options_free (config_cli); nm_config_cmd_line_options_free (config_cli);
config_cli = NULL; config_cli = NULL;
if (config == NULL) { if (config == NULL) {

View file

@ -48,6 +48,8 @@ typedef struct {
char *config_description; char *config_description;
GKeyFile *keyfile; GKeyFile *keyfile;
GKeyFile *keyfile_user;
GKeyFile *keyfile_intern;
/* A zero-terminated list of pre-processed information from the /* A zero-terminated list of pre-processed information from the
* [connection] sections. This is to speed up lookup. */ * [connection] sections. This is to speed up lookup. */
@ -77,7 +79,8 @@ enum {
PROP_0, PROP_0,
PROP_CONFIG_MAIN_FILE, PROP_CONFIG_MAIN_FILE,
PROP_CONFIG_DESCRIPTION, PROP_CONFIG_DESCRIPTION,
PROP_KEYFILE, PROP_KEYFILE_USER,
PROP_KEYFILE_INTERN,
PROP_CONNECTIVITY_URI, PROP_CONNECTIVITY_URI,
PROP_CONNECTIVITY_INTERVAL, PROP_CONNECTIVITY_INTERVAL,
PROP_CONNECTIVITY_RESPONSE, PROP_CONNECTIVITY_RESPONSE,
@ -92,6 +95,14 @@ G_DEFINE_TYPE (NMConfigData, nm_config_data, G_TYPE_OBJECT)
/************************************************************************/ /************************************************************************/
#define _HAS_PREFIX(str, prefix) \
({ \
const char *_str = (str); \
g_str_has_prefix ( _str, ""prefix"") && _str[STRLEN(prefix)] != '\0'; \
})
/************************************************************************/
const char * const char *
nm_config_data_get_config_main_file (const NMConfigData *self) nm_config_data_get_config_main_file (const NMConfigData *self)
{ {
@ -238,6 +249,40 @@ nm_config_data_get_assume_ipv6ll_only (const NMConfigData *self, NMDevice *devic
return nm_device_spec_match_list (device, NM_CONFIG_DATA_GET_PRIVATE (self)->assume_ipv6ll_only); return nm_device_spec_match_list (device, NM_CONFIG_DATA_GET_PRIVATE (self)->assume_ipv6ll_only);
} }
GKeyFile *
nm_config_data_clone_keyfile_intern (const NMConfigData *self)
{
NMConfigDataPrivate *priv;
GKeyFile *keyfile;
g_return_val_if_fail (NM_IS_CONFIG_DATA (self), FALSE);
priv = NM_CONFIG_DATA_GET_PRIVATE (self);
keyfile = nm_config_create_keyfile ();
if (priv->keyfile_intern)
_nm_keyfile_copy (keyfile, priv->keyfile_intern);
return keyfile;
}
GKeyFile *
_nm_config_data_get_keyfile (const NMConfigData *self)
{
return NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile;
}
GKeyFile *
_nm_config_data_get_keyfile_intern (const NMConfigData *self)
{
return NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile_intern;
}
GKeyFile *
_nm_config_data_get_keyfile_user (const NMConfigData *self)
{
return NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile_user;
}
/************************************************************************/ /************************************************************************/
/** /**
@ -265,15 +310,128 @@ nm_config_data_get_keys (const NMConfigData *self, const char *group)
return g_key_file_get_keys (NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile, group, NULL, NULL); return g_key_file_get_keys (NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile, group, NULL, NULL);
} }
/**
* nm_config_data_is_intern_atomic_group:
* @self:
* @group: name of the group to check.
*
* whether a configuration group @group exists and is entirely overwritten
* by internal configuration, i.e. whether it is an atomic group that is
* overwritten.
*
* It doesn't say, that there actually is a user setting that was overwritten. That
* means there could be no corresponding section defined in user configuration
* that required overwriting.
*
* Returns: %TRUE if @group exists and is an atomic group set via internal configuration.
*/
gboolean
nm_config_data_is_intern_atomic_group (const NMConfigData *self, const char *group)
{
NMConfigDataPrivate *priv;
g_return_val_if_fail (NM_IS_CONFIG_DATA (self), FALSE);
g_return_val_if_fail (group && *group, FALSE);
priv = NM_CONFIG_DATA_GET_PRIVATE (self);
if ( !priv->keyfile_intern
|| !g_key_file_has_key (priv->keyfile_intern, group, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS, NULL))
return FALSE;
/* we have a .was entry for the section. That means that the section would be overwritten
* from user configuration. But it doesn't mean that the merged configuration contains this
* groups, because the internal setting could hide the user section.
* Only return TRUE, if we actually have such a group in the merged configuration.*/
return g_key_file_has_group (priv->keyfile, group);
}
/************************************************************************/
static GKeyFile *
_merge_keyfiles (GKeyFile *keyfile_user, GKeyFile *keyfile_intern)
{
gs_strfreev char **groups = NULL;
guint g, k;
GKeyFile *keyfile;
gsize ngroups;
keyfile = nm_config_create_keyfile ();
if (keyfile_user)
_nm_keyfile_copy (keyfile, keyfile_user);
if (!keyfile_intern)
return keyfile;
groups = g_key_file_get_groups (keyfile_intern, &ngroups);
if (!groups)
return keyfile;
/* we must reverse the order of the connection settings so that we
* have lowest priority last. */
_nm_config_sort_groups (groups, ngroups);
for (g = 0; groups[g]; g++) {
const char *group = groups[g];
gs_strfreev char **keys = NULL;
gboolean is_intern, is_atomic = FALSE;
keys = g_key_file_get_keys (keyfile_intern, group, NULL, NULL);
if (!keys)
continue;
is_intern = g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
if ( !is_intern
&& g_key_file_has_key (keyfile_intern, group, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS, NULL)) {
/* the entire section is atomically overwritten by @keyfile_intern. */
g_key_file_remove_group (keyfile, group, NULL);
is_atomic = TRUE;
}
for (k = 0; keys[k]; k++) {
const char *key = keys[k];
gs_free char *value = NULL;
if (is_atomic && strcmp (key, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS) == 0)
continue;
if ( !is_intern && !is_atomic
&& _HAS_PREFIX (key, NM_CONFIG_KEYFILE_KEYPREFIX_WAS)) {
const char *key_base = &key[STRLEN (NM_CONFIG_KEYFILE_KEYPREFIX_WAS)];
if (!g_key_file_has_key (keyfile_intern, group, key_base, NULL))
g_key_file_remove_key (keyfile, group, key_base, NULL);
continue;
}
if (!is_intern && !is_atomic && _HAS_PREFIX (key, NM_CONFIG_KEYFILE_KEYPREFIX_SET))
continue;
value = g_key_file_get_value (keyfile_intern, group, key, NULL);
g_key_file_set_value (keyfile, group, key, value);
}
}
return keyfile;
}
/************************************************************************/ /************************************************************************/
static int static int
_nm_config_data_log_sort (const char **pa, const char **pb, gpointer dummy) _nm_config_data_log_sort (const char **pa, const char **pb, gpointer dummy)
{ {
gboolean a_is_connection, b_is_connection; gboolean a_is_connection, b_is_connection;
gboolean a_is_intern, b_is_intern;
const char *a = *pa; const char *a = *pa;
const char *b = *pb; const char *b = *pb;
/* we sort intern groups to the end. */
a_is_intern = g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
b_is_intern = g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
if (a_is_intern && b_is_intern)
return 0;
if (a_is_intern)
return 1;
if (b_is_intern)
return -1;
/* we sort connection groups before intern groups (to the end). */ /* we sort connection groups before intern groups (to the end). */
a_is_connection = a && g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION); a_is_connection = a && g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION);
b_is_connection = b && g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION); b_is_connection = b && g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION);
@ -336,9 +494,12 @@ nm_config_data_log (const NMConfigData *self, const char *prefix)
for (g = 0; g < ngroups; g++) { for (g = 0; g < ngroups; g++) {
const char *group = groups[g]; const char *group = groups[g];
gs_strfreev char **keys = NULL; gs_strfreev char **keys = NULL;
gboolean is_atomic;
is_atomic = nm_config_data_is_intern_atomic_group (self, group);
_LOG (""); _LOG ("");
_LOG ("[%s]", group); _LOG ("[%s]%s", group, is_atomic ? "*" : "");
keys = g_key_file_get_keys (priv->keyfile, group, NULL, NULL); keys = g_key_file_get_keys (priv->keyfile, group, NULL, NULL);
for (k = 0; keys && keys[k]; k++) { for (k = 0; keys && keys[k]; k++) {
@ -479,8 +640,11 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data)
priv_old = NM_CONFIG_DATA_GET_PRIVATE (old_data); priv_old = NM_CONFIG_DATA_GET_PRIVATE (old_data);
priv_new = NM_CONFIG_DATA_GET_PRIVATE (new_data); priv_new = NM_CONFIG_DATA_GET_PRIVATE (new_data);
if (!_nm_keyfile_equals (priv_old->keyfile, priv_new->keyfile, TRUE)) if (!_nm_keyfile_equals (priv_old->keyfile_user, priv_new->keyfile_user, TRUE))
changes |= NM_CONFIG_CHANGE_VALUES; changes |= NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER;
if (!_nm_keyfile_equals (priv_old->keyfile_intern, priv_new->keyfile_intern, TRUE))
changes |= NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN;
if ( g_strcmp0 (nm_config_data_get_config_main_file (old_data), nm_config_data_get_config_main_file (new_data)) != 0 if ( g_strcmp0 (nm_config_data_get_config_main_file (old_data), nm_config_data_get_config_main_file (new_data)) != 0
|| g_strcmp0 (nm_config_data_get_config_description (old_data), nm_config_data_get_config_description (new_data)) != 0) || g_strcmp0 (nm_config_data_get_config_description (old_data), nm_config_data_get_config_description (new_data)) != 0)
@ -553,10 +717,21 @@ set_property (GObject *object,
case PROP_CONFIG_DESCRIPTION: case PROP_CONFIG_DESCRIPTION:
priv->config_description = g_value_dup_string (value); priv->config_description = g_value_dup_string (value);
break; break;
case PROP_KEYFILE: case PROP_KEYFILE_USER:
priv->keyfile = g_value_dup_boxed (value); priv->keyfile_user = g_value_dup_boxed (value);
if (!priv->keyfile) if ( priv->keyfile_user
priv->keyfile = nm_config_create_keyfile (); && !_nm_keyfile_has_values (priv->keyfile_user)) {
g_key_file_unref (priv->keyfile_user);
priv->keyfile_user = NULL;
}
break;
case PROP_KEYFILE_INTERN:
priv->keyfile_intern = g_value_dup_boxed (value);
if ( priv->keyfile_intern
&& !_nm_keyfile_has_values (priv->keyfile_intern)) {
g_key_file_unref (priv->keyfile_intern);
priv->keyfile_intern = NULL;
}
break; break;
case PROP_NO_AUTO_DEFAULT: case PROP_NO_AUTO_DEFAULT:
{ {
@ -620,6 +795,10 @@ finalize (GObject *gobject)
} }
g_key_file_unref (priv->keyfile); g_key_file_unref (priv->keyfile);
if (priv->keyfile_user)
g_key_file_unref (priv->keyfile_user);
if (priv->keyfile_intern)
g_key_file_unref (priv->keyfile_intern);
G_OBJECT_CLASS (nm_config_data_parent_class)->finalize (gobject); G_OBJECT_CLASS (nm_config_data_parent_class)->finalize (gobject);
} }
@ -636,6 +815,8 @@ constructed (GObject *object)
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (self); NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (self);
char *interval; char *interval;
priv->keyfile = _merge_keyfiles (priv->keyfile_user, priv->keyfile_intern);
priv->connection_infos = _get_connection_infos (priv->keyfile); priv->connection_infos = _get_connection_infos (priv->keyfile);
priv->connectivity.uri = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "uri", NULL)); priv->connectivity.uri = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "uri", NULL));
@ -664,16 +845,32 @@ NMConfigData *
nm_config_data_new (const char *config_main_file, nm_config_data_new (const char *config_main_file,
const char *config_description, const char *config_description,
const char *const*no_auto_default, const char *const*no_auto_default,
GKeyFile *keyfile) GKeyFile *keyfile_user,
GKeyFile *keyfile_intern)
{ {
return g_object_new (NM_TYPE_CONFIG_DATA, return g_object_new (NM_TYPE_CONFIG_DATA,
NM_CONFIG_DATA_CONFIG_MAIN_FILE, config_main_file, NM_CONFIG_DATA_CONFIG_MAIN_FILE, config_main_file,
NM_CONFIG_DATA_CONFIG_DESCRIPTION, config_description, NM_CONFIG_DATA_CONFIG_DESCRIPTION, config_description,
NM_CONFIG_DATA_KEYFILE, keyfile, NM_CONFIG_DATA_KEYFILE_USER, keyfile_user,
NM_CONFIG_DATA_KEYFILE_INTERN, keyfile_intern,
NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default, NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default,
NULL); NULL);
} }
NMConfigData *
nm_config_data_new_update_keyfile_intern (const NMConfigData *base, GKeyFile *keyfile_intern)
{
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (base);
return g_object_new (NM_TYPE_CONFIG_DATA,
NM_CONFIG_DATA_CONFIG_MAIN_FILE, priv->config_main_file,
NM_CONFIG_DATA_CONFIG_DESCRIPTION, priv->config_description,
NM_CONFIG_DATA_KEYFILE_USER, priv->keyfile_user, /* the keyfile is unchanged. It's safe to share it. */
NM_CONFIG_DATA_KEYFILE_INTERN, keyfile_intern,
NM_CONFIG_DATA_NO_AUTO_DEFAULT, priv->no_auto_default.arr,
NULL);
}
NMConfigData * NMConfigData *
nm_config_data_new_update_no_auto_default (const NMConfigData *base, nm_config_data_new_update_no_auto_default (const NMConfigData *base,
const char *const*no_auto_default) const char *const*no_auto_default)
@ -683,7 +880,8 @@ nm_config_data_new_update_no_auto_default (const NMConfigData *base,
return g_object_new (NM_TYPE_CONFIG_DATA, return g_object_new (NM_TYPE_CONFIG_DATA,
NM_CONFIG_DATA_CONFIG_MAIN_FILE, priv->config_main_file, NM_CONFIG_DATA_CONFIG_MAIN_FILE, priv->config_main_file,
NM_CONFIG_DATA_CONFIG_DESCRIPTION, priv->config_description, NM_CONFIG_DATA_CONFIG_DESCRIPTION, priv->config_description,
NM_CONFIG_DATA_KEYFILE, priv->keyfile, /* the keyfile is unchanged. It's safe to share it. */ NM_CONFIG_DATA_KEYFILE_USER, priv->keyfile_user, /* the keyfile is unchanged. It's safe to share it. */
NM_CONFIG_DATA_KEYFILE_INTERN, priv->keyfile_intern,
NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default, NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default,
NULL); NULL);
} }
@ -718,8 +916,16 @@ nm_config_data_class_init (NMConfigDataClass *config_class)
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
g_object_class_install_property g_object_class_install_property
(object_class, PROP_KEYFILE, (object_class, PROP_KEYFILE_USER,
g_param_spec_boxed (NM_CONFIG_DATA_KEYFILE, "", "", g_param_spec_boxed (NM_CONFIG_DATA_KEYFILE_USER, "", "",
G_TYPE_KEY_FILE,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_KEYFILE_INTERN,
g_param_spec_boxed (NM_CONFIG_DATA_KEYFILE_INTERN, "", "",
G_TYPE_KEY_FILE, G_TYPE_KEY_FILE,
G_PARAM_WRITABLE | G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT_ONLY |

View file

@ -38,7 +38,8 @@ G_BEGIN_DECLS
#define NM_CONFIG_DATA_CONFIG_MAIN_FILE "config-main-file" #define NM_CONFIG_DATA_CONFIG_MAIN_FILE "config-main-file"
#define NM_CONFIG_DATA_CONFIG_DESCRIPTION "config-description" #define NM_CONFIG_DATA_CONFIG_DESCRIPTION "config-description"
#define NM_CONFIG_DATA_KEYFILE "keyfile" #define NM_CONFIG_DATA_KEYFILE_USER "keyfile-user"
#define NM_CONFIG_DATA_KEYFILE_INTERN "keyfile-intern"
#define NM_CONFIG_DATA_CONNECTIVITY_URI "connectivity-uri" #define NM_CONFIG_DATA_CONNECTIVITY_URI "connectivity-uri"
#define NM_CONFIG_DATA_CONNECTIVITY_INTERVAL "connectivity-interval" #define NM_CONFIG_DATA_CONNECTIVITY_INTERVAL "connectivity-interval"
#define NM_CONFIG_DATA_CONNECTIVITY_RESPONSE "connectivity-response" #define NM_CONFIG_DATA_CONNECTIVITY_RESPONSE "connectivity-response"
@ -71,10 +72,12 @@ typedef enum { /*< flags >*/
NM_CONFIG_CHANGE_CONFIG_FILES = (1L << 3), NM_CONFIG_CHANGE_CONFIG_FILES = (1L << 3),
NM_CONFIG_CHANGE_VALUES = (1L << 4), NM_CONFIG_CHANGE_VALUES = (1L << 4),
NM_CONFIG_CHANGE_CONNECTIVITY = (1L << 5), NM_CONFIG_CHANGE_VALUES_USER = (1L << 5),
NM_CONFIG_CHANGE_NO_AUTO_DEFAULT = (1L << 6), NM_CONFIG_CHANGE_VALUES_INTERN = (1L << 6),
NM_CONFIG_CHANGE_DNS_MODE = (1L << 7), NM_CONFIG_CHANGE_CONNECTIVITY = (1L << 7),
NM_CONFIG_CHANGE_RC_MANAGER = (1L << 8), NM_CONFIG_CHANGE_NO_AUTO_DEFAULT = (1L << 8),
NM_CONFIG_CHANGE_DNS_MODE = (1L << 9),
NM_CONFIG_CHANGE_RC_MANAGER = (1L << 10),
_NM_CONFIG_CHANGE_LAST, _NM_CONFIG_CHANGE_LAST,
NM_CONFIG_CHANGE_ALL = ((_NM_CONFIG_CHANGE_LAST - 1) << 1) - 1, NM_CONFIG_CHANGE_ALL = ((_NM_CONFIG_CHANGE_LAST - 1) << 1) - 1,
@ -93,7 +96,9 @@ GType nm_config_data_get_type (void);
NMConfigData *nm_config_data_new (const char *config_main_file, NMConfigData *nm_config_data_new (const char *config_main_file,
const char *config_description, const char *config_description,
const char *const*no_auto_default, const char *const*no_auto_default,
GKeyFile *keyfile); GKeyFile *keyfile_user,
GKeyFile *keyfile_intern);
NMConfigData *nm_config_data_new_update_keyfile_intern (const NMConfigData *base, GKeyFile *keyfile_intern);
NMConfigData *nm_config_data_new_update_no_auto_default (const NMConfigData *base, const char *const*no_auto_default); NMConfigData *nm_config_data_new_update_no_auto_default (const NMConfigData *base, const char *const*no_auto_default);
NMConfigChangeFlags nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data); NMConfigChangeFlags nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data);
@ -127,6 +132,14 @@ char *nm_config_data_get_connection_default (const NMConfigData *self,
char **nm_config_data_get_groups (const NMConfigData *self); char **nm_config_data_get_groups (const NMConfigData *self);
char **nm_config_data_get_keys (const NMConfigData *self, const char *group); char **nm_config_data_get_keys (const NMConfigData *self, const char *group);
gboolean nm_config_data_is_intern_atomic_group (const NMConfigData *self, const char *group);
GKeyFile *nm_config_data_clone_keyfile_intern (const NMConfigData *self);
/* private accessors */
GKeyFile *_nm_config_data_get_keyfile (const NMConfigData *self);
GKeyFile *_nm_config_data_get_keyfile_user (const NMConfigData *self);
GKeyFile *_nm_config_data_get_keyfile_intern (const NMConfigData *self);
G_END_DECLS G_END_DECLS

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,7 @@ G_BEGIN_DECLS
/* Properties */ /* Properties */
#define NM_CONFIG_CMD_LINE_OPTIONS "cmd-line-options" #define NM_CONFIG_CMD_LINE_OPTIONS "cmd-line-options"
#define NM_CONFIG_ATOMIC_SECTION_PREFIXES "atomic-section-prefixes"
/* Signals */ /* Signals */
#define NM_CONFIG_SIGNAL_CONFIG_CHANGED "config-changed" #define NM_CONFIG_SIGNAL_CONFIG_CHANGED "config-changed"
@ -48,6 +49,7 @@ G_BEGIN_DECLS
#define NM_CONFIG_KEYFILE_LIST_SEPARATOR ',' #define NM_CONFIG_KEYFILE_LIST_SEPARATOR ','
#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN ".intern."
#define NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION "connection" #define NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION "connection"
#define NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST ".test-append-stringlist" #define NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST ".test-append-stringlist"
@ -59,10 +61,14 @@ G_BEGIN_DECLS
#define NM_CONFIG_KEYFILE_GROUP_IFUPDOWN "ifupdown" #define NM_CONFIG_KEYFILE_GROUP_IFUPDOWN "ifupdown"
#define NM_CONFIG_KEYFILE_GROUP_IFNET "ifnet" #define NM_CONFIG_KEYFILE_GROUP_IFNET "ifnet"
#define NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS ".was"
#define NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH "auto_refresh" #define NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH "auto_refresh"
#define NM_CONFIG_KEYFILE_KEY_IFNET_MANAGED "managed" #define NM_CONFIG_KEYFILE_KEY_IFNET_MANAGED "managed"
#define NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED "managed" #define NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED "managed"
#define NM_CONFIG_KEYFILE_KEYPREFIX_WAS ".was."
#define NM_CONFIG_KEYFILE_KEYPREFIX_SET ".set."
typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions; typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions;
struct _NMConfig { struct _NMConfig {
@ -97,6 +103,11 @@ const char *nm_config_get_log_domains (NMConfig *config);
const char *nm_config_get_debug (NMConfig *config); const char *nm_config_get_debug (NMConfig *config);
gboolean nm_config_get_configure_and_quit (NMConfig *config); gboolean nm_config_get_configure_and_quit (NMConfig *config);
void nm_config_set_values (NMConfig *self,
GKeyFile *keyfile_intern_new,
gboolean allow_write,
gboolean force_rewrite);
/* for main.c only */ /* for main.c only */
NMConfigCmdLineOptions *nm_config_cmd_line_options_new (void); NMConfigCmdLineOptions *nm_config_cmd_line_options_new (void);
void nm_config_cmd_line_options_free (NMConfigCmdLineOptions *cli); void nm_config_cmd_line_options_free (NMConfigCmdLineOptions *cli);
@ -106,8 +117,8 @@ void nm_config_cmd_line_options_add_to_entries (NMConfigCmdLi
gboolean nm_config_get_no_auto_default_for_device (NMConfig *config, NMDevice *device); gboolean nm_config_get_no_auto_default_for_device (NMConfig *config, NMDevice *device);
void nm_config_set_no_auto_default_for_device (NMConfig *config, NMDevice *device); void nm_config_set_no_auto_default_for_device (NMConfig *config, NMDevice *device);
NMConfig *nm_config_new (const NMConfigCmdLineOptions *cli, GError **error); NMConfig *nm_config_new (const NMConfigCmdLineOptions *cli, char **atomic_section_prefixes, GError **error);
NMConfig *nm_config_setup (const NMConfigCmdLineOptions *cli, GError **error); NMConfig *nm_config_setup (const NMConfigCmdLineOptions *cli, char **atomic_section_prefixes, GError **error);
void nm_config_reload (NMConfig *config, int signal); void nm_config_reload (NMConfig *config, int signal);
gint nm_config_parse_boolean (const char *str, gint default_value); gint nm_config_parse_boolean (const char *str, gint default_value);
@ -128,6 +139,8 @@ void nm_config_keyfile_set_string_list (GKeyFile *keyfile,
gssize len); gssize len);
GSList *nm_config_get_device_match_spec (const GKeyFile *keyfile, const char *group, const char *key, gboolean *out_has_key); GSList *nm_config_get_device_match_spec (const GKeyFile *keyfile, const char *group, const char *key, gboolean *out_has_key);
void _nm_config_sort_groups (char **groups, gsize ngroups);
G_END_DECLS G_END_DECLS
#endif /* __NETWORKMANAGER_CONFIG_H__ */ #endif /* __NETWORKMANAGER_CONFIG_H__ */

View file

@ -764,18 +764,20 @@ load_plugins (NMSettings *self, const char **plugins, GError **error)
const char **iter; const char **iter;
gboolean keyfile_added = FALSE; gboolean keyfile_added = FALSE;
gboolean success = TRUE; gboolean success = TRUE;
gboolean add_ibft = FALSE;
gboolean has_no_ibft;
gssize idx_no_ibft, idx_ibft;
idx_ibft = _nm_utils_strv_find_first ((char **) plugins, -1, "ibft");
idx_no_ibft = _nm_utils_strv_find_first ((char **) plugins, -1, "no-ibft");
has_no_ibft = idx_no_ibft >= 0 && idx_no_ibft > idx_ibft;
#if WITH_SETTINGS_PLUGIN_IBFT
add_ibft = idx_no_ibft < 0 && idx_ibft < 0;
#endif
for (iter = plugins; iter && *iter; iter++) { for (iter = plugins; iter && *iter; iter++) {
GModule *plugin; const char *pname = *iter;
gs_free char *full_name = NULL;
gs_free char *path = NULL;
const char *pname;
GObject *obj; GObject *obj;
GObject * (*factory_func) (void);
struct stat st;
int errsv;
pname = *iter;
if (!*pname || strchr (pname, '/')) { if (!*pname || strchr (pname, '/')) {
LOG (LOGL_WARN, "ignore invalid plugin \"%s\"", pname); LOG (LOGL_WARN, "ignore invalid plugin \"%s\"", pname);
@ -787,6 +789,11 @@ load_plugins (NMSettings *self, const char **plugins, GError **error)
continue; continue;
} }
if (!strcmp (pname, "no-ibft"))
continue;
if (has_no_ibft && !strcmp (pname, "ibft"))
continue;
obj = find_plugin (list, pname); obj = find_plugin (list, pname);
if (obj) if (obj)
continue; continue;
@ -800,61 +807,79 @@ load_plugins (NMSettings *self, const char **plugins, GError **error)
continue; continue;
} }
full_name = g_strdup_printf ("nm-settings-plugin-%s", pname); load_plugin:
path = g_module_build_path (NMPLUGINDIR, full_name); {
GModule *plugin;
gs_free char *full_name = NULL;
gs_free char *path = NULL;
GObject * (*factory_func) (void);
struct stat st;
int errsv;
if (stat (path, &st) != 0) { full_name = g_strdup_printf ("nm-settings-plugin-%s", pname);
errsv = errno; path = g_module_build_path (NMPLUGINDIR, full_name);
LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': %s", pname, path, strerror (errsv));
continue;
}
if (!S_ISREG (st.st_mode)) {
LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': not a file", pname, path);
continue;
}
if (st.st_uid != 0) {
LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': file must be owned by root", pname, path);
continue;
}
if (st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) {
LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': invalid file permissions", pname, path);
continue;
}
plugin = g_module_open (path, G_MODULE_BIND_LOCAL); if (stat (path, &st) != 0) {
if (!plugin) { errsv = errno;
LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': %s", LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': %s", pname, path, strerror (errsv));
pname, path, g_module_error ()); goto next;
continue; }
if (!S_ISREG (st.st_mode)) {
LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': not a file", pname, path);
goto next;
}
if (st.st_uid != 0) {
LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': file must be owned by root", pname, path);
goto next;
}
if (st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) {
LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': invalid file permissions", pname, path);
goto next;
}
plugin = g_module_open (path, G_MODULE_BIND_LOCAL);
if (!plugin) {
LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': %s",
pname, path, g_module_error ());
goto next;
}
/* errors after this point are fatal, because we loaded the shared library already. */
if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
"Could not find plugin '%s' factory function.",
pname);
success = FALSE;
g_module_close (plugin);
break;
}
obj = (*factory_func) ();
if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
"Plugin '%s' returned invalid system config object.",
pname);
success = FALSE;
g_module_close (plugin);
break;
}
g_module_make_resident (plugin);
g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin);
g_object_set_data_full (obj, PLUGIN_MODULE_PATH, path, g_free);
path = NULL;
add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (obj));
list = g_slist_append (list, obj);
} }
next:
/* errors after this point are fatal, because we loaded the shared library already. */ if (add_ibft && !strcmp (pname, "ifcfg-rh")) {
/* The plugin ibft is not explicitly mentioned but we just enabled "ifcfg-rh".
if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) { * Enable "ibft" by default after "ifcfg-rh". */
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, pname = "ibft";
"Could not find plugin '%s' factory function.", add_ibft = FALSE;
pname); goto load_plugin;
success = FALSE;
g_module_close (plugin);
break;
} }
obj = (*factory_func) ();
if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
"Plugin '%s' returned invalid system config object.",
pname);
success = FALSE;
g_module_close (plugin);
break;
}
g_module_make_resident (plugin);
g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin);
g_object_set_data_full (obj, PLUGIN_MODULE_PATH, path, g_free);
path = NULL;
add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (obj));
list = g_slist_append (list, obj);
} }
/* If keyfile plugin was not among configured plugins, add it as the last one */ /* If keyfile plugin was not among configured plugins, add it as the last one */

View file

@ -32,8 +32,27 @@
#include "nm-test-utils.h" #include "nm-test-utils.h"
/********************************************************************************/
static void
_assert_config_value (const NMConfigData *config_data, const char *group, const char *key, const char *expected_value, const char *file, int line)
{
gs_free char *value = NULL;
value = nm_config_data_get_value (config_data, group, key, NM_CONFIG_GET_VALUE_NONE);
if (g_strcmp0 (value, expected_value)) {
g_error ("(%s:%d) invalid value in config-data %s.%s = %s%s%s (instead of %s%s%s)",
file, line, group, key,
NM_PRINT_FMT_QUOTED (value, "\"", value, "\"", "(null)"),
NM_PRINT_FMT_QUOTED (expected_value, "\"", expected_value, "\"", "(null)"));
}
}
#define assert_config_value(config_data, group, key, expected_value) _assert_config_value (config_data, group, key, expected_value, __FILE__, __LINE__)
/********************************************************************************/
static NMConfig * static NMConfig *
setup_config (GError **error, const char *config_file, const char *config_dir, ...) setup_config (GError **error, const char *config_file, const char *intern_config, const char *const* atomic_section_prefixes, const char *config_dir, const char *system_config_dir, ...)
{ {
va_list ap; va_list ap;
GPtrArray *args; GPtrArray *args;
@ -51,10 +70,18 @@ setup_config (GError **error, const char *config_file, const char *config_dir, .
g_ptr_array_add (args, "test-config"); g_ptr_array_add (args, "test-config");
g_ptr_array_add (args, "--config"); g_ptr_array_add (args, "--config");
g_ptr_array_add (args, (char *)config_file); g_ptr_array_add (args, (char *)config_file);
if (intern_config) {
g_ptr_array_add (args, "--intern-config");
g_ptr_array_add (args, (char *)intern_config);
}
g_ptr_array_add (args, "--config-dir"); g_ptr_array_add (args, "--config-dir");
g_ptr_array_add (args, (char *)config_dir); g_ptr_array_add (args, (char *)config_dir);
if (system_config_dir) {
g_ptr_array_add (args, "--system-config-dir");
g_ptr_array_add (args, (char *) system_config_dir);
}
va_start (ap, config_dir); va_start (ap, system_config_dir);
while ((arg = va_arg (ap, char *))) while ((arg = va_arg (ap, char *)))
g_ptr_array_add (args, arg); g_ptr_array_add (args, arg);
va_end (ap); va_end (ap);
@ -74,7 +101,7 @@ setup_config (GError **error, const char *config_file, const char *config_dir, .
g_ptr_array_free (args, TRUE); g_ptr_array_free (args, TRUE);
config = nm_config_setup (cli, &local_error); config = nm_config_setup (cli, (char **) atomic_section_prefixes, &local_error);
if (error) { if (error) {
g_assert (!config); g_assert (!config);
g_assert (local_error); g_assert (local_error);
@ -97,7 +124,7 @@ test_config_simple (void)
gs_unref_object NMDevice *dev51 = nm_test_device_new ("00:00:00:00:00:51"); gs_unref_object NMDevice *dev51 = nm_test_device_new ("00:00:00:00:00:51");
gs_unref_object NMDevice *dev52 = nm_test_device_new ("00:00:00:00:00:52"); gs_unref_object NMDevice *dev52 = nm_test_device_new ("00:00:00:00:00:52");
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir", NULL); config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, "/no/such/dir", "", NULL);
g_assert_cmpstr (nm_config_data_get_config_main_file (nm_config_get_data_orig (config)), ==, SRCDIR "/NetworkManager.conf"); g_assert_cmpstr (nm_config_data_get_config_main_file (nm_config_get_data_orig (config)), ==, SRCDIR "/NetworkManager.conf");
g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhclient"); g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhclient");
@ -176,7 +203,7 @@ test_config_non_existent (void)
{ {
GError *error = NULL; GError *error = NULL;
setup_config (&error, SRCDIR "/no-such-file", "/no/such/dir", NULL); setup_config (&error, SRCDIR "/no-such-file", "", NULL, "/no/such/dir", "", NULL);
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND); g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND);
g_clear_error (&error); g_clear_error (&error);
} }
@ -186,7 +213,7 @@ test_config_parse_error (void)
{ {
GError *error = NULL; GError *error = NULL;
setup_config (&error, SRCDIR "/bad.conf", "/no/such/dir", NULL); setup_config (&error, SRCDIR "/bad.conf", "", NULL, "/no/such/dir", "", NULL);
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE); g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
g_clear_error (&error); g_clear_error (&error);
} }
@ -197,7 +224,7 @@ test_config_override (void)
NMConfig *config; NMConfig *config;
const char **plugins; const char **plugins;
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir", config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, "/no/such/dir", "",
"--plugins", "alpha,beta,gamma,delta", "--plugins", "alpha,beta,gamma,delta",
"--connectivity-interval", "12", "--connectivity-interval", "12",
NULL); NULL);
@ -235,7 +262,7 @@ test_config_no_auto_default (void)
g_assert_cmpint (nwrote, ==, 18); g_assert_cmpint (nwrote, ==, 18);
close (fd); close (fd);
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir", config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, "/no/such/dir", "",
"--no-auto-default", state_file, "--no-auto-default", state_file,
NULL); NULL);
@ -257,7 +284,7 @@ test_config_no_auto_default (void)
g_object_unref (config); g_object_unref (config);
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir", config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, "/no/such/dir", "",
"--no-auto-default", state_file, "--no-auto-default", state_file,
NULL); NULL);
@ -285,7 +312,7 @@ test_config_confdir (void)
char *value; char *value;
GSList *specs; GSList *specs;
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", SRCDIR "/conf.d", NULL); config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL);
g_assert_cmpstr (nm_config_data_get_config_main_file (nm_config_get_data_orig (config)), ==, SRCDIR "/NetworkManager.conf"); g_assert_cmpstr (nm_config_data_get_config_main_file (nm_config_get_data_orig (config)), ==, SRCDIR "/NetworkManager.conf");
g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhcpcd"); g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhcpcd");
@ -391,11 +418,336 @@ test_config_confdir_parse_error (void)
GError *error = NULL; GError *error = NULL;
/* Using SRCDIR as the conf dir will pick up bad.conf */ /* Using SRCDIR as the conf dir will pick up bad.conf */
setup_config (&error, SRCDIR "/NetworkManager.conf", SRCDIR, NULL); setup_config (&error, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR, "", NULL);
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE); g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
g_clear_error (&error); g_clear_error (&error);
} }
/*****************************************************************************/
typedef void (*TestSetValuesUserSetFcn) (NMConfig *config, gboolean is_user, GKeyFile *keyfile_user, NMConfigChangeFlags *out_expected_changes);
typedef void (*TestSetValuesCheckStateFcn) (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data);
typedef struct {
NMConfigChangeFlags changes;
TestSetValuesCheckStateFcn check_state_fcn;
} TestSetValuesConfigChangedData;
static void
_set_values_config_changed_cb (NMConfig *config,
NMConfigData *config_data,
NMConfigChangeFlags changes,
NMConfigData *old_data,
TestSetValuesConfigChangedData *config_changed_data)
{
g_assert (changes != NM_CONFIG_CHANGE_NONE);
g_assert (config_changed_data);
g_assert (config_changed_data->changes == NM_CONFIG_CHANGE_NONE);
if (changes == NM_CONFIG_CHANGE_SIGHUP)
return;
changes &= ~NM_CONFIG_CHANGE_SIGHUP;
config_changed_data->changes = changes;
if (config_changed_data->check_state_fcn)
config_changed_data->check_state_fcn (config, config_data, TRUE, changes, old_data);
}
static void
_set_values_user (NMConfig *config,
const char *CONFIG_USER,
TestSetValuesUserSetFcn set_fcn,
TestSetValuesCheckStateFcn check_state_fcn)
{
GKeyFile *keyfile_user;
gboolean success;
gs_free_error GError *error = NULL;
TestSetValuesConfigChangedData config_changed_data = {
.changes = NM_CONFIG_CHANGE_NONE,
.check_state_fcn = check_state_fcn,
};
NMConfigChangeFlags expected_changes = NM_CONFIG_CHANGE_NONE;
gs_unref_object NMConfigData *config_data_before = NULL;
keyfile_user = nm_config_create_keyfile ();
success = g_key_file_load_from_file (keyfile_user, CONFIG_USER, G_KEY_FILE_NONE, &error);
nmtst_assert_success (success, error);
if (set_fcn)
set_fcn (config, TRUE, keyfile_user, &expected_changes);
success = g_key_file_save_to_file (keyfile_user, CONFIG_USER, &error);
nmtst_assert_success (success, error);
g_signal_connect (G_OBJECT (config),
NM_CONFIG_SIGNAL_CONFIG_CHANGED,
G_CALLBACK (_set_values_config_changed_cb),
&config_changed_data);
config_data_before = g_object_ref (nm_config_get_data (config));
if (expected_changes != NM_CONFIG_CHANGE_NONE)
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: update *");
else
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: signal SIGHUP (no changes from disk)*");
nm_config_reload (config, SIGHUP);
g_test_assert_expected_messages ();
g_assert (expected_changes == config_changed_data.changes);
if (check_state_fcn)
check_state_fcn (config, nm_config_get_data (config), FALSE, NM_CONFIG_CHANGE_NONE, config_data_before);
g_signal_handlers_disconnect_by_func (config, _set_values_config_changed_cb, &config_changed_data);
g_key_file_unref (keyfile_user);
}
static void
_set_values_intern (NMConfig *config,
TestSetValuesUserSetFcn set_fcn,
TestSetValuesCheckStateFcn check_state_fcn)
{
GKeyFile *keyfile_intern;
TestSetValuesConfigChangedData config_changed_data = {
.changes = NM_CONFIG_CHANGE_NONE,
.check_state_fcn = check_state_fcn,
};
NMConfigChangeFlags expected_changes = NM_CONFIG_CHANGE_NONE;
gs_unref_object NMConfigData *config_data_before = NULL;
config_data_before = g_object_ref (nm_config_get_data (config));
keyfile_intern = nm_config_data_clone_keyfile_intern (config_data_before);
if (set_fcn)
set_fcn (config, FALSE, keyfile_intern, &expected_changes);
g_signal_connect (G_OBJECT (config),
NM_CONFIG_SIGNAL_CONFIG_CHANGED,
G_CALLBACK (_set_values_config_changed_cb),
&config_changed_data);
if (expected_changes != NM_CONFIG_CHANGE_NONE)
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: update *");
nm_config_set_values (config, keyfile_intern, TRUE, FALSE);
g_test_assert_expected_messages ();
g_assert (expected_changes == config_changed_data.changes);
if (check_state_fcn)
check_state_fcn (config, nm_config_get_data (config), FALSE, NM_CONFIG_CHANGE_NONE, config_data_before);
g_signal_handlers_disconnect_by_func (config, _set_values_config_changed_cb, &config_changed_data);
g_key_file_unref (keyfile_intern);
}
static void
_set_values_user_intern_section_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
{
g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1", "key", "this-should-be-ignored");
}
static void
_set_values_user_intern_section_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
{
g_assert (changes == NM_CONFIG_CHANGE_NONE);
g_assert (!nm_config_data_has_group (config_data, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1"));
}
static void
_set_values_user_initial_values_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
{
g_key_file_remove_group (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1", NULL);
g_key_file_set_string (keyfile, "section1", "key1", "value1");
*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER;
}
static void
_set_values_user_initial_values_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
{
if (is_change_event)
g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER));
assert_config_value (config_data, "section1", "key1", "value1");
}
static void
_set_values_intern_internal_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
{
g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1", "key", "internal-section");
*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN;
}
static void
_set_values_intern_internal_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
{
if (is_change_event)
g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN));
assert_config_value (config_data, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1", "key", "internal-section");
}
static void
_set_values_user_atomic_section_1_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
{
g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key1", "user-value1");
g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key2", "user-value2");
g_key_file_set_string (keyfile, "atomic-prefix-1.section-b", "key1", "user-value1");
g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key1", "user-value1");
g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2");
*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER;
}
static void
_set_values_user_atomic_section_1_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
{
if (is_change_event)
g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER));
assert_config_value (config_data, "atomic-prefix-1.section-a", "key1", "user-value1");
assert_config_value (config_data, "atomic-prefix-1.section-a", "key2", "user-value2");
assert_config_value (config_data, "atomic-prefix-1.section-b", "key1", "user-value1");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key1", "user-value1");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2");
}
static void
_set_values_intern_atomic_section_1_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
{
g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key1", "intern-value1");
g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key3", "intern-value3");
g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key1", "intern-value1");
g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN;
}
static void
_set_values_intern_atomic_section_1_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
{
if (is_change_event)
g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN));
assert_config_value (config_data, "atomic-prefix-1.section-a", "key1", "intern-value1");
assert_config_value (config_data, "atomic-prefix-1.section-a", "key2", NULL);
assert_config_value (config_data, "atomic-prefix-1.section-a", "key3", "intern-value3");
assert_config_value (config_data, "atomic-prefix-1.section-b", "key1", "user-value1");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key1", "intern-value1");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
g_assert ( nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-a"));
g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-b"));
g_assert (!nm_config_data_is_intern_atomic_group (config_data, "non-atomic-prefix-1.section-a"));
}
static void
_set_values_user_atomic_section_2_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
{
g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key1", "user-value1-x");
g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key2", "user-value2");
g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key1", "user-value1-x");
g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2-x");
*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER | NM_CONFIG_CHANGE_VALUES_INTERN;
}
static void
_set_values_user_atomic_section_2_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
{
if (is_change_event)
g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER | NM_CONFIG_CHANGE_VALUES_INTERN));
assert_config_value (config_data, "atomic-prefix-1.section-a", "key1", "user-value1-x");
assert_config_value (config_data, "atomic-prefix-1.section-a", "key2", "user-value2");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key1", "user-value1-x");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2-x");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-a"));
g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-b"));
g_assert (!nm_config_data_is_intern_atomic_group (config_data, "non-atomic-prefix-1.section-a"));
}
static void
_set_values_intern_atomic_section_2_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
{
/* let's hide an atomic section and one key. */
g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS, "any-value");
g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", NM_CONFIG_KEYFILE_KEYPREFIX_WAS"nap1-key1", "any-value");
g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"with-whitespace", "key1", " b c\\, d ");
g_key_file_set_value (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"with-whitespace", "key2", " b c\\, d ");
*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN;
}
static void
_set_values_intern_atomic_section_2_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
{
if (is_change_event)
g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN));
g_assert (!nm_config_data_has_group (config_data, "atomic-prefix-1.section-a"));
assert_config_value (config_data, "atomic-prefix-1.section-b", "key1", "user-value1");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key1", NULL);
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2-x");
assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-a"));
g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-b"));
g_assert (!nm_config_data_is_intern_atomic_group (config_data, "non-atomic-prefix-1.section-a"));
assert_config_value (config_data, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"with-whitespace", "key1", " b c\\, d ");
assert_config_value (config_data, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"with-whitespace", "key2", " b c\\, d ");
}
static void
test_config_set_values (void)
{
gs_unref_object NMConfig *config = NULL;
const char *CONFIG_USER = SRCDIR"/test-set-values-user.conf";
const char *CONFIG_INTERN = SRCDIR"/test-set-values-intern.conf";
const char *atomic_section_prefixes[] = {
"atomic-prefix-1.",
"atomic-prefix-2.",
NULL,
};
g_assert (g_file_set_contents (CONFIG_USER, "", 0, NULL));
g_assert (g_file_set_contents (CONFIG_INTERN, "", 0, NULL));
config = setup_config (NULL, CONFIG_USER, CONFIG_INTERN, atomic_section_prefixes, "", "", NULL);
_set_values_user (config, CONFIG_USER,
_set_values_user_intern_section_set,
_set_values_user_intern_section_check);
_set_values_user (config, CONFIG_USER,
_set_values_user_initial_values_set,
_set_values_user_initial_values_check);
_set_values_intern (config,
_set_values_intern_internal_set,
_set_values_intern_internal_check);
_set_values_user (config, CONFIG_USER,
_set_values_user_atomic_section_1_set,
_set_values_user_atomic_section_1_check);
_set_values_intern (config,
_set_values_intern_atomic_section_1_set,
_set_values_intern_atomic_section_1_check);
_set_values_user (config, CONFIG_USER,
_set_values_user_atomic_section_2_set,
_set_values_user_atomic_section_2_check);
_set_values_intern (config,
_set_values_intern_atomic_section_2_set,
_set_values_intern_atomic_section_2_check);
g_assert (remove (CONFIG_USER) == 0);
g_assert (remove (CONFIG_INTERN) == 0);
}
/*****************************************************************************/
NMTST_DEFINE (); NMTST_DEFINE ();
int int
@ -419,6 +771,8 @@ main (int argc, char **argv)
g_test_add_func ("/config/confdir", test_config_confdir); g_test_add_func ("/config/confdir", test_config_confdir);
g_test_add_func ("/config/confdir-parse-error", test_config_confdir_parse_error); g_test_add_func ("/config/confdir-parse-error", test_config_confdir_parse_error);
g_test_add_func ("/config/set-values", test_config_set_values);
/* This one has to come last, because it leaves its values in /* This one has to come last, because it leaves its values in
* nm-config.c's global variables, and there's no way to reset * nm-config.c's global variables, and there's no way to reset
* those to NULL. * those to NULL.