xref: /OK3568_Linux_fs/buildroot/package/busybox/0006-Support-PARTLABEL.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From a3c839f7ca05ecd424be293f49e90f36845b8b8b Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Fri, 25 Nov 2022 19:39:30 +0800
4Subject: [PATCH 6/8] Support PARTLABEL
5
6Tested on RK3588 EVB:
7busybox mount PARTLABEL=rootfs /media/
8
9Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
10---
11 include/volume_id.h                       |  1 +
12 util-linux/volume_id/get_devname.c        | 59 +++++++++++++++++++----
13 util-linux/volume_id/volume_id_internal.h |  1 +
14 3 files changed, 52 insertions(+), 9 deletions(-)
15
16diff --git a/include/volume_id.h b/include/volume_id.h
17index a83da89..afb76e4 100644
18--- a/include/volume_id.h
19+++ b/include/volume_id.h
20@@ -20,6 +20,7 @@
21
22 char *get_devname_from_label(const char *spec);
23 char *get_devname_from_uuid(const char *spec);
24+char *get_devname_from_partlabel(const char *spec);
25 void display_uuid_cache(int scan_devices);
26
27 /* Returns:
28diff --git a/util-linux/volume_id/get_devname.c b/util-linux/volume_id/get_devname.c
29index 00cfb28..61d0461 100644
30--- a/util-linux/volume_id/get_devname.c
31+++ b/util-linux/volume_id/get_devname.c
32@@ -24,15 +24,16 @@ static struct uuidCache_s {
33 //	int major, minor;
34 	char *device;
35 	char *label;
36+	char *partlabel;
37 	char *uc_uuid; /* prefix makes it easier to grep for */
38 	IF_FEATURE_BLKID_TYPE(const char *type;)
39 } *uuidCache;
40
41 #if !ENABLE_FEATURE_BLKID_TYPE
42-#define get_label_uuid(fd, label, uuid, type) \
43-	get_label_uuid(fd, label, uuid)
44-#define uuidcache_addentry(device, label, uuid, type) \
45-	uuidcache_addentry(device, label, uuid)
46+#define get_label_uuid(fd, label, partlabel, uuid, type) \
47+	get_label_uuid(fd, label, partlabel, uuid)
48+#define uuidcache_addentry(device, label, partlabel, uuid, type) \
49+	uuidcache_addentry(device, label, partlabel, uuid)
50 #endif
51
52 /* Returns !0 on error.
53@@ -40,11 +41,13 @@ static struct uuidCache_s {
54  * (and they can't be NULL, although they can be "").
55  * NB: closes fd. */
56 static int
57-get_label_uuid(int fd, char **label, char **uuid, const char **type)
58+get_label_uuid(int fd, char **label, char **partlabel, char **uuid, const char **type)
59 {
60 	int rv = 1;
61 	uint64_t size;
62 	struct volume_id *vid;
63+	struct stat st;
64+	char *uevent;
65
66 	/* fd is owned by vid now */
67 	vid = volume_id_open_node(fd);
68@@ -55,12 +58,30 @@ get_label_uuid(int fd, char **label, char **uuid, const char **type)
69 	if (volume_id_probe_all(vid, /*0,*/ size) != 0)
70 		goto ret;
71
72-	if (vid->label[0] != '\0' || vid->uuid[0] != '\0'
73+	fstat(fd, &st);
74+	uevent = xasprintf("/sys/dev/block/%d:%d/uevent",
75+			   major(st.st_rdev), minor(st.st_rdev));
76+	if (uevent) {
77+		FILE *rfile = fopen_for_read(uevent);
78+		if (rfile) {
79+			const char *line;
80+			while ((line = xmalloc_fgetline(rfile)) != NULL) {
81+				if (sscanf(line, "PARTNAME=%s",
82+					   vid->partlabel) > 0)
83+					break;
84+			}
85+			fclose(rfile);
86+		}
87+		free(uevent);
88+	}
89+
90+	if (vid->label[0] != '\0' || vid->partlabel[0] != '\0' || vid->uuid[0] != '\0'
91 #if ENABLE_FEATURE_BLKID_TYPE
92 	 || vid->type != NULL
93 #endif
94 	) {
95 		*label = xstrndup(vid->label, sizeof(vid->label));
96+		*partlabel = xstrndup(vid->partlabel, sizeof(vid->partlabel));
97 		*uuid  = xstrndup(vid->uuid, sizeof(vid->uuid));
98 #if ENABLE_FEATURE_BLKID_TYPE
99 		*type = vid->type;
100@@ -77,7 +98,7 @@ get_label_uuid(int fd, char **label, char **uuid, const char **type)
101
102 /* NB: we take ownership of (malloc'ed) label and uuid */
103 static void
104-uuidcache_addentry(char *device, /*int major, int minor,*/ char *label, char *uuid, const char *type)
105+uuidcache_addentry(char *device, /*int major, int minor,*/ char *label, char *partlabel, char *uuid, const char *type)
106 {
107 	struct uuidCache_s *last;
108
109@@ -94,6 +115,7 @@ uuidcache_addentry(char *device, /*int major, int minor,*/ char *label, char *uu
110 //	last->minor = minor;
111 	last->device = device;
112 	last->label = label;
113+	last->partlabel = partlabel;
114 	last->uc_uuid = uuid;
115 	IF_FEATURE_BLKID_TYPE(last->type = type;)
116 }
117@@ -244,6 +266,8 @@ void display_uuid_cache(int scan_devices)
118 	if (uc->type)
119 		printf(" TYPE=\"%s\"", uc->type);
120 #endif
121+		if (uc->partlabel[0])
122+			printf(" PARTLABEL=\"%s\"", uc->partlabel);
123 		bb_putchar('\n');
124 		uc = uc->next;
125 	}
126@@ -253,6 +277,7 @@ int add_to_uuid_cache(const char *device)
127 {
128 	char *uuid = uuid; /* for compiler */
129 	char *label = label;
130+	char *partlabel = partlabel;
131 #if ENABLE_FEATURE_BLKID_TYPE
132 	const char *type = type;
133 #endif
134@@ -263,9 +288,9 @@ int add_to_uuid_cache(const char *device)
135 		return 0;
136
137 	/* get_label_uuid() closes fd in all cases (success & failure) */
138-	if (get_label_uuid(fd, &label, &uuid, &type) == 0) {
139+	if (get_label_uuid(fd, &label, &partlabel, &uuid, &type) == 0) {
140 		/* uuidcache_addentry() takes ownership of all four params */
141-		uuidcache_addentry(xstrdup(device), /*ma, mi,*/ label, uuid, type);
142+		uuidcache_addentry(xstrdup(device), /*ma, mi,*/ label, partlabel, uuid, type);
143 		return 1;
144 	}
145 	return 0;
146@@ -288,6 +313,20 @@ char *get_devname_from_label(const char *spec)
147 	return NULL;
148 }
149
150+char *get_devname_from_partlabel(const char *spec)
151+{
152+	struct uuidCache_s *uc;
153+
154+	uc = uuidcache_init(/*scan_devices:*/ 1);
155+	while (uc) {
156+		if (uc->partlabel[0] && strcmp(spec, uc->partlabel) == 0) {
157+			return xstrdup(uc->device);
158+		}
159+		uc = uc->next;
160+	}
161+	return NULL;
162+}
163+
164 char *get_devname_from_uuid(const char *spec)
165 {
166 	struct uuidCache_s *uc;
167@@ -311,6 +350,8 @@ int resolve_mount_spec(char **fsname)
168 		tmp = get_devname_from_uuid(*fsname + 5);
169 	else if (is_prefixed_with(*fsname, "LABEL="))
170 		tmp = get_devname_from_label(*fsname + 6);
171+	else if (is_prefixed_with(*fsname, "PARTLABEL="))
172+		tmp = get_devname_from_partlabel(*fsname + 10);
173
174 	if (tmp == *fsname)
175 		return 0; /* no UUID= or LABEL= prefix found */
176diff --git a/util-linux/volume_id/volume_id_internal.h b/util-linux/volume_id/volume_id_internal.h
177index b1e4448..d1d9d4d 100644
178--- a/util-linux/volume_id/volume_id_internal.h
179+++ b/util-linux/volume_id/volume_id_internal.h
180@@ -76,6 +76,7 @@ struct volume_id {
181 //	uint8_t		label_raw[VOLUME_ID_LABEL_SIZE];
182 //	size_t		label_raw_len;
183 	char		label[VOLUME_ID_LABEL_SIZE+1];
184+	char		partlabel[VOLUME_ID_LABEL_SIZE+1];
185 //	uint8_t		uuid_raw[VOLUME_ID_UUID_SIZE];
186 //	size_t		uuid_raw_len;
187 	/* uuid is stored in ASCII (not binary) form here: */
188--
1892.20.1
190
191