dns/resolved: various fixes

- mode in init_resolv_conf_mode() must be initialized in
  case it is NULL.
- drop the NULL sentinal from resolved_paths and make it
  static.
- resolved_proxy_created() must handle the fact that @self
  might be already destroyed.
- call_done() must not access @self before ensuring that
  the call was not cancelled.
  What's more, send_update() can be called by resolved_proxy_created(),
  thus it must ensure that it has an @update_cancellable. Let
  send_update() create and cancel the @update_cancellable().
  Also, send_update() -- which now manages @update_cancellable
  instead of update() -- must actually cancel the previous
  cancellable, otherwise the callback again might access
  a disposed @self.

Co-authored-by: Beniamino Galvani <bgalvani@redhat.com>
This commit is contained in:
Thomas Haller 2016-09-06 14:35:45 +02:00
parent 040bf6c1e8
commit 7d3bfce1dc
2 changed files with 22 additions and 18 deletions

View file

@ -1592,15 +1592,14 @@ NM_DEFINE_SINGLETON_GETTER (NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGE
static gboolean
_resolvconf_resolved_managed (void)
{
GFile *f;
GFileInfo *info;
gboolean ret = FALSE;
const gchar *resolved_paths[] = {
static const char *const resolved_paths[] = {
"/run/systemd/resolve/resolv.conf",
"/lib/systemd/resolv.conf",
"/usr/lib/systemd/resolv.conf",
NULL
};
GFile *f;
GFileInfo *info;
gboolean ret = FALSE;
f = g_file_new_for_path (_PATH_RESCONF);
info = g_file_query_info (f,
@ -1674,6 +1673,7 @@ again:
priv->plugin = nm_dns_systemd_resolved_new ();
plugin_changed = TRUE;
}
mode = "systemd-resolved";
} else if (nm_streq0 (mode, "dnsmasq")) {
if (force_reload_plugin || !NM_IS_DNS_DNSMASQ (priv->plugin)) {
_clear_plugin (self);

View file

@ -83,7 +83,7 @@ call_done (GObject *source, GAsyncResult *r, gpointer user_data)
{
GVariant *v;
GError *error = NULL;
NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED (user_data);
NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data;
v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), r, &error);
@ -251,9 +251,13 @@ send_updates (NMDnsSystemdResolved *self)
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
GVariant *v;
nm_clear_g_cancellable (&priv->update_cancellable);
if (!priv->resolve)
return;
priv->update_cancellable = g_cancellable_new ();
while ((v = g_queue_pop_head (&priv->dns_updates)) != NULL) {
g_dbus_proxy_call (priv->resolve, "SetLinkDNS", v,
G_DBUS_CALL_FLAGS_NONE,
@ -276,7 +280,6 @@ update (NMDnsPlugin *plugin,
const char *hostname)
{
NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED (plugin);
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
GArray *interfaces = g_array_new (TRUE, TRUE, sizeof (InterfaceConfig));
const NMDnsIPConfigData **c;
int i;
@ -285,9 +288,6 @@ update (NMDnsPlugin *plugin,
add_interface_configuration (self, interfaces, *c);
free_pending_updates (self);
g_clear_object (&priv->update_cancellable);
priv->update_cancellable = g_cancellable_new ();
for (i = 0; i < interfaces->len; i++) {
InterfaceConfig *ic = &g_array_index (interfaces, InterfaceConfig, i);
@ -328,21 +328,25 @@ nm_dns_systemd_resolved_new (void)
static void
resolved_proxy_created (GObject *source, GAsyncResult *r, gpointer user_data)
{
NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED (user_data);
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
GError *error = NULL;
NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data;
NMDnsSystemdResolvedPrivate *priv;
gs_free_error GError *error = NULL;
GDBusProxy *resolve;
resolve = g_dbus_proxy_new_finish (r, &error);
if ( !resolve
&& g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
g_clear_object (&priv->init_cancellable);
priv->resolve = g_dbus_proxy_new_finish (r, &error);
if (priv->resolve == NULL) {
if (!resolve) {
_LOGW ("failed to connect to resolved via DBus: %s", error->message);
g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED);
g_error_free (error);
return;
}
priv->resolve = resolve;
send_updates (self);
}