diff --git a/src/main.c b/src/main.c index 7e75f05ef..5b1a78045 100644 --- a/src/main.c +++ b/src/main.c @@ -453,6 +453,7 @@ main (int argc, char *argv[]) NMDBusManager *dbus_mgr = NULL; NMSupplicantManager *sup_mgr = NULL; NMDHCPManager *dhcp_mgr = NULL; + NMSysconfigSettings *settings = NULL; GError *error = NULL; gboolean wrote_pidfile = FALSE; char *cfg_log_level = NULL, *cfg_log_domains = NULL; @@ -672,7 +673,14 @@ main (int argc, char *argv[]) goto done; } - manager = nm_manager_get (config, + settings = nm_sysconfig_settings_new (config, plugins, &error); + if (!settings) { + nm_log_err (LOGD_CORE, "failed to initialize settings storage."); + goto done; + } + + manager = nm_manager_get (settings, + config, plugins, state_file, net_enabled, @@ -685,7 +693,7 @@ main (int argc, char *argv[]) goto done; } - policy = nm_policy_new (manager, vpn_manager); + policy = nm_policy_new (manager, vpn_manager, settings); if (policy == NULL) { nm_log_err (LOGD_CORE, "failed to initialize the policy."); goto done; @@ -733,6 +741,9 @@ done: if (manager) g_object_unref (manager); + if (settings) + g_object_unref (settings); + if (vpn_manager) g_object_unref (vpn_manager); diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index 546ecfafe..36b968ed8 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -652,7 +652,7 @@ dispose (GObject *object) device_cleanup (self); - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); if (priv->device_added_id) g_signal_handler_disconnect (manager, priv->device_added_id); g_object_unref (manager); @@ -850,7 +850,7 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other) priv->companion = other; /* When we've found the companion, stop listening for other devices */ - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); if (priv->device_added_id) { g_signal_handler_disconnect (manager, priv->device_added_id); priv->device_added_id = 0; @@ -905,7 +905,7 @@ check_companion_cb (gpointer user_data) if (priv->device_added_id != 0) return FALSE; - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); priv->device_added_id = g_signal_connect (manager, "device-added", G_CALLBACK (device_added_cb), self); diff --git a/src/nm-manager.c b/src/nm-manager.c index b98600d62..91a2879c0 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -200,8 +200,7 @@ typedef struct { NMUdevManager *udev_mgr; NMBluezManager *bluez_mgr; - GHashTable *system_connections; - NMSysconfigSettings *sys_settings; + NMSysconfigSettings *settings; char *hostname; GSList *secrets_calls; @@ -244,10 +243,6 @@ enum { STATE_CHANGED, STATE_CHANGE, /* DEPRECATED */ PROPERTIES_CHANGED, - CONNECTIONS_ADDED, - CONNECTION_ADDED, - CONNECTION_UPDATED, - CONNECTION_REMOVED, CHECK_PERMISSIONS, USER_PERMISSIONS_CHANGED, @@ -490,7 +485,7 @@ remove_one_device (NMManager *manager, g_signal_handlers_disconnect_by_func (device, manager_device_state_changed, manager); - nm_sysconfig_settings_device_removed (priv->sys_settings, device); + nm_sysconfig_settings_device_removed (priv->settings, device); g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device); g_object_unref (device); @@ -580,15 +575,6 @@ nm_manager_get_state (NMManager *manager) return NM_MANAGER_GET_PRIVATE (manager)->state; } -static void -emit_removed (gpointer key, gpointer value, gpointer user_data) -{ - NMManager *manager = NM_MANAGER (user_data); - NMConnection *connection = NM_CONNECTION (value); - - g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, connection); -} - static PendingActivation * pending_activation_new (NMManager *manager, PolkitAuthority *authority, @@ -756,106 +742,18 @@ get_active_connections (NMManager *manager, NMConnection *filter) return active; } -static void -remove_connection (NMManager *manager, - NMConnection *connection, - GHashTable *hash) -{ - /* Destroys the connection, then associated DBusGProxy due to the - * weak reference notify function placed on the connection when it - * was created. - */ - g_object_ref (connection); - g_hash_table_remove (hash, nm_connection_get_path (connection)); - g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, connection); - g_object_unref (connection); - - bluez_manager_resync_devices (manager); -} - /*******************************************************************/ -/* System settings stuff via NMSysconfigSettings */ +/* Settings stuff via NMSysconfigSettings */ /*******************************************************************/ static void -system_connection_updated_cb (NMSysconfigConnection *connection, - gpointer unused, - NMManager *manager) +connections_changed (NMSysconfigSettings *settings, + NMSysconfigConnection *connection, + NMManager *manager) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - const char *path; - NMSysconfigConnection *existing; - GError *error = NULL; - - path = nm_connection_get_path (NM_CONNECTION (connection)); - - existing = g_hash_table_lookup (priv->system_connections, path); - if (!existing) - return; - if (existing != connection) { - nm_log_warn (LOGD_SYS_SET, "existing connection didn't matched updated."); - return; - } - - if (!nm_connection_verify (NM_CONNECTION (existing), &error)) { - /* Updated connection invalid, remove existing connection */ - nm_log_warn (LOGD_SYS_SET, "invalid connection: '%s' / '%s' invalid: %d", - g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), - error->message, error->code); - g_error_free (error); - remove_connection (manager, NM_CONNECTION (existing), priv->system_connections); - return; - } - - g_signal_emit (manager, signals[CONNECTION_UPDATED], 0, existing); - bluez_manager_resync_devices (manager); } -static void -system_connection_removed_cb (NMSysconfigConnection *connection, - NMManager *manager) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - const char *path; - - path = nm_connection_get_path (NM_CONNECTION (connection)); - - connection = g_hash_table_lookup (priv->system_connections, path); - if (connection) - remove_connection (manager, NM_CONNECTION (connection), priv->system_connections); -} - -static void -_new_connection (NMSysconfigSettings *settings, - NMSysconfigConnection *connection, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - const char *path; - - g_return_if_fail (connection != NULL); - - g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_UPDATED, - G_CALLBACK (system_connection_updated_cb), self); - g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, - G_CALLBACK (system_connection_removed_cb), self); - - path = nm_connection_get_path (NM_CONNECTION (connection)); - g_hash_table_insert (priv->system_connections, g_strdup (path), - g_object_ref (connection)); - g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); -} - -static void -system_new_connection_cb (NMSysconfigSettings *settings, - NMSysconfigConnection *connection, - NMManager *self) -{ - _new_connection (settings, connection, self); -} - static void system_unmanaged_devices_changed_cb (NMSysconfigSettings *sys_settings, GParamSpec *pspec, @@ -1031,6 +929,7 @@ manager_hidden_ap_found (NMDeviceInterface *device, gpointer user_data) { NMManager *manager = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); const struct ether_addr *ap_addr; const GByteArray *ap_ssid; GSList *iter; @@ -1046,7 +945,7 @@ manager_hidden_ap_found (NMDeviceInterface *device, /* Look for this AP's BSSID in the seen-bssids list of a connection, * and if a match is found, copy over the SSID */ - connections = nm_manager_get_connections (manager); + connections = nm_sysconfig_settings_get_connections (priv->settings); for (iter = connections; iter && !done; iter = g_slist_next (iter)) { NMConnection *connection = NM_CONNECTION (iter->data); @@ -1353,8 +1252,6 @@ add_device (NMManager *self, NMDevice *device) static guint32 devcount = 0; const GSList *unmanaged_specs; NMConnection *existing = NULL; - GHashTableIter iter; - gpointer value; gboolean managed = FALSE, enabled = FALSE; iface = nm_device_get_ip_iface (device); @@ -1433,9 +1330,7 @@ add_device (NMManager *self, NMDevice *device) if (nm_device_interface_can_assume_connections (NM_DEVICE_INTERFACE (device))) { GSList *connections = NULL; - g_hash_table_iter_init (&iter, priv->system_connections); - while (g_hash_table_iter_next (&iter, NULL, &value)) - connections = g_slist_append (connections, value); + connections = nm_sysconfig_settings_get_connections (priv->settings); existing = nm_device_interface_connection_match_config (NM_DEVICE_INTERFACE (device), (const GSList *) connections); g_slist_free (connections); @@ -1451,7 +1346,7 @@ add_device (NMManager *self, NMDevice *device) } /* Start the device if it's supposed to be managed */ - unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->sys_settings); + unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->settings); if ( !manager_sleeping (self) && !nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs)) { nm_device_set_managed (device, @@ -1461,7 +1356,7 @@ add_device (NMManager *self, NMDevice *device) managed = TRUE; } - nm_sysconfig_settings_device_added (priv->sys_settings, device); + nm_sysconfig_settings_device_added (priv->settings, device); g_signal_emit (self, signals[DEVICE_ADDED], 0, device); /* If the device has a connection it can assume, do that now */ @@ -1516,10 +1411,11 @@ bluez_manager_find_connection (NMManager *manager, const char *bdaddr, guint32 capabilities) { + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); NMConnection *found = NULL; GSList *connections, *l; - connections = nm_manager_get_connections (manager); + connections = nm_sysconfig_settings_get_connections (priv->settings); for (l = connections; l != NULL; l = l->next) { NMConnection *candidate = NM_CONNECTION (l->data); @@ -1884,7 +1780,7 @@ system_get_secrets_idle_cb (gpointer user_data) info->idle_id = 0; - connection = nm_sysconfig_settings_get_connection_by_path (priv->sys_settings, + connection = nm_sysconfig_settings_get_connection_by_path (priv->settings, info->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, @@ -2137,13 +2033,15 @@ nm_manager_activate_connection (NMManager *manager, static void check_pending_ready (NMManager *self, PendingActivation *pending) { - NMConnection *connection; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMSysconfigConnection *connection; const char *path = NULL; GError *error = NULL; /* Ok, we're authorized */ - connection = nm_manager_get_connection_by_object_path (self, pending->connection_path); + connection = nm_sysconfig_settings_get_connection_by_path (priv->settings, + pending->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, @@ -2152,7 +2050,7 @@ check_pending_ready (NMManager *self, PendingActivation *pending) } path = nm_manager_activate_connection (self, - connection, + NM_CONNECTION (connection), pending->specific_object_path, pending->device_path, TRUE, @@ -2388,7 +2286,7 @@ do_sleep_wake (NMManager *self) } else { nm_log_info (LOGD_SUSPEND, "waking up and re-enabling..."); - unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->sys_settings); + unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->settings); /* Ensure rfkill state is up-to-date since we don't respond to state * changes during sleep. @@ -2847,73 +2745,6 @@ impl_manager_set_logging (NMManager *manager, return FALSE; } -/* Connections */ - -static int -connection_sort (gconstpointer pa, gconstpointer pb) -{ - NMConnection *a = NM_CONNECTION (pa); - NMSettingConnection *con_a; - NMConnection *b = NM_CONNECTION (pb); - NMSettingConnection *con_b; - - con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION); - g_assert (con_a); - con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); - g_assert (con_b); - - if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) { - if (nm_setting_connection_get_autoconnect (con_a)) - return -1; - return 1; - } - - if (nm_setting_connection_get_timestamp (con_a) > nm_setting_connection_get_timestamp (con_b)) - return -1; - else if (nm_setting_connection_get_timestamp (con_a) == nm_setting_connection_get_timestamp (con_b)) - return 0; - return 1; -} - -static void -connections_to_slist (gpointer key, gpointer value, gpointer user_data) -{ - GSList **list = (GSList **) user_data; - - *list = g_slist_insert_sorted (*list, g_object_ref (value), connection_sort); -} - -/* Returns a GSList of referenced NMConnection objects, caller must - * unref the connections in the list and destroy the list. - */ -GSList * -nm_manager_get_connections (NMManager *manager) -{ - NMManagerPrivate *priv; - GSList *list = NULL; - - g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); - - priv = NM_MANAGER_GET_PRIVATE (manager); - g_hash_table_foreach (priv->system_connections, connections_to_slist, &list); - return list; -} - -NMConnection * -nm_manager_get_connection_by_object_path (NMManager *manager, - const char *path) -{ - NMManagerPrivate *priv; - NMConnection *connection = NULL; - - g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); - g_return_val_if_fail (path != NULL, NULL); - - priv = NM_MANAGER_GET_PRIVATE (manager); - connection = (NMConnection *) g_hash_table_lookup (priv->system_connections, path); - return connection; -} - GPtrArray * nm_manager_get_active_connections_by_connection (NMManager *manager, NMConnection *connection) @@ -2951,13 +2782,8 @@ nm_manager_start (NMManager *self) nm_log_info (LOGD_CORE, "Networking is %s by state file", priv->net_enabled ? "enabled" : "disabled"); - system_unmanaged_devices_changed_cb (priv->sys_settings, NULL, self); - system_hostname_changed_cb (priv->sys_settings, NULL, self); - - /* Get all connections */ - nm_sysconfig_settings_for_each_connection (NM_MANAGER_GET_PRIVATE (self)->sys_settings, - _new_connection, - self); + system_unmanaged_devices_changed_cb (priv->settings, NULL, self); + system_hostname_changed_cb (priv->settings, NULL, self); nm_udev_manager_query_devices (priv->udev_mgr); bluez_manager_resync_devices (self); @@ -3178,7 +3004,8 @@ out: } NMManager * -nm_manager_get (const char *config_file, +nm_manager_get (NMSysconfigSettings *settings, + const char *config_file, const char *plugins, const char *state_file, gboolean initial_net_enabled, @@ -3194,6 +3021,8 @@ nm_manager_get (const char *config_file, if (singleton) return g_object_ref (singleton); + g_assert (settings); + singleton = (NMManager *) g_object_new (NM_TYPE_MANAGER, NULL); g_assert (singleton); @@ -3210,14 +3039,9 @@ nm_manager_get (const char *config_file, return NULL; } - priv->sys_settings = nm_sysconfig_settings_new (config_file, plugins, error); - if (!priv->sys_settings) { - g_object_unref (singleton); - return NULL; - } + priv->settings = settings; priv->config_file = g_strdup (config_file); - priv->state_file = g_strdup (state_file); priv->net_enabled = initial_net_enabled; @@ -3225,12 +3049,18 @@ nm_manager_get (const char *config_file, priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = initial_wifi_enabled; priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = initial_wwan_enabled; - g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, + g_signal_connect (priv->settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); - g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_HOSTNAME, + g_signal_connect (priv->settings, "notify::" NM_SYSCONFIG_SETTINGS_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); - g_signal_connect (priv->sys_settings, "new-connection", - G_CALLBACK (system_new_connection_cb), singleton); + g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, + G_CALLBACK (connections_changed), singleton); + g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, + G_CALLBACK (connections_changed), singleton); + g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connections_changed), singleton); + g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + G_CALLBACK (connections_changed), singleton); dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), NM_DBUS_PATH, @@ -3293,18 +3123,10 @@ dispose (GObject *object) TRUE); } - g_hash_table_foreach (priv->system_connections, emit_removed, manager); - g_hash_table_remove_all (priv->system_connections); - g_hash_table_destroy (priv->system_connections); - priv->system_connections = NULL; - g_free (priv->hostname); g_free (priv->config_file); - if (priv->sys_settings) { - g_object_unref (priv->sys_settings); - priv->sys_settings = NULL; - } + g_object_unref (priv->settings); if (priv->vpn_manager_id) { g_source_remove (priv->vpn_manager_id); @@ -3506,11 +3328,6 @@ nm_manager_init (NMManager *manager) priv->dbus_mgr = nm_dbus_manager_get (); - priv->system_connections = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - priv->modem_manager = nm_modem_manager_get (); priv->modem_added_id = g_signal_connect (priv->modem_manager, "modem-added", G_CALLBACK (modem_added), manager); @@ -3724,42 +3541,6 @@ nm_manager_class_init (NMManagerClass *manager_class) nm_properties_changed_signal_new (object_class, G_STRUCT_OFFSET (NMManagerClass, properties_changed)); - signals[CONNECTIONS_ADDED] = - g_signal_new ("connections-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connections_added), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[CONNECTION_ADDED] = - g_signal_new ("connection-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connection_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[CONNECTION_UPDATED] = - g_signal_new ("connection-updated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connection_updated), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[CONNECTION_REMOVED] = - g_signal_new ("connection-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connection_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - signals[CHECK_PERMISSIONS] = g_signal_new ("check-permissions", G_OBJECT_CLASS_TYPE (object_class), diff --git a/src/nm-manager.h b/src/nm-manager.h index 5bf92d602..2d0186b7c 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -20,13 +20,14 @@ */ #ifndef NM_MANAGER_H -#define NM_MANAGER_H 1 +#define NM_MANAGER_H #include #include #include #include "nm-device.h" #include "nm-device-interface.h" +#include "nm-sysconfig-settings.h" #define NM_TYPE_MANAGER (nm_manager_get_type ()) #define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager)) @@ -60,22 +61,12 @@ typedef struct { void (*device_removed) (NMManager *manager, NMDevice *device); void (*state_changed) (NMManager *manager, guint state); void (*properties_changed) (NMManager *manager, GHashTable *properties); - - void (*connections_added) (NMManager *manager); - - void (*connection_added) (NMManager *manager, - NMConnection *connection); - - void (*connection_updated) (NMManager *manager, - NMConnection *connection); - - void (*connection_removed) (NMManager *manager, - NMConnection *connection); } NMManagerClass; GType nm_manager_get_type (void); -NMManager *nm_manager_get (const char *config_file, +NMManager *nm_manager_get (NMSysconfigSettings *settings, + const char *config_file, const char *plugins, const char *state_file, gboolean initial_net_enabled, @@ -105,13 +96,6 @@ gboolean nm_manager_deactivate_connection (NMManager *manager, NMState nm_manager_get_state (NMManager *manager); -/* Connections */ - -GSList *nm_manager_get_connections (NMManager *manager); - -NMConnection * nm_manager_get_connection_by_object_path (NMManager *manager, - const char *path); - GPtrArray * nm_manager_get_active_connections_by_connection (NMManager *manager, NMConnection *connection); diff --git a/src/nm-policy.c b/src/nm-policy.c index df7689b72..793a5a7b4 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -56,6 +56,8 @@ struct NMPolicy { gulong vpn_activated_id; gulong vpn_deactivated_id; + NMSysconfigSettings *settings; + NMDevice *default_device4; NMDevice *default_device6; @@ -739,7 +741,7 @@ auto_activate_device (gpointer user_data) if (nm_device_get_act_request (data->device)) goto out; - connections = nm_manager_get_connections (policy->manager); + connections = nm_sysconfig_settings_get_connections (policy->settings); /* Remove connections that are in the invalid list. */ iter = connections; @@ -822,6 +824,7 @@ hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) static void sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) { + NMPolicy *policy = user_data; gboolean sleeping = FALSE, enabled = FALSE; GSList *connections, *iter; @@ -830,7 +833,7 @@ sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) /* Clear the invalid flag on all connections so they'll get retried on wakeup */ if (sleeping || !enabled) { - connections = nm_manager_get_connections (manager); + connections = nm_sysconfig_settings_get_connections (policy->settings); for (iter = connections; iter; iter = g_slist_next (iter)) g_object_set_data (G_OBJECT (iter->data), INVALID_TAG, NULL); g_slist_free (connections); @@ -1043,14 +1046,7 @@ schedule_activate_all (NMPolicy *policy) } static void -connections_added (NMManager *manager, - gpointer user_data) -{ - schedule_activate_all ((NMPolicy *) user_data); -} - -static void -connection_added (NMManager *manager, +connection_added (NMSysconfigSettings *settings, NMConnection *connection, gpointer user_data) { @@ -1058,7 +1054,7 @@ connection_added (NMManager *manager, } static void -connection_updated (NMManager *manager, +connection_updated (NMSysconfigSettings *settings, NMConnection *connection, gpointer user_data) { @@ -1069,22 +1065,19 @@ connection_updated (NMManager *manager, } static void -connection_removed (NMManager *manager, - NMConnection *connection, - gpointer user_data) +_deactivate_if_active (NMManager *manager, NMConnection *connection) { NMSettingConnection *s_con; GPtrArray *list; int i; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); - if (!s_con) - return; - list = nm_manager_get_active_connections_by_connection (manager, connection); if (!list) return; + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + for (i = 0; i < list->len; i++) { char *path = g_ptr_array_index (list, i); GError *error = NULL; @@ -1100,13 +1093,32 @@ connection_removed (NMManager *manager, } static void -manager_user_permissions_changed (NMManager *manager, NMPolicy *policy) +connection_removed (NMSysconfigSettings *settings, + NMConnection *connection, + gpointer user_data) { - schedule_activate_all (policy); + NMPolicy *policy = user_data; + + _deactivate_if_active (policy->manager, connection); +} + +static void +connection_visibility_changed (NMSysconfigSettings *settings, + NMSysconfigConnection *connection, + gpointer user_data) +{ + NMPolicy *policy = user_data; + + if (nm_sysconfig_connection_is_visible (connection)) + schedule_activate_all (policy); + else + _deactivate_if_active (policy->manager, NM_CONNECTION (connection)); } NMPolicy * -nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager) +nm_policy_new (NMManager *manager, + NMVPNManager *vpn_manager, + NMSysconfigSettings *settings) { NMPolicy *policy; static gboolean initialized = FALSE; @@ -1160,28 +1172,25 @@ nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager) G_CALLBACK (device_removed), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - /* Large batch of connections added, manager doesn't want us to - * process each one individually. - */ - id = g_signal_connect (manager, "connections-added", - G_CALLBACK (connections_added), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - /* Single connection added */ - id = g_signal_connect (manager, "connection-added", + /* Listen for events related to connections */ + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED, G_CALLBACK (connection_added), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - id = g_signal_connect (manager, "connection-updated", + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, + G_CALLBACK (connection_added), policy); + policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); + + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, G_CALLBACK (connection_updated), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - id = g_signal_connect (manager, "connection-removed", + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - id = g_signal_connect (manager, "user-permissions-changed", - G_CALLBACK (manager_user_permissions_changed), policy); + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + G_CALLBACK (connection_visibility_changed), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); return policy; @@ -1227,6 +1236,8 @@ nm_policy_destroy (NMPolicy *policy) } g_slist_free (policy->dev_signal_ids); + g_object_unref (policy->settings); + /* Rewrite /etc/hosts on exit to ensure we don't leave stale IP addresses * lying around. FIXME: this will take out a valid IP address of an * ethernet device we're leaving active (ie, a connection we can "assume" diff --git a/src/nm-policy.h b/src/nm-policy.h index 7d99613cc..968d62019 100644 --- a/src/nm-policy.h +++ b/src/nm-policy.h @@ -15,22 +15,22 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2008 Red Hat, Inc. + * Copyright (C) 2004 - 2010 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. */ #ifndef NETWORK_MANAGER_POLICY_H #define NETWORK_MANAGER_POLICY_H -#include "NetworkManager.h" #include "nm-manager.h" #include "nm-vpn-manager.h" -#include "nm-device.h" -#include "nm-activation-request.h" +#include "nm-sysconfig-settings.h" typedef struct NMPolicy NMPolicy; -NMPolicy *nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager); +NMPolicy *nm_policy_new (NMManager *manager, + NMVPNManager *vpn_manager, + NMSysconfigSettings *settings); void nm_policy_destroy (NMPolicy *policy); #endif /* NETWORK_MANAGER_POLICY_H */ diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 254fd9104..2f7ac629a 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -120,7 +120,11 @@ G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, G_TYPE_OBJECT) enum { PROPERTIES_CHANGED, - NEW_CONNECTION, + CONNECTION_ADDED, + CONNECTION_UPDATED, + CONNECTION_REMOVED, + CONNECTION_VISIBILITY_CHANGED, + CONNECTIONS_LOADED, LAST_SIGNAL }; @@ -166,6 +170,8 @@ load_connections (NMSysconfigSettings *self) /* FIXME: Bad hack */ unmanaged_specs_changed (NULL, self); + + g_signal_emit (self, signals[CONNECTIONS_LOADED], 0); } void @@ -175,7 +181,7 @@ nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *self, { NMSysconfigSettingsPrivate *priv; GHashTableIter iter; - gpointer key; + gpointer data; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); @@ -186,8 +192,8 @@ nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *self, load_connections (self); g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) - for_each_func (self, NM_SYSCONFIG_CONNECTION (key), user_data); + while (g_hash_table_iter_next (&iter, NULL, &data)) + for_each_func (self, NM_SYSCONFIG_CONNECTION (data), user_data); } static gboolean @@ -197,23 +203,65 @@ impl_settings_list_connections (NMSysconfigSettings *self, { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; - gpointer key; + gpointer data; load_connections (self); *connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) - g_ptr_array_add (*connections, g_strdup (nm_connection_get_path (NM_CONNECTION (key)))); + while (g_hash_table_iter_next (&iter, NULL, &data)) + g_ptr_array_add (*connections, g_strdup (nm_connection_get_path (NM_CONNECTION (data)))); return TRUE; } +static int +connection_sort (gconstpointer pa, gconstpointer pb) +{ + NMConnection *a = NM_CONNECTION (pa); + NMSettingConnection *con_a; + NMConnection *b = NM_CONNECTION (pb); + NMSettingConnection *con_b; + + con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION); + g_assert (con_a); + con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); + g_assert (con_b); + + if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) { + if (nm_setting_connection_get_autoconnect (con_a)) + return -1; + return 1; + } + + if (nm_setting_connection_get_timestamp (con_a) > nm_setting_connection_get_timestamp (con_b)) + return -1; + else if (nm_setting_connection_get_timestamp (con_a) == nm_setting_connection_get_timestamp (con_b)) + return 0; + return 1; +} + +/* Returns a GSList of referenced NMConnection objects, caller must + * unref the connections in the list and destroy the list. + */ +GSList * +nm_sysconfig_settings_get_connections (NMSysconfigSettings *self) +{ + GHashTableIter iter; + gpointer key = NULL; + GSList *list = NULL; + + g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL); + + g_hash_table_iter_init (&iter, NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self)->connections); + while (g_hash_table_iter_next (&iter, key, NULL)) + list = g_slist_insert_sorted (list, key, connection_sort); + return g_slist_reverse (list); +} + NMSysconfigConnection * nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, const char *path) { NMSysconfigSettingsPrivate *priv; - GHashTableIter iter; - gpointer key; g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL); @@ -223,12 +271,7 @@ nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, const c load_connections (self); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) { - if (!strcmp (nm_connection_get_path (NM_CONNECTION (key)), path)) - return NM_SYSCONFIG_CONNECTION (key); - } - return NULL; + return (NMSysconfigConnection *) g_hash_table_lookup (priv->connections, path); } static void @@ -532,10 +575,34 @@ load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error) } static void -connection_removed (NMSysconfigConnection *connection, - gpointer user_data) +connection_removed (NMSysconfigConnection *connection, gpointer user_data) { + g_object_ref (connection); + g_hash_table_remove (NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data)->connections, connection); + g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), + signals[CONNECTION_REMOVED], + 0, + connection); + g_object_unref (connection); +} + +static void +connection_updated (NMSysconfigConnection *connection, gpointer user_data) +{ + g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), + signals[CONNECTION_UPDATED], + 0, + connection); +} + +static void +connection_visibility_changed (NMSysconfigConnection *connection, gpointer user_data) +{ + g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), + signals[CONNECTION_VISIBILITY_CHANGED], + 0, + connection); } static void @@ -544,23 +611,64 @@ claim_connection (NMSysconfigSettings *self, gboolean do_export) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + static guint32 ec_counter = 0; + GError *error = NULL; + GHashTableIter iter; + gpointer data; + char *path; g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); - if (g_hash_table_lookup (priv->connections, connection)) - /* A plugin is lying to us. */ - return; + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + /* prevent duplicates */ + if (data == connection) + return; + } + + if (!nm_connection_verify (NM_CONNECTION (connection), &error)) { + nm_log_warn (LOGD_SYS_SET, "plugin provided invalid connection: '%s' / '%s' invalid: %d", + g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), + error->message, error->code); + g_error_free (error); + return; + } + + /* Ensure it's initial visibility is up-to-date */ + nm_sysconfig_connection_recheck_visibility (connection); - g_hash_table_insert (priv->connections, g_object_ref (connection), GINT_TO_POINTER (1)); g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); - /* Ensure it's initial visibility is up-to-date */ - nm_sysconfig_connection_recheck_visibility (connection); + g_signal_connect (connection, + NM_SYSCONFIG_CONNECTION_UPDATED, + G_CALLBACK (connection_updated), + self); - g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); + g_signal_connect (connection, "notify::" NM_SYSCONFIG_CONNECTION_VISIBLE, + G_CALLBACK (connection_visibility_changed), + self); + + /* Export the connection over D-Bus */ + g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); + path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++); + nm_connection_set_path (NM_CONNECTION (connection), path); + dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection)); + g_free (path); + + g_hash_table_insert (priv->connections, + (gpointer) nm_connection_get_path (NM_CONNECTION (connection)), + g_object_ref (connection)); + + /* Only emit the individual connection-added signal after connections + * have been initially loaded. While getting the first list of connections + * we suppress it, then send the connections-loaded signal after we're all + * done to minimize processing. + */ + if (priv->connections_loaded) + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); } // TODO it seems that this is only ever used to remove a @@ -572,10 +680,11 @@ remove_default_wired_connection (NMSysconfigSettings *self, gboolean do_signal) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + const char *path = nm_connection_get_path (NM_CONNECTION (connection)); - if (g_hash_table_lookup (priv->connections, connection)) { + if (g_hash_table_lookup (priv->connections, path)) { g_signal_emit_by_name (G_OBJECT (connection), NM_SYSCONFIG_CONNECTION_REMOVED); - g_hash_table_remove (priv->connections, connection); + g_hash_table_remove (priv->connections, path); } } @@ -878,7 +987,7 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; - gpointer key; + gpointer data; NMSettingConnection *s_con; NMSettingWired *s_wired; const GByteArray *setting_mac; @@ -889,8 +998,8 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) /* Find a wired connection locked to the given MAC address, if any */ g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) { - NMConnection *connection = NM_CONNECTION (key); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + NMConnection *connection = NM_CONNECTION (data); const char *connection_type; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); @@ -1190,6 +1299,8 @@ nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *devic remove_default_wired_connection (self, NM_SYSCONFIG_CONNECTION (connection), TRUE); } +/***************************************************************/ + NMSysconfigSettings * nm_sysconfig_settings_new (const char *config_file, const char *plugins, @@ -1226,8 +1337,6 @@ nm_sysconfig_settings_new (const char *config_file, return self; } -/***************************************************************/ - static void dispose (GObject *object) { @@ -1350,15 +1459,51 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT); - signals[NEW_CONNECTION] = - g_signal_new (NM_SYSCONFIG_SETTINGS_NEW_CONNECTION, + signals[CONNECTION_ADDED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - 0, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_added), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); + signals[CONNECTION_UPDATED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_updated), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTION_REMOVED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTION_VISIBILITY_CHANGED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_visibility_changed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTIONS_LOADED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connections_loaded), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, NM_DBUS_IFACE_SETTINGS, NM_TYPE_SYSCONFIG_SETTINGS_ERROR); @@ -1393,7 +1538,7 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self) NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); GError *error = NULL; - priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); + priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); priv->authority = polkit_authority_get_sync (NULL, &error); if (!priv->authority) { diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h index 948349820..9f8565daa 100644 --- a/src/system-settings/nm-sysconfig-settings.h +++ b/src/system-settings/nm-sysconfig-settings.h @@ -43,7 +43,11 @@ #define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname" #define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify" -#define NM_SYSCONFIG_SETTINGS_NEW_CONNECTION "new-connection" +#define NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED "connection-added" +#define NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED "connection-updated" +#define NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED "connection-removed" +#define NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed" +#define NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED "connections-loaded" typedef struct { GObject parent_instance; @@ -54,6 +58,16 @@ typedef struct { /* Signals */ void (*properties_changed) (NMSysconfigSettings *self, GHashTable *properties); + + void (*connection_added) (NMSysconfigSettings *self, NMConnection *connection); + + void (*connection_updated) (NMSysconfigSettings *self, NMConnection *connection); + + void (*connection_removed) (NMSysconfigSettings *self, NMConnection *connection); + + void (*connection_visibility_changed) (NMSysconfigSettings *self, NMConnection *connection); + + void (*connections_loaded) (NMSysconfigSettings *self); } NMSysconfigSettingsClass; GType nm_sysconfig_settings_get_type (void); @@ -70,10 +84,13 @@ void nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *settings, NMSysconfigSettingsForEachFunc for_each_func, gpointer user_data); -GSList * nm_sysconfig_settings_list_connections (NMSysconfigSettings *settings); +/* Returns a list of NMSysconfigConnections. Caller must free the list with + * g_slist_free(). + */ +GSList *nm_sysconfig_settings_get_connections (NMSysconfigSettings *settings); -NMSysconfigConnection * nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *settings, - const char *path); +NMSysconfigConnection *nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *settings, + const char *path); const GSList *nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 6c2acfb56..7b47b18da 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -30,11 +30,11 @@ #include "NetworkManager.h" #include "NetworkManagerVPN.h" #include "nm-vpn-connection.h" +#include "nm-device-interface.h" #include "nm-setting-connection.h" #include "nm-setting-vpn.h" #include "nm-setting-ip4-config.h" #include "nm-dbus-manager.h" -#include "nm-manager.h" #include "nm-system.h" #include "nm-logging.h" #include "nm-utils.h"