Message ID | 20210609223024.85579-1-christian.storm@siemens.com |
---|---|
State | Accepted |
Headers | show |
Series | util: Add get_root source /proc/self/mountinfo | expand |
Hi Christian, On 10.06.21 00:30, Christian Storm wrote: > Filesystems such as BTRFS report synthetic device major:minor > numbers in stat(2)'s st_dev value. Hence, such a root filesystem > won't be found by get_root_from_partitions(). > > As /proc/self/mountinfo's information is subject to mount- > namespacing, it complements get_root_from_partitions() rather > than replacing it. > > Signed-off-by: Christian Storm <christian.storm@siemens.com> > --- > core/util.c | 28 ++++++++++++++++++++++++++++ > 1 file changed, 28 insertions(+) > > diff --git a/core/util.c b/core/util.c > index 7d7673a..51a16b6 100644 > --- a/core/util.c > +++ b/core/util.c > @@ -883,6 +883,32 @@ static char *get_root_from_partitions(void) > return NULL; > } > > +/* > + * Return the rootfs's device name from /proc/self/mountinfo. > + * Needed for filesystems having synthetic stat(2) st_dev > + * values such as BTRFS. > + */ > +static char *get_root_from_mountinfo(void) > +{ > + char *mnt_point, *device = NULL; > + FILE *fp = fopen("/proc/self/mountinfo", "r"); > + while (fp && !feof(fp)){ > + /* format: https://www.kernel.org/doc/Documentation/filesystems/proc.txt */ > + if (fscanf(fp, "%*s %*s %*u:%*u %*s %ms %*s %*[-] %*s %ms %*s", > + &mnt_point, &device) == 2) { > + if ( (!strcmp(mnt_point, "/")) && (strcmp(device, "none")) ) { > + free(mnt_point); > + break; > + } > + free(mnt_point); > + free(device); > + } > + device = NULL; > + } > + (void)fclose(fp); > + return device; > +} > + > #define MAX_CMDLINE_LENGTH 4096 > static char *get_root_from_cmdline(void) > { > @@ -936,6 +962,8 @@ char *get_root_device(void) > root = get_root_from_partitions(); > if (!root) > root = get_root_from_cmdline(); > + if (!root) > + root = get_root_from_mountinfo(); > > return root; > } > Thanks - I will apply it. I take the chance to ask you if you have already had the case with device mapper and how you solved - this could be next improvement of the function. I have in fact in one project an encrypted rootfs. getroot() reports as expected "dm-0" as device. This is in fact the device mapper device, but it does not tell me which is the underlying storage. Digging a bit, I see this could be done as lsblk is doing. In fact, lsblk reports: mmcblk0 179:0 0 29.1G 0 disk |-mmcblk0p1 179:1 0 64M 0 part |-mmcblk0p2 179:2 0 64M 0 part |-mmcblk0p3 179:3 0 3.1G 0 part |-mmcblk0p4 179:4 0 3.1G 0 part | `-cr_disk 253:0 0 3.1G 0 crypt / So the parent of mount point "/" is the partition, that is mmcblk0p4. Do you have already solved this ? I mean, I have currently solved outside Lua before starting SWUpdate, but it will be nice to have it in Lua, too. Best regards, Stefano
Hi Stefano, > > Filesystems such as BTRFS report synthetic device major:minor > > numbers in stat(2)'s st_dev value. Hence, such a root filesystem > > won't be found by get_root_from_partitions(). > > > > As /proc/self/mountinfo's information is subject to mount- > > namespacing, it complements get_root_from_partitions() rather > > than replacing it. > > > > Signed-off-by: Christian Storm <christian.storm@siemens.com> > > [...] > > Thanks - I will apply it. You're welcome and thanks for merging it! > I take the chance to ask you if you have already had the case with device > mapper and how you solved - this could be next improvement of the function. Yes, and then put some LVM into the mix as well :) Seriously, I thought about this and came to the conclusion that if one wants to support the whole range of possibilities, binding to something like libblkid or similar would be the way to go. Otherwise you end up (re-)implementing the same functionality in SWUpdate. The other option is to limit the functionality to some sensible subset and implement that in SWUpdate so to not introduce the library dependency.... > I have in fact in one project an encrypted rootfs. getroot() reports as > expected "dm-0" as device. This is in fact the device mapper device, but it > does not tell me which is the underlying storage. > > Digging a bit, I see this could be done as lsblk is doing. In fact, lsblk > reports: > > mmcblk0 179:0 0 29.1G 0 disk > |-mmcblk0p1 179:1 0 64M 0 part > |-mmcblk0p2 179:2 0 64M 0 part > |-mmcblk0p3 179:3 0 3.1G 0 part > |-mmcblk0p4 179:4 0 3.1G 0 part > | `-cr_disk 253:0 0 3.1G 0 crypt / > > So the parent of mount point "/" is the partition, that is mmcblk0p4. Do you > have already solved this ? I mean, I have currently solved outside Lua before > starting SWUpdate, but it will be nice to have it in Lua, too. Supporting dm-crypt is on my agenda as well, it's a natural next step IMO. I haven't yet investigated much but in general you get all information via walking /sys: For example, looking at /sys/block/dm-0/slaves reveals nvme0n1p2 which links to [...]/nvme/nvme0/nvme0n1/nvme0n1p2 and this is indeed the partition of my root filesystem, including the storage topology. Kind regards, Christian
Hi Christian, On 11.06.21 11:53, Christian Storm wrote: > Hi Stefano, > >>> Filesystems such as BTRFS report synthetic device major:minor >>> numbers in stat(2)'s st_dev value. Hence, such a root filesystem >>> won't be found by get_root_from_partitions(). >>> >>> As /proc/self/mountinfo's information is subject to mount- >>> namespacing, it complements get_root_from_partitions() rather >>> than replacing it. >>> >>> Signed-off-by: Christian Storm <christian.storm@siemens.com> >>> [...] >> >> Thanks - I will apply it. > > You're welcome and thanks for merging it! > > >> I take the chance to ask you if you have already had the case with device >> mapper and how you solved - this could be next improvement of the function. > > Yes, and then put some LVM into the mix as well :) Seriously, I thought > about this and came to the conclusion that if one wants to support the > whole range of possibilities, binding to something like libblkid or > similar would be the way to go. libblkid is already linked: ifeq ($(CONFIG_UNIQUEUUID),y) LDLIBS += blkid endif It can be added as fix dependency. > Otherwise you end up (re-)implementing > the same functionality in SWUpdate. The other option is to limit the > functionality to some sensible subset and implement that in SWUpdate so > to not introduce the library dependency.... > > >> I have in fact in one project an encrypted rootfs. getroot() reports as >> expected "dm-0" as device. This is in fact the device mapper device, but it >> does not tell me which is the underlying storage. >> >> Digging a bit, I see this could be done as lsblk is doing. In fact, lsblk >> reports: >> >> mmcblk0 179:0 0 29.1G 0 disk >> |-mmcblk0p1 179:1 0 64M 0 part >> |-mmcblk0p2 179:2 0 64M 0 part >> |-mmcblk0p3 179:3 0 3.1G 0 part >> |-mmcblk0p4 179:4 0 3.1G 0 part >> | `-cr_disk 253:0 0 3.1G 0 crypt / >> >> So the parent of mount point "/" is the partition, that is mmcblk0p4. Do you >> have already solved this ? I mean, I have currently solved outside Lua before >> starting SWUpdate, but it will be nice to have it in Lua, too. > > Supporting dm-crypt is on my agenda as well, it's a natural next step > IMO. I haven't yet investigated much but in general you get all information > via walking /sys: For example, looking at /sys/block/dm-0/slaves I discover this yesterday myself, and I wrote a small temporary patch for this. Then I simply post it for review.... > reveals > nvme0n1p2 which links to [...]/nvme/nvme0/nvme0n1/nvme0n1p2 and this is > indeed the partition of my root filesystem, including the storage topology. > > Best regards, Stefano
Hi Stefano, > > > > Filesystems such as BTRFS report synthetic device major:minor > > > > numbers in stat(2)'s st_dev value. Hence, such a root filesystem > > > > won't be found by get_root_from_partitions(). > > > > > > > > As /proc/self/mountinfo's information is subject to mount- > > > > namespacing, it complements get_root_from_partitions() rather > > > > than replacing it. > > > > > > > > Signed-off-by: Christian Storm <christian.storm@siemens.com> > > > > [...] > > > > > > Thanks - I will apply it. > > > > You're welcome and thanks for merging it! > > > > > > > I take the chance to ask you if you have already had the case with device > > > mapper and how you solved - this could be next improvement of the function. > > > > Yes, and then put some LVM into the mix as well :) Seriously, I thought > > about this and came to the conclusion that if one wants to support the > > whole range of possibilities, binding to something like libblkid or > > similar would be the way to go. > > libblkid is already linked: > > ifeq ($(CONFIG_UNIQUEUUID),y) > LDLIBS += blkid > endif > > It can be added as fix dependency. Yes, that's the point I guess, it becomes a hard dependency, probably unconditionally. I do have no objections on this, though... > > Otherwise you end up (re-)implementing > > the same functionality in SWUpdate. The other option is to limit the > > functionality to some sensible subset and implement that in SWUpdate so > > to not introduce the library dependency.... > > > > > > > I have in fact in one project an encrypted rootfs. getroot() reports as > > > expected "dm-0" as device. This is in fact the device mapper device, but it > > > does not tell me which is the underlying storage. > > > > > > Digging a bit, I see this could be done as lsblk is doing. In fact, lsblk > > > reports: > > > > > > mmcblk0 179:0 0 29.1G 0 disk > > > |-mmcblk0p1 179:1 0 64M 0 part > > > |-mmcblk0p2 179:2 0 64M 0 part > > > |-mmcblk0p3 179:3 0 3.1G 0 part > > > |-mmcblk0p4 179:4 0 3.1G 0 part > > > | `-cr_disk 253:0 0 3.1G 0 crypt / > > > > > > So the parent of mount point "/" is the partition, that is mmcblk0p4. Do you > > > have already solved this ? I mean, I have currently solved outside Lua before > > > starting SWUpdate, but it will be nice to have it in Lua, too. > > > > Supporting dm-crypt is on my agenda as well, it's a natural next step > > IMO. I haven't yet investigated much but in general you get all information > > via walking /sys: For example, looking at /sys/block/dm-0/slaves > > I discover this yesterday myself, and I wrote a small temporary patch for > this. Then I simply post it for review.... Thanks, sounds good, will review it :) Kind regards, Christian
diff --git a/core/util.c b/core/util.c index 7d7673a..51a16b6 100644 --- a/core/util.c +++ b/core/util.c @@ -883,6 +883,32 @@ static char *get_root_from_partitions(void) return NULL; } +/* + * Return the rootfs's device name from /proc/self/mountinfo. + * Needed for filesystems having synthetic stat(2) st_dev + * values such as BTRFS. + */ +static char *get_root_from_mountinfo(void) +{ + char *mnt_point, *device = NULL; + FILE *fp = fopen("/proc/self/mountinfo", "r"); + while (fp && !feof(fp)){ + /* format: https://www.kernel.org/doc/Documentation/filesystems/proc.txt */ + if (fscanf(fp, "%*s %*s %*u:%*u %*s %ms %*s %*[-] %*s %ms %*s", + &mnt_point, &device) == 2) { + if ( (!strcmp(mnt_point, "/")) && (strcmp(device, "none")) ) { + free(mnt_point); + break; + } + free(mnt_point); + free(device); + } + device = NULL; + } + (void)fclose(fp); + return device; +} + #define MAX_CMDLINE_LENGTH 4096 static char *get_root_from_cmdline(void) { @@ -936,6 +962,8 @@ char *get_root_device(void) root = get_root_from_partitions(); if (!root) root = get_root_from_cmdline(); + if (!root) + root = get_root_from_mountinfo(); return root; }
Filesystems such as BTRFS report synthetic device major:minor numbers in stat(2)'s st_dev value. Hence, such a root filesystem won't be found by get_root_from_partitions(). As /proc/self/mountinfo's information is subject to mount- namespacing, it complements get_root_from_partitions() rather than replacing it. Signed-off-by: Christian Storm <christian.storm@siemens.com> --- core/util.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)