[U-Boot] [PATCH 2/2] env: Fix saving environment to "bad CRC" location

Simon Goldschmidt simon.k.r.goldschmidt at gmail.com
Mon Jan 21 09:18:32 UTC 2019


Am 19.01.2019 um 14:28 schrieb Sam Protsenko:
> Hi Simon,
> 
> On Fri, Jan 18, 2019 at 10:46 PM Simon Goldschmidt
> <simon.k.r.goldschmidt at gmail.com> wrote:
>>
>>
>>
>> Am Fr., 18. Jan. 2019, 20:20 hat Sam Protsenko <semen.protsenko at linaro.org> geschrieben:
>>>
>>> In case when the environment on some location is malformed (CRC isn't
>>> matching), there is a chance we won't be able to save the environment to
>>> that location. For example, consider the case when we only have the
>>> environment on eMMC, but it's zeroed out. In that case, we won't be able
>>> to "env save" to it, because of "bad CRC" error. That's happening
>>> because in env_load() function we consider malformed environment as
>>> incorrect one, and  defaulting to the location with highest (0)
>>> priority, which can be different from one we are dealing with right now
>>> (e.g., highest priority can be ENV_FAT on SD card, which is not
>>> inserted, but we want to use ENV_MMC on eMMC, where we were booted
>>> from).
>>>
>>> This issue began to reproduce after commit d30ba2315ae3 ("u-boot: remove
>>> driver lookup loop from env_save()") on BeagleBone Black, but that
>>> commit didn't introduce the wrong logic, it just changed the behavior
>>> for default location to use, merely revealing this issue.
>>
>>
>> In my opinion, this automatism of selecting a driver to save the env can always produce a behaviour that is unexpected to the user.
>>
> 
> Completely agree with you. That's my thoughts exactly, when I ran into
> this issue.
> 
>> I wonder if it wouldn't be better to either let the board define some default env driver for saving or the user should specify the driver as argument to 'env save'.
>>
> 
> Yeah, if I have some spare time, gonna implement something like this,
> at least as RFC patch. We can start full-scale discussion in that
> thread, as there could be more possible ways of fixing that, and we
> should consider different platforms when deciding on that. But I think
> we should take this patch anyway, as "env save" without arguments
> should be left too, for compatibility reasons.
> 
>> Note that this is not an objection to your oatches, I'm just not content with the current auto-selection...
>>
> 
> Yeah, but that's another matter, I hope I will get to that soon.
> Meanwhile, can you please add your "Reviewed-by" tag, if the code
> looks ok to you? With this patch we won't have semi-bricked boards, at
> least.

Well, I don't know if that's another matter. This multi-env code is 
pretty new, and it seems to me it hasn't fully worked, yet, for corner 
cases. Being like that, I'm not totally sure your change is OK for 
everyone using more than one env source. What if the first device 
returning an error code was an unexpected error? You'll then save your 
environment to some other storage without noticing... Is that expected 
behaviour for multi-env support? Or shouldn't we rather return an error 
and let the user supply the target device instead?

I just fear your change might break things for others.

I'm not saying your patch is totally wrong, just thinking. I did use 
multi-env support, but never checked error paths back then...

Regards,
Simon

> 
>> Regards,
>> Simon
>>
>>>
>>> To fix that, let's implement next logic in env_load():
>>>    1. Try to find out correct environment; if found -- use it
>>>    2. If working environment wasn't found, but we found malformed one
>>>       (with bad CRC), let's use it for further "env save". But make sure
>>>       to use malformed environment location with highest priority.
>>>    3. If neither correct nor malformed environment was found, let's
>>>       default to environment location with highest priority (0)
>>>
>>> Steps to reproduce mentioned issue on BeagleBone Black (fixed in this
>>> patch):
>>>
>>> 1. Boot from SD card and erase eMMC in U-Boot shell:
>>>     => mmc dev 1
>>>     => mmc erase 0 100000
>>>     => gpt write mmc 1 $partitions
>>> 2. Write new SPL and U-Boot to eMMC; the rest of eMMC will stay filled
>>>     with zeroes
>>> 3. Boot from eMMC; try to do:
>>>     => env save
>>> 4. Observe the error (incorrect behavior). Correct behavior: environment
>>>     should be stored correctly on eMMC, in spite of it has "bad CRC"
>>>
>>> Fixes: d30ba2315ae3 ("u-boot: remove driver lookup loop from env_save()")
>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>> ---
>>>   env/env.c | 25 +++++++++++++++++++------
>>>   1 file changed, 19 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/env/env.c b/env/env.c
>>> index 003509d342..4b417b90a2 100644
>>> --- a/env/env.c
>>> +++ b/env/env.c
>>> @@ -177,6 +177,7 @@ int env_get_char(int index)
>>>   int env_load(void)
>>>   {
>>>          struct env_driver *drv;
>>> +       int best_prio = -1;
>>>          int prio;
>>>
>>>          for (prio = 0; (drv = env_driver_lookup(ENVOP_LOAD, prio)); prio++) {
>>> @@ -195,20 +196,32 @@ int env_load(void)
>>>                   * one message.
>>>                   */
>>>                  ret = drv->load();
>>> -               if (ret) {
>>> -                       debug("Failed (%d)\n", ret);
>>> -               } else {
>>> +               if (!ret) {
>>>                          printf("OK\n");
>>>                          return 0;
>>> +               } else if (ret == -ENOMSG) {
>>> +                       /* Handle "bad CRC" case */
>>> +                       if (best_prio == -1)
>>> +                               best_prio = prio;
>>> +               } else {
>>> +                       debug("Failed (%d)\n", ret);
>>>                  }
>>>          }
>>>
>>>          /*
>>>           * In case of invalid environment, we set the 'default' env location
>>> -        * to the highest priority. In this way, next calls to env_save()
>>> -        * will restore the environment at the right place.
>>> +        * to the best choice, i.e.:
>>> +        *   1. Environment location with bad CRC, if such location was found
>>> +        *   2. Otherwise use the location with highest priority
>>> +        *
>>> +        * This way, next calls to env_save() will restore the environment
>>> +        * at the right place.
>>>           */
>>> -       env_get_location(ENVOP_LOAD, 0);
>>> +       if (best_prio >= 0)
>>> +               debug("Selecting environment with bad CRC\n");
>>> +       else
>>> +               best_prio = 0;
>>> +       env_get_location(ENVOP_LOAD, best_prio);
>>>
>>>          return -ENODEV;
>>>   }
>>> --
>>> 2.20.1
>>>
>>> _______________________________________________
>>> U-Boot mailing list
>>> U-Boot at lists.denx.de
>>> https://lists.denx.de/listinfo/u-boot



More information about the U-Boot mailing list