about summary refs log tree commit diff
path: root/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c')
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c172
1 files changed, 88 insertions, 84 deletions
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
index 0743fc9f..0fb77b9d 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
@@ -37,7 +37,6 @@
 #include "settings/nm-settings-plugin.h"
 #include "nm-config.h"
 #include "NetworkManagerUtils.h"
-#include "nm-exported-object.h"
 
 #include "nms-ifcfg-rh-connection.h"
 #include "nms-ifcfg-rh-common.h"
@@ -46,10 +45,10 @@
 #include "nms-ifcfg-rh-utils.h"
 #include "shvar.h"
 
-#include "settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.h"
-
-#define IFCFGRH1_DBUS_SERVICE_NAME "com.redhat.ifcfgrh1"
-#define IFCFGRH1_DBUS_OBJECT_PATH "/com/redhat/ifcfgrh1"
+#define IFCFGRH1_BUS_NAME                               "com.redhat.ifcfgrh1"
+#define IFCFGRH1_OBJECT_PATH                            "/com/redhat/ifcfgrh1"
+#define IFCFGRH1_IFACE1_NAME                            "com.redhat.ifcfgrh1"
+#define IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS        "GetIfcfgDetails"
 
 /*****************************************************************************/
 
@@ -58,9 +57,9 @@ typedef struct {
 
 	struct {
 		GDBusConnection *connection;
-		GDBusInterfaceSkeleton *interface;
 		GCancellable *cancellable;
 		gulong signal_id;
+		guint regist_id;
 	} dbus;
 
 	GHashTable *connections;  /* uuid::connection */
@@ -126,7 +125,6 @@ connection_ifcfg_changed (NMIfcfgConnection *connection, gpointer user_data)
 	path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection));
 	g_return_if_fail (path != NULL);
 
-
 	if (!priv->ifcfg_monitor) {
 		_LOGD ("connection_ifcfg_changed("NM_IFCFG_CONNECTION_LOG_FMTD"): %s", NM_IFCFG_CONNECTION_LOG_ARGD (connection), "ignore event");
 		return;
@@ -327,21 +325,21 @@ update_connection (SettingsPluginIfcfg *self,
 
 			if (new_unmanaged || new_unrecognized) {
 				if (!old_unmanaged && !old_unrecognized) {
+					/* ref connection first, because we put it into priv->connections below.
+					 * Emitting signal-removed might otherwise delete it. */
 					g_object_ref (connection_by_uuid);
+
 					/* Unexport the connection by telling the settings service it's
 					 * been removed.
 					 */
 					nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection_by_uuid));
-					/* Remove the path so that claim_connection() doesn't complain later when
-					 * interface gets managed and connection is re-added. */
-					nm_connection_set_path (NM_CONNECTION (connection_by_uuid), NULL);
 
 					/* signal_remove() will end up removing the connection from our hash,
 					 * so add it back now.
 					 */
 					g_hash_table_insert (priv->connections,
 					                     g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection_by_uuid))),
-					                     connection_by_uuid);
+					                     connection_by_uuid /* we took reference above and pass it on */);
 				}
 			} else {
 				if (old_unmanaged /* && !new_unmanaged */) {
@@ -373,7 +371,9 @@ update_connection (SettingsPluginIfcfg *self,
 			_LOGI ("add connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new));
 		else
 			_LOGI ("new connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new));
-		g_hash_table_insert (priv->connections, g_strdup (uuid), connection_new);
+		g_hash_table_insert (priv->connections,
+		                     g_strdup (uuid),
+		                     connection_new /* take reference */);
 
 		g_signal_connect (connection_new, NM_SETTINGS_CONNECTION_REMOVED,
 		                  G_CALLBACK (connection_removed_cb),
@@ -418,7 +418,7 @@ ifcfg_dir_changed (GFileMonitor *monitor,
 	path = g_file_get_path (file);
 
 	ifcfg_path = utils_detect_ifcfg_path (path, FALSE);
-	_LOGD ("ifcfg_dir_changed(%s) = %d // %s", path, event_type, ifcfg_path ? ifcfg_path : "(none)");
+	_LOGD ("ifcfg_dir_changed(%s) = %d // %s", path, event_type, ifcfg_path ?: "(none)");
 	if (ifcfg_path) {
 		connection = find_by_path (plugin, ifcfg_path);
 		switch (event_type) {
@@ -516,7 +516,7 @@ read_connections (SettingsPluginIfcfg *plugin)
 		return;
 	}
 
-	alive_connections = g_hash_table_new (NULL, NULL);
+	alive_connections = g_hash_table_new (nm_direct_hash, NULL);
 
 	filenames = g_ptr_array_new_with_free_func (g_free);
 	while ((item = g_dir_read_name (dir))) {
@@ -749,7 +749,7 @@ impl_ifcfgrh_get_ifcfg_details (SettingsPluginIfcfg *plugin,
 		return;
 	}
 
-	path = nm_connection_get_path (NM_CONNECTION (connection));
+	path = nm_dbus_object_get_path (NM_DBUS_OBJECT (connection));
 	if (!path) {
 		g_dbus_method_invocation_return_error (context,
 		                                       NM_SETTINGS_ERROR,
@@ -768,15 +768,15 @@ static void
 _dbus_clear (SettingsPluginIfcfg *self)
 {
 	SettingsPluginIfcfgPrivate *priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self);
+	guint id;
 
 	nm_clear_g_signal_handler (priv->dbus.connection, &priv->dbus.signal_id);
 
 	nm_clear_g_cancellable (&priv->dbus.cancellable);
 
-	if (priv->dbus.interface) {
-		g_dbus_interface_skeleton_unexport (priv->dbus.interface);
-		nm_exported_object_skeleton_release (priv->dbus.interface);
-		priv->dbus.interface = NULL;
+	if ((id = nm_steal_int (&priv->dbus.regist_id))) {
+		if (!g_dbus_connection_unregister_object (priv->dbus.connection, id))
+			_LOGW ("dbus: unexpected failure to unregister object");
 	}
 
 	g_clear_object (&priv->dbus.connection);
@@ -788,13 +788,56 @@ _dbus_connection_closed (GDBusConnection *connection,
                          GError          *error,
                          gpointer         user_data)
 {
-	_LOGW ("dbus: %s bus closed", IFCFGRH1_DBUS_SERVICE_NAME);
+	_LOGW ("dbus: %s bus closed", IFCFGRH1_BUS_NAME);
 	_dbus_clear (SETTINGS_PLUGIN_IFCFG (user_data));
 
 	/* Retry or recover? */
 }
 
 static void
+_method_call (GDBusConnection *connection,
+              const char *sender,
+              const char *object_path,
+              const char *interface_name,
+              const char *method_name,
+              GVariant *parameters,
+              GDBusMethodInvocation *invocation,
+              gpointer user_data)
+{
+	SettingsPluginIfcfg *self = SETTINGS_PLUGIN_IFCFG (user_data);
+	const char *ifcfg;
+
+	if (   !nm_streq (interface_name, IFCFGRH1_IFACE1_NAME)
+	    || !nm_streq (method_name, IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS)) {
+		g_dbus_method_invocation_return_error (invocation,
+		                                       G_DBUS_ERROR,
+		                                       G_DBUS_ERROR_UNKNOWN_METHOD,
+		                                       "Unknown method %s",
+		                                       method_name);
+		return;
+	}
+
+	g_variant_get (parameters, "(&s)", &ifcfg);
+	impl_ifcfgrh_get_ifcfg_details (self, invocation, ifcfg);
+}
+
+static GDBusInterfaceInfo *const interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO (
+	IFCFGRH1_BUS_NAME,
+	.methods = NM_DEFINE_GDBUS_METHOD_INFOS (
+		NM_DEFINE_GDBUS_METHOD_INFO (
+			IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS,
+			.in_args = NM_DEFINE_GDBUS_ARG_INFOS (
+				NM_DEFINE_GDBUS_ARG_INFO ("ifcfg", "s"),
+			),
+			.out_args = NM_DEFINE_GDBUS_ARG_INFOS (
+				NM_DEFINE_GDBUS_ARG_INFO ("uuid", "s"),
+				NM_DEFINE_GDBUS_ARG_INFO ("path", "o"),
+			),
+		),
+	),
+);
+
+static void
 _dbus_request_name_done (GObject *source_object,
                          GAsyncResult *res,
                          gpointer user_data)
@@ -830,36 +873,27 @@ _dbus_request_name_done (GObject *source_object,
 	}
 
 	{
-		GType skeleton_type = NMDBUS_TYPE_IFCFGRH1_SKELETON;
-		gs_free char *method_name_get_ifcfg_details = NULL;
-		NMExportedObjectDBusMethodImpl methods[] = {
-			{
-				.method_name = (method_name_get_ifcfg_details = nm_exported_object_skeletonify_method_name ("GetIfcfgDetails")),
-				.impl = G_CALLBACK (impl_ifcfgrh_get_ifcfg_details),
-			},
+		static const GDBusInterfaceVTable interface_vtable = {
+			.method_call = _method_call,
 		};
 
-		priv->dbus.interface = nm_exported_object_skeleton_create (skeleton_type,
-		                                                           g_type_class_peek (SETTINGS_TYPE_PLUGIN_IFCFG),
-		                                                           methods,
-		                                                           G_N_ELEMENTS (methods),
-		                                                           (GObject *) self);
-
-		if (!g_dbus_interface_skeleton_export (priv->dbus.interface,
-		                                       priv->dbus.connection,
-		                                       IFCFGRH1_DBUS_OBJECT_PATH,
-		                                       &error)) {
-			nm_exported_object_skeleton_release (priv->dbus.interface);
-			priv->dbus.interface = NULL;
-			_LOGW ("dbus: failed exporting interface: %s", error->message);
+		priv->dbus.regist_id = g_dbus_connection_register_object (connection,
+		                                                          IFCFGRH1_OBJECT_PATH,
+		                                                          interface_info,
+		                                                          NM_UNCONST_PTR (GDBusInterfaceVTable, &interface_vtable),
+		                                                          self,
+		                                                          NULL,
+		                                                          &error);
+		if (!priv->dbus.regist_id) {
+			_LOGW ("dbus: couldn't register D-Bus service: %s", error->message);
 			_dbus_clear (self);
 			return;
 		}
 	}
 
-	_LOGD ("dbus: aquired D-Bus service %s and exported %s object",
-	       IFCFGRH1_DBUS_SERVICE_NAME,
-	       IFCFGRH1_DBUS_OBJECT_PATH);
+	_LOGD ("dbus: acquired D-Bus service %s and exported %s object",
+	       IFCFGRH1_BUS_NAME,
+	       IFCFGRH1_OBJECT_PATH);
 }
 
 static void
@@ -900,7 +934,7 @@ _dbus_create_done (GObject *source_object,
 	                        DBUS_INTERFACE_DBUS,
 	                        "RequestName",
 	                        g_variant_new ("(su)",
-	                                       IFCFGRH1_DBUS_SERVICE_NAME,
+	                                       IFCFGRH1_BUS_NAME,
 	                                       DBUS_NAME_FLAG_DO_NOT_QUEUE),
 	                        G_VARIANT_TYPE ("(u)"),
 	                        G_DBUS_CALL_FLAGS_NONE,
@@ -917,7 +951,7 @@ _dbus_setup (SettingsPluginIfcfg *self)
 	gs_free char *address = NULL;
 	gs_free_error GError *error = NULL;
 
-	g_return_if_fail (!priv->dbus.connection);
+	_dbus_clear (self);
 
 	address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
 	if (address == NULL) {
@@ -943,39 +977,22 @@ config_changed_cb (NMConfig *config,
                    NMConfigData *old_data,
                    SettingsPluginIfcfg *self)
 {
+	SettingsPluginIfcfgPrivate *priv;
+
 	/* If the dbus connection for some reason is borked the D-Bus service
 	 * won't be offered.
 	 *
 	 * On SIGHUP and SIGUSR1 try to re-connect to D-Bus. So in the unlikely
 	 * event that the D-Bus conneciton is broken, that allows for recovery
 	 * without need for restarting NetworkManager. */
-	if (NM_FLAGS_ANY (changes,   NM_CONFIG_CHANGE_CAUSE_SIGHUP
-	                           | NM_CONFIG_CHANGE_CAUSE_SIGUSR1)) {
-		if (!SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self)->dbus.connection)
-			_dbus_setup (self);
-	}
-}
-
-/*****************************************************************************/
+	if (!NM_FLAGS_ANY (changes,   NM_CONFIG_CHANGE_CAUSE_SIGHUP
+	                            | NM_CONFIG_CHANGE_CAUSE_SIGUSR1))
+		return;
 
-static void
-get_property (GObject *object, guint prop_id,
-              GValue *value, GParamSpec *pspec)
-{
-	switch (prop_id) {
-	case NM_SETTINGS_PLUGIN_PROP_NAME:
-		g_value_set_string (value, IFCFG_PLUGIN_NAME);
-		break;
-	case NM_SETTINGS_PLUGIN_PROP_INFO:
-		g_value_set_string (value, IFCFG_PLUGIN_INFO);
-		break;
-	case NM_SETTINGS_PLUGIN_PROP_CAPABILITIES:
-		g_value_set_uint (value, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
+	priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self);
+	if (   !priv->dbus.connection
+	    && !priv->dbus.cancellable)
+		_dbus_setup (self);
 }
 
 /*****************************************************************************/
@@ -1048,19 +1065,6 @@ settings_plugin_ifcfg_class_init (SettingsPluginIfcfgClass *req_class)
 
 	object_class->constructed = constructed;
 	object_class->dispose = dispose;
-	object_class->get_property = get_property;
-
-	g_object_class_override_property (object_class,
-	                                  NM_SETTINGS_PLUGIN_PROP_NAME,
-	                                  NM_SETTINGS_PLUGIN_NAME);
-
-	g_object_class_override_property (object_class,
-	                                  NM_SETTINGS_PLUGIN_PROP_INFO,
-	                                  NM_SETTINGS_PLUGIN_INFO);
-
-	g_object_class_override_property (object_class,
-	                                  NM_SETTINGS_PLUGIN_PROP_CAPABILITIES,
-	                                  NM_SETTINGS_PLUGIN_CAPABILITIES);
 }
 
 static void