rootdev: Strip partitions less aggressively
In device names like dm-N or loopN, the N is not a partition number and
should not be stripped off. These can arise for example if run inside a
chroot mounted on a loopback device.
BUG=chromium:748665, chromium:730144
TEST=New unit tests.
Change-Id: If7ecacbfcf00690376cb4ffc75baa45422579085
Reviewed-on: https://chromium-review.googlesource.com/585652
Commit-Ready: Benjamin Gordon <bmgordon@chromium.org>
Tested-by: Benjamin Gordon <bmgordon@chromium.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/rootdev.c b/rootdev.c
index 6340ddd..3cad4f4 100644
--- a/rootdev.c
+++ b/rootdev.c
@@ -218,10 +218,18 @@
char *part = (char *)rootdev_get_partition(dst, len);
if (!part)
return;
+
+ /* For devices matching dm-NN, the digits are not a partition. */
+ if (*(part - 1) == '-')
+ return;
+
/* For devices that end with a digit, the kernel uses a 'p'
- * as a separator. E.g., mmcblk1p2. */
- if (*(part - 1) == 'p')
+ * as a separator. E.g., mmcblk1p2 and loop0p1, but not loop0. */
+ if (*(part - 1) == 'p') {
part--;
+ if (strncmp(dst, "loop", 4) == 0 && dst + 3 == part)
+ return;
+ }
*part = '\0';
}
diff --git a/rootdev_test.sh b/rootdev_test.sh
index d236b2b..74d45eb 100755
--- a/rootdev_test.sh
+++ b/rootdev_test.sh
@@ -279,6 +279,72 @@
}
run_test t12_sda_strip
+# Set up dev nodes and minimal /sys/block entries for a loopback device with a
+# partition on it.
+#
+# Using the same major for the partition doesn't accurately reflect how a real
+# partitioned loopback device would be created, but rootdev doesn't currently
+# support partitions with a different major number than their containing device.
+# This setup can only be used to test that the partition stripping code
+# correctly handles both loop0 and loop0p1.
+h03_setup_loop_tree() {
+ local block=$1
+ local dev=$2
+ mkdir -p $block/loop0/loop0p1
+ mkdir -p $dev
+ echo "7:0" > $block/loop0/dev
+ echo "7:10" > $block/loop0/loop0p1/dev
+ mknod $dev/loop0 b 7 0
+ mknod $dev/loop0p1 b 7 10
+}
+
+# Verify that the pN doesn't get stripped from loopN.
+t13_loop_nostrip_device() {
+ local block=$WORKDIR/sys/block
+ local dev=$WORKDIR/dev
+ h03_setup_loop_tree $block $dev
+ out=$("${ROOTDEV}" -d --dev $dev --block $block --major 7 --minor 0 \
+ 2>/dev/null)
+ expect "$? -eq 0" || return 1
+ expect "'$dev/loop0' = '$out'" || return 1
+}
+run_test t13_loop_nostrip_device
+
+# Verify that the pM does get stripped from loopNpM.
+t14_loop_strip_partition() {
+ local block=$WORKDIR/sys/block
+ local dev=$WORKDIR/dev
+ h03_setup_loop_tree $block $dev
+ out=$("${ROOTDEV}" -d --dev $dev --block $block --major 7 --minor 10 \
+ 2>/dev/null)
+ expect "$? -eq 0" || return 1
+ expect "'$dev/loop0' = '$out'" || return 1
+}
+run_test t14_loop_strip_partition
+
+# Set up dev nodes and minimal /sys/block entries for a device mapper device.
+h04_setup_dm_tree() {
+ local block=$1
+ local dev=$2
+ mkdir -p $block
+ mkdir -p $dev
+ mkdir -p $block/dm-3
+ echo "252:3" > $block/dm-3/dev
+ mknod $dev/dm-3 b 252 3
+}
+
+# Verify that the -NN doesn't get stripped from dm-NN.
+t15_dm_strip() {
+ local block=$WORKDIR/sys/block
+ local dev=$WORKDIR/dev
+ h04_setup_dm_tree $block $dev
+ out=$("${ROOTDEV}" -d --dev $dev --block $block --major 252 --minor 3 \
+ 2>/dev/null)
+ expect "$? -eq 0" || return 1
+ expect "'$dev/dm-3' = '$out'" || return 1
+}
+run_test t15_dm_strip
+
# TODO(wad) add node creation tests
TEST_COUNT=$((PASS_COUNT + FAIL_COUNT))