diff options
author | Robert Roth <robert.roth.off@gmail.com> | 2017-02-12 17:59:08 +0200 |
---|---|---|
committer | Robert Roth <robert.roth.off@gmail.com> | 2017-02-12 17:59:08 +0200 |
commit | dff7c5588e9761224f2811f0ce5792ff93d95e29 (patch) | |
tree | 32a0acb5b1c4c217e4b9de52e1963a1fe9562ab2 | |
parent | 1a103bf142856ec129eb124d1dae70ddb3dd02e8 (diff) | |
download | libgtop-dff7c5588e9761224f2811f0ce5792ff93d95e29.tar.gz |
New API to retrieve process io stats, with Linux implementation
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | examples/Makefile.am | 6 | ||||
-rw-r--r-- | examples/diskio.c | 39 | ||||
-rw-r--r-- | features.def | 1 | ||||
-rw-r--r-- | include/glibtop/Makefile.am | 1 | ||||
-rw-r--r-- | include/glibtop/command.h | 3 | ||||
-rw-r--r-- | include/glibtop/procdiskio.h | 90 | ||||
-rw-r--r-- | include/glibtop/sysdeps.h | 4 | ||||
-rw-r--r-- | include/glibtop/union.h | 2 | ||||
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/command.c | 1 | ||||
-rw-r--r-- | lib/libgtop.sym | 2 | ||||
-rw-r--r-- | lib/sysdeps.c | 9 | ||||
-rw-r--r-- | src/daemon/main.c | 6 | ||||
-rw-r--r-- | sysdeps/common/default.c | 15 | ||||
-rw-r--r-- | sysdeps/common/sysdeps_suid.c | 3 | ||||
-rw-r--r-- | sysdeps/linux/Makefile.am | 2 | ||||
-rw-r--r-- | sysdeps/linux/glibtop_server.h | 1 | ||||
-rw-r--r-- | sysdeps/linux/procdiskio.c | 66 | ||||
-rw-r--r-- | sysdeps/stub/procdiskio.c | 43 | ||||
-rw-r--r-- | sysdeps/stub_suid/glibtop_server.h | 1 |
21 files changed, 292 insertions, 6 deletions
@@ -70,6 +70,7 @@ examples/smp examples/sysdeps examples/timings examples/wd +examples/diskio gtk-doc.make install-sh lib/GTop-2.0.gir diff --git a/examples/Makefile.am b/examples/Makefile.am index 48ac4849..25585e04 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -11,7 +11,7 @@ AM_LDFLAGS = $(LIBGTOP_EXTRA_LIBS) noinst_PROGRAMS = first second pprint procargs df netlist \ mountlist procmap netload sysdeps timings \ - openfiles smp proclist free wd affinity + openfiles smp proclist free wd affinity diskio first_SOURCES = first.c first_LDADD = $(top_builddir)/lib/libgtop-2.0.la @@ -43,6 +43,7 @@ pprint_LDADD = $(top_builddir)/lib/libgtop-2.0.la procargs_SOURCES = procargs.c procargs_LDADD = $(top_builddir)/lib/libgtop-2.0.la + df_SOURCES = df.c df_LDADD = $(top_builddir)/lib/libgtop-2.0.la @@ -63,3 +64,6 @@ free_LDADD = $(top_builddir)/lib/libgtop-2.0.la affinity_SOURCES = affinity.c affinity_LDADD = $(top_builddir)/lib/libgtop-2.0.la + +diskio_SOURCES = diskio.c +diskio_LDADD = $(top_builddir)/lib/libgtop-2.0.la diff --git a/examples/diskio.c b/examples/diskio.c new file mode 100644 index 00000000..e52844aa --- /dev/null +++ b/examples/diskio.c @@ -0,0 +1,39 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <glibtop.h> +#include <glibtop/procdiskio.h> + +#include <stdlib.h> + +#include <unistd.h> + +static void show_diskio(pid_t pid) +{ + glibtop_proc_diskio diskio; + + glibtop_get_proc_diskio (&diskio, pid); + + printf("<%ld>\t", (long)pid); + + printf("rchar : %lu, wchar : %lu, read_bytes : %lu, write_bytes : %lu\n", diskio.rchar, diskio.wchar, diskio.rbytes, diskio.wbytes); + +} + + +int main(int argc, char **argv) +{ + glibtop_init(); + + while(*++argv) + { + pid_t pid = strtol(*argv, NULL, 10); + show_diskio(pid); + } + + glibtop_close(); + + return 0; +} + diff --git a/features.def b/features.def index 1025313e..065d8fa1 100644 --- a/features.def +++ b/features.def @@ -24,4 +24,5 @@ void|ppp|ushort(device) char **|netlist char **|proc_wd|pid_t(pid) guint16*|proc_affinity|pid_t(pid) +void|proc_diskio|pid_t(pid) diff --git a/include/glibtop/Makefile.am b/include/glibtop/Makefile.am index 66bdd344..b797385e 100644 --- a/include/glibtop/Makefile.am +++ b/include/glibtop/Makefile.am @@ -9,6 +9,7 @@ glibtop_HEADERS = close.h loadavg.h prockernel.h procstate.h \ parameter.h mountlist.h fsusage.h procmap.h signal.h \ sysinfo.h ppp.h procargs.h netload.h \ procwd.h procaffinity.h \ + procdiskio.h \ netlist.h procopenfiles.h open.h noinst_HEADERS = error.h write.h read_data.h read.h init_hooks.h machine.h \ diff --git a/include/glibtop/command.h b/include/glibtop/command.h index 1d4d630c..6e9dc079 100644 --- a/include/glibtop/command.h +++ b/include/glibtop/command.h @@ -59,8 +59,9 @@ G_BEGIN_DECLS #define GLIBTOP_CMND_PROC_OPEN_FILES 25 #define GLIBTOP_CMND_PROC_WD 26 #define GLIBTOP_CMND_PROC_AFFINITY 27 +#define GLIBTOP_CMND_PROC_DISKIO 28 -#define GLIBTOP_MAX_CMND 28 +#define GLIBTOP_MAX_CMND 29 #define _GLIBTOP_PARAM_SIZE 16 diff --git a/include/glibtop/procdiskio.h b/include/glibtop/procdiskio.h new file mode 100644 index 00000000..5d7b18e3 --- /dev/null +++ b/include/glibtop/procdiskio.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2017 Robert Roth + This file is part of LibGTop. + + Contributed by Robert Roth <robert.roth.off@gmail.com>, February 2017. + + 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_PROCDISKIO_H__ +#define __GLIBTOP_PROCDISKIO_H__ + +#include <glibtop.h> +#include <glibtop/global.h> + +G_BEGIN_DECLS + +#define GLIBTOP_PROC_DISKIO_RCHAR 0 +#define GLIBTOP_PROC_DISKIO_WCHAR 1 +#define GLIBTOP_PROC_DISKIO_RBYTES 2 +#define GLIBTOP_PROC_DISKIO_WBYTES 3 + +#define GLIBTOP_MAX_PROC_TIME 3 + +typedef struct _glibtop_proc_diskio glibtop_proc_diskio; + +/* Time section */ + +/** + * glibtop_proc_diskio: + * @rchar: The number of bytes which this task has caused to be read from storage. This + * is simply the sum of bytes which this process passed to read() and pread(), also including tty IO, + * and it is unaffected by whether or not actual physical disk IO was required. + * @wchar: The number of bytes which this task has caused, or shall cause to be written + * to disk. Similar caveats apply here as with rchar. + * @rbytes: Attempt to count the number of bytes which this process really did cause to + * be fetched from the storage layer. Done at the submit_bio() level, so it is + * accurate for block-backed filesystems. + * @wbytes: Attempt to count the number of bytes which this process caused to be sent to + * the storage layer. This is done at page-dirtying time. + * + * Process disk io data filled by glibtop_get_proc_diskio(). + * + */ +struct _glibtop_proc_diskio +{ + /*< private >*/ + guint64 flags; + /*< public >*/ + guint64 rchar; + guint64 wchar; + guint64 rbytes; + guint64 wbytes; +}; + + +void glibtop_get_proc_diskio (glibtop_proc_diskio *buf, pid_t pid); + +#if GLIBTOP_SUID_PROC_DISKIO +#define glibtop_get_proc_diskio_r glibtop_get_proc_diskio_p +#else +#define glibtop_get_proc_diskio_r glibtop_get_proc_diskio_s +#endif + +void glibtop_get_proc_diskio_l (glibtop *server, glibtop_proc_diskio *buf, pid_t pid); + +#if GLIBTOP_SUID_PROC_DISKIO +void _glibtop_init_proc_diskio_p (glibtop *server); +void glibtop_get_proc_diskio_p (glibtop *server, glibtop_proc_diskio *buf, pid_t pid); +#else +void _glibtop_init_proc_diskio_s (glibtop *server); +void glibtop_get_proc_diskio_s (glibtop *server, glibtop_proc_diskio *buf, pid_t pid); +#endif + + +G_END_DECLS + +#endif diff --git a/include/glibtop/sysdeps.h b/include/glibtop/sysdeps.h index 61006a0a..39c2dad2 100644 --- a/include/glibtop/sysdeps.h +++ b/include/glibtop/sysdeps.h @@ -53,8 +53,9 @@ G_BEGIN_DECLS #define GLIBTOP_SYSDEPS_PROC_OPEN_FILES 24 #define GLIBTOP_SYSDEPS_PROC_WD 25 #define GLIBTOP_SYSDEPS_PROC_AFFINITY 26 +#define GLIBTOP_SYSDEPS_PROC_DISKIO 27 -#define GLIBTOP_MAX_SYSDEPS 27 +#define GLIBTOP_MAX_SYSDEPS 28 /* The 'features' args to glibtop_init_* is an unsigned long */ G_STATIC_ASSERT((1UL << (GLIBTOP_MAX_SYSDEPS - 1)) <= ULONG_MAX); @@ -93,6 +94,7 @@ struct _glibtop_sysdeps guint64 ppp; /* glibtop_ppp */ guint64 proc_wd; /* glibtop_proc_wd */ guint64 proc_affinity; /* glibtop_proc_affinity */ + guint64 proc_diskio; /* glibtop_proc_diskio */ }; void glibtop_get_sysdeps (glibtop_sysdeps *buf); diff --git a/include/glibtop/union.h b/include/glibtop/union.h index a140d71a..9148c408 100644 --- a/include/glibtop/union.h +++ b/include/glibtop/union.h @@ -44,6 +44,7 @@ #include <glibtop/procopenfiles.h> #include <glibtop/procwd.h> #include <glibtop/procaffinity.h> +#include <glibtop/procdiskio.h> #include <glibtop/mountlist.h> #include <glibtop/fsusage.h> @@ -84,6 +85,7 @@ union _glibtop_union glibtop_proc_open_files proc_open_files; glibtop_proc_wd proc_wd; glibtop_proc_affinity proc_affinity; + glibtop_proc_diskio proc_diskio; }; G_END_DECLS diff --git a/lib/Makefile.am b/lib/Makefile.am index dec24a04..b23ba5ea 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -35,7 +35,7 @@ introspection_sources = $(libgtop_2_0_la_SOURCES) lib.c ../glibtop.h ../libgtopc ../include/glibtop/procsignal.h ../include/glibtop/union.h ../include/glibtop/gnuserv.h \ ../include/glibtop/parameter.h ../include/glibtop/mountlist.h ../include/glibtop/fsusage.h ../include/glibtop/procmap.h ../include/glibtop/signal.h \ ../include/glibtop/sysinfo.h ../include/glibtop/ppp.h ../include/glibtop/procargs.h ../include/glibtop/netload.h \ - ../include/glibtop/procwd.h ../include/glibtop/procaffinity.h \ + ../include/glibtop/procwd.h ../include/glibtop/procaffinity.h ../include/glibtop/procdiskio.h \ ../include/glibtop/netlist.h ../include/glibtop/procopenfiles.h ../include/glibtop/open.h GTop-2.0.gir: libgtop-2.0.la diff --git a/lib/command.c b/lib/command.c index 414081c3..c2ad44d3 100644 --- a/lib/command.c +++ b/lib/command.c @@ -68,6 +68,7 @@ glibtop_call_l (glibtop *server, unsigned command, size_t send_size, CHECK_CMND(GLIBTOP_CMND_PROC_OPEN_FILES); CHECK_CMND(GLIBTOP_CMND_PROC_WD); CHECK_CMND(GLIBTOP_CMND_PROC_AFFINITY); + CHECK_CMND(GLIBTOP_CMND_PROC_DISKIO); default: glibtop_error_r(server, "CALL: command UNKNOWN(%d) sending %lu bytes", command, (unsigned long)send_size); break; } diff --git a/lib/libgtop.sym b/lib/libgtop.sym index d15adcc6..484b9061 100644 --- a/lib/libgtop.sym +++ b/lib/libgtop.sym @@ -52,6 +52,8 @@ glibtop_get_shm_limits glibtop_get_shm_limits_l glibtop_get_proc_affinity glibtop_get_proc_affinity_l +glibtop_get_proc_diskio +glibtop_get_proc_diskio_l glibtop_get_swap glibtop_get_swap_l glibtop_get_sysdeps diff --git a/lib/sysdeps.c b/lib/sysdeps.c index 3a90a54c..47333f98 100644 --- a/lib/sysdeps.c +++ b/lib/sysdeps.c @@ -48,7 +48,8 @@ GLIBTOP_SUID_NETLOAD + GLIBTOP_SUID_NETLIST + GLIBTOP_SUID_PROC_WD + GLIBTOP_SUID_PROC_AFFINITY + -GLIBTOP_SUID_PPP; +GLIBTOP_SUID_PPP + +GLIBTOP_SUID_PROC_DISKIO; const _glibtop_init_func_t _glibtop_init_hook_s [] = { #if !GLIBTOP_SUID_CPU @@ -120,6 +121,9 @@ const _glibtop_init_func_t _glibtop_init_hook_s [] = { #if !GLIBTOP_SUID_PPP _glibtop_init_ppp_s, #endif +#if !GLIBTOP_SUID_PROC_DISKIO + _glibtop_init_proc_diskio_s, +#endif NULL }; @@ -193,6 +197,9 @@ const _glibtop_init_func_t _glibtop_init_hook_p [] = { #if GLIBTOP_SUID_PPP _glibtop_init_ppp_p, #endif +#if GLIBTOP_SUID_PROC_DISKIO + _glibtop_init_proc_diskio_p, +#endif NULL }; diff --git a/src/daemon/main.c b/src/daemon/main.c index 11364229..14868765 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -221,6 +221,12 @@ handle_parent_connection (int s) do_output (s, resp, _offset_data (fsusage), 0, NULL); break; + case GLIBTOP_CMND_PROC_DISKIO: + glibtop_get_proc_diskio_l + (server, &resp->u.data.proc_diskio, parameter); + do_output (s, resp, _offset_data (proc_diskio), + 0, NULL); + break; case GLIBTOP_CMND_PPP: memcpy (&device, parameter, sizeof (device)); glibtop_get_ppp_l diff --git a/sysdeps/common/default.c b/sysdeps/common/default.c index 2df25ee6..6987fb20 100644 --- a/sysdeps/common/default.c +++ b/sysdeps/common/default.c @@ -431,3 +431,18 @@ glibtop_get_proc_affinity(glibtop_proc_affinity *buf, pid_t pid) { return glibtop_get_proc_affinity_l(glibtop_global_server, buf, pid); } + +/** + * glibtop_get_proc_diskio: Get the disk io stats for the given pid + * @buf: Buffer where the result will be given + * @pid: Process id to get the io stats for + * + * Get the io stats for a process + * + * Returns: A list of processor ID of 'buf.number' elements. + */ +void +glibtop_get_proc_diskio(glibtop_proc_diskio *buf, pid_t pid) +{ + return glibtop_get_proc_diskio_l(glibtop_global_server, buf, pid); +} diff --git a/sysdeps/common/sysdeps_suid.c b/sysdeps/common/sysdeps_suid.c index 91ff806c..70dd2256 100644 --- a/sysdeps/common/sysdeps_suid.c +++ b/sysdeps/common/sysdeps_suid.c @@ -90,6 +90,9 @@ const _glibtop_init_func_t _glibtop_init_hook_p [] = { #if GLIBTOP_SUID_PPP _glibtop_init_ppp_p, #endif +#if GLIBTOP_SUID_PROC_DISKIO + _glibtop_init_proc_diskio_p, +#endif NULL }; diff --git a/sysdeps/linux/Makefile.am b/sysdeps/linux/Makefile.am index ae480f1f..0657fdc2 100644 --- a/sysdeps/linux/Makefile.am +++ b/sysdeps/linux/Makefile.am @@ -10,7 +10,7 @@ libgtop_sysdeps_2_0_la_SOURCES = open.c close.c cpu.c mem.c swap.c \ proctime.c procmem.c procsignal.c prockernel.c \ procsegment.c procargs.c procmap.c siglist.c \ sysinfo.c netload.c ppp.c glibtop_private.c \ - mountlist.c procaffinity.c \ + mountlist.c procaffinity.c procdiskio.c \ fsusage.c netlist.c procopenfiles.c procwd.c libgtop_sysdeps_2_0_la_LIBADD = @GLIB_LIBS@ diff --git a/sysdeps/linux/glibtop_server.h b/sysdeps/linux/glibtop_server.h index 5912ad05..db81b71c 100644 --- a/sysdeps/linux/glibtop_server.h +++ b/sysdeps/linux/glibtop_server.h @@ -46,5 +46,6 @@ #define GLIBTOP_SUID_PROC_AFFINITY 0 #define GLIBTOP_SUID_PPP 0 #define GLIBTOP_SUID_PROC_FILE 0 +#define GLIBTOP_SUID_PROC_DISKIO 0 #endif /* __LINUX__GLIBTOP_SERVER_H__ */ diff --git a/sysdeps/linux/procdiskio.c b/sysdeps/linux/procdiskio.c new file mode 100644 index 00000000..fba687f1 --- /dev/null +++ b/sysdeps/linux/procdiskio.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2017 Robert Roth + This file is part of LibGTop. + + Contributed by Robert Roth <robert.roth.off@gmail.com>, February 2017. + + 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 <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procdiskio.h> + +#include "glibtop_private.h" + +static const unsigned long _glibtop_sysdeps_proc_diskio = +(1L << GLIBTOP_PROC_DISKIO_RCHAR) + (1L << GLIBTOP_PROC_DISKIO_WCHAR) + +(1L << GLIBTOP_PROC_DISKIO_RBYTES) + (1L << GLIBTOP_PROC_DISKIO_WBYTES); + +/* Init function. */ + +void +_glibtop_init_proc_diskio_s (glibtop *server) +{ + server->sysdeps.proc_diskio = _glibtop_sysdeps_proc_diskio; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_diskio_s (glibtop *server, glibtop_proc_diskio *buf, pid_t pid) +{ + char buffer [BUFSIZ], *p; + memset (buf, 0, sizeof (glibtop_proc_diskio)); + + + if (proc_file_to_buffer(buffer, sizeof buffer, "/proc/%d/io", pid)) + return; + + p = skip_token (buffer); + buf->rchar = g_ascii_strtoull (p, &p, 10); + p = skip_line (p); + p = skip_token (p); + buf->wchar = g_ascii_strtoull (p, &p, 10); + p = skip_line (p); + p = skip_line (p); + p = skip_line (p); + p = skip_token (p); + buf->rbytes = g_ascii_strtoull (p, &p, 10); + p = skip_line (p); + p = skip_token (p); + buf->wbytes = g_ascii_strtoull (p, &p, 10); +} diff --git a/sysdeps/stub/procdiskio.c b/sysdeps/stub/procdiskio.c new file mode 100644 index 00000000..455fec6d --- /dev/null +++ b/sysdeps/stub/procdiskio.c @@ -0,0 +1,43 @@ +/* Copyright (C) 2017 Robert Roth + This file is part of LibGTop. + + Contributed by Robert Roth <robert.roth.off@gmail.com>, February 2017. + + 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 <config.h> +#include <glibtop.h> +#include <glibtop/procdiskio.h> + +static const unsigned long _glibtop_sysdeps_proc_diskio = 0; + +/* Init function. */ + +void +_glibtop_init_proc_diskio_s (glibtop *server) +{ + server->sysdeps.proc_diskio = _glibtop_sysdeps_proc_diskio; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_diskio_s (glibtop *server, glibtop_proc_diskio *buf, + pid_t pid) +{ + memset (buf, 0, sizeof (glibtop_proc_diskio)); +} diff --git a/sysdeps/stub_suid/glibtop_server.h b/sysdeps/stub_suid/glibtop_server.h index cf121212..ef0b191b 100644 --- a/sysdeps/stub_suid/glibtop_server.h +++ b/sysdeps/stub_suid/glibtop_server.h @@ -45,6 +45,7 @@ G_BEGIN_DECLS #define GLIBTOP_SUID_NETLOAD (1 << GLIBTOP_SYSDEPS_NETLOAD) #define GLIBTOP_SUID_NETLIST 0 #define GLIBTOP_SUID_PPP (1 << GLIBTOP_SYSDEPS_PPP) +#define GLIBTOP_SUID_PROC_DISKIO (1 << GLIBTOP_SYSDEPS_PROC_DISKIO) G_END_DECLS |