diff --git a/0001-GDBusProxy-Call-into-well-known-name-if-no-name-owne.patch b/0001-GDBusProxy-Call-into-well-known-name-if-no-name-owne.patch new file mode 100644 index 0000000..9f90160 --- /dev/null +++ b/0001-GDBusProxy-Call-into-well-known-name-if-no-name-owne.patch @@ -0,0 +1,225 @@ +From 5bb94348f4760352f6ae974002db48cb130343a4 Mon Sep 17 00:00:00 2001 +From: David Zeuthen +Date: Wed, 18 Aug 2010 11:35:25 -0400 +Subject: [PATCH 1/4] GDBusProxy: Call into well-known name if no name owner currently exists + +This is really what (API) users expect from GDBusProxy - in +particular, mclasen and I ran into this problem while debugging a +upower issue, see + + https://bugzilla.redhat.com/show_bug.cgi?id=624125 + +In a nutshell, the problem is that polkitd crashes while upower holds +a PolkitAuthority object (which in turns contains a GDBusProxy for the +well-known name org.freedesktop.PolicyKit1). This means that +subsequent calls on the PolkitAuthority (which is translated into +calls into the GDBusProxy) fails since :g-name-owner is NULL. + +With this fix, we'll be requesting the bus daemon to launch polkitd +since we will start calling into org.freedesktop.PolicyKit1 as soon as +we notice that there is no owner for this name. + +Unfortunately our test suite doesn't cover service activation so there +is no way to reliably test this. I will file a bug about this. + +Signed-off-by: David Zeuthen +--- + gio/gdbusproxy.c | 108 ++++++++++++++++++++++++++++++++++++++++-------------- + 1 files changed, 80 insertions(+), 28 deletions(-) + +diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c +index d47a4ad..17e6730 100644 +--- a/gio/gdbusproxy.c ++++ b/gio/gdbusproxy.c +@@ -61,9 +61,13 @@ + * name is tracked and can be read from + * #GDBusProxy:g-name-owner. Connect to the #GObject::notify signal to + * get notified of changes. Additionally, only signals and property +- * changes emitted from the current name owner are considered. This +- * avoids a number of race conditions when the name is lost by one +- * owner and claimed by another. ++ * changes emitted from the current name owner are considered and ++ * calls are always sent to the current name owner. This avoids a ++ * number of race conditions when the name is lost by one owner and ++ * claimed by another. However, if no name owner currently exists, ++ * then calls will be sent to the well-known name which may result in ++ * the message bus launching an owner (unless ++ * %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is set). + * + * The generic #GDBusProxy::g-properties-changed and #GDBusProxy::g-signal + * signals are not very convenient to work with. Therefore, the recommended +@@ -2179,6 +2183,31 @@ lookup_method_info_or_warn (GDBusProxy *proxy, + return info; + } + ++static const gchar * ++get_destination_for_call (GDBusProxy *proxy) ++{ ++ const gchar *ret; ++ ++ ret = NULL; ++ ++ /* If proxy->priv->name is a unique name, then proxy->priv->name_owner ++ * is never NULL and always the same as proxy->priv->name. We use this ++ * knowledge to avoid checking if proxy->priv->name is a unique or ++ * well-known name. ++ */ ++ ret = proxy->priv->name_owner; ++ if (ret != NULL) ++ goto out; ++ ++ if (proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START) ++ goto out; ++ ++ ret = proxy->priv->name; ++ ++ out: ++ return ret; ++} ++ + /** + * g_dbus_proxy_call: + * @proxy: A #GDBusProxy. +@@ -2243,9 +2272,9 @@ g_dbus_proxy_call (GDBusProxy *proxy, + gboolean was_split; + gchar *split_interface_name; + const gchar *split_method_name; +- const GDBusMethodInfo *expected_method_info; + const gchar *target_method_name; + const gchar *target_interface_name; ++ const gchar *destination; + GVariantType *reply_type; + + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); +@@ -2253,6 +2282,9 @@ g_dbus_proxy_call (GDBusProxy *proxy, + g_return_if_fail (parameters == NULL || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)); + g_return_if_fail (timeout_msec == -1 || timeout_msec >= 0); + ++ reply_type = NULL; ++ split_interface_name = NULL; ++ + simple = g_simple_async_result_new (G_OBJECT (proxy), + callback, + user_data, +@@ -2265,17 +2297,30 @@ g_dbus_proxy_call (GDBusProxy *proxy, + g_object_set_data_full (G_OBJECT (simple), "-gdbus-proxy-method-name", g_strdup (target_method_name), g_free); + + /* Warn if method is unexpected (cf. :g-interface-info) */ +- expected_method_info = NULL; + if (!was_split) +- expected_method_info = lookup_method_info_or_warn (proxy, target_method_name); ++ { ++ const GDBusMethodInfo *expected_method_info; ++ expected_method_info = lookup_method_info_or_warn (proxy, target_method_name); ++ if (expected_method_info != NULL) ++ reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args); ++ } + +- if (expected_method_info) +- reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args); +- else +- reply_type = NULL; ++ destination = NULL; ++ if (proxy->priv->name != NULL) ++ { ++ destination = get_destination_for_call (proxy); ++ if (destination == NULL) ++ { ++ g_simple_async_result_set_error (simple, ++ G_IO_ERROR, ++ G_IO_ERROR_FAILED, ++ _("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag")); ++ goto out; ++ } ++ } + + g_dbus_connection_call (proxy->priv->connection, +- proxy->priv->name_owner, ++ destination, + proxy->priv->object_path, + target_interface_name, + target_method_name, +@@ -2287,6 +2332,7 @@ g_dbus_proxy_call (GDBusProxy *proxy, + (GAsyncReadyCallback) reply_cb, + simple); + ++ out: + if (reply_type != NULL) + g_variant_type_free (reply_type); + +@@ -2392,9 +2438,9 @@ g_dbus_proxy_call_sync (GDBusProxy *proxy, + gboolean was_split; + gchar *split_interface_name; + const gchar *split_method_name; +- const GDBusMethodInfo *expected_method_info; + const gchar *target_method_name; + const gchar *target_interface_name; ++ const gchar *destination; + GVariantType *reply_type; + + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); +@@ -2403,32 +2449,37 @@ g_dbus_proxy_call_sync (GDBusProxy *proxy, + g_return_val_if_fail (timeout_msec == -1 || timeout_msec >= 0, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + ++ reply_type = NULL; ++ + was_split = maybe_split_method_name (method_name, &split_interface_name, &split_method_name); + target_method_name = was_split ? split_method_name : method_name; + target_interface_name = was_split ? split_interface_name : proxy->priv->interface_name; + +- if (proxy->priv->expected_interface) ++ /* Warn if method is unexpected (cf. :g-interface-info) */ ++ if (!was_split) + { +- expected_method_info = g_dbus_interface_info_lookup_method (proxy->priv->expected_interface, target_method_name); +- if (expected_method_info == NULL) +- { +- g_warning ("Trying to invoke method `%s' which isn't in expected interface `%s'", +- target_method_name, +- target_interface_name); +- } ++ const GDBusMethodInfo *expected_method_info; ++ expected_method_info = lookup_method_info_or_warn (proxy, target_method_name); ++ if (expected_method_info != NULL) ++ reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args); + } +- else ++ ++ destination = NULL; ++ if (proxy->priv->name != NULL) + { +- expected_method_info = NULL; ++ destination = get_destination_for_call (proxy); ++ if (destination == NULL) ++ { ++ g_set_error_literal (error, ++ G_IO_ERROR, ++ G_IO_ERROR_FAILED, ++ _("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag")); ++ goto out; ++ } + } + +- if (expected_method_info) +- reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args); +- else +- reply_type = NULL; +- + ret = g_dbus_connection_call_sync (proxy->priv->connection, +- proxy->priv->name_owner, ++ destination, + proxy->priv->object_path, + target_interface_name, + target_method_name, +@@ -2439,6 +2490,7 @@ g_dbus_proxy_call_sync (GDBusProxy *proxy, + cancellable, + error); + ++ out: + if (reply_type != NULL) + g_variant_type_free (reply_type); + +-- +1.7.2.1 + diff --git a/glib2.spec b/glib2.spec index a3c135f..9c5999c 100644 --- a/glib2.spec +++ b/glib2.spec @@ -3,7 +3,7 @@ Summary: A library of handy utility functions Name: glib2 Version: 2.25.14 -Release: 1%{?dist} +Release: 2%{?dist} License: LGPLv2+ Group: System Environment/Libraries URL: http://www.gtk.org @@ -29,6 +29,9 @@ BuildRequires: gtk-doc # required for GIO content-type support Requires: shared-mime-info +# Upstream fix for a problem with PolicyKit problems +Patch0: 0001-GDBusProxy-Call-into-well-known-name-if-no-name-owne.patch + %description GLib is the low-level core library that forms the basis for projects such as GTK+ and GNOME. It provides data structure handling for C, @@ -55,6 +58,7 @@ The glib2-static package includes static libraries of the GLib library. %prep %setup -q -n glib-%{version} +%patch0 -p1 -b .wellknown-call %build # Support builds of both git snapshots and tarballs packed with autogoo @@ -162,6 +166,9 @@ gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules %{_libdir}/lib*.a %changelog +* Wed Aug 18 2010 Matthias Clasen - 2.25.14-2 +- Fix a PolicyKit problem + * Tue Aug 17 2010 Matthias Clasen - 2.25.14-1 - Update to 2.25.14