Hiccup/oversight in mkinitrd
by JayByrd from LinuxQuestions.org on (#5NES7)
Recently, while building up another BOINC crunching rig, I discovered something peculiar in the Slackware boot process.
This system is an old laptop with a faulty internal harddrive, so I installed Slackware to a USB pen drive. When I would try to boot the new install, it would drop me to an emergency shell, saying the root device didn't exist. Checking the logs, I soon realized that init was trying to mount the root file system before the root device had been enumerated. Easy enough fix: I just added "-w 2" to my mkinitrd command line.
However, this got me curious, so I delved into the mkinitrd script itself and found this:
Code:# If $WAIT is not set, assume we need only one second
# to have all devices done
# (unless we find that value is already set in the initrd-tree):
if [ -z "$WAIT" -a -z "$(cat $SOURCE_TREE/wait-for-root)" ]; then
WAIT=1
# ARM devices need even more time:
case "$( uname -m )" in
arm*) WAIT=4;;
esac
fi
if [ ! -z "$WAIT" ]; then
echo $WAIT > $SOURCE_TREE/wait-for-root
fiUnfortunately, this test for ARM-ness never gets run. When extracting the skeleton initrd-tree, rootdev and rootfs are empty files (0 bytes,) but wait-for-root contains a "1". Thus, testing "-z $SOURCE_TREE/wait-for-root" always fails, so the body of that block is never entered.
The only way I can see for the ARM-test to actually run would be to run mkinitrd once to extract the skeleton initrd-tree, manually empty/null the wait-for-root file, and then run mkinitrd again without the "-c" option. (Also note that the second if-statement applies only if "-w" is specified on the command line. Otherwise, $WAIT is always empty.)
Simple solution: make wait-for-root an empty file in the skeleton tree, like rootfs, etc. Then the test for ARM-ness will actually run.
However, this does make it so that the second if-block above will always override the wait-for-root value, even in the case where there is a preexisting initrd-tree with a non-empty wait-for-root. So, in addition to making wait-for-root a null file in the skeleton tree, I suggest the following change to the above mkinitrd code:
Code:if [ -z "$WAIT" ]; then
PRESET_WAIT="$(cat $SOURCE_TREE/wait-for-root)"
if [ -n "$PRESET_WAIT" ]; then
WAIT="$PRESET_WAIT"
else
case "$( uname -m )" in
arm*) WAIT=4;;
*) WAIT=1;;
esac
fi
fi
if [ ! -z "$WAIT" ]; then
echo $WAIT > $SOURCE_TREE/wait-for-root
fiThis change preserves the intended order of priority:
1st priority: "-w" on the command line
2nd priority: preexisting value in wait-for-root
3rd priority: default to 1 or 4
(I suppose at this point you could also drop that final if-statement before the echo, because now $WAIT should never be empty by this point in the script.)
(note: this diagnosis applies at least to 14.1, 14.2, and the last time I checked it in current a few weeks ago...)


This system is an old laptop with a faulty internal harddrive, so I installed Slackware to a USB pen drive. When I would try to boot the new install, it would drop me to an emergency shell, saying the root device didn't exist. Checking the logs, I soon realized that init was trying to mount the root file system before the root device had been enumerated. Easy enough fix: I just added "-w 2" to my mkinitrd command line.
However, this got me curious, so I delved into the mkinitrd script itself and found this:
Code:# If $WAIT is not set, assume we need only one second
# to have all devices done
# (unless we find that value is already set in the initrd-tree):
if [ -z "$WAIT" -a -z "$(cat $SOURCE_TREE/wait-for-root)" ]; then
WAIT=1
# ARM devices need even more time:
case "$( uname -m )" in
arm*) WAIT=4;;
esac
fi
if [ ! -z "$WAIT" ]; then
echo $WAIT > $SOURCE_TREE/wait-for-root
fiUnfortunately, this test for ARM-ness never gets run. When extracting the skeleton initrd-tree, rootdev and rootfs are empty files (0 bytes,) but wait-for-root contains a "1". Thus, testing "-z $SOURCE_TREE/wait-for-root" always fails, so the body of that block is never entered.
The only way I can see for the ARM-test to actually run would be to run mkinitrd once to extract the skeleton initrd-tree, manually empty/null the wait-for-root file, and then run mkinitrd again without the "-c" option. (Also note that the second if-statement applies only if "-w" is specified on the command line. Otherwise, $WAIT is always empty.)
Simple solution: make wait-for-root an empty file in the skeleton tree, like rootfs, etc. Then the test for ARM-ness will actually run.
However, this does make it so that the second if-block above will always override the wait-for-root value, even in the case where there is a preexisting initrd-tree with a non-empty wait-for-root. So, in addition to making wait-for-root a null file in the skeleton tree, I suggest the following change to the above mkinitrd code:
Code:if [ -z "$WAIT" ]; then
PRESET_WAIT="$(cat $SOURCE_TREE/wait-for-root)"
if [ -n "$PRESET_WAIT" ]; then
WAIT="$PRESET_WAIT"
else
case "$( uname -m )" in
arm*) WAIT=4;;
*) WAIT=1;;
esac
fi
fi
if [ ! -z "$WAIT" ]; then
echo $WAIT > $SOURCE_TREE/wait-for-root
fiThis change preserves the intended order of priority:
1st priority: "-w" on the command line
2nd priority: preexisting value in wait-for-root
3rd priority: default to 1 or 4
(I suppose at this point you could also drop that final if-statement before the echo, because now $WAIT should never be empty by this point in the script.)
(note: this diagnosis applies at least to 14.1, 14.2, and the last time I checked it in current a few weeks ago...)