aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-01-17 16:06:30 +0000
committerMichael Brown <mcb30@ipxe.org>2022-01-17 16:06:30 +0000
commit8e8c2188daddecc0a659bf4ed3eb8a503eb0b7ae (patch)
treed2865843766052671a0718445981d825d3e1b92e
parente814d33900992e034a8c3ddec2c65463c5206090 (diff)
downloadipxe-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.c28
-rw-r--r--src/core/settings.c4
-rw-r--r--src/include/ipxe/cachedhcp.h3
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 );