From 48e79fb4b29f297d29502e75a8956ffe65fe51db Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 1 Sep 2021 16:59:19 +0200 Subject: [PATCH] cloud-setup: track sorted list of NMCSProviderGetConfigIfaceData Sorted by iface_idx. The iface_idx is probably something useful and stable, provided by the provider. E.g. it's the order in which interfaces are exposed on the meta data. (cherry picked from commit 1c5cb9d3c2be5addd3b011873cfc6b99204955d1) (cherry picked from commit 0a2ed627038349d838add8f3fd72e2d282e74693) --- clients/cloud-setup/nmcs-provider.c | 49 ++++++++++++++++++++++++++++- clients/cloud-setup/nmcs-provider.h | 8 +++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/clients/cloud-setup/nmcs-provider.c b/clients/cloud-setup/nmcs-provider.c index 1ac5cd42bb..8dd5cc1997 100644 --- a/clients/cloud-setup/nmcs-provider.c +++ b/clients/cloud-setup/nmcs-provider.c @@ -51,6 +51,19 @@ nmcs_provider_get_main_context(NMCSProvider *self) } /*****************************************************************************/ +static int +_result_new_sort_iface_data(gconstpointer pa, gconstpointer pb) +{ + const NMCSProviderGetConfigIfaceData *a = *((const NMCSProviderGetConfigIfaceData *const *) pa); + const NMCSProviderGetConfigIfaceData *b = *((const NMCSProviderGetConfigIfaceData *const *) pb); + + /* negative iface_idx are sorted to the end. */ + NM_CMP_DIRECT((a->iface_idx < 0), (b->iface_idx < 0)); + + NM_CMP_FIELD(a, b, iface_idx); + return 0; +} + static NMCSProviderGetConfigResult * nmcs_provider_get_config_result_new(GHashTable *iface_datas) { @@ -59,6 +72,12 @@ nmcs_provider_get_config_result_new(GHashTable *iface_datas) GHashTableIter h_iter; guint num_valid_ifaces = 0; guint num_ipv4s = 0; + GPtrArray * ptrarr; + guint n_iface_datas; + + n_iface_datas = g_hash_table_size(iface_datas); + + ptrarr = g_ptr_array_sized_new(n_iface_datas + 1u); g_hash_table_iter_init(&h_iter, iface_datas); while (g_hash_table_iter_next(&h_iter, NULL, (gpointer *) &iface_data)) { @@ -66,15 +85,42 @@ nmcs_provider_get_config_result_new(GHashTable *iface_datas) num_valid_ifaces++; num_ipv4s += iface_data->ipv4s_len; } + g_ptr_array_add(ptrarr, (gpointer) iface_data); } + g_ptr_array_sort(ptrarr, _result_new_sort_iface_data); + + nm_assert(n_iface_datas == ptrarr->len); + + g_ptr_array_add(ptrarr, NULL); + result = g_new(NMCSProviderGetConfigResult, 1); *result = (NMCSProviderGetConfigResult){ - .iface_datas = g_hash_table_ref(iface_datas), + .iface_datas = g_hash_table_ref(iface_datas), + .n_iface_datas = n_iface_datas, + .iface_datas_arr = + (const NMCSProviderGetConfigIfaceData **) g_ptr_array_free(ptrarr, FALSE), .num_valid_ifaces = num_valid_ifaces, .num_ipv4s = num_ipv4s, }; +#if NM_MORE_ASSERTS > 5 + { + gsize iface_idx_expected = 0; + guint i; + + for (i = 0; i < result->n_iface_datas; i++) { + if (result->iface_datas_arr[i]->iface_idx < 0) { + nm_assert(result->iface_datas_arr[i]->iface_idx == -1); + iface_idx_expected = -1; + continue; + } + nm_assert(result->iface_datas_arr[i]->iface_idx == iface_idx_expected); + iface_idx_expected++; + } + } +#endif + return result; } @@ -83,6 +129,7 @@ nmcs_provider_get_config_result_free(NMCSProviderGetConfigResult *result) { if (result) { nm_g_hash_table_unref(result->iface_datas); + g_free((gpointer) result->iface_datas_arr); g_free(result); } } diff --git a/clients/cloud-setup/nmcs-provider.h b/clients/cloud-setup/nmcs-provider.h index 19bf56bd05..261f589f2f 100644 --- a/clients/cloud-setup/nmcs-provider.h +++ b/clients/cloud-setup/nmcs-provider.h @@ -61,6 +61,14 @@ typedef struct { /* the number of IPv4 addresses over all valid iface_datas. */ guint num_ipv4s; + + guint n_iface_datas; + + /* The sorted value of @iface_datas, sorted by iface_idx. + * + * Not found entries (iface_idx == -1) are sorted at the end. */ + const NMCSProviderGetConfigIfaceData *const *iface_datas_arr; + } NMCSProviderGetConfigResult; void nmcs_provider_get_config_result_free(NMCSProviderGetConfigResult *result);