hyperic-sigar 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +339 -0
- data/EXCEPTIONS +104 -0
- data/README +2 -0
- data/Rakefile +87 -0
- data/bindings/SigarWrapper.pm +2934 -0
- data/bindings/ruby/examples/cpu_info.rb +16 -0
- data/bindings/ruby/examples/df.rb +32 -0
- data/bindings/ruby/examples/free.rb +19 -0
- data/bindings/ruby/examples/ifconfig.rb +67 -0
- data/bindings/ruby/examples/netstat.rb +54 -0
- data/bindings/ruby/examples/pargs.rb +18 -0
- data/bindings/ruby/examples/penv.rb +14 -0
- data/bindings/ruby/examples/route.rb +31 -0
- data/bindings/ruby/examples/who.rb +13 -0
- data/bindings/ruby/extconf.rb +110 -0
- data/bindings/ruby/rbsigar.c +628 -0
- data/include/sigar.h +901 -0
- data/include/sigar_fileinfo.h +141 -0
- data/include/sigar_format.h +65 -0
- data/include/sigar_getline.h +18 -0
- data/include/sigar_log.h +82 -0
- data/include/sigar_private.h +365 -0
- data/include/sigar_ptql.h +55 -0
- data/include/sigar_util.h +192 -0
- data/src/os/aix/aix_sigar.c +1927 -0
- data/src/os/aix/sigar_os.h +71 -0
- data/src/os/darwin/darwin_sigar.c +3450 -0
- data/src/os/darwin/sigar_os.h +82 -0
- data/src/os/hpux/dlpi.c +284 -0
- data/src/os/hpux/hpux_sigar.c +1205 -0
- data/src/os/hpux/sigar_os.h +51 -0
- data/src/os/linux/linux_sigar.c +2595 -0
- data/src/os/linux/sigar_os.h +84 -0
- data/src/os/netware/netware_sigar.c +719 -0
- data/src/os/netware/sigar_os.h +26 -0
- data/src/os/osf1/osf1_sigar.c +593 -0
- data/src/os/osf1/sigar_os.h +42 -0
- data/src/os/solaris/get_mib2.c +321 -0
- data/src/os/solaris/get_mib2.h +127 -0
- data/src/os/solaris/hmekstat.h +77 -0
- data/src/os/solaris/kstats.c +182 -0
- data/src/os/solaris/procfs.c +99 -0
- data/src/os/solaris/sigar_os.h +225 -0
- data/src/os/solaris/solaris_sigar.c +2561 -0
- data/src/os/stub/sigar_os.h +8 -0
- data/src/os/stub/stub_sigar.c +303 -0
- data/src/os/win32/peb.c +213 -0
- data/src/os/win32/sigar_os.h +623 -0
- data/src/os/win32/sigar_pdh.h +49 -0
- data/src/os/win32/win32_sigar.c +3718 -0
- data/src/sigar.c +2292 -0
- data/src/sigar_cache.c +181 -0
- data/src/sigar_fileinfo.c +792 -0
- data/src/sigar_format.c +649 -0
- data/src/sigar_getline.c +1849 -0
- data/src/sigar_ptql.c +1966 -0
- data/src/sigar_signal.c +218 -0
- data/src/sigar_util.c +1061 -0
- data/version.properties +11 -0
- metadata +112 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
3
|
+
* This file is part of SIGAR.
|
4
|
+
*
|
5
|
+
* SIGAR is free software; you can redistribute it and/or modify
|
6
|
+
* it under the terms version 2 of the GNU General Public License as
|
7
|
+
* published by the Free Software Foundation. This program is distributed
|
8
|
+
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
9
|
+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
10
|
+
* PARTICULAR PURPOSE. See the GNU General Public License for more
|
11
|
+
* details.
|
12
|
+
*
|
13
|
+
* You should have received a copy of the GNU General Public License
|
14
|
+
* along with this program; if not, write to the Free Software
|
15
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
16
|
+
* USA.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#ifndef SIGAR_PTQL_H
|
20
|
+
#define SIGAR_PTQL_H
|
21
|
+
|
22
|
+
#define SIGAR_PTQL_MALFORMED_QUERY -1
|
23
|
+
|
24
|
+
typedef struct sigar_ptql_query_t sigar_ptql_query_t;
|
25
|
+
|
26
|
+
#define SIGAR_PTQL_ERRMSG_SIZE 1024
|
27
|
+
|
28
|
+
typedef struct {
|
29
|
+
char message[SIGAR_PTQL_ERRMSG_SIZE];
|
30
|
+
} sigar_ptql_error_t;
|
31
|
+
|
32
|
+
typedef int (*sigar_ptql_re_impl_t)(void *, char *, char *);
|
33
|
+
|
34
|
+
SIGAR_DECLARE(void) sigar_ptql_re_impl_set(sigar_t *sigar, void *data,
|
35
|
+
sigar_ptql_re_impl_t impl);
|
36
|
+
|
37
|
+
SIGAR_DECLARE(int) sigar_ptql_query_create(sigar_ptql_query_t **query,
|
38
|
+
char *ptql,
|
39
|
+
sigar_ptql_error_t *error);
|
40
|
+
|
41
|
+
SIGAR_DECLARE(int) sigar_ptql_query_match(sigar_t *sigar,
|
42
|
+
sigar_ptql_query_t *query,
|
43
|
+
sigar_pid_t pid);
|
44
|
+
|
45
|
+
SIGAR_DECLARE(int) sigar_ptql_query_destroy(sigar_ptql_query_t *query);
|
46
|
+
|
47
|
+
SIGAR_DECLARE(int) sigar_ptql_query_find_process(sigar_t *sigar,
|
48
|
+
sigar_ptql_query_t *query,
|
49
|
+
sigar_pid_t *pid);
|
50
|
+
|
51
|
+
SIGAR_DECLARE(int) sigar_ptql_query_find(sigar_t *sigar,
|
52
|
+
sigar_ptql_query_t *query,
|
53
|
+
sigar_proc_list_t *proclist);
|
54
|
+
|
55
|
+
#endif /*SIGAR_PTQL_H*/
|
@@ -0,0 +1,192 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
3
|
+
* This file is part of SIGAR.
|
4
|
+
*
|
5
|
+
* SIGAR is free software; you can redistribute it and/or modify
|
6
|
+
* it under the terms version 2 of the GNU General Public License as
|
7
|
+
* published by the Free Software Foundation. This program is distributed
|
8
|
+
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
9
|
+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
10
|
+
* PARTICULAR PURPOSE. See the GNU General Public License for more
|
11
|
+
* details.
|
12
|
+
*
|
13
|
+
* You should have received a copy of the GNU General Public License
|
14
|
+
* along with this program; if not, write to the Free Software
|
15
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
16
|
+
* USA.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#ifndef SIGAR_UTIL_H
|
20
|
+
#define SIGAR_UTIL_H
|
21
|
+
|
22
|
+
/* most of this is crap for dealing with linux /proc */
|
23
|
+
#define UITOA_BUFFER_SIZE \
|
24
|
+
(sizeof(int) * 3 + 1)
|
25
|
+
|
26
|
+
#define SSTRLEN(s) \
|
27
|
+
(sizeof(s)-1)
|
28
|
+
|
29
|
+
#define sigar_strtoul(ptr) \
|
30
|
+
strtoul(ptr, &ptr, 10)
|
31
|
+
|
32
|
+
#define sigar_strtoull(ptr) \
|
33
|
+
strtoull(ptr, &ptr, 10)
|
34
|
+
|
35
|
+
#define sigar_isspace(c) \
|
36
|
+
(isspace(((unsigned char)(c))))
|
37
|
+
|
38
|
+
#define sigar_isdigit(c) \
|
39
|
+
(isdigit(((unsigned char)(c))))
|
40
|
+
|
41
|
+
#define sigar_isalpha(c) \
|
42
|
+
(isalpha(((unsigned char)(c))))
|
43
|
+
|
44
|
+
#define sigar_isupper(c) \
|
45
|
+
(isupper(((unsigned char)(c))))
|
46
|
+
|
47
|
+
#define sigar_tolower(c) \
|
48
|
+
(tolower(((unsigned char)(c))))
|
49
|
+
|
50
|
+
#ifdef WIN32
|
51
|
+
#define sigar_fileno _fileno
|
52
|
+
#define sigar_isatty _isatty
|
53
|
+
#define sigar_write _write
|
54
|
+
#else
|
55
|
+
#define sigar_fileno fileno
|
56
|
+
#define sigar_isatty isatty
|
57
|
+
#define sigar_write write
|
58
|
+
#endif
|
59
|
+
|
60
|
+
#ifndef PROC_FS_ROOT
|
61
|
+
#define PROC_FS_ROOT "/proc/"
|
62
|
+
#endif
|
63
|
+
|
64
|
+
#ifndef PROCP_FS_ROOT
|
65
|
+
#define PROCP_FS_ROOT "/proc/"
|
66
|
+
#endif
|
67
|
+
|
68
|
+
sigar_int64_t sigar_time_now_millis(void);
|
69
|
+
|
70
|
+
char *sigar_uitoa(char *buf, unsigned int n, int *len);
|
71
|
+
|
72
|
+
int sigar_inet_ntoa(sigar_t *sigar,
|
73
|
+
sigar_uint32_t address,
|
74
|
+
char *addr_str);
|
75
|
+
|
76
|
+
struct hostent *sigar_gethostbyname(const char *name,
|
77
|
+
sigar_hostent_t *data);
|
78
|
+
|
79
|
+
SIGAR_INLINE char *sigar_skip_line(char *buffer, int buflen);
|
80
|
+
|
81
|
+
SIGAR_INLINE char *sigar_skip_token(char *p);
|
82
|
+
|
83
|
+
SIGAR_INLINE char *sigar_skip_multiple_token(char *p, int count);
|
84
|
+
|
85
|
+
char *sigar_getword(char **line, char stop);
|
86
|
+
|
87
|
+
char *sigar_strcasestr(const char *s1, const char *s2);
|
88
|
+
|
89
|
+
int sigar_file2str(const char *fname, char *buffer, int buflen);
|
90
|
+
|
91
|
+
int sigar_proc_file2str(char *buffer, int buflen,
|
92
|
+
sigar_pid_t pid,
|
93
|
+
const char *fname,
|
94
|
+
int fname_len);
|
95
|
+
|
96
|
+
#define SIGAR_PROC_FILE2STR(buffer, pid, fname) \
|
97
|
+
sigar_proc_file2str(buffer, sizeof(buffer), \
|
98
|
+
pid, fname, SSTRLEN(fname))
|
99
|
+
|
100
|
+
#define SIGAR_PROC_FILENAME(buffer, pid, fname) \
|
101
|
+
sigar_proc_filename(buffer, sizeof(buffer), \
|
102
|
+
pid, fname, SSTRLEN(fname))
|
103
|
+
|
104
|
+
#define SIGAR_SKIP_SPACE(ptr) \
|
105
|
+
while (sigar_isspace(*ptr)) ++ptr
|
106
|
+
|
107
|
+
char *sigar_proc_filename(char *buffer, int buflen,
|
108
|
+
sigar_pid_t pid,
|
109
|
+
const char *fname, int fname_len);
|
110
|
+
|
111
|
+
int sigar_proc_list_procfs_get(sigar_t *sigar,
|
112
|
+
sigar_proc_list_t *proclist);
|
113
|
+
|
114
|
+
int sigar_proc_fd_count(sigar_t *sigar, sigar_pid_t pid,
|
115
|
+
sigar_uint64_t *total);
|
116
|
+
|
117
|
+
/* linux + freebsd */
|
118
|
+
int sigar_procfs_args_get(sigar_t *sigar, sigar_pid_t pid,
|
119
|
+
sigar_proc_args_t *procargs);
|
120
|
+
|
121
|
+
int sigar_mem_calc_ram(sigar_t *sigar, sigar_mem_t *mem);
|
122
|
+
|
123
|
+
int sigar_statvfs(sigar_t *sigar,
|
124
|
+
const char *dirname,
|
125
|
+
sigar_file_system_usage_t *fsusage);
|
126
|
+
|
127
|
+
double sigar_file_system_usage_calc_used(sigar_t *sigar,
|
128
|
+
sigar_file_system_usage_t *fs);
|
129
|
+
|
130
|
+
#define SIGAR_DEV_PREFIX "/dev/"
|
131
|
+
|
132
|
+
#define SIGAR_NAME_IS_DEV(dev) \
|
133
|
+
strnEQ(dev, SIGAR_DEV_PREFIX, SSTRLEN(SIGAR_DEV_PREFIX))
|
134
|
+
|
135
|
+
typedef struct {
|
136
|
+
char name[256];
|
137
|
+
int is_partition;
|
138
|
+
sigar_disk_usage_t disk;
|
139
|
+
} sigar_iodev_t;
|
140
|
+
|
141
|
+
sigar_iodev_t *sigar_iodev_get(sigar_t *sigar,
|
142
|
+
const char *dirname);
|
143
|
+
|
144
|
+
int sigar_cpu_core_count(sigar_t *sigar);
|
145
|
+
|
146
|
+
/* e.g. VM guest may have 1 virtual ncpu on multicore hosts */
|
147
|
+
#define sigar_cpu_socket_count(sigar) \
|
148
|
+
(sigar->ncpu < sigar->lcpu) ? sigar->ncpu : \
|
149
|
+
(sigar->ncpu / sigar->lcpu)
|
150
|
+
|
151
|
+
int sigar_cpu_core_rollup(sigar_t *sigar);
|
152
|
+
|
153
|
+
void sigar_cpu_model_adjust(sigar_t *sigar, sigar_cpu_info_t *info);
|
154
|
+
|
155
|
+
int sigar_cpu_mhz_from_model(char *model);
|
156
|
+
|
157
|
+
char *sigar_get_self_path(sigar_t *sigar);
|
158
|
+
|
159
|
+
#if defined(__sun) || defined(__FreeBSD__)
|
160
|
+
|
161
|
+
#define SIGAR_HAS_DLINFO_MODULES
|
162
|
+
#include <dlfcn.h>
|
163
|
+
#include <link.h>
|
164
|
+
|
165
|
+
int sigar_dlinfo_modules(sigar_t *sigar, sigar_proc_modules_t *procmods);
|
166
|
+
#endif
|
167
|
+
|
168
|
+
typedef struct sigar_cache_entry_t sigar_cache_entry_t;
|
169
|
+
|
170
|
+
struct sigar_cache_entry_t {
|
171
|
+
sigar_cache_entry_t *next;
|
172
|
+
sigar_uint64_t id;
|
173
|
+
void *value;
|
174
|
+
};
|
175
|
+
|
176
|
+
typedef struct {
|
177
|
+
sigar_cache_entry_t **entries;
|
178
|
+
unsigned int count, size;
|
179
|
+
void (*free_value)(void *ptr);
|
180
|
+
} sigar_cache_t;
|
181
|
+
|
182
|
+
sigar_cache_t *sigar_cache_new(int size);
|
183
|
+
|
184
|
+
sigar_cache_entry_t *sigar_cache_get(sigar_cache_t *table,
|
185
|
+
sigar_uint64_t key);
|
186
|
+
|
187
|
+
sigar_cache_entry_t *sigar_cache_find(sigar_cache_t *table,
|
188
|
+
sigar_uint64_t key);
|
189
|
+
|
190
|
+
void sigar_cache_destroy(sigar_cache_t *table);
|
191
|
+
|
192
|
+
#endif /* SIGAR_UTIL_H */
|
@@ -0,0 +1,1927 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
3
|
+
* This file is part of SIGAR.
|
4
|
+
*
|
5
|
+
* SIGAR is free software; you can redistribute it and/or modify
|
6
|
+
* it under the terms version 2 of the GNU General Public License as
|
7
|
+
* published by the Free Software Foundation. This program is distributed
|
8
|
+
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
9
|
+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
10
|
+
* PARTICULAR PURPOSE. See the GNU General Public License for more
|
11
|
+
* details.
|
12
|
+
*
|
13
|
+
* You should have received a copy of the GNU General Public License
|
14
|
+
* along with this program; if not, write to the Free Software
|
15
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
16
|
+
* USA.
|
17
|
+
*/
|
18
|
+
|
19
|
+
/* pull in time.h before resource.h does w/ _KERNEL */
|
20
|
+
#include <sys/time.h>
|
21
|
+
#define _KERNEL 1
|
22
|
+
#include <sys/file.h> /* for struct file */
|
23
|
+
#include <sys/resource.h> /* for rlimit32 in 64-bit mode */
|
24
|
+
#undef _KERNEL
|
25
|
+
|
26
|
+
#include "sigar.h"
|
27
|
+
#include "sigar_private.h"
|
28
|
+
#include "sigar_util.h"
|
29
|
+
#include "sigar_os.h"
|
30
|
+
|
31
|
+
#include <dlfcn.h>
|
32
|
+
#include <nlist.h>
|
33
|
+
#include <pthread.h>
|
34
|
+
#include <stdio.h>
|
35
|
+
#include <utmp.h>
|
36
|
+
#include <libperfstat.h>
|
37
|
+
#include <pthread.h>
|
38
|
+
|
39
|
+
#include <sys/statfs.h>
|
40
|
+
#include <sys/systemcfg.h>
|
41
|
+
#include <sys/sysinfo.h>
|
42
|
+
#include <sys/var.h>
|
43
|
+
#include <sys/vminfo.h>
|
44
|
+
#include <sys/mntctl.h>
|
45
|
+
#include <sys/stat.h>
|
46
|
+
#include <sys/user.h>
|
47
|
+
#include <sys/utsname.h>
|
48
|
+
#include <sys/vmount.h>
|
49
|
+
#include <sys/proc.h>
|
50
|
+
|
51
|
+
#include <sys/socket.h>
|
52
|
+
#include <arpa/inet.h>
|
53
|
+
#include <net/if.h>
|
54
|
+
|
55
|
+
/* for proc_port */
|
56
|
+
#include <netinet/in_pcb.h>
|
57
|
+
#include <sys/domain.h>
|
58
|
+
#include <sys/protosw.h>
|
59
|
+
#include <sys/socketvar.h>
|
60
|
+
|
61
|
+
/* for net_connection_list */
|
62
|
+
#include <netinet/ip_var.h>
|
63
|
+
#include <netinet/tcp_timer.h>
|
64
|
+
#include <netinet/tcp_var.h>
|
65
|
+
#include <netinet/tcp_fsm.h>
|
66
|
+
|
67
|
+
/* for odm api */
|
68
|
+
#include <sys/cfgodm.h>
|
69
|
+
#include <sys/cfgdb.h>
|
70
|
+
#include <cf.h>
|
71
|
+
|
72
|
+
#include <sys/ldr.h>
|
73
|
+
|
74
|
+
/* not defined in aix 4.3 */
|
75
|
+
#ifndef SBITS
|
76
|
+
#define SBITS 16
|
77
|
+
#endif
|
78
|
+
|
79
|
+
#ifndef PTHRDSINFO_RUSAGE_START
|
80
|
+
#define PTHRDSINFO_RUSAGE_START 0x00000001
|
81
|
+
#define PTHRDSINFO_RUSAGE_STOP 0x00000002
|
82
|
+
#define PTHRDSINFO_RUSAGE_COLLECT 0x00000004
|
83
|
+
#endif
|
84
|
+
|
85
|
+
/*
|
86
|
+
* from libperfstat.h:
|
87
|
+
* "To calculate the load average, divide the numbers by (1<<SBITS).
|
88
|
+
* SBITS is defined in <sys/proc.h>."
|
89
|
+
*/
|
90
|
+
#define FIXED_TO_DOUBLE(x) (((double)x) / (1<<SBITS))
|
91
|
+
|
92
|
+
/* these offsets wont change so just lookup them up during open */
|
93
|
+
static int get_koffsets(sigar_t *sigar)
|
94
|
+
{
|
95
|
+
int i;
|
96
|
+
/* see man knlist and nlist.h */
|
97
|
+
struct nlist klist[] = {
|
98
|
+
{"avenrun", 0, 0, 0, 0, 0}, /* KOFFSET_LOADAVG */
|
99
|
+
{"v", 0, 0, 0, 0, 0}, /* KOFFSET_VAR */
|
100
|
+
{"sysinfo", 0, 0, 0, 0, 0}, /* KOFFSET_SYSINFO */
|
101
|
+
{"ifnet", 0, 0, 0, 0, 0}, /* KOFFSET_IFNET */
|
102
|
+
{"vmminfo", 0, 0, 0, 0, 0}, /* KOFFSET_VMINFO */
|
103
|
+
{"cpuinfo", 0, 0, 0, 0, 0}, /* KOFFSET_CPUINFO */
|
104
|
+
{"tcb", 0, 0, 0, 0, 0}, /* KOFFSET_TCB */
|
105
|
+
{NULL, 0, 0, 0, 0, 0}
|
106
|
+
};
|
107
|
+
|
108
|
+
if (knlist(klist,
|
109
|
+
sizeof(klist) / sizeof(klist[0]),
|
110
|
+
sizeof(klist[0])) != 0)
|
111
|
+
{
|
112
|
+
return errno;
|
113
|
+
}
|
114
|
+
|
115
|
+
for (i=0; i<KOFFSET_MAX; i++) {
|
116
|
+
sigar->koffsets[i] = klist[i].n_value;
|
117
|
+
}
|
118
|
+
|
119
|
+
return SIGAR_OK;
|
120
|
+
}
|
121
|
+
|
122
|
+
static int kread(sigar_t *sigar, void *data, int size, long offset)
|
123
|
+
{
|
124
|
+
if (sigar->kmem < 0) {
|
125
|
+
return SIGAR_EPERM_KMEM;
|
126
|
+
}
|
127
|
+
|
128
|
+
if (lseek(sigar->kmem, offset, SEEK_SET) != offset) {
|
129
|
+
return errno;
|
130
|
+
}
|
131
|
+
|
132
|
+
if (read(sigar->kmem, data, size) != size) {
|
133
|
+
return errno;
|
134
|
+
}
|
135
|
+
|
136
|
+
return SIGAR_OK;
|
137
|
+
}
|
138
|
+
|
139
|
+
static int sigar_thread_rusage(struct rusage *usage, int mode)
|
140
|
+
{
|
141
|
+
return pthread_getrusage_np(pthread_self(), usage, mode);
|
142
|
+
}
|
143
|
+
|
144
|
+
static int sigar_perfstat_memory(perfstat_memory_total_t *memory)
|
145
|
+
{
|
146
|
+
return perfstat_memory_total(NULL, memory, sizeof(*memory), 1);
|
147
|
+
}
|
148
|
+
|
149
|
+
static int sigar_perfstat_cpu(perfstat_cpu_total_t *cpu_total)
|
150
|
+
{
|
151
|
+
return perfstat_cpu_total(NULL, cpu_total, sizeof(*cpu_total), 1);
|
152
|
+
}
|
153
|
+
|
154
|
+
int sigar_os_open(sigar_t **sigar)
|
155
|
+
{
|
156
|
+
int status, i;
|
157
|
+
int kmem = -1;
|
158
|
+
struct utsname name;
|
159
|
+
|
160
|
+
kmem = open("/dev/kmem", O_RDONLY);
|
161
|
+
|
162
|
+
*sigar = malloc(sizeof(**sigar));
|
163
|
+
|
164
|
+
(*sigar)->getprocfd = NULL; /*XXX*/
|
165
|
+
(*sigar)->kmem = kmem;
|
166
|
+
(*sigar)->pagesize = 0;
|
167
|
+
(*sigar)->ticks = sysconf(_SC_CLK_TCK);
|
168
|
+
(*sigar)->boot_time = 0;
|
169
|
+
(*sigar)->last_pid = -1;
|
170
|
+
(*sigar)->pinfo = NULL;
|
171
|
+
(*sigar)->cpuinfo = NULL;
|
172
|
+
(*sigar)->cpuinfo_size = 0;
|
173
|
+
SIGAR_ZERO(&(*sigar)->swaps);
|
174
|
+
|
175
|
+
i = getpagesize();
|
176
|
+
while ((i >>= 1) > 0) {
|
177
|
+
(*sigar)->pagesize++;
|
178
|
+
}
|
179
|
+
|
180
|
+
if (kmem > 0) {
|
181
|
+
if ((status = get_koffsets(*sigar)) != SIGAR_OK) {
|
182
|
+
/* libperfstat only mode (aix 6) */
|
183
|
+
close((*sigar)->kmem);
|
184
|
+
(*sigar)->kmem = -1;
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
(*sigar)->cpu_mhz = -1;
|
189
|
+
|
190
|
+
(*sigar)->model[0] = '\0';
|
191
|
+
|
192
|
+
uname(&name);
|
193
|
+
|
194
|
+
(*sigar)->aix_version = atoi(name.version);
|
195
|
+
|
196
|
+
(*sigar)->thrusage = PTHRDSINFO_RUSAGE_STOP;
|
197
|
+
|
198
|
+
(*sigar)->diskmap = NULL;
|
199
|
+
|
200
|
+
return SIGAR_OK;
|
201
|
+
}
|
202
|
+
|
203
|
+
static void swaps_free(swaps_t *swaps);
|
204
|
+
|
205
|
+
int sigar_os_close(sigar_t *sigar)
|
206
|
+
{
|
207
|
+
swaps_free(&sigar->swaps);
|
208
|
+
if (sigar->kmem > 0) {
|
209
|
+
close(sigar->kmem);
|
210
|
+
}
|
211
|
+
if (sigar->pinfo) {
|
212
|
+
free(sigar->pinfo);
|
213
|
+
}
|
214
|
+
if (sigar->cpuinfo) {
|
215
|
+
free(sigar->cpuinfo);
|
216
|
+
}
|
217
|
+
if (sigar->diskmap) {
|
218
|
+
sigar_cache_destroy(sigar->diskmap);
|
219
|
+
}
|
220
|
+
if (sigar->thrusage == PTHRDSINFO_RUSAGE_START) {
|
221
|
+
struct rusage usage;
|
222
|
+
sigar_thread_rusage(&usage,
|
223
|
+
PTHRDSINFO_RUSAGE_STOP);
|
224
|
+
}
|
225
|
+
free(sigar);
|
226
|
+
return SIGAR_OK;
|
227
|
+
}
|
228
|
+
|
229
|
+
char *sigar_os_error_string(sigar_t *sigar, int err)
|
230
|
+
{
|
231
|
+
switch (err) {
|
232
|
+
case SIGAR_EPERM_KMEM:
|
233
|
+
return "Failed to open /dev/kmem for reading";
|
234
|
+
default:
|
235
|
+
return NULL;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
#define PAGESHIFT(v) \
|
240
|
+
((v) << sigar->pagesize)
|
241
|
+
|
242
|
+
int sigar_mem_get(sigar_t *sigar, sigar_mem_t *mem)
|
243
|
+
{
|
244
|
+
int status;
|
245
|
+
perfstat_memory_total_t minfo;
|
246
|
+
|
247
|
+
if (sigar_perfstat_memory(&minfo) == 1) {
|
248
|
+
mem->total = PAGESHIFT(minfo.real_total);
|
249
|
+
mem->free = PAGESHIFT(minfo.real_free);
|
250
|
+
}
|
251
|
+
else {
|
252
|
+
return errno;
|
253
|
+
}
|
254
|
+
|
255
|
+
mem->used = mem->total - mem->free;
|
256
|
+
mem->actual_used = mem->used;
|
257
|
+
mem->actual_free = mem->free;
|
258
|
+
|
259
|
+
sigar_mem_calc_ram(sigar, mem);
|
260
|
+
|
261
|
+
return SIGAR_OK;
|
262
|
+
}
|
263
|
+
|
264
|
+
static void swaps_free(swaps_t *swaps)
|
265
|
+
{
|
266
|
+
if (swaps->num) {
|
267
|
+
int i;
|
268
|
+
|
269
|
+
for (i=0; i<swaps->num; i++) {
|
270
|
+
free(swaps->devs[i]);
|
271
|
+
}
|
272
|
+
|
273
|
+
free(swaps->devs);
|
274
|
+
|
275
|
+
swaps->num = 0;
|
276
|
+
}
|
277
|
+
}
|
278
|
+
|
279
|
+
/*
|
280
|
+
* there is no public api for parsing this file.
|
281
|
+
* well, there is something, but its super ugly and requires
|
282
|
+
* linking 2 static libraries (libodm and something else)
|
283
|
+
* maybe will switch to that if it can add value elsewhere too.
|
284
|
+
*/
|
285
|
+
#define SWAPSPACES "/etc/swapspaces"
|
286
|
+
|
287
|
+
static int swaps_get(swaps_t *swaps)
|
288
|
+
{
|
289
|
+
FILE *fp;
|
290
|
+
char buf[512];
|
291
|
+
char *ptr;
|
292
|
+
struct stat statbuf;
|
293
|
+
|
294
|
+
if (stat(SWAPSPACES, &statbuf) < 0) {
|
295
|
+
return errno;
|
296
|
+
}
|
297
|
+
|
298
|
+
/* only re-parse if file has changed */
|
299
|
+
if (swaps->mtime == statbuf.st_mtime) {
|
300
|
+
return 0;
|
301
|
+
}
|
302
|
+
|
303
|
+
swaps->mtime = statbuf.st_mtime;
|
304
|
+
|
305
|
+
/* easier to just start from scratch */
|
306
|
+
swaps_free(swaps);
|
307
|
+
|
308
|
+
if (!(fp = fopen(SWAPSPACES, "r"))) {
|
309
|
+
return errno;
|
310
|
+
}
|
311
|
+
|
312
|
+
while ((ptr = fgets(buf, sizeof(buf), fp))) {
|
313
|
+
if (!isalpha(*ptr)) {
|
314
|
+
continue;
|
315
|
+
}
|
316
|
+
|
317
|
+
if (strchr(ptr, ':')) {
|
318
|
+
int len;
|
319
|
+
|
320
|
+
ptr = fgets(buf, sizeof(buf), fp);
|
321
|
+
|
322
|
+
while (isspace(*ptr)) {
|
323
|
+
++ptr;
|
324
|
+
}
|
325
|
+
|
326
|
+
if (strncmp(ptr, "dev", 3)) {
|
327
|
+
continue;
|
328
|
+
}
|
329
|
+
ptr += 3;
|
330
|
+
while (isspace(*ptr) || (*ptr == '=')) {
|
331
|
+
++ptr;
|
332
|
+
}
|
333
|
+
|
334
|
+
len = strlen(ptr);
|
335
|
+
ptr[len-1] = '\0'; /* -1 == chomp \n */
|
336
|
+
|
337
|
+
swaps->devs = realloc(swaps->devs, swaps->num+1 * sizeof(char *));
|
338
|
+
swaps->devs[swaps->num] = malloc(len);
|
339
|
+
memcpy(swaps->devs[swaps->num], ptr, len);
|
340
|
+
|
341
|
+
swaps->num++;
|
342
|
+
}
|
343
|
+
}
|
344
|
+
|
345
|
+
fclose(fp);
|
346
|
+
|
347
|
+
return 0;
|
348
|
+
}
|
349
|
+
|
350
|
+
/*
|
351
|
+
* documented in aix tech ref,
|
352
|
+
* but this prototype is not in any friggin header file.
|
353
|
+
* struct pginfo is in sys/vminfo.h
|
354
|
+
*/
|
355
|
+
|
356
|
+
int swapqry(char *path, struct pginfo *info);
|
357
|
+
|
358
|
+
static int sigar_swap_get_swapqry(sigar_t *sigar, sigar_swap_t *swap)
|
359
|
+
{
|
360
|
+
int status, i;
|
361
|
+
|
362
|
+
if ((status = swaps_get(&sigar->swaps)) != SIGAR_OK) {
|
363
|
+
return status;
|
364
|
+
}
|
365
|
+
|
366
|
+
if (SIGAR_LOG_IS_DEBUG(sigar)) {
|
367
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
368
|
+
"[swap] pagesize=%d, shift=%d",
|
369
|
+
getpagesize(), sigar->pagesize);
|
370
|
+
}
|
371
|
+
|
372
|
+
swap->total = swap->free = 0;
|
373
|
+
|
374
|
+
for (i=0; i<sigar->swaps.num; i++) {
|
375
|
+
struct pginfo info;
|
376
|
+
|
377
|
+
status = swapqry(sigar->swaps.devs[i], &info);
|
378
|
+
|
379
|
+
if (status != 0) {
|
380
|
+
if (SIGAR_LOG_IS_DEBUG(sigar)) {
|
381
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
382
|
+
"[swap] swapqry(%s) failed: %s",
|
383
|
+
sigar->swaps.devs[i],
|
384
|
+
sigar_strerror(sigar, errno));
|
385
|
+
}
|
386
|
+
continue;
|
387
|
+
}
|
388
|
+
|
389
|
+
if (SIGAR_LOG_IS_DEBUG(sigar)) {
|
390
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
391
|
+
"[swap] %s total=%d/%d, free=%d/%d",
|
392
|
+
sigar->swaps.devs[i],
|
393
|
+
info.size, PAGESHIFT(info.size),
|
394
|
+
info.free, PAGESHIFT(info.free));
|
395
|
+
}
|
396
|
+
|
397
|
+
swap->total += PAGESHIFT(info.size); /* lsps -a */
|
398
|
+
swap->free += PAGESHIFT(info.free);
|
399
|
+
}
|
400
|
+
|
401
|
+
swap->used = swap->total - swap->free;
|
402
|
+
|
403
|
+
return SIGAR_OK;
|
404
|
+
}
|
405
|
+
|
406
|
+
#define SWAP_DEV(ps) \
|
407
|
+
((ps.type == LV_PAGING) ? \
|
408
|
+
ps.u.lv_paging.vgname : \
|
409
|
+
ps.u.nfs_paging.filename)
|
410
|
+
|
411
|
+
#define SWAP_MB_TO_BYTES(v) ((v) * (1024 * 1024))
|
412
|
+
|
413
|
+
int sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap)
|
414
|
+
{
|
415
|
+
perfstat_memory_total_t minfo;
|
416
|
+
perfstat_pagingspace_t ps;
|
417
|
+
perfstat_id_t id;
|
418
|
+
|
419
|
+
id.name[0] = '\0';
|
420
|
+
|
421
|
+
SIGAR_ZERO(swap);
|
422
|
+
|
423
|
+
do {
|
424
|
+
if (perfstat_pagingspace(&id, &ps, sizeof(ps), 1) != 1) {
|
425
|
+
if (SIGAR_LOG_IS_DEBUG(sigar)) {
|
426
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
427
|
+
"[swap] dev=%s query failed: %s",
|
428
|
+
SWAP_DEV(ps),
|
429
|
+
sigar_strerror(sigar, errno));
|
430
|
+
}
|
431
|
+
continue;
|
432
|
+
}
|
433
|
+
if (SIGAR_LOG_IS_DEBUG(sigar)) {
|
434
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
435
|
+
"[swap] dev=%s: active=%s, "
|
436
|
+
"total=%lluMb, used=%lluMb",
|
437
|
+
SWAP_DEV(ps),
|
438
|
+
((ps.active == 1) ? "yes" : "no"),
|
439
|
+
ps.mb_size, ps.mb_used);
|
440
|
+
}
|
441
|
+
if (ps.active != 1) {
|
442
|
+
continue;
|
443
|
+
}
|
444
|
+
/* convert MB sizes to bytes */
|
445
|
+
swap->total += SWAP_MB_TO_BYTES(ps.mb_size);
|
446
|
+
swap->used += SWAP_MB_TO_BYTES(ps.mb_used);
|
447
|
+
} while (id.name[0] != '\0');
|
448
|
+
|
449
|
+
swap->free = swap->total - swap->used;
|
450
|
+
|
451
|
+
if (sigar_perfstat_memory(&minfo) == 1) {
|
452
|
+
swap->page_in = minfo.pgins;
|
453
|
+
swap->page_out = minfo.pgouts;
|
454
|
+
}
|
455
|
+
else {
|
456
|
+
swap->page_in = swap->page_out = -1;
|
457
|
+
}
|
458
|
+
return SIGAR_OK;
|
459
|
+
}
|
460
|
+
|
461
|
+
int sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu)
|
462
|
+
{
|
463
|
+
int i, status;
|
464
|
+
struct sysinfo data;
|
465
|
+
perfstat_cpu_total_t cpu_data;
|
466
|
+
|
467
|
+
if (sigar_perfstat_cpu(&cpu_data) == 1) {
|
468
|
+
cpu->user = SIGAR_TICK2MSEC(cpu_data.user);
|
469
|
+
cpu->nice = SIGAR_FIELD_NOTIMPL; /* N/A */
|
470
|
+
cpu->sys = SIGAR_TICK2MSEC(cpu_data.sys);
|
471
|
+
cpu->idle = SIGAR_TICK2MSEC(cpu_data.idle);
|
472
|
+
cpu->wait = SIGAR_TICK2MSEC(cpu_data.wait);
|
473
|
+
cpu->irq = 0; /*N/A*/
|
474
|
+
cpu->soft_irq = 0; /*N/A*/
|
475
|
+
cpu->stolen = 0; /*N/A*/
|
476
|
+
cpu->total = cpu->user + cpu->sys + cpu->idle + cpu->wait;
|
477
|
+
return SIGAR_OK;
|
478
|
+
}
|
479
|
+
else {
|
480
|
+
return errno;
|
481
|
+
}
|
482
|
+
}
|
483
|
+
|
484
|
+
/*
|
485
|
+
* other possible metrics we could add:
|
486
|
+
* struct cpuinfo {
|
487
|
+
* long cpu[CPU_NTIMES];
|
488
|
+
* long pswitch;
|
489
|
+
* long syscall;
|
490
|
+
* long sysread;
|
491
|
+
* long syswrite;
|
492
|
+
* long sysfork;
|
493
|
+
* long sysexec;
|
494
|
+
* long readch;
|
495
|
+
* long writech;
|
496
|
+
* long iget;
|
497
|
+
* long namei;
|
498
|
+
* long dirblk;
|
499
|
+
* long msg;
|
500
|
+
* long sema;
|
501
|
+
* long bread;
|
502
|
+
* long bwrite;
|
503
|
+
* long lread;
|
504
|
+
* long lwrite;
|
505
|
+
* long phread;
|
506
|
+
* long phwrite;
|
507
|
+
* };
|
508
|
+
*/
|
509
|
+
|
510
|
+
int sigar_cpu_list_get(sigar_t *sigar, sigar_cpu_list_t *cpulist)
|
511
|
+
{
|
512
|
+
perfstat_cpu_t data;
|
513
|
+
int i, ncpu = _system_configuration.ncpus; /* this can change */
|
514
|
+
perfstat_id_t id;
|
515
|
+
|
516
|
+
id.name[0] = '\0';
|
517
|
+
|
518
|
+
sigar_cpu_list_create(cpulist);
|
519
|
+
|
520
|
+
for (i=0; i<ncpu; i++) {
|
521
|
+
sigar_cpu_t *cpu;
|
522
|
+
|
523
|
+
SIGAR_CPU_LIST_GROW(cpulist);
|
524
|
+
|
525
|
+
cpu = &cpulist->data[cpulist->number++];
|
526
|
+
|
527
|
+
if (SIGAR_LOG_IS_DEBUG(sigar)) {
|
528
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
529
|
+
"cpu%d perfstat_id='%s'",
|
530
|
+
i, id.name);
|
531
|
+
}
|
532
|
+
|
533
|
+
if (perfstat_cpu(&id, &data, sizeof(data), 1) == 1) {
|
534
|
+
cpu->user = SIGAR_TICK2MSEC(data.user);
|
535
|
+
cpu->nice = SIGAR_FIELD_NOTIMPL; /* N/A */
|
536
|
+
cpu->sys = SIGAR_TICK2MSEC(data.sys);
|
537
|
+
cpu->idle = SIGAR_TICK2MSEC(data.idle);
|
538
|
+
cpu->wait = SIGAR_TICK2MSEC(data.wait);
|
539
|
+
cpu->irq = 0; /*N/A*/
|
540
|
+
cpu->soft_irq = 0; /*N/A*/
|
541
|
+
cpu->stolen = 0; /*N/A*/
|
542
|
+
cpu->total = cpu->user + cpu->sys + cpu->idle + cpu->wait;
|
543
|
+
}
|
544
|
+
else {
|
545
|
+
sigar_log_printf(sigar, SIGAR_LOG_ERROR,
|
546
|
+
"cpu%d perfstat_cpu(%s) failed: %s",
|
547
|
+
i, id.name, sigar_strerror(sigar, errno));
|
548
|
+
SIGAR_ZERO(cpu);
|
549
|
+
}
|
550
|
+
}
|
551
|
+
|
552
|
+
return SIGAR_OK;
|
553
|
+
}
|
554
|
+
|
555
|
+
static int boot_time(sigar_t *sigar, time_t *time)
|
556
|
+
{
|
557
|
+
int fd;
|
558
|
+
struct utmp data;
|
559
|
+
|
560
|
+
if ((fd = open(UTMP_FILE, O_RDONLY)) < 0) {
|
561
|
+
return errno;
|
562
|
+
}
|
563
|
+
|
564
|
+
do {
|
565
|
+
if (read(fd, &data, sizeof(data)) != sizeof(data)) {
|
566
|
+
int status = errno;
|
567
|
+
close(fd);
|
568
|
+
return status;
|
569
|
+
}
|
570
|
+
} while (data.ut_type != BOOT_TIME);
|
571
|
+
|
572
|
+
*time = data.ut_time;
|
573
|
+
|
574
|
+
close(fd);
|
575
|
+
|
576
|
+
return SIGAR_OK;
|
577
|
+
}
|
578
|
+
|
579
|
+
int sigar_uptime_get(sigar_t *sigar,
|
580
|
+
sigar_uptime_t *uptime)
|
581
|
+
{
|
582
|
+
if (sigar->boot_time == 0) {
|
583
|
+
int status;
|
584
|
+
time_t time;
|
585
|
+
|
586
|
+
if ((status = boot_time(sigar, &time)) != SIGAR_OK) {
|
587
|
+
return status;
|
588
|
+
}
|
589
|
+
|
590
|
+
sigar->boot_time = time;
|
591
|
+
}
|
592
|
+
|
593
|
+
uptime->uptime = time(NULL) - sigar->boot_time;
|
594
|
+
|
595
|
+
return SIGAR_OK;
|
596
|
+
}
|
597
|
+
|
598
|
+
#define WHOCPY(dest, src) \
|
599
|
+
SIGAR_SSTRCPY(dest, src); \
|
600
|
+
if (sizeof(src) < sizeof(dest)) \
|
601
|
+
dest[sizeof(dest)-1] = '\0'
|
602
|
+
|
603
|
+
static int sigar_who_utmp(sigar_t *sigar,
|
604
|
+
sigar_who_list_t *wholist)
|
605
|
+
{
|
606
|
+
struct utmp ut;
|
607
|
+
FILE *fp;
|
608
|
+
|
609
|
+
if (!(fp = fopen(UTMP_FILE, "r"))) {
|
610
|
+
return errno;
|
611
|
+
}
|
612
|
+
|
613
|
+
while (fread(&ut, sizeof(ut), 1, fp) == 1) {
|
614
|
+
sigar_who_t *who;
|
615
|
+
|
616
|
+
if (*ut.ut_name == '\0') {
|
617
|
+
continue;
|
618
|
+
}
|
619
|
+
|
620
|
+
if (ut.ut_type != USER_PROCESS) {
|
621
|
+
continue;
|
622
|
+
}
|
623
|
+
|
624
|
+
SIGAR_WHO_LIST_GROW(wholist);
|
625
|
+
who = &wholist->data[wholist->number++];
|
626
|
+
|
627
|
+
WHOCPY(who->user, ut.ut_user);
|
628
|
+
WHOCPY(who->device, ut.ut_line);
|
629
|
+
WHOCPY(who->host, ut.ut_host);
|
630
|
+
|
631
|
+
who->time = ut.ut_time;
|
632
|
+
}
|
633
|
+
|
634
|
+
fclose(fp);
|
635
|
+
|
636
|
+
return SIGAR_OK;
|
637
|
+
}
|
638
|
+
|
639
|
+
int sigar_who_list_get(sigar_t *sigar,
|
640
|
+
sigar_who_list_t *wholist)
|
641
|
+
{
|
642
|
+
int status;
|
643
|
+
|
644
|
+
sigar_who_list_create(wholist);
|
645
|
+
|
646
|
+
status = sigar_who_utmp(sigar, wholist);
|
647
|
+
if (status != SIGAR_OK) {
|
648
|
+
sigar_who_list_destroy(sigar, wholist);
|
649
|
+
return status;
|
650
|
+
}
|
651
|
+
|
652
|
+
return SIGAR_OK;
|
653
|
+
}
|
654
|
+
|
655
|
+
int sigar_loadavg_get(sigar_t *sigar,
|
656
|
+
sigar_loadavg_t *loadavg)
|
657
|
+
{
|
658
|
+
int status, i;
|
659
|
+
int data[3];
|
660
|
+
perfstat_cpu_total_t cpu_data;
|
661
|
+
|
662
|
+
if (sigar_perfstat_cpu(&cpu_data) == 1) {
|
663
|
+
for (i=0; i<3; i++) {
|
664
|
+
loadavg->loadavg[i] = FIXED_TO_DOUBLE(cpu_data.loadavg[i]);
|
665
|
+
}
|
666
|
+
return SIGAR_OK;
|
667
|
+
}
|
668
|
+
else {
|
669
|
+
return errno;
|
670
|
+
}
|
671
|
+
}
|
672
|
+
|
673
|
+
int sigar_os_proc_list_get(sigar_t *sigar,
|
674
|
+
sigar_proc_list_t *proclist)
|
675
|
+
{
|
676
|
+
pid_t pid = 0;
|
677
|
+
struct procsinfo info;
|
678
|
+
|
679
|
+
for (;;) {
|
680
|
+
int num = getprocs(&info, sizeof(info),
|
681
|
+
NULL, 0, &pid, 1);
|
682
|
+
|
683
|
+
if (num == 0) {
|
684
|
+
break;
|
685
|
+
}
|
686
|
+
|
687
|
+
SIGAR_PROC_LIST_GROW(proclist);
|
688
|
+
|
689
|
+
proclist->data[proclist->number++] = info.pi_pid;
|
690
|
+
}
|
691
|
+
|
692
|
+
return SIGAR_OK;
|
693
|
+
}
|
694
|
+
|
695
|
+
static int sigar_getprocs(sigar_t *sigar, sigar_pid_t pid)
|
696
|
+
{
|
697
|
+
int status, num;
|
698
|
+
time_t timenow = time(NULL);
|
699
|
+
|
700
|
+
if (sigar->pinfo == NULL) {
|
701
|
+
sigar->pinfo = malloc(sizeof(*sigar->pinfo));
|
702
|
+
}
|
703
|
+
|
704
|
+
if (sigar->last_pid == pid) {
|
705
|
+
if ((timenow - sigar->last_getprocs) < SIGAR_LAST_PROC_EXPIRE) {
|
706
|
+
return SIGAR_OK;
|
707
|
+
}
|
708
|
+
}
|
709
|
+
|
710
|
+
sigar->last_pid = pid;
|
711
|
+
sigar->last_getprocs = timenow;
|
712
|
+
|
713
|
+
num = getprocs(sigar->pinfo, sizeof(*sigar->pinfo),
|
714
|
+
NULL, 0, &pid, 1);
|
715
|
+
|
716
|
+
if (num != 1) {
|
717
|
+
return ESRCH;
|
718
|
+
}
|
719
|
+
|
720
|
+
return SIGAR_OK;
|
721
|
+
}
|
722
|
+
|
723
|
+
int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid,
|
724
|
+
sigar_proc_mem_t *procmem)
|
725
|
+
{
|
726
|
+
int status = sigar_getprocs(sigar, pid);
|
727
|
+
struct procsinfo64 *pinfo = sigar->pinfo;
|
728
|
+
|
729
|
+
if (status != SIGAR_OK) {
|
730
|
+
return status;
|
731
|
+
}
|
732
|
+
|
733
|
+
procmem->size = PAGESHIFT(pinfo->pi_size); /* XXX fold in pi_dvm ? */
|
734
|
+
procmem->share = PAGESHIFT(pinfo->pi_sdsize);
|
735
|
+
procmem->resident = PAGESHIFT(pinfo->pi_drss + pinfo->pi_trss);
|
736
|
+
|
737
|
+
procmem->minor_faults = pinfo->pi_minflt;
|
738
|
+
procmem->major_faults = pinfo->pi_majflt;
|
739
|
+
procmem->page_faults =
|
740
|
+
procmem->minor_faults +
|
741
|
+
procmem->major_faults;
|
742
|
+
|
743
|
+
return SIGAR_OK;
|
744
|
+
}
|
745
|
+
|
746
|
+
int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid,
|
747
|
+
sigar_proc_cred_t *proccred)
|
748
|
+
{
|
749
|
+
int status = sigar_getprocs(sigar, pid);
|
750
|
+
struct procsinfo64 *pinfo = sigar->pinfo;
|
751
|
+
|
752
|
+
if (status != SIGAR_OK) {
|
753
|
+
return status;
|
754
|
+
}
|
755
|
+
|
756
|
+
proccred->uid = pinfo->pi_cred.cr_ruid;
|
757
|
+
proccred->euid = pinfo->pi_cred.cr_uid;
|
758
|
+
if (proccred->uid == -1) {
|
759
|
+
/*
|
760
|
+
* aix 5.2 has a process named 'jfsz'
|
761
|
+
* where uid is '-1', getpwuid returns EPERM
|
762
|
+
*/
|
763
|
+
proccred->uid = proccred->euid = 0;
|
764
|
+
}
|
765
|
+
proccred->gid = pinfo->pi_cred.cr_rgid;
|
766
|
+
proccred->egid = pinfo->pi_cred.cr_gid;
|
767
|
+
|
768
|
+
return SIGAR_OK;
|
769
|
+
}
|
770
|
+
|
771
|
+
int sigar_proc_time_get(sigar_t *sigar, sigar_pid_t pid,
|
772
|
+
sigar_proc_time_t *proctime)
|
773
|
+
{
|
774
|
+
int status = sigar_getprocs(sigar, pid);
|
775
|
+
struct procsinfo64 *pinfo = sigar->pinfo;
|
776
|
+
|
777
|
+
if (status != SIGAR_OK) {
|
778
|
+
return status;
|
779
|
+
}
|
780
|
+
|
781
|
+
proctime->start_time = pinfo->pi_start;
|
782
|
+
proctime->start_time *= SIGAR_MSEC; /* convert to ms */
|
783
|
+
proctime->user = pinfo->pi_utime * SIGAR_MSEC;
|
784
|
+
proctime->sys = pinfo->pi_stime * SIGAR_MSEC;
|
785
|
+
proctime->total = proctime->user + proctime->sys;
|
786
|
+
|
787
|
+
return SIGAR_OK;
|
788
|
+
}
|
789
|
+
|
790
|
+
int sigar_proc_state_get(sigar_t *sigar, sigar_pid_t pid,
|
791
|
+
sigar_proc_state_t *procstate)
|
792
|
+
{
|
793
|
+
int status = sigar_getprocs(sigar, pid);
|
794
|
+
struct procsinfo64 *pinfo = sigar->pinfo;
|
795
|
+
tid_t tid = 0;
|
796
|
+
struct thrdsinfo64 thrinfo;
|
797
|
+
|
798
|
+
if (status != SIGAR_OK) {
|
799
|
+
return status;
|
800
|
+
}
|
801
|
+
|
802
|
+
if (getthrds(pid, &thrinfo, sizeof(thrinfo), &tid, 1) == 1) {
|
803
|
+
procstate->processor = thrinfo.ti_affinity;
|
804
|
+
}
|
805
|
+
else {
|
806
|
+
procstate->processor = SIGAR_FIELD_NOTIMPL;
|
807
|
+
}
|
808
|
+
|
809
|
+
SIGAR_SSTRCPY(procstate->name, pinfo->pi_comm);
|
810
|
+
procstate->ppid = pinfo->pi_ppid;
|
811
|
+
procstate->nice = pinfo->pi_nice;
|
812
|
+
procstate->tty = pinfo->pi_ttyd;
|
813
|
+
procstate->priority = pinfo->pi_pri;
|
814
|
+
procstate->threads = pinfo->pi_thcount;
|
815
|
+
|
816
|
+
switch (pinfo->pi_state) {
|
817
|
+
case SACTIVE:
|
818
|
+
procstate->state = 'R';
|
819
|
+
break;
|
820
|
+
case SIDL:
|
821
|
+
procstate->state = 'D';
|
822
|
+
break;
|
823
|
+
case SSTOP:
|
824
|
+
procstate->state = 'S';
|
825
|
+
break;
|
826
|
+
case SZOMB:
|
827
|
+
procstate->state = 'Z';
|
828
|
+
break;
|
829
|
+
case SSWAP:
|
830
|
+
procstate->state = 'S';
|
831
|
+
break;
|
832
|
+
}
|
833
|
+
|
834
|
+
return SIGAR_OK;
|
835
|
+
}
|
836
|
+
|
837
|
+
int sigar_os_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
|
838
|
+
sigar_proc_args_t *procargs)
|
839
|
+
{
|
840
|
+
/* XXX if buffer is not large enough args are truncated */
|
841
|
+
char buffer[8192], *ptr;
|
842
|
+
struct procsinfo pinfo;
|
843
|
+
|
844
|
+
pinfo.pi_pid = pid;
|
845
|
+
|
846
|
+
if (getargs(&pinfo, sizeof(pinfo),
|
847
|
+
buffer, sizeof(buffer)) != 0)
|
848
|
+
{
|
849
|
+
return errno;
|
850
|
+
}
|
851
|
+
|
852
|
+
ptr = buffer;
|
853
|
+
|
854
|
+
while (*ptr) {
|
855
|
+
int alen = strlen(ptr)+1;
|
856
|
+
char *arg = malloc(alen);
|
857
|
+
|
858
|
+
SIGAR_PROC_ARGS_GROW(procargs);
|
859
|
+
memcpy(arg, ptr, alen);
|
860
|
+
|
861
|
+
procargs->data[procargs->number++] = arg;
|
862
|
+
|
863
|
+
ptr += alen;
|
864
|
+
}
|
865
|
+
|
866
|
+
return SIGAR_OK;
|
867
|
+
}
|
868
|
+
|
869
|
+
int sigar_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
870
|
+
sigar_proc_env_t *procenv)
|
871
|
+
{
|
872
|
+
/* XXX if buffer is not large enough args are truncated */
|
873
|
+
char buffer[8192], *ptr;
|
874
|
+
struct procsinfo pinfo;
|
875
|
+
|
876
|
+
pinfo.pi_pid = pid;
|
877
|
+
|
878
|
+
if (getevars(&pinfo, sizeof(pinfo),
|
879
|
+
buffer, sizeof(buffer)) != 0)
|
880
|
+
{
|
881
|
+
return errno;
|
882
|
+
}
|
883
|
+
|
884
|
+
ptr = buffer;
|
885
|
+
|
886
|
+
while (*ptr) {
|
887
|
+
char *val = strchr(ptr, '=');
|
888
|
+
int klen, vlen, status;
|
889
|
+
char key[128]; /* XXX is there a max key size? */
|
890
|
+
|
891
|
+
if (val == NULL) {
|
892
|
+
/* not key=val format */
|
893
|
+
procenv->env_getter(procenv->data, ptr, strlen(ptr), NULL, 0);
|
894
|
+
break;
|
895
|
+
}
|
896
|
+
|
897
|
+
klen = val - ptr;
|
898
|
+
SIGAR_SSTRCPY(key, ptr);
|
899
|
+
key[klen] = '\0';
|
900
|
+
++val;
|
901
|
+
|
902
|
+
vlen = strlen(val);
|
903
|
+
status = procenv->env_getter(procenv->data,
|
904
|
+
key, klen, val, vlen);
|
905
|
+
|
906
|
+
if (status != SIGAR_OK) {
|
907
|
+
/* not an error; just stop iterating */
|
908
|
+
break;
|
909
|
+
}
|
910
|
+
|
911
|
+
ptr += (klen + 1 + vlen + 1);
|
912
|
+
}
|
913
|
+
|
914
|
+
return SIGAR_OK;
|
915
|
+
}
|
916
|
+
|
917
|
+
int sigar_proc_fd_get(sigar_t *sigar, sigar_pid_t pid,
|
918
|
+
sigar_proc_fd_t *procfd)
|
919
|
+
{
|
920
|
+
#ifdef SIGAR_64BIT
|
921
|
+
/* XXX no getuser() in 64-bit mode */
|
922
|
+
return SIGAR_ENOTIMPL;
|
923
|
+
#else
|
924
|
+
int i;
|
925
|
+
struct procsinfo pinfo;
|
926
|
+
struct user uinfo;
|
927
|
+
|
928
|
+
procfd->total = 0;
|
929
|
+
pinfo.pi_pid = pid;
|
930
|
+
|
931
|
+
if (getuser(&pinfo, sizeof(pinfo),
|
932
|
+
&uinfo, sizeof(uinfo)) != 0) {
|
933
|
+
if (errno == EINVAL) {
|
934
|
+
return SIGAR_ENOTIMPL; /*XXX 5.2+*/
|
935
|
+
}
|
936
|
+
}
|
937
|
+
|
938
|
+
/* see sys/user.h */
|
939
|
+
for (i=0; i<uinfo.U_maxofile; i++) {
|
940
|
+
if (uinfo.U_ofile(i)) {
|
941
|
+
procfd->total++;
|
942
|
+
}
|
943
|
+
}
|
944
|
+
|
945
|
+
return SIGAR_OK;
|
946
|
+
#endif
|
947
|
+
}
|
948
|
+
|
949
|
+
int sigar_proc_exe_get(sigar_t *sigar, sigar_pid_t pid,
|
950
|
+
sigar_proc_exe_t *procexe)
|
951
|
+
{
|
952
|
+
return SIGAR_ENOTIMPL;
|
953
|
+
}
|
954
|
+
|
955
|
+
static int sigar_proc_modules_local_get(sigar_t *sigar,
|
956
|
+
sigar_proc_modules_t *procmods)
|
957
|
+
{
|
958
|
+
struct ld_info *info;
|
959
|
+
char *buffer;
|
960
|
+
int size = 2048, status;
|
961
|
+
unsigned int offset;
|
962
|
+
|
963
|
+
buffer = malloc(size);
|
964
|
+
while ((loadquery(L_GETINFO, buffer, size) == -1) &&
|
965
|
+
(errno == ENOMEM))
|
966
|
+
{
|
967
|
+
size += 2048;
|
968
|
+
buffer = realloc(buffer, size);
|
969
|
+
}
|
970
|
+
|
971
|
+
info = (struct ld_info *)buffer;
|
972
|
+
|
973
|
+
do {
|
974
|
+
char *name = info->ldinfo_filename;
|
975
|
+
|
976
|
+
status =
|
977
|
+
procmods->module_getter(procmods->data, name, strlen(name));
|
978
|
+
|
979
|
+
if (status != SIGAR_OK) {
|
980
|
+
/* not an error; just stop iterating */
|
981
|
+
free(buffer);
|
982
|
+
return status;
|
983
|
+
}
|
984
|
+
|
985
|
+
offset = info->ldinfo_next;
|
986
|
+
info = (struct ld_info *)((char*)info + offset);
|
987
|
+
} while(offset);
|
988
|
+
|
989
|
+
free(buffer);
|
990
|
+
|
991
|
+
return SIGAR_OK;
|
992
|
+
}
|
993
|
+
|
994
|
+
int sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid,
|
995
|
+
sigar_proc_modules_t *procmods)
|
996
|
+
{
|
997
|
+
if (pid == sigar_pid_get(sigar)) {
|
998
|
+
return sigar_proc_modules_local_get(sigar, procmods);
|
999
|
+
}
|
1000
|
+
else {
|
1001
|
+
return SIGAR_ENOTIMPL;
|
1002
|
+
}
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
#define SIGAR_MICROSEC2NANO(s) \
|
1006
|
+
((sigar_uint64_t)(s) * (sigar_uint64_t)1000)
|
1007
|
+
|
1008
|
+
#define TIME_NSEC(t) \
|
1009
|
+
(SIGAR_SEC2NANO((t).tv_sec) + SIGAR_MICROSEC2NANO((t).tv_usec))
|
1010
|
+
|
1011
|
+
int sigar_thread_cpu_get(sigar_t *sigar,
|
1012
|
+
sigar_uint64_t id,
|
1013
|
+
sigar_thread_cpu_t *cpu)
|
1014
|
+
{
|
1015
|
+
struct rusage usage;
|
1016
|
+
int retval;
|
1017
|
+
|
1018
|
+
if (sigar->thrusage != PTHRDSINFO_RUSAGE_START) {
|
1019
|
+
sigar->thrusage = PTHRDSINFO_RUSAGE_START;
|
1020
|
+
retval =
|
1021
|
+
sigar_thread_rusage(&usage,
|
1022
|
+
PTHRDSINFO_RUSAGE_START);
|
1023
|
+
if (retval != 0) {
|
1024
|
+
return retval;
|
1025
|
+
}
|
1026
|
+
}
|
1027
|
+
|
1028
|
+
retval =
|
1029
|
+
sigar_thread_rusage(&usage,
|
1030
|
+
PTHRDSINFO_RUSAGE_COLLECT);
|
1031
|
+
if (retval != 0) {
|
1032
|
+
return retval;
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
cpu->user = TIME_NSEC(usage.ru_utime);
|
1036
|
+
cpu->sys = TIME_NSEC(usage.ru_stime);
|
1037
|
+
cpu->total = TIME_NSEC(usage.ru_utime) + TIME_NSEC(usage.ru_stime);
|
1038
|
+
|
1039
|
+
return SIGAR_OK;
|
1040
|
+
}
|
1041
|
+
|
1042
|
+
int sigar_os_fs_type_get(sigar_file_system_t *fsp)
|
1043
|
+
{
|
1044
|
+
return fsp->type;
|
1045
|
+
}
|
1046
|
+
|
1047
|
+
#ifndef MNT_NFS4
|
1048
|
+
/* another one documented in aix tech ref
|
1049
|
+
* with no friggin prototype in any header file...
|
1050
|
+
* ...but added in 5.2
|
1051
|
+
*/
|
1052
|
+
int mntctl(int command, int size, char *buffer);
|
1053
|
+
#endif
|
1054
|
+
|
1055
|
+
int sigar_file_system_list_get(sigar_t *sigar,
|
1056
|
+
sigar_file_system_list_t *fslist)
|
1057
|
+
{
|
1058
|
+
int i, size, num;
|
1059
|
+
char *buf, *mntlist;
|
1060
|
+
|
1061
|
+
/* get required size */
|
1062
|
+
if (mntctl(MCTL_QUERY, sizeof(size), (char *)&size) < 0) {
|
1063
|
+
return errno;
|
1064
|
+
}
|
1065
|
+
|
1066
|
+
mntlist = buf = malloc(size);
|
1067
|
+
|
1068
|
+
if ((num = mntctl(MCTL_QUERY, size, buf)) < 0) {
|
1069
|
+
free(buf);
|
1070
|
+
return errno;
|
1071
|
+
}
|
1072
|
+
|
1073
|
+
sigar_file_system_list_create(fslist);
|
1074
|
+
|
1075
|
+
for (i=0; i<num; i++) {
|
1076
|
+
char *devname;
|
1077
|
+
const char *typename = NULL;
|
1078
|
+
sigar_file_system_t *fsp;
|
1079
|
+
struct vmount *ent = (struct vmount *)mntlist;
|
1080
|
+
|
1081
|
+
mntlist += ent->vmt_length;
|
1082
|
+
|
1083
|
+
SIGAR_FILE_SYSTEM_LIST_GROW(fslist);
|
1084
|
+
|
1085
|
+
fsp = &fslist->data[fslist->number++];
|
1086
|
+
|
1087
|
+
switch (ent->vmt_gfstype) {
|
1088
|
+
case MNT_AIX:
|
1089
|
+
typename = "aix";
|
1090
|
+
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
1091
|
+
break;
|
1092
|
+
case MNT_JFS:
|
1093
|
+
typename = "jfs";
|
1094
|
+
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
1095
|
+
break;
|
1096
|
+
case MNT_NFS:
|
1097
|
+
case MNT_NFS3:
|
1098
|
+
typename = "nfs";
|
1099
|
+
fsp->type = SIGAR_FSTYPE_NETWORK;
|
1100
|
+
break;
|
1101
|
+
case MNT_CDROM:
|
1102
|
+
fsp->type = SIGAR_FSTYPE_CDROM;
|
1103
|
+
break;
|
1104
|
+
case MNT_SFS:
|
1105
|
+
case MNT_CACHEFS:
|
1106
|
+
case MNT_AUTOFS:
|
1107
|
+
default:
|
1108
|
+
if (ent->vmt_flags & MNT_REMOTE) {
|
1109
|
+
fsp->type = SIGAR_FSTYPE_NETWORK;
|
1110
|
+
}
|
1111
|
+
else {
|
1112
|
+
fsp->type = SIGAR_FSTYPE_NONE;
|
1113
|
+
}
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
SIGAR_SSTRCPY(fsp->dir_name, vmt2dataptr(ent, VMT_STUB));
|
1117
|
+
SIGAR_SSTRCPY(fsp->options, vmt2dataptr(ent, VMT_ARGS));
|
1118
|
+
|
1119
|
+
devname = vmt2dataptr(ent, VMT_OBJECT);
|
1120
|
+
|
1121
|
+
if (fsp->type == SIGAR_FSTYPE_NETWORK) {
|
1122
|
+
char *hostname = vmt2dataptr(ent, VMT_HOSTNAME);
|
1123
|
+
#if 0
|
1124
|
+
/* XXX: these do not seem reliable */
|
1125
|
+
int hostname_len = vmt2datasize(ent, VMT_HOSTNAME)-1; /* -1 == skip '\0' */
|
1126
|
+
int devname_len = vmt2datasize(ent, VMT_OBJECT); /* includes '\0' */
|
1127
|
+
#else
|
1128
|
+
int hostname_len = strlen(hostname);
|
1129
|
+
int devname_len = strlen(devname) + 1;
|
1130
|
+
#endif
|
1131
|
+
int total_len = hostname_len + devname_len + 1; /* 1 == strlen(":") */
|
1132
|
+
|
1133
|
+
if (total_len > sizeof(fsp->dev_name)) {
|
1134
|
+
/* justincase - prevent overflow. chances: slim..none */
|
1135
|
+
SIGAR_SSTRCPY(fsp->dev_name, devname);
|
1136
|
+
}
|
1137
|
+
else {
|
1138
|
+
/* sprintf(fsp->devname, "%s:%s", hostname, devname) */
|
1139
|
+
char *ptr = fsp->dev_name;
|
1140
|
+
|
1141
|
+
memcpy(ptr, hostname, hostname_len);
|
1142
|
+
ptr += hostname_len;
|
1143
|
+
|
1144
|
+
*ptr++ = ':';
|
1145
|
+
|
1146
|
+
memcpy(ptr, devname, devname_len);
|
1147
|
+
}
|
1148
|
+
}
|
1149
|
+
else {
|
1150
|
+
SIGAR_SSTRCPY(fsp->dev_name, devname);
|
1151
|
+
}
|
1152
|
+
|
1153
|
+
/* we set fsp->type, just looking up sigar.c:fstype_names[type] */
|
1154
|
+
sigar_fs_type_get(fsp);
|
1155
|
+
|
1156
|
+
if (typename == NULL) {
|
1157
|
+
typename = fsp->type_name;
|
1158
|
+
}
|
1159
|
+
|
1160
|
+
SIGAR_SSTRCPY(fsp->sys_type_name, typename);
|
1161
|
+
}
|
1162
|
+
|
1163
|
+
free(buf);
|
1164
|
+
|
1165
|
+
return SIGAR_OK;
|
1166
|
+
}
|
1167
|
+
|
1168
|
+
typedef struct {
|
1169
|
+
char name[IDENTIFIER_LENGTH];
|
1170
|
+
long addr;
|
1171
|
+
} aix_diskio_t;
|
1172
|
+
|
1173
|
+
static int create_diskmap(sigar_t *sigar)
|
1174
|
+
{
|
1175
|
+
int i, total, num;
|
1176
|
+
perfstat_disk_t *disk;
|
1177
|
+
perfstat_id_t id;
|
1178
|
+
|
1179
|
+
total = perfstat_disk(NULL, NULL, sizeof(*disk), 0);
|
1180
|
+
if (total < 1) {
|
1181
|
+
return ENOENT;
|
1182
|
+
}
|
1183
|
+
|
1184
|
+
disk = malloc(total * sizeof(*disk));
|
1185
|
+
id.name[0] = '\0';
|
1186
|
+
|
1187
|
+
num = perfstat_disk(&id, disk, sizeof(*disk), total);
|
1188
|
+
if (num < 1) {
|
1189
|
+
free(disk);
|
1190
|
+
return ENOENT;
|
1191
|
+
}
|
1192
|
+
|
1193
|
+
sigar->diskmap = sigar_cache_new(25);
|
1194
|
+
|
1195
|
+
odm_initialize();
|
1196
|
+
|
1197
|
+
for (i=0; i<num; i++) {
|
1198
|
+
char query[256];
|
1199
|
+
struct CuDv *dv, *ptr;
|
1200
|
+
struct listinfo info;
|
1201
|
+
sigar_cache_entry_t *ent;
|
1202
|
+
int j;
|
1203
|
+
|
1204
|
+
snprintf(query, sizeof(query),
|
1205
|
+
"parent = '%s'", disk[i].vgname);
|
1206
|
+
|
1207
|
+
ptr = dv = odm_get_list(CuDv_CLASS, query, &info, 256, 1);
|
1208
|
+
if ((int)dv == -1) {
|
1209
|
+
continue; /* XXX */
|
1210
|
+
}
|
1211
|
+
|
1212
|
+
for (j=0; j<info.num; j++, ptr++) {
|
1213
|
+
struct CuAt *attr;
|
1214
|
+
int num, retval;
|
1215
|
+
struct stat sb;
|
1216
|
+
|
1217
|
+
if ((attr = getattr(ptr->name, "label", 0, &num))) {
|
1218
|
+
retval = stat(attr->value, &sb);
|
1219
|
+
|
1220
|
+
if (retval == 0) {
|
1221
|
+
aix_diskio_t *diskio = malloc(sizeof(*diskio));
|
1222
|
+
SIGAR_SSTRCPY(diskio->name, disk[i].name);
|
1223
|
+
diskio->addr = -1;
|
1224
|
+
ent = sigar_cache_get(sigar->diskmap, SIGAR_FSDEV_ID(sb));
|
1225
|
+
ent->value = diskio;
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
free(attr);
|
1229
|
+
}
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
odm_free_list(dv, &info);
|
1233
|
+
}
|
1234
|
+
|
1235
|
+
free(disk);
|
1236
|
+
odm_terminate();
|
1237
|
+
|
1238
|
+
return SIGAR_OK;
|
1239
|
+
}
|
1240
|
+
|
1241
|
+
int sigar_disk_usage_get(sigar_t *sigar, const char *name,
|
1242
|
+
sigar_disk_usage_t *usage)
|
1243
|
+
{
|
1244
|
+
perfstat_disk_t disk;
|
1245
|
+
perfstat_id_t id;
|
1246
|
+
|
1247
|
+
SIGAR_SSTRCPY(id.name, name);
|
1248
|
+
|
1249
|
+
if (perfstat_disk(&id, &disk, sizeof(disk), 1) != 1) {
|
1250
|
+
return ENXIO;
|
1251
|
+
}
|
1252
|
+
|
1253
|
+
usage->reads = disk.rblks;
|
1254
|
+
usage->writes = disk.wblks;
|
1255
|
+
usage->read_bytes = disk.rblks * disk.bsize;
|
1256
|
+
usage->write_bytes = disk.wblks * disk.bsize;
|
1257
|
+
usage->queue = disk.qdepth;
|
1258
|
+
usage->time = disk.time;
|
1259
|
+
usage->rtime = SIGAR_FIELD_NOTIMPL;
|
1260
|
+
usage->wtime = SIGAR_FIELD_NOTIMPL;
|
1261
|
+
|
1262
|
+
return SIGAR_OK;
|
1263
|
+
}
|
1264
|
+
|
1265
|
+
int sigar_file_system_usage_get(sigar_t *sigar,
|
1266
|
+
const char *dirname,
|
1267
|
+
sigar_file_system_usage_t *fsusage)
|
1268
|
+
{
|
1269
|
+
sigar_cache_entry_t *ent;
|
1270
|
+
struct stat sb;
|
1271
|
+
int status;
|
1272
|
+
|
1273
|
+
status = sigar_statvfs(sigar, dirname, fsusage);
|
1274
|
+
|
1275
|
+
if (status != SIGAR_OK) {
|
1276
|
+
return status;
|
1277
|
+
}
|
1278
|
+
|
1279
|
+
fsusage->use_percent = sigar_file_system_usage_calc_used(sigar, fsusage);
|
1280
|
+
|
1281
|
+
SIGAR_DISK_STATS_INIT(&fsusage->disk);
|
1282
|
+
|
1283
|
+
if (!sigar->diskmap) {
|
1284
|
+
status = create_diskmap(sigar);
|
1285
|
+
if (status != SIGAR_OK) {
|
1286
|
+
return SIGAR_OK;
|
1287
|
+
}
|
1288
|
+
}
|
1289
|
+
|
1290
|
+
status = stat(dirname, &sb);
|
1291
|
+
if (status == 0) {
|
1292
|
+
sigar_cache_entry_t *ent =
|
1293
|
+
sigar_cache_get(sigar->diskmap, SIGAR_FSDEV_ID(sb));
|
1294
|
+
if (!ent->value) {
|
1295
|
+
return SIGAR_OK;
|
1296
|
+
}
|
1297
|
+
sigar_disk_usage_get(sigar, ((aix_diskio_t *)ent->value)->name, &fsusage->disk);
|
1298
|
+
}
|
1299
|
+
|
1300
|
+
return SIGAR_OK;
|
1301
|
+
}
|
1302
|
+
|
1303
|
+
/* from sys/systemcfg.h, not defined in 4.3 headers */
|
1304
|
+
#ifndef POWER_4
|
1305
|
+
#define POWER_4 0x0800
|
1306
|
+
#endif
|
1307
|
+
#ifndef POWER_MPC7450
|
1308
|
+
#define POWER_MPC7450 0x1000
|
1309
|
+
#endif
|
1310
|
+
#ifndef POWER_5
|
1311
|
+
#define POWER_5 0x2000
|
1312
|
+
#endif
|
1313
|
+
|
1314
|
+
static char *sigar_get_odm_model(sigar_t *sigar)
|
1315
|
+
{
|
1316
|
+
if (sigar->model[0] == '\0') {
|
1317
|
+
struct CuAt *odm_obj;
|
1318
|
+
int num;
|
1319
|
+
|
1320
|
+
odm_initialize();
|
1321
|
+
|
1322
|
+
if ((odm_obj = getattr("proc0", "type", 0, &num))) {
|
1323
|
+
SIGAR_SSTRCPY(sigar->model, odm_obj->value);
|
1324
|
+
free(odm_obj);
|
1325
|
+
}
|
1326
|
+
|
1327
|
+
odm_terminate();
|
1328
|
+
}
|
1329
|
+
|
1330
|
+
return sigar->model;
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
#define SIGAR_CPU_CACHE_SIZE \
|
1334
|
+
(_system_configuration.L2_cache_size / 1024)
|
1335
|
+
|
1336
|
+
static int sigar_get_cpu_mhz(sigar_t *sigar)
|
1337
|
+
{
|
1338
|
+
if (sigar->cpu_mhz == SIGAR_FIELD_NOTIMPL) {
|
1339
|
+
perfstat_cpu_total_t data;
|
1340
|
+
|
1341
|
+
if (sigar_perfstat_cpu(&data) == 1) {
|
1342
|
+
sigar->cpu_mhz = data.processorHZ / 1000000;
|
1343
|
+
}
|
1344
|
+
else {
|
1345
|
+
sigar_log_printf(sigar, SIGAR_LOG_ERROR,
|
1346
|
+
"perfstat_cpu_total failed: %s",
|
1347
|
+
sigar_strerror(sigar, errno));
|
1348
|
+
}
|
1349
|
+
}
|
1350
|
+
|
1351
|
+
return sigar->cpu_mhz;
|
1352
|
+
}
|
1353
|
+
|
1354
|
+
static char *get_cpu_arch(void)
|
1355
|
+
{
|
1356
|
+
switch (_system_configuration.architecture) {
|
1357
|
+
case POWER_RS:
|
1358
|
+
return "Power Classic";
|
1359
|
+
case POWER_PC:
|
1360
|
+
return "PowerPC";
|
1361
|
+
case IA64:
|
1362
|
+
return "IA64";
|
1363
|
+
default:
|
1364
|
+
return "PowerPC"; /* what else could it be */
|
1365
|
+
}
|
1366
|
+
}
|
1367
|
+
|
1368
|
+
static char *get_ppc_cpu_model(void)
|
1369
|
+
{
|
1370
|
+
switch (_system_configuration.implementation) {
|
1371
|
+
case POWER_RS1:
|
1372
|
+
return "RS1";
|
1373
|
+
case POWER_RSC:
|
1374
|
+
return "RSC";
|
1375
|
+
case POWER_RS2:
|
1376
|
+
return "RS2";
|
1377
|
+
case POWER_601:
|
1378
|
+
return "601";
|
1379
|
+
case POWER_603:
|
1380
|
+
return "603";
|
1381
|
+
case POWER_604:
|
1382
|
+
return "604";
|
1383
|
+
case POWER_620:
|
1384
|
+
return "620";
|
1385
|
+
case POWER_630:
|
1386
|
+
return "630";
|
1387
|
+
case POWER_A35:
|
1388
|
+
return "A35";
|
1389
|
+
case POWER_RS64II:
|
1390
|
+
return "RS64-II";
|
1391
|
+
case POWER_RS64III:
|
1392
|
+
return "RS64-III";
|
1393
|
+
case POWER_4:
|
1394
|
+
return "POWER4";
|
1395
|
+
case POWER_MPC7450:
|
1396
|
+
return "MPC7450";
|
1397
|
+
case POWER_5:
|
1398
|
+
return "POWER5";
|
1399
|
+
default:
|
1400
|
+
return "Unknown";
|
1401
|
+
}
|
1402
|
+
}
|
1403
|
+
|
1404
|
+
static char *get_ia64_cpu_model(void)
|
1405
|
+
{
|
1406
|
+
switch (_system_configuration.implementation) {
|
1407
|
+
case IA64_M1:
|
1408
|
+
return "M1";
|
1409
|
+
case IA64_M2:
|
1410
|
+
return "M2";
|
1411
|
+
default:
|
1412
|
+
return "Unknown";
|
1413
|
+
}
|
1414
|
+
}
|
1415
|
+
|
1416
|
+
static char *get_cpu_model(void)
|
1417
|
+
{
|
1418
|
+
if (_system_configuration.architecture == IA64) {
|
1419
|
+
return get_ia64_cpu_model();
|
1420
|
+
}
|
1421
|
+
else {
|
1422
|
+
return get_ppc_cpu_model();
|
1423
|
+
}
|
1424
|
+
}
|
1425
|
+
|
1426
|
+
int sigar_cpu_info_list_get(sigar_t *sigar,
|
1427
|
+
sigar_cpu_info_list_t *cpu_infos)
|
1428
|
+
{
|
1429
|
+
int i;
|
1430
|
+
int ncpu = _system_configuration.ncpus; /* this can change */
|
1431
|
+
char *arch = get_cpu_arch(), *model = get_cpu_model();
|
1432
|
+
|
1433
|
+
/*XXX should only do this once*/
|
1434
|
+
sigar_cpu_info_list_create(cpu_infos);
|
1435
|
+
|
1436
|
+
for (i=0; i<ncpu; i++) {
|
1437
|
+
sigar_cpu_info_t *info;
|
1438
|
+
|
1439
|
+
SIGAR_CPU_INFO_LIST_GROW(cpu_infos);
|
1440
|
+
|
1441
|
+
info = &cpu_infos->data[cpu_infos->number++];
|
1442
|
+
|
1443
|
+
info->total_cores = ncpu;
|
1444
|
+
info->cores_per_socket = 1; /*XXX*/
|
1445
|
+
info->total_sockets = ncpu; /*XXX*/
|
1446
|
+
|
1447
|
+
info->cache_size = SIGAR_CPU_CACHE_SIZE;
|
1448
|
+
|
1449
|
+
info->mhz = sigar_get_cpu_mhz(sigar);
|
1450
|
+
|
1451
|
+
if (*arch == 'P') {
|
1452
|
+
SIGAR_SSTRCPY(info->vendor, "IBM");
|
1453
|
+
}
|
1454
|
+
else if (*arch == 'I') {
|
1455
|
+
SIGAR_SSTRCPY(info->vendor, "Intel");
|
1456
|
+
}
|
1457
|
+
else {
|
1458
|
+
SIGAR_SSTRCPY(info->vendor, "Unknown");
|
1459
|
+
}
|
1460
|
+
|
1461
|
+
snprintf(info->model, sizeof(info->model),
|
1462
|
+
"%s %s", arch, model);
|
1463
|
+
}
|
1464
|
+
|
1465
|
+
return SIGAR_OK;
|
1466
|
+
}
|
1467
|
+
|
1468
|
+
int sigar_net_route_list_get(sigar_t *sigar,
|
1469
|
+
sigar_net_route_list_t *routelist)
|
1470
|
+
{
|
1471
|
+
return SIGAR_ENOTIMPL;
|
1472
|
+
}
|
1473
|
+
|
1474
|
+
int sigar_net_interface_stat_get(sigar_t *sigar,
|
1475
|
+
const char *name,
|
1476
|
+
sigar_net_interface_stat_t *ifstat)
|
1477
|
+
{
|
1478
|
+
perfstat_id_t id;
|
1479
|
+
perfstat_netinterface_t data;
|
1480
|
+
|
1481
|
+
sigar_log(sigar, SIGAR_LOG_DEBUG, "[ifstat] using libperfstat");
|
1482
|
+
|
1483
|
+
SIGAR_SSTRCPY(id.name, name);
|
1484
|
+
|
1485
|
+
if (perfstat_netinterface(&id, &data, sizeof(data), 1) == 1) {
|
1486
|
+
ifstat->rx_bytes = data.ibytes;
|
1487
|
+
ifstat->rx_packets = data.ipackets;
|
1488
|
+
ifstat->rx_errors = data.ierrors;
|
1489
|
+
ifstat->rx_dropped = SIGAR_FIELD_NOTIMPL;
|
1490
|
+
ifstat->rx_overruns = SIGAR_FIELD_NOTIMPL;
|
1491
|
+
ifstat->rx_frame = SIGAR_FIELD_NOTIMPL;
|
1492
|
+
|
1493
|
+
ifstat->tx_bytes = data.obytes;
|
1494
|
+
ifstat->tx_packets = data.opackets;
|
1495
|
+
ifstat->tx_errors = data.oerrors;
|
1496
|
+
ifstat->tx_dropped = SIGAR_FIELD_NOTIMPL;
|
1497
|
+
ifstat->tx_overruns = SIGAR_FIELD_NOTIMPL;
|
1498
|
+
ifstat->tx_collisions = data.collisions;
|
1499
|
+
ifstat->tx_carrier = SIGAR_FIELD_NOTIMPL;
|
1500
|
+
|
1501
|
+
ifstat->speed = data.bitrate;
|
1502
|
+
|
1503
|
+
return SIGAR_OK;
|
1504
|
+
}
|
1505
|
+
else {
|
1506
|
+
return errno;
|
1507
|
+
}
|
1508
|
+
}
|
1509
|
+
|
1510
|
+
#define IS_TCP_SERVER(state, flags) \
|
1511
|
+
((flags & SIGAR_NETCONN_SERVER) && (state == TCPS_LISTEN))
|
1512
|
+
|
1513
|
+
#define IS_TCP_CLIENT(state, flags) \
|
1514
|
+
((flags & SIGAR_NETCONN_CLIENT) && (state != TCPS_LISTEN))
|
1515
|
+
|
1516
|
+
static int net_conn_get_tcp(sigar_net_connection_walker_t *walker)
|
1517
|
+
{
|
1518
|
+
sigar_t *sigar = walker->sigar;
|
1519
|
+
int flags = walker->flags;
|
1520
|
+
int status;
|
1521
|
+
struct inpcb tcp_inpcb;
|
1522
|
+
struct tcpcb tcpcb;
|
1523
|
+
struct inpcb *entry;
|
1524
|
+
|
1525
|
+
status = kread(sigar, &tcp_inpcb, sizeof(tcp_inpcb),
|
1526
|
+
sigar->koffsets[KOFFSET_TCB]);
|
1527
|
+
|
1528
|
+
if (status != SIGAR_OK) {
|
1529
|
+
return status;
|
1530
|
+
}
|
1531
|
+
|
1532
|
+
entry = tcp_inpcb.inp_next;
|
1533
|
+
while (entry) {
|
1534
|
+
struct inpcb pcb;
|
1535
|
+
int state;
|
1536
|
+
|
1537
|
+
status = kread(sigar, &pcb, sizeof(pcb), (long)entry);
|
1538
|
+
if (status != SIGAR_OK) {
|
1539
|
+
return status;
|
1540
|
+
}
|
1541
|
+
status = kread(sigar, &tcpcb, sizeof(tcpcb), (long)pcb.inp_ppcb);
|
1542
|
+
if (status != SIGAR_OK) {
|
1543
|
+
return status;
|
1544
|
+
}
|
1545
|
+
|
1546
|
+
state = tcpcb.t_state;
|
1547
|
+
if ((IS_TCP_SERVER(state, flags) ||
|
1548
|
+
IS_TCP_CLIENT(state, flags)))
|
1549
|
+
{
|
1550
|
+
sigar_net_connection_t conn;
|
1551
|
+
|
1552
|
+
SIGAR_ZERO(&conn);
|
1553
|
+
|
1554
|
+
conn.type = SIGAR_NETCONN_TCP;
|
1555
|
+
|
1556
|
+
sigar_net_address_set(conn.local_address,
|
1557
|
+
pcb.inp_laddr.s_addr);
|
1558
|
+
|
1559
|
+
sigar_net_address_set(conn.remote_address,
|
1560
|
+
pcb.inp_faddr.s_addr);
|
1561
|
+
|
1562
|
+
conn.local_port = ntohs(pcb.inp_lport);
|
1563
|
+
conn.remote_port = ntohs(pcb.inp_fport);
|
1564
|
+
|
1565
|
+
conn.send_queue = conn.receive_queue = SIGAR_FIELD_NOTIMPL;
|
1566
|
+
|
1567
|
+
switch (state) {
|
1568
|
+
case TCPS_CLOSED:
|
1569
|
+
conn.state = SIGAR_TCP_CLOSE;
|
1570
|
+
break;
|
1571
|
+
case TCPS_LISTEN:
|
1572
|
+
conn.state = SIGAR_TCP_LISTEN;
|
1573
|
+
break;
|
1574
|
+
case TCPS_SYN_SENT:
|
1575
|
+
conn.state = SIGAR_TCP_SYN_SENT;
|
1576
|
+
break;
|
1577
|
+
case TCPS_SYN_RECEIVED:
|
1578
|
+
conn.state = SIGAR_TCP_SYN_RECV;
|
1579
|
+
break;
|
1580
|
+
case TCPS_ESTABLISHED:
|
1581
|
+
conn.state = SIGAR_TCP_ESTABLISHED;
|
1582
|
+
break;
|
1583
|
+
case TCPS_CLOSE_WAIT:
|
1584
|
+
conn.state = SIGAR_TCP_CLOSE_WAIT;
|
1585
|
+
break;
|
1586
|
+
case TCPS_FIN_WAIT_1:
|
1587
|
+
conn.state = SIGAR_TCP_FIN_WAIT1;
|
1588
|
+
break;
|
1589
|
+
case TCPS_CLOSING:
|
1590
|
+
conn.state = SIGAR_TCP_CLOSING;
|
1591
|
+
break;
|
1592
|
+
case TCPS_LAST_ACK:
|
1593
|
+
conn.state = SIGAR_TCP_LAST_ACK;
|
1594
|
+
break;
|
1595
|
+
case TCPS_FIN_WAIT_2:
|
1596
|
+
conn.state = SIGAR_TCP_FIN_WAIT2;
|
1597
|
+
break;
|
1598
|
+
case TCPS_TIME_WAIT:
|
1599
|
+
conn.state = SIGAR_TCP_TIME_WAIT;
|
1600
|
+
break;
|
1601
|
+
default:
|
1602
|
+
conn.state = SIGAR_TCP_UNKNOWN;
|
1603
|
+
break;
|
1604
|
+
}
|
1605
|
+
|
1606
|
+
if (walker->add_connection(walker, &conn) != SIGAR_OK) {
|
1607
|
+
break;
|
1608
|
+
}
|
1609
|
+
}
|
1610
|
+
|
1611
|
+
entry = pcb.inp_next;
|
1612
|
+
if (entry == tcp_inpcb.inp_next) {
|
1613
|
+
break;
|
1614
|
+
}
|
1615
|
+
}
|
1616
|
+
|
1617
|
+
return SIGAR_OK;
|
1618
|
+
}
|
1619
|
+
|
1620
|
+
int sigar_net_connection_walk(sigar_net_connection_walker_t *walker)
|
1621
|
+
{
|
1622
|
+
int status;
|
1623
|
+
|
1624
|
+
if (walker->flags & SIGAR_NETCONN_TCP) {
|
1625
|
+
status = net_conn_get_tcp(walker);
|
1626
|
+
|
1627
|
+
if (status != SIGAR_OK) {
|
1628
|
+
return status;
|
1629
|
+
}
|
1630
|
+
}
|
1631
|
+
#if 0
|
1632
|
+
if (walker->flags & SIGAR_NETCONN_UDP) {
|
1633
|
+
status = net_conn_get_udp(walker);
|
1634
|
+
|
1635
|
+
if (status != SIGAR_OK) {
|
1636
|
+
return status;
|
1637
|
+
}
|
1638
|
+
}
|
1639
|
+
#endif
|
1640
|
+
return SIGAR_OK;
|
1641
|
+
}
|
1642
|
+
|
1643
|
+
SIGAR_DECLARE(int)
|
1644
|
+
sigar_tcp_get(sigar_t *sigar,
|
1645
|
+
sigar_tcp_t *tcp)
|
1646
|
+
{
|
1647
|
+
perfstat_id_t id;
|
1648
|
+
perfstat_protocol_t proto;
|
1649
|
+
|
1650
|
+
SIGAR_SSTRCPY(id.name, "tcp");
|
1651
|
+
|
1652
|
+
if (perfstat_protocol(&id, &proto, sizeof(proto), 1) != 1) {
|
1653
|
+
return ENOENT;
|
1654
|
+
}
|
1655
|
+
|
1656
|
+
tcp->active_opens = proto.u.tcp.initiated;
|
1657
|
+
tcp->passive_opens = proto.u.tcp.accepted;
|
1658
|
+
tcp->attempt_fails = proto.u.tcp.dropped;
|
1659
|
+
tcp->estab_resets = proto.u.tcp.dropped;
|
1660
|
+
tcp->curr_estab = proto.u.tcp.established;
|
1661
|
+
tcp->in_segs = proto.u.tcp.ipackets;
|
1662
|
+
tcp->out_segs = proto.u.tcp.opackets;
|
1663
|
+
tcp->retrans_segs = 0;
|
1664
|
+
tcp->in_errs = proto.u.tcp.ierrors;
|
1665
|
+
tcp->out_rsts = 0;
|
1666
|
+
}
|
1667
|
+
|
1668
|
+
#define NFS_V2_STAT_SET(type) \
|
1669
|
+
nfs->null = proto.u.nfsv2.type.null; \
|
1670
|
+
nfs->getattr = proto.u.nfsv2.type.getattr; \
|
1671
|
+
nfs->setattr = proto.u.nfsv2.type.setattr; \
|
1672
|
+
nfs->root = proto.u.nfsv2.type.root; \
|
1673
|
+
nfs->lookup = proto.u.nfsv2.type.lookup; \
|
1674
|
+
nfs->readlink = proto.u.nfsv2.type.readlink; \
|
1675
|
+
nfs->read = proto.u.nfsv2.type.read; \
|
1676
|
+
nfs->writecache = proto.u.nfsv2.type.writecache; \
|
1677
|
+
nfs->write = proto.u.nfsv2.type.write; \
|
1678
|
+
nfs->create = proto.u.nfsv2.type.create; \
|
1679
|
+
nfs->remove = proto.u.nfsv2.type.remove; \
|
1680
|
+
nfs->rename = proto.u.nfsv2.type.rename; \
|
1681
|
+
nfs->link = proto.u.nfsv2.type.link; \
|
1682
|
+
nfs->symlink = proto.u.nfsv2.type.symlink; \
|
1683
|
+
nfs->mkdir = proto.u.nfsv2.type.mkdir; \
|
1684
|
+
nfs->rmdir = proto.u.nfsv2.type.rmdir; \
|
1685
|
+
nfs->readdir = proto.u.nfsv2.type.readdir; \
|
1686
|
+
nfs->fsstat = proto.u.nfsv2.type.statfs
|
1687
|
+
|
1688
|
+
int sigar_nfs_client_v2_get(sigar_t *sigar,
|
1689
|
+
sigar_nfs_client_v2_t *nfs)
|
1690
|
+
{
|
1691
|
+
perfstat_id_t id;
|
1692
|
+
perfstat_protocol_t proto;
|
1693
|
+
|
1694
|
+
SIGAR_SSTRCPY(id.name, "nfsv2");
|
1695
|
+
|
1696
|
+
if (perfstat_protocol(&id, &proto, sizeof(proto), 1) != 1) {
|
1697
|
+
return ENOENT;
|
1698
|
+
}
|
1699
|
+
|
1700
|
+
NFS_V2_STAT_SET(client);
|
1701
|
+
|
1702
|
+
return SIGAR_OK;
|
1703
|
+
}
|
1704
|
+
|
1705
|
+
int sigar_nfs_server_v2_get(sigar_t *sigar,
|
1706
|
+
sigar_nfs_server_v2_t *nfs)
|
1707
|
+
{
|
1708
|
+
perfstat_id_t id;
|
1709
|
+
perfstat_protocol_t proto;
|
1710
|
+
|
1711
|
+
SIGAR_SSTRCPY(id.name, "nfsv2");
|
1712
|
+
|
1713
|
+
if (perfstat_protocol(&id, &proto, sizeof(proto), 1) != 1) {
|
1714
|
+
return ENOENT;
|
1715
|
+
}
|
1716
|
+
|
1717
|
+
NFS_V2_STAT_SET(server);
|
1718
|
+
|
1719
|
+
return SIGAR_OK;
|
1720
|
+
}
|
1721
|
+
|
1722
|
+
#define NFS_V3_STAT_SET(type) \
|
1723
|
+
nfs->null = proto.u.nfsv3.type.null; \
|
1724
|
+
nfs->getattr = proto.u.nfsv3.type.getattr; \
|
1725
|
+
nfs->setattr = proto.u.nfsv3.type.setattr; \
|
1726
|
+
nfs->lookup = proto.u.nfsv3.type.lookup; \
|
1727
|
+
nfs->access = proto.u.nfsv3.type.access; \
|
1728
|
+
nfs->readlink = proto.u.nfsv3.type.readlink; \
|
1729
|
+
nfs->read = proto.u.nfsv3.type.read; \
|
1730
|
+
nfs->write = proto.u.nfsv3.type.write; \
|
1731
|
+
nfs->create = proto.u.nfsv3.type.create; \
|
1732
|
+
nfs->mkdir = proto.u.nfsv3.type.mkdir; \
|
1733
|
+
nfs->symlink = proto.u.nfsv3.type.symlink; \
|
1734
|
+
nfs->mknod = proto.u.nfsv3.type.mknod; \
|
1735
|
+
nfs->remove = proto.u.nfsv3.type.remove; \
|
1736
|
+
nfs->rmdir = proto.u.nfsv3.type.rmdir; \
|
1737
|
+
nfs->rename = proto.u.nfsv3.type.rename; \
|
1738
|
+
nfs->link = proto.u.nfsv3.type.link; \
|
1739
|
+
nfs->readdir = proto.u.nfsv3.type.readdir; \
|
1740
|
+
nfs->readdirplus = proto.u.nfsv3.type.readdirplus; \
|
1741
|
+
nfs->fsstat = proto.u.nfsv3.type.fsstat; \
|
1742
|
+
nfs->fsinfo = proto.u.nfsv3.type.fsinfo; \
|
1743
|
+
nfs->pathconf = proto.u.nfsv3.type.pathconf; \
|
1744
|
+
nfs->commit = proto.u.nfsv3.type.commit
|
1745
|
+
|
1746
|
+
int sigar_nfs_client_v3_get(sigar_t *sigar,
|
1747
|
+
sigar_nfs_client_v3_t *nfs)
|
1748
|
+
{
|
1749
|
+
perfstat_id_t id;
|
1750
|
+
perfstat_protocol_t proto;
|
1751
|
+
|
1752
|
+
SIGAR_SSTRCPY(id.name, "nfsv3");
|
1753
|
+
|
1754
|
+
if (perfstat_protocol(&id, &proto, sizeof(proto), 1) != 1) {
|
1755
|
+
return ENOENT;
|
1756
|
+
}
|
1757
|
+
|
1758
|
+
NFS_V3_STAT_SET(client);
|
1759
|
+
|
1760
|
+
return SIGAR_OK;
|
1761
|
+
}
|
1762
|
+
|
1763
|
+
int sigar_nfs_server_v3_get(sigar_t *sigar,
|
1764
|
+
sigar_nfs_server_v3_t *nfs)
|
1765
|
+
{
|
1766
|
+
perfstat_id_t id;
|
1767
|
+
perfstat_protocol_t proto;
|
1768
|
+
|
1769
|
+
SIGAR_SSTRCPY(id.name, "nfsv3");
|
1770
|
+
|
1771
|
+
if (perfstat_protocol(&id, &proto, sizeof(proto), 1) != 1) {
|
1772
|
+
return ENOENT;
|
1773
|
+
}
|
1774
|
+
|
1775
|
+
NFS_V3_STAT_SET(server);
|
1776
|
+
|
1777
|
+
return SIGAR_OK;
|
1778
|
+
}
|
1779
|
+
|
1780
|
+
/* derived from pidentd's k_aix432.c */
|
1781
|
+
int sigar_proc_port_get(sigar_t *sigar, int protocol,
|
1782
|
+
unsigned long port, sigar_pid_t *pidp)
|
1783
|
+
{
|
1784
|
+
struct procsinfo pinfo;
|
1785
|
+
struct fdsinfo finfo;
|
1786
|
+
pid_t pid = 0;
|
1787
|
+
int type;
|
1788
|
+
|
1789
|
+
switch (protocol) {
|
1790
|
+
case SIGAR_NETCONN_TCP:
|
1791
|
+
type = IPPROTO_TCP;
|
1792
|
+
break;
|
1793
|
+
case SIGAR_NETCONN_UDP:
|
1794
|
+
type = IPPROTO_UDP;
|
1795
|
+
break;
|
1796
|
+
default:
|
1797
|
+
return SIGAR_ENOTIMPL;
|
1798
|
+
}
|
1799
|
+
|
1800
|
+
for (;;) {
|
1801
|
+
int fd, status;
|
1802
|
+
int num = getprocs(&pinfo, sizeof(pinfo),
|
1803
|
+
&finfo, sizeof(finfo),
|
1804
|
+
&pid, 1);
|
1805
|
+
|
1806
|
+
if (num == 0) {
|
1807
|
+
break;
|
1808
|
+
}
|
1809
|
+
|
1810
|
+
if ((pinfo.pi_state == 0) || (pinfo.pi_state == SZOMB)) {
|
1811
|
+
continue;
|
1812
|
+
}
|
1813
|
+
|
1814
|
+
for (fd = 0; fd < pinfo.pi_maxofile; fd++) {
|
1815
|
+
struct file file;
|
1816
|
+
struct socket socket, *sockp;
|
1817
|
+
struct protosw protosw;
|
1818
|
+
struct domain domain;
|
1819
|
+
struct inpcb inpcb;
|
1820
|
+
long ptr;
|
1821
|
+
|
1822
|
+
if (!(ptr = (long)finfo.pi_ufd[fd].fp)) {
|
1823
|
+
continue;
|
1824
|
+
}
|
1825
|
+
|
1826
|
+
status = kread(sigar, &file, sizeof(file), ptr);
|
1827
|
+
if (status != SIGAR_OK) {
|
1828
|
+
continue;
|
1829
|
+
}
|
1830
|
+
|
1831
|
+
if (file.f_type != DTYPE_SOCKET) {
|
1832
|
+
continue;
|
1833
|
+
}
|
1834
|
+
|
1835
|
+
if (!(sockp = (struct socket *)file.f_data)) {
|
1836
|
+
continue;
|
1837
|
+
}
|
1838
|
+
|
1839
|
+
status = kread(sigar, &socket, sizeof(socket), (long)sockp);
|
1840
|
+
if (status != SIGAR_OK) {
|
1841
|
+
continue;
|
1842
|
+
}
|
1843
|
+
|
1844
|
+
if (!(ptr = (long)socket.so_proto)) {
|
1845
|
+
continue;
|
1846
|
+
}
|
1847
|
+
|
1848
|
+
status = kread(sigar, &protosw, sizeof(protosw), ptr);
|
1849
|
+
if (status != SIGAR_OK) {
|
1850
|
+
continue;
|
1851
|
+
}
|
1852
|
+
|
1853
|
+
if (protosw.pr_protocol != type) {
|
1854
|
+
continue;
|
1855
|
+
}
|
1856
|
+
|
1857
|
+
if (!(ptr = (long)protosw.pr_domain)) {
|
1858
|
+
continue;
|
1859
|
+
}
|
1860
|
+
|
1861
|
+
status = kread(sigar, &domain, sizeof(domain), ptr);
|
1862
|
+
if (status != SIGAR_OK) {
|
1863
|
+
continue;
|
1864
|
+
}
|
1865
|
+
|
1866
|
+
if ((domain.dom_family != AF_INET) &&
|
1867
|
+
domain.dom_family != AF_INET6)
|
1868
|
+
{
|
1869
|
+
continue;
|
1870
|
+
}
|
1871
|
+
|
1872
|
+
if (!(ptr = (long)socket.so_pcb)) {
|
1873
|
+
continue;
|
1874
|
+
}
|
1875
|
+
|
1876
|
+
status = kread(sigar, &inpcb, sizeof(inpcb), ptr);
|
1877
|
+
if (status != SIGAR_OK) {
|
1878
|
+
continue;
|
1879
|
+
}
|
1880
|
+
|
1881
|
+
if (sockp != inpcb.inp_socket) {
|
1882
|
+
continue;
|
1883
|
+
}
|
1884
|
+
|
1885
|
+
if (inpcb.inp_lport != port) {
|
1886
|
+
continue;
|
1887
|
+
}
|
1888
|
+
|
1889
|
+
*pidp = pinfo.pi_pid;
|
1890
|
+
|
1891
|
+
return SIGAR_OK;
|
1892
|
+
}
|
1893
|
+
}
|
1894
|
+
|
1895
|
+
return ENOENT;
|
1896
|
+
}
|
1897
|
+
|
1898
|
+
int sigar_os_sys_info_get(sigar_t *sigar,
|
1899
|
+
sigar_sys_info_t *sysinfo)
|
1900
|
+
{
|
1901
|
+
struct utsname name;
|
1902
|
+
|
1903
|
+
uname(&name);
|
1904
|
+
|
1905
|
+
SIGAR_SSTRCPY(sysinfo->vendor, "IBM");
|
1906
|
+
SIGAR_SSTRCPY(sysinfo->arch, get_cpu_arch());
|
1907
|
+
/* utsname.machine is a sequence number */
|
1908
|
+
/* XXX odm might have something better */
|
1909
|
+
snprintf(sysinfo->machine,
|
1910
|
+
sizeof(sysinfo->machine),
|
1911
|
+
"%s %s",
|
1912
|
+
sysinfo->arch, get_cpu_model());
|
1913
|
+
|
1914
|
+
snprintf(sysinfo->version,
|
1915
|
+
sizeof(sysinfo->version),
|
1916
|
+
"%s.%s",
|
1917
|
+
name.version, name.release);
|
1918
|
+
|
1919
|
+
SIGAR_SSTRCPY(sysinfo->vendor_version, sysinfo->version);
|
1920
|
+
|
1921
|
+
snprintf(sysinfo->description,
|
1922
|
+
sizeof(sysinfo->description),
|
1923
|
+
"%s %s",
|
1924
|
+
sysinfo->name, sysinfo->version);
|
1925
|
+
|
1926
|
+
return SIGAR_OK;
|
1927
|
+
}
|