diff mbox series

libfstools: partname: Create block device in init if needed

Message ID 20250919185420.3038448-1-cjd@cjdns.fr
State New
Headers show
Series libfstools: partname: Create block device in init if needed | expand

Commit Message

Caleb James DeLisle Sept. 19, 2025, 6:54 p.m. UTC
Rootfs on devices such as USB is currently impossible, but
not because the kernel modules aren't loaded early enough.
The only problem is that procd does not create hotplug
device files until after preinit.

Update partname_volume_init to also create the device file
if necessary so that it will be able to be mounted. With
this patch, USB rootfs with normal kmods Just Works.

Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
---
 libfstools/partname.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

Comments

Caleb James DeLisle Oct. 6, 2025, 2:09 p.m. UTC | #1
Does anybody have any opinions about this patch?
It seems like a relatively non-controversial idea, and it
makes USB rootfs able to work.


Thanks,

Caleb


On 19/09/2025 20:54, Caleb James DeLisle wrote:
> Rootfs on devices such as USB is currently impossible, but
> not because the kernel modules aren't loaded early enough.
> The only problem is that procd does not create hotplug
> device files until after preinit.
>
> Update partname_volume_init to also create the device file
> if necessary so that it will be able to be mounted. With
> this patch, USB rootfs with normal kmods Just Works.
>
> Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
> ---
>   libfstools/partname.c | 33 +++++++++++++++++++++++++++++++++
>   1 file changed, 33 insertions(+)
>
> diff --git a/libfstools/partname.c b/libfstools/partname.c
> index 9f2347a..a2b2b2c 100644
> --- a/libfstools/partname.c
> +++ b/libfstools/partname.c
> @@ -2,6 +2,8 @@
>   
>   #include "common.h"
>   
> +#include <sys/sysmacros.h>
> +
>   #define BUFLEN 64
>   
>   struct devpath {
> @@ -41,14 +43,45 @@ static int partname_volume_identify(struct volume *v)
>   	return ret;
>   }
>   
> +static int ensure_block_dev(struct partname_volume *p, const char *voldir)
> +{
> +	unsigned int major, minor;
> +	struct stat s;
> +	char dev[8];
> +
> +	if (stat(p->dev.devpathstr, &s) < 0) {
> +		if (errno != ENOENT)
> +			return -1;
> +	} else {
> +		return S_ISBLK(s.st_mode) ? 0 : -2;
> +	}
> +
> +	if (read_string_from_file(voldir, "dev", dev, sizeof(dev)) == NULL)
> +		return -3;
> +
> +	if (sscanf(dev, "%d:%d", &major, &minor) != 2)
> +		return -4;
> +
> +	if (mknod(p->dev.devpathstr, S_IFBLK | 0600, makedev(major, minor)) < 0)
> +		return -5;
> +
> +	return 0;
> +}
> +
>   static int partname_volume_init(struct volume *v)
>   {
>   	struct partname_volume *p = container_of(v, struct partname_volume, v);
>   	char voldir[BUFLEN];
>   	unsigned int volsize;
> +	int ret;
>   
>   	snprintf(voldir, sizeof(voldir), "%s/%s", block_dir_name, p->dev.devpath.device);
>   
> +	ret = ensure_block_dev(p, voldir);
> +	if (ret < 0)
> +		printf("Failed to create block device %s ret=%d errno=%d\n",
> +			p->dev.devpathstr, ret, errno);
> +
>   	if (read_uint_from_file(voldir, "size", &volsize))
>   		return -1;
>
Ivan Davydov Oct. 9, 2025, 5:02 p.m. UTC | #2
The sender domain has a DMARC Reject/Quarantine policy which disallows
sending mailing list messages using the original "From" header.

To mitigate this problem, the original message has been wrapped
automatically by the mailing list software.
By the way, does this make rootfs on NFS work?

Je 2025-oktobro-06 14:09:56 UTC, Caleb James DeLisle <cjd@cjdns.fr> skribis:
>Does anybody have any opinions about this patch?
>It seems like a relatively non-controversial idea, and it
>makes USB rootfs able to work.
>
>
>Thanks,
>
>Caleb
>
>
>On 19/09/2025 20:54, Caleb James DeLisle wrote:
>> Rootfs on devices such as USB is currently impossible, but
>> not because the kernel modules aren't loaded early enough.
>> The only problem is that procd does not create hotplug
>> device files until after preinit.
>> 
>> Update partname_volume_init to also create the device file
>> if necessary so that it will be able to be mounted. With
>> this patch, USB rootfs with normal kmods Just Works.
>> 
>> Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
>> ---
>>   libfstools/partname.c | 33 +++++++++++++++++++++++++++++++++
>>   1 file changed, 33 insertions(+)
>> 
>> diff --git a/libfstools/partname.c b/libfstools/partname.c
>> index 9f2347a..a2b2b2c 100644
>> --- a/libfstools/partname.c
>> +++ b/libfstools/partname.c
>> @@ -2,6 +2,8 @@
>>     #include "common.h"
>>   +#include <sys/sysmacros.h>
>> +
>>   #define BUFLEN 64
>>     struct devpath {
>> @@ -41,14 +43,45 @@ static int partname_volume_identify(struct volume *v)
>>   	return ret;
>>   }
>>   +static int ensure_block_dev(struct partname_volume *p, const char *voldir)
>> +{
>> +	unsigned int major, minor;
>> +	struct stat s;
>> +	char dev[8];
>> +
>> +	if (stat(p->dev.devpathstr, &s) < 0) {
>> +		if (errno != ENOENT)
>> +			return -1;
>> +	} else {
>> +		return S_ISBLK(s.st_mode) ? 0 : -2;
>> +	}
>> +
>> +	if (read_string_from_file(voldir, "dev", dev, sizeof(dev)) == NULL)
>> +		return -3;
>> +
>> +	if (sscanf(dev, "%d:%d", &major, &minor) != 2)
>> +		return -4;
>> +
>> +	if (mknod(p->dev.devpathstr, S_IFBLK | 0600, makedev(major, minor)) < 0)
>> +		return -5;
>> +
>> +	return 0;
>> +}
>> +
>>   static int partname_volume_init(struct volume *v)
>>   {
>>   	struct partname_volume *p = container_of(v, struct partname_volume, v);
>>   	char voldir[BUFLEN];
>>   	unsigned int volsize;
>> +	int ret;
>>     	snprintf(voldir, sizeof(voldir), "%s/%s", block_dir_name, p->dev.devpath.device);
>>   +	ret = ensure_block_dev(p, voldir);
>> +	if (ret < 0)
>> +		printf("Failed to create block device %s ret=%d errno=%d\n",
>> +			p->dev.devpathstr, ret, errno);
>> +
>>   	if (read_uint_from_file(voldir, "size", &volsize))
>>   		return -1;
>>   
>
>_______________________________________________
>openwrt-devel mailing list
>openwrt-devel@lists.openwrt.org
>https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Michael Richardson Oct. 9, 2025, 7:58 p.m. UTC | #3
Ivan Davydov via openwrt-devel <openwrt-devel@lists.openwrt.org> wrote:
    > By the way, does this make rootfs on NFS work?

NFS doesn't use/need block devices.
(Maybe there are network modules that could be loaded earlier that this would
help, though)
diff mbox series

Patch

diff --git a/libfstools/partname.c b/libfstools/partname.c
index 9f2347a..a2b2b2c 100644
--- a/libfstools/partname.c
+++ b/libfstools/partname.c
@@ -2,6 +2,8 @@ 
 
 #include "common.h"
 
+#include <sys/sysmacros.h>
+
 #define BUFLEN 64
 
 struct devpath {
@@ -41,14 +43,45 @@  static int partname_volume_identify(struct volume *v)
 	return ret;
 }
 
+static int ensure_block_dev(struct partname_volume *p, const char *voldir)
+{
+	unsigned int major, minor;
+	struct stat s;
+	char dev[8];
+
+	if (stat(p->dev.devpathstr, &s) < 0) {
+		if (errno != ENOENT)
+			return -1;
+	} else {
+		return S_ISBLK(s.st_mode) ? 0 : -2;
+	}
+
+	if (read_string_from_file(voldir, "dev", dev, sizeof(dev)) == NULL)
+		return -3;
+
+	if (sscanf(dev, "%d:%d", &major, &minor) != 2)
+		return -4;
+
+	if (mknod(p->dev.devpathstr, S_IFBLK | 0600, makedev(major, minor)) < 0)
+		return -5;
+
+	return 0;
+}
+
 static int partname_volume_init(struct volume *v)
 {
 	struct partname_volume *p = container_of(v, struct partname_volume, v);
 	char voldir[BUFLEN];
 	unsigned int volsize;
+	int ret;
 
 	snprintf(voldir, sizeof(voldir), "%s/%s", block_dir_name, p->dev.devpath.device);
 
+	ret = ensure_block_dev(p, voldir);
+	if (ret < 0)
+		printf("Failed to create block device %s ret=%d errno=%d\n",
+			p->dev.devpathstr, ret, errno);
+
 	if (read_uint_from_file(voldir, "size", &volsize))
 		return -1;