<div dir="ltr"><div dir="ltr">Hello Richard,<div><br clear="all"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><br><br><div style="display:inline"></div></div></div></div></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il giorno gio 27 ott 2022 alle ore 11:16 Richard Palethorpe <<a href="mailto:rpalethorpe@suse.de">rpalethorpe@suse.de</a>> ha scritto:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
Alessandro Carminati <<a href="mailto:alessandro.carminati@gmail.com" target="_blank">alessandro.carminati@gmail.com</a>> writes:<br>
<br>
> In some minimal Linux the /dev/root can be missing. The consequence for this<br>
> is that mountinfo doesn't contain the correct information.<br>
><br>
> The unevent file in sysfs is another method to retrieve device info given <br>
> a major/minor.<br>
><br>
> btrfs subvolumes can be an exception to this rule, but they are not expected<br>
> to be used in the current usecase.<br>
<br>
Unfortunately this is not true. If you mount /tmp on BTRFS (or set<br>
TMPDIR to some BTRFS mount), then we hit this issue.<br></blockquote><div><br></div><div>This is also true if you use the mountinfo strategy.</div>I ran a few tests on my test environment, and I could see that the ioctl_loop05 </div><div class="gmail_quote">on btrfs filesystem doesn't work either with the mountinfo strategy.<br><br>Here is a sample running the original (with a few additional debug output) test</div><div class="gmail_quote">using the mountinfo strategy on ext3:</div><div class="gmail_quote"><br>VFS: Mounted root (ext2 filesystem) on device 8:0.<br>devtmpfs: mounted<br>Freeing unused kernel image (initmem) memory: 956K<br>Write protecting the kernel read-only data: 14336k<br>Freeing unused kernel image (text/rodata gap) memory: 2044K<br>Freeing unused kernel image (rodata/data gap) memory: 48K<br>Run /sbin/init as init process<br>random: fast init done<br>EXT4-fs (sda): re-mounted. Opts: (null). Quota mode: disabled.<br>Starting syslogd: OK<br>Starting klogd: OK<br>Running sysctl: OK<br>Saving random seed: random: dd: uninitialized urandom read (512 bytes read)<br>OK<br>Starting network: Waiting for interface eth0 to appear............... timeout!<br>run-parts: /etc/network/if-pre-up.d/wait_iface: exit status 1<br>FAIL<br><br>Welcome to Buildroot<br>buildroot login: root<br># /usr/lib/ltp-testsuite/testcases/bin/ioctl_loop05<br>tst_test.c:1363: TINFO: Timeout per run is 0h 05m 00s<br>tst_test.c:1115: TINFO: ext2/ext3/ext4 is supported by the test<br>tst_device.c:88: TINFO: Found free device 0 '/dev/loop0'<br>loop0: detected capacity change from 0 to 2048<br>tst_device.c:522: TINFO: Debug: Device numbers: 8/0</div><div class="gmail_quote">tst_device.c:527: TINFO: Debug: 14 1 8:0 / / rw,relatime - ext2 /dev/root rw<br>tst_device.c:543: TINFO: Debug: devneme=/dev/root<br>tst_device.c:548: TWARN: stat(/dev/root) failed: ENOENT (2)<br><br>Summary:<br>passed   0<br>failed   0<br>broken   0<br>skipped  0<br>warnings 1<br># ln -s /dev/sda /dev/root<br># /usr/lib/ltp-testsuite/testcases/bin/ioctl_loop05<br>tst_test.c:1363: TINFO: Timeout per run is 0h 05m 00s<br>tst_test.c:1115: TINFO: ext2/ext3/ext4 is supported by the test<br>tst_device.c:88: TINFO: Found free device 0 '/dev/loop0'<br>loop0: detected capacity change from 0 to 2048<br>tst_device.c:522: TINFO: Debug: Device numbers: 8/0</div><div class="gmail_quote">tst_device.c:527: TINFO: Debug: 14 1 8:0 / / rw,relatime - ext2 /dev/root rw<br>tst_device.c:543: TINFO: Debug: devneme=/dev/root<br>ioctl_loop05.c:126: TINFO: backing dev(/dev/root) logical_block_size is 512<br>ioctl_loop05.c:62: TINFO: Without setting lo_offset or sizelimit<br>ioctl_loop05.c:45: TINFO: In dio mode<br>ioctl_loop05.c:48: TPASS: lo_flags has LO_FLAGS_DIRECT_IO flag<br>ioctl_loop05.c:52: TPASS: /sys/block/loop0/loop/dio = 1<br>ioctl_loop05.c:45: TINFO: In non dio mode<br>ioctl_loop05.c:50: TPASS: lo_flags doesn't have LO_FLAGS_DIRECT_IO flag<br>ioctl_loop05.c:52: TPASS: /sys/block/loop0/loop/dio = 0<br>ioctl_loop05.c:69: TINFO: With offset equal to logical_block_size<br>loop0: detected capacity change from 2048 to 2047<br>ioctl_loop05.c:74: TPASS: LOOP_SET_DIRECT_IO succeeded<br>ioctl_loop05.c:45: TINFO: In dio mode<br>ioctl_loop05.c:48: TPASS: lo_flags has LO_FLAGS_DIRECT_IO flag<br>ioctl_loop05.c:52: TPASS: /sys/block/loop0/loop/dio = 1<br>ioctl_loop05.c:81: TINFO: With nonzero offset less than logical_block_size<br>ioctl_loop05.c:92: TPASS: LOOP_SET_DIRECT_IO failed as expected: EINVAL (22)<br><br>Summary:<br>passed   8<br>failed   0<br>broken   0<br>skipped  0<br>warnings 0<br><br>here the same system on a btrfs<br><br>VFS: Mounted root (btrfs filesystem) on device 0:13.<br>random: fast init done<br>devtmpfs: mounted<br>Freeing unused kernel image (initmem) memory: 956K<br>Write protecting the kernel read-only data: 14336k<br>Freeing unused kernel image (text/rodata gap) memory: 2044K<br>Freeing unused kernel image (rodata/data gap) memory: 48K<br>Run /sbin/init as init process<br>BTRFS info (device sda): disk space caching is enabled<br>Starting syslogd: OK<br>Starting klogd: OK<br>Running sysctl: OK<br>Saving random seed: random: dd: uninitialized urandom read (512 bytes read)<br>OK<br>Starting network: Waiting for interface eth0 to appear............... timeout!<br>run-parts: /etc/network/if-pre-up.d/wait_iface: exit status 1<br>FAIL<br><br>Welcome to Buildroot<br>buildroot login: root<br># kill 71<br># umount /tmp<br># umount /run<br># /usr/lib/ltp-testsuite/testcases/bin/ioctl_loop05<br>tst_test.c:1363: TINFO: Timeout per run is 0h 05m 00s<br>tst_test.c:1115: TINFO: btrfs is supported by the test<br>tst_device.c:88: TINFO: Found free device 0 '/dev/loop0'<br>loop0: detected capacity change from 0 to 2048<br>tst_device.c:522: TINFO: Debug: Device numbers: 0/14</div><div class="gmail_quote">tst_device.c:527: TINFO: Debug: 15 1 0:13 / / rw,relatime - btrfs /dev/root rw,space_cache,subvolid=5,subvol=/<br>tst_device.c:527: TINFO: Debug: 16 15 0:5 / /dev rw,relatime - devtmpfs devtmpfs rw,size=505416k,nr_inodes=126354,mode=755<br>tst_device.c:527: TINFO: Debug: 14 15 0:15 / /proc rw,relatime - proc proc rw<br>tst_device.c:527: TINFO: Debug: 17 16 0:16 / /dev/pts rw,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666<br>tst_device.c:527: TINFO: Debug: 18 16 0:17 / /dev/shm rw,relatime - tmpfs tmpfs rw,mode=777<br>tst_device.c:527: TINFO: Debug: 21 15 0:20 / /sys rw,relatime - sysfs sysfs rw<br>tst_device.c:543: TINFO: Debug: devneme=<br>tst_device.c:545: TBROK: Cannot find block device for /tmp/iocz4RUVG/test.img<br><br>Summary:<br>passed   0<br>failed   0<br>broken   1<br>skipped  0<br>warnings 0<br># ln -s /dev/sda /dev/root<br># /usr/lib/ltp-testsuite/testcases/bin/ioctl_loop05<br>tst_test.c:1363: TINFO: Timeout per run is 0h 05m 00s<br>tst_test.c:1115: TINFO: btrfs is supported by the test<br>tst_device.c:88: TINFO: Found free device 0 '/dev/loop0'<br>loop0: detected capacity change from 0 to 2048<br>tst_device.c:522: TINFO: Debug: Device numbers: 0/14</div><div class="gmail_quote">tst_device.c:527: TINFO: Debug: 15 1 0:13 / / rw,relatime - btrfs /dev/root rw,space_cache,subvolid=5,subvol=/<br>tst_device.c:527: TINFO: Debug: 16 15 0:5 / /dev rw,relatime - devtmpfs devtmpfs rw,size=505416k,nr_inodes=126354,mode=755<br>tst_device.c:527: TINFO: Debug: 14 15 0:15 / /proc rw,relatime - proc proc rw<br>tst_device.c:527: TINFO: Debug: 17 16 0:16 / /dev/pts rw,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666<br>tst_device.c:527: TINFO: Debug: 18 16 0:17 / /dev/shm rw,relatime - tmpfs tmpfs rw,mode=777<br>tst_device.c:527: TINFO: Debug: 21 15 0:20 / /sys rw,relatime - sysfs sysfs rw<br>tst_device.c:543: TINFO: Debug: devneme=<br>tst_device.c:545: TBROK: Cannot find block device for /tmp/ioctVo52r/test.img<br><br>Summary:<br>passed   0<br>failed   0<br>broken   1<br>skipped  0<br>warnings 0<br>#</div><div class="gmail_quote"><br></div><div class="gmail_quote">a stat on the /, results in a couple of minor/major that is different from the </div><div class="gmail_quote">couple listed in the mountinfo. This leads, as a result, a test failure.</div><div class="gmail_quote"><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
><br>
> This solution requires sysfs to be mounted in /sys, but considering many <br>
> tests depends on the same, including the ioctl_loop05 that triggered this <br>
> patch, this requirement is not too restricted, and the old mountinfo can be <br>
> dropped altogether.<br>
<br>
The mountinfo method is not such a maintenance issue that it needs to be<br>
removed IMO. Possibly it could be replaced by tst_stat_mount_dev<br>
instead, but we're cautious about touching this function.<br></blockquote><div><br></div><div>tst_find_backing_dev(), the function that is the target of this patch, seems to </div><div>be referenced in only a couple of points in all the LTP test suite.<br>One place is in the ioctl_loop05 test, the other reference I found is in the </div><div>lib/tst_device.c - tst_dev_block_size().  tst_dev_block_size() is a function <br></div><div>that seems not to be referenced by any test.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
To be clear, I'm not sure anyone compiles Linux without /sys then tries<br>
to run LTP on it. However the fact that it is possible to remove /sys is<br>
another signal (in addition to BTRFS) that the situation is complicated.<br></blockquote><div><br></div><div>Indeed, if we want to have a test that works in all the possible scenarios, </div><div>it needs additional work. </div><div>But IMHO, keeping the mountinfo strategy gives no advantage over not </div><div>having it. </div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
><br>
> $ sudo /usr/lib/ltp-testsuite/testcases/bin/ioctl_loop05<br>
> tst_test.c:1363: TINFO: Timeout per run is 0h 05m 00s<br>
> tst_test.c:1115: TINFO: ext2/ext3/ext4 is supported by the test<br>
> tst_device.c:91: TINFO: Found free device 0 '/dev/loop0'<br>
> loop0: detected capacity change from 0 to 2048<br>
> tst_device.c:570: TINFO: Device name retrived through mountinfo<br>
> ioctl_loop05.c:126: TINFO: backing dev(/dev/root) logical_block_size is 512<br>
> ioctl_loop05.c:62: TINFO: Without setting lo_offset or sizelimit<br>
> ioctl_loop05.c:45: TINFO: In dio mode<br>
> ioctl_loop05.c:48: TPASS: lo_flags has LO_FLAGS_DIRECT_IO flag<br>
> ioctl_loop05.c:52: TBROK: Failed to open FILE '/sys/block/loop0/loop/dio' for reading: ENOENT (2)<br>
><br>
> Summary:<br>
> passed   1<br>
> failed   0<br>
> broken   1<br>
> skipped  0<br>
> warnings 0<br>
><br>
> The example here shows what happen if sysfs is not mounted and the<br>
> mountinfo method is used: the tests that depends on sysfs fail with<br>
> broken and not just warn.<br>
><br>
> Signed-off-by: Richard Palethorpe <<a href="mailto:rpalethorpe@suse.com" target="_blank">rpalethorpe@suse.com</a>><br>
> Signed-off-by: Alessandro Carminati <<a href="mailto:alessandro.carminati@gmail.com" target="_blank">alessandro.carminati@gmail.com</a>><br>
> ---<br>
>  lib/tst_device.c | 41 ++++++++++-------------------------------<br>
>  1 file changed, 10 insertions(+), 31 deletions(-)<br>
><br>
> diff --git a/lib/tst_device.c b/lib/tst_device.c<br>
> index 8419b80c3..4ccb71ac8 100644<br>
> --- a/lib/tst_device.c<br>
> +++ b/lib/tst_device.c<br>
> @@ -520,48 +520,27 @@ void tst_find_backing_dev(const char *path, char *dev)<br>
>  {<br>
>       struct stat buf;<br>
>       FILE *file;<br>
> -     char line[PATH_MAX];<br>
> -     char *pre = NULL;<br>
> -     char *next = NULL;<br>
> -     unsigned int dev_major, dev_minor, line_mjr, line_mnr;<br>
> -     unsigned int len, best_match_len = 1;<br>
> -     char mnt_point[PATH_MAX];<br>
> +     unsigned int dev_major, dev_minor;<br>
> +     char uevent_path[PATH_MAX];<br>
> +     char dev_name[NAME_MAX];<br>
>  <br>
>       if (stat(path, &buf) < 0)<br>
>               tst_brkm(TWARN | TERRNO, NULL, "stat() failed");<br>
>  <br>
> +     *dev = '\0';<br>
>       dev_major = major(buf.st_dev);<br>
>       dev_minor = minor(buf.st_dev);<br>
> -     file = SAFE_FOPEN(NULL, "/proc/self/mountinfo", "r");<br>
> -     *dev = '\0';<br>
> -<br>
> -     while (fgets(line, sizeof(line), file)) {<br>
> -             if (sscanf(line, "%*d %*d %d:%d %*s %s",<br>
> -                     &line_mjr, &line_mnr, mnt_point) != 3)<br>
> -                     continue;<br>
>  <br>
> -             pre = strstr(line, " - ");<br>
> -             pre = strtok_r(pre, " ", &next);<br>
> -             pre = strtok_r(NULL, " ", &next);<br>
> -             pre = strtok_r(NULL, " ", &next);<br>
> +     sprintf(uevent_path,<br>
> +             "/sys/dev/block/%d:%d/uevent", dev_major, dev_minor);<br>
>  <br>
> -             if (line_mjr == dev_major && line_mnr == dev_minor) {<br>
> -                     strcpy(dev, pre);<br>
> -                     break;<br>
> -             }<br>
> +     if (!access(uevent_path, R_OK)) {<br>
> +             FILE_LINES_SCANF(NULL, uevent_path, "DEVNAME=%s", dev_name);<br>
>  <br>
> -             len = count_match_len(path, mnt_point);<br>
> -             if (len > best_match_len) {<br>
> -                     strcpy(dev, pre);<br>
> -                     best_match_len = len;<br>
> -             }<br>
> +             if (dev_name[0])<br>
> +                     sprintf(dev, "/dev/%s", dev_name);<br>
>       }<br>
>  <br>
> -     SAFE_FCLOSE(NULL, file);<br>
> -<br>
> -     if (!*dev)<br>
> -             tst_brkm(TBROK, NULL, "Cannot find block device for %s", path);<br>
> -<br>
>       if (stat(dev, &buf) < 0)<br>
>               tst_brkm(TWARN | TERRNO, NULL, "stat(%s) failed", dev);<br>
<br>
<br>
-- <br>
Thank you,<br>
Richard.<br></blockquote><div><br>Thank you for your time.</div><div>Alessandro <br></div></div></div>