diff options
| author | Michael Biebl <biebl@debian.org> | 2023-08-09 21:55:35 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2023-08-09 21:55:35 +0200 |
| commit | 05e4a733f2141995181a551854d5df929f084adf (patch) | |
| tree | 83bb937740a6667525ba0df046748ecaa829c269 /src/nm-cloud-setup/main.c | |
| parent | 14b0f3a9dc9ea90d60a3b057350fd4d637dc021a (diff) | |
New upstream version 1.44.0 upstream/1.44.0
Diffstat (limited to 'src/nm-cloud-setup/main.c')
| -rw-r--r-- | src/nm-cloud-setup/main.c | 183 |
1 files changed, 147 insertions, 36 deletions
diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c index 630f26ef..084b5f62 100644 --- a/src/nm-cloud-setup/main.c +++ b/src/nm-cloud-setup/main.c @@ -22,10 +22,12 @@ typedef struct { } SigTermData; typedef struct { + SigTermData *sigterm_data; GMainLoop *main_loop; GCancellable *cancellable; NMCSProvider *provider_result; guint detect_count; + gboolean any_provider_enabled; } ProviderDetectData; static void @@ -33,38 +35,45 @@ _provider_detect_cb(GObject *source, GAsyncResult *result, gpointer user_data) { gs_unref_object NMCSProvider *provider = NMCS_PROVIDER(source); gs_free_error GError *error = NULL; - ProviderDetectData *dd; + ProviderDetectData *dd = user_data; gboolean success; + nm_assert(dd->detect_count > 0); + dd->detect_count--; + success = nmcs_provider_detect_finish(provider, result, &error); nm_assert(success != (!!error)); - if (nm_utils_error_is_cancelled(error)) - return; - - dd = user_data; - - nm_assert(dd->detect_count > 0); - dd->detect_count--; - + if (nm_utils_error_is_cancelled(error)) { + _LOGD("provider %s detection cancelled", nmcs_provider_get_name(provider)); + goto out; + } if (error) { + if (nm_g_error_matches(error, NM_UTILS_ERROR, NM_UTILS_ERROR_NOT_READY)) { + /* This error tells us, that the provider was not enabled in configuration. */ + } else + dd->any_provider_enabled = TRUE; _LOGI("provider %s not detected: %s", nmcs_provider_get_name(provider), error->message); - if (dd->detect_count > 0) { - /* wait longer. */ - return; - } - - _LOGI("no provider detected"); - goto done; + goto out; } _LOGI("provider %s detected", nmcs_provider_get_name(provider)); dd->provider_result = g_steal_pointer(&provider); - -done: g_cancellable_cancel(dd->cancellable); - g_main_loop_quit(dd->main_loop); + +out: + if (dd->detect_count == 0) { + if (!dd->provider_result) { + NMLogLevel level = LOGL_INFO; + + if (dd->any_provider_enabled && !dd->sigterm_data->signal_received) + level = LOGL_WARN; + + _NMLOG(level, "no provider detected"); + } + g_main_loop_quit(dd->main_loop); + } } static void @@ -74,21 +83,21 @@ _provider_detect_sigterm_cb(GCancellable *source, gpointer user_data) g_cancellable_cancel(dd->cancellable); g_clear_object(&dd->provider_result); - dd->detect_count = 0; - g_main_loop_quit(dd->main_loop); } static NMCSProvider * -_provider_detect(GCancellable *sigterm_cancellable) +_provider_detect(SigTermData *sigterm_data) { nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new(NULL, FALSE); gs_unref_object GCancellable *cancellable = g_cancellable_new(); gs_unref_object NMHttpClient *http_client = NULL; ProviderDetectData dd = { - .cancellable = cancellable, - .main_loop = main_loop, - .detect_count = 0, - .provider_result = NULL, + .sigterm_data = sigterm_data, + .cancellable = cancellable, + .main_loop = main_loop, + .detect_count = 0, + .provider_result = NULL, + .any_provider_enabled = FALSE, }; const GType gtypes[] = { NMCS_TYPE_PROVIDER_EC2, @@ -99,7 +108,7 @@ _provider_detect(GCancellable *sigterm_cancellable) int i; gulong cancellable_signal_id; - cancellable_signal_id = g_cancellable_connect(sigterm_cancellable, + cancellable_signal_id = g_cancellable_connect(sigterm_data->cancellable, G_CALLBACK(_provider_detect_sigterm_cb), &dd, NULL); @@ -123,12 +132,113 @@ _provider_detect(GCancellable *sigterm_cancellable) g_main_loop_run(main_loop); out: - nm_clear_g_signal_handler(sigterm_cancellable, &cancellable_signal_id); + nm_clear_g_signal_handler(sigterm_data->cancellable, &cancellable_signal_id); return dd.provider_result; } /*****************************************************************************/ +static NMUtilsNamedValue * +_map_interfaces_parse(void) +{ + gs_free const char **split = NULL; + NMUtilsNamedValue *map_interfaces; + const char *env_var; + gsize i; + gsize j; + gsize alloc_len; + + env_var = g_getenv(NMCS_ENV_NM_CLOUD_SETUP_MAP_INTERFACES); + + if (nm_str_is_empty(env_var)) + return NULL; + + split = nm_strsplit_set_full(env_var, ";", NM_STRSPLIT_SET_FLAGS_STRSTRIP); + + alloc_len = NM_PTRARRAY_LEN(split) + 1u; + + map_interfaces = g_new(NMUtilsNamedValue, alloc_len); + + _LOGD("test: map interfaces via NM_CLOUD_SETUP_MAP_INTERFACES=\"%s\"", env_var); + + for (i = 0, j = 0; split && split[i]; i++) { + NMUtilsNamedValue *m; + const char *str = split[i]; + char *hwaddr; + const char *s; + + s = strchr(str, '='); + if (!s || str == s) + continue; + + hwaddr = nmcs_utils_hwaddr_normalize(&s[1], -1); + if (!hwaddr) + continue; + + nm_assert(j < alloc_len); + m = &map_interfaces[j++]; + + *m = (NMUtilsNamedValue){ + .name = g_strndup(str, s - str), + .value_str = hwaddr, + }; + + _LOGD("test: map \"%s\" -> %s", m->name, m->value_str); + } + + nm_assert(j < alloc_len); + map_interfaces[j++] = (NMUtilsNamedValue){ + .name = NULL, + .value_str = NULL, + }; + + return g_steal_pointer(&map_interfaces); +} + +static const char * +_device_get_hwaddr(NMDeviceEthernet *device) +{ + static const NMUtilsNamedValue *gl_map_interfaces_map = NULL; + static gsize gl_initialized = 0; + const NMUtilsNamedValue *map = NULL; + + nm_assert(NM_IS_DEVICE_ETHERNET(device)); + + /* Network interfaces in cloud environments are identified by their permanent + * MAC address. + * + * For testing, we can set NMCS_ENV_NM_CLOUD_SETUP_MAP_INTERFACES + * to a ';' separate list of "$INTERFACE=$HWADDR", which means that we + * pretend that device with ip-interface "$INTERFACE" has the specified permanent + * MAC address. */ + + if (g_once_init_enter(&gl_initialized)) { + gl_map_interfaces_map = _map_interfaces_parse(); + g_once_init_leave(&gl_initialized, 1); + } + + map = gl_map_interfaces_map; + if (G_UNLIKELY(map)) { + const char *const iface = nm_device_get_iface(NM_DEVICE(device)); + + /* For testing, the device<->hwaddr is remapped and the actual permanent + * MAC address of the device ignored. This mapping is configured via + * NMCS_ENV_NM_CLOUD_SETUP_MAP_INTERFACES environment variable. */ + + if (!iface) + return NULL; + + for (; map->name; map++) { + if (nm_streq(map->name, iface)) + return map->value_str; + } + + return NULL; + } + + return nm_device_ethernet_get_permanent_hw_address(device); +} + static char ** _nmc_get_hwaddrs(NMClient *nmc) { @@ -151,7 +261,7 @@ _nmc_get_hwaddrs(NMClient *nmc) if (nm_device_get_state(device) < NM_DEVICE_STATE_UNAVAILABLE) continue; - hwaddr = nm_device_ethernet_get_permanent_hw_address(NM_DEVICE_ETHERNET(device)); + hwaddr = _device_get_hwaddr(NM_DEVICE_ETHERNET(device)); if (!hwaddr) continue; @@ -193,7 +303,7 @@ _nmc_get_device_by_hwaddr(NMClient *nmc, const char *hwaddr) if (!NM_IS_DEVICE_ETHERNET(device)) continue; - hwaddr_dev = nm_device_ethernet_get_permanent_hw_address(NM_DEVICE_ETHERNET(device)); + hwaddr_dev = _device_get_hwaddr(NM_DEVICE_ETHERNET(device)); if (!hwaddr_dev) continue; @@ -321,8 +431,9 @@ _nmc_mangle_connection(NMDevice *device, addrs_new = g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_address_unref); rules_new = g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_routing_rule_unref); - routes_new = g_ptr_array_new_full(config_data->iproutes_len + !!config_data->ipv4s_len, - (GDestroyNotify) nm_ip_route_unref); + routes_new = + g_ptr_array_new_full(nm_g_ptr_array_len(config_data->iproutes) + !!config_data->ipv4s_len, + (GDestroyNotify) nm_ip_route_unref); if (remote_s_ip) { guint len; @@ -428,8 +539,8 @@ _nmc_mangle_connection(NMDevice *device, } } - for (i = 0; i < config_data->iproutes_len; ++i) - g_ptr_array_add(routes_new, config_data->iproutes_arr[i]); + for (i = 0; i < nm_g_ptr_array_len(config_data->iproutes); i++) + g_ptr_array_add(routes_new, _nm_ip_route_ref(config_data->iproutes->pdata[i])); addrs_changed = nmcs_setting_ip_replace_ipv4_addresses(s_ip, (NMIPAddress **) addrs_new->pdata, @@ -644,7 +755,7 @@ main(int argc, const char *const *argv) gs_free_error GError *error = NULL; SigTermData sigterm_data; - _nm_logging_enabled_init(g_getenv(NMCS_ENV_VARIABLE("NM_CLOUD_SETUP_LOG"))); + _nm_logging_enabled_init(g_getenv(NMCS_ENV_NM_CLOUD_SETUP_LOG)); _LOGD("nm-cloud-setup %s starting...", NM_DIST_VERSION); @@ -662,7 +773,7 @@ main(int argc, const char *const *argv) }; sigterm_source = nm_g_unix_signal_add_source(SIGTERM, sigterm_handler, &sigterm_data); - provider = _provider_detect(sigterm_cancellable); + provider = _provider_detect(&sigterm_data); if (!provider) goto done; |