config: move no-auto-default to NMConfigData

With this change, NMConfig is really immutable and all
modifyable parts migrated to NMConfigData.

Another advantage is that components can now subscribe to
NMConfig changes to pickup changes to no-auto-default.
This commit is contained in:
Thomas Haller
2015-01-07 17:09:52 +01:00
parent 49b3f5b8d9
commit 13c7f6a56d
7 changed files with 143 additions and 51 deletions

View File

@@ -1463,7 +1463,7 @@ new_default_connection (NMDevice *self)
const char *hw_address;
char *defname, *uuid;
if (!nm_config_get_ethernet_can_auto_default (nm_config_get (), self))
if (nm_config_get_no_auto_default_for_device (nm_config_get (), self))
return NULL;
hw_address = nm_device_get_hw_address (self);

View File

@@ -37,6 +37,11 @@ typedef struct {
char *response;
guint interval;
} connectivity;
struct {
char **arr;
GSList *specs;
} no_auto_default;
} NMConfigDataPrivate;
@@ -48,6 +53,7 @@ enum {
PROP_CONNECTIVITY_URI,
PROP_CONNECTIVITY_INTERVAL,
PROP_CONNECTIVITY_RESPONSE,
PROP_NO_AUTO_DEFAULT,
LAST_PROP
};
@@ -106,6 +112,21 @@ nm_config_data_get_connectivity_response (const NMConfigData *self)
return NM_CONFIG_DATA_GET_PRIVATE (self)->connectivity.response;
}
const char *const*
nm_config_data_get_no_auto_default (const NMConfigData *self)
{
g_return_val_if_fail (self, FALSE);
return (const char *const*) NM_CONFIG_DATA_GET_PRIVATE (self)->no_auto_default.arr;
}
const GSList *
nm_config_data_get_no_auto_default_list (const NMConfigData *self)
{
g_return_val_if_fail (self, NULL);
return NM_CONFIG_DATA_GET_PRIVATE (self)->no_auto_default.specs;
}
/************************************************************************/
@@ -141,6 +162,7 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data)
{
GHashTable *changes;
NMConfigDataPrivate *priv_old, *priv_new;
GSList *spec_old, *spec_new;
g_return_val_if_fail (NM_IS_CONFIG_DATA (old_data), NULL);
g_return_val_if_fail (NM_IS_CONFIG_DATA (new_data), NULL);
@@ -163,6 +185,15 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data)
|| g_strcmp0 (nm_config_data_get_connectivity_response (old_data), nm_config_data_get_connectivity_response (new_data)))
g_hash_table_insert (changes, NM_CONFIG_CHANGES_CONNECTIVITY, NULL);
spec_old = priv_old->no_auto_default.specs;
spec_new = priv_new->no_auto_default.specs;
while (spec_old && spec_new && strcmp (spec_old->data, spec_new->data) == 0) {
spec_old = spec_old->next;
spec_new = spec_new->next;
}
if (spec_old || spec_new)
g_hash_table_insert (changes, NM_CONFIG_CHANGES_NO_AUTO_DEFAULT, NULL);
if (!g_hash_table_size (changes)) {
g_hash_table_destroy (changes);
return NULL;
@@ -187,6 +218,9 @@ get_property (GObject *object,
case PROP_CONFIG_DESCRIPTION:
g_value_set_string (value, nm_config_data_get_config_description (self));
break;
case PROP_NO_AUTO_DEFAULT:
g_value_take_boxed (value, g_strdupv ((char **) nm_config_data_get_no_auto_default (self)));
break;
case PROP_CONNECTIVITY_URI:
g_value_set_string (value, nm_config_data_get_connectivity_uri (self));
break;
@@ -210,6 +244,7 @@ set_property (GObject *object,
{
NMConfigData *self = NM_CONFIG_DATA (object);
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (self);
guint i;
/* This type is immutable. All properties are construct only. */
switch (prop_id) {
@@ -224,6 +259,14 @@ set_property (GObject *object,
if (!priv->keyfile)
priv->keyfile = nm_config_create_keyfile ();
break;
case PROP_NO_AUTO_DEFAULT:
priv->no_auto_default.arr = g_strdupv (g_value_get_boxed (value));
if (!priv->no_auto_default.arr)
priv->no_auto_default.arr = g_new0 (char *, 1);
for (i = 0; priv->no_auto_default.arr[i]; i++)
priv->no_auto_default.specs = g_slist_prepend (priv->no_auto_default.specs, priv->no_auto_default.arr[i]);
priv->no_auto_default.specs = g_slist_reverse (priv->no_auto_default.specs);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -246,6 +289,9 @@ finalize (GObject *gobject)
g_free (priv->connectivity.uri);
g_free (priv->connectivity.response);
g_slist_free (priv->no_auto_default.specs);
g_strfreev (priv->no_auto_default.arr);
G_OBJECT_CLASS (nm_config_data_parent_class)->finalize (gobject);
}
@@ -273,12 +319,28 @@ constructed (GObject *object)
NMConfigData *
nm_config_data_new (const char *config_main_file,
const char *config_description,
const char *const*no_auto_default,
GKeyFile *keyfile)
{
return g_object_new (NM_TYPE_CONFIG_DATA,
NM_CONFIG_DATA_CONFIG_MAIN_FILE, config_main_file,
NM_CONFIG_DATA_CONFIG_DESCRIPTION, config_description,
NM_CONFIG_DATA_KEYFILE, keyfile,
NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default,
NULL);
}
NMConfigData *
nm_config_data_new_update_no_auto_default (const NMConfigData *base,
const char *const*no_auto_default)
{
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, priv->keyfile, /* the keyfile is unchanged. It's safe to share it. */
NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default,
NULL);
}
@@ -340,5 +402,13 @@ nm_config_data_class_init (NMConfigDataClass *config_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_NO_AUTO_DEFAULT,
g_param_spec_boxed (NM_CONFIG_DATA_NO_AUTO_DEFAULT, "", "",
G_TYPE_STRV,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

View File

@@ -42,6 +42,7 @@ G_BEGIN_DECLS
#define NM_CONFIG_DATA_CONNECTIVITY_URI "connectivity-uri"
#define NM_CONFIG_DATA_CONNECTIVITY_INTERVAL "connectivity-interval"
#define NM_CONFIG_DATA_CONNECTIVITY_RESPONSE "connectivity-response"
#define NM_CONFIG_DATA_NO_AUTO_DEFAULT "no-auto-default"
struct _NMConfigData {
GObject parent;
@@ -55,7 +56,9 @@ GType nm_config_data_get_type (void);
NMConfigData *nm_config_data_new (const char *config_main_file,
const char *config_description,
const char *const*no_auto_default,
GKeyFile *keyfile);
NMConfigData *nm_config_data_new_update_no_auto_default (const NMConfigData *base, const char *const*no_auto_default);
GHashTable *nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data);
@@ -68,6 +71,9 @@ const char *nm_config_data_get_connectivity_uri (const NMConfigData *config_data
const guint nm_config_data_get_connectivity_interval (const NMConfigData *config_data);
const char *nm_config_data_get_connectivity_response (const NMConfigData *config_data);
const char *const*nm_config_data_get_no_auto_default (const NMConfigData *config_data);
const GSList * nm_config_data_get_no_auto_default_list (const NMConfigData *config_data);
G_END_DECLS
#endif /* NM_CONFIG_DATA_H */

View File

@@ -73,13 +73,9 @@ typedef struct {
char *debug;
char **no_auto_default_orig;
char **ignore_carrier;
gboolean configure_and_quit;
/* MUTABLE properties: */
char **no_auto_default; /* mutable via merge_no_auto_default_state() */
} NMConfigPrivate;
enum {
@@ -102,6 +98,10 @@ G_DEFINE_TYPE (NMConfig, nm_config, G_TYPE_OBJECT)
/************************************************************************/
static void _set_config_data (NMConfig *self, NMConfigData *new_data);
/************************************************************************/
static gboolean
_get_bool_value (GKeyFile *keyfile,
const char *section,
@@ -288,32 +288,31 @@ no_auto_default_merge_from_file (const char *no_auto_default_file, const char *c
}
gboolean
nm_config_get_ethernet_can_auto_default (NMConfig *config, NMDevice *device)
nm_config_get_no_auto_default_for_device (NMConfig *self, NMDevice *device)
{
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
GSList *specs = NULL;
int i;
gboolean match;
NMConfigData *config_data;
for (i = 0; priv->no_auto_default[i]; i++)
specs = g_slist_prepend (specs, priv->no_auto_default[i]);
g_return_val_if_fail (NM_IS_CONFIG (self), FALSE);
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
match = nm_device_spec_match_list (device, specs);
g_slist_free (specs);
return !match;
config_data = NM_CONFIG_GET_PRIVATE (self)->config_data;
return nm_device_spec_match_list (device, nm_config_data_get_no_auto_default_list (config_data));
}
void
nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device)
nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device)
{
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self);
char *current;
GString *updated;
GError *error = NULL;
char **no_auto_default;
NMConfigData *new_data = NULL;
if (!nm_config_get_ethernet_can_auto_default (config, device))
g_return_if_fail (NM_IS_CONFIG (self));
g_return_if_fail (NM_IS_DEVICE (device));
if (nm_config_get_no_auto_default_for_device (self, device))
return;
updated = g_string_new (NULL);
@@ -335,9 +334,11 @@ nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device)
g_string_free (updated, TRUE);
no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, (const char *const *) priv->no_auto_default);
g_strfreev (priv->no_auto_default);
priv->no_auto_default = no_auto_default;
no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, nm_config_data_get_no_auto_default (priv->config_data));
new_data = nm_config_data_new_update_no_auto_default (priv->config_data, (const char *const*) no_auto_default);
g_strfreev (no_auto_default);
_set_config_data (self, new_data);
}
/************************************************************************/
@@ -679,9 +680,7 @@ nm_config_reload (NMConfig *self)
{
NMConfigPrivate *priv;
GError *error = NULL;
GHashTable *changes;
GKeyFile *keyfile;
NMConfigData *old_data;
NMConfigData *new_data = NULL;
char *config_main_file = NULL;
char *config_description = NULL;
@@ -690,7 +689,6 @@ nm_config_reload (NMConfig *self)
priv = NM_CONFIG_GET_PRIVATE (self);
/* pass on the original command line options. This means, that
* options specified at command line cannot ever be reloaded from
* file. That seems desirable.
@@ -705,12 +703,21 @@ nm_config_reload (NMConfig *self)
g_clear_error (&error);
return;
}
new_data = nm_config_data_new (config_main_file, config_description, keyfile);
new_data = nm_config_data_new (config_main_file, config_description, nm_config_data_get_no_auto_default (priv->config_data), keyfile);
g_free (config_main_file);
g_free (config_description);
g_key_file_unref (keyfile);
old_data = priv->config_data;
_set_config_data (self, new_data);
}
static void
_set_config_data (NMConfig *self, NMConfigData *new_data)
{
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self);
NMConfigData *old_data = priv->config_data;
GHashTable *changes;
changes = nm_config_data_diff (old_data, new_data);
if (!changes) {
@@ -769,6 +776,8 @@ nm_config_new (const NMConfigCmdLineOptions *cli, GError **error)
GKeyFile *keyfile;
char *config_main_file = NULL;
char *config_description = NULL;
char **no_auto_default;
char **no_auto_default_orig;
self = NM_CONFIG (g_object_new (NM_TYPE_CONFIG,
NM_CONFIG_CMD_LINE_OPTIONS, cli,
@@ -796,7 +805,6 @@ nm_config_new (const NMConfigCmdLineOptions *cli, GError **error)
priv->no_auto_default_file = g_strdup (priv->cli.no_auto_default_file);
else
priv->no_auto_default_file = g_strdup (NM_NO_AUTO_DEFAULT_STATE_FILE);
priv->no_auto_default_orig = g_key_file_get_string_list (keyfile, "main", "no-auto-default", NULL, NULL);
priv->plugins = g_key_file_get_string_list (keyfile, "main", "plugins", NULL, NULL);
if (!priv->plugins)
@@ -818,13 +826,18 @@ nm_config_new (const NMConfigCmdLineOptions *cli, GError **error)
priv->configure_and_quit = _get_bool_value (keyfile, "main", "configure-and-quit", FALSE);
priv->config_data_orig = nm_config_data_new (config_main_file, config_description, keyfile);
no_auto_default_orig = g_key_file_get_string_list (keyfile, "main", "no-auto-default", NULL, NULL);
no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, (const char *const *) no_auto_default_orig);
priv->config_data_orig = nm_config_data_new (config_main_file, config_description, (const char *const*) no_auto_default, keyfile);
g_strfreev (no_auto_default);
g_strfreev (no_auto_default_orig);
/* Initialize mutable members. */
priv->config_data = g_object_ref (priv->config_data_orig);
priv->no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, (const char *const *) priv->no_auto_default_orig);
g_free (config_main_file);
g_free (config_description);
@@ -853,8 +866,6 @@ finalize (GObject *gobject)
g_free (priv->log_level);
g_free (priv->log_domains);
g_free (priv->debug);
g_strfreev (priv->no_auto_default_orig);
g_strfreev (priv->no_auto_default);
g_strfreev (priv->ignore_carrier);
_nm_config_cmd_line_options_clear (&priv->cli);

View File

@@ -46,6 +46,7 @@ G_BEGIN_DECLS
#define NM_CONFIG_CHANGES_CONFIG_FILES "config-files"
#define NM_CONFIG_CHANGES_VALUES "values"
#define NM_CONFIG_CHANGES_CONNECTIVITY "connectivity"
#define NM_CONFIG_CHANGES_NO_AUTO_DEFAULT "no-auto-default"
typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions;
@@ -76,9 +77,6 @@ const char *nm_config_get_log_domains (NMConfig *config);
const char *nm_config_get_debug (NMConfig *config);
gboolean nm_config_get_configure_and_quit (NMConfig *config);
gboolean nm_config_get_ethernet_can_auto_default (NMConfig *config, NMDevice *device);
void nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device);
gboolean nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device);
/* for main.c only */
@@ -87,6 +85,9 @@ void nm_config_cmd_line_options_free (NMConfigCmdLineOptions
void nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli,
GOptionContext *opt_ctx);
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);
NMConfig *nm_config_new (const NMConfigCmdLineOptions *cli, GError **error);
NMConfig *nm_config_setup (const NMConfigCmdLineOptions *cli, GError **error);
void nm_config_reload (NMConfig *config);

View File

@@ -1669,7 +1669,7 @@ default_wired_clear_tag (NMSettings *self,
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_updated_by_user_cb), self);
if (add_to_no_auto_default)
nm_config_set_ethernet_no_auto_default (NM_SETTINGS_GET_PRIVATE (self)->config, device);
nm_config_set_no_auto_default_for_device (NM_SETTINGS_GET_PRIVATE (self)->config, device);
}
void

View File

@@ -27,6 +27,9 @@
#include <nm-config.h>
#include "nm-test-device.h"
#include "nm-fake-platform.h"
#include "nm-logging.h"
#include "nm-test-utils.h"
static NMConfig *
setup_config (GError **error, const char *config_file, const char *config_dir, ...)
@@ -194,13 +197,16 @@ test_config_no_auto_default (void)
dev3 = nm_test_device_new ("33:33:33:33:33:33");
dev4 = nm_test_device_new ("44:44:44:44:44:44");
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev1));
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2));
g_assert (nm_config_get_ethernet_can_auto_default (config, dev3));
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4));
g_assert (nm_config_get_no_auto_default_for_device (config, dev1));
g_assert (nm_config_get_no_auto_default_for_device (config, dev2));
g_assert (!nm_config_get_no_auto_default_for_device (config, dev3));
g_assert (nm_config_get_no_auto_default_for_device (config, dev4));
nm_config_set_ethernet_no_auto_default (config, dev3);
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3));
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: update * (no-auto-default)*");
nm_config_set_no_auto_default_for_device (config, dev3);
g_test_assert_expected_messages ();
g_assert (nm_config_get_no_auto_default_for_device (config, dev3));
g_object_unref (config);
@@ -208,10 +214,10 @@ test_config_no_auto_default (void)
"--no-auto-default", state_file,
NULL);
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev1));
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2));
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3));
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4));
g_assert (nm_config_get_no_auto_default_for_device (config, dev1));
g_assert (nm_config_get_no_auto_default_for_device (config, dev2));
g_assert (nm_config_get_no_auto_default_for_device (config, dev3));
g_assert (nm_config_get_no_auto_default_for_device (config, dev4));
g_object_unref (config);
@@ -280,14 +286,12 @@ test_config_confdir_parse_error (void)
g_clear_error (&error);
}
NMTST_DEFINE ();
int
main (int argc, char **argv)
{
#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
#endif
g_test_init (&argc, &argv, NULL);
nmtst_init_assert_logging (&argc, &argv);
nm_fake_platform_setup ();