diff options
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.c | 172 |
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 |