sigar 0.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/README +2 -0
- data/Rakefile +105 -0
- data/bindings/SigarBuild.pm +310 -0
- data/bindings/SigarWrapper.pm +2978 -0
- data/bindings/ruby/examples/arp.rb +24 -0
- data/bindings/ruby/examples/cpu_info.rb +35 -0
- data/bindings/ruby/examples/df.rb +49 -0
- data/bindings/ruby/examples/free.rb +36 -0
- data/bindings/ruby/examples/ifconfig.rb +101 -0
- data/bindings/ruby/examples/logging.rb +58 -0
- data/bindings/ruby/examples/net_info.rb +31 -0
- data/bindings/ruby/examples/netstat.rb +71 -0
- data/bindings/ruby/examples/pargs.rb +35 -0
- data/bindings/ruby/examples/penv.rb +31 -0
- data/bindings/ruby/examples/route.rb +48 -0
- data/bindings/ruby/examples/version.rb +40 -0
- data/bindings/ruby/examples/who.rb +30 -0
- data/bindings/ruby/extconf.rb +128 -0
- data/bindings/ruby/rbsigar.c +888 -0
- data/bindings/ruby/test/cpu_test.rb +40 -0
- data/bindings/ruby/test/file_system_test.rb +43 -0
- data/bindings/ruby/test/helper.rb +57 -0
- data/bindings/ruby/test/loadavg_test.rb +30 -0
- data/bindings/ruby/test/mem_test.rb +45 -0
- data/bindings/ruby/test/swap_test.rb +36 -0
- data/bindings/ruby/test/uptime_test.rb +26 -0
- data/include/sigar.h +939 -0
- data/include/sigar_fileinfo.h +157 -0
- data/include/sigar_format.h +65 -0
- data/include/sigar_getline.h +18 -0
- data/include/sigar_log.h +80 -0
- data/include/sigar_private.h +422 -0
- data/include/sigar_ptql.h +53 -0
- data/include/sigar_util.h +191 -0
- data/src/os/aix/aix_sigar.c +2151 -0
- data/src/os/aix/sigar_os.h +73 -0
- data/src/os/darwin/Info.plist.in +27 -0
- data/src/os/darwin/darwin_sigar.c +3709 -0
- data/src/os/darwin/sigar_os.h +80 -0
- data/src/os/hpux/hpux_sigar.c +1342 -0
- data/src/os/hpux/sigar_os.h +49 -0
- data/src/os/linux/linux_sigar.c +2782 -0
- data/src/os/linux/sigar_os.h +82 -0
- data/src/os/solaris/get_mib2.c +321 -0
- data/src/os/solaris/get_mib2.h +127 -0
- data/src/os/solaris/kstats.c +181 -0
- data/src/os/solaris/procfs.c +97 -0
- data/src/os/solaris/sigar_os.h +224 -0
- data/src/os/solaris/solaris_sigar.c +2717 -0
- data/src/os/win32/peb.c +212 -0
- data/src/os/win32/sigar.rc.in +40 -0
- data/src/os/win32/sigar_os.h +653 -0
- data/src/os/win32/sigar_pdh.h +47 -0
- data/src/os/win32/win32_sigar.c +3911 -0
- data/src/sigar.c +2428 -0
- data/src/sigar_cache.c +179 -0
- data/src/sigar_fileinfo.c +815 -0
- data/src/sigar_format.c +696 -0
- data/src/sigar_getline.c +1849 -0
- data/src/sigar_ptql.c +1967 -0
- data/src/sigar_signal.c +216 -0
- data/src/sigar_util.c +1060 -0
- data/src/sigar_version.c.in +22 -0
- data/src/sigar_version_autoconf.c.in +22 -0
- data/version.properties +11 -0
- metadata +131 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2004-2006, 2008 Hyperic, Inc.
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#ifndef SIGAR_OS_H
|
18
|
+
#define SIGAR_OS_H
|
19
|
+
|
20
|
+
#ifdef DARWIN
|
21
|
+
#include <mach/port.h>
|
22
|
+
#include <mach/host_info.h>
|
23
|
+
#ifdef DARWIN_HAS_LIBPROC_H
|
24
|
+
#include <mach-o/dyld.h>
|
25
|
+
#include <libproc.h>
|
26
|
+
typedef int (*proc_pidinfo_func_t)(int, int, uint64_t, void *, int);
|
27
|
+
typedef int (*proc_pidfdinfo_func_t)(int, int, int, void *, int);
|
28
|
+
#endif
|
29
|
+
#else
|
30
|
+
#include <kvm.h>
|
31
|
+
#endif
|
32
|
+
|
33
|
+
#ifdef __NetBSD__
|
34
|
+
#include <sys/param.h>
|
35
|
+
#endif
|
36
|
+
#include <sys/sysctl.h>
|
37
|
+
|
38
|
+
enum {
|
39
|
+
KOFFSET_CPUINFO,
|
40
|
+
KOFFSET_VMMETER,
|
41
|
+
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
42
|
+
KOFFSET_TCPSTAT,
|
43
|
+
KOFFSET_TCBTABLE,
|
44
|
+
#endif
|
45
|
+
KOFFSET_MAX
|
46
|
+
};
|
47
|
+
|
48
|
+
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
49
|
+
typedef struct kinfo_proc2 bsd_pinfo_t;
|
50
|
+
#else
|
51
|
+
typedef struct kinfo_proc bsd_pinfo_t;
|
52
|
+
#endif
|
53
|
+
|
54
|
+
struct sigar_t {
|
55
|
+
SIGAR_T_BASE;
|
56
|
+
int pagesize;
|
57
|
+
time_t last_getprocs;
|
58
|
+
sigar_pid_t last_pid;
|
59
|
+
bsd_pinfo_t *pinfo;
|
60
|
+
int lcpu;
|
61
|
+
size_t argmax;
|
62
|
+
#ifdef DARWIN
|
63
|
+
mach_port_t mach_port;
|
64
|
+
# ifdef DARWIN_HAS_LIBPROC_H
|
65
|
+
void *libproc;
|
66
|
+
proc_pidinfo_func_t proc_pidinfo;
|
67
|
+
proc_pidfdinfo_func_t proc_pidfdinfo;
|
68
|
+
# endif
|
69
|
+
#else
|
70
|
+
kvm_t *kmem;
|
71
|
+
/* offsets for seeking on kmem */
|
72
|
+
unsigned long koffsets[KOFFSET_MAX];
|
73
|
+
int proc_mounted;
|
74
|
+
#endif
|
75
|
+
};
|
76
|
+
|
77
|
+
#define SIGAR_EPERM_KMEM (SIGAR_OS_START_ERROR+EACCES)
|
78
|
+
#define SIGAR_EPROC_NOENT (SIGAR_OS_START_ERROR+2)
|
79
|
+
|
80
|
+
#endif /* SIGAR_OS_H */
|
@@ -0,0 +1,1342 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2004-2009 Hyperic, Inc.
|
3
|
+
* Copyright (c) 2009 SpringSource, Inc.
|
4
|
+
* Copyright (c) 2009-2010 VMware, Inc.
|
5
|
+
*
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
* you may not use this file except in compliance with the License.
|
8
|
+
* You may obtain a copy of the License at
|
9
|
+
*
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
*
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
* See the License for the specific language governing permissions and
|
16
|
+
* limitations under the License.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include "sigar.h"
|
20
|
+
#include "sigar_private.h"
|
21
|
+
#include "sigar_util.h"
|
22
|
+
#include "sigar_os.h"
|
23
|
+
|
24
|
+
#include <net/if.h>
|
25
|
+
#include <sys/dk.h>
|
26
|
+
#ifndef __ia64__
|
27
|
+
#include <sys/lwp.h>
|
28
|
+
#endif
|
29
|
+
#include <sys/ioctl.h>
|
30
|
+
#include <sys/stat.h>
|
31
|
+
#include <errno.h>
|
32
|
+
|
33
|
+
#ifdef _PSTAT64
|
34
|
+
typedef int64_t pstat_int_t;
|
35
|
+
#else
|
36
|
+
typedef int32_t pstat_int_t;
|
37
|
+
#endif
|
38
|
+
|
39
|
+
int sigar_os_open(sigar_t **sigar)
|
40
|
+
{
|
41
|
+
*sigar = malloc(sizeof(**sigar));
|
42
|
+
|
43
|
+
/* does not change while system is running */
|
44
|
+
pstat_getstatic(&(*sigar)->pstatic,
|
45
|
+
sizeof((*sigar)->pstatic),
|
46
|
+
1, 0);
|
47
|
+
|
48
|
+
(*sigar)->ticks = sysconf(_SC_CLK_TCK);
|
49
|
+
|
50
|
+
(*sigar)->last_pid = -1;
|
51
|
+
|
52
|
+
(*sigar)->pinfo = NULL;
|
53
|
+
|
54
|
+
(*sigar)->mib = -1;
|
55
|
+
|
56
|
+
return SIGAR_OK;
|
57
|
+
|
58
|
+
}
|
59
|
+
|
60
|
+
int sigar_os_close(sigar_t *sigar)
|
61
|
+
{
|
62
|
+
if (sigar->pinfo) {
|
63
|
+
free(sigar->pinfo);
|
64
|
+
}
|
65
|
+
if (sigar->mib >= 0) {
|
66
|
+
close_mib(sigar->mib);
|
67
|
+
}
|
68
|
+
free(sigar);
|
69
|
+
return SIGAR_OK;
|
70
|
+
}
|
71
|
+
|
72
|
+
char *sigar_os_error_string(sigar_t *sigar, int err)
|
73
|
+
{
|
74
|
+
return NULL;
|
75
|
+
}
|
76
|
+
|
77
|
+
int sigar_mem_get(sigar_t *sigar, sigar_mem_t *mem)
|
78
|
+
{
|
79
|
+
struct pst_dynamic stats;
|
80
|
+
struct pst_vminfo vminfo;
|
81
|
+
sigar_uint64_t pagesize = sigar->pstatic.page_size;
|
82
|
+
sigar_uint64_t kern;
|
83
|
+
|
84
|
+
mem->total = sigar->pstatic.physical_memory * pagesize;
|
85
|
+
|
86
|
+
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
87
|
+
|
88
|
+
mem->free = stats.psd_free * pagesize;
|
89
|
+
mem->used = mem->total - mem->free;
|
90
|
+
|
91
|
+
pstat_getvminfo(&vminfo, sizeof(vminfo), 1, 0);
|
92
|
+
|
93
|
+
/* "kernel dynamic memory" */
|
94
|
+
kern = vminfo.psv_kern_dynmem * pagesize;
|
95
|
+
mem->actual_free = mem->free + kern;
|
96
|
+
mem->actual_used = mem->used - kern;
|
97
|
+
|
98
|
+
sigar_mem_calc_ram(sigar, mem);
|
99
|
+
|
100
|
+
return SIGAR_OK;
|
101
|
+
}
|
102
|
+
|
103
|
+
int sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap)
|
104
|
+
{
|
105
|
+
struct pst_swapinfo swapinfo;
|
106
|
+
struct pst_vminfo vminfo;
|
107
|
+
int i=0;
|
108
|
+
|
109
|
+
swap->total = swap->free = 0;
|
110
|
+
|
111
|
+
while (pstat_getswap(&swapinfo, sizeof(swapinfo), 1, i++) > 0) {
|
112
|
+
swapinfo.pss_nfpgs *= 4; /* nfpgs is in 512 byte blocks */
|
113
|
+
|
114
|
+
if (swapinfo.pss_nblksenabled == 0) {
|
115
|
+
swapinfo.pss_nblksenabled = swapinfo.pss_nfpgs;
|
116
|
+
}
|
117
|
+
|
118
|
+
swap->total += swapinfo.pss_nblksenabled;
|
119
|
+
swap->free += swapinfo.pss_nfpgs;
|
120
|
+
}
|
121
|
+
|
122
|
+
swap->used = swap->total - swap->free;
|
123
|
+
|
124
|
+
pstat_getvminfo(&vminfo, sizeof(vminfo), 1, 0);
|
125
|
+
|
126
|
+
swap->page_in = vminfo.psv_spgin;
|
127
|
+
swap->page_out = vminfo.psv_spgout;
|
128
|
+
|
129
|
+
return SIGAR_OK;
|
130
|
+
}
|
131
|
+
|
132
|
+
static void get_cpu_metrics(sigar_t *sigar,
|
133
|
+
sigar_cpu_t *cpu,
|
134
|
+
pstat_int_t *cpu_time)
|
135
|
+
{
|
136
|
+
cpu->user = SIGAR_TICK2MSEC(cpu_time[CP_USER]);
|
137
|
+
|
138
|
+
cpu->sys = SIGAR_TICK2MSEC(cpu_time[CP_SYS] +
|
139
|
+
cpu_time[CP_SSYS]);
|
140
|
+
|
141
|
+
cpu->nice = SIGAR_TICK2MSEC(cpu_time[CP_NICE]);
|
142
|
+
|
143
|
+
cpu->idle = SIGAR_TICK2MSEC(cpu_time[CP_IDLE]);
|
144
|
+
|
145
|
+
cpu->wait = SIGAR_TICK2MSEC(cpu_time[CP_SWAIT] +
|
146
|
+
cpu_time[CP_BLOCK]);
|
147
|
+
|
148
|
+
cpu->irq = SIGAR_TICK2MSEC(cpu_time[CP_INTR]);
|
149
|
+
cpu->soft_irq = 0; /*N/A*/
|
150
|
+
cpu->stolen = 0; /*N/A*/
|
151
|
+
|
152
|
+
cpu->total =
|
153
|
+
cpu->user + cpu->sys + cpu->nice + cpu->idle + cpu->wait + cpu->irq;
|
154
|
+
}
|
155
|
+
|
156
|
+
int sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu)
|
157
|
+
{
|
158
|
+
struct pst_dynamic stats;
|
159
|
+
|
160
|
+
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
161
|
+
sigar->ncpu = stats.psd_proc_cnt;
|
162
|
+
|
163
|
+
get_cpu_metrics(sigar, cpu, stats.psd_cpu_time);
|
164
|
+
|
165
|
+
return SIGAR_OK;
|
166
|
+
}
|
167
|
+
|
168
|
+
int sigar_cpu_list_get(sigar_t *sigar, sigar_cpu_list_t *cpulist)
|
169
|
+
{
|
170
|
+
int i;
|
171
|
+
struct pst_dynamic stats;
|
172
|
+
|
173
|
+
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
174
|
+
sigar->ncpu = stats.psd_proc_cnt;
|
175
|
+
|
176
|
+
sigar_cpu_list_create(cpulist);
|
177
|
+
|
178
|
+
for (i=0; i<sigar->ncpu; i++) {
|
179
|
+
sigar_cpu_t *cpu;
|
180
|
+
struct pst_processor proc;
|
181
|
+
|
182
|
+
if (pstat_getprocessor(&proc, sizeof(proc), 1, i) < 0) {
|
183
|
+
continue;
|
184
|
+
}
|
185
|
+
|
186
|
+
SIGAR_CPU_LIST_GROW(cpulist);
|
187
|
+
|
188
|
+
cpu = &cpulist->data[cpulist->number++];
|
189
|
+
|
190
|
+
get_cpu_metrics(sigar, cpu, proc.psp_cpu_time);
|
191
|
+
}
|
192
|
+
|
193
|
+
return SIGAR_OK;
|
194
|
+
}
|
195
|
+
|
196
|
+
int sigar_uptime_get(sigar_t *sigar,
|
197
|
+
sigar_uptime_t *uptime)
|
198
|
+
{
|
199
|
+
uptime->uptime = time(NULL) - sigar->pstatic.boot_time;
|
200
|
+
|
201
|
+
return SIGAR_OK;
|
202
|
+
}
|
203
|
+
|
204
|
+
int sigar_loadavg_get(sigar_t *sigar,
|
205
|
+
sigar_loadavg_t *loadavg)
|
206
|
+
{
|
207
|
+
struct pst_dynamic stats;
|
208
|
+
|
209
|
+
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
210
|
+
|
211
|
+
loadavg->loadavg[0] = stats.psd_avg_1_min;
|
212
|
+
loadavg->loadavg[1] = stats.psd_avg_5_min;
|
213
|
+
loadavg->loadavg[2] = stats.psd_avg_15_min;
|
214
|
+
|
215
|
+
return SIGAR_OK;
|
216
|
+
}
|
217
|
+
|
218
|
+
#define PROC_ELTS 16
|
219
|
+
|
220
|
+
int sigar_os_proc_list_get(sigar_t *sigar,
|
221
|
+
sigar_proc_list_t *proclist)
|
222
|
+
{
|
223
|
+
int num, idx=0;
|
224
|
+
struct pst_status proctab[PROC_ELTS];
|
225
|
+
|
226
|
+
while ((num = pstat_getproc(proctab, sizeof(proctab[0]),
|
227
|
+
PROC_ELTS, idx)) > 0)
|
228
|
+
{
|
229
|
+
int i;
|
230
|
+
|
231
|
+
for (i=0; i<num; i++) {
|
232
|
+
SIGAR_PROC_LIST_GROW(proclist);
|
233
|
+
proclist->data[proclist->number++] =
|
234
|
+
proctab[i].pst_pid;
|
235
|
+
}
|
236
|
+
|
237
|
+
idx = proctab[num-1].pst_idx + 1;
|
238
|
+
}
|
239
|
+
|
240
|
+
if (proclist->number == 0) {
|
241
|
+
return errno;
|
242
|
+
}
|
243
|
+
|
244
|
+
return SIGAR_OK;
|
245
|
+
}
|
246
|
+
|
247
|
+
static int sigar_pstat_getproc(sigar_t *sigar, sigar_pid_t pid)
|
248
|
+
{
|
249
|
+
int status, num;
|
250
|
+
time_t timenow = time(NULL);
|
251
|
+
|
252
|
+
if (sigar->pinfo == NULL) {
|
253
|
+
sigar->pinfo = malloc(sizeof(*sigar->pinfo));
|
254
|
+
}
|
255
|
+
|
256
|
+
if (sigar->last_pid == pid) {
|
257
|
+
if ((timenow - sigar->last_getprocs) < SIGAR_LAST_PROC_EXPIRE) {
|
258
|
+
return SIGAR_OK;
|
259
|
+
}
|
260
|
+
}
|
261
|
+
|
262
|
+
sigar->last_pid = pid;
|
263
|
+
sigar->last_getprocs = timenow;
|
264
|
+
|
265
|
+
if (pstat_getproc(sigar->pinfo,
|
266
|
+
sizeof(*sigar->pinfo),
|
267
|
+
0, pid) == -1)
|
268
|
+
{
|
269
|
+
return errno;
|
270
|
+
}
|
271
|
+
|
272
|
+
return SIGAR_OK;
|
273
|
+
}
|
274
|
+
|
275
|
+
int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid,
|
276
|
+
sigar_proc_mem_t *procmem)
|
277
|
+
{
|
278
|
+
int pagesize = sigar->pstatic.page_size;
|
279
|
+
int status = sigar_pstat_getproc(sigar, pid);
|
280
|
+
struct pst_status *pinfo = sigar->pinfo;
|
281
|
+
|
282
|
+
if (status != SIGAR_OK) {
|
283
|
+
return status;
|
284
|
+
}
|
285
|
+
|
286
|
+
procmem->size =
|
287
|
+
pinfo->pst_vtsize + /* text */
|
288
|
+
pinfo->pst_vdsize + /* data */
|
289
|
+
pinfo->pst_vssize + /* stack */
|
290
|
+
pinfo->pst_vshmsize + /* shared memory */
|
291
|
+
pinfo->pst_vmmsize + /* mem-mapped files */
|
292
|
+
pinfo->pst_vusize + /* U-Area & K-Stack */
|
293
|
+
pinfo->pst_viosize; /* I/O dev mapping */
|
294
|
+
|
295
|
+
procmem->size *= pagesize;
|
296
|
+
|
297
|
+
procmem->resident = pinfo->pst_rssize * pagesize;
|
298
|
+
|
299
|
+
procmem->share = pinfo->pst_vshmsize * pagesize;
|
300
|
+
|
301
|
+
procmem->minor_faults = pinfo->pst_minorfaults;
|
302
|
+
procmem->major_faults = pinfo->pst_majorfaults;
|
303
|
+
procmem->page_faults =
|
304
|
+
procmem->minor_faults +
|
305
|
+
procmem->major_faults;
|
306
|
+
|
307
|
+
return SIGAR_OK;
|
308
|
+
}
|
309
|
+
|
310
|
+
int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid,
|
311
|
+
sigar_proc_cred_t *proccred)
|
312
|
+
{
|
313
|
+
int status = sigar_pstat_getproc(sigar, pid);
|
314
|
+
struct pst_status *pinfo = sigar->pinfo;
|
315
|
+
|
316
|
+
if (status != SIGAR_OK) {
|
317
|
+
return status;
|
318
|
+
}
|
319
|
+
|
320
|
+
proccred->uid = pinfo->pst_uid;
|
321
|
+
proccred->gid = pinfo->pst_gid;
|
322
|
+
proccred->euid = pinfo->pst_euid;
|
323
|
+
proccred->egid = pinfo->pst_egid;
|
324
|
+
|
325
|
+
return SIGAR_OK;
|
326
|
+
}
|
327
|
+
|
328
|
+
int sigar_proc_time_get(sigar_t *sigar, sigar_pid_t pid,
|
329
|
+
sigar_proc_time_t *proctime)
|
330
|
+
{
|
331
|
+
int status = sigar_pstat_getproc(sigar, pid);
|
332
|
+
struct pst_status *pinfo = sigar->pinfo;
|
333
|
+
|
334
|
+
if (status != SIGAR_OK) {
|
335
|
+
return status;
|
336
|
+
}
|
337
|
+
|
338
|
+
proctime->start_time = pinfo->pst_start;
|
339
|
+
proctime->start_time *= SIGAR_MSEC;
|
340
|
+
proctime->user = pinfo->pst_utime * SIGAR_MSEC;
|
341
|
+
proctime->sys = pinfo->pst_stime * SIGAR_MSEC;
|
342
|
+
proctime->total = proctime->user + proctime->sys;
|
343
|
+
|
344
|
+
return SIGAR_OK;
|
345
|
+
}
|
346
|
+
|
347
|
+
int sigar_proc_state_get(sigar_t *sigar, sigar_pid_t pid,
|
348
|
+
sigar_proc_state_t *procstate)
|
349
|
+
{
|
350
|
+
int status = sigar_pstat_getproc(sigar, pid);
|
351
|
+
struct pst_status *pinfo = sigar->pinfo;
|
352
|
+
|
353
|
+
if (status != SIGAR_OK) {
|
354
|
+
return status;
|
355
|
+
}
|
356
|
+
|
357
|
+
|
358
|
+
SIGAR_SSTRCPY(procstate->name, pinfo->pst_ucomm);
|
359
|
+
procstate->ppid = pinfo->pst_ppid;
|
360
|
+
procstate->tty = makedev(pinfo->pst_term.psd_major,
|
361
|
+
pinfo->pst_term.psd_minor);
|
362
|
+
procstate->priority = pinfo->pst_pri;
|
363
|
+
procstate->nice = pinfo->pst_nice;
|
364
|
+
procstate->threads = pinfo->pst_nlwps;
|
365
|
+
procstate->processor = pinfo->pst_procnum;
|
366
|
+
|
367
|
+
/* cast to prevent compiler warning: */
|
368
|
+
/* Case label too big for the type of the switch expression */
|
369
|
+
switch ((int32_t)pinfo->pst_stat) {
|
370
|
+
case PS_SLEEP:
|
371
|
+
procstate->state = 'S';
|
372
|
+
break;
|
373
|
+
case PS_RUN:
|
374
|
+
procstate->state = 'R';
|
375
|
+
break;
|
376
|
+
case PS_STOP:
|
377
|
+
procstate->state = 'T';
|
378
|
+
break;
|
379
|
+
case PS_ZOMBIE:
|
380
|
+
procstate->state = 'Z';
|
381
|
+
break;
|
382
|
+
case PS_IDLE:
|
383
|
+
procstate->state = 'D';
|
384
|
+
break;
|
385
|
+
}
|
386
|
+
|
387
|
+
return SIGAR_OK;
|
388
|
+
}
|
389
|
+
|
390
|
+
int sigar_os_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
|
391
|
+
sigar_proc_args_t *procargs)
|
392
|
+
{
|
393
|
+
char *args, *arg;
|
394
|
+
#ifdef PSTAT_GETCOMMANDLINE
|
395
|
+
char buf[1024]; /* kernel limit */
|
396
|
+
|
397
|
+
# ifdef pstat_getcommandline /* 11i v2 + */
|
398
|
+
if (pstat_getcommandline(buf, sizeof(buf), sizeof(buf[0]), pid) == -1) {
|
399
|
+
return errno;
|
400
|
+
}
|
401
|
+
# else
|
402
|
+
union pstun pu;
|
403
|
+
|
404
|
+
pu.pst_command = buf;
|
405
|
+
if (pstat(PSTAT_GETCOMMANDLINE, pu, sizeof(buf), sizeof(buf[0]), pid) == -1) {
|
406
|
+
return errno;
|
407
|
+
}
|
408
|
+
# endif /* pstat_getcommandline */
|
409
|
+
|
410
|
+
args = buf;
|
411
|
+
#else
|
412
|
+
struct pst_status status;
|
413
|
+
|
414
|
+
if (pstat_getproc(&status, sizeof(status), 0, pid) == -1) {
|
415
|
+
return errno;
|
416
|
+
}
|
417
|
+
|
418
|
+
args = status.pst_cmd;
|
419
|
+
#endif
|
420
|
+
|
421
|
+
while (*args && (arg = sigar_getword(&args, ' '))) {
|
422
|
+
SIGAR_PROC_ARGS_GROW(procargs);
|
423
|
+
procargs->data[procargs->number++] = arg;
|
424
|
+
}
|
425
|
+
|
426
|
+
return SIGAR_OK;
|
427
|
+
}
|
428
|
+
|
429
|
+
int sigar_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
430
|
+
sigar_proc_env_t *procenv)
|
431
|
+
{
|
432
|
+
return SIGAR_ENOTIMPL;
|
433
|
+
}
|
434
|
+
|
435
|
+
int sigar_proc_fd_get(sigar_t *sigar, sigar_pid_t pid,
|
436
|
+
sigar_proc_fd_t *procfd)
|
437
|
+
{
|
438
|
+
struct pst_status status;
|
439
|
+
int idx=0, n;
|
440
|
+
struct pst_fileinfo2 psf[16];
|
441
|
+
|
442
|
+
procfd->total = 0;
|
443
|
+
|
444
|
+
if (pstat_getproc(&status, sizeof(status), 0, pid) == -1) {
|
445
|
+
return errno;
|
446
|
+
}
|
447
|
+
|
448
|
+
/* HPUX 11.31 removed the deprecated pstat_getfile call */
|
449
|
+
while ((n = pstat_getfile2(psf, sizeof(psf[0]),
|
450
|
+
sizeof(psf)/sizeof(psf[0]),
|
451
|
+
idx, pid)) > 0)
|
452
|
+
{
|
453
|
+
procfd->total += n;
|
454
|
+
idx = psf[n-1].psf_fd + 1;
|
455
|
+
}
|
456
|
+
|
457
|
+
if (n == -1) {
|
458
|
+
return errno;
|
459
|
+
}
|
460
|
+
|
461
|
+
return SIGAR_OK;
|
462
|
+
}
|
463
|
+
|
464
|
+
int sigar_proc_exe_get(sigar_t *sigar, sigar_pid_t pid,
|
465
|
+
sigar_proc_exe_t *procexe)
|
466
|
+
{
|
467
|
+
#ifdef __pst_fid /* 11.11+ */
|
468
|
+
int rc;
|
469
|
+
struct pst_status status;
|
470
|
+
|
471
|
+
if (pstat_getproc(&status, sizeof(status), 0, pid) == -1) {
|
472
|
+
return errno;
|
473
|
+
}
|
474
|
+
|
475
|
+
rc = pstat_getpathname(procexe->cwd,
|
476
|
+
sizeof(procexe->cwd),
|
477
|
+
&status.pst_fid_cdir);
|
478
|
+
if (rc == -1) {
|
479
|
+
return errno;
|
480
|
+
}
|
481
|
+
|
482
|
+
rc = pstat_getpathname(procexe->name,
|
483
|
+
sizeof(procexe->name),
|
484
|
+
&status.pst_fid_text);
|
485
|
+
if (rc == -1) {
|
486
|
+
return errno;
|
487
|
+
}
|
488
|
+
|
489
|
+
rc = pstat_getpathname(procexe->root,
|
490
|
+
sizeof(procexe->root),
|
491
|
+
&status.pst_fid_rdir);
|
492
|
+
if (rc == -1) {
|
493
|
+
return errno;
|
494
|
+
}
|
495
|
+
|
496
|
+
return SIGAR_OK;
|
497
|
+
#else
|
498
|
+
return SIGAR_ENOTIMPL; /* 11.00 */
|
499
|
+
#endif
|
500
|
+
}
|
501
|
+
|
502
|
+
int sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid,
|
503
|
+
sigar_proc_modules_t *procmods)
|
504
|
+
{
|
505
|
+
return SIGAR_ENOTIMPL;
|
506
|
+
}
|
507
|
+
|
508
|
+
#define TIME_NSEC(t) \
|
509
|
+
(SIGAR_SEC2NANO((t).tv_sec) + (sigar_uint64_t)(t).tv_nsec)
|
510
|
+
|
511
|
+
int sigar_thread_cpu_get(sigar_t *sigar,
|
512
|
+
sigar_uint64_t id,
|
513
|
+
sigar_thread_cpu_t *cpu)
|
514
|
+
{
|
515
|
+
#ifdef __ia64__
|
516
|
+
/* XXX seems _lwp funcs were for solaris compat and dont exist
|
517
|
+
* on itanium. hp docs claim that have equiv functions,
|
518
|
+
* but wtf is it for _lwp_info?
|
519
|
+
*/
|
520
|
+
return SIGAR_ENOTIMPL;
|
521
|
+
#else
|
522
|
+
struct lwpinfo info;
|
523
|
+
|
524
|
+
if (id != 0) {
|
525
|
+
return SIGAR_ENOTIMPL;
|
526
|
+
}
|
527
|
+
|
528
|
+
_lwp_info(&info);
|
529
|
+
|
530
|
+
cpu->user = TIME_NSEC(info.lwp_utime);
|
531
|
+
cpu->sys = TIME_NSEC(info.lwp_stime);
|
532
|
+
cpu->total = TIME_NSEC(info.lwp_utime) + TIME_NSEC(info.lwp_stime);
|
533
|
+
|
534
|
+
return SIGAR_OK;
|
535
|
+
#endif
|
536
|
+
}
|
537
|
+
|
538
|
+
#include <mntent.h>
|
539
|
+
|
540
|
+
int sigar_os_fs_type_get(sigar_file_system_t *fsp)
|
541
|
+
{
|
542
|
+
char *type = fsp->sys_type_name;
|
543
|
+
|
544
|
+
switch (*type) {
|
545
|
+
case 'h':
|
546
|
+
if (strEQ(type, "hfs")) {
|
547
|
+
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
548
|
+
}
|
549
|
+
break;
|
550
|
+
case 'c':
|
551
|
+
if (strEQ(type, "cdfs")) {
|
552
|
+
fsp->type = SIGAR_FSTYPE_CDROM;
|
553
|
+
}
|
554
|
+
break;
|
555
|
+
}
|
556
|
+
|
557
|
+
return fsp->type;
|
558
|
+
}
|
559
|
+
|
560
|
+
int sigar_file_system_list_get(sigar_t *sigar,
|
561
|
+
sigar_file_system_list_t *fslist)
|
562
|
+
{
|
563
|
+
struct mntent *ent;
|
564
|
+
|
565
|
+
FILE *fp;
|
566
|
+
sigar_file_system_t *fsp;
|
567
|
+
|
568
|
+
if (!(fp = setmntent(MNT_MNTTAB, "r"))) {
|
569
|
+
return errno;
|
570
|
+
}
|
571
|
+
|
572
|
+
sigar_file_system_list_create(fslist);
|
573
|
+
|
574
|
+
while ((ent = getmntent(fp))) {
|
575
|
+
if ((*(ent->mnt_type) == 's') &&
|
576
|
+
strEQ(ent->mnt_type, "swap"))
|
577
|
+
{
|
578
|
+
/*
|
579
|
+
* in this case, devname == "...", for
|
580
|
+
* which statfs chokes on. so skip it.
|
581
|
+
* also notice hpux df command has no swap info.
|
582
|
+
*/
|
583
|
+
continue;
|
584
|
+
}
|
585
|
+
|
586
|
+
SIGAR_FILE_SYSTEM_LIST_GROW(fslist);
|
587
|
+
|
588
|
+
fsp = &fslist->data[fslist->number++];
|
589
|
+
|
590
|
+
SIGAR_SSTRCPY(fsp->dir_name, ent->mnt_dir);
|
591
|
+
SIGAR_SSTRCPY(fsp->dev_name, ent->mnt_fsname);
|
592
|
+
SIGAR_SSTRCPY(fsp->sys_type_name, ent->mnt_type);
|
593
|
+
SIGAR_SSTRCPY(fsp->options, ent->mnt_opts);
|
594
|
+
sigar_fs_type_init(fsp);
|
595
|
+
}
|
596
|
+
|
597
|
+
endmntent(fp);
|
598
|
+
|
599
|
+
return SIGAR_OK;
|
600
|
+
}
|
601
|
+
|
602
|
+
static int create_fsdev_cache(sigar_t *sigar)
|
603
|
+
{
|
604
|
+
sigar_file_system_list_t fslist;
|
605
|
+
int i;
|
606
|
+
int status =
|
607
|
+
sigar_file_system_list_get(sigar, &fslist);
|
608
|
+
|
609
|
+
if (status != SIGAR_OK) {
|
610
|
+
return status;
|
611
|
+
}
|
612
|
+
|
613
|
+
sigar->fsdev = sigar_cache_new(15);
|
614
|
+
|
615
|
+
for (i=0; i<fslist.number; i++) {
|
616
|
+
sigar_file_system_t *fsp = &fslist.data[i];
|
617
|
+
|
618
|
+
if (fsp->type == SIGAR_FSTYPE_LOCAL_DISK) {
|
619
|
+
sigar_cache_entry_t *ent;
|
620
|
+
struct stat sb;
|
621
|
+
|
622
|
+
if (stat(fsp->dir_name, &sb) < 0) {
|
623
|
+
continue;
|
624
|
+
}
|
625
|
+
|
626
|
+
ent = sigar_cache_get(sigar->fsdev, SIGAR_FSDEV_ID(sb));
|
627
|
+
ent->value = strdup(fsp->dev_name);
|
628
|
+
}
|
629
|
+
}
|
630
|
+
|
631
|
+
return SIGAR_OK;
|
632
|
+
}
|
633
|
+
|
634
|
+
int sigar_disk_usage_get(sigar_t *sigar, const char *name,
|
635
|
+
sigar_disk_usage_t *usage)
|
636
|
+
{
|
637
|
+
return SIGAR_ENOTIMPL;
|
638
|
+
}
|
639
|
+
|
640
|
+
int sigar_file_system_usage_get(sigar_t *sigar,
|
641
|
+
const char *dirname,
|
642
|
+
sigar_file_system_usage_t *fsusage)
|
643
|
+
{
|
644
|
+
struct stat sb;
|
645
|
+
int status = sigar_statvfs(sigar, dirname, fsusage);
|
646
|
+
|
647
|
+
if (status != SIGAR_OK) {
|
648
|
+
return status;
|
649
|
+
}
|
650
|
+
|
651
|
+
fsusage->use_percent = sigar_file_system_usage_calc_used(sigar, fsusage);
|
652
|
+
|
653
|
+
SIGAR_DISK_STATS_INIT(&fsusage->disk);
|
654
|
+
|
655
|
+
if (!sigar->fsdev) {
|
656
|
+
if (create_fsdev_cache(sigar) != SIGAR_OK) {
|
657
|
+
return SIGAR_OK;
|
658
|
+
}
|
659
|
+
}
|
660
|
+
|
661
|
+
if (stat(dirname, &sb) == 0) {
|
662
|
+
sigar_cache_entry_t *ent;
|
663
|
+
struct pst_lvinfo lv;
|
664
|
+
struct stat devsb;
|
665
|
+
char *devname;
|
666
|
+
int retval;
|
667
|
+
|
668
|
+
ent = sigar_cache_get(sigar->fsdev, SIGAR_FSDEV_ID(sb));
|
669
|
+
if (ent->value == NULL) {
|
670
|
+
return SIGAR_OK;
|
671
|
+
}
|
672
|
+
|
673
|
+
if (stat((char *)ent->value, &devsb) < 0) {
|
674
|
+
return SIGAR_OK;
|
675
|
+
}
|
676
|
+
|
677
|
+
retval = pstat_getlv(&lv, sizeof(lv), 0, (int)devsb.st_rdev);
|
678
|
+
|
679
|
+
if (retval == 1) {
|
680
|
+
fsusage->disk.reads = lv.psl_rxfer;
|
681
|
+
fsusage->disk.writes = lv.psl_wxfer;
|
682
|
+
fsusage->disk.read_bytes = lv.psl_rcount;
|
683
|
+
fsusage->disk.write_bytes = lv.psl_wcount;
|
684
|
+
fsusage->disk.queue = SIGAR_FIELD_NOTIMPL;
|
685
|
+
}
|
686
|
+
}
|
687
|
+
|
688
|
+
return SIGAR_OK;
|
689
|
+
}
|
690
|
+
|
691
|
+
int sigar_cpu_info_list_get(sigar_t *sigar,
|
692
|
+
sigar_cpu_info_list_t *cpu_infos)
|
693
|
+
{
|
694
|
+
int i;
|
695
|
+
struct pst_dynamic stats;
|
696
|
+
|
697
|
+
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
698
|
+
sigar->ncpu = stats.psd_proc_cnt;
|
699
|
+
|
700
|
+
sigar_cpu_info_list_create(cpu_infos);
|
701
|
+
|
702
|
+
for (i=0; i<sigar->ncpu; i++) {
|
703
|
+
sigar_cpu_info_t *info;
|
704
|
+
struct pst_processor proc;
|
705
|
+
|
706
|
+
if (pstat_getprocessor(&proc, sizeof(proc), 1, i) < 0) {
|
707
|
+
perror("pstat_getprocessor");
|
708
|
+
continue;
|
709
|
+
}
|
710
|
+
|
711
|
+
SIGAR_CPU_INFO_LIST_GROW(cpu_infos);
|
712
|
+
|
713
|
+
info = &cpu_infos->data[cpu_infos->number++];
|
714
|
+
|
715
|
+
info->total_cores = sigar->ncpu;
|
716
|
+
info->cores_per_socket = 1; /*XXX*/
|
717
|
+
info->total_sockets = sigar->ncpu; /*XXX*/
|
718
|
+
|
719
|
+
#ifdef __ia64__
|
720
|
+
SIGAR_SSTRCPY(info->vendor, "Intel"); /*XXX*/
|
721
|
+
SIGAR_SSTRCPY(info->model, "Itanium"); /*XXX*/
|
722
|
+
#else
|
723
|
+
SIGAR_SSTRCPY(info->vendor, "HP"); /*XXX*/
|
724
|
+
SIGAR_SSTRCPY(info->model, "PA RISC"); /*XXX*/
|
725
|
+
#endif
|
726
|
+
#ifdef PSP_MAX_CACHE_LEVELS /* 11.31+; see SIGAR-196 */
|
727
|
+
info->mhz = proc.psp_cpu_frequency / 1000000;
|
728
|
+
#else
|
729
|
+
info->mhz = sigar->ticks * proc.psp_iticksperclktick / 1000000;
|
730
|
+
#endif
|
731
|
+
info->cache_size = SIGAR_FIELD_NOTIMPL; /*XXX*/
|
732
|
+
}
|
733
|
+
|
734
|
+
return SIGAR_OK;
|
735
|
+
}
|
736
|
+
|
737
|
+
static int sigar_get_mib_info(sigar_t *sigar,
|
738
|
+
struct nmparms *parms)
|
739
|
+
{
|
740
|
+
if (sigar->mib < 0) {
|
741
|
+
if ((sigar->mib = open_mib("/dev/ip", O_RDONLY, 0, 0)) < 0) {
|
742
|
+
return errno;
|
743
|
+
}
|
744
|
+
}
|
745
|
+
return get_mib_info(sigar->mib, parms);
|
746
|
+
}
|
747
|
+
|
748
|
+
/* wrapper around get_physical_stat() */
|
749
|
+
static int sigar_get_physical_stat(sigar_t *sigar, int *count)
|
750
|
+
{
|
751
|
+
int status;
|
752
|
+
unsigned int len;
|
753
|
+
struct nmparms parms;
|
754
|
+
|
755
|
+
len = sizeof(*count);
|
756
|
+
parms.objid = ID_ifNumber;
|
757
|
+
parms.buffer = count;
|
758
|
+
parms.len = &len;
|
759
|
+
|
760
|
+
if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) {
|
761
|
+
return status;
|
762
|
+
}
|
763
|
+
|
764
|
+
len = sizeof(nmapi_phystat) * *count;
|
765
|
+
|
766
|
+
if (sigar->ifconf_len < len) {
|
767
|
+
sigar->ifconf_buf = realloc(sigar->ifconf_buf, len);
|
768
|
+
sigar->ifconf_len = len;
|
769
|
+
}
|
770
|
+
|
771
|
+
if (get_physical_stat(sigar->ifconf_buf, &len) < 0) {
|
772
|
+
return errno;
|
773
|
+
}
|
774
|
+
else {
|
775
|
+
return SIGAR_OK;
|
776
|
+
}
|
777
|
+
}
|
778
|
+
|
779
|
+
#define SIGAR_IF_NAMESIZE 16
|
780
|
+
/* hpux if_indextoname() does not work as advertised in 11.11 */
|
781
|
+
static int sigar_if_indextoname(sigar_t *sigar,
|
782
|
+
char *name,
|
783
|
+
int index)
|
784
|
+
{
|
785
|
+
int i, status, count;
|
786
|
+
nmapi_phystat *stat;
|
787
|
+
|
788
|
+
if ((status = sigar_get_physical_stat(sigar, &count) != SIGAR_OK)) {
|
789
|
+
return status;
|
790
|
+
}
|
791
|
+
|
792
|
+
for (i=0, stat = (nmapi_phystat *)sigar->ifconf_buf;
|
793
|
+
i<count;
|
794
|
+
i++, stat++)
|
795
|
+
{
|
796
|
+
if (stat->if_entry.ifIndex == index) {
|
797
|
+
strncpy(name, stat->nm_device, SIGAR_IF_NAMESIZE);
|
798
|
+
return SIGAR_OK;
|
799
|
+
}
|
800
|
+
}
|
801
|
+
|
802
|
+
return ENXIO;
|
803
|
+
}
|
804
|
+
|
805
|
+
int sigar_net_route_list_get(sigar_t *sigar,
|
806
|
+
sigar_net_route_list_t *routelist)
|
807
|
+
{
|
808
|
+
int status, count, i;
|
809
|
+
unsigned int len;
|
810
|
+
struct nmparms parms;
|
811
|
+
mib_ipRouteEnt *routes;
|
812
|
+
sigar_net_route_t *route;
|
813
|
+
|
814
|
+
len = sizeof(count);
|
815
|
+
parms.objid = ID_ipRouteNumEnt;
|
816
|
+
parms.buffer = &count;
|
817
|
+
parms.len = &len;
|
818
|
+
|
819
|
+
if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) {
|
820
|
+
return status;
|
821
|
+
}
|
822
|
+
|
823
|
+
len = count * sizeof(*routes);
|
824
|
+
routes = malloc(len);
|
825
|
+
|
826
|
+
parms.objid = ID_ipRouteTable;
|
827
|
+
parms.buffer = routes;
|
828
|
+
parms.len = &len;
|
829
|
+
|
830
|
+
if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) {
|
831
|
+
free(routes);
|
832
|
+
return status;
|
833
|
+
}
|
834
|
+
|
835
|
+
routelist->size = routelist->number = 0;
|
836
|
+
|
837
|
+
sigar_net_route_list_create(routelist);
|
838
|
+
|
839
|
+
for (i=0; i<count; i++) {
|
840
|
+
mib_ipRouteEnt *ent = &routes[i];
|
841
|
+
|
842
|
+
SIGAR_NET_ROUTE_LIST_GROW(routelist);
|
843
|
+
|
844
|
+
route = &routelist->data[routelist->number++];
|
845
|
+
SIGAR_ZERO(route); /* XXX: other fields */
|
846
|
+
|
847
|
+
sigar_net_address_set(route->destination,
|
848
|
+
ent->Dest);
|
849
|
+
|
850
|
+
sigar_net_address_set(route->mask,
|
851
|
+
ent->Mask);
|
852
|
+
|
853
|
+
sigar_net_address_set(route->gateway,
|
854
|
+
ent->NextHop);
|
855
|
+
|
856
|
+
sigar_if_indextoname(sigar, route->ifname, ent->IfIndex);
|
857
|
+
|
858
|
+
route->flags = SIGAR_RTF_UP;
|
859
|
+
if ((ent->Dest == 0) &&
|
860
|
+
(ent->Mask == 0))
|
861
|
+
{
|
862
|
+
route->flags |= SIGAR_RTF_GATEWAY;
|
863
|
+
}
|
864
|
+
}
|
865
|
+
|
866
|
+
free(routes);
|
867
|
+
|
868
|
+
return SIGAR_OK;
|
869
|
+
}
|
870
|
+
|
871
|
+
static int get_mib_ifstat(sigar_t *sigar,
|
872
|
+
const char *name,
|
873
|
+
mib_ifEntry *mib)
|
874
|
+
{
|
875
|
+
int i, status, count;
|
876
|
+
nmapi_phystat *stat;
|
877
|
+
|
878
|
+
if ((status = sigar_get_physical_stat(sigar, &count) != SIGAR_OK)) {
|
879
|
+
return status;
|
880
|
+
}
|
881
|
+
|
882
|
+
for (i=0, stat = (nmapi_phystat *)sigar->ifconf_buf;
|
883
|
+
i<count;
|
884
|
+
i++, stat++)
|
885
|
+
{
|
886
|
+
if (strEQ(stat->nm_device, name)) {
|
887
|
+
memcpy(mib, &stat->if_entry, sizeof(*mib));
|
888
|
+
return SIGAR_OK;
|
889
|
+
}
|
890
|
+
}
|
891
|
+
|
892
|
+
return ENXIO;
|
893
|
+
}
|
894
|
+
|
895
|
+
int sigar_net_interface_stat_get(sigar_t *sigar, const char *name,
|
896
|
+
sigar_net_interface_stat_t *ifstat)
|
897
|
+
{
|
898
|
+
int status;
|
899
|
+
mib_ifEntry mib;
|
900
|
+
|
901
|
+
status = get_mib_ifstat(sigar, name, &mib);
|
902
|
+
|
903
|
+
if (status != SIGAR_OK) {
|
904
|
+
return status;
|
905
|
+
}
|
906
|
+
|
907
|
+
ifstat->rx_bytes = mib.ifInOctets;
|
908
|
+
ifstat->rx_packets = mib.ifInUcastPkts + mib.ifInNUcastPkts;
|
909
|
+
ifstat->rx_errors = mib.ifInErrors;
|
910
|
+
ifstat->rx_dropped = mib.ifInDiscards;
|
911
|
+
ifstat->rx_overruns = SIGAR_FIELD_NOTIMPL;
|
912
|
+
ifstat->rx_frame = SIGAR_FIELD_NOTIMPL;
|
913
|
+
|
914
|
+
ifstat->tx_bytes = mib.ifOutOctets;
|
915
|
+
ifstat->tx_packets = mib.ifOutUcastPkts + mib.ifOutNUcastPkts;
|
916
|
+
ifstat->tx_errors = mib.ifOutErrors;
|
917
|
+
ifstat->tx_dropped = mib.ifOutDiscards;
|
918
|
+
ifstat->tx_overruns = SIGAR_FIELD_NOTIMPL;
|
919
|
+
ifstat->tx_collisions = SIGAR_FIELD_NOTIMPL;
|
920
|
+
ifstat->tx_carrier = SIGAR_FIELD_NOTIMPL;
|
921
|
+
|
922
|
+
ifstat->speed = mib.ifSpeed;
|
923
|
+
|
924
|
+
return SIGAR_OK;
|
925
|
+
}
|
926
|
+
|
927
|
+
int sigar_net_interface_ipv6_config_get(sigar_t *sigar, const char *name,
|
928
|
+
sigar_net_interface_config_t *ifconfig)
|
929
|
+
{
|
930
|
+
int sock;
|
931
|
+
struct if_laddrreq iflr;
|
932
|
+
|
933
|
+
if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
|
934
|
+
return errno;
|
935
|
+
}
|
936
|
+
|
937
|
+
SIGAR_SSTRCPY(iflr.iflr_name, name);
|
938
|
+
|
939
|
+
if (ioctl(sock, SIOCGLIFADDR, &iflr) == 0) {
|
940
|
+
struct in6_addr *addr = SIGAR_SIN6_ADDR(&iflr.iflr_addr);
|
941
|
+
|
942
|
+
sigar_net_address6_set(ifconfig->address6, addr);
|
943
|
+
sigar_net_interface_scope6_set(ifconfig, addr);
|
944
|
+
|
945
|
+
if (ioctl(sock, SIOCGLIFNETMASK, &iflr) == 0) {
|
946
|
+
addr = SIGAR_SIN6_ADDR(&iflr.iflr_addr);
|
947
|
+
ifconfig->prefix6_length = 10; /*XXX*/
|
948
|
+
}
|
949
|
+
}
|
950
|
+
|
951
|
+
close(sock);
|
952
|
+
return SIGAR_OK;
|
953
|
+
}
|
954
|
+
|
955
|
+
static int net_conn_get_udp_listen(sigar_net_connection_walker_t *walker)
|
956
|
+
{
|
957
|
+
sigar_t *sigar = walker->sigar;
|
958
|
+
int flags = walker->flags;
|
959
|
+
int status, count, i;
|
960
|
+
unsigned int len;
|
961
|
+
mib_udpLsnEnt *entries;
|
962
|
+
struct nmparms parms;
|
963
|
+
|
964
|
+
len = sizeof(count);
|
965
|
+
parms.objid = ID_udpLsnNumEnt;
|
966
|
+
parms.buffer = &count;
|
967
|
+
parms.len = &len;
|
968
|
+
|
969
|
+
if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) {
|
970
|
+
return status;
|
971
|
+
}
|
972
|
+
|
973
|
+
if (count <= 0) {
|
974
|
+
return ENOENT;
|
975
|
+
}
|
976
|
+
|
977
|
+
len = count * sizeof(*entries);
|
978
|
+
entries = malloc(len);
|
979
|
+
parms.objid = ID_udpLsnTable;
|
980
|
+
parms.buffer = entries;
|
981
|
+
parms.len = &len;
|
982
|
+
|
983
|
+
if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) {
|
984
|
+
free(entries);
|
985
|
+
return status;
|
986
|
+
}
|
987
|
+
|
988
|
+
for (i=0; i<count; i++) {
|
989
|
+
sigar_net_connection_t conn;
|
990
|
+
mib_udpLsnEnt *entry = &entries[i];
|
991
|
+
|
992
|
+
SIGAR_ZERO(&conn);
|
993
|
+
|
994
|
+
conn.type = SIGAR_NETCONN_UDP;
|
995
|
+
|
996
|
+
conn.local_port = (unsigned short)entry->LocalPort;
|
997
|
+
conn.remote_port = 0;
|
998
|
+
|
999
|
+
sigar_net_address_set(conn.local_address,
|
1000
|
+
entry->LocalAddress);
|
1001
|
+
|
1002
|
+
sigar_net_address_set(conn.remote_address, 0);
|
1003
|
+
|
1004
|
+
conn.send_queue = conn.receive_queue = SIGAR_FIELD_NOTIMPL;
|
1005
|
+
|
1006
|
+
if (walker->add_connection(walker, &conn) != SIGAR_OK) {
|
1007
|
+
break;
|
1008
|
+
}
|
1009
|
+
}
|
1010
|
+
|
1011
|
+
free(entries);
|
1012
|
+
return SIGAR_OK;
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
static int net_conn_get_udp(sigar_net_connection_walker_t *walker)
|
1016
|
+
{
|
1017
|
+
int status = SIGAR_OK;
|
1018
|
+
|
1019
|
+
if (walker->flags & SIGAR_NETCONN_SERVER) {
|
1020
|
+
status = net_conn_get_udp_listen(walker);
|
1021
|
+
}
|
1022
|
+
|
1023
|
+
return status;
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
#define IS_TCP_SERVER(state, flags) \
|
1027
|
+
((flags & SIGAR_NETCONN_SERVER) && (state == TCLISTEN))
|
1028
|
+
|
1029
|
+
#define IS_TCP_CLIENT(state, flags) \
|
1030
|
+
((flags & SIGAR_NETCONN_CLIENT) && (state != TCLISTEN))
|
1031
|
+
|
1032
|
+
static int net_conn_get_tcp(sigar_net_connection_walker_t *walker)
|
1033
|
+
{
|
1034
|
+
sigar_t *sigar = walker->sigar;
|
1035
|
+
int flags = walker->flags;
|
1036
|
+
int status, count, i;
|
1037
|
+
unsigned int len;
|
1038
|
+
mib_tcpConnEnt *entries;
|
1039
|
+
struct nmparms parms;
|
1040
|
+
|
1041
|
+
len = sizeof(count);
|
1042
|
+
parms.objid = ID_tcpConnNumEnt;
|
1043
|
+
parms.buffer = &count;
|
1044
|
+
parms.len = &len;
|
1045
|
+
|
1046
|
+
if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) {
|
1047
|
+
return status;
|
1048
|
+
}
|
1049
|
+
|
1050
|
+
if (count <= 0) {
|
1051
|
+
return ENOENT;
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
len = count * sizeof(*entries);
|
1055
|
+
entries = malloc(len);
|
1056
|
+
parms.objid = ID_tcpConnTable;
|
1057
|
+
parms.buffer = entries;
|
1058
|
+
parms.len = &len;
|
1059
|
+
|
1060
|
+
if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) {
|
1061
|
+
free(entries);
|
1062
|
+
return status;
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
for (i=0; i<count; i++) {
|
1066
|
+
sigar_net_connection_t conn;
|
1067
|
+
mib_tcpConnEnt *entry = &entries[i];
|
1068
|
+
int state = entry->State;
|
1069
|
+
|
1070
|
+
if (!(IS_TCP_SERVER(state, flags) ||
|
1071
|
+
IS_TCP_CLIENT(state, flags)))
|
1072
|
+
{
|
1073
|
+
continue;
|
1074
|
+
}
|
1075
|
+
|
1076
|
+
SIGAR_ZERO(&conn);
|
1077
|
+
|
1078
|
+
switch (state) {
|
1079
|
+
case TCCLOSED:
|
1080
|
+
conn.state = SIGAR_TCP_CLOSE;
|
1081
|
+
break;
|
1082
|
+
case TCLISTEN:
|
1083
|
+
conn.state = SIGAR_TCP_LISTEN;
|
1084
|
+
break;
|
1085
|
+
case TCSYNSENT:
|
1086
|
+
conn.state = SIGAR_TCP_SYN_SENT;
|
1087
|
+
break;
|
1088
|
+
case TCSYNRECEIVE:
|
1089
|
+
conn.state = SIGAR_TCP_SYN_RECV;
|
1090
|
+
break;
|
1091
|
+
case TCESTABLISED:
|
1092
|
+
conn.state = SIGAR_TCP_ESTABLISHED;
|
1093
|
+
break;
|
1094
|
+
case TCFINWAIT1:
|
1095
|
+
conn.state = SIGAR_TCP_FIN_WAIT1;
|
1096
|
+
break;
|
1097
|
+
case TCFINWAIT2:
|
1098
|
+
conn.state = SIGAR_TCP_FIN_WAIT2;
|
1099
|
+
break;
|
1100
|
+
case TCCLOSEWAIT:
|
1101
|
+
conn.state = SIGAR_TCP_CLOSE_WAIT;
|
1102
|
+
break;
|
1103
|
+
case TCCLOSING:
|
1104
|
+
conn.state = SIGAR_TCP_CLOSING;
|
1105
|
+
break;
|
1106
|
+
case TCLASTACK:
|
1107
|
+
conn.state = SIGAR_TCP_LAST_ACK;
|
1108
|
+
break;
|
1109
|
+
case TCTIMEWAIT:
|
1110
|
+
conn.state = SIGAR_TCP_TIME_WAIT;
|
1111
|
+
break;
|
1112
|
+
case TCDELETETCB:
|
1113
|
+
default:
|
1114
|
+
conn.state = SIGAR_TCP_UNKNOWN;
|
1115
|
+
break;
|
1116
|
+
}
|
1117
|
+
|
1118
|
+
conn.local_port = (unsigned short)entry->LocalPort;
|
1119
|
+
conn.remote_port = (unsigned short)entry->RemPort;
|
1120
|
+
conn.type = SIGAR_NETCONN_TCP;
|
1121
|
+
|
1122
|
+
sigar_net_address_set(conn.local_address, entry->LocalAddress);
|
1123
|
+
sigar_net_address_set(conn.remote_address, entry->RemAddress);
|
1124
|
+
|
1125
|
+
conn.send_queue = conn.receive_queue = SIGAR_FIELD_NOTIMPL;
|
1126
|
+
|
1127
|
+
if (walker->add_connection(walker, &conn) != SIGAR_OK) {
|
1128
|
+
break;
|
1129
|
+
}
|
1130
|
+
}
|
1131
|
+
|
1132
|
+
free(entries);
|
1133
|
+
|
1134
|
+
return SIGAR_OK;
|
1135
|
+
}
|
1136
|
+
|
1137
|
+
int sigar_net_connection_walk(sigar_net_connection_walker_t *walker)
|
1138
|
+
{
|
1139
|
+
int status;
|
1140
|
+
|
1141
|
+
if (walker->flags & SIGAR_NETCONN_TCP) {
|
1142
|
+
status = net_conn_get_tcp(walker);
|
1143
|
+
|
1144
|
+
if (status != SIGAR_OK) {
|
1145
|
+
return status;
|
1146
|
+
}
|
1147
|
+
}
|
1148
|
+
|
1149
|
+
if (walker->flags & SIGAR_NETCONN_UDP) {
|
1150
|
+
status = net_conn_get_udp(walker);
|
1151
|
+
|
1152
|
+
if (status != SIGAR_OK) {
|
1153
|
+
return status;
|
1154
|
+
}
|
1155
|
+
}
|
1156
|
+
|
1157
|
+
return SIGAR_OK;
|
1158
|
+
}
|
1159
|
+
|
1160
|
+
#define tcpsoff(x) sigar_offsetof(sigar_tcp_t, x)
|
1161
|
+
|
1162
|
+
static struct {
|
1163
|
+
unsigned int id;
|
1164
|
+
size_t offset;
|
1165
|
+
} tcps_lu[] = {
|
1166
|
+
#if 0
|
1167
|
+
{ ID_tcpRtoAlgorithm, tcpsoff(xxx) },
|
1168
|
+
{ ID_tcpRtoMin, tcpsoff(xxx) },
|
1169
|
+
{ ID_tcpRtoMax, tcpsoff(xxx) },
|
1170
|
+
{ ID_tcpMaxConn, tcpsoff(max_conn) },
|
1171
|
+
#endif
|
1172
|
+
{ ID_tcpActiveOpens, tcpsoff(active_opens) },
|
1173
|
+
{ ID_tcpPassiveOpens, tcpsoff(passive_opens) },
|
1174
|
+
{ ID_tcpAttemptFails, tcpsoff(attempt_fails) },
|
1175
|
+
{ ID_tcpEstabResets, tcpsoff(estab_resets) },
|
1176
|
+
{ ID_tcpCurrEstab, tcpsoff(curr_estab) },
|
1177
|
+
{ ID_tcpInSegs, tcpsoff(in_segs) },
|
1178
|
+
{ ID_tcpOutSegs, tcpsoff(out_segs) },
|
1179
|
+
{ ID_tcpRetransSegs, tcpsoff(retrans_segs) },
|
1180
|
+
{ ID_tcpInErrs, tcpsoff(in_errs) },
|
1181
|
+
{ ID_tcpOutRsts, tcpsoff(out_rsts) }
|
1182
|
+
};
|
1183
|
+
|
1184
|
+
SIGAR_DECLARE(int)
|
1185
|
+
sigar_tcp_get(sigar_t *sigar,
|
1186
|
+
sigar_tcp_t *tcp)
|
1187
|
+
{
|
1188
|
+
int i;
|
1189
|
+
|
1190
|
+
for (i=0; i<sizeof(tcps_lu)/sizeof(tcps_lu[0]); i++) {
|
1191
|
+
struct nmparms parms;
|
1192
|
+
int val;
|
1193
|
+
unsigned int len = sizeof(val);
|
1194
|
+
parms.objid = tcps_lu[i].id;
|
1195
|
+
parms.buffer = &val;
|
1196
|
+
parms.len = &len;
|
1197
|
+
|
1198
|
+
if (sigar_get_mib_info(sigar, &parms) != SIGAR_OK) {
|
1199
|
+
val = -1;
|
1200
|
+
}
|
1201
|
+
|
1202
|
+
*(sigar_uint64_t *)((char *)tcp + tcps_lu[i].offset) = val;
|
1203
|
+
}
|
1204
|
+
|
1205
|
+
return SIGAR_OK;
|
1206
|
+
}
|
1207
|
+
|
1208
|
+
int sigar_nfs_client_v2_get(sigar_t *sigar,
|
1209
|
+
sigar_nfs_client_v2_t *nfs)
|
1210
|
+
{
|
1211
|
+
return SIGAR_ENOTIMPL;
|
1212
|
+
}
|
1213
|
+
|
1214
|
+
int sigar_nfs_server_v2_get(sigar_t *sigar,
|
1215
|
+
sigar_nfs_server_v2_t *nfs)
|
1216
|
+
{
|
1217
|
+
return SIGAR_ENOTIMPL;
|
1218
|
+
}
|
1219
|
+
|
1220
|
+
int sigar_nfs_client_v3_get(sigar_t *sigar,
|
1221
|
+
sigar_nfs_client_v3_t *nfs)
|
1222
|
+
{
|
1223
|
+
return SIGAR_ENOTIMPL;
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
int sigar_nfs_server_v3_get(sigar_t *sigar,
|
1227
|
+
sigar_nfs_server_v3_t *nfs)
|
1228
|
+
{
|
1229
|
+
return SIGAR_ENOTIMPL;
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
int sigar_arp_list_get(sigar_t *sigar,
|
1233
|
+
sigar_arp_list_t *arplist)
|
1234
|
+
{
|
1235
|
+
int status, count, i;
|
1236
|
+
unsigned int len;
|
1237
|
+
struct nmparms parms;
|
1238
|
+
mib_ipNetToMediaEnt *entries;
|
1239
|
+
sigar_arp_t *arp;
|
1240
|
+
|
1241
|
+
len = sizeof(count);
|
1242
|
+
parms.objid = ID_ipNetToMediaTableNum;
|
1243
|
+
parms.buffer = &count;
|
1244
|
+
parms.len = &len;
|
1245
|
+
|
1246
|
+
if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) {
|
1247
|
+
return status;
|
1248
|
+
}
|
1249
|
+
|
1250
|
+
len = count * sizeof(*entries);
|
1251
|
+
entries = malloc(len);
|
1252
|
+
|
1253
|
+
parms.objid = ID_ipNetToMediaTable;
|
1254
|
+
parms.buffer = entries;
|
1255
|
+
parms.len = &len;
|
1256
|
+
|
1257
|
+
if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) {
|
1258
|
+
free(entries);
|
1259
|
+
return status;
|
1260
|
+
}
|
1261
|
+
|
1262
|
+
sigar_arp_list_create(arplist);
|
1263
|
+
|
1264
|
+
for (i=0; i<count; i++) {
|
1265
|
+
mib_ipNetToMediaEnt *ent = &entries[i];
|
1266
|
+
|
1267
|
+
SIGAR_ARP_LIST_GROW(arplist);
|
1268
|
+
|
1269
|
+
arp = &arplist->data[arplist->number++];
|
1270
|
+
|
1271
|
+
sigar_net_address_set(arp->address,
|
1272
|
+
ent->NetAddr);
|
1273
|
+
|
1274
|
+
sigar_net_address_mac_set(arp->hwaddr,
|
1275
|
+
ent->PhysAddr.o_bytes,
|
1276
|
+
ent->PhysAddr.o_length);
|
1277
|
+
|
1278
|
+
sigar_if_indextoname(sigar, arp->ifname, ent->IfIndex);
|
1279
|
+
|
1280
|
+
SIGAR_SSTRCPY(arp->type, "ether"); /*XXX*/
|
1281
|
+
arp->flags = 0; /*XXX*/
|
1282
|
+
}
|
1283
|
+
|
1284
|
+
free(entries);
|
1285
|
+
|
1286
|
+
return SIGAR_OK;
|
1287
|
+
}
|
1288
|
+
|
1289
|
+
int sigar_proc_port_get(sigar_t *sigar, int protocol,
|
1290
|
+
unsigned long port, sigar_pid_t *pid)
|
1291
|
+
{
|
1292
|
+
return SIGAR_ENOTIMPL;
|
1293
|
+
}
|
1294
|
+
|
1295
|
+
|
1296
|
+
int sigar_os_sys_info_get(sigar_t *sigar,
|
1297
|
+
sigar_sys_info_t *sysinfo)
|
1298
|
+
{
|
1299
|
+
char *vendor_version, *arch;
|
1300
|
+
long cpu = sysconf(_SC_CPU_VERSION);
|
1301
|
+
|
1302
|
+
switch (cpu) {
|
1303
|
+
case CPU_PA_RISC1_0:
|
1304
|
+
arch = "PA_RISC1.0";
|
1305
|
+
break;
|
1306
|
+
case CPU_PA_RISC1_1:
|
1307
|
+
arch = "PA_RISC1.1";
|
1308
|
+
break;
|
1309
|
+
case CPU_PA_RISC2_0:
|
1310
|
+
arch = "PA_RISC2.0";
|
1311
|
+
break;
|
1312
|
+
#ifdef CPU_IA64_ARCHREV_0
|
1313
|
+
case CPU_IA64_ARCHREV_0:
|
1314
|
+
arch = "ia64";
|
1315
|
+
break;
|
1316
|
+
#endif
|
1317
|
+
default:
|
1318
|
+
arch = "unknown";
|
1319
|
+
break;
|
1320
|
+
}
|
1321
|
+
|
1322
|
+
SIGAR_SSTRCPY(sysinfo->arch, arch);
|
1323
|
+
|
1324
|
+
SIGAR_SSTRCPY(sysinfo->name, "HPUX");
|
1325
|
+
SIGAR_SSTRCPY(sysinfo->vendor, "Hewlett-Packard");
|
1326
|
+
|
1327
|
+
if (strstr(sysinfo->version, ".11.")) {
|
1328
|
+
vendor_version = "11";
|
1329
|
+
}
|
1330
|
+
else {
|
1331
|
+
vendor_version = sysinfo->version;
|
1332
|
+
}
|
1333
|
+
|
1334
|
+
SIGAR_SSTRCPY(sysinfo->vendor_version, vendor_version);
|
1335
|
+
|
1336
|
+
snprintf(sysinfo->description,
|
1337
|
+
sizeof(sysinfo->description),
|
1338
|
+
"%s %s",
|
1339
|
+
sysinfo->vendor_name, sysinfo->vendor_version);
|
1340
|
+
|
1341
|
+
return SIGAR_OK;
|
1342
|
+
}
|