summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2017-07-03 09:14:50 +0200
committerLubomir Rintel <lkundrak@v3.sk>2017-07-12 08:53:19 +0200
commitffe52feea851d047dbff66b8096672ae4f1ac268 (patch)
tree1e95f00a486d0894f1da99dbcae724847e8bc81d
parenta40c3d696671b8700d4f87db186a6da3b74e75cd (diff)
downloadNetworkManager-ffe52feea851d047dbff66b8096672ae4f1ac268.tar.gz
dns: replace the FAILED and CHILD_QUIT signals with a STATE property
When we'll supporting multiple DNS plugins, we'll need to know whether a particular plugin is in a workable state instead of just reacting to state change events.
-rw-r--r--src/dns/nm-dns-dnsmasq.c6
-rw-r--r--src/dns/nm-dns-manager.c50
-rw-r--r--src/dns/nm-dns-plugin.c106
-rw-r--r--src/dns/nm-dns-plugin.h12
-rw-r--r--src/dns/nm-dns-systemd-resolved.c3
-rw-r--r--src/dns/nm-dns-unbound.c11
6 files changed, 127 insertions, 61 deletions
diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c
index df3ca11120..91a42a6e61 100644
--- a/src/dns/nm-dns-dnsmasq.c
+++ b/src/dns/nm-dns-dnsmasq.c
@@ -430,8 +430,10 @@ name_owner_changed (GObject *object,
} else {
_LOGI ("dnsmasq disappeared");
priv->running = FALSE;
- g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED);
}
+
+ nm_dns_plugin_set_state (NM_DNS_PLUGIN (self),
+ priv->running ? NM_DNS_PLUGIN_STATE_RUNNING : NM_DNS_PLUGIN_STATE_FAILED);
}
static void
@@ -452,7 +454,7 @@ dnsmasq_proxy_cb (GObject *source, GAsyncResult *res, gpointer user_data)
if (!proxy) {
_LOGW ("failed to connect to dnsmasq via DBus: %s", error->message);
- g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED);
+ nm_dns_plugin_set_state (NM_DNS_PLUGIN (self), NM_DNS_PLUGIN_STATE_FAILED);
return;
}
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c
index f5776d13a7..e048f9bc78 100644
--- a/src/dns/nm-dns-manager.c
+++ b/src/dns/nm-dns-manager.c
@@ -147,6 +147,8 @@ G_DEFINE_TYPE (NMDnsManager, nm_dns_manager, NM_TYPE_EXPORTED_OBJECT)
#define NM_DNS_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDnsManager, NM_IS_DNS_MANAGER)
+static void plugin_state_changed (NMDnsPlugin *plugin, GParamSpec *pspec, gpointer user_data);
+
static gboolean
domain_is_valid (const gchar *domain)
{
@@ -1132,6 +1134,7 @@ update_dns (NMDnsManager *self,
caching = TRUE;
_LOGD ("update-dns: updating plugin %s", plugin_name);
+ g_signal_handlers_block_by_func (plugin, plugin_state_changed, self);
if (!nm_dns_plugin_update (plugin,
priv->configs,
global_config,
@@ -1143,6 +1146,7 @@ update_dns (NMDnsManager *self,
*/
caching = FALSE;
}
+ g_signal_handlers_unblock_by_func (plugin, plugin_state_changed, self);
skip:
;
@@ -1204,28 +1208,29 @@ update_dns (NMDnsManager *self,
}
static void
-plugin_failed (NMDnsPlugin *plugin, gpointer user_data)
-{
- NMDnsManager *self = NM_DNS_MANAGER (user_data);
- GError *error = NULL;
-
- /* Disable caching until the next DNS update */
- if (!update_dns (self, TRUE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
- }
-}
-
-static void
-plugin_child_quit (NMDnsPlugin *plugin, gpointer user_data)
+plugin_state_changed (NMDnsPlugin *plugin, GParamSpec *pspec, gpointer user_data)
{
NMDnsManager *self = NM_DNS_MANAGER (user_data);
GError *error = NULL;
+ const char *plugin_name = nm_dns_plugin_get_name (plugin);
- /* Let the plugin try to spawn the child again */
- if (!update_dns (self, FALSE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
+ switch (nm_dns_plugin_get_state (plugin)) {
+ case NM_DNS_PLUGIN_STATE_STOPPED:
+ _LOGI ("dns: plugin %s stopped, restarting it", plugin_name);
+ if (!update_dns (self, FALSE, &error)) {
+ _LOGW ("could not commit DNS changes: %s", error->message);
+ g_clear_error (&error);
+ }
+ break;
+ case NM_DNS_PLUGIN_STATE_FAILED:
+ _LOGW ("dns: plugin %s failed", plugin_name);
+ if (!update_dns (self, TRUE, &error)) {
+ _LOGW ("could not commit DNS changes: %s", error->message);
+ g_clear_error (&error);
+ }
+ break;
+ default:
+ return;
}
}
@@ -1524,8 +1529,7 @@ _clear_plugin (NMDnsManager *self)
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
if (priv->plugin) {
- g_signal_handlers_disconnect_by_func (priv->plugin, plugin_failed, self);
- g_signal_handlers_disconnect_by_func (priv->plugin, plugin_child_quit, self);
+ g_signal_handlers_disconnect_by_func (priv->plugin, plugin_state_changed, self);
nm_dns_plugin_stop (priv->plugin);
g_clear_object (&priv->plugin);
return TRUE;
@@ -1725,10 +1729,8 @@ again:
plugin_changed = TRUE;
}
- if (plugin_changed && priv->plugin) {
- g_signal_connect (priv->plugin, NM_DNS_PLUGIN_FAILED, G_CALLBACK (plugin_failed), self);
- g_signal_connect (priv->plugin, NM_DNS_PLUGIN_CHILD_QUIT, G_CALLBACK (plugin_child_quit), self);
- }
+ if (plugin_changed && priv->plugin)
+ g_signal_connect (priv->plugin, "notify::" NM_DNS_PLUGIN_STATE, G_CALLBACK (plugin_state_changed), self);
g_object_freeze_notify (G_OBJECT (self));
diff --git a/src/dns/nm-dns-plugin.c b/src/dns/nm-dns-plugin.c
index 6d65913d51..a998da5807 100644
--- a/src/dns/nm-dns-plugin.c
+++ b/src/dns/nm-dns-plugin.c
@@ -36,19 +36,16 @@
#define PLUGIN_RATELIMIT_BURST 5
#define PLUGIN_RATELIMIT_DELAY 300
-enum {
- FAILED,
- CHILD_QUIT,
- LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
+NM_GOBJECT_PROPERTIES_DEFINE (NMDnsPlugin,
+ PROP_STATE,
+);
typedef struct _NMDnsPluginPrivate {
GPid pid;
guint watch_id;
char *progname;
char *pidfile;
+ NMDnsPluginState state;
struct {
guint64 ts;
@@ -173,7 +170,7 @@ emit_ratelimited_child_quit (gpointer user_data)
{
NMDnsPlugin *self = NM_DNS_PLUGIN (user_data);
- g_signal_emit (self, signals[CHILD_QUIT], 0);
+ nm_dns_plugin_set_state (self, NM_DNS_PLUGIN_STATE_STOPPED);
return G_SOURCE_REMOVE;
}
@@ -213,9 +210,9 @@ watch_cb (GPid pid, gint status, gpointer user_data)
}
if (failed)
- g_signal_emit (self, signals[FAILED], 0);
+ nm_dns_plugin_set_state (self, NM_DNS_PLUGIN_STATE_FAILED);
else
- g_signal_emit (self, signals[CHILD_QUIT], 0);
+ nm_dns_plugin_set_state (self, NM_DNS_PLUGIN_STATE_STOPPED);
}
/*****************************************************************************/
@@ -307,6 +304,64 @@ nm_dns_plugin_stop (NMDnsPlugin *self)
/*****************************************************************************/
+NMDnsPluginState
+nm_dns_plugin_get_state (NMDnsPlugin *self)
+{
+ NMDnsPluginPrivate *priv = NM_DNS_PLUGIN_GET_PRIVATE (self);
+
+ return priv->state;
+}
+
+void
+nm_dns_plugin_set_state (NMDnsPlugin *self, NMDnsPluginState state)
+{
+ NMDnsPluginPrivate *priv = NM_DNS_PLUGIN_GET_PRIVATE (self);
+
+ if (priv->state == state)
+ return;
+
+ priv->state = state;
+ _notify (self, PROP_STATE);
+}
+
+/*****************************************************************************/
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMDnsPlugin *self = NM_DNS_PLUGIN (object);
+ NMDnsPluginPrivate *priv = NM_DNS_PLUGIN_GET_PRIVATE (self);
+
+ switch (prop_id) {
+ case PROP_STATE:
+ g_value_set_uint (value, priv->state);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMDnsPlugin *self = NM_DNS_PLUGIN (object);
+ NMDnsPluginPrivate *priv = NM_DNS_PLUGIN_GET_PRIVATE (self);
+
+ switch (prop_id) {
+ case PROP_STATE:
+ priv->state = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/*****************************************************************************/
+
static void
nm_dns_plugin_init (NMDnsPlugin *self)
{
@@ -330,26 +385,17 @@ nm_dns_plugin_class_init (NMDnsPluginClass *plugin_class)
g_type_class_add_private (plugin_class, sizeof (NMDnsPluginPrivate));
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
object_class->dispose = dispose;
- /* Emitted by the plugin and consumed by NMDnsManager when
- * some error happens with the nameserver subprocess. Causes NM to fall
- * back to writing out a non-local-caching resolv.conf until the next
- * DNS update.
- */
- signals[FAILED] =
- g_signal_new (NM_DNS_PLUGIN_FAILED,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[CHILD_QUIT] =
- g_signal_new (NM_DNS_PLUGIN_CHILD_QUIT,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ obj_properties[PROP_STATE] =
+ g_param_spec_uint (NM_DNS_PLUGIN_STATE, "", "",
+ NM_DNS_PLUGIN_STATE_STOPPED,
+ NM_DNS_PLUGIN_STATE_FAILED,
+ NM_DNS_PLUGIN_STATE_STOPPED,
+ G_PARAM_READABLE
+ | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
}
diff --git a/src/dns/nm-dns-plugin.h b/src/dns/nm-dns-plugin.h
index c37c657e01..e4a6cd40fa 100644
--- a/src/dns/nm-dns-plugin.h
+++ b/src/dns/nm-dns-plugin.h
@@ -29,8 +29,7 @@
#define NM_IS_DNS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DNS_PLUGIN))
#define NM_DNS_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DNS_PLUGIN, NMDnsPluginClass))
-#define NM_DNS_PLUGIN_FAILED "failed"
-#define NM_DNS_PLUGIN_CHILD_QUIT "child-quit"
+#define NM_DNS_PLUGIN_STATE "state"
struct _NMDnsPluginPrivate;
@@ -64,10 +63,19 @@ typedef struct {
gboolean (*child_quit) (NMDnsPlugin *self, gint status);
} NMDnsPluginClass;
+typedef enum {
+ NM_DNS_PLUGIN_STATE_STOPPED,
+ NM_DNS_PLUGIN_STATE_RUNNING,
+ NM_DNS_PLUGIN_STATE_FAILED,
+} NMDnsPluginState;
+
GType nm_dns_plugin_get_type (void);
const char *nm_dns_plugin_get_name (NMDnsPlugin *self);
+NMDnsPluginState nm_dns_plugin_get_state (NMDnsPlugin *self);
+void nm_dns_plugin_set_state (NMDnsPlugin *self, NMDnsPluginState state);
+
gboolean nm_dns_plugin_update (NMDnsPlugin *self,
const GPtrArray *configs,
const NMGlobalDnsConfig *global_config,
diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c
index d090de3f80..a48f78d259 100644
--- a/src/dns/nm-dns-systemd-resolved.c
+++ b/src/dns/nm-dns-systemd-resolved.c
@@ -353,10 +353,11 @@ resolved_proxy_created (GObject *source, GAsyncResult *r, gpointer user_data)
g_clear_object (&priv->init_cancellable);
if (!resolve) {
_LOGW ("failed to connect to resolved via DBus: %s", error->message);
- g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED);
+ nm_dns_plugin_set_state (NM_DNS_PLUGIN (self), NM_DNS_PLUGIN_STATE_FAILED);
return;
}
+ nm_dns_plugin_set_state (NM_DNS_PLUGIN (self), NM_DNS_PLUGIN_STATE_RUNNING);
priv->resolve = resolve;
send_updates (self);
}
diff --git a/src/dns/nm-dns-unbound.c b/src/dns/nm-dns-unbound.c
index 0d2dc0adb2..e86e51e08a 100644
--- a/src/dns/nm-dns-unbound.c
+++ b/src/dns/nm-dns-unbound.c
@@ -45,6 +45,7 @@ update (NMDnsPlugin *plugin,
{
char *argv[] = { DNSSEC_TRIGGER_SCRIPT, "--async", "--update", NULL };
int status;
+ gboolean success;
/* TODO: We currently call a script installed with the dnssec-trigger
* package that queries all information itself. Later, the dependency
@@ -56,8 +57,14 @@ update (NMDnsPlugin *plugin,
* may be eventually merged into NetworkManager.
*/
if (!g_spawn_sync ("/", argv, NULL, 0, NULL, NULL, NULL, NULL, &status, NULL))
- return FALSE;
- return (status == 0);
+ success = FALSE;
+ else
+ success = (status == 0);
+
+ nm_dns_plugin_set_state (plugin,
+ success ? NM_DNS_PLUGIN_STATE_RUNNING : NM_DNS_PLUGIN_STATE_FAILED);
+
+ return success;
}
static const char *