Files
Rasmus VillemoesandTom Rini 4cb0bd4702 bootretry: only reinitialize retry_time when bootretry env variable has been touched
Commit aa5ef3c0a7 ("bootretry: check for bootretry variable changes")
broke the feature where one can define different keys for "delaying"
versus "stopping" boot. The way the latter is implemented is by the code
in autoboot.c calling bootretry_dont_retry() when the stop sequence
has been detected, and that simply sets the retry_time variable in
bootretry.c to -1.

However, with the mentioned commit, that is unconditionally overridden
on every command, since it gets re-initialized from either the
bootretry environment variable or CONFIG_BOOT_RETRY_TIME, thus making
"delay" and "stop" effectively the same.

To fix that, while still picking up changes to the bootretry
environment variable, use the proper mechanism for C code to be
notified about changes to environment variables.

Since the callback is invoked before the change has actually been done
to the environment (callbacks can reject the change from taking
effect), we cannot simply call the existing
bootretry_init_cmd_timeout() from the callback, as its env_get() would
not see the new value. Instead, refactor most of it to an internal
bootretry_parse(), and call that with the new value (which is NULL in
the case bootretry is being deleted, so that works exactly as it
should).

Signed-off-by: Rasmus Villemoes <ravi@prevas.dk>
2026-08-10 14:47:50 -06:00

106 lines
2.1 KiB
C

/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2012
* Joe Hershberger, National Instruments, joe.hershberger@ni.com
*/
#ifndef __ENV_CALLBACK_H__
#define __ENV_CALLBACK_H__
#include <config.h>
#include <env_flags.h>
#include <linker_lists.h>
#include <search.h>
#define ENV_CALLBACK_VAR ".callbacks"
#ifdef CONFIG_SILENT_CONSOLE
#define SILENT_CALLBACK "silent:silent,"
#else
#define SILENT_CALLBACK
#endif
#ifdef CONFIG_REGEX
#define ENV_DOT_ESCAPE "\\"
#else
#define ENV_DOT_ESCAPE
#endif
#ifdef CONFIG_CMD_DNS
#define DNS_CALLBACK "dnsip:dnsip,"
#else
#define DNS_CALLBACK
#endif
#if CONFIG_IS_ENABLED(NET)
#define NET_CALLBACKS \
"bootfile:bootfile," \
"ipaddr:ipaddr," \
"gatewayip:gatewayip," \
"netmask:netmask," \
"serverip:serverip," \
"nvlan:nvlan," \
"vlan:vlan," \
DNS_CALLBACK \
"eth" ETHADDR_WILDCARD "addr:ethaddr,"
#else
#define NET_CALLBACKS
#endif
#ifdef CONFIG_IPV6
#define NET6_CALLBACKS \
"ip6addr:ip6addr," \
"serverip6:serverip6," \
"gatewayip6:gatewayip6,"
#else
#define NET6_CALLBACKS
#endif
#ifdef CONFIG_BOOTSTD_FULL
#define BOOTSTD_CALLBACK \
"bootmeths:bootmeths," \
"bootargs:bootargs,"
#else
#define BOOTSTD_CALLBACK
#endif
#ifdef CONFIG_DFU
#define DFU_CALLBACK "dfu_alt_info:dfu_alt_info,"
#else
#define DFU_CALLBACK
#endif
#ifdef CONFIG_BOOT_RETRY
#define BOOTRETRY_CALLBACK "bootretry:bootretry,"
#else
#define BOOTRETRY_CALLBACK
#endif
/*
* This list of callback bindings is static, but may be overridden by defining
* a new association in the ".callbacks" environment variable.
*/
#define ENV_CALLBACK_LIST_STATIC ENV_DOT_ESCAPE ENV_CALLBACK_VAR ":callbacks," \
ENV_DOT_ESCAPE ENV_FLAGS_VAR ":flags," \
"baudrate:baudrate," \
NET_CALLBACKS \
NET6_CALLBACKS \
BOOTSTD_CALLBACK \
DFU_CALLBACK \
BOOTRETRY_CALLBACK \
"loadaddr:loadaddr," \
SILENT_CALLBACK \
"stdin:console,stdout:console,stderr:console," \
"serial#:serialno," \
CONFIG_ENV_CALLBACK_LIST_STATIC
#ifndef CONFIG_XPL_BUILD
void env_callback_init(struct env_entry *var_entry);
#else
static inline void env_callback_init(struct env_entry *var_entry)
{
}
#endif
#endif /* __ENV_CALLBACK_H__ */