summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-07-09 18:54:47 +0200
committerThomas Haller <thaller@redhat.com>2015-02-03 13:01:53 +0100
commit82cfd5ad47b43de640dfa2dd60c4b84f0857e6a5 (patch)
tree9404d175ca3d731a6f700373eb158a9ec3ede586
parentd62022e28a508070e3d5ef089ab4e17dd45d3b23 (diff)
downloadNetworkManager-82cfd5ad47b43de640dfa2dd60c4b84f0857e6a5.tar.gz
config: add support for reloading of configuration
No actual reloading is yet implemented. Later we will decide on specific configuration parameters where we support reloading. They must be then implemented one-by-one. Some configuration parameters can be set via command line. If a parameter is set from command line, the original value from command line will still be preserved after reloading.
-rw-r--r--src/main.c9
-rw-r--r--src/nm-config.c70
-rw-r--r--src/nm-config.h7
3 files changed, 85 insertions, 1 deletions
diff --git a/src/main.c b/src/main.c
index 89cfeb1cda..d60c67e38b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -178,7 +178,14 @@ _init_nm_debug (const char *debug)
void
nm_main_config_reload ()
{
- nm_log_info (LOGD_CORE, "reloading configuration not supported.");
+ nm_log_info (LOGD_CORE, "reload configuration...");
+ /* The signal handler thread is only installed after
+ * creating NMConfig instance, and on shut down we
+ * no longer run the mainloop (to reach this point).
+ *
+ * Hence, a NMConfig singleton instance must always be
+ * available. */
+ nm_config_reload (nm_config_get ());
}
static void
diff --git a/src/nm-config.c b/src/nm-config.c
index 742a72e38c..4362ea3cdf 100644
--- a/src/nm-config.c
+++ b/src/nm-config.c
@@ -29,6 +29,7 @@
#include "nm-utils.h"
#include "nm-glib-compat.h"
#include "nm-device.h"
+#include "NetworkManagerUtils.h"
#include <gio/gio.h>
#include <glib/gi18n.h>
@@ -81,6 +82,14 @@ typedef struct {
gboolean configure_and_quit;
} NMConfigPrivate;
+enum {
+ SIGNAL_CONFIG_CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
G_DEFINE_TYPE (NMConfig, nm_config, G_TYPE_OBJECT)
#define NM_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CONFIG, NMConfigPrivate))
@@ -551,6 +560,59 @@ find_base_config (NMConfig *config, GError **error)
/************************************************************************/
+void
+nm_config_reload (NMConfig *self)
+{
+ NMConfigPrivate *priv;
+ NMConfig *new;
+ GError *error = NULL;
+ GHashTable *changes;
+ NMConfigData *old_data;
+ NMConfigData *new_data = NULL;
+
+ g_return_if_fail (NM_IS_CONFIG (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.
+ */
+ new = nm_config_new (&priv->cli, &error);
+
+ if (!new) {
+ nm_log_err (LOGD_CORE, "Failed to reload the configuration: %s", error->message);
+ g_clear_error (&error);
+ return;
+ }
+
+ old_data = priv->config_data;
+ new_data = nm_config_get_data (new);
+
+ changes = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* reloading configuration means we have to carefully check every single option
+ * that we want to support and take specific actions. */
+
+ /* FIXME: no actual reloading implemented yet */
+
+ if (g_hash_table_size (changes))
+ new_data = g_object_ref (new_data);
+ else
+ new_data = NULL;
+
+ g_object_unref (new);
+
+ if (new_data) {
+ old_data = priv->config_data;
+ priv->config_data = new_data;
+ g_signal_emit (self, signals[SIGNAL_CONFIG_CHANGED], 0, new_data, changes, old_data);
+ g_object_unref (old_data);
+ }
+
+ g_hash_table_destroy (changes);
+}
+
NM_DEFINE_SINGLETON_DESTRUCTOR (NMConfig);
NM_DEFINE_SINGLETON_WEAK_REF (NMConfig);
@@ -751,5 +813,13 @@ nm_config_class_init (NMConfigClass *config_class)
g_type_class_add_private (config_class, sizeof (NMConfigPrivate));
object_class->finalize = finalize;
+
+ signals[SIGNAL_CONFIG_CHANGED] =
+ g_signal_new (NM_CONFIG_SIGNAL_CONFIG_CHANGED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMConfigClass, config_changed),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 3, NM_TYPE_CONFIG_DATA, G_TYPE_HASH_TABLE, NM_TYPE_CONFIG_DATA);
}
diff --git a/src/nm-config.h b/src/nm-config.h
index 3b0ee6cfae..68f1a4ed30 100644
--- a/src/nm-config.h
+++ b/src/nm-config.h
@@ -37,6 +37,9 @@ G_BEGIN_DECLS
#define NM_IS_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CONFIG))
#define NM_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONFIG, NMConfigClass))
+/* Signals */
+#define NM_CONFIG_SIGNAL_CONFIG_CHANGED "config-changed"
+
typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions;
struct _NMConfig {
@@ -45,6 +48,9 @@ struct _NMConfig {
typedef struct {
GObjectClass parent;
+
+ /* Signals */
+ void (*config_changed) (NMConfig *config, GHashTable *changes, NMConfigData *old_data);
} NMConfigClass;
GType nm_config_get_type (void);
@@ -80,6 +86,7 @@ void nm_config_cmd_line_options_add_to_entries (NMConfigCmdLi
NMConfig *nm_config_new (const NMConfigCmdLineOptions *cli, GError **error);
NMConfig *nm_config_setup (const NMConfigCmdLineOptions *cli, GError **error);
+void nm_config_reload (NMConfig *config);
G_END_DECLS