[v2] tst_dev_bytes_written: parsing /proc/diskstats instead of sys file
diff mbox series

Message ID 1578299418-4961-1-git-send-email-xuyang2018.jy@cn.fujitsu.com
State Superseded
Headers show
Series
  • [v2] tst_dev_bytes_written: parsing /proc/diskstats instead of sys file
Related show

Commit Message

Yang Xu Jan. 6, 2020, 8:30 a.m. UTC
Now, tst_dev_bytes_written api can get the whole disk stat correctly(such as /dev/sda),
but can not get partition stat correctly(such as /dev/sda5).
fail as below:
export LTP_DEV=/dev/sda5
tst_device.c:388: CONF: Test device stat file: /sys/block/sda5/stat not found

To fix this, use /proc/diskstats to parse instead of /sys/block/<devices>/stat.
Data format as same as diskstats_show function in kernel genhd.c[1].

Also, add hint when loop driver doesn't support blk-mq[2]. So that, user can export
LTP_DEV to test.

[1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/block/genhd.c
[2]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b5dd2f60

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 lib/tst_device.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

Comments

Sumit Garg Jan. 6, 2020, 9:16 a.m. UTC | #1
On Mon, 6 Jan 2020 at 14:00, Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> Now, tst_dev_bytes_written api can get the whole disk stat correctly(such as /dev/sda),
> but can not get partition stat correctly(such as /dev/sda5).
> fail as below:
> export LTP_DEV=/dev/sda5
> tst_device.c:388: CONF: Test device stat file: /sys/block/sda5/stat not found
>
> To fix this, use /proc/diskstats to parse instead of /sys/block/<devices>/stat.
> Data format as same as diskstats_show function in kernel genhd.c[1].
>
> Also, add hint when loop driver doesn't support blk-mq[2]. So that, user can export
> LTP_DEV to test.
>
> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/block/genhd.c
> [2]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b5dd2f60
>
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> ---
>  lib/tst_device.c | 26 ++++++++++++--------------
>  1 file changed, 12 insertions(+), 14 deletions(-)
>

Reviewed-by: Sumit Garg <sumit.garg@linaro.org>

> diff --git a/lib/tst_device.c b/lib/tst_device.c
> index 10f71901d..ad764a38d 100644
> --- a/lib/tst_device.c
> +++ b/lib/tst_device.c
> @@ -375,24 +375,22 @@ int tst_umount(const char *path)
>
>  unsigned long tst_dev_bytes_written(const char *dev)
>  {
> -       struct stat st;
> -       unsigned long dev_sec_write = 0, dev_bytes_written, io_ticks = 0;
> -       char dev_stat_path[1024];
> -
> -       snprintf(dev_stat_path, sizeof(dev_stat_path), "/sys/block/%s/stat",
> -                strrchr(dev, '/') + 1);
> +       unsigned long dev_sec_write = 0, dev_bytes_written;
> +       unsigned int io_ticks = 0;
> +       char fmt[1024];
>
> -       if (stat(dev_stat_path, &st) != 0)
> -               tst_brkm(TCONF, NULL, "Test device stat file: %s not found",
> -                        dev_stat_path);
> +       sprintf(fmt, "%%*4d %%*7d %s %%*lu %%*lu %%*lu %%*u %%*lu %%*lu %%lu %%*u %%*u %%u",
> +                       strrchr(dev, '/') + 1);
>
> -       SAFE_FILE_SCANF(NULL, dev_stat_path,
> -                       "%*s %*s %*s %*s %*s %*s %lu %*s %*s %lu",
> -                       &dev_sec_write, &io_ticks);
> +       SAFE_FILE_LINES_SCANF(NULL, "/proc/diskstats", fmt, &dev_sec_write, &io_ticks);
>
> +       /* If we create block device by attaching a free loop device, loop driver
> +        * needs to support blk-mq(commit b5dd2f6047c), so that kernel can get I/O
> +        * statistics about loop device.
> +        */
>         if (!io_ticks)
> -               tst_brkm(TCONF, NULL, "Test device stat file: %s broken",
> -                        dev_stat_path);
> +               tst_brkm(TCONF, NULL, "io_ticks on test device %s is always 0, "
> +                               "export LTP_DEV to test", dev);
>
>         dev_bytes_written = (dev_sec_write - prev_dev_sec_write) * 512;
>
> --
> 2.18.0
>
>
>
Cyril Hrubis Jan. 8, 2020, 1:12 p.m. UTC | #2
Hi!
> Now, tst_dev_bytes_written api can get the whole disk stat correctly(such as /dev/sda),
> but can not get partition stat correctly(such as /dev/sda5).
> fail as below:
> export LTP_DEV=/dev/sda5
> tst_device.c:388: CONF: Test device stat file: /sys/block/sda5/stat not found

It seems that in case of partitions the stat file is available under
/sys/block/sda/sda5/stat.

For NVME it's similar as:

/sys/block/nvme0n1/nvme0n1p1/stat

I do wonder if it wouldn't be easier to try to match the prefix of the
device name first, then try a directory with a full name after that.
Yang Xu Jan. 9, 2020, 8:35 a.m. UTC | #3
Hi
> Hi!
>> Now, tst_dev_bytes_written api can get the whole disk stat correctly(such as /dev/sda),
>> but can not get partition stat correctly(such as /dev/sda5).
>> fail as below:
>> export LTP_DEV=/dev/sda5
>> tst_device.c:388: CONF: Test device stat file: /sys/block/sda5/stat not found
> 
> It seems that in case of partitions the stat file is available under
> /sys/block/sda/sda5/stat.
> 
> For NVME it's similar as:
> 
> /sys/block/nvme0n1/nvme0n1p1/stat
> 
> I do wonder if it wouldn't be easier to try to match the prefix of the
> device name first, then try a directory with a full name after that.
Maybe, I am fine with your way(I tested it). I only  refer to kernel 
documention [1] .sysfs and proc file  use the same source for the 
information and so should not differ. So I use fixed format as kernel 
function to exact.  Also, I want to listen advise from Sumit.

[1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/iostats.rst

Best Regards
Yang Xu
>
Sumit Garg Jan. 9, 2020, 9:34 a.m. UTC | #4
Hi Cyril, Yang,

On Thu, 9 Jan 2020 at 14:05, Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> Hi
> > Hi!
> >> Now, tst_dev_bytes_written api can get the whole disk stat correctly(such as /dev/sda),
> >> but can not get partition stat correctly(such as /dev/sda5).
> >> fail as below:
> >> export LTP_DEV=/dev/sda5
> >> tst_device.c:388: CONF: Test device stat file: /sys/block/sda5/stat not found
> >
> > It seems that in case of partitions the stat file is available under
> > /sys/block/sda/sda5/stat.
> >
> > For NVME it's similar as:
> >
> > /sys/block/nvme0n1/nvme0n1p1/stat
> >
> > I do wonder if it wouldn't be easier to try to match the prefix of the
> > device name first, then try a directory with a full name after that.

I did checked earlier that we could use partition specific
sub-directory for "stat" file but I thought it would be complex in
comparison to referring a single file. But your implementation doesn't
look that complex.

> Maybe, I am fine with your way(I tested it). I only  refer to kernel
> documention [1] .sysfs and proc file  use the same source for the
> information and so should not differ. So I use fixed format as kernel
> function to exact.  Also, I want to listen advise from Sumit.
>

TBH, I think it's just a matter of taste. I am fine with either approach.

-Sumit

> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/iostats.rst
>
> Best Regards
> Yang Xu
> >
>
>
Cyril Hrubis Jan. 10, 2020, 12:30 p.m. UTC | #5
Hi!
> > Maybe, I am fine with your way(I tested it). I only  refer to kernel
> > documention [1] .sysfs and proc file  use the same source for the
> > information and so should not differ. So I use fixed format as kernel
> > function to exact.  Also, I want to listen advise from Sumit.
> >
> 
> TBH, I think it's just a matter of taste. I am fine with either approach.

I dot not like that much that we generate the scanf format string on the
fly in the version that parses /proc/diskstat.

In the end we have to merge one of them, I slightly prefer mine, but I
do not have a strong feelings about this.
Petr Vorel Jan. 15, 2020, 10:46 a.m. UTC | #6
Hi,

Reviewed-by: Petr Vorel <pvorel@suse.cz>

> > > Maybe, I am fine with your way(I tested it). I only  refer to kernel
> > > documention [1] .sysfs and proc file  use the same source for the
> > > information and so should not differ. So I use fixed format as kernel
> > > function to exact.  Also, I want to listen advise from Sumit.


> > TBH, I think it's just a matter of taste. I am fine with either approach.

> I dot not like that much that we generate the scanf format string on the
> fly in the version that parses /proc/diskstat.
+1

> In the end we have to merge one of them, I slightly prefer mine, but I
> do not have a strong feelings about this.
+1

If we merge Cyril's, I'd be for adding the hint about LTP_DEV (maybe as a
separate commit).

Thank you both for working on this fix.

Kind regards,
Petr
Cyril Hrubis Jan. 15, 2020, 10:58 a.m. UTC | #7
Hi!
> If we merge Cyril's, I'd be for adding the hint about LTP_DEV (maybe as a
> separate commit).

Maybe it would be a bit better to print short TINFO message in the case
of failure instead of adding comments into the source code...
Petr Vorel Jan. 15, 2020, 11:05 a.m. UTC | #8
Hi,

> > If we merge Cyril's, I'd be for adding the hint about LTP_DEV (maybe as a
> > separate commit).

> Maybe it would be a bit better to print short TINFO message in the case
> of failure instead of adding comments into the source code...
There is extended TCONF message in the patch. Yep, maybe just append the commend
to that message as well.

Kind regards,
Petr

Patch
diff mbox series

diff --git a/lib/tst_device.c b/lib/tst_device.c
index 10f71901d..ad764a38d 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -375,24 +375,22 @@  int tst_umount(const char *path)
 
 unsigned long tst_dev_bytes_written(const char *dev)
 {
-	struct stat st;
-	unsigned long dev_sec_write = 0, dev_bytes_written, io_ticks = 0;
-	char dev_stat_path[1024];
-
-	snprintf(dev_stat_path, sizeof(dev_stat_path), "/sys/block/%s/stat",
-		 strrchr(dev, '/') + 1);
+	unsigned long dev_sec_write = 0, dev_bytes_written;
+	unsigned int io_ticks = 0;
+	char fmt[1024];
 
-	if (stat(dev_stat_path, &st) != 0)
-		tst_brkm(TCONF, NULL, "Test device stat file: %s not found",
-			 dev_stat_path);
+	sprintf(fmt, "%%*4d %%*7d %s %%*lu %%*lu %%*lu %%*u %%*lu %%*lu %%lu %%*u %%*u %%u",
+			strrchr(dev, '/') + 1);
 
-	SAFE_FILE_SCANF(NULL, dev_stat_path,
-			"%*s %*s %*s %*s %*s %*s %lu %*s %*s %lu",
-			&dev_sec_write, &io_ticks);
+	SAFE_FILE_LINES_SCANF(NULL, "/proc/diskstats", fmt, &dev_sec_write, &io_ticks);
 
+	/* If we create block device by attaching a free loop device, loop driver
+	 * needs to support blk-mq(commit b5dd2f6047c), so that kernel can get I/O
+	 * statistics about loop device.
+	 */
 	if (!io_ticks)
-		tst_brkm(TCONF, NULL, "Test device stat file: %s broken",
-			 dev_stat_path);
+		tst_brkm(TCONF, NULL, "io_ticks on test device %s is always 0, "
+				"export LTP_DEV to test", dev);
 
 	dev_bytes_written = (dev_sec_write - prev_dev_sec_write) * 512;