diff mbox series

[V2] util: Extend get_root to find LUKS devices

Message ID 20210614122522.904662-1-stefano.babic@babic.homelinux.org
State Accepted
Headers show
Series [V2] util: Extend get_root to find LUKS devices | expand

Commit Message

Stefano Babic June 14, 2021, 12:25 p.m. UTC
From: Stefano Babic <sbabic@denx.de>

This helps in case of encrypted filesystem or device mapper.
The returned device read from partitions is usually a dm-X device and
this does not show which is the block device that contains it. Look in
sysfs and check if the device has "slaves" entries, indicating the
presence of an underlying device. If found, return this instead of the
device returned parsing /proc/partitions.

Signed-off-by: Stefano Babic <sbabic@denx.de>
---

Changes since V1:
	- initialize dirent to NULL to avoid segfault whren freed

 core/util.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

Comments

Christian Storm June 14, 2021, 3:23 p.m. UTC | #1
Hi Stefano,

> +	snprintf(buf, sizeof(buf) - 1, "/sys/dev/block/%d:%d/slaves", dev_major, dev_minor);
> +	n = scandir(buf, &devlist, filter_slave, NULL);
> +	if (n == 1) {
> +		devname = strdup(devlist[0]->d_name);
> +		free(devlist);
> +		return devname;
> +        }

This } seems to be misaligned?



Kind regards,
   Christian
Stefano Babic June 14, 2021, 3:47 p.m. UTC | #2
On 14.06.21 17:23, Christian Storm wrote:
> Hi Stefano,
> 
>> +	snprintf(buf, sizeof(buf) - 1, "/sys/dev/block/%d:%d/slaves", dev_major, dev_minor);
>> +	n = scandir(buf, &devlist, filter_slave, NULL);
>> +	if (n == 1) {
>> +		devname = strdup(devlist[0]->d_name);
>> +		free(devlist);
>> +		return devname;
>> +        }
> 
> This } seems to be misaligned?
> 
> 

There are spaces instead of tab, I fix it while merging - thanks !

Best regards,
Stefano
diff mbox series

Patch

diff --git a/core/util.c b/core/util.c
index 51a16b6..11e7d5a 100644
--- a/core/util.c
+++ b/core/util.c
@@ -24,6 +24,7 @@ 
 #include <libgen.h>
 #include <regex.h>
 #include <string.h>
+#include <dirent.h>
 
 #if defined(__linux__)
 #include <sys/statvfs.h>
@@ -851,6 +852,10 @@  size_t snescape(char *dst, size_t n, const char *src)
 /*
  * This returns the device name where rootfs is mounted
  */
+
+static int filter_slave(const struct dirent *ent) {
+	return (strcmp(ent->d_name, ".") && strcmp(ent->d_name, ".."));
+}
 static char *get_root_from_partitions(void)
 {
 	struct stat info;
@@ -858,11 +863,28 @@  static char *get_root_from_partitions(void)
 	char *devname = NULL;
 	unsigned long major, minor, nblocks;
 	char buf[256];
-	int ret;
+	int ret, dev_major, dev_minor, n;
+	struct dirent **devlist = NULL;
 
 	if (stat("/", &info) < 0)
 		return NULL;
 
+	dev_major = info.st_dev / 256;
+	dev_minor = info.st_dev % 256;
+
+	/*
+	 * Check if this is just a container, for example in case of LUKS
+	 * Search if the device has slaves pointing to another device
+	 */
+	snprintf(buf, sizeof(buf) - 1, "/sys/dev/block/%d:%d/slaves", dev_major, dev_minor);
+	n = scandir(buf, &devlist, filter_slave, NULL);
+	if (n == 1) {
+		devname = strdup(devlist[0]->d_name);
+		free(devlist);
+		return devname;
+        }
+	free(devlist);
+
 	fp = fopen("/proc/partitions", "r");
 	if (!fp)
 		return NULL;
@@ -872,7 +894,7 @@  static char *get_root_from_partitions(void)
 			     &major, &minor, &nblocks, &devname);
 		if (ret != 4)
 			continue;
-		if ((major == info.st_dev / 256) && (minor == info.st_dev % 256)) {
+		if ((major == dev_major) && (minor == dev_minor)) {
 			fclose(fp);
 			return devname;
 		}