ifcfg-rh: track connections by UUID not file path

We'll need this for later with unsaved connections.
This commit is contained in:
Dan Williams
2013-04-18 14:49:43 -05:00
parent 9d94000c69
commit b225a9f53b

View File

@@ -76,8 +76,9 @@ G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
typedef struct {
GHashTable *connections;
GHashTable *connections; /* uuid::connection */
gboolean initialized;
gulong ih_event_id;
int sc_network_wd;
GFileMonitor *hostname_monitor;
@@ -141,7 +142,7 @@ _internal_new_connection (SCPluginIfcfg *self,
g_assert (cid);
g_hash_table_insert (priv->connections,
(gpointer) nm_ifcfg_connection_get_path (connection),
(gpointer) nm_connection_get_uuid (NM_CONNECTION (connection)),
connection);
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid);
@@ -194,32 +195,19 @@ read_connections (SCPluginIfcfg *plugin)
/* Monitoring */
/* Callback for nm_settings_connection_replace_and_commit. Report any errors
* encountered when commiting connection settings updates. */
static void
commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused)
{
if (error) {
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error updating: %s",
(error && error->message) ? error->message : "(unknown)");
}
}
static void
remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection)
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
gboolean managed = FALSE;
const char *path;
g_return_if_fail (self != NULL);
g_return_if_fail (connection != NULL);
managed = !nm_ifcfg_connection_get_unmanaged_spec (connection);
path = nm_ifcfg_connection_get_path (connection);
g_object_ref (connection);
g_hash_table_remove (priv->connections, path);
g_hash_table_remove (priv->connections, nm_connection_get_uuid (NM_CONNECTION (connection)));
nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection));
g_object_unref (connection);
@@ -228,6 +216,23 @@ remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection)
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
}
static NMIfcfgConnection *
find_by_path (SCPluginIfcfg *self, const char *path)
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
GHashTableIter iter;
NMIfcfgConnection *candidate = NULL;
g_return_val_if_fail (path != NULL, NULL);
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) {
if (g_str_equal (path, nm_ifcfg_connection_get_path (candidate)))
return candidate;
}
return NULL;
}
static void
connection_new_or_changed (SCPluginIfcfg *self,
const char *path,
@@ -242,7 +247,7 @@ connection_new_or_changed (SCPluginIfcfg *self,
g_return_if_fail (path != NULL);
if (!existing) {
/* Completely new connection */
/* New connection */
new = _internal_new_connection (self, path, NULL, NULL);
if (new) {
if (nm_ifcfg_connection_get_unmanaged_spec (new)) {
@@ -305,19 +310,20 @@ connection_new_or_changed (SCPluginIfcfg *self,
}
} else {
if (old_unmanaged) { /* now managed */
const char *cid;
cid = nm_connection_get_id (NM_CONNECTION (new));
g_assert (cid);
const char *cid = nm_connection_get_id (NM_CONNECTION (new));
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Managing connection '%s' and its "
"device because NM_CONTROLLED was true.", cid);
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, existing);
}
nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (existing),
NM_CONNECTION (new),
commit_cb, NULL);
if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (existing),
NM_CONNECTION (new),
FALSE, /* don't set Unsaved */
&error)) {
/* Shouldn't ever get here as 'new' was verified by the reader already */
g_assert_no_error (error);
}
/* Update unmanaged status */
g_object_set (existing, NM_IFCFG_CONNECTION_UNMANAGED, new_unmanaged, NULL);
@@ -334,8 +340,7 @@ ifcfg_dir_changed (GFileMonitor *monitor,
gpointer user_data)
{
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
char *path, *name;
char *path, *ifcfg_path;
NMIfcfgConnection *connection;
path = g_file_get_path (file);
@@ -345,26 +350,26 @@ ifcfg_dir_changed (GFileMonitor *monitor,
}
/* Given any ifcfg, keys, or routes file, get the ifcfg file path */
name = utils_get_ifcfg_path (path);
g_free (path);
if (name) {
connection = g_hash_table_lookup (priv->connections, name);
ifcfg_path = utils_get_ifcfg_path (path);
if (ifcfg_path) {
connection = find_by_path (plugin, ifcfg_path);
switch (event_type) {
case G_FILE_MONITOR_EVENT_DELETED:
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", name);
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", ifcfg_path);
if (connection)
remove_connection (plugin, connection);
break;
case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
/* Update or new */
connection_new_or_changed (plugin, name, connection);
connection_new_or_changed (plugin, ifcfg_path, connection);
break;
default:
break;
}
g_free (name);
g_free (ifcfg_path);
}
g_free (path);
}
static void
@@ -374,8 +379,6 @@ setup_ifcfg_monitoring (SCPluginIfcfg *plugin)
GFile *file;
GFileMonitor *monitor;
priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
file = g_file_new_for_path (IFCFG_DIR "/");
monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
g_object_unref (file);
@@ -394,58 +397,55 @@ get_connections (NMSystemConfigInterface *config)
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
GSList *list = NULL;
GHashTableIter iter;
gpointer value;
NMIfcfgConnection *connection;
if (!priv->connections) {
if (!priv->initialized) {
setup_ifcfg_monitoring (plugin);
read_connections (plugin);
priv->initialized = TRUE;
}
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &value)) {
NMIfcfgConnection *exported = NM_IFCFG_CONNECTION (value);
if (!nm_ifcfg_connection_get_unmanaged_spec (exported))
list = g_slist_prepend (list, value);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) {
if (!nm_ifcfg_connection_get_unmanaged_spec (connection))
list = g_slist_prepend (list, connection);
}
return list;
}
static void
check_unmanaged (gpointer key, gpointer data, gpointer user_data)
{
GSList **list = (GSList **) user_data;
NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (data);
const char *unmanaged_spec;
GSList *iter;
unmanaged_spec = nm_ifcfg_connection_get_unmanaged_spec (connection);
if (!unmanaged_spec)
return;
/* Just return if the unmanaged spec is already in the list */
for (iter = *list; iter; iter = g_slist_next (iter)) {
if (!strcmp ((char *) iter->data, unmanaged_spec))
return;
}
*list = g_slist_prepend (*list, g_strdup (unmanaged_spec));
}
static GSList *
get_unmanaged_specs (NMSystemConfigInterface *config)
{
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
GSList *list = NULL;
GSList *list = NULL, *list_iter;
GHashTableIter iter;
NMIfcfgConnection *connection;
const char *spec;
gboolean found;
if (!priv->connections) {
if (!priv->initialized) {
setup_ifcfg_monitoring (plugin);
read_connections (plugin);
priv->initialized = TRUE;
}
g_hash_table_foreach (priv->connections, check_unmanaged, &list);
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) {
spec = nm_ifcfg_connection_get_unmanaged_spec (connection);
if (spec) {
/* Ignore duplicates */
for (list_iter = list, found = FALSE; list_iter; list_iter = g_slist_next (list_iter)) {
if (g_str_equal (list_iter->data, spec)) {
found = TRUE;
break;
}
}
if (!found)
list = g_slist_prepend (list, g_strdup (spec));
}
}
return list;
}
@@ -579,7 +579,6 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin,
const char **out_path,
GError **error)
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
NMIfcfgConnection *connection;
NMSettingConnection *s_con;
const char *uuid;
@@ -593,7 +592,7 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin,
return FALSE;
}
connection = g_hash_table_lookup (priv->connections, in_ifcfg);
connection = find_by_path (plugin, in_ifcfg);
if (!connection || nm_ifcfg_connection_get_unmanaged_spec (connection)) {
g_set_error (error,
NM_SETTINGS_ERROR,
@@ -650,6 +649,8 @@ sc_plugin_ifcfg_init (SCPluginIfcfg *plugin)
GFile *file;
GFileMonitor *monitor;
priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
/* We watch SC_NETWORK_FILE via NMInotifyHelper (which doesn't track file creation but
* *does* track modifications made via other hard links), since we expect it to always
* exist. But we watch HOSTNAME_FILE via GFileMonitor (which has the opposite
@@ -745,8 +746,10 @@ dispose (GObject *object)
g_free (priv->hostname);
if (priv->connections)
if (priv->connections) {
g_hash_table_destroy (priv->connections);
priv->connections = NULL;
}
if (priv->ifcfg_monitor) {
if (priv->ifcfg_monitor_id)
@@ -759,12 +762,6 @@ dispose (GObject *object)
G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->finalize (object);
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
@@ -817,7 +814,6 @@ sc_plugin_ifcfg_class_init (SCPluginIfcfgClass *req_class)
g_type_class_add_private (req_class, sizeof (SCPluginIfcfgPrivate));
object_class->dispose = dispose;
object_class->finalize = finalize;
object_class->get_property = get_property;
object_class->set_property = set_property;