From 9e62440b314fbf87bbeca865a4223311314c52a3 Mon Sep 17 00:00:00 2001 From: "James Dominic P. Guana" Date: Sat, 23 May 2020 08:26:34 +0800 Subject: New API to retrieve disk stats in Linux --- glibtop.h | 2 + include/glibtop/disk.h | 74 +++++++++++++++++++++++++++++++ include/glibtop/sysdeps.h | 4 +- include/glibtop/union.h | 2 + lib/Makefile.am | 2 +- lib/command.c | 1 + lib/libgtop.sym | 2 + lib/sysdeps.c | 4 ++ src/daemon/main.c | 4 ++ sysdeps/common/default.c | 14 ++++++ sysdeps/common/sysdeps_suid.c | 3 ++ sysdeps/linux/Makefile.am | 2 +- sysdeps/linux/disk.c | 96 +++++++++++++++++++++++++++++++++++++++++ sysdeps/linux/glibtop_private.c | 18 ++++++++ sysdeps/linux/glibtop_private.h | 3 ++ sysdeps/linux/glibtop_server.h | 1 + sysdeps/stub/disk.c | 42 ++++++++++++++++++ sysdeps/stub/glibtop_server.h | 1 + 18 files changed, 272 insertions(+), 3 deletions(-) create mode 100644 include/glibtop/disk.h create mode 100644 sysdeps/linux/disk.c create mode 100644 sysdeps/stub/disk.c diff --git a/glibtop.h b/glibtop.h index 3542249a..804294da 100644 --- a/glibtop.h +++ b/glibtop.h @@ -80,6 +80,8 @@ struct _glibtop int socket; /* Accepted connection of a socket */ int ncpu; /* Number of CPUs, zero if single-processor */ int real_ncpu; /* Real number of CPUs. Only ncpu are monitored */ + int ndisk; /* Number of DISKs, zero if single-disk */ + int real_ndisk; /* Number of PHYSICAL DISKs. Only ncpu is monitored */ unsigned long os_version_code; /* Version code of the operating system */ const char *name; /* Program name for error messages */ const char *server_command; /* Command used to invoke server */ diff --git a/include/glibtop/disk.h b/include/glibtop/disk.h new file mode 100644 index 00000000..8843112c --- /dev/null +++ b/include/glibtop/disk.h @@ -0,0 +1,74 @@ +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by James Dominic P. Guana , May 2020. + + LibGTop is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + LibGTop is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __GLIBTOP_DISK_H__ +#define __GLIBTOP_DISK_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GLIBTOP_XDISK_SECTORS_READ 0 +#define GLIBTOP_XDISK_TIME_READ 1 +#define GLIBTOP_XDISK_SECTORS_WRITE 2 +#define GLIBTOP_XDISK_TIME_WRITE 3 + +#define GLIBTOP_MAX_DISK 4 + +/* Nobody should really be using more than 4 disk. + Yes we are :) + Nobody should really be using more than 32 disk. +*/ +#define GLIBTOP_NDISK 1024 + +typedef struct _glibtop_disk glibtop_disk; + +struct _glibtop_disk +{ + guint64 xdisk_sectors_read [GLIBTOP_NDISK]; /* GLIBTOP_XDISK_SECTORS_READ */ + guint64 xdisk_time_read [GLIBTOP_NDISK]; /* GLIBTOP_XDISK_TIME_READ */ + guint64 xdisk_sectors_write [GLIBTOP_NDISK]; /* GLIBTOP_XDISK_SECTORS_WRITE */ + guint64 xdisk_time_write [GLIBTOP_NDISK]; /* GLIBTOP_XDISK_TIME_WRITE */ +}; + +void glibtop_get_disk(glibtop_disk *buf); + +#if GLIBTOP_SUID_DISK +#define glibtop_get_disk_r glibtop_get_disk_p +#else +#define glibtop_get_disk_r glibtop_get_disk_s +#endif + +void glibtop_get_disk_l (glibtop *server, glibtop_disk *buf); + +#if GLIBTOP_SUID_DISK +void _glibtop_init_disk_p (glibtop *server); +void glibtop_get_disk_p (glibtop *server, glibtop_disk *buf); +#else +void _glibtop_init_disk_s (glibtop *server); +void glibtop_get_disk_s (glibtop *server, glibtop_disk *buf); +#endif + + +G_END_DECLS + +#endif diff --git a/include/glibtop/sysdeps.h b/include/glibtop/sysdeps.h index a18c69e6..a1db66d8 100644 --- a/include/glibtop/sysdeps.h +++ b/include/glibtop/sysdeps.h @@ -54,8 +54,9 @@ G_BEGIN_DECLS #define GLIBTOP_SYSDEPS_PROC_WD 25 #define GLIBTOP_SYSDEPS_PROC_AFFINITY 26 #define GLIBTOP_SYSDEPS_PROC_IO 27 +#define GLIBTOP_SYSDEPS_DISK 28 -#define GLIBTOP_MAX_SYSDEPS 28 +#define GLIBTOP_MAX_SYSDEPS 29 /* The 'features' args to glibtop_init_* is an unsigned long */ G_STATIC_ASSERT((1UL << (GLIBTOP_MAX_SYSDEPS - 1)) <= ULONG_MAX); @@ -69,6 +70,7 @@ struct _glibtop_sysdeps guint64 flags; guint64 features; /* server features */ guint64 cpu; /* glibtop_cpu */ + guint64 disk; /* glibtop_cpu */ guint64 mem; /* glibtop_mem */ guint64 swap; /* glibtop_swap */ guint64 uptime; /* glibtop_uptime */ diff --git a/include/glibtop/union.h b/include/glibtop/union.h index 334f0217..bda7c576 100644 --- a/include/glibtop/union.h +++ b/include/glibtop/union.h @@ -23,6 +23,7 @@ #define __GLIBTOP_UNION_H__ #include +#include #include #include #include @@ -60,6 +61,7 @@ typedef union _glibtop_union glibtop_union; union _glibtop_union { glibtop_cpu cpu; + glibtop_disk disk; glibtop_mem mem; glibtop_swap swap; glibtop_uptime uptime; diff --git a/lib/Makefile.am b/lib/Makefile.am index 90b82861..5a6f6511 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -29,7 +29,7 @@ if HAVE_INTROSPECTION introspection_sources = $(libgtop_2_0_la_SOURCES) lib.c ../glibtop.h ../libgtopconfig.h \ ../include/glibtop/close.h ../include/glibtop/loadavg.h ../include/glibtop/prockernel.h ../include/glibtop/procstate.h \ ../include/glibtop/sem_limits.h ../include/glibtop/uptime.h ../include/glibtop/command.h ../include/glibtop/mem.h ../include/glibtop/proclist.h \ - ../include/glibtop/proctime.h ../include/glibtop/shm_limits.h ../include/glibtop/cpu.h ../include/glibtop/msg_limits.h \ + ../include/glibtop/proctime.h ../include/glibtop/shm_limits.h ../include/glibtop/cpu.h ../include/glibtop/disk.h ../include/glibtop/msg_limits.h \ ../include/glibtop/procmem.h ../include/glibtop/procuid.h ../include/glibtop/swap.h \ ../include/glibtop/procsegment.h ../include/glibtop/sysdeps.h ../include/glibtop/global.h \ ../include/glibtop/procsignal.h ../include/glibtop/union.h ../include/glibtop/gnuserv.h \ diff --git a/lib/command.c b/lib/command.c index b6ccf1f2..cf2270e0 100644 --- a/lib/command.c +++ b/lib/command.c @@ -43,6 +43,7 @@ glibtop_call_l (glibtop *server, unsigned command, size_t send_size, CHECK_CMND(GLIBTOP_CMND_QUIT); CHECK_CMND(GLIBTOP_CMND_SYSDEPS); CHECK_CMND(GLIBTOP_CMND_CPU); + CHECK_CMND(GLIBTOP_CMND_DISK); CHECK_CMND(GLIBTOP_CMND_MEM); CHECK_CMND(GLIBTOP_CMND_SWAP); CHECK_CMND(GLIBTOP_CMND_UPTIME); diff --git a/lib/libgtop.sym b/lib/libgtop.sym index afa9d070..60316a72 100644 --- a/lib/libgtop.sym +++ b/lib/libgtop.sym @@ -3,6 +3,8 @@ glibtop_close glibtop_close_r glibtop_get_cpu glibtop_get_cpu_l +glibtop_get_disk +glibtop_get_disk_l glibtop_get_fsusage glibtop_get_fsusage_l glibtop_get_loadavg diff --git a/lib/sysdeps.c b/lib/sysdeps.c index 2a761576..96292568 100644 --- a/lib/sysdeps.c +++ b/lib/sysdeps.c @@ -27,6 +27,7 @@ const unsigned long glibtop_server_features = GLIBTOP_SUID_CPU + +GLIBTOP_SUID_DISK + GLIBTOP_SUID_MEM + GLIBTOP_SUID_SWAP + GLIBTOP_SUID_UPTIME + @@ -56,6 +57,9 @@ const _glibtop_init_func_t _glibtop_init_hook_s [] = { #if !GLIBTOP_SUID_CPU _glibtop_init_cpu_s, #endif +#if !GLIBTOP_SUID_DISK + _glibtop_init_disk_s, +#endif #if !GLIBTOP_SUID_MEM _glibtop_init_mem_s, #endif diff --git a/src/daemon/main.c b/src/daemon/main.c index b51addf6..34cbaf50 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -97,6 +97,10 @@ handle_parent_connection (int s) glibtop_get_cpu_l (server, &resp->u.data.cpu); do_output (s, resp, _offset_data (cpu), 0, NULL); break; + case GLIBTOP_CMND_DISK: + glibtop_get_disk_l (server, &resp->u.disk.cpu); + do_output (s, resp, _offset_data (disk), 0, NULL); + break; case GLIBTOP_CMND_MEM: glibtop_get_mem_l (server, &resp->u.data.mem); do_output (s, resp, _offset_data (mem), 0, NULL); diff --git a/sysdeps/common/default.c b/sysdeps/common/default.c index e3b096f2..c20f2938 100644 --- a/sysdeps/common/default.c +++ b/sysdeps/common/default.c @@ -64,6 +64,20 @@ glibtop_get_cpu(glibtop_cpu *buf) } +/** + * glibtop_get_disk: + * @buf: A location to return the disk usage. + * + * Get the DISK usage. + * + */ +void +glibtop_get_cpu(glibtop_cpu *buf) +{ + glibtop_get_cpu_l(glibtop_global_server, buf); +} + + /** * glibtop_get_fsusage: * @buf: A location to return the file system usage. diff --git a/sysdeps/common/sysdeps_suid.c b/sysdeps/common/sysdeps_suid.c index 24953176..ecb1d53e 100644 --- a/sysdeps/common/sysdeps_suid.c +++ b/sysdeps/common/sysdeps_suid.c @@ -30,6 +30,9 @@ const _glibtop_init_func_t _glibtop_init_hook_p [] = { #if GLIBTOP_SUID_CPU _glibtop_init_cpu_p, #endif +#if GLIBTOP_SUID_DISK + _glibtop_init_disk_p, +#endif #if GLIBTOP_SUID_MEM _glibtop_init_mem_p, #endif diff --git a/sysdeps/linux/Makefile.am b/sysdeps/linux/Makefile.am index fdd54696..c51bb155 100644 --- a/sysdeps/linux/Makefile.am +++ b/sysdeps/linux/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libgtop_sysdeps-2.0.la libgtop_sysdeps_suid-2.0.la EXTRA_DIST = procmap_smaps.gperf procmap_smaps.c -libgtop_sysdeps_2_0_la_SOURCES = open.c close.c cpu.c mem.c swap.c \ +libgtop_sysdeps_2_0_la_SOURCES = open.c close.c cpu.c disk.c mem.c swap.c \ uptime.c loadavg.c shm_limits.c msg_limits.c \ sem_limits.c proclist.c procstate.c procuid.c \ proctime.c procmem.c procsignal.c prockernel.c \ diff --git a/sysdeps/linux/disk.c b/sysdeps/linux/disk.c new file mode 100644 index 00000000..159f8f12 --- /dev/null +++ b/sysdeps/linux/disk.c @@ -0,0 +1,96 @@ +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by James Dominic P. Guana , May 2020. + + LibGTop is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + LibGTop is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include "glibtop_private.h" + +static const unsigned long _glibtop_sysdeps_disk = +(1L << GLIBTOP_XDISK_SECTORS_READ) + (1L << GLIBTOP_XDISK_TIME_READ) + +(1L << GLIBTOP_XDISK_SECTORS_WRITE) + (1L << GLIBTOP_XDISK_TIME_WRITE); + +/* Init function. */ + +void +_glibtop_init_disk_s (glibtop *server) +{ + server->sysdeps.disk = _glibtop_sysdeps_disk; +} + +/* Provides information about disk usage. */ + +#define FILENAME "/proc/diskstats" //kernel reports sectors by 512 bytes even for AF 4kn +#define STAT_BUFSIZ 81920 + +void +glibtop_get_disk_s (glibtop *server, glibtop_disk *buf) +{ + char buffer [STAT_BUFSIZ], *p; + int i; + + memset (buf, 0, sizeof (glibtop_disk)); + + file_to_buffer(server, buffer, sizeof buffer, FILENAME); + + /* + * GLOBAL + */ + + p = buffer; /* "disk" */ + + /* + * PER DISK + */ + + for (i = 0; i <= server->ndisk; i++) { + + p = skip_multiple_token(p,2); + + // skip if disk is the raw device + if(!check_alphanumeric_word(p)){ + + p = skip_line(p); /* move to ^ */ + p = skip_multiple_token(p,2); + + } + + if (!check_disk_line_warn(server, p, i)) + break; + + p = skip_token(p); /* prev xdisk_name */ + p = skip_token(p); /* prev xdisk_reads_completed */ + p = skip_token(p); /* prev xdisk_reads_merged */ + + buf->xdisk_sectors_read [i] = strtoull (p, &p, 0); + buf->xdisk_time_read [i] = strtoull (p, &p, 0); + + p = skip_token(p); /* prev xdisk_writes_completed */ + p = skip_token(p); /* prev xdisk_writes_merged */ + + buf->xdisk_sectors_write [i] = strtoull (p, &p, 0); + buf->xdisk_time_write [i] = strtoull (p, &p, 0); + + p = skip_line(p); /* move to ^ */ + + } +} diff --git a/sysdeps/linux/glibtop_private.c b/sysdeps/linux/glibtop_private.c index d3a49aa6..7b36561c 100644 --- a/sysdeps/linux/glibtop_private.c +++ b/sysdeps/linux/glibtop_private.c @@ -57,6 +57,24 @@ skip_token (const char *p) } +int +check_alphanumeric_word (const char *p) +{ + int test = 0; + p = next_token(p); + while (*p && !g_ascii_isspace(*p)) { + if(g_ascii_isalpha(*p)){ + test = 0; + }else if(g_ascii_isdigit(*p)){ + test = 1; + } + p++; + }; + p = next_token(p); + return test; +} + + /* * Read functions */ diff --git a/sysdeps/linux/glibtop_private.h b/sysdeps/linux/glibtop_private.h index 03761f4f..d42ee669 100644 --- a/sysdeps/linux/glibtop_private.h +++ b/sysdeps/linux/glibtop_private.h @@ -61,6 +61,9 @@ skip_line (const char *p) return (char *) (*p ? p+1 : p); } +int +check_alphanumeric_word (const char *p); + /* * Smart strtoul which handles binary suffixes * e.g: get_scaled("Size: 32 kB", "Size:") == 32768 diff --git a/sysdeps/linux/glibtop_server.h b/sysdeps/linux/glibtop_server.h index 6240d5de..43dd9d9f 100644 --- a/sysdeps/linux/glibtop_server.h +++ b/sysdeps/linux/glibtop_server.h @@ -23,6 +23,7 @@ #define __LINUX__GLIBTOP_SERVER_H__ #define GLIBTOP_SUID_CPU 0 +#define GLIBTOP_SUID_DISK 0 #define GLIBTOP_SUID_MEM 0 #define GLIBTOP_SUID_SWAP 0 #define GLIBTOP_SUID_UPTIME 0 diff --git a/sysdeps/stub/disk.c b/sysdeps/stub/disk.c new file mode 100644 index 00000000..a946fdf5 --- /dev/null +++ b/sysdeps/stub/disk.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by James Dominic P. Guana , May 2020. + + LibGTop is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + LibGTop is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +static const unsigned long _glibtop_sysdeps_disk = 0; + +/* Init function. */ + +void +_glibtop_init_disk_s (glibtop *server) +{ + server->sysdeps.disk = _glibtop_sysdeps_disk; +} + +/* Provides information about disk usage. */ + +void +glibtop_get_disk_s (glibtop *server, glibtop_disk *buf) +{ + memset (buf, 0, sizeof (glibtop_disk)); +} diff --git a/sysdeps/stub/glibtop_server.h b/sysdeps/stub/glibtop_server.h index 1dd18bf0..0f8bd194 100644 --- a/sysdeps/stub/glibtop_server.h +++ b/sysdeps/stub/glibtop_server.h @@ -25,6 +25,7 @@ G_BEGIN_DECLS #define GLIBTOP_SUID_CPU 0 +#define GLIBTOP_SUID_DISK 0 #define GLIBTOP_SUID_MEM 0 #define GLIBTOP_SUID_SWAP 0 #define GLIBTOP_SUID_UPTIME 0 -- cgit v1.2.1