From ec489fb3362bebba5c06a8910cd7b2d8d85ca6c1 Mon Sep 17 00:00:00 2001 From: Netta Gavrieli Date: Tue, 30 Jul 2013 10:22:50 +0300 Subject: [PATCH 01/15] Java - Fixed loading native libraries from paths that contain international characters. This fixes Hyperic bug https://jira.hyperic.com/browse/HQ-4227 --- .../hyperic_jni/src/org/hyperic/jni/ArchLoader.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bindings/java/hyperic_jni/src/org/hyperic/jni/ArchLoader.java b/bindings/java/hyperic_jni/src/org/hyperic/jni/ArchLoader.java index 6a4fd8c3..c44fb5cd 100644 --- a/bindings/java/hyperic_jni/src/org/hyperic/jni/ArchLoader.java +++ b/bindings/java/hyperic_jni/src/org/hyperic/jni/ArchLoader.java @@ -17,6 +17,7 @@ package org.hyperic.jni; import java.io.File; +import java.io.UnsupportedEncodingException; import java.util.StringTokenizer; import java.net.URL; import java.net.URLClassLoader; @@ -315,7 +316,16 @@ public class ArchLoader { if ((file != null) && ((file = file.getParentFile()) != null)) { - String dir = URLDecoder.decode(file.toString()); + String dir; + try { + // Passing UTF-8 according to the recommendation in the URLDecoder.decode JavaDoc. + dir = URLDecoder.decode(file.toString(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + String msg = "Unsupported encoding in file name: " + file.toString(); + ArchLoaderException archLoaderException = new ArchLoaderException(msg); + archLoaderException.initCause(e); + throw archLoaderException; + } if (findNativeLibrary(dir, libName)) { return dir; } From a62558af5011d55ed7ed08c06bd7e8b97ec68794 Mon Sep 17 00:00:00 2001 From: nettag Date: Tue, 30 Jul 2013 10:37:01 +0300 Subject: [PATCH 02/15] Added Sigar.getProcDiskIO to Java API on Linux Returns the total bytes read and written for a process using /proc/pid/io. --- bindings/SigarWrapper.pm | 12 ++++++ .../java/src/org/hyperic/sigar/Sigar.java | 25 ++++++++++- .../src/org/hyperic/sigar/SigarProxy.java | 4 ++ .../src/org/hyperic/sigar/cmd/ProcInfo.java | 3 ++ .../hyperic/sigar/test/TestProcDiskIO.java | 43 +++++++++++++++++++ include/sigar.h | 9 ++++ src/os/linux/linux_sigar.c | 27 ++++++++++++ 7 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 bindings/java/src/org/hyperic/sigar/test/TestProcDiskIO.java diff --git a/bindings/SigarWrapper.pm b/bindings/SigarWrapper.pm index ce0dec4d..ef9d1e5c 100644 --- a/bindings/SigarWrapper.pm +++ b/bindings/SigarWrapper.pm @@ -627,6 +627,18 @@ use vars qw(%classes %cmds); plat => '*' }, ], + ProcDiskIO => [ + { + name => 'bytes_read', type => 'Long', + desc => 'Bytes Read', + plat => 'L' + }, + { + name => 'bytes_written', type => 'Long', + desc => 'Bytes Written', + plat => 'L' + } + ], ProcState => [ { name => 'state', type => 'Char', diff --git a/bindings/java/src/org/hyperic/sigar/Sigar.java b/bindings/java/src/org/hyperic/sigar/Sigar.java index 8274ba1e..7f230589 100644 --- a/bindings/java/src/org/hyperic/sigar/Sigar.java +++ b/bindings/java/src/org/hyperic/sigar/Sigar.java @@ -440,7 +440,7 @@ public class Sigar implements SigarProxy { return this.processFinder.findSingleProcess(pid); } } - + /** * Get process memory info. * @param pid The process id. @@ -638,6 +638,29 @@ public class Sigar implements SigarProxy { Integer.parseInt(port)); } + /** + * Get process disk IO info. + * @param pid THe process id. + * @exception SigarException on failure. + */ + public ProcDiskIO getProcDiskIO(long pid) throws SigarException { + try { + return ProcDiskIO.fetch(this, pid); + } catch (UnsatisfiedLinkError linkErrorException) { + // We want to handle exceptions gracefully even if the linked + // shared library is older and isn't compiled with the ProcDiskIO APIs. + // The downside of this is that we throw SigarNotImplemented exception + // also when the shared library can't be loaded. + SigarException sigarException = new SigarNotImplementedException(); + sigarException.initCause(linkErrorException); + throw sigarException; + } + } + + public ProcDiskIO getProcDiskIO(String pid) throws SigarException { + return getProcDiskIO(convertPid(pid)); + } + /** * Get the cumulative cpu time for the calling thread. */ diff --git a/bindings/java/src/org/hyperic/sigar/SigarProxy.java b/bindings/java/src/org/hyperic/sigar/SigarProxy.java index 97f03629..9c6b7e24 100644 --- a/bindings/java/src/org/hyperic/sigar/SigarProxy.java +++ b/bindings/java/src/org/hyperic/sigar/SigarProxy.java @@ -106,6 +106,10 @@ public interface SigarProxy { public long getProcPort(String protocol, String port) throws SigarException; + public ProcDiskIO getProcDiskIO(long pid) throws SigarException; + + public ProcDiskIO getProcDiskIO(String pid) throws SigarException; + public FileSystem[] getFileSystemList() throws SigarException; public FileSystemMap getFileSystemMap() throws SigarException; diff --git a/bindings/java/src/org/hyperic/sigar/cmd/ProcInfo.java b/bindings/java/src/org/hyperic/sigar/cmd/ProcInfo.java index e7614034..cd2f1dbd 100644 --- a/bindings/java/src/org/hyperic/sigar/cmd/ProcInfo.java +++ b/bindings/java/src/org/hyperic/sigar/cmd/ProcInfo.java @@ -100,6 +100,9 @@ public class ProcInfo extends SigarCommandBase { try { println("credname=" + sigar.getProcCredName(pid)); } catch (SigarException e) {} + try { + println("diskio=" + sigar.getProcDiskIO(pid)); + } catch (SigarException e) {} } public static void main(String[] args) throws Exception { diff --git a/bindings/java/src/org/hyperic/sigar/test/TestProcDiskIO.java b/bindings/java/src/org/hyperic/sigar/test/TestProcDiskIO.java new file mode 100644 index 00000000..d2eaf04e --- /dev/null +++ b/bindings/java/src/org/hyperic/sigar/test/TestProcDiskIO.java @@ -0,0 +1,43 @@ +package org.hyperic.sigar.test; + +import org.hyperic.sigar.ProcDiskIO; +import org.hyperic.sigar.Sigar; +import org.hyperic.sigar.SigarException; + +public class TestProcDiskIO extends SigarTestCase { + + public TestProcDiskIO(String name) { + super(name); + } + + + private void traceDiskIO(Sigar sigar, long pid) throws Exception { + ProcDiskIO procDiskIO; + + try { + procDiskIO = sigar.getProcDiskIO(pid); + } catch (SigarException e) { + traceln("pid " + pid + ": " + e.getMessage()); + return; + } + + traceln("Pid=" + pid); + traceln("Bytes Read=" + Sigar.formatSize(procDiskIO.getBytesRead())); + traceln("Bytes Written=" + Sigar.formatSize(procDiskIO.getBytesWritten())); + } + + public void testCreate() throws Exception { + Sigar sigar = getSigar(); + + try { + sigar.getProcDiskIO(getInvalidPid()); + } catch (SigarException e) { + } + + long[] pids = sigar.getProcList(); + for (int i=0; ibytes_read = get_named_proc_token(buffer, "\nread_bytes"); + proc_disk_io->bytes_written = get_named_proc_token(buffer, "\nwrite_bytes"); + + return SIGAR_OK; +} + #define NO_ID_MSG "[proc_cred] /proc/%lu" PROC_PSTATUS " missing " int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid, From 273889f82744e8ff8638393c9c20af0f0b3c56c7 Mon Sep 17 00:00:00 2001 From: Netta Gavrieli Date: Tue, 30 Jul 2013 06:04:06 -0700 Subject: [PATCH 03/15] Implemented process disk IO metrics on Windows --- src/os/win32/sigar_os.h | 2 ++ src/os/win32/win32_sigar.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/os/win32/sigar_os.h b/src/os/win32/sigar_os.h index cf61c25f..e98de45d 100755 --- a/src/os/win32/sigar_os.h +++ b/src/os/win32/sigar_os.h @@ -345,6 +345,8 @@ typedef struct { sigar_uint64_t handles; sigar_uint64_t threads; sigar_uint64_t page_faults; + sigar_uint64_t bytes_read; + sigar_uint64_t bytes_written; } sigar_win32_pinfo_t; typedef struct { diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index 4288f08f..100dee2e 100755 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -62,6 +62,8 @@ typedef enum { #define PERF_TITLE_PPID 1410 #define PERF_TITLE_PRIORITY 682 #define PERF_TITLE_START_TIME 684 +#define PERF_TITLE_IO_READ_BYTES_SEC 1420 +#define PERF_TITLE_IO_WRITE_BYTES_SEC 1422 typedef enum { PERF_IX_CPUTIME, @@ -74,6 +76,8 @@ typedef enum { PERF_IX_PPID, PERF_IX_PRIORITY, PERF_IX_START_TIME, + PERF_IX_IO_READ_BYTES_SEC, + PERF_IX_IO_WRITE_BYTES_SEC, PERF_IX_MAX } perf_proc_offsets_t; @@ -1210,6 +1214,22 @@ SIGAR_DECLARE(int) sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } +SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_disk_io_t *proc_disk_io) +{ + int status = get_proc_info(sigar, pid); + sigar_win32_pinfo_t *pinfo = &sigar->pinfo; + + if (status != SIGAR_OK) { + return status; + } + + proc_disk_io->bytes_read = pinfo->bytes_read; + proc_disk_io->bytes_written = pinfo->bytes_written; + + return SIGAR_OK; +} + #define TOKEN_DAC (STANDARD_RIGHTS_READ | READ_CONTROL | TOKEN_QUERY) SIGAR_DECLARE(int) @@ -1441,6 +1461,12 @@ static int get_proc_info(sigar_t *sigar, sigar_pid_t pid) case PERF_TITLE_START_TIME: perf_offsets[PERF_IX_START_TIME] = offset; break; + case PERF_TITLE_IO_READ_BYTES_SEC: + perf_offsets[PERF_IX_IO_READ_BYTES_SEC] = offset; + break; + case PERF_TITLE_IO_WRITE_BYTES_SEC: + perf_offsets[PERF_IX_IO_WRITE_BYTES_SEC] = offset; + break; } } @@ -1466,6 +1492,8 @@ static int get_proc_info(sigar_t *sigar, sigar_pid_t pid) pinfo->handles = PERF_VAL(PERF_IX_HANDLE_CNT); pinfo->threads = PERF_VAL(PERF_IX_THREAD_CNT); pinfo->page_faults = PERF_VAL(PERF_IX_PAGE_FAULTS); + pinfo->bytes_read = PERF_VAL(PERF_IX_IO_READ_BYTES_SEC); + pinfo->bytes_written = PERF_VAL(PERF_IX_IO_WRITE_BYTES_SEC); return SIGAR_OK; } From b13b8dcbbb45e7b9612e86dd6c2669f8426b8080 Mon Sep 17 00:00:00 2001 From: nettag Date: Tue, 30 Jul 2013 16:22:40 +0300 Subject: [PATCH 04/15] Implemented empty sigar_proc_disk_io_get on unsupported systems, to avoid breaking compilation. --- bindings/SigarWrapper.pm | 4 ++-- src/os/aix/aix_sigar.c | 7 +++++++ src/os/darwin/darwin_sigar.c | 7 +++++++ src/os/hpux/hpux_sigar.c | 7 +++++++ src/os/solaris/solaris_sigar.c | 6 ++++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/bindings/SigarWrapper.pm b/bindings/SigarWrapper.pm index ef9d1e5c..3fb33397 100644 --- a/bindings/SigarWrapper.pm +++ b/bindings/SigarWrapper.pm @@ -631,12 +631,12 @@ use vars qw(%classes %cmds); { name => 'bytes_read', type => 'Long', desc => 'Bytes Read', - plat => 'L' + plat => 'LW' }, { name => 'bytes_written', type => 'Long', desc => 'Bytes Written', - plat => 'L' + plat => 'LW' } ], ProcState => [ diff --git a/src/os/aix/aix_sigar.c b/src/os/aix/aix_sigar.c index a4c0a88d..7f58b58e 100644 --- a/src/os/aix/aix_sigar.c +++ b/src/os/aix/aix_sigar.c @@ -754,6 +754,13 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } +int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_disk_io_t *proc_disk_io) +{ + return SIGAR_ENOTIMPL; +} + + int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_cred_t *proccred) { diff --git a/src/os/darwin/darwin_sigar.c b/src/os/darwin/darwin_sigar.c index 0e154b09..8a80cd8f 100644 --- a/src/os/darwin/darwin_sigar.c +++ b/src/os/darwin/darwin_sigar.c @@ -1241,6 +1241,13 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } +int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_disk_io_t *proc_disk_io) +{ + return SIGAR_ENOTIMPL; +} + + int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_cred_t *proccred) { diff --git a/src/os/hpux/hpux_sigar.c b/src/os/hpux/hpux_sigar.c index f7a7adce..d362b04e 100644 --- a/src/os/hpux/hpux_sigar.c +++ b/src/os/hpux/hpux_sigar.c @@ -307,6 +307,13 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } +int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_disk_io_t *proc_disk_io) +{ + return SIGAR_ENOTIMPL; +} + + int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_cred_t *proccred) { diff --git a/src/os/solaris/solaris_sigar.c b/src/os/solaris/solaris_sigar.c index da9a2b63..8e8726e0 100644 --- a/src/os/solaris/solaris_sigar.c +++ b/src/os/solaris/solaris_sigar.c @@ -719,6 +719,12 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } +int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_disk_io_t *proc_disk_io) +{ + return SIGAR_ENOTIMPL; +} + int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_cred_t *proccred) { From 0d91f7d6a49e85269616a2ea31b36ecf1a87a1a1 Mon Sep 17 00:00:00 2001 From: nettag Date: Sun, 4 Aug 2013 16:19:41 +0300 Subject: [PATCH 05/15] Added total disk IO metric --- bindings/SigarWrapper.pm | 5 +++++ include/sigar.h | 3 ++- src/os/linux/linux_sigar.c | 1 + src/os/win32/win32_sigar.c | 5 +++-- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/bindings/SigarWrapper.pm b/bindings/SigarWrapper.pm index 3fb33397..6897c424 100644 --- a/bindings/SigarWrapper.pm +++ b/bindings/SigarWrapper.pm @@ -637,6 +637,11 @@ use vars qw(%classes %cmds); name => 'bytes_written', type => 'Long', desc => 'Bytes Written', plat => 'LW' + }, + { + name => 'bytes_total', type => 'Long', + desc => 'Bytes Total', + plat => 'LW' } ], ProcState => [ diff --git a/include/sigar.h b/include/sigar.h index 537c488e..f28b7594 100644 --- a/include/sigar.h +++ b/include/sigar.h @@ -295,7 +295,8 @@ SIGAR_DECLARE(int) sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, typedef struct { sigar_uint64_t bytes_read, - bytes_written; + bytes_written, + bytes_total; } sigar_proc_disk_io_t; SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, diff --git a/src/os/linux/linux_sigar.c b/src/os/linux/linux_sigar.c index 458ec213..6aab1c61 100644 --- a/src/os/linux/linux_sigar.c +++ b/src/os/linux/linux_sigar.c @@ -791,6 +791,7 @@ int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, proc_disk_io->bytes_read = get_named_proc_token(buffer, "\nread_bytes"); proc_disk_io->bytes_written = get_named_proc_token(buffer, "\nwrite_bytes"); + proc_disk_io->bytes_total = proc_disk_io->bytes_read + proc_disk_io->bytes_written; return SIGAR_OK; } diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index 100dee2e..aa15e757 100755 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -1224,8 +1224,9 @@ SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, return status; } - proc_disk_io->bytes_read = pinfo->bytes_read; - proc_disk_io->bytes_written = pinfo->bytes_written; + proc_disk_io->bytes_read = pinfo->bytes_read; + proc_disk_io->bytes_written = pinfo->bytes_written; + proc_disk_io->bytes_total = proc_disk_io->bytes_read + proc_disk_io->bytes_written; return SIGAR_OK; } From f15aa84dfee04b3bebd8686fe25007cd662b9744 Mon Sep 17 00:00:00 2001 From: nettag Date: Sun, 4 Aug 2013 16:41:36 +0300 Subject: [PATCH 06/15] Fixed TestProcDiskIO Added bytesTotal and some more verification. --- .../org/hyperic/sigar/test/TestProcDiskIO.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/test/TestProcDiskIO.java b/bindings/java/src/org/hyperic/sigar/test/TestProcDiskIO.java index d2eaf04e..5148941e 100644 --- a/bindings/java/src/org/hyperic/sigar/test/TestProcDiskIO.java +++ b/bindings/java/src/org/hyperic/sigar/test/TestProcDiskIO.java @@ -18,21 +18,35 @@ public class TestProcDiskIO extends SigarTestCase { procDiskIO = sigar.getProcDiskIO(pid); } catch (SigarException e) { traceln("pid " + pid + ": " + e.getMessage()); + // throw e; return; } + long bytesRead = procDiskIO.getBytesRead(); + long bytesWritten = procDiskIO.getBytesWritten(); + long bytesTotal = procDiskIO.getBytesTotal(); + traceln("Pid=" + pid); - traceln("Bytes Read=" + Sigar.formatSize(procDiskIO.getBytesRead())); - traceln("Bytes Written=" + Sigar.formatSize(procDiskIO.getBytesWritten())); + traceln("Bytes Read=" + Sigar.formatSize(bytesRead)); + traceln("Bytes Written=" + Sigar.formatSize(bytesWritten)); + traceln("Bytes Total=" + Sigar.formatSize(bytesTotal)); + + if (bytesRead != -1 && bytesWritten != -1 && bytesTotal != -1) { + assertTrue("Bytes total should equal bytesRead + bytesWritten", + (bytesTotal == bytesRead + bytesWritten)); + } } public void testCreate() throws Exception { Sigar sigar = getSigar(); + boolean caughtException = false; try { sigar.getProcDiskIO(getInvalidPid()); } catch (SigarException e) { + caughtException = true; } + assertTrue("Test on invalid PID should have thrown an exception.", caughtException); long[] pids = sigar.getProcList(); for (int i=0; i Date: Mon, 12 Aug 2013 09:34:24 +0000 Subject: [PATCH 07/15] show windoes 2012 --- src/os/win32/win32_sigar.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index aa15e757..a9f9d4ac 100755 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -3722,6 +3722,7 @@ int sigar_who_list_get_win32(sigar_t *sigar, #define SIGAR_ARCH "x86" #endif + int sigar_os_sys_info_get(sigar_t *sigar, sigar_sys_info_t *sysinfo) { @@ -3729,7 +3730,7 @@ int sigar_os_sys_info_get(sigar_t *sigar, char *vendor_name, *vendor_version, *code_name=NULL; version.dwOSVersionInfoSize = sizeof(version); - GetVersionEx((OSVERSIONINFO *)&version); + GetVersionEx((OSVERSIONINFO *)&version); if (version.dwMajorVersion == 4) { vendor_name = "Windows NT"; @@ -3769,11 +3770,25 @@ int sigar_os_sys_info_get(sigar_t *sigar, code_name = "Vienna"; } } - else { - vendor_name = "Windows 2008"; - vendor_version = "2008"; - code_name = "Longhorn Server"; - } + else { + // not nt work station + if (version.dwMinorVersion == 0 || version.dwMinorVersion ==1) { + vendor_name = "Windows 2008"; + vendor_version = "2008"; + code_name = "Longhorn Server"; + } + else if (version.dwMinorVersion == 2) { + vendor_name = "Windows 2012"; + vendor_version = "2012"; + code_name = "Windows Server 8"; + } + else { + // defaults + vendor_name = "Windows Unknown"; + vendor_version = "2012"; + } + } + } SIGAR_SSTRCPY(sysinfo->name, "Win32"); From aee1d82fae3573e03c4dd7b206c04c7e20f82f33 Mon Sep 17 00:00:00 2001 From: nira11 Date: Wed, 14 Aug 2013 10:20:58 +0000 Subject: [PATCH 08/15] disk io hpux --- src/os/hpux/hpux_sigar.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/os/hpux/hpux_sigar.c b/src/os/hpux/hpux_sigar.c index d362b04e..e2ec906a 100644 --- a/src/os/hpux/hpux_sigar.c +++ b/src/os/hpux/hpux_sigar.c @@ -310,7 +310,19 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_disk_io_t *proc_disk_io) { - return SIGAR_ENOTIMPL; + + int status = sigar_pstat_getproc(sigar, pid); + struct pst_status *pinfo = sigar->pinfo; + + if (status != SIGAR_OK) { + return status; + } + proc_disk_io->bytes_read = pinfo->pst_inblock; + proc_disk_io->bytes_written = pinfo->pst_oublock; + proc_disk_io->bytes_total = pinfo->pst_inblock + pinfo->pst_oublock; + + + return SIGAR_OK; } From 64f32dd125f31c2331969e5a9c7964846cda4e95 Mon Sep 17 00:00:00 2001 From: nira11 Date: Sun, 18 Aug 2013 08:24:25 +0000 Subject: [PATCH 09/15] solaris disk io --- src/os/solaris/solaris_sigar.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/os/solaris/solaris_sigar.c b/src/os/solaris/solaris_sigar.c index 8e8726e0..5083eac7 100644 --- a/src/os/solaris/solaris_sigar.c +++ b/src/os/solaris/solaris_sigar.c @@ -722,7 +722,16 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_disk_io_t *proc_disk_io) { - return SIGAR_ENOTIMPL; + prusage_t usage; + int status; + if ((status = sigar_proc_usage_get(sigar, &usage, pid)) != SIGAR_OK) { + return status; + } + proc_disk_io->bytes_read = usage.pr_inblk; + proc_disk_io->bytes_written = usage.pr_oublk; + proc_disk_io->bytes_total = usage.pr_ioch; + + return SIGAR_OK; } int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid, From 6508b09304cf6ba2bb97fceaee1854a37caae0ac Mon Sep 17 00:00:00 2001 From: nira11 Date: Sun, 18 Aug 2013 11:45:47 +0000 Subject: [PATCH 10/15] disk io on aix --- src/os/aix/aix_sigar.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/os/aix/aix_sigar.c b/src/os/aix/aix_sigar.c index 7f58b58e..2bc0d5bb 100644 --- a/src/os/aix/aix_sigar.c +++ b/src/os/aix/aix_sigar.c @@ -757,7 +757,19 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_disk_io_t *proc_disk_io) { - return SIGAR_ENOTIMPL; + int status = sigar_getprocs(sigar, pid); + struct procsinfo64 *pinfo = sigar->pinfo; + + if (status != SIGAR_OK) { + return status; + } + proc_disk_io->bytes_read = 0; + proc_disk_io->bytes_written = 0; + proc_disk_io->bytes_total = pinfo->pi_ioch; + + return SIGAR_OK; + + } From f2ba707d9fe39108c30f980b3811b10aad5536a7 Mon Sep 17 00:00:00 2001 From: nira11 Date: Tue, 27 Aug 2013 11:37:22 +0000 Subject: [PATCH 11/15] sigar hpux - disk io fix --- src/os/aix/aix_sigar.c | 4 ++-- src/os/hpux/hpux_sigar.c | 6 +++--- src/os/solaris/solaris_sigar.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/os/aix/aix_sigar.c b/src/os/aix/aix_sigar.c index 2bc0d5bb..ca6d5935 100644 --- a/src/os/aix/aix_sigar.c +++ b/src/os/aix/aix_sigar.c @@ -763,8 +763,8 @@ int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, if (status != SIGAR_OK) { return status; } - proc_disk_io->bytes_read = 0; - proc_disk_io->bytes_written = 0; + proc_disk_io->bytes_read = SIGAR_FIELD_NOTIMPL; + proc_disk_io->bytes_written = SIGAR_FIELD_NOTIMPL; proc_disk_io->bytes_total = pinfo->pi_ioch; return SIGAR_OK; diff --git a/src/os/hpux/hpux_sigar.c b/src/os/hpux/hpux_sigar.c index e2ec906a..0d5bbf92 100644 --- a/src/os/hpux/hpux_sigar.c +++ b/src/os/hpux/hpux_sigar.c @@ -317,9 +317,9 @@ int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, if (status != SIGAR_OK) { return status; } - proc_disk_io->bytes_read = pinfo->pst_inblock; - proc_disk_io->bytes_written = pinfo->pst_oublock; - proc_disk_io->bytes_total = pinfo->pst_inblock + pinfo->pst_oublock; + proc_disk_io->bytes_read = SIGAR_FIELD_NOTIMPL; + proc_disk_io->bytes_written = SIGAR_FIELD_NOTIMPL; + proc_disk_io->bytes_total = pinfo->pst_ioch; return SIGAR_OK; diff --git a/src/os/solaris/solaris_sigar.c b/src/os/solaris/solaris_sigar.c index 5083eac7..35a9d7df 100644 --- a/src/os/solaris/solaris_sigar.c +++ b/src/os/solaris/solaris_sigar.c @@ -727,8 +727,8 @@ int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, if ((status = sigar_proc_usage_get(sigar, &usage, pid)) != SIGAR_OK) { return status; } - proc_disk_io->bytes_read = usage.pr_inblk; - proc_disk_io->bytes_written = usage.pr_oublk; + proc_disk_io->bytes_read = SIGAR_FIELD_NOTIMPL; + proc_disk_io->bytes_written = SIGAR_FIELD_NOTIMPL; proc_disk_io->bytes_total = usage.pr_ioch; return SIGAR_OK; From 07b221a25345367f55fbfba6d3113c0e04068846 Mon Sep 17 00:00:00 2001 From: nira11 Date: Sun, 15 Sep 2013 12:00:23 +0000 Subject: [PATCH 12/15] disk io works using cache - also pid cache cleanup and pid cache dump --- bindings/SigarWrapper.pm | 32 +++++- .../java/src/org/hyperic/sigar/Sigar.java | 30 +++++ .../src/org/hyperic/sigar/SigarProxy.java | 6 + .../org/hyperic/sigar/cmd/PidCacheInfo.java | 51 +++++++++ .../src/org/hyperic/sigar/cmd/ProcInfo.java | 5 + .../java/src/org/hyperic/sigar/cmd/Shell.java | 2 + .../org/hyperic/sigar/jmx/SigarProcess.java | 16 +++ .../hyperic/sigar/jmx/SigarProcessMBean.java | 2 + include/sigar.h | 33 +++++- include/sigar_private.h | 9 +- include/sigar_util.h | 6 + src/os/aix/aix_sigar.c | 12 +- src/os/darwin/darwin_sigar.c | 4 +- src/os/hpux/hpux_sigar.c | 10 +- src/os/linux/linux_sigar.c | 12 +- src/os/solaris/solaris_sigar.c | 12 +- src/os/win32/win32_sigar.c | 10 +- src/sigar.c | 106 +++++++++++++++++- src/sigar_cache.c | 85 ++++++++++++-- src/sigar_ptql.c | 9 ++ 20 files changed, 409 insertions(+), 43 deletions(-) create mode 100644 bindings/java/src/org/hyperic/sigar/cmd/PidCacheInfo.java diff --git a/bindings/SigarWrapper.pm b/bindings/SigarWrapper.pm index 6897c424..1ddb50d2 100644 --- a/bindings/SigarWrapper.pm +++ b/bindings/SigarWrapper.pm @@ -43,6 +43,7 @@ my %has_name_arg = map { $_, 1 } qw(FileSystemUsage DiskUsage FileAttrs DirStat DirUsage NetInterfaceConfig NetInterfaceStat); + my %proc_no_arg = map { $_, 1 } qw(stat); my %get_not_impl = map { $_, 1 } qw(net_address net_route net_connection net_stat cpu_perc @@ -527,6 +528,7 @@ use vars qw(%classes %cmds); plat => '*' }, ], + ProcMem => [ { name => 'size', type => 'Long', @@ -641,9 +643,37 @@ use vars qw(%classes %cmds); { name => 'bytes_total', type => 'Long', desc => 'Bytes Total', - plat => 'LW' + plat => 'LWAHS' } ], + + ProcCumulativeDiskIO => [ + { + name => 'bytes_read', type => 'Long', + desc => 'Bytes Read from Start', + plat => 'LW' + }, + { + name => 'bytes_written', type => 'Long', + desc => 'Bytes Written from Start', + plat => 'LW' + }, + { + name => 'bytes_total', type => 'Long', + desc => 'Bytes Total from Start', + plat => 'LWAHS' + } + ], + + DumpPidCache => [ + { + name => 'dummy', type => 'Long', + desc => 'Dummy', + plat => 'LWAHS' + } + ], + + ProcState => [ { name => 'state', type => 'Char', diff --git a/bindings/java/src/org/hyperic/sigar/Sigar.java b/bindings/java/src/org/hyperic/sigar/Sigar.java index 7f230589..2b138add 100644 --- a/bindings/java/src/org/hyperic/sigar/Sigar.java +++ b/bindings/java/src/org/hyperic/sigar/Sigar.java @@ -42,6 +42,8 @@ public class Sigar implements SigarProxy { private static String loadError = null; public static final long FIELD_NOTIMPL = -1; + public static final int PID_PROC_CPU_CACHE = 1; + public static final int PID_PROC_IO_CACHE = 2; /** * The Sigar java version. @@ -661,6 +663,34 @@ public class Sigar implements SigarProxy { return getProcDiskIO(convertPid(pid)); } + /** + * Get process cumulative disk IO info. + * @param pid THe process id. + * @exception SigarException on failure. + */ + public ProcCumulativeDiskIO getProcCumulativeDiskIO(long pid) throws SigarException { + try { + return ProcCumulativeDiskIO.fetch(this, pid); + } catch (UnsatisfiedLinkError linkErrorException) { + // We want to handle exceptions gracefully even if the linked + // shared library is older and isn't compiled with the ProcDiskIO APIs. + // The downside of this is that we throw SigarNotImplemented exception + // also when the shared library can't be loaded. + SigarException sigarException = new SigarNotImplementedException(); + sigarException.initCause(linkErrorException); + throw sigarException; + } + } + + public ProcCumulativeDiskIO getProcCumulativeDiskIO(String pid) throws SigarException { + return getProcCumulativeDiskIO(convertPid(pid)); + } + + public DumpPidCache dumpPidCache() throws SigarException { + return DumpPidCache.fetch(this); + } + + /** * Get the cumulative cpu time for the calling thread. */ diff --git a/bindings/java/src/org/hyperic/sigar/SigarProxy.java b/bindings/java/src/org/hyperic/sigar/SigarProxy.java index 9c6b7e24..124be26a 100644 --- a/bindings/java/src/org/hyperic/sigar/SigarProxy.java +++ b/bindings/java/src/org/hyperic/sigar/SigarProxy.java @@ -110,6 +110,12 @@ public interface SigarProxy { public ProcDiskIO getProcDiskIO(String pid) throws SigarException; + public ProcCumulativeDiskIO getProcCumulativeDiskIO(long pid) throws SigarException; + + public ProcCumulativeDiskIO getProcCumulativeDiskIO(String pid) throws SigarException; + + public DumpPidCache dumpPidCache() throws SigarException; + public FileSystem[] getFileSystemList() throws SigarException; public FileSystemMap getFileSystemMap() throws SigarException; diff --git a/bindings/java/src/org/hyperic/sigar/cmd/PidCacheInfo.java b/bindings/java/src/org/hyperic/sigar/cmd/PidCacheInfo.java new file mode 100644 index 00000000..7404db3c --- /dev/null +++ b/bindings/java/src/org/hyperic/sigar/cmd/PidCacheInfo.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006-2007 Hyperic, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.hyperic.sigar.cmd; + +import org.hyperic.sigar.SigarException; +import org.hyperic.sigar.SigarPermissionDeniedException; + +/** + * Display all pid cache information. + */ +public class PidCacheInfo extends SigarCommandBase { + + + public PidCacheInfo(Shell shell) { + super(shell); + } + + public PidCacheInfo() { + super(); + } + + protected boolean validateArgs(String[] args) { + return true; + } + + public String getUsageShort() { + return "Display cache info for CPU cache and for IO cache"; + } + + public boolean isPidCompleter() { + return false; + } + + public void output(String[] args) throws SigarException { + sigar.dumpPidCache(); + } +} diff --git a/bindings/java/src/org/hyperic/sigar/cmd/ProcInfo.java b/bindings/java/src/org/hyperic/sigar/cmd/ProcInfo.java index cd2f1dbd..d68f9e75 100644 --- a/bindings/java/src/org/hyperic/sigar/cmd/ProcInfo.java +++ b/bindings/java/src/org/hyperic/sigar/cmd/ProcInfo.java @@ -103,6 +103,11 @@ public class ProcInfo extends SigarCommandBase { try { println("diskio=" + sigar.getProcDiskIO(pid)); } catch (SigarException e) {} + + try { + println("cumulative diskio=" + sigar.getProcCumulativeDiskIO(pid)); + } catch (SigarException e) {} + } public static void main(String[] args) throws Exception { diff --git a/bindings/java/src/org/hyperic/sigar/cmd/Shell.java b/bindings/java/src/org/hyperic/sigar/cmd/Shell.java index ed4ed92f..fd955380 100644 --- a/bindings/java/src/org/hyperic/sigar/cmd/Shell.java +++ b/bindings/java/src/org/hyperic/sigar/cmd/Shell.java @@ -103,6 +103,8 @@ public class Shell extends ShellBase { registerCommandHandler("time", new Time(this)); registerCommandHandler("ulimit", new Ulimit(this)); registerCommandHandler("who", new Who(this)); + registerCommandHandler("pid_cache_info", new PidCacheInfo(this)); + if (SigarLoader.IS_WIN32) { registerCommandHandler("service", new Win32Service(this)); registerCommandHandler("fversion", new FileVersionInfo(this)); diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarProcess.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarProcess.java index 55f23adb..ace1d874 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarProcess.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarProcess.java @@ -20,6 +20,7 @@ import org.hyperic.sigar.ProcCpu; import org.hyperic.sigar.ProcFd; import org.hyperic.sigar.ProcMem; import org.hyperic.sigar.ProcUtil; +import org.hyperic.sigar.ProcDiskIO; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.SigarProxy; @@ -76,6 +77,16 @@ public class SigarProcess implements SigarProcessMBean { } } + + private synchronized ProcDiskIO getDiskIO() { + try { + return this.sigar.getProcDiskIO(getPid()); + } catch (SigarException e) { + throw unexpectedError("DiskIO", e); + } + } + + private synchronized ProcFd getFd() throws SigarException { return this.sigar.getProcFd(getPid()); } @@ -153,4 +164,9 @@ public class SigarProcess implements SigarProcessMBean { return NOTIMPL; } } + + public Double getBytesReadWriteTotal() { + return new Double(getDiskIO().getBytesTotal()); + } + } diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarProcessMBean.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarProcessMBean.java index d88d35e8..52b45488 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarProcessMBean.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarProcessMBean.java @@ -44,4 +44,6 @@ public interface SigarProcessMBean { public Double getCpuUsage(); public Long getOpenFd(); + + public Double getBytesReadWriteTotal(); } diff --git a/include/sigar.h b/include/sigar.h index f28b7594..2245d46e 100644 --- a/include/sigar.h +++ b/include/sigar.h @@ -293,7 +293,7 @@ SIGAR_DECLARE(int) sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_mem_t *procmem); typedef struct { - sigar_uint64_t + sigar_uint64_t bytes_read, bytes_written, bytes_total; @@ -302,6 +302,37 @@ typedef struct { SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_disk_io_t *proc_disk_io); +typedef struct { + sigar_uint64_t + bytes_read, + bytes_written, + bytes_total; + sigar_uint64_t last_time; + sigar_uint64_t + bytes_read_diff, + bytes_written_diff, + bytes_total_diff; +} sigar_cached_proc_disk_io_t; + + +typedef struct { + sigar_uint64_t + bytes_read, + bytes_written, + bytes_total; +} sigar_proc_cumulative_disk_io_t; + +SIGAR_DECLARE(int) sigar_proc_cumulative_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_cumulative_disk_io_t *proc_cumulative_disk_io); + + +typedef struct { + sigar_uint64_t dummy; +}sigar_dump_pid_cache_t; + +SIGAR_DECLARE(int) sigar_dump_pid_cache_get(sigar_t *sigar, sigar_dump_pid_cache_t *info); + + typedef struct { sigar_uid_t uid; sigar_gid_t gid; diff --git a/include/sigar_private.h b/include/sigar_private.h index cfc9aa2f..303a16a3 100644 --- a/include/sigar_private.h +++ b/include/sigar_private.h @@ -68,7 +68,8 @@ sigar_cache_t *proc_cpu; \ sigar_cache_t *net_listen; \ sigar_cache_t *net_services_tcp; \ - sigar_cache_t *net_services_udp + sigar_cache_t *net_services_udp;\ + sigar_cache_t *proc_io; #if defined(WIN32) # define SIGAR_INLINE __inline @@ -398,11 +399,15 @@ int sigar_get_iftype(const char *name, int *type, int *inst); #define SIGAR_NIC_SIT "IPv6-in-IPv4" #define SIGAR_NIC_IRDA "IrLAP" #define SIGAR_NIC_EC "Econet" - +#define PID_CACHE_CLEANUP_PERIOD 1000*60*10 /* 10 minutes */ +#define PID_CACHE_ENTRY_EXPIRE_PERIOD 1000*60*20 /* 20 minutes */ #ifndef WIN32 #include #endif +#define PROC_PID_CPU_CACHE 1 +#define PROC_PID_IO_CACHE 2 + #define SIGAR_HOSTENT_LEN 1024 #if defined(_AIX) #define SIGAR_HAS_HOSTENT_DATA diff --git a/include/sigar_util.h b/include/sigar_util.h index bc605fc9..b3c4dd7d 100644 --- a/include/sigar_util.h +++ b/include/sigar_util.h @@ -170,15 +170,21 @@ struct sigar_cache_entry_t { sigar_cache_entry_t *next; sigar_uint64_t id; void *value; + sigar_uint64_t last_access_time; }; typedef struct { sigar_cache_entry_t **entries; unsigned int count, size; void (*free_value)(void *ptr); + sigar_uint64_t entry_expire_period; + sigar_uint64_t cleanup_period_millis; + sigar_uint64_t last_cleanup_time; } sigar_cache_t; sigar_cache_t *sigar_cache_new(int size); +sigar_cache_t *sigar_expired_cache_new(int size, sigar_uint64_t cleanup_period_millis, sigar_uint64_t entry_expire_period); +void sigar_cache_dump(sigar_cache_t *table); sigar_cache_entry_t *sigar_cache_get(sigar_cache_t *table, sigar_uint64_t key); diff --git a/src/os/aix/aix_sigar.c b/src/os/aix/aix_sigar.c index ca6d5935..882e2723 100644 --- a/src/os/aix/aix_sigar.c +++ b/src/os/aix/aix_sigar.c @@ -754,8 +754,8 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } -int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, - sigar_proc_disk_io_t *proc_disk_io) +int sigar_proc_cumulative_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_cumulative_disk_io_t *cumulative_proc_disk_io) { int status = sigar_getprocs(sigar, pid); struct procsinfo64 *pinfo = sigar->pinfo; @@ -763,13 +763,11 @@ int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, if (status != SIGAR_OK) { return status; } - proc_disk_io->bytes_read = SIGAR_FIELD_NOTIMPL; - proc_disk_io->bytes_written = SIGAR_FIELD_NOTIMPL; - proc_disk_io->bytes_total = pinfo->pi_ioch; + cumulative_proc_disk_io->bytes_read = SIGAR_FIELD_NOTIMPL; + cumulative_proc_disk_io->bytes_written = SIGAR_FIELD_NOTIMPL; + cumulative_proc_disk_io->bytes_total = pinfo->pi_ioch; return SIGAR_OK; - - } diff --git a/src/os/darwin/darwin_sigar.c b/src/os/darwin/darwin_sigar.c index 8a80cd8f..b8c7568a 100644 --- a/src/os/darwin/darwin_sigar.c +++ b/src/os/darwin/darwin_sigar.c @@ -1241,8 +1241,8 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } -int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, - sigar_proc_disk_io_t *proc_disk_io) +int sigar_proc_cumulative_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_cumulative_disk_io_t *proc_cumulative_disk_io) { return SIGAR_ENOTIMPL; } diff --git a/src/os/hpux/hpux_sigar.c b/src/os/hpux/hpux_sigar.c index 0d5bbf92..cb98f0a5 100644 --- a/src/os/hpux/hpux_sigar.c +++ b/src/os/hpux/hpux_sigar.c @@ -307,8 +307,8 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } -int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, - sigar_proc_disk_io_t *proc_disk_io) +int sigar_proc_cumulative_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_cumulative_disk_io_t *proc_cumulative_disk_io) { int status = sigar_pstat_getproc(sigar, pid); @@ -317,9 +317,9 @@ int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, if (status != SIGAR_OK) { return status; } - proc_disk_io->bytes_read = SIGAR_FIELD_NOTIMPL; - proc_disk_io->bytes_written = SIGAR_FIELD_NOTIMPL; - proc_disk_io->bytes_total = pinfo->pst_ioch; + proc_cumulative_disk_io->bytes_read = SIGAR_FIELD_NOTIMPL; + proc_cumulative_disk_io->bytes_written = SIGAR_FIELD_NOTIMPL; + proc_cumulative_disk_io->bytes_total = pinfo->pst_ioch; return SIGAR_OK; diff --git a/src/os/linux/linux_sigar.c b/src/os/linux/linux_sigar.c index 6aab1c61..a3fd2301 100644 --- a/src/os/linux/linux_sigar.c +++ b/src/os/linux/linux_sigar.c @@ -778,10 +778,10 @@ SIGAR_INLINE sigar_uint64_t get_named_proc_token(char *buffer, return sigar_strtoul(ptr); } -int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, - sigar_proc_disk_io_t *proc_disk_io) +int sigar_proc_cumulative_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_cumulative_disk_io_t *proc_cumulative_disk_io) { - char buffer[BUFSIZ], *ptr=buffer; + char buffer[BUFSIZ]; int status = SIGAR_PROC_FILE2STR(buffer, pid, "/io"); @@ -789,9 +789,9 @@ int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, return status; } - proc_disk_io->bytes_read = get_named_proc_token(buffer, "\nread_bytes"); - proc_disk_io->bytes_written = get_named_proc_token(buffer, "\nwrite_bytes"); - proc_disk_io->bytes_total = proc_disk_io->bytes_read + proc_disk_io->bytes_written; + proc_cumulative_disk_io->bytes_read = get_named_proc_token(buffer, "\nread_bytes"); + proc_cumulative_disk_io->bytes_written = get_named_proc_token(buffer, "\nwrite_bytes"); + proc_cumulative_disk_io->bytes_total = proc_cumulative_disk_io->bytes_read + proc_cumulative_disk_io->bytes_written; return SIGAR_OK; } diff --git a/src/os/solaris/solaris_sigar.c b/src/os/solaris/solaris_sigar.c index 35a9d7df..7a21e194 100644 --- a/src/os/solaris/solaris_sigar.c +++ b/src/os/solaris/solaris_sigar.c @@ -407,7 +407,7 @@ int sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu) cpu->idle += xcpu->idle; cpu->nice += xcpu->nice; cpu->wait += xcpu->wait; - cpu->total = xcpu->total; + cpu->total += xcpu->total; } return SIGAR_OK; @@ -719,17 +719,17 @@ int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } -int sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, - sigar_proc_disk_io_t *proc_disk_io) +int sigar_proc_cumulative_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_cumulative_disk_io_t *proc_cumulative_disk_io) { prusage_t usage; int status; if ((status = sigar_proc_usage_get(sigar, &usage, pid)) != SIGAR_OK) { return status; } - proc_disk_io->bytes_read = SIGAR_FIELD_NOTIMPL; - proc_disk_io->bytes_written = SIGAR_FIELD_NOTIMPL; - proc_disk_io->bytes_total = usage.pr_ioch; + proc_cumulative_disk_io->bytes_read = SIGAR_FIELD_NOTIMPL; + proc_cumulative_disk_io->bytes_written = SIGAR_FIELD_NOTIMPL; + proc_cumulative_disk_io->bytes_total = usage.pr_ioch; return SIGAR_OK; } diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index a9f9d4ac..cbe94a4e 100755 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -1214,8 +1214,8 @@ SIGAR_DECLARE(int) sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } -SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, - sigar_proc_disk_io_t *proc_disk_io) +SIGAR_DECLARE(int) sigar_proc_cumulative_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_cumulative_disk_io_t *proc_cumulative_disk_io) { int status = get_proc_info(sigar, pid); sigar_win32_pinfo_t *pinfo = &sigar->pinfo; @@ -1224,9 +1224,9 @@ SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, return status; } - proc_disk_io->bytes_read = pinfo->bytes_read; - proc_disk_io->bytes_written = pinfo->bytes_written; - proc_disk_io->bytes_total = proc_disk_io->bytes_read + proc_disk_io->bytes_written; + proc_cumulative_disk_io->bytes_read = pinfo->bytes_read; + proc_cumulative_disk_io->bytes_written = pinfo->bytes_written; + proc_cumulative_disk_io->bytes_total = proc_cumulative_disk_io->bytes_read + proc_cumulative_disk_io->bytes_written; return SIGAR_OK; } diff --git a/src/sigar.c b/src/sigar.c index 7f76dfd6..2bf223ae 100644 --- a/src/sigar.c +++ b/src/sigar.c @@ -64,6 +64,7 @@ SIGAR_DECLARE(int) sigar_open(sigar_t **sigar) (*sigar)->net_listen = NULL; (*sigar)->net_services_tcp = NULL; (*sigar)->net_services_udp = NULL; + (*sigar)->proc_io = NULL; } return status; @@ -96,6 +97,11 @@ SIGAR_DECLARE(int) sigar_close(sigar_t *sigar) if (sigar->net_services_udp) { sigar_cache_destroy(sigar->net_services_udp); } + if (sigar->proc_io) { + sigar_cache_destroy(sigar->proc_io); + } + + return sigar_os_close(sigar); } @@ -123,7 +129,7 @@ SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid, int status; if (!sigar->proc_cpu) { - sigar->proc_cpu = sigar_cache_new(128); + sigar->proc_cpu = sigar_expired_cache_new(128, PID_CACHE_CLEANUP_PERIOD, PID_CACHE_ENTRY_EXPIRE_PERIOD); } entry = sigar_cache_get(sigar->proc_cpu, pid); @@ -172,6 +178,104 @@ SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid, return SIGAR_OK; } +void copy_cached_disk_io_into_disk_io( sigar_cached_proc_disk_io_t *cached, sigar_proc_disk_io_t *proc_disk_io) { + proc_disk_io->bytes_read = cached->bytes_read_diff; + proc_disk_io->bytes_written = cached->bytes_written_diff; + proc_disk_io->bytes_total = cached->bytes_total_diff; +} + +sigar_uint64_t get_io_diff(sigar_uint64_t current_value, sigar_uint64_t prev_value, sigar_uint64_t time_diff) { + if ( current_value == SIGAR_FIELD_NOTIMPL ) { + return SIGAR_FIELD_NOTIMPL; + } + double io_diff = (( current_value - prev_value)/(double)time_diff)*SIGAR_MSEC; + sigar_uint64_t int_io_diff = (sigar_uint64_t)io_diff; + if (int_io_diff >=0) { + return int_io_diff; + } + return 0; +} + +void calculate_io_diff(sigar_proc_cumulative_disk_io_t * proc_disk_io, sigar_cached_proc_disk_io_t *cached, sigar_uint64_t time_diff, int is_first_time) { + /*calculate avg diff /read/write/total per second*/ + if (!is_first_time) { + cached->bytes_written_diff = get_io_diff(proc_disk_io->bytes_written, cached->bytes_written, time_diff); + cached->bytes_read_diff = get_io_diff(proc_disk_io->bytes_read, cached->bytes_read, time_diff); + cached->bytes_total_diff = get_io_diff(proc_disk_io->bytes_total, cached->bytes_total, time_diff); + } + else { + cached->bytes_total_diff = cached->bytes_read_diff = cached->bytes_written_diff = 0.0; + } + // now put in cache the current cumulative values + cached->bytes_written = proc_disk_io->bytes_written; + cached->bytes_read = proc_disk_io->bytes_read; + cached->bytes_total = proc_disk_io->bytes_total; +} + +SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, + sigar_proc_disk_io_t *proc_disk_io) +{ + sigar_cache_entry_t *entry; + sigar_cached_proc_disk_io_t *prev; + sigar_proc_cumulative_disk_io_t cumulative_proc_disk_io; + sigar_uint64_t time_now = sigar_time_now_millis(); + sigar_uint64_t time_diff; + int status; + + if (!sigar->proc_io) { + sigar->proc_io = sigar_expired_cache_new(128, PID_CACHE_CLEANUP_PERIOD, PID_CACHE_ENTRY_EXPIRE_PERIOD); + } + + entry = sigar_cache_get(sigar->proc_io, pid); + if (entry->value) { + prev = (sigar_cached_proc_disk_io_t *)entry->value; + } + else { + prev = entry->value = malloc(sizeof(*prev)); + SIGAR_ZERO(prev); + } + int is_first_time = (prev->last_time == 0); + time_diff = time_now - prev->last_time; + + if (time_diff < 1000) { + /* we were just called within < 1 second ago. */ + copy_cached_disk_io_into_disk_io(prev, proc_disk_io); + if (time_diff < 0) { + // something is wrong at least from now on the time will be ok + prev->last_time = time_now; + } + return SIGAR_OK; + } + prev->last_time = time_now; + + + status = + sigar_proc_cumulative_disk_io_get(sigar, pid, + &cumulative_proc_disk_io); + + if (status != SIGAR_OK) { + return status; + } + calculate_io_diff(&cumulative_proc_disk_io, prev, time_diff, is_first_time); + copy_cached_disk_io_into_disk_io(prev, proc_disk_io); + return SIGAR_OK; +} + +void get_cache_info(sigar_cache_t * cache, char * name){ + if (cache == NULL) { + return; + } + + printf("******** %s *********\n", name); + sigar_cache_dump(cache); +} + +SIGAR_DECLARE(int) sigar_dump_pid_cache_get(sigar_t *sigar, sigar_dump_pid_cache_t *info) { + + get_cache_info(sigar->proc_cpu, "proc cpu cache"); + get_cache_info(sigar->proc_io, "proc io cache"); + return SIGAR_OK; +} SIGAR_DECLARE(int) sigar_proc_stat_get(sigar_t *sigar, sigar_proc_stat_t *procstat) diff --git a/src/sigar_cache.c b/src/sigar_cache.c index 8d640167..57b08e00 100644 --- a/src/sigar_cache.c +++ b/src/sigar_cache.c @@ -35,7 +35,7 @@ static void free_value(void *ptr) free(ptr); } -sigar_cache_t *sigar_cache_new(int size) +sigar_cache_t *sigar_expired_cache_new(int size, sigar_uint64_t cleanup_period_millis, sigar_uint64_t entry_expire_period) { sigar_cache_t *table = malloc(sizeof(*table)); table->count = 0; @@ -43,16 +43,27 @@ sigar_cache_t *sigar_cache_new(int size) table->entries = malloc(ENTRIES_SIZE(size)); memset(table->entries, '\0', ENTRIES_SIZE(size)); table->free_value = free_value; + table->cleanup_period_millis = cleanup_period_millis; + table->last_cleanup_time = sigar_time_now_millis(); + table->entry_expire_period = entry_expire_period; return table; } -#ifdef DEBUG_CACHE +sigar_cache_t *sigar_cache_new(int size) +{ + return sigar_expired_cache_new(size, SIGAR_FIELD_NOTIMPL, SIGAR_FIELD_NOTIMPL); +} + + +/*#ifdef DEBUG_CACHE*/ /* see how well entries are distributed */ -static void sigar_cache_dump(sigar_cache_t *table) +void sigar_cache_dump(sigar_cache_t *table) { int i; sigar_cache_entry_t **entries = table->entries; - + printf("table size %lu\n", (long)table->size); + printf("table count %lu\n", (long)table->count); + for (i=0; isize; i++) { sigar_cache_entry_t *entry = *entries++; @@ -68,12 +79,12 @@ static void sigar_cache_dump(sigar_cache_t *table) printf("\n"); fflush(stdout); } -#endif +/*#endif*/ static void sigar_cache_rehash(sigar_cache_t *table) { int i; - unsigned int new_size = table->size * 2 + 1; + unsigned int new_size = table->count * 2 + 1; sigar_cache_entry_t **entries = table->entries; sigar_cache_entry_t **new_entries = malloc(ENTRIES_SIZE(new_size)); @@ -101,16 +112,73 @@ static void sigar_cache_rehash(sigar_cache_t *table) #define SIGAR_CACHE_IX(t, k) \ t->entries + (k % t->size) +void sigar_perform_cleanup_if_necessary(sigar_cache_t *table) { + if (table->cleanup_period_millis == SIGAR_FIELD_NOTIMPL) { + /* no cleanup for this cache) */ + } + sigar_uint64_t current_time = sigar_time_now_millis(); + if ((current_time - table->last_cleanup_time) < table->cleanup_period_millis) { + /* not enough time has passed since last cleanup */ + return; + } + + /* performing cleanup */ + int i; + sigar_cache_entry_t **entries = table->entries; + + table->last_cleanup_time = current_time; + + for (i=0; isize; i++) { + sigar_cache_entry_t *entry, *ptr, *entry_prev=NULL, **entry_in_table; + entry_in_table = entries; + entry = *entries++; + + while (entry) { + ptr = entry->next; + sigar_uint64_t period_with_no_access = current_time - entry->last_access_time; + if (table->entry_expire_period < period_with_no_access) { + /* no one acess this entry for too long - we can delete it */ + if (entry->value) { + table->free_value(entry->value); + } + free(entry); + table->count--; + if (entry_prev != NULL) { + entry_prev->next = ptr; + } + else { + /* removing first entry - head of list should point to next entry */ + *entry_in_table = ptr; + } + } + else { + /* entry not expired - advance entry_prev to current entry*/ + entry_prev = entry; + } + entry = ptr; + } + } + if (table->count < (table->size/4)) { + /* hash table (the array size) too big for the amount of values it contains perform rehash */ + sigar_cache_rehash(table); + } +} + + + + sigar_cache_entry_t *sigar_cache_find(sigar_cache_t *table, sigar_uint64_t key) { sigar_cache_entry_t *entry, **ptr; + sigar_perform_cleanup_if_necessary(table); for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr; entry; ptr = &entry->next, entry = *ptr) { if (entry->id == key) { + entry->last_access_time = sigar_time_now_millis(); return entry; } } @@ -123,17 +191,19 @@ sigar_cache_entry_t *sigar_cache_get(sigar_cache_t *table, sigar_uint64_t key) { sigar_cache_entry_t *entry, **ptr; + sigar_perform_cleanup_if_necessary(table); for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr; entry; ptr = &entry->next, entry = *ptr) { if (entry->id == key) { + entry->last_access_time = sigar_time_now_millis(); return entry; } } - if (table->count++ > table->size) { + if (++table->count > table->size) { sigar_cache_rehash(table); for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr; @@ -147,6 +217,7 @@ sigar_cache_entry_t *sigar_cache_get(sigar_cache_t *table, entry->id = key; entry->value = NULL; entry->next = NULL; + entry->last_access_time = sigar_time_now_millis(); return entry; } diff --git a/src/sigar_ptql.c b/src/sigar_ptql.c index 8e80e827..3ed5a46c 100644 --- a/src/sigar_ptql.c +++ b/src/sigar_ptql.c @@ -1338,6 +1338,14 @@ static ptql_lookup_t PTQL_Cpu[] = { { NULL } }; +static ptql_lookup_t PTQL_Disk_IO[] = { + { "BytesRead", PTQL_LOOKUP_ENTRY(proc_disk_io, bytes_read, UI64) }, + { "BytesWritten", PTQL_LOOKUP_ENTRY(proc_disk_io, bytes_written, UI64) }, + { "BytesTotal", PTQL_LOOKUP_ENTRY(proc_disk_io, bytes_total, UI64) }, + { NULL } +}; + + static ptql_lookup_t PTQL_CredName[] = { { "User", PTQL_LOOKUP_ENTRY(proc_cred_name, user, STR) }, { "Group", PTQL_LOOKUP_ENTRY(proc_cred_name, group, STR) }, @@ -1424,6 +1432,7 @@ static ptql_entry_t ptql_map[] = { { "Port", PTQL_Port }, { "Pid", PTQL_Pid }, { "Service", PTQL_Service }, + { "Disk_IO", PTQL_Disk_IO }, { NULL } }; From 924c4c7476f73c6d1abb444dccb9977dbbd3eadf Mon Sep 17 00:00:00 2001 From: nira11 Date: Sun, 15 Sep 2013 13:54:49 +0000 Subject: [PATCH 13/15] removed; --- include/sigar_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sigar_private.h b/include/sigar_private.h index 303a16a3..484f8306 100644 --- a/include/sigar_private.h +++ b/include/sigar_private.h @@ -69,7 +69,7 @@ sigar_cache_t *net_listen; \ sigar_cache_t *net_services_tcp; \ sigar_cache_t *net_services_udp;\ - sigar_cache_t *proc_io; + sigar_cache_t *proc_io #if defined(WIN32) # define SIGAR_INLINE __inline From 6ed8f3c9b5046ea7594f97ddc8c9173708a18e9d Mon Sep 17 00:00:00 2001 From: nira11 Date: Sun, 15 Sep 2013 14:14:42 +0000 Subject: [PATCH 14/15] c on win compatability poblems --- src/sigar.c | 10 ++++++---- src/sigar_cache.c | 25 ++++++++++++++----------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/sigar.c b/src/sigar.c index 2bf223ae..45ce5de5 100644 --- a/src/sigar.c +++ b/src/sigar.c @@ -185,11 +185,13 @@ void copy_cached_disk_io_into_disk_io( sigar_cached_proc_disk_io_t *cached, sig } sigar_uint64_t get_io_diff(sigar_uint64_t current_value, sigar_uint64_t prev_value, sigar_uint64_t time_diff) { + double io_diff; + sigar_uint64_t int_io_diff; if ( current_value == SIGAR_FIELD_NOTIMPL ) { return SIGAR_FIELD_NOTIMPL; } - double io_diff = (( current_value - prev_value)/(double)time_diff)*SIGAR_MSEC; - sigar_uint64_t int_io_diff = (sigar_uint64_t)io_diff; + io_diff = (( current_value - prev_value)/(double)time_diff)*SIGAR_MSEC; + int_io_diff = (sigar_uint64_t)io_diff; if (int_io_diff >=0) { return int_io_diff; } @@ -220,7 +222,7 @@ SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_cumulative_disk_io_t cumulative_proc_disk_io; sigar_uint64_t time_now = sigar_time_now_millis(); sigar_uint64_t time_diff; - int status; + int status, is_first_time; if (!sigar->proc_io) { sigar->proc_io = sigar_expired_cache_new(128, PID_CACHE_CLEANUP_PERIOD, PID_CACHE_ENTRY_EXPIRE_PERIOD); @@ -234,7 +236,7 @@ SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid, prev = entry->value = malloc(sizeof(*prev)); SIGAR_ZERO(prev); } - int is_first_time = (prev->last_time == 0); + is_first_time = (prev->last_time == 0); time_diff = time_now - prev->last_time; if (time_diff < 1000) { diff --git a/src/sigar_cache.c b/src/sigar_cache.c index 57b08e00..5b158edc 100644 --- a/src/sigar_cache.c +++ b/src/sigar_cache.c @@ -113,18 +113,21 @@ static void sigar_cache_rehash(sigar_cache_t *table) t->entries + (k % t->size) void sigar_perform_cleanup_if_necessary(sigar_cache_t *table) { + sigar_uint64_t current_time; + int i; + sigar_cache_entry_t **entries; if (table->cleanup_period_millis == SIGAR_FIELD_NOTIMPL) { - /* no cleanup for this cache) */ + /* no cleanup for this cache) */ + return; } - sigar_uint64_t current_time = sigar_time_now_millis(); + current_time = sigar_time_now_millis(); if ((current_time - table->last_cleanup_time) < table->cleanup_period_millis) { /* not enough time has passed since last cleanup */ return; } - /* performing cleanup */ - int i; - sigar_cache_entry_t **entries = table->entries; + /* performing cleanup */ + entries = table->entries; table->last_cleanup_time = current_time; @@ -134,15 +137,15 @@ void sigar_perform_cleanup_if_necessary(sigar_cache_t *table) { entry = *entries++; while (entry) { - ptr = entry->next; - sigar_uint64_t period_with_no_access = current_time - entry->last_access_time; + sigar_uint64_t period_with_no_access = current_time - entry->last_access_time; + ptr = entry->next; if (table->entry_expire_period < period_with_no_access) { - /* no one acess this entry for too long - we can delete it */ - if (entry->value) { + /* no one acess this entry for too long - we can delete it */ + if (entry->value) { table->free_value(entry->value); } free(entry); - table->count--; + table->count--; if (entry_prev != NULL) { entry_prev->next = ptr; } @@ -154,7 +157,7 @@ void sigar_perform_cleanup_if_necessary(sigar_cache_t *table) { else { /* entry not expired - advance entry_prev to current entry*/ entry_prev = entry; - } + } entry = ptr; } } From 47f01e0177918f90f1b987e1786957a72c664f5c Mon Sep 17 00:00:00 2001 From: tgoldman Date: Mon, 30 Sep 2013 10:53:08 +0200 Subject: [PATCH 15/15] [SIGAR-248]- Sigar log monitoring ignores successive lines with same timestamp --- .../java/src/org/hyperic/sigar/FileInfo.java | 161 +++++++++++------- .../org/hyperic/sigar/test/TestFileInfo.java | 8 +- 2 files changed, 100 insertions(+), 69 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/FileInfo.java b/bindings/java/src/org/hyperic/sigar/FileInfo.java index 6e34fc24..bed90860 100644 --- a/bindings/java/src/org/hyperic/sigar/FileInfo.java +++ b/bindings/java/src/org/hyperic/sigar/FileInfo.java @@ -292,74 +292,58 @@ public class FileInfo extends FileAttrs implements java.io.Serializable { } public String diff(FileInfo info) { - ArrayList changes = new ArrayList(); + ArrayList changes = new ArrayList(); - if (this.getMtime() != info.getMtime()) { - changes.add(new Diff("Mtime", - formatDate(info.getMtime()), - formatDate(this.getMtime()))); + if (this.getMtime() != info.getMtime()) { + changes.add(new Diff("Mtime", formatDate(info.getMtime()), + formatDate(this.getMtime()))); + } else if (this.getCtime() != info.getCtime()) { + changes.add(new Diff("Ctime", formatDate(info.getCtime()), + formatDate(this.getCtime()))); + } + + if (this.getPermissions() != info.getPermissions()) { + changes.add(new Diff("Perms", info.getPermissionsString(), this + .getPermissionsString())); + } + + if (this.getType() != info.getType()) { + changes.add(new Diff("Type", info.getTypeString(), this + .getTypeString())); + } + + if (this.getUid() != info.getUid()) { + changes.add(new Diff("Uid", info.getUid(), this.getUid())); + } + + if (this.getGid() != info.getGid()) { + changes.add(new Diff("Gid", info.getGid(), this.getGid())); + } + + if (this.getSize() != info.getSize()) { + changes.add(new Diff("Size", info.getSize(), this.getSize())); + } + + if (!OperatingSystem.IS_WIN32) { + if (this.getInode() != info.getInode()) { + changes.add(new Diff("Inode", info.getInode(), this.getInode())); + } + + if (this.getDevice() != info.getDevice()) { + changes.add(new Diff("Device", info.getDevice(), this + .getDevice())); + } + + if (this.getNlink() != info.getNlink()) { + changes.add(new Diff("Nlink", info.getNlink(), this.getNlink())); + } } - else if (this.getCtime() != info.getCtime()) { - changes.add(new Diff("Ctime", - formatDate(info.getCtime()), - formatDate(this.getCtime()))); - } - else { - //no point in checking the rest if all times are the same. - //or should we include atime in the diff? + + /* if changes were not detected then return empty String */ + if (changes.isEmpty()){ return ""; } - - if (this.getPermissions() != info.getPermissions()) { - changes.add(new Diff("Perms", - info.getPermissionsString(), - this.getPermissionsString())); - } - - if (this.getType() != info.getType()) { - changes.add(new Diff("Type", - info.getTypeString(), - this.getTypeString())); - } - - if (this.getUid() != info.getUid()) { - changes.add(new Diff("Uid", - info.getUid(), - this.getUid())); - } - - if (this.getGid() != info.getGid()) { - changes.add(new Diff("Gid", - info.getGid(), - this.getGid())); - } - - if (this.getSize() != info.getSize()) { - changes.add(new Diff("Size", - info.getSize(), - this.getSize())); - } - - if (!OperatingSystem.IS_WIN32) { - if (this.getInode() != info.getInode()) { - changes.add(new Diff("Inode", - info.getInode(), - this.getInode())); - } - - if (this.getDevice() != info.getDevice()) { - changes.add(new Diff("Device", - info.getDevice(), - this.getDevice())); - } - - if (this.getNlink() != info.getNlink()) { - changes.add(new Diff("Nlink", - info.getNlink(), - this.getNlink())); - } - } - + StringBuffer sb = format(changes); if (this.dirStatEnabled) { sb.append(diff(info.stat)); @@ -389,7 +373,9 @@ public class FileInfo extends FileAttrs implements java.io.Serializable { stat(); - return this.mtime != oldInfo.mtime; + boolean isModified = isModified(this.oldInfo); + + return isModified; } public boolean changed() @@ -455,4 +441,49 @@ public class FileInfo extends FileAttrs implements java.io.Serializable { return fetchInfo(sigar, name, false); } + + private boolean isModified(FileInfo info){ + /* Check modified time */ + if (this.getMtime() != info.getMtime()) { + return true; + } else if (this.getCtime() != info.getCtime()) { + return true; + } + + if (this.getPermissions() != info.getPermissions()) { + return true; + } + + if (this.getType() != info.getType()) { + return true; + } + + if (this.getUid() != info.getUid()) { + return true; + } + + if (this.getGid() != info.getGid()) { + return true; + } + + if (this.getSize() != info.getSize()) { + return true; + } + + if (!OperatingSystem.IS_WIN32) { + if (this.getInode() != info.getInode()) { + return true; + } + + if (this.getDevice() != info.getDevice()) { + return true; + } + + if (this.getNlink() != info.getNlink()) { + return true; + } + } + + return false; + } } diff --git a/bindings/java/src/org/hyperic/sigar/test/TestFileInfo.java b/bindings/java/src/org/hyperic/sigar/test/TestFileInfo.java index 54150f0f..6e123923 100644 --- a/bindings/java/src/org/hyperic/sigar/test/TestFileInfo.java +++ b/bindings/java/src/org/hyperic/sigar/test/TestFileInfo.java @@ -133,11 +133,11 @@ public class TestFileInfo extends SigarTestCase { tmp.deleteOnExit(); traceln("TMP=" + file); - try { + // try { //stat() mtime is in seconds, this happens to quick to detect change. - Thread.sleep(1000 * 1); - } catch (InterruptedException e) { - } + //Thread.sleep(1000 * 1); + // } catch (InterruptedException e) { + // } try { FileInfo info = sigar.getFileInfo(file);