System Partition Integrity Check Failure

While reviewing the boot process output of the WD My Cloud PR4100, I noticed something which didn’t seem right. The full boot process output can only be seen while connected to the UART port via a serial console.

initramfs: checking integrity of system partitions (/dev/mmcb)

Having become quite familiar with the hardware of the PR4100, I was reasonably certain that the /dev/mmcb device didn’t exist, so I located the code behind the message to see what was going on. The code is contained within the uRamdisk initial ramdisk file. Specifically, it’s located within the /etc/rc.sh script, which is executed every time the system boots.

Original Code:

echo -n "initramfs: checking integrity of system partitions "
ucpd="$(blkid | grep 'wdnas_efi' | awk -F: '{ print $1}')"
ucpd="${ucpd:0:9}"
echo "($ucpd)"
# 1st: vfat EFI
if stat "${ucpd}1" >/dev/null 2>&1; then
	dosfsck -p ${ucpd}1 2>/dev/null
else
	echo "initramfs: cannot find devnode: ${ucpd}1"
fi
# all others ext4
for i in $(seq 2 9); do
	if stat "${ucpd}$i" >/dev/null 2>&1; then
	  if [ "$i" = "6" ] || [ "$i" = "9" ]; then
	    e2fsck -p "${ucpd}$i" 2>/dev/null || e2fsck -f -y "${ucpd}$i"
	  else
		  e2fsck -p "${ucpd}$i" 2>/dev/null
	  fi
	else
		echo "initramfs: cannot find devnode: ${ucpd}$i"
	fi
done

Original Code Output:

initramfs: checking integrity of system partitions (/dev/mmcb)
initramfs: cannot find devnode: /dev/mmcb1
initramfs: cannot find devnode: /dev/mmcb2
initramfs: cannot find devnode: /dev/mmcb3
initramfs: cannot find devnode: /dev/mmcb4
initramfs: cannot find devnode: /dev/mmcb5
initramfs: cannot find devnode: /dev/mmcb6
initramfs: cannot find devnode: /dev/mmcb7
initramfs: cannot find devnode: /dev/mmcb8
initramfs: cannot find devnode: /dev/mmcb9

As it turns out, the programmers had made a very simple mistake, which caused the code to fail to check the system partitions as it was intended to do. In the following code snippet, the first line assigns the result of commands to a variable, and the second line returns a portion of the string within the original variable. Specifically, it returns the first 9 characters of the string.

ucpd="$(blkid | grep 'wdnas_efi' | awk -F: '{ print $1}')"
ucpd="${ucpd:0:9}"

The following command returns a list of all system partitions, each of which has a label starting with “wdnas_”, making them easier to identify.

blkid | grep 'wdnas_' | awk -F: '{ print $1}'

/dev/mmcblk0p1
/dev/mmcblk0p2
/dev/mmcblk0p3
/dev/mmcblk0p4
/dev/mmcblk0p5
/dev/mmcblk0p6
/dev/mmcblk0p7
/dev/mmcblk0p8
/dev/mmcblk0p9

The first 9 character of each of them are “/dev/mmcb”, which explains the /dev/mmcb1 to /dev/mmcb9 results returned by the loop within the code.

ucpd="$(blkid | grep 'wdnas_efi' | awk -F: '{ print $1}')";
ucpd="${ucpd:0:9}";
echo "($ucpd)"

(/dev/mmcb)

To fix the code, one simply has to change the 9 to 13 so that the correct portion of the string is returned for processing by the loop.

ucpd="$(blkid | grep 'wdnas_efi' | awk -F: '{ print $1}')";
ucpd="${ucpd:0:13}";
echo "($ucpd)"

(/dev/mmcblk0p)

Afterwards, the code correctly identifies each of the system partitions, using dosfsck to check the first vfat partition, and e2fsck to check the remaining ext4 partitions.

Fixed Code:

echo -n "initramfs: checking integrity of system partitions "
ucpd="$(blkid | grep 'wdnas_efi' | awk -F: '{ print $1}')"
ucpd="${ucpd:0:13}"
echo "($ucpd)"
# 1st: vfat EFI
if stat "${ucpd}1" >/dev/null 2>&1; then
	dosfsck -p ${ucpd}1 2>/dev/null
else
	echo "initramfs: cannot find devnode: ${ucpd}1"
fi
# all others ext4
for i in $(seq 2 9); do
	if stat "${ucpd}$i" >/dev/null 2>&1; then
		if [ "$i" = "6" ] || [ "$i" = "9" ]; then
			e2fsck -p "${ucpd}$i" 2>/dev/null || e2fsck -f -y "${ucpd}$i"
		else
			e2fsck -p "${ucpd}$i" 2>/dev/null
		fi
	else
		echo "initramfs: cannot find devnode: ${ucpd}$i"
	fi
done

Fixed Code Output:

initramfs: checking integrity of system partitions (/dev/mmcblk0p)
fsck.fat 3.0.26 (2014-03-07)
/
  Bad short file name ().
  Auto-renaming it.
  Renamed to
/dev/mmcblk0p1: 6 files, 1118/70544 clusters
wdnas_kernel: clean, 11/2560 files, 7091/10240 blocks
wdnas_initramfs: clean, 11/2560 files, 5204/10240 blocks
wdnas_image.cfs: clean, 11/65536 files, 37774/262144 blocks
wdnas_rescue_fw: clean, 15/10240 files, 34900/40960 blocks
wdnas_config: recovering journal
wdnas_config: clean, 84/5136 files, 2659/20480 blocks
wdnas_reserve1: clean, 10/2560 files, 1433/10240 blocks
wdnas_reserve2: clean, 11/2560 files, 1434/10240 blocks
wdnas_backup: clean, 84/5136 files, 2621/20480 blocks

The “Bad short file name ()” message is the result of a bug in dosfstools-3.0.26 which was fixed in dosfstools-3.0.27.

Suggestions:

  1. Fix the code within the /etc/rc.sh script.
  2. Update dosfstools from version 3.0.26 to a newer version.
1 Like