[U-Boot] is there any issue with creating and using more than one hashtable?

Wolfgang Denk wd at denx.de
Sat Oct 1 10:13:31 CEST 2016


Dear Robert,

In message <alpine.LFD.2.20.1609301101260.11297 at localhost.localdomain> you wrote:
> 
>   in misc_init_r(), i create a new hashtable to just grab the contents
> of that bootline as is. i then create a *second* hashtable and
> selectively move over just those keys i want from the first hashtable,
> possibly renaming them in the process.

I'm not sure how you implemented this "move over" thing...

> now here's the thing ... after all that, i manually check whether the
> CRC for the env table in persistent storage is valid and, if it is, i
> do *nothing* with all that hashtable content -- that was all wasted
> cycles, but it should not do any harm.
> 
>   but it does, because this is what happens:
> 
>   TFTP from server 10.35.5.37; our IP address is 192.168.1.2; sending
>   through gateway 192.168.1.1
> 
> the server address is correct, but the IP address and gateway are
> totally wrong -- they should have been untouched and been completely
> different values; instead, they now equal the values in that second
> hashtable, which i chose to do nothing with.

For a test, I would like to ask you to run the following commands
beofre the TFTP command:

	printenv serverip;setenv serverip ${serverip};printenv serverip
	printenv ipaddr;setenv ipaddr ${ipaddr};printenv ipaddr
	printenv gatewayip;setenv gatewayip ${gatewayip};printenv gatewayip

Does this change anything?

>   is there some weird issue with re-entrancy here? if i print "ipaddr"
> and "gatewayip", they seem correct. if i "md" the environment in
> persistent storage, again, they seem correct. and yet, when TFTP kicks
> in, it seems to pick up the values from that hashtable.

Actually the TFTP will not access the environment directly to determine the
boot  parameters like bootfile, ipaddr, gatewayip, netmask, serverip,
etc.; instead, it uses internal variables.  So your environment
settings for "ipaddr" and "gatewayip" may contain totally different
values than the variables  net_ip  resp.  net_gateway  which get used
by the TFTP code.

These variables get set through the U_BOOT_ENV_CALLBACK functionality,
i. e. as a callback whenever the corresponfing variable gets set.
"setting" here means that the value in the hash table gets changed -
see function _compare_and_overwrite_entry() in "hashtable.c":

244                         /* If there is a callback, call it */
245                         if (htab->table[idx].entry.callback &&
246                             htab->table[idx].entry.callback(item.key,
247                             item.data, env_op_overwrite, flag)) {
248                                 debug("callback() rejected setting variable "
249                                         "%s, skipping it!\n", item.key);
250                                 __set_errno(EINVAL);
251                                 *retval = NULL;
252                                 return 0;
253                         }


So when you insert variable sof these registered names into your
alternative hash table using the common code, then the respective
callbacks will fire in the same way as if you had changed the
environment settings through a setenv command.


It is obvious that the U-Boot design did not anticipate a situation
where an alternative hash table with different settings would be
created.

A quick but ugly workaround could be to re-set the variables to the
values stored in the environment by running something like

	setenv ipaddr ${ipaddr}

etc.


Hope this helps.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Do not simplify the design of a program if a way can be found to make
it complex and wonderful.


More information about the U-Boot mailing list