#include #include #include #include "glibtop_private.h" #include #include #include #include #include #include #include #include void _glibtop_linux_get_fsusage_read_write(glibtop *server, glibtop_fsusage *buf, const char *path); /* * Linux 2.6.x * linux/Documentation/iostats.txt */ static char * get_partition(const char *mountpoint) { FILE *partitions; char *name = NULL; char line[1024]; struct stat statb; if(stat(mountpoint, &statb) == -1) return NULL; if((partitions = fopen("/proc/partitions", "r")) == NULL) return 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; name = g_strdup(dev); break; } fclose(partitions); return name; } static void get_sys_path(const char *device, char **stat_path, const char **parse_format) { if(g_str_has_prefix(device, "hd") || g_str_has_prefix(device, "sd")) { char *prefix; char *path; size_t offset; offset = strcspn(device, "0123456789"); prefix = g_strdup(device); prefix [offset] = '\0'; path = g_strdup_printf("/sys/block/%s/%s/stat", prefix, device); g_free(prefix); *stat_path = path; *parse_format = "%*llu %llu %*llu %llu"; } else { *stat_path = g_strdup_printf("/sys/block/%s/stat", device); *parse_format = "%*llu %*llu %llu %*llu %*llu %*llu %llu"; } } static void linux_2_6_0(glibtop *server, glibtop_fsusage *buf, const char *path) { char *device; char *filename; const char *format; int ret; char buffer[BUFSIZ]; device = get_partition(path); if(!device) return; get_sys_path(device, &filename, &format); g_free(device); ret = try_file_to_buffer(buffer, sizeof buffer, filename); if(ret < 0) return; if (sscanf(buffer, format, &buf->read, &buf->write) != 2) { glibtop_warn_io_r(server, "Could not parse %s", filename); return; } g_free(filename); buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE); } static void linux_2_4_0(glibtop *server, glibtop_fsusage *buf, const char *path) { } void _glibtop_linux_get_fsusage_read_write(glibtop *server, glibtop_fsusage *buf, const char *path) { if(server->os_version_code >= LINUX_VERSION_CODE(2, 6, 0)) { linux_2_6_0(server, buf, path); } else if(server->os_version_code >= LINUX_VERSION_CODE(2, 4, 0)) { linux_2_4_0(server, buf, path); } }