Conky: Add disk by-partuuid to diskio

Created on 12 Nov 2016  路  21Comments  路  Source: brndnmtthws/conky

Would like to be able to use diskio with partuuid instead of label, because labels have a tendency to change after reboots. So far, I've tried modifying diskio.cc to change the identifier from label to partuuid, but Conky segfaults and crashes. It doesn't give any errors about the disks not existing, however. I'm guessing this has something to do with the by-partuuid names containing hyphens?

Changed:
if (strncmp(s, "label:", 6) == 0) {
snprintf(&(device_name[0]), text_buffer_size.get(*state), "/dev/disk/by-label/%s", s+6);
rpbuf = realpath(&device_name[0], NULL);
} else {
rpbuf = realpath(s, NULL);
}

if (rpbuf) {
    strncpy(&device_s[0], rpbuf, text_buffer_size.get(*state));
    free(rpbuf);
} else {
    strncpy(&device_s[0], s, text_buffer_size.get(*state));
}

if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__linux__)

if (strncmp(&device_s[0], "/dev/", 5) == 0) {
    device_s.erase(device_s.begin(), device_s.begin()+5);
}

endif

strncpy(&(device_name[0]), &device_s[0], text_buffer_size.get(*state));

snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s", &(device_name[0]));

To:
if (strncmp(s, "partuuid:", 6) == 0) {
snprintf(&(device_name[0]), text_buffer_size.get(*state), "/dev/disk/by-partuuid/%s", s+6);
rpbuf = realpath(&device_name[0], NULL);
} else {
rpbuf = realpath(s, NULL);
}

    if (rpbuf) {
            strncpy(&device_s[0], rpbuf, text_buffer_size.get(*state));
            free(rpbuf);
    } else {
            strncpy(&device_s[0], s, text_buffer_size.get(*state));
    }

if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__linux__)

    if (strncmp(&device_s[0], "/dev/disk/by-partuuid/", 5) == 0) {
            device_s.erase(device_s.begin(), device_s.begin()+5);
    }

endif

    strncpy(&(device_name[0]), &device_s[0], text_buffer_size.get(*state));

    snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/disk/by-partuuid/%s", &(device_name[0]));

My knowledge of programming is limited to shell scripting, pretty much what I've picked up by reading online, so I don't know anything about c.

enhancement

Most helpful comment

Now valid sda1, won't print errors. Here's valid diff that does pathname resolution and saves it in a rpbuf2 and uses that path in the stat() call to see whether it exists or not.

diff --git a/src/diskio.cc b/src/diskio.cc
index fb590f03..e989c695 100644
--- a/src/diskio.cc
+++ b/src/diskio.cc
@@ -60,6 +60,7 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
       device_s(text_buffer_size.get(*state));
   struct diskio_stat *cur = &stats;
   char *rpbuf;
+  char rpbuf2[256];

   if (s == nullptr) {
     return &stats;
@@ -69,6 +70,11 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
     snprintf(&(device_name[0]), text_buffer_size.get(*state),
              "/dev/disk/by-label/%s", s + 6);
     rpbuf = realpath(&device_name[0], nullptr);
+  } else if (0 == (strncmp(s, "partuuid:", 9))) {
+    snprintf(&(device_name[0]), text_buffer_size.get(*state),
+             "/dev/disk/by-partuuid/%s", s + 9);
+    rpbuf = realpath(&device_name[0], nullptr);
+    snprintf(rpbuf2, 255, "%s", rpbuf);
   } else {
     rpbuf = realpath(s, nullptr);
   }
@@ -92,12 +98,19 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
    * On Solaris we currently don't use the name of disk's special file so
    * this test is useless.
    */
-  snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
-           &(device_name[0]));

-  if ((stat(&(stat_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
-    NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+  if (strncmp(s, "label:", 6) == 0) {
+    snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
+           &(device_name[0]));
+    if ((stat(&(stat_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
+      NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+    }
+  } else if (0 == (strncmp(s, "partuuid:", 9))) {
+    if ((stat(rpbuf2, &sb) != 0) || !S_ISBLK(sb.st_mode)) {
+      NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+    }
   }
+
 #endif

   /* lookup existing */

All 21 comments

@su8 See fs_* too just in case since they accept (fs) paths.

@lasers Can you try this diff:

diff --git a/src/diskio.cc b/src/diskio.cc
index fb590f03..5abaa2d0 100644
--- a/src/diskio.cc
+++ b/src/diskio.cc
@@ -69,6 +69,10 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
     snprintf(&(device_name[0]), text_buffer_size.get(*state),
              "/dev/disk/by-label/%s", s + 6);
     rpbuf = realpath(&device_name[0], nullptr);
+  } else if (0 == (strncmp(s, "uuid:", 5))) {
+    snprintf(&(device_name[0]), text_buffer_size.get(*state),
+             "/dev/disk/by-partuuid/%s", s + 5);
+    rpbuf = realpath(&device_name[0], nullptr);
   } else {
     rpbuf = realpath(s, nullptr);
   }
@@ -92,8 +96,14 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
    * On Solaris we currently don't use the name of disk's special file so
    * this test is useless.
    */
-  snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
+
+  if (strncmp(s, "label:", 6) == 0) {
+    snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
            &(device_name[0]));
+  } else {
+    snprintf(&(stat_name[0]), text_buffer_size.get(*state),
+          "/dev/disk/by-partuuid/%s", &(device_name[0]));
+  }

   if ((stat(&(stat_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
     NORM_ERR("diskio device '%s' does not exist", &device_s[0]);

To get your disks uuid type:

realpath /dev/disk/by-partuuid/  # <--- tab to complete

or just type blkid and copy the last part PARTUUID=

In your conky.conf type ${diskio uuid:a8a1aaa4-02}

It worked, but is it normal to print this at startup?

conky: diskio device 'sda1' does not exist
conky: diskio device 'sda2' does not exist

EDIT: Also, I think uuid is misleading. Maybe use partuuid instead?

Just moved the NORM_ERR() call into the if (strncmp(s, "label:", 6) == 0) { block.

diff --git a/src/diskio.cc b/src/diskio.cc
index fb590f03..595b8c82 100644
--- a/src/diskio.cc
+++ b/src/diskio.cc
@@ -69,6 +69,10 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
     snprintf(&(device_name[0]), text_buffer_size.get(*state),
              "/dev/disk/by-label/%s", s + 6);
     rpbuf = realpath(&device_name[0], nullptr);
+  } else if (0 == (strncmp(s, "partuuid:", 9))) {
+    snprintf(&(device_name[0]), text_buffer_size.get(*state),
+             "/dev/disk/by-partuuid/%s", s + 9);
+    rpbuf = realpath(&device_name[0], nullptr);
   } else {
     rpbuf = realpath(s, nullptr);
   }
@@ -92,12 +96,19 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
    * On Solaris we currently don't use the name of disk's special file so
    * this test is useless.
    */
-  snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
+
+  if (strncmp(s, "label:", 6) == 0) {
+    snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
            &(device_name[0]));

-  if ((stat(&(stat_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
-    NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+    if ((stat(&(stat_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
+      NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+    }
+  } else {
+    snprintf(&(stat_name[0]), text_buffer_size.get(*state),
+          "/dev/disk/by-partuuid/%s", &(device_name[0]));
   }
+
 #endif

   /* lookup existing */

edit: as you requested the partuuid replaced uuid.

Go ahead and open up a PR with those changes, don't forget to update the variables in the wiki/documentation.

It'll also print 0B on invalid partuuid. EDIT: Let's avoid that.

That's acceptable as the error is printed in the terminal conky: diskio device 'label:sda3' does not exist

I see... It does that for label, but not for uuid partuuid.

The code expects block device, but the partuuid is pointing to symbolic link.

Can you check symbolic link or nonexistent file? We can make conky better by throwing messages when things does not match up. Also, my personal-for-now conky module will throw errors on lines starting with conky: {message}. I think it just should print an invalid message once (then 0B) rather than nothing.

diff --git a/src/diskio.cc b/src/diskio.cc
index fb590f03..dc6d5f4c 100644
--- a/src/diskio.cc
+++ b/src/diskio.cc
@@ -69,6 +69,10 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
     snprintf(&(device_name[0]), text_buffer_size.get(*state),
              "/dev/disk/by-label/%s", s + 6);
     rpbuf = realpath(&device_name[0], nullptr);
+  } else if (0 == (strncmp(s, "partuuid:", 9))) {
+    snprintf(&(device_name[0]), text_buffer_size.get(*state),
+             "/dev/disk/by-partuuid/%s", s + 9);
+    rpbuf = realpath(&device_name[0], nullptr);
   } else {
     rpbuf = realpath(s, nullptr);
   }
@@ -92,12 +96,20 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
    * On Solaris we currently don't use the name of disk's special file so
    * this test is useless.
    */
-  snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
+
+  if (strncmp(s, "label:", 6) == 0) {
+    snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
            &(device_name[0]));

-  if ((stat(&(stat_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
-    NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+    if ((stat(&(stat_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
+      NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+    }
+  } else {
+    if ((stat(&(device_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
+      NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+    }
   }
+
 #endif

   /* lookup existing */
conky: diskio device 'sda1' does not exist
conky: diskio device 'sda2' does not exist
conky: diskio device 'partuuid:40740869-03' does not exist
conky: diskio device 'partuuid:40740869-04' does not exist
conky: diskio device 'uuid:40740869-04' does not exist
conky: diskio device 'uuid:40740869-05' does not exist
conky: diskio device 'fake_uuid:40740869-01' does not exist
conky: diskio device 'label:AntergosRootzzz' does not exist
    0B
    0B
    0B
    0B
    0B
    0B

Invalid keys fake_uuid works here.

conky: diskio device 'sda1' does not exist
conky: diskio device 'sda2' does not exist

Incorrect. I have this.

$ ls -al /dev/sda*                                                                         
brw-rw---- 1 root disk 8, 0 Aug  8 05:01 /dev/sda                                                                 
brw-rw---- 1 root disk 8, 1 Aug  8 05:01 /dev/sda1
brw-rw---- 1 root disk 8, 2 Aug  8 05:01 /dev/sda2

FYI: It does not print nonexistent sda1, sda2 on master branch so it's related to this diff. We do partuuid: prefix, right? Not misleading uuid.

I'm getting also conky: diskio device 'label:sda1' does not exist on label usage too. Performed git reset --hard and still get this error printed on the terminal.

Do you label your hard drives? You might meant sda1 and not label:sda1

Okay, I think I heard you first time. I always want to clear up potential confusions. Be back in an hour. Break time from conkying.

In the documentation it's written that we can use 'label:foo' - https://github.com/brndnmtthws/conky/wiki/Configuration-Variables , and the code does it's scanning to see whether the 'label:' was used or not.

Now valid sda1, won't print errors. Here's valid diff that does pathname resolution and saves it in a rpbuf2 and uses that path in the stat() call to see whether it exists or not.

diff --git a/src/diskio.cc b/src/diskio.cc
index fb590f03..e989c695 100644
--- a/src/diskio.cc
+++ b/src/diskio.cc
@@ -60,6 +60,7 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
       device_s(text_buffer_size.get(*state));
   struct diskio_stat *cur = &stats;
   char *rpbuf;
+  char rpbuf2[256];

   if (s == nullptr) {
     return &stats;
@@ -69,6 +70,11 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
     snprintf(&(device_name[0]), text_buffer_size.get(*state),
              "/dev/disk/by-label/%s", s + 6);
     rpbuf = realpath(&device_name[0], nullptr);
+  } else if (0 == (strncmp(s, "partuuid:", 9))) {
+    snprintf(&(device_name[0]), text_buffer_size.get(*state),
+             "/dev/disk/by-partuuid/%s", s + 9);
+    rpbuf = realpath(&device_name[0], nullptr);
+    snprintf(rpbuf2, 255, "%s", rpbuf);
   } else {
     rpbuf = realpath(s, nullptr);
   }
@@ -92,12 +98,19 @@ struct diskio_stat *prepare_diskio_stat(const char *s) {
    * On Solaris we currently don't use the name of disk's special file so
    * this test is useless.
    */
-  snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
-           &(device_name[0]));

-  if ((stat(&(stat_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
-    NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+  if (strncmp(s, "label:", 6) == 0) {
+    snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
+           &(device_name[0]));
+    if ((stat(&(stat_name[0]), &sb) != 0) || !S_ISBLK(sb.st_mode)) {
+      NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+    }
+  } else if (0 == (strncmp(s, "partuuid:", 9))) {
+    if ((stat(rpbuf2, &sb) != 0) || !S_ISBLK(sb.st_mode)) {
+      NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
+    }
   }
+
 #endif

   /* lookup existing */

@su8 LGTM!!! Push a new branch to this repo. Open a PR from this repo and not from su8:master!

Go ahead and open up a PR :heart_eyes:

@su8 Sure. Push it to your su8:master to retain your author. EDIT: Don't open a PR.

Closed via https://github.com/brndnmtthws/conky/pull/598. Try it now! @krakenfury :sweat_smile:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nwwt picture nwwt  路  5Comments

oberon-manjaro picture oberon-manjaro  路  4Comments

moyamo picture moyamo  路  3Comments

leahneukirchen picture leahneukirchen  路  3Comments

LeoIannacone picture LeoIannacone  路  3Comments