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.

(cherry picked from commit 82cfd5ad47)
This commit is contained in:
Thomas Haller 2014-07-09 18:54:47 +02:00 committed by Lubomir Rintel
parent 3a5fb56b60
commit 63293bba19
3 changed files with 85 additions and 1 deletions

View file

@ -211,7 +211,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

View file

@ -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))
@ -553,6 +562,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);
@ -753,5 +815,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);
}

View file

@ -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