diff options
author | Thomas Haller <thaller@redhat.com> | 2016-04-04 19:31:53 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-08-21 12:56:31 +0200 |
commit | 5e0df650e8d12111dacde0c3c56b6bfe1f24bcb3 (patch) | |
tree | 065814f6beb73e5e1c0507274bad8b5cd0f8a67f | |
parent | 8dcfda6dcdf6a7498a386a952da8b78071ccf71c (diff) | |
download | NetworkManager-th/device-run-state.tar.gz |
-rw-r--r-- | src/devices/nm-device.c | 119 | ||||
-rw-r--r-- | src/devices/nm-device.h | 12 | ||||
-rw-r--r-- | src/nm-manager.c | 21 |
3 files changed, 148 insertions, 4 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 44e22ff9c0..c9745dad7c 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -663,6 +663,125 @@ _get_stable_id (NMConnection *connection, NMUtilsStableType *out_stable_type) return stable_id; } +/*****************************************************************************/ + +#define NM_DEV_RUN_STATE_KEYFILE_GROUP_DEV "dev" +#define NM_DEV_RUN_STATE_KEYFILE_KEY_DEV_MANAGED "managed" +#define NM_DEV_RUN_STATE_KEYFILE_KEY_DEV_UUID "uuid" + +static NMDevRunState * +_dev_run_state_new (GKeyFile *kf) +{ + NMDevRunState *run_state; + gboolean managed = TRUE; + gs_free char *uuid = NULL; + gsize uuid_len_plus_1; + char *run_state_data; + + run_state = g_slice_new (NMDevRunState); + + if (kf) { + managed = nm_config_keyfile_get_boolean (kf, + NM_DEV_RUN_STATE_KEYFILE_GROUP_DEV, + NM_DEV_RUN_STATE_KEYFILE_KEY_DEV_MANAGED, + FALSE); + } + if (kf && managed) { + uuid = nm_config_keyfile_get_value (kf, + NM_DEV_RUN_STATE_KEYFILE_GROUP_DEV, + NM_DEV_RUN_STATE_KEYFILE_KEY_DEV_UUID, + NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY); + } + + uuid_len_plus_1 = uuid ? strlen (uuid) + 1 : 0; + + run_state = g_malloc (sizeof (NMDevRunState) + uuid_len_plus_1); + + run_state->managed = managed; + if (uuid) { + run_state_data = (((char *) run_state) + sizeof (NMDevRunState)); + memcpy (run_state_data, uuid, uuid_len_plus_1); + run_state->uuid = run_state_data; + } else + run_state->uuid = NULL; + + return run_state; +} + +/** + * nm_dev_run_state_load: + * @ifindex: the ifindex for which the state is to load + * @unlink_file: if TRUE, the state file will be deleted + * after reading. + * + * Returns: (transfer full): a run state object. + * Must be freed with g_free(). + */ +NMDevRunState * +nm_dev_run_state_load (int ifindex, gboolean unlink_file) +{ + char path[NM_STRLEN (NM_DEVICE_STATE_DIR) + 60]; + gs_unref_keyfile GKeyFile *kf = NULL; + gs_free_error GError *error = NULL; + + g_return_val_if_fail (ifindex > 0, NULL); + + nm_sprintf_buf (path, "%s/%d", NM_DEVICE_STATE_DIR, ifindex); + + kf = nm_config_create_keyfile (); + if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, &error)) { + if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + unlink_file = FALSE; + g_clear_pointer (&kf, g_key_file_unref); + } + + if (unlink_file) + (void) unlink (path); + + return _dev_run_state_new (kf); +} + +void +nm_dev_run_state_purge_stale_files (GHashTable *seen_ifindexes) +{ + GDir *dir; + const char *fn; + int ifindex; + gsize fn_len; + char buf[NM_STRLEN (NM_DEVICE_STATE_DIR"/") + 30 + 3] = NM_DEVICE_STATE_DIR"/"; + char *buf_p = &buf[NM_STRLEN (NM_DEVICE_STATE_DIR"/")]; + + g_return_if_fail (seen_ifindexes); + + dir = g_dir_open (NM_DEVICE_STATE_DIR, 0, NULL); + if (!dir) + return; + + while ((fn = g_dir_read_name (dir))) { + + if ( !fn[0] + || g_ascii_isspace (fn[0])) + continue; + + fn_len = strlen (fn); + if ( fn_len >= 30 + || g_ascii_isspace (fn[fn_len - 1])) + continue; + + ifindex = _nm_utils_ascii_str_to_int64 (fn, 10, 1, G_MAXINT, 0); + if (!ifindex) + continue; + + if (g_hash_table_contains (seen_ifindexes, GINT_TO_POINTER (ifindex))) + continue; + + memcpy (buf_p, fn, fn_len + 1); + (void) unlink (buf_p); + } + + g_dir_close (dir); +} + /***********************************************************/ const char * diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index e33a312605..3514b2c2ed 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -101,8 +101,20 @@ typedef enum NMActStageReturn NMActStageReturn; +/*****************************************************************************/ + #define NM_DEVICE_STATE_DIR ""NMRUNDIR"/devices" +typedef struct { + bool managed:1; + const char *uuid; +} NMDevRunState; + +NMDevRunState *nm_dev_run_state_load (int ifindex, gboolean unlink_file); +void nm_dev_run_state_purge_stale_files (GHashTable *seen_ifindexes); + +/*****************************************************************************/ + /* These flags affect whether a connection is considered available on a device * (check_connection_available()). The flags should have the meaning of relaxing * a condition, so that adding a flag might make a connection available that would diff --git a/src/nm-manager.c b/src/nm-manager.c index 237a45537d..06dbc86d7c 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2089,7 +2089,8 @@ _register_device_factory (NMDeviceFactory *factory, gpointer user_data) static void platform_link_added (NMManager *self, int ifindex, - const NMPlatformLink *plink) + const NMPlatformLink *plink, + NMDevRunState *run_state) { NMDeviceFactory *factory; NMDevice *device = NULL; @@ -2200,7 +2201,7 @@ _platform_link_cb_idle (PlatformLinkCbData *data) NMPlatformLink pllink; pllink = *l; /* make a copy of the link instance */ - platform_link_added (self, data->ifindex, &pllink); + platform_link_added (self, data->ifindex, &pllink, NULL); } else { NMDevice *device; GError *error = NULL; @@ -2258,11 +2259,23 @@ platform_query_devices (NMManager *self) GArray *links_array; NMPlatformLink *links; int i; + gs_unref_hashtable GHashTable *seen_ifindexes = NULL; + + seen_ifindexes = g_hash_table_new (NULL, NULL); links_array = nm_platform_link_get_all (NM_PLATFORM_GET); links = (NMPlatformLink *) links_array->data; - for (i = 0; i < links_array->len; i++) - platform_link_added (self, links[i].ifindex, &links[i]); + for (i = 0; i < links_array->len; i++) { + gs_free NMDevRunState *run_state = NULL; + + g_hash_table_add (seen_ifindexes, GINT_TO_POINTER (links[i].ifindex)); + + run_state = nm_dev_run_state_load (links[i].ifindex, FALSE); + + platform_link_added (self, links[i].ifindex, &links[i], run_state); + } + + nm_dev_run_state_purge_stale_files (seen_ifindexes); g_array_unref (links_array); } |