public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: "Marek Behún" <kabel@kernel.org>
To: "Simon Glass" <sjg@chromium.org>, "Stefan Roese" <sr@denx.de>,
	"Pali Rohár" <pali@kernel.org>
Cc: u-boot@lists.denx.de, "Marek Behún" <marek.behun@nic.cz>
Subject: [PATCH 4/5] env: Add support for board specific special default environment
Date: Thu, 28 Oct 2021 05:28:09 +0200	[thread overview]
Message-ID: <20211028032810.18146-5-kabel@kernel.org> (raw)
In-Reply-To: <20211028032810.18146-1-kabel@kernel.org>

From: Marek Behún <marek.behun@nic.cz>

The default_environment[] buffer is built at compile time, but sometimes
it makes sense for some default environment variables to be determined
at runtime, for example:
- one board code may support different boards, and needs that
    fdtfile, board, board_name
  are set appropriately when command
    env default -a
  is executed
- some boards may want to prohibit the
    env default -a
  command to remove device MAC addresses stored in
    ethaddr, ethNaddr.
  This is the case for the ESPRESSObin board code, for example, where
  currently the board_late_init() function rewrites the default
  environment array to achieve this.

Add a new board specific function,

  const char *board_special_default_env(unsigned i, const char **name);

which returns the value of i-th board special default environemnt
variable, while storing it's name to *name.

Add default weak implementation of this functions returning NULL.

Add code to default environemnt handlers in env/common.c, which iterate
these special board default environment variables and get it's values in
precedence to values in the default_environment[] buffer.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
---
 env/common.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 96 insertions(+), 3 deletions(-)

diff --git a/env/common.c b/env/common.c
index 208e2adaa0..d157ca562a 100644
--- a/env/common.c
+++ b/env/common.c
@@ -148,6 +148,41 @@ char *from_env(const char *envvar)
 	return ret;
 }
 
+__weak const char *board_special_default_env(unsigned i, const char **name)
+{
+	return NULL;
+}
+
+static int board_special_default_env_get(const char *var, char *buf,
+					 unsigned len)
+{
+	int i;
+
+	/*
+	 * Iterate all board special default env variables, and if one
+	 * exists with the requested name, return it.
+	 */
+	for (i = 0; ; ++i) {
+		const char *name, *value;
+
+		value = board_special_default_env(i, &name);
+		if (!value)
+			break;
+
+		if (!strcmp(var, name)) {
+			unsigned res = strlen(value);
+
+			memcpy(buf, value, min(len, res + 1));
+			if (len <= res)
+				buf[len - 1] = '\0';
+
+			return res;
+		}
+	}
+
+	return -1;
+}
+
 static int env_get_from_linear(const char *env, const char *name, char *buf,
 			       unsigned len)
 {
@@ -157,6 +192,17 @@ static int env_get_from_linear(const char *env, const char *name, char *buf,
 	if (name == NULL || *name == '\0')
 		return -1;
 
+	if (env == default_environment) {
+		int res = board_special_default_env_get(name, buf, len);
+
+		/*
+		 * Board special default envs take precedence over the
+		 * default_environment[] array.
+		 */
+		if (res >= 0)
+			return res;
+	}
+
 	name_len = strlen(name);
 
 	for (p = env; *p != '\0'; p = end + 1) {
@@ -248,6 +294,41 @@ char *env_get_default(const char *name)
 	return NULL;
 }
 
+static int import_board_special_default_envs(bool all, int nvars,
+					     char * const vars[], int flags)
+{
+	int i;
+
+	for (i = 0; ; ++i) {
+		const char *name, *value;
+		struct env_entry e, *ep;
+
+		value = board_special_default_env(i, &name);
+		if (!value)
+			break;
+
+		if (!all) {
+			int j;
+
+			/* If name is not in vars, skip */
+
+			for (j = 0; j < nvars; ++j)
+				if (!strcmp(name, vars[j]))
+					break;
+			if (j == nvars)
+				continue;
+		}
+
+		e.key = name;
+		e.data = (char *)value;
+
+		if (!hsearch_r(e, ENV_ENTER, &ep, &env_htab, flags))
+			return -1;
+	}
+
+	return 0;
+}
+
 void env_set_default(const char *s, int flags)
 {
 	if (s) {
@@ -270,6 +351,12 @@ void env_set_default(const char *s, int flags)
 		return;
 	}
 
+	if (import_board_special_default_envs(true, 0, NULL, flags) < 0) {
+		pr_err("## Error: Board special default environment import failed: errno = %d\n",
+		       errno);
+		return;
+	}
+
 	gd->flags |= GD_FLG_ENV_READY;
 	gd->flags |= GD_FLG_ENV_DEFAULT;
 }
@@ -278,14 +365,20 @@ void env_set_default(const char *s, int flags)
 /* [re]set individual variables to their value in the default environment */
 int env_set_default_vars(int nvars, char * const vars[], int flags)
 {
+	int res;
+
 	/*
 	 * Special use-case: import from default environment
 	 * (and use \0 as a separator)
 	 */
 	flags |= H_NOCLEAR | H_DEFAULT;
-	return himport_r(&env_htab, default_environment,
-				sizeof(default_environment), '\0',
-				flags, 0, nvars, vars);
+	res = himport_r(&env_htab, default_environment,
+			sizeof(default_environment), '\0', flags, 0, nvars,
+			vars);
+	if (!res)
+		return res;
+
+	return import_board_special_default_envs(false, nvars, vars, flags);
 }
 
 /*
-- 
2.32.0


  parent reply	other threads:[~2021-10-28  3:29 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-28  3:28 [PATCH 0/5] Board specific runtime determined default env Marek Behún
2021-10-28  3:28 ` [PATCH 1/5] env: Don't set ready flag if import failed in env_set_default() Marek Behún
2021-10-29  3:17   ` Simon Glass
2021-10-28  3:28 ` [PATCH 2/5] env: Fix env_get() when returning empty string using env_get_f() Marek Behún
2021-10-29  3:17   ` Simon Glass
2021-10-29  8:51     ` Marek Behún
2021-10-29  9:03     ` Pali Rohár
2021-10-31 13:07       ` Simon Glass
2021-10-31 15:27         ` Marek Behún
2021-10-28  3:28 ` [PATCH 3/5] env: Simplify env_get_default() Marek Behún
2021-10-29  3:17   ` Simon Glass
2021-10-28  3:28 ` Marek Behún [this message]
2021-10-29  3:17   ` [PATCH 4/5] env: Add support for board specific special default environment Simon Glass
2021-10-29  8:57     ` Marek Behún
2021-10-31 13:07       ` Simon Glass
2021-10-28  3:28 ` [PATCH 5/5] arm: mvebu: Espressobin: Use new API for setting default env at runtime Marek Behún
2021-10-29  3:17   ` Simon Glass
2021-10-31 20:15   ` Pali Rohár
2021-11-02 14:57     ` Simon Glass
2021-11-03 10:48       ` Pali Rohár
2021-10-29  3:17 ` [PATCH 0/5] Board specific runtime determined default env Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211028032810.18146-5-kabel@kernel.org \
    --to=kabel@kernel.org \
    --cc=marek.behun@nic.cz \
    --cc=pali@kernel.org \
    --cc=sjg@chromium.org \
    --cc=sr@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox