summaryrefslogtreecommitdiff
path: root/multiload/linux-proc.c
diff options
context:
space:
mode:
authorVictor Kareh <[email protected]>2019-07-10 14:22:51 -0400
committerraveit65 <[email protected]>2019-07-13 15:55:47 +0200
commitac49426ee506384ee66b3ba1ef4349216aad82ea (patch)
treea7cfcc90c2cbc3483a2f256184fe38cf39576367 /multiload/linux-proc.c
parent69127b30999b223773f29458ecf2e12239eca95e (diff)
downloadmate-applets-ac49426ee506384ee66b3ba1ef4349216aad82ea.tar.bz2
mate-applets-ac49426ee506384ee66b3ba1ef4349216aad82ea.tar.xz
multiload: Use /proc/diskstats for NVMe drives
Since glibtop does not support NVMe drives, we rely on /proc/diskstats to tell use load information for NVMe drives. If diskstats is not present it returns to glibtop as a fallback.
Diffstat (limited to 'multiload/linux-proc.c')
-rw-r--r--multiload/linux-proc.c77
1 files changed, 58 insertions, 19 deletions
diff --git a/multiload/linux-proc.c b/multiload/linux-proc.c
index c661dd8f..355fe040 100644
--- a/multiload/linux-proc.c
+++ b/multiload/linux-proc.c
@@ -100,14 +100,14 @@ GetDiskLoad (int Maximum, int data [3], LoadGraph *g)
static guint64 lastread = 0, lastwrite = 0;
static AutoScaler scaler;
- glibtop_mountlist mountlist;
- glibtop_mountentry *mountentries;
guint i;
int max;
+ gboolean nvme_diskstats;
guint64 read, write;
guint64 readdiff, writediff;
+ nvme_diskstats = g_settings_get_boolean (g->multiload->settings, "diskload-nvme-diskstats");
if(first_call)
{
@@ -116,32 +116,71 @@ GetDiskLoad (int Maximum, int data [3], LoadGraph *g)
read = write = 0;
- mountentries = glibtop_get_mountlist (&mountlist, FALSE);
-
- for (i = 0; i < mountlist.number; i++)
+ if (nvme_diskstats)
{
- struct statvfs statresult;
- glibtop_fsusage fsusage;
+ FILE *fdr;
+ char line[255];
+ guint64 s_read, s_write;
- if (strstr (mountentries[i].devname, "/dev/") == NULL)
- continue;
+ fdr = fopen("/proc/diskstats", "r");
+ if (!fdr)
+ {
+ g_settings_set_boolean (g->multiload->settings, "diskload-nvme-diskstats", FALSE);
+ return;
+ }
- if (strstr (mountentries[i].mountdir, "/media/") != NULL)
- continue;
+ while (fgets(line, 255, fdr))
+ {
+ /* Match main device, rather than individual partitions (e.g. nvme0n1) */
+ if (!g_regex_match_simple("\\snvme\\d+\\w+\\d+\\s", line, 0, 0))
+ {
+ continue;
+ }
+
+ /*
+ 6 - sectors read
+ 10 - sectors written
+ */
+ if (sscanf(line, "%*d %*d %*s %*d %*d %ld %*d %*d %*d %ld", &s_read, &s_write) == 2)
+ {
+ read += 512 * s_read;
+ write += 512 * s_write;
+ }
+ }
+ fclose(fdr);
+ }
+ else
+ {
+ glibtop_mountlist mountlist;
+ glibtop_mountentry *mountentries;
+
+ mountentries = glibtop_get_mountlist (&mountlist, FALSE);
- if (statvfs (mountentries[i].mountdir, &statresult) < 0)
+ for (i = 0; i < mountlist.number; i++)
{
- g_debug ("Failed to get statistics for mount entry: %s. Reason: %s. Skipping entry.",
- mountentries[i].mountdir, strerror(errno));
- continue;
+ struct statvfs statresult;
+ glibtop_fsusage fsusage;
+
+ if (strstr (mountentries[i].devname, "/dev/") == NULL)
+ continue;
+
+ if (strstr (mountentries[i].mountdir, "/media/") != NULL)
+ continue;
+
+ if (statvfs (mountentries[i].mountdir, &statresult) < 0)
+ {
+ g_debug ("Failed to get statistics for mount entry: %s. Reason: %s. Skipping entry.",
+ mountentries[i].mountdir, strerror(errno));
+ continue;
+ }
+
+ glibtop_get_fsusage(&fsusage, mountentries[i].mountdir);
+ read += fsusage.read; write += fsusage.write;
}
- glibtop_get_fsusage(&fsusage, mountentries[i].mountdir);
- read += fsusage.read; write += fsusage.write;
+ g_free(mountentries);
}
- g_free(mountentries);
-
readdiff = read - lastread;
writediff = write - lastwrite;