summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-07-29 16:11:36 +0200
committerThomas Haller <thaller@redhat.com>2020-07-29 17:29:14 +0200
commit93e1b82e183fccab006fdd181bfc54f5e2e14cc3 (patch)
treeefe7d5d088f83b03fb5424bb166a4b940b629fca
parent70db0fa735c9169b83b6ee7721109cec7c41831c (diff)
downloadNetworkManager-th/cloud-setup-error-handling.tar.gz
cloud-setup: rework error handling and completion for EC2 providerth/cloud-setup-error-handling
Make the error handling similar to the other provider implementations. - only actually return once all callbacks completed. - cache the first error and report it.
-rw-r--r--clients/cloud-setup/nmcs-provider-ec2.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/clients/cloud-setup/nmcs-provider-ec2.c b/clients/cloud-setup/nmcs-provider-ec2.c
index 1578a33bed..3439a1680c 100644
--- a/clients/cloud-setup/nmcs-provider-ec2.c
+++ b/clients/cloud-setup/nmcs-provider-ec2.c
@@ -141,30 +141,43 @@ detect (NMCSProvider *provider,
typedef struct {
NMCSProviderGetConfigTaskData *get_config_data;
+ GError *error;
GCancellable *cancellable;
gulong cancelled_id;
guint n_pending;
} GetConfigIfaceData;
static void
-_get_config_task_return (GetConfigIfaceData *iface_data,
- GError *error_take)
+_get_config_task_maybe_return (GetConfigIfaceData *iface_data,
+ GError *error_take)
{
NMCSProviderGetConfigTaskData *get_config_data = iface_data->get_config_data;
+ if (error_take) {
+ if (!iface_data->error)
+ iface_data->error = error_take;
+ else if ( !nm_utils_error_is_cancelled (iface_data->error)
+ && nm_utils_error_is_cancelled (error_take)) {
+ nm_clear_error (&iface_data->error);
+ iface_data->error = error_take;
+ } else
+ g_error_free (error_take);
+ }
+
+ if (iface_data->n_pending > 0)
+ return;
+
nm_clear_g_cancellable_disconnect (g_task_get_cancellable (get_config_data->task),
&iface_data->cancelled_id);
nm_clear_g_cancellable (&iface_data->cancellable);
- nm_g_slice_free (iface_data);
-
- if (error_take) {
- if (nm_utils_error_is_cancelled (error_take))
+ if (iface_data->error) {
+ if (nm_utils_error_is_cancelled (iface_data->error))
_LOGD ("get-config: cancelled");
else
- _LOGD ("get-config: failed: %s", error_take->message);
- g_task_return_error (get_config_data->task, error_take);
+ _LOGD ("get-config: failed: %s", iface_data->error->message);
+ g_task_return_error (get_config_data->task, g_steal_pointer (&iface_data->error));
} else {
_LOGD ("get-config: success");
g_task_return_pointer (get_config_data->task,
@@ -172,6 +185,7 @@ _get_config_task_return (GetConfigIfaceData *iface_data,
(GDestroyNotify) g_hash_table_unref);
}
+ nm_g_slice_free (iface_data);
g_object_unref (get_config_data->task);
}
@@ -194,9 +208,6 @@ _get_config_fetch_done_cb (NMHttpClient *http_client,
&response_data,
&error);
- if (nm_utils_error_is_cancelled (error))
- return;
-
if (!error) {
NMCSProviderGetConfigIfaceData *config_iface_data;
in_addr_t tmp_addr;
@@ -240,10 +251,8 @@ _get_config_fetch_done_cb (NMHttpClient *http_client,
}
}
- if (--iface_data->n_pending > 0)
- return;
-
- _get_config_task_return (iface_data, NULL);
+ iface_data->n_pending--;
+ _get_config_task_maybe_return (iface_data, g_steal_pointer (&error));
}
static void
@@ -272,8 +281,8 @@ _get_config_fetch_cancelled_cb (GObject *object, gpointer user_data)
nm_clear_g_signal_handler (g_task_get_cancellable (iface_data->get_config_data->task),
&iface_data->cancelled_id);
- _get_config_task_return (iface_data,
- nm_utils_error_new_cancelled (FALSE, NULL));
+ _get_config_task_maybe_return (iface_data,
+ nm_utils_error_new_cancelled (FALSE, NULL));
}
typedef struct {
@@ -317,16 +326,16 @@ _get_config_metadata_ready_cb (GObject *source,
};
if (nm_utils_error_is_cancelled (error)) {
- _get_config_task_return (iface_data, g_steal_pointer (&error));
+ _get_config_task_maybe_return (iface_data, g_steal_pointer (&error));
return;
}
/* We ignore errors. Only if we got no response at all, it's a problem.
* Otherwise, we proceed with whatever we could fetch. */
if (!response_parsed) {
- _get_config_task_return (iface_data,
- nm_utils_error_new (NM_UTILS_ERROR_UNKNOWN,
- "meta data for interfaces not found"));
+ _get_config_task_maybe_return (iface_data,
+ nm_utils_error_new (NM_UTILS_ERROR_UNKNOWN,
+ "meta data for interfaces not found"));
return;
}
@@ -339,8 +348,8 @@ _get_config_metadata_ready_cb (GObject *source,
iface_data,
NULL);
if (cancelled_id == 0) {
- _get_config_task_return (iface_data,
- nm_utils_error_new_cancelled (FALSE, NULL));
+ _get_config_task_maybe_return (iface_data,
+ nm_utils_error_new_cancelled (FALSE, NULL));
return;
}
@@ -411,8 +420,7 @@ _get_config_metadata_ready_cb (GObject *source,
nm_utils_user_data_pack (iface_data, hwaddr));
}
- if (iface_data->n_pending == 0)
- _get_config_task_return (iface_data, NULL);
+ _get_config_task_maybe_return (iface_data, NULL);
}
static gboolean