diff options
author | Michael Brown <mcb30@ipxe.org> | 2022-01-17 16:06:30 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2022-01-17 16:06:30 +0000 |
commit | 8e8c2188daddecc0a659bf4ed3eb8a503eb0b7ae (patch) | |
tree | d2865843766052671a0718445981d825d3e1b92e | |
parent | e814d33900992e034a8c3ddec2c65463c5206090 (diff) | |
download | ipxe-8e8c2188daddecc0a659bf4ed3eb8a503eb0b7ae.tar.gz |
[pxe] Allow cached DHCP settings to be fetched before registration
Register cached DHCP settings in a placeholder standalone settings
block, to allow settings to be fetched during early initialisation
code (before the startup code that registers them into the root
settings hierarchy).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/core/cachedhcp.c | 28 | ||||
-rw-r--r-- | src/core/settings.c | 4 | ||||
-rw-r--r-- | src/include/ipxe/cachedhcp.h | 3 |
3 files changed, 34 insertions, 1 deletions
diff --git a/src/core/cachedhcp.c b/src/core/cachedhcp.c index 2fa9b0c73..105201a57 100644 --- a/src/core/cachedhcp.c +++ b/src/core/cachedhcp.c @@ -67,8 +67,22 @@ static struct cached_dhcp_packet *cached_packets[] = { &cached_pxebs, }; +/** Cached DHCP settings placeholder block */ +struct generic_settings cachedhcp_generic = { + .settings = { + .refcnt = NULL, + .name = "cachedhcp", + .siblings = + LIST_HEAD_INIT ( cachedhcp_generic.settings.siblings ), + .children = + LIST_HEAD_INIT ( cachedhcp_generic.settings.children ), + .op = &generic_settings_operations, + }, + .list = LIST_HEAD_INIT ( cachedhcp_generic.list ), +}; + /** Colour for debug messages */ -#define colour &cached_dhcpack +#define colour &cachedhcp_settings /** * Free cached DHCP packet @@ -114,6 +128,9 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache, /* Select appropriate parent settings block */ settings = ( netdev ? netdev_settings ( netdev ) : NULL ); + /* Unregister from placeholder settings block */ + unregister_settings ( &cache->dhcppkt->settings ); + /* Register settings */ if ( ( rc = register_settings ( &cache->dhcppkt->settings, settings, cache->name ) ) != 0 ) { @@ -143,6 +160,7 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data, struct dhcphdr *dhcphdr; unsigned int i; size_t len; + int rc; /* Free any existing cached packet */ cachedhcp_free ( cache ); @@ -188,6 +206,14 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data, } } + /* Register in placeholder settings block */ + if ( ( rc = register_settings ( &dhcppkt->settings, &cachedhcp_settings, + cache->name ) ) != 0 ) { + DBGC ( colour, "CACHEDHCP %s could not register placeholder " + "settings: %s\n", cache->name, strerror ( rc ) ); + return rc; + } + /* Store as cached packet */ DBGC ( colour, "CACHEDHCP %s at %#08lx+%#zx/%#zx\n", cache->name, user_to_phys ( data, 0 ), len, max_len ); diff --git a/src/core/settings.c b/src/core/settings.c index fcdf98d2b..d81b2ffbf 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -526,6 +526,10 @@ void unregister_settings ( struct settings *settings ) { DBGC ( settings, "Settings %p (\"%s\") unregistered\n", settings, settings_name ( settings ) ); + /* Do nothing more if settings are already unregistered */ + if ( ! settings->parent ) + return; + /* Remove from list of settings */ ref_put ( settings->parent->refcnt ); settings->parent = NULL; diff --git a/src/include/ipxe/cachedhcp.h b/src/include/ipxe/cachedhcp.h index 39ce74543..7a48cfb62 100644 --- a/src/include/ipxe/cachedhcp.h +++ b/src/include/ipxe/cachedhcp.h @@ -17,6 +17,9 @@ struct cached_dhcp_packet; extern struct cached_dhcp_packet cached_dhcpack; extern struct cached_dhcp_packet cached_proxydhcp; extern struct cached_dhcp_packet cached_pxebs; +extern struct generic_settings cachedhcp_generic; + +#define cachedhcp_settings cachedhcp_generic.settings extern int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data, size_t max_len ); |