2011-06-30 21:13:14

by Will Drewry

[permalink] [raw]
Subject: [PATCH v3 1/2] init: add root=PARTUUID=UUID/PARTNROFF=%d support

Expand root=PARTUUID=UUID syntax to support selecting a root partition
by integer offset from a known, unique partition. This approach
provides similar properties to specifying a device and partition number,
but using the UUID as the unique path prior to evaluating the offset.

For example,
root=PARTUUID=99DE9194-FC15-4223-9192-FC243948F88B/PARTNROFF=1
selects the partition with UUID 99DE.. then select the next
partition.

This change is motivated by a particular usecase in Chromium OS where
the bootloader can easily determine what partition it is on (by UUID)
but doesn't perform general partition table walking.

That said, support for this model provides a direct mechanism for the
user to modify the root partition to boot without specifically needing
to extract each UUID or update the bootloader explicitly when the root
partition UUID is changed (if it is recreated to be larger, for
instance). Pinning to a /boot-style partition UUID allows the arbitrary
root partition reconfiguration/modifications with slightly less
ambiguity than just [dev][partition] and less stringency than the
specific root partition UUID.

v3: - emit syntax error warning to KERN_ERR
- fail on poorly formed syntax
- use / instead of , as a separator
v2: - move from +/-%u to ,PARTNR=%d (as per Kay)

Signed-off-by: Will Drewry <[email protected]>
---
init/do_mounts.c | 40 ++++++++++++++++++++++++++++++++++++----
1 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/init/do_mounts.c b/init/do_mounts.c
index c0851a8..13cddea 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -85,12 +85,15 @@ no_match:

/**
* devt_from_partuuid - looks up the dev_t of a partition by its UUID
- * @uuid: 36 byte char array containing a hex ascii UUID
+ * @uuid: min 36 byte char array containing a hex ascii UUID
*
* The function will return the first partition which contains a matching
* UUID value in its partition_meta_info struct. This does not search
* by filesystem UUIDs.
*
+ * If @uuid is followed by a "/PARTNROFF=%d", then the number will be
+ * extracted and used as an offset from the partition identified by the UUID.
+ *
* Returns the matching dev_t on success or 0 on failure.
*/
static dev_t devt_from_partuuid(char *uuid_str)
@@ -98,6 +101,22 @@ static dev_t devt_from_partuuid(char *uuid_str)
dev_t res = 0;
struct device *dev = NULL;
u8 uuid[16];
+ struct gendisk *disk;
+ struct hd_struct *part;
+ int offset = 0;
+
+ if (strlen(uuid_str) < 36)
+ goto done;
+
+ /* Check for optional partition number offset attributes. */
+ if (uuid_str[36]) {
+ /* Explicitly fail on poor PARTUUID syntax. */
+ if (sscanf(&uuid_str[36], "/PARTNROFF=%d", &offset) != 1) {
+ printk(KERN_ERR "VFS: PARTUUID= is invalid.\n"
+ "Expected PARTUUID=<valid-uuid-id>[/PARTNROFF=%%d]\n");
+ goto done;
+ }
+ }

/* Pack the requested UUID in the expected format. */
part_pack_uuid(uuid_str, uuid);
@@ -107,8 +126,21 @@ static dev_t devt_from_partuuid(char *uuid_str)
goto done;

res = dev->devt;
- put_device(dev);

+ /* Attempt to find the partition by offset. */
+ if (!offset)
+ goto no_offset;
+
+ res = 0;
+ disk = part_to_disk(dev_to_part(dev));
+ part = disk_get_part(disk, dev_to_part(dev)->partno + offset);
+ if (part) {
+ res = part_devt(part);
+ put_device(part_to_dev(part));
+ }
+
+no_offset:
+ put_device(dev);
done:
return res;
}
@@ -126,6 +158,8 @@ done:
* used when disk name of partitioned disk ends on a digit.
* 6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the
* unique id of a partition if the partition table provides it.
+ * 7) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to
+ * a partition with a known unique id.
*
* If name doesn't have fall into the categories above, we return (0,0).
* block_class is used to check if something is a disk name. If the disk
@@ -143,8 +177,6 @@ dev_t name_to_dev_t(char *name)
#ifdef CONFIG_BLOCK
if (strncmp(name, "PARTUUID=", 9) == 0) {
name += 9;
- if (strlen(name) != 36)
- goto fail;
res = devt_from_partuuid(name);
if (!res)
goto fail;
--
1.7.0.4


2011-06-30 21:13:23

by Will Drewry

[permalink] [raw]
Subject: [PATCH v3 2/2] Documentation: add pointer to name_to_dev_t for root= values

Updates kernel-parameters.txt to point users to the authoritative
comment for name_to_dev_t. In addition, updates other places where some
name_to_dev_t behavior was discussed. All other references to root=
appear to be for explicit sample usage or just side comments when
discussing other kernel parameters.

Signed-off-by: Will Drewry <[email protected]>
---
Documentation/frv/booting.txt | 13 ++++++++++---
Documentation/kernel-parameters.txt | 1 +
Documentation/m68k/kernel-options.txt | 14 ++++++++++++++
3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/Documentation/frv/booting.txt b/Documentation/frv/booting.txt
index ace200b..37c4d84 100644
--- a/Documentation/frv/booting.txt
+++ b/Documentation/frv/booting.txt
@@ -106,13 +106,20 @@ separated by spaces:
To use the first on-chip serial port at baud rate 115200, no parity, 8
bits, and no flow control.

- (*) root=/dev/<xxxx>
+ (*) root=<xxxx>

- This specifies the device upon which the root filesystem resides. For
- example:
+ This specifies the device upon which the root filesystem resides. It
+ may be specified by major and minor number, device path, or even
+ partition uuid, if supported. For example:

/dev/nfs NFS root filesystem
/dev/mtdblock3 Fourth RedBoot partition on the System Flash
+ PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF/PARTNROFF=1
+ first partition after the partition with the given UUID
+ 253:0 Device with major 253 and minor 0
+
+ Authoritative information can be found in
+ "Documentation/kernel-parameters.txt".

(*) rw

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index fd248a3..c8e1737 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2234,6 +2234,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
ro [KNL] Mount root device read-only on boot

root= [KNL] Root filesystem
+ See name_to_dev_t comment in init/do_mounts.c.

rootdelay= [KNL] Delay (in seconds) to pause before attempting to
mount the root filesystem
diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt
index c93bed6..97d45f2 100644
--- a/Documentation/m68k/kernel-options.txt
+++ b/Documentation/m68k/kernel-options.txt
@@ -129,6 +129,20 @@ decimal 11 is the major of SCSI CD-ROMs, and the minor 0 stands for
the first of these. You can find out all valid major numbers by
looking into include/linux/major.h.

+In addition to major and minor numbers, if the device containing your
+root partition uses a partition table format with unique partition
+identifiers, then you may use them. For instance,
+"root=PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF". It is also
+possible to reference another partition on the same device using a
+known partition UUID as the starting point. For example,
+if partition 5 of the device has the UUID of
+00112233-4455-6677-8899-AABBCCDDEEFF then partition 3 may be found as
+follows:
+ PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF/PARTNROFF=-2
+
+Authoritative information can be found in
+"Documentation/kernel-parameters.txt".
+

2.2) ro, rw
-----------
--
1.7.0.4