summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoît Dejean <bdejean@src.gnome.org>2005-01-13 08:56:54 +0000
committerBenoît Dejean <bdejean@src.gnome.org>2005-01-13 08:56:54 +0000
commitfcb83e637dfc105d5136de419de865615f883ec2 (patch)
treed9964ce2821535b4ddf8e1c9a0b8709be12d595a
parent50e4e0701314260eb11ec260254c5a9451849941 (diff)
downloadlibgtop-fcb83e637dfc105d5136de419de865615f883ec2.tar.gz
Reworked. Should works with IDE, SCSI. DM support is ready, but i don't
* fsusage.c: (get_partition), (get_sys_path), (linux_2_6_0): Reworked. Should works with IDE, SCSI. DM support is ready, but i don't know why their /stat is empty ...
-rw-r--r--sysdeps/linux/ChangeLog6
-rw-r--r--sysdeps/linux/fsusage.c120
2 files changed, 81 insertions, 45 deletions
diff --git a/sysdeps/linux/ChangeLog b/sysdeps/linux/ChangeLog
index 8de4e6b5..8641029e 100644
--- a/sysdeps/linux/ChangeLog
+++ b/sysdeps/linux/ChangeLog
@@ -1,3 +1,9 @@
+2005-01-13 Benoît Dejean <TazForEver@dlfp.org>
+
+ * fsusage.c: (get_partition), (get_sys_path), (linux_2_6_0): Reworked.
+ Should works with IDE, SCSI. DM support is ready, but i don't know why
+ their /stat is empty ...
+
2005-01-12 Benoît Dejean <TazForEver@dlfp.org>
* procopenfiles.c: (get_all_sockets),
diff --git a/sysdeps/linux/fsusage.c b/sysdeps/linux/fsusage.c
index e6035577..1be17cf8 100644
--- a/sysdeps/linux/fsusage.c
+++ b/sysdeps/linux/fsusage.c
@@ -5,9 +5,10 @@
#include <glib.h>
-#include <mntent.h>
-#include <fcntl.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <linux/kdev_t.h>
#include <stdio.h>
#include <string.h>
@@ -24,68 +25,97 @@ _glibtop_linux_get_fsusage_read_write(glibtop *server,
* linux/Documentation/iostats.txt
*/
-static void linux_2_6_0(glibtop *server, glibtop_fsusage *buf, const char *path)
+
+
+
+static char *
+get_partition(const char *mountpoint)
{
- FILE *mtab = setmntent("/etc/mtab", "r");
+ FILE *partitions;
+ char *name = NULL;
+ char line[1024];
+ struct stat statb;
- struct mntent *emnt;
+ if(stat(mountpoint, &statb) == -1)
+ return NULL;
- while((emnt = getmntent(mtab)) != NULL)
- {
- if(strcmp(emnt->mnt_dir, path) == 0)
- {
- char filename[64]; /* magic */
+ g_return_val_if_fail((partitions = fopen("/proc/partitions", "r")), NULL);
+
+ while(fgets(line, sizeof line, partitions))
+ {
+ unsigned major, minor;
+ char dev[32];
+
+ if(sscanf(line, "%u %u %*u %31s", &major, &minor, dev) != 3)
+ continue;
+
+ if(MKDEV(major, minor) != statb.st_dev)
+ continue;
- char buffer[1024]; /* magic */
- char *p;
+ name = g_strdup(dev);
+ break;
+ }
- char device[32]; /* magic */
- unsigned partition;
+ fclose(partitions);
+ return name;
+}
+
+
+static char *
+get_sys_path(const char *device)
+{
+ if(g_str_has_prefix(device, "hd") || g_str_has_prefix(device, "sd"))
+ {
+ char *prefix;
+ char *path;
+ size_t offset;
- const char *devname = emnt->mnt_fsname;
- size_t offset;
+ offset = strcspn(device, "0123456789");
- /*
- we only deal with /dev block devices "/dev/<DEVICE><PARTITION>"
- i don't know if other block devices such as network block
- devices provide this kind of information.
- */
+ prefix = g_strdup(device);
+ prefix [offset] = '\0';
- if(!g_str_has_prefix(devname, "/dev/"))
- break;
+ path = g_strdup_printf("/sys/block/%s/%s/stat",
+ prefix, device);
- /* skip the "/dev/" */
- devname += sizeof "/dev/" - 1;
+ g_free(prefix);
+ return path;
- g_strlcpy(device, devname, sizeof device);
+ }
+ else
+ {
+ return g_strdup_printf("/sys/block/%s/stat", device);
+ }
+}
- offset = strcspn(devname, "0123456789");
- partition = strtoul(devname + offset, NULL, 0);
- device[offset] = '\0';
- if((size_t) g_snprintf(filename, sizeof filename,
- "/sys/block/%s/%s%u/stat",
- device, device, partition) >= sizeof filename)
- break;
+static void linux_2_6_0(glibtop *server, glibtop_fsusage *buf, const char *path)
+{
+ char *device;
+ char *filename;
+ int ret;
+ char buffer[BUFSIZ];
+ char *p;
+ device = get_partition(path);
+ if(!device) return;
- if(try_file_to_buffer(buffer, filename) < 0)
- break;
+ filename = get_sys_path(device);
+ g_free(device);
- p = buffer;
- p = skip_token(p);
- buf->read = strtoull(p, &p, 0);
- p = skip_token(p);
- buf->write = strtoull(p, &p, 0);
+ ret = try_file_to_buffer(buffer, filename);
+ g_free(filename);
- buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
+ if(ret < 0) return;
- break;
- }
- }
+ p = buffer;
+ p = skip_token(p);
+ buf->read = strtoull(p, &p, 0);
+ p = skip_token(p);
+ buf->write = strtoull(p, &p, 0);
- endmntent(mtab);
+ buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
}