#2926 Issue closed: ERROR 420_autoresize_last_partitions.sh: line 73: 10: command not found

Labels: fixed / solved / done, minor bug

schlomo opened issue at 2023-02-13 19:35:

Context: Recovery of 8GB disk on 7.5GB disk, triggering automatic shrinking.

end of recovery output:

Comparing disks
Cannot check write protection by ID for /dev/sda (no ID found)
Device sda has size 8053063680 bytes but 8589934592 bytes is expected (needs manual configuration)
Switching to manual disk layout configuration (GiB sizes rounded down to integer)
/dev/sda had size 8589934592 (8 GiB) but is now 8053063680 (7 GiB)
Original disk /dev/sda does not exist (with same size) in the target system
Cannot check write protection by ID for /dev/sda (no ID found)
Using /dev/sda (the only available of the disks) for recreating /dev/sda
Current disk mapping table (source => target):
  /dev/sda => /dev/sda

Confirm or edit the disk mapping
1) Confirm disk mapping and continue 'rear recover'
2) Confirm identical disk mapping and proceed without manual configuration
3) Edit disk mapping (/var/lib/rear/layout/disk_mappings)
4) Use Relax-and-Recover shell and return back to here
5) Abort 'rear recover'
(default '1' timeout 300 seconds)
1
User confirmed disk mapping
Trying to automatically resize last partition when disk size changed
Last partition /dev/sda2 must be shrinked by 537902592 bytes to still fit on device
ERROR: Last partition /dev/sda2 cannot be shrinked (new device more than 2% smaller, see AUTOSHRINK_DISK_SIZE_LIMIT_PERCENTAGE)
Some latest log messages since the last called script 420_autoresize_last_partitions.sh:
  2023-02-13 19:21:15.705015961 Trying to automatically resize last partition when disk size changed
  2023-02-13 19:21:15.764584572 Last partition /dev/sda2 must be shrinked by 537902592 bytes to still fit on device
Some messages from /var/tmp/rear.BSY0Nr07uqIcQF5/tmp/rear.recover.stdout_stderr since the last called script 420_autoresize_last_partitions.sh:
  /usr/share/rear/layout/prepare/default/420_autoresize_last_partitions.sh: line 73: 10: command not found
  8589934592
  8053063680
  512
  9437184
  legacy_boot
  3623878656
  0
Use debug mode '-d' for some debug messages or debugscript mode '-D' for full debug messages with 'set -x' output
Aborting due to an error, check /var/log/rear/rear-rear-sle15sp4.log for details
Exiting rear recover (PID 3777) and its descendant processes ...
Running exit tasks
Terminated

Looking at the root cause I find in https://github.com/rear/rear/blob/master/usr/share/rear/layout/prepare/default/420_autoresize_last_partitions.sh#L73 the following:

# Avoid 'set -e -u' exit e.g. because of "AUTORESIZE_PARTITIONS[@]: unbound variable"
# note that assigning an empty array like AUTORESIZE_PARTITIONS=() does not help
# against array elements like AUTORESIZE_PARTITIONS[0] are unbound variables:
${AUTORESIZE_PARTITIONS:=}
${AUTORESIZE_EXCLUDE_PARTITIONS:=}
# Set fallbacks (same as default.conf) if mandatory numbers are not set (the user may set them empty):
${AUTOSHRINK_DISK_SIZE_LIMIT_PERCENTAGE:=2}
${AUTOINCREASE_DISK_SIZE_THRESHOLD_PERCENTAGE:=10}

# Skip if not in migration mode:
is_true "$MIGRATION_MODE" || return 0

that explains also the error message of line 73: 10: command not found which refers to ${AUTOINCREASE_DISK_SIZE_THRESHOLD_PERCENTAGE:=10} as that resolves to just a line with 10 in it.

The change happened in DEc 2021 by @jsmeix in https://github.com/rear/rear/commit/fd3a3bbf6b0ea7a57286b737159f310cd94414e8 and I'm wondering about these lines and they are supposed to do.

Maybe a simple : is missing in front of the lines, like this:

# Avoid 'set -e -u' exit e.g. because of "AUTORESIZE_PARTITIONS[@]: unbound variable"
# note that assigning an empty array like AUTORESIZE_PARTITIONS=() does not help
# against array elements like AUTORESIZE_PARTITIONS[0] are unbound variables:
: ${AUTORESIZE_PARTITIONS:=}
: ${AUTORESIZE_EXCLUDE_PARTITIONS:=}
# Set fallbacks (same as default.conf) if mandatory numbers are not set (the user may set them empty):
: ${AUTOSHRINK_DISK_SIZE_LIMIT_PERCENTAGE:=2}
: ${AUTOINCREASE_DISK_SIZE_THRESHOLD_PERCENTAGE:=10}

# Skip if not in migration mode:
is_true "$MIGRATION_MODE" || return 0

jsmeix commented at 2023-02-14 09:30:

Because that variables are set in default.conf
those assingments normally do nothing - except
evaluating to a nonsense command.

Sigh!
I should have tried that more carefully on command line
or have had a look how plain ':=' is done at other code places.

# AUTOSHRINK_DISK_SIZE_LIMIT_PERCENTAGE=""

# ${AUTOSHRINK_DISK_SIZE_LIMIT_PERCENTAGE:=2}
bash: 2: command not found

#  echo "'$AUTOSHRINK_DISK_SIZE_LIMIT_PERCENTAGE'"
'2'

But the intended assignment works nevertheless.
I think it works because when bash evaluates the command line
it first sets the variable to the value and
then it runs the resulting command which fails
but the variable has the new value nevertheless.

schlomo commented at 2023-02-14 09:33:

Yes, that is why I suggested to use : var=val as a "no-operation" command instead of echo. That way you'd see it in a debug log but not in a normal log.

schlomo commented at 2023-02-14 09:35:

BTW, IMHO we should avoid having commands in our scripts that are expected to fail as we otherwise will never gain the ability to enable hard error control via set -eu or such. It is also super confusing to find random strange output in the logs that is actually normal without an indication that it is not a problem.

jsmeix commented at 2023-02-14 09:37:

Of course I did not want to make a command that fails.
I try hard to not let things fail, cf.
https://github.com/rear/rear/wiki/Coding-Style
But I am a human - not a bot.

jsmeix commented at 2023-02-14 09:39:

Fixed by
https://github.com/rear/rear/commit/b20796b8c93f88a90cadca73d0fb84fe0d1e9ac5


[Export of Github issue for rear/rear.]