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