summaryrefslogtreecommitdiff
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
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.
-rw-r--r--multiload/linux-proc.c77
-rw-r--r--multiload/org.mate.panel.applet.multiload.gschema.xml.in4
-rw-r--r--multiload/properties.c45
3 files changed, 106 insertions, 20 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;
diff --git a/multiload/org.mate.panel.applet.multiload.gschema.xml.in b/multiload/org.mate.panel.applet.multiload.gschema.xml.in
index d0d27a32..53bf8c76 100644
--- a/multiload/org.mate.panel.applet.multiload.gschema.xml.in
+++ b/multiload/org.mate.panel.applet.multiload.gschema.xml.in
@@ -141,6 +141,10 @@
<default>'#000000'</default>
<summary>Background color for disk load graph</summary>
</key>
+ <key name="diskload-nvme-diskstats" type="b">
+ <default>false</default>
+ <summary>Uses /proc/diskstats to determine NVMe disk load</summary>
+ </key>
<key name="system-monitor" type="s">
<default>'mate-system-monitor.desktop'</default>
<summary>The desktop description file to execute as the system monitor</summary>
diff --git a/multiload/properties.c b/multiload/properties.c
index f78c3447..de4c060b 100644
--- a/multiload/properties.c
+++ b/multiload/properties.c
@@ -324,6 +324,49 @@ add_color_selector(GtkWidget *page, gchar *name, gchar *key, MultiloadApplet *ma
return;
}
+/* save the checkbox option to gsettings and apply it on the applet */
+static void
+checkbox_toggled_cb(GtkCheckButton *checkbox, gchar *key)
+{
+ MultiloadApplet *ma;
+ gboolean option;
+
+ ma = g_object_get_data (G_OBJECT (checkbox), "MultiloadApplet");
+
+ option = g_settings_get_boolean(ma->settings, key);
+ g_settings_set_boolean(ma->settings, key, !option);
+
+ return;
+}
+
+/* adds checkbox option */
+static void
+add_checkbox(GtkWidget *page, gchar *name, gchar *key, MultiloadApplet *ma)
+{
+ GtkWidget *vbox;
+ GtkWidget *checkbox;
+ gboolean option;
+
+ option = g_settings_get_boolean (ma->settings, key);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ checkbox = gtk_check_button_new_with_mnemonic (name);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(checkbox), option);
+
+ gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(page), vbox, FALSE, FALSE, 0);
+
+ g_object_set_data (G_OBJECT (checkbox), "MultiloadApplet", ma);
+
+ g_signal_connect(G_OBJECT(checkbox), "toggled", G_CALLBACK(checkbox_toggled_cb), key);
+
+ if ( ! g_settings_is_writable (ma->settings, key))
+ hard_set_sensitive (vbox, FALSE);
+
+ return;
+}
+
/* creates the properties dialog using up-to-the-minute info from gsettings */
static void
fill_properties(GtkWidget *dialog, MultiloadApplet *ma)
@@ -638,6 +681,7 @@ fill_properties(GtkWidget *dialog, MultiloadApplet *ma)
add_color_selector (page, _("_Read"), "diskload-color0", ma);
add_color_selector (page, _("_Write"), "diskload-color1", ma);
add_color_selector (page, _("_Background"), "diskload-color2", ma);
+ add_checkbox(page, _("Use diskstats for NVMe"), "diskload-nvme-diskstats", ma);
title = g_strconcat ("<span weight=\"bold\">", _("Network speed thresholds"), "</span>", NULL);
label = gtk_label_new (title);
@@ -667,7 +711,6 @@ fill_properties(GtkWidget *dialog, MultiloadApplet *ma)
label_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
- orient = mate_panel_applet_get_orient(ma->applet);
label_text = g_strdup(_("Threshold 1: "));
label = gtk_label_new_with_mnemonic(label_text);
gtk_label_set_xalign (GTK_LABEL (label), 0.0f);