From f027c34d844013d9d6c902af8fa01a82d6e5073d Mon Sep 17 00:00:00 2001 From: Nikolaus Voss Date: Tue, 30 Oct 2018 15:05:57 -0700 Subject: [PATCH] init/do_mounts.c: add root=PARTLABEL= support Support referencing the root partition label from GPT as argument to the root= option on the kernel command line in analogy to referencing the partition uuid as root=PARTUUID=. Specifying the partition label instead of the uuid is often much easier, e.g. in embedded environments when there is an A/B rootfs partition scheme for interruptible firmware updates (i.e. rootfsA/ rootfsB). The partition label can be queried with the blkid command. Link: http://lkml.kernel.org/r/20180822060904.828E510665E@pc-niv.weinmann.com Signed-off-by: Nikolaus Voss Reviewed-by: Andrew Morton Cc: Dominik Brodowski Cc: Sasha Levin Cc: Al Viro Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/do_mounts.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/init/do_mounts.c b/init/do_mounts.c index e1c9afa9d8c9..a754e3ba9831 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -167,6 +167,24 @@ static dev_t devt_from_partuuid(const char *uuid_str) } return res; } + +/** + * match_dev_by_label - callback for finding a partition using its label + * @dev: device passed in by the caller + * @data: opaque pointer to the label to match + * + * Returns 1 if the device matches, and 0 otherwise. + */ +static int match_dev_by_label(struct device *dev, const void *data) +{ + const char *label = data; + struct hd_struct *part = dev_to_part(dev); + + if (part->info && !strcmp(label, part->info->volname)) + return 1; + + return 0; +} #endif /* @@ -190,6 +208,8 @@ static dev_t devt_from_partuuid(const char *uuid_str) * a partition with a known unique id. * 8) : major and minor number of the device separated by * a colon. + * 9) PARTLABEL= with name being the GPT partition label. + * MSDOS partitions do not support labels! * * 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 @@ -211,6 +231,17 @@ dev_t name_to_dev_t(const char *name) if (!res) goto fail; goto done; + } else if (strncmp(name, "PARTLABEL=", 10) == 0) { + struct device *dev; + + dev = class_find_device(&block_class, NULL, name + 10, + &match_dev_by_label); + if (!dev) + goto fail; + + res = dev->devt; + put_device(dev); + goto done; } #endif