diff options
author | Thomas Haller <thaller@redhat.com> | 2022-04-29 10:19:54 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-05-05 08:29:53 +0200 |
commit | 1e696c7e93c14bc2ea7bfdcf4a655621ceb4e862 (patch) | |
tree | 4c9806a725ec28e92f1d34158712ba7cf9b9d168 | |
parent | 069946cda14b2465d1eb5434402609fcd96f35ba (diff) | |
download | NetworkManager-1e696c7e93c14bc2ea7bfdcf4a655621ceb4e862.tar.gz |
cloud-setup: use union for NMCSProviderGetConfigIfaceData.priv
Use a union, it makes more sense.
Note that with union, C's struct initialization might not sufficiently
set all fields to the default. In practice yes, but theoretically in C
a NULL pointer and floats must not have all zero bits, so the following
is not guaranteed to work:
struct {
int some_field;
union {
void *v_ptr;
int v_int;
};
} variable = {
.some_field = 24,
};
assert(variable.union.v_ptr == 0);
assert(variable.union.v_int == 0);
When initializing the variable, we should not rely on automatically
initialize all union members correctly. It cannot at the same time
set NULL pointers and zero integers -- well, on our architectures it
probably can, but not as far as guaranteed by C language.
We need to know which union field we are going to use and initialize
it explicitly.
As we know the provider type, we can do that.
Also, maybe in the future we need special free/unref calls when
destroying the type specific data in NMCSProviderGetConfigIfaceData.
As we know the provider, we can.
Note that having type specific data in NMCSProviderGetConfigIfaceData.priv
is a layering violation. But it is still simpler than implementing
type specific handlers (callbacks) or tracking the data somewhere else.
After all, we know at compile time all the existing provider types.
-rw-r--r-- | src/nm-cloud-setup/nmcs-provider.c | 11 | ||||
-rw-r--r-- | src/nm-cloud-setup/nmcs-provider.h | 9 |
2 files changed, 19 insertions, 1 deletions
diff --git a/src/nm-cloud-setup/nmcs-provider.c b/src/nm-cloud-setup/nmcs-provider.c index a519ef9b5e..fd9a61b813 100644 --- a/src/nm-cloud-setup/nmcs-provider.c +++ b/src/nm-cloud-setup/nmcs-provider.c @@ -192,6 +192,17 @@ nmcs_provider_get_config_iface_data_create(NMCSProviderGetConfigTaskData *get_co .was_requested = was_requested, }; + /* "priv" is a union, and according to C, it might not be properly initialized + * that all union members are set to false/0/NULL/0.0. We need to know which + * union field we are going to use, and that depends on the type of "self". + * Also, knowing the type would allow us to initialize to something other than + * false/0/NULL/0.0. */ + if (G_OBJECT_TYPE(get_config_data->self) == nmcs_provider_aliyun_get_type()) { + iface_data->priv.aliyun = (typeof(iface_data->priv.aliyun)){ + .has_primary_ip_address = FALSE, + }; + } + /* the has does not own the key (iface_datta->hwaddr), the lifetime of the * key is associated with the iface_data instance. */ g_hash_table_replace(get_config_data->result_dict, (char *) iface_data->hwaddr, iface_data); diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h index d1ab0a33c2..502f1d0323 100644 --- a/src/nm-cloud-setup/nmcs-provider.h +++ b/src/nm-cloud-setup/nmcs-provider.h @@ -45,7 +45,7 @@ typedef struct { * the implementations. However, it's convenient to track implementation specific data * here, thus we violate such separation. In practice, all subclasses are known * at compile time, and it will be simpler this way. */ - struct { + union { struct { in_addr_t primary_ip_address; bool has_primary_ip_address : 1; @@ -191,4 +191,11 @@ void nmcs_provider_get_config(NMCSProvider *provider, NMCSProviderGetConfigResult * nmcs_provider_get_config_finish(NMCSProvider *provider, GAsyncResult *result, GError **error); +/*****************************************************************************/ + +/* Forward declare the implemented gtype getters so we can use it at a few places without requiring + * to include the full header. The other parts of those headers should not be used aside where they + * are necessary. */ +GType nmcs_provider_aliyun_get_type(void); + #endif /* __NMCS_PROVIDER_H__ */ |