From: Will Drewry <wad@chromium.org>
To: linux-kernel@vger.kernel.org
Cc: Kay Sievers <kay.sievers@vrfy.org>, Jens Axboe <axboe@kernel.dk>,
Karel Zak <kzak@redhat.com>, Tejun Heo <tj@kernel.org>,
"David S. Miller" <davem@davemloft.net>,
Andrew Morton <akpm@linux-foundation.org>,
Joe Perches <joe@perches.com>, Jan Blunck <jblunck@suse.de>,
Greg Kroah-Hartman <gregkh@suse.de>,
Will Drewry <wad@chromium.org>
Subject: [PATCH 3/3] init: add support for root devices specified by partition UUID
Date: Tue, 3 Aug 2010 21:04:43 -0500 [thread overview]
Message-ID: <1280887483-2979-3-git-send-email-wad@chromium.org> (raw)
In-Reply-To: <AANLkTim6Bn++JaspY0cbpLLvi=MYBLNgUhARwKQkoYpE@mail.gmail.com>
This is the third patch in a series which adds support for
storing partition metadata, optionally, off of the hd_struct.
One major use for that data is being able to resolve partition
by other identities than just the index on a block device. Device
enumeration varies by platform and there's a benefit to being able
to use something like EFI GPT's GUIDs to determine the correct
block device and partition to mount as the root.
This change adds that support to root= by adding support for
the following syntax:
root=PARTUUID=hex-uuid
I can't say this is the best way to do it, but it should be reasonably
clean to extend. There are a number of alternate approaches, and I'd love to
hear what is preferred.
Signed-off-by: Will Drewry <wad@chromium.org>
---
init/do_mounts.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 02e3ca4..7b22abf 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -58,6 +58,78 @@ static int __init readwrite(char *str)
__setup("ro", readonly);
__setup("rw", readwrite);
+/**
+ * match_dev_by_uuid - callback for finding a partition using its uuid
+ * @dev: device passed in by the caller
+ * @data: opaque pointer to a 36 byte char array with a UUID
+ *
+ * Returns 1 if the device matches, and 0 otherwise.
+ */
+static int __init match_dev_by_uuid(struct device *dev, void *data)
+{
+ u8 *uuid = data;
+ char candidate[37];
+ struct hd_struct *part = dev_to_part(dev);
+
+ if (!part->info)
+ goto no_match;
+
+ /* Each format may parse UUIDs differently. To that end,
+ * each format will have to parse either the given uuid or
+ * the candidate partition. It'd be more efficient to parse
+ * prior to the walk, but we'd need to store all the possible
+ * parsed guids.
+ */
+ switch (part->info->format) {
+#ifdef CONFIG_EFI_PARTITION
+ case PARTITION_META_INFO_FORMAT_EFI:
+ snprintf(candidate, sizeof(candidate), "%pUl",
+ part->info->efi.uuid.b);
+ if (!strcmp(uuid, candidate))
+ goto match;
+#endif
+ default:
+ goto no_match;
+ }
+
+match:
+ return 1;
+no_match:
+ return 0;
+}
+
+
+/**
+ * devt_from_partuuid - looks up the dev_t of a partition by its UUID
+ * @uuid: 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.
+ *
+ * Returns the matching dev_t on success or 0 on failure.
+ */
+static dev_t __init devt_from_partuuid(char *uuid)
+{
+ dev_t res = 0;
+ struct device *dev = NULL;
+ unsigned char *uuid_cur = (unsigned char *) uuid;
+
+ /* Downcase the letters in the UUID for uniformity. */
+ for (; *uuid_cur; ++uuid_cur)
+ *uuid_cur = tolower(*uuid_cur);
+
+ dev = class_find_device(&block_class, NULL, uuid, &match_dev_by_uuid);
+ if (!dev)
+ goto done;
+
+ res = dev->devt;
+ put_device(dev);
+
+done:
+ return res;
+}
+
/*
* Convert a name into device number. We accept the following variants:
*
@@ -68,6 +140,8 @@ __setup("rw", readwrite);
* of partition - device number of disk plus the partition number
* 5) /dev/<disk_name>p<decimal> - same as the above, that form is
* 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.
*
* 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
@@ -82,6 +156,16 @@ dev_t name_to_dev_t(char *name)
dev_t res = 0;
int part;
+ if (strncmp(name, "PARTUUID=", 9) == 0) {
+ name += 9;
+ if (strlen(name) != 36)
+ goto fail;
+ res = devt_from_partuuid(name);
+ if (!res)
+ goto fail;
+ goto done;
+ }
+
if (strncmp(name, "/dev/", 5) != 0) {
unsigned maj, min;
--
1.7.0.4
next prev parent reply other threads:[~2010-08-04 2:06 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-02 19:17 [PATCH RFC] efi: add and expose efi_partition_by_guid Will Drewry
2010-08-02 23:00 ` David Miller
2010-08-03 2:44 ` Will Drewry
2010-08-03 2:52 ` [PATCH v2 " Will Drewry
2010-08-03 18:50 ` Randy Dunlap
2010-08-03 18:52 ` Will Drewry
2010-08-03 2:48 ` [PATCH RFC (alt)] efi: add efi_partition_walk and expose for kernel access Will Drewry
2010-08-03 16:08 ` [PATCH RFC] efi: add and expose efi_partition_by_guid Tejun Heo
2010-08-03 17:17 ` Kay Sievers
2010-08-03 17:55 ` Will Drewry
2010-08-03 18:23 ` Kay Sievers
2010-08-03 18:52 ` Will Drewry
2010-08-03 21:35 ` [PATCH 1/2] block, partition: add partition_meta_info to hd_struct Will Drewry
2010-08-03 21:35 ` [PATCH 2/2] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-03 21:54 ` Kay Sievers
2010-08-03 22:27 ` Will Drewry
2010-08-03 23:13 ` Kay Sievers
2010-08-04 2:04 ` [PATCH v2 1/3] block, partition: add partition_meta_info to hd_struct Will Drewry
2010-08-04 7:57 ` Tejun Heo
2010-08-04 14:46 ` Will Drewry
2010-08-04 2:04 ` [PATCH v2 2/3] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-04 7:59 ` Tejun Heo
2010-08-04 9:00 ` Karel Zak
2010-08-04 10:14 ` Kay Sievers
2010-08-04 14:44 ` Will Drewry
2010-08-04 15:28 ` Kay Sievers
2010-08-04 15:56 ` Will Drewry
2010-08-04 18:22 ` [PATCH v3 1/3] block, partition: add partition_meta_info to hd_struct Will Drewry
2010-08-04 18:22 ` [PATCH v3 2/3] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-04 18:22 ` [PATCH v3 3/3] init: add support for root devices specified by partition UUID Will Drewry
2010-08-05 10:55 ` Tejun Heo
2010-08-05 14:26 ` Will Drewry
2010-08-05 14:29 ` Tejun Heo
2010-08-05 19:19 ` Will Drewry
2010-08-05 19:29 ` Kay Sievers
2010-08-31 20:47 ` [PATCH v4 1/3] block, partition: add partition_meta_info to hd_struct Will Drewry
2010-09-15 14:22 ` Jens Axboe
2010-08-31 20:47 ` [PATCH v4 2/3] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-31 20:47 ` [PATCH v4 3/3] init: add support for root devices specified by partition UUID Will Drewry
2010-08-04 14:44 ` [PATCH v2 2/3] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-04 2:04 ` Will Drewry [this message]
2010-08-04 14:27 ` [PATCH 2/2] " John Stoffel
2010-08-04 14:45 ` Will Drewry
2010-08-04 15:25 ` Kay Sievers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1280887483-2979-3-git-send-email-wad@chromium.org \
--to=wad@chromium.org \
--cc=akpm@linux-foundation.org \
--cc=axboe@kernel.dk \
--cc=davem@davemloft.net \
--cc=gregkh@suse.de \
--cc=jblunck@suse.de \
--cc=joe@perches.com \
--cc=kay.sievers@vrfy.org \
--cc=kzak@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®