|
Packit |
d37888 |
#include <config.h>
|
|
Packit |
d37888 |
#include <glibtop.h>
|
|
Packit |
d37888 |
#include <glibtop/fsusage.h>
|
|
Packit |
d37888 |
#include <glibtop/error.h>
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
#include "glibtop_private.h"
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
#include <glib.h>
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
#include <unistd.h>
|
|
Packit |
d37888 |
#include <sys/types.h>
|
|
Packit |
d37888 |
#include <sys/stat.h>
|
|
Packit |
d37888 |
#include <linux/kdev_t.h>
|
|
Packit |
d37888 |
#include <sys/statvfs.h>
|
|
Packit |
d37888 |
#include <stdio.h>
|
|
Packit |
d37888 |
#include <string.h>
|
|
Packit |
d37888 |
#include <stdlib.h>
|
|
Packit |
d37888 |
#include <errno.h>
|
|
Packit |
d37888 |
#include <mntent.h>
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
/*
|
|
Packit |
d37888 |
* Linux 2.6.x
|
|
Packit |
d37888 |
* linux/Documentation/iostats.txt
|
|
Packit |
d37888 |
*/
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
static gboolean
|
|
Packit |
d37888 |
get_device(glibtop* server, const char *mountpoint,
|
|
Packit |
d37888 |
char* device, size_t device_size)
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
const struct mntent *mnt;
|
|
Packit |
d37888 |
FILE *fp;
|
|
Packit |
d37888 |
gboolean found = FALSE;
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
if (!(fp = setmntent(MOUNTED, "r"))) {
|
|
Packit |
d37888 |
glibtop_warn_io_r(server, "Could not open %s", MOUNTED);
|
|
Packit |
d37888 |
goto out;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
while ((mnt = getmntent(fp)))
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
/* There can be multiple root mount entries, skip the unuseful one */
|
|
Packit |
d37888 |
if (!strcmp(mnt->mnt_fsname, "rootfs"))
|
|
Packit |
d37888 |
continue;
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
if (!strcmp(mountpoint, mnt->mnt_dir)) {
|
|
Packit |
d37888 |
if (!strncmp(mnt->mnt_fsname, "/dev/", 5)) {
|
|
Packit |
d37888 |
g_strlcpy(device, mnt->mnt_fsname + 5, device_size);
|
|
Packit |
d37888 |
found = TRUE;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
break;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
endmntent(fp);
|
|
Packit |
d37888 |
out:
|
|
Packit |
d37888 |
return found;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
/*
|
|
Packit |
d37888 |
TRUE if device is like "hda3" and then set prefix to "hda".
|
|
Packit |
d37888 |
*/
|
|
Packit |
d37888 |
static gboolean
|
|
Packit |
d37888 |
is_partition(const char* device, char* prefix, size_t prefix_size)
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
g_strlcpy(prefix, device, prefix_size);
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
for ( ; *prefix; prefix++) {
|
|
Packit |
d37888 |
if (isdigit(*prefix)) {
|
|
Packit |
d37888 |
*prefix = '\0';
|
|
Packit |
d37888 |
return TRUE;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
return FALSE;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
/*
|
|
Packit |
d37888 |
Bug #539360.
|
|
Packit |
d37888 |
/sys/.../stat format is partially defined in
|
|
Packit |
d37888 |
linux/Documentation/block/stat.txt (looks outdated). Before linux
|
|
Packit |
d37888 |
2.5.25, /sys/block/%s/stat and /sys/block/%s/%s/stat were not the
|
|
Packit |
d37888 |
same, but the following commit changed the latter to have the same
|
|
Packit |
d37888 |
format and broke compatibility.
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
Commit 34e8beac92c27d292938065f8375842d2840767c
|
|
Packit |
d37888 |
Author: Jerome Marchand <jmarchan@redhat.com>
|
|
Packit |
d37888 |
Date: Fri Feb 8 11:04:55 2008 +0100
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
Enhanced partition statistics: sysfs
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
Reports enhanced partition statistics in sysfs.
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
fs/partitions/check.c | 22 +++++++++++++++++++---
|
|
Packit |
d37888 |
1 files changed, 19 insertions(+), 3 deletions(-)
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
*/
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
static void
|
|
Packit |
d37888 |
get_sys_path(glibtop* server, const char *device, char **stat_path, const char **parse_format)
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
const char* linux_2_6_25_format = "%*llu %*llu %llu %*llu"
|
|
Packit |
d37888 |
"%*llu %*llu %llu %*llu";
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
char prefix[32];
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
if (is_partition(device, prefix, sizeof prefix)) {
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
*stat_path = g_strdup_printf("/sys/block/%s/%s/stat",
|
|
Packit |
d37888 |
prefix, device);
|
|
Packit |
d37888 |
if (server->os_version_code < LINUX_VERSION_CODE(2, 6, 25))
|
|
Packit |
d37888 |
*parse_format = "%*llu %llu %*llu %llu";
|
|
Packit |
d37888 |
else
|
|
Packit |
d37888 |
*parse_format = linux_2_6_25_format;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
else
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
*stat_path = g_strdup_printf("/sys/block/%s/stat", device);
|
|
Packit |
d37888 |
if (server->os_version_code < LINUX_VERSION_CODE(2, 6, 25))
|
|
Packit |
d37888 |
*parse_format = "%*llu %*llu %llu %*llu %*llu %*llu %llu";
|
|
Packit |
d37888 |
else
|
|
Packit |
d37888 |
*parse_format = linux_2_6_25_format;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
static void linux_2_6_0(glibtop *server, glibtop_fsusage *buf, const char *path)
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
char *filename = NULL;
|
|
Packit |
d37888 |
const char *format;
|
|
Packit |
d37888 |
int ret;
|
|
Packit |
d37888 |
char buffer[BUFSIZ];
|
|
Packit |
d37888 |
char device[64];
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
if (!get_device(server, path, device, sizeof device))
|
|
Packit |
d37888 |
goto out;
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
get_sys_path(server, device, &filename, &format);
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
ret = try_file_to_buffer(buffer, sizeof buffer, "%s", filename);
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
if (ret < 0) goto out;
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
if (sscanf(buffer, format, &buf->read, &buf->write) != 2) {
|
|
Packit |
d37888 |
glibtop_warn_io_r(server, "Could not parse %s", filename);
|
|
Packit |
d37888 |
goto out;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
|
|
Packit |
d37888 |
out:
|
|
Packit |
d37888 |
g_free(filename);
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
static void linux_2_4_0(glibtop *server, glibtop_fsusage *buf, const char *path)
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
static void
|
|
Packit |
d37888 |
get_fsusage_read_write(glibtop *server, glibtop_fsusage *buf, const char *path)
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
if(server->os_version_code >= LINUX_VERSION_CODE(2, 6, 0))
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
linux_2_6_0(server, buf, path);
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
else if(server->os_version_code >= LINUX_VERSION_CODE(2, 4, 0))
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
linux_2_4_0(server, buf, path);
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
/* the following comes from sysdeps/common/mountlist.c if copyright matters...
|
|
Packit |
d37888 |
*/
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
static const unsigned long _glibtop_sysdeps_fsusage =
|
|
Packit |
d37888 |
(1L << GLIBTOP_FSUSAGE_BLOCKS) + (1L << GLIBTOP_FSUSAGE_BFREE)
|
|
Packit |
d37888 |
+ (1L << GLIBTOP_FSUSAGE_BAVAIL) + (1L << GLIBTOP_FSUSAGE_FILES)
|
|
Packit |
d37888 |
+ (1L << GLIBTOP_FSUSAGE_FFREE) + (1L << GLIBTOP_FSUSAGE_BLOCK_SIZE);
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
void
|
|
Packit |
d37888 |
glibtop_get_fsusage_s(glibtop *server, glibtop_fsusage *buf, const char *path)
|
|
Packit |
d37888 |
{
|
|
Packit |
d37888 |
struct statvfs fsd;
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
memset(buf, 0, sizeof(glibtop_fsusage));
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
if (statvfs(path, &fsd) < 0) {
|
|
Packit |
d37888 |
glibtop_warn_r(server, "statvfs '%s' failed: %s", path, strerror (errno));
|
|
Packit |
d37888 |
return;
|
|
Packit |
d37888 |
}
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
buf->blocks = fsd.f_blocks;
|
|
Packit |
d37888 |
buf->bfree = fsd.f_bfree;
|
|
Packit |
d37888 |
buf->bavail = (fsd.f_bavail > fsd.f_bfree) ? 0 : fsd.f_bavail;
|
|
Packit |
d37888 |
buf->files = fsd.f_files;
|
|
Packit |
d37888 |
buf->ffree = fsd.f_ffree;
|
|
Packit |
d37888 |
buf->block_size = fsd.f_bsize;
|
|
Packit |
d37888 |
buf->flags = _glibtop_sysdeps_fsusage;
|
|
Packit |
d37888 |
|
|
Packit |
d37888 |
/* setting additional flags is delegated */
|
|
Packit |
d37888 |
get_fsusage_read_write(server, buf, path);
|
|
Packit |
d37888 |
}
|