Imported Upstream version 1.26
Marc Haber
11 years ago
0 | #!/bin/sh | |
1 | ||
2 | . "${PM_FUNCTIONS}" | |
3 | ||
4 | LOGPATH=/var/log/atop | |
5 | BINPATH=/usr/bin | |
6 | PIDFILE=/var/run/atop.pid | |
7 | INTERVAL=600 # interval 10 minutes | |
8 | CURDAY=`date +%Y%m%d` # current date in same format | |
9 | ||
10 | # If the system suspends, one final sample will be taken for the logfile | |
11 | # | |
12 | suspend_atop() | |
13 | { | |
14 | if [ -e $PIDFILE ] && ps -p `cat $PIDFILE` | grep 'atop$' > /dev/null | |
15 | then | |
16 | kill -USR2 `cat $PIDFILE` # final sample and terminate | |
17 | ||
18 | CNT=0 | |
19 | ||
20 | while ps -p `cat $PIDFILE` > /dev/null | |
21 | do | |
22 | let CNT+=1 | |
23 | ||
24 | if [ $CNT -gt 5 ] | |
25 | then | |
26 | break; | |
27 | fi | |
28 | ||
29 | sleep 1 | |
30 | done | |
31 | fi | |
32 | } | |
33 | ||
34 | # If the system resumes, a new atop will be started (similar to boot) | |
35 | # | |
36 | resume_atop() | |
37 | { | |
38 | # in case atop is running, stop it | |
39 | # | |
40 | if [ -e $PIDFILE ] && ps -p `cat $PIDFILE` | grep 'atop$' > /dev/null | |
41 | then | |
42 | kill -TERM `cat $PIDFILE` | |
43 | rm $PIDFILE | |
44 | sleep 1 | |
45 | fi | |
46 | ||
47 | # start atop | |
48 | # | |
49 | $BINPATH/atop -a -w $LOGPATH/atop_$CURDAY $INTERVAL \ | |
50 | > $LOGPATH/daily.log 2>&1 & | |
51 | echo $! > $PIDFILE | |
52 | ||
53 | # delete logfiles older than four weeks | |
54 | # | |
55 | ( | |
56 | sleep 3; | |
57 | find $LOGPATH -name 'atop_*' -mtime +28 -exec rm {} \; | |
58 | )& | |
59 | ||
60 | exit 0 | |
61 | } | |
62 | ||
63 | case "$1" in | |
64 | hibernate|suspend) | |
65 | suspend_atop | |
66 | ;; | |
67 | thaw|resume) | |
68 | resume_atop | |
69 | ;; | |
70 | *) exit $NA | |
71 | ;; | |
72 | esac |
0 | 2008-03-06 Gerlof Langeveld <gerlof@ATComputing.nl> | |
0 | 2010-11-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
1 | ||
2 | * rawlog.c | |
3 | The flag -r followed by exactly 8 'y' characters is not | |
4 | considered as 8 days ago, but as a literal filename. | |
5 | ||
6 | 2010-11-14 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
7 | ||
8 | * photosyst.c | |
9 | Overflow of file descriptors because /proc/cpuinfo was | |
10 | opened for every interval, but not closed any more. | |
11 | Credits: Dardo Kleiner | |
12 | ||
13 | 2010-11-12 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
14 | ||
15 | * various.c | |
16 | Show all parts of timestamp in header line, even when zero. | |
17 | ||
18 | 2010-11-12 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
19 | ||
20 | * showsys.c, showprocs.c | |
21 | Sometimes segmentation-fault on particular CPU-types | |
22 | due to memcpy i.s.o. memmove when moving memory in overlap. | |
23 | ||
24 | 2010-10-25 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
25 | ||
26 | * showgeneric.c | |
27 | When the number of lines is too small for the system-level | |
28 | lines, limit the number of variable resources automatically | |
29 | to a minimum. | |
30 | ||
31 | 2010-10-23 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
32 | ||
33 | * atopsar.c | |
34 | Optimized code to show total number of running/sleeping | |
35 | threads. | |
36 | ||
37 | 2010-10-23 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
38 | ||
39 | * photosyst.c | |
40 | Add support for mmcblk disks (MMC/SD cardreaders) | |
41 | Credits: Anssi Hannula | |
42 | ||
43 | 2010-10-23 JC van Winkel <jc@ATComputing.nl> | |
44 | ||
45 | * atop.c, atopsar.c, deviate.c, parseable.c, rawlog.cs, showgeneric.c, | |
46 | showlinux.c, showsys.c | |
47 | Add counters for total number of running and sleeping (S and | |
48 | D) threads. | |
49 | ||
50 | 2010-05-18 JC van Winkel <jc@ATComputing.nl> | |
51 | ||
52 | * various.c, showsys.c, deviate.c, photosyst.c, parseable.c, showlinux.c | |
53 | Introduce CPU frequency and scaling. | |
54 | ||
55 | 2010-04-28 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
56 | ||
57 | * various.c | |
58 | Cast value larger than 4GB to long long. | |
59 | ||
60 | 2010-04-23 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
61 | ||
62 | * showprocs.c | |
63 | Added special routined for uid/gid not available for exited | |
64 | processes. | |
65 | ||
66 | 2010-04-23 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
67 | ||
68 | * showgeneric.c, atop.c | |
69 | Version (flag -V) handled earlier after startup. | |
70 | ||
71 | 2010-04-23 JC van Winkel <jc@ATComputing.nl> | |
72 | ||
73 | * showsys.c | |
74 | Field 'avque' modified to 'avq' to be able to show higher | |
75 | values (especially on LVM-level). | |
76 | ||
77 | 2010-04-23 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
78 | ||
79 | * showgeneric.c | |
80 | Proper sorting of processes when switching from single | |
81 | process view to cumulative view (key 'u' or 'p') and vice | |
82 | versa. | |
83 | ||
84 | 2010-04-17 JC van Winkel <jc@ATComputing.nl> | |
85 | ||
86 | * atop.c, showgeneric.c, showlinux.c | |
87 | Allow modifying the layout of the columns in the system | |
88 | lines via ~/.atoprc and /etc/atoprc | |
89 | ||
90 | 2010-04-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
91 | ||
92 | * atop.c, rawlog.c | |
93 | Automatically start another version of atop if the logfile | |
94 | to be read has not been created by the current version. | |
95 | ||
96 | 2010-03-26 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
97 | ||
98 | * various.c | |
99 | Introduced unit of Tbytes for memory-usage. | |
100 | ||
101 | 2010-03-19 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
102 | ||
103 | * 45atoppm | |
104 | Add script to handle power management for laptops, i.e. | |
105 | to take an extra sample just before hibernate/suspend and | |
106 | to restart atop in case of thaw/resume. | |
107 | ||
108 | 2010-03-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
109 | ||
110 | * showgeneric.c, showlinux.c | |
111 | Program and user selection can be combined with program and | |
112 | user accumulation. | |
113 | ||
114 | 2010-03-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
115 | ||
116 | * showgeneric.c | |
117 | Show in header-line if user selection (U) and | |
118 | program selection (P) is active. | |
119 | ||
120 | 2010-03-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
121 | ||
122 | * showgeneric.c | |
123 | Performance improvement - only sort system-resources once per | |
124 | interval. | |
125 | ||
126 | 2010-03-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
127 | ||
128 | * photosyst.c | |
129 | Add recognition of disk type "/dev/fio...". | |
130 | ||
131 | 2010-03-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
132 | ||
133 | * photosyst.c, atop.c, atopsar.c, deviate.c, parseable.c, | |
134 | showgeneric.c, showlinux.c, showsys.c | |
135 | Major change to support I/O-statistics on LVM and MD level. | |
136 | ||
137 | 2010-03-05 JC van Winkel <jc@ATComputing.nl> | |
138 | ||
139 | * showsys.c | |
140 | CPU-number was wrong in the sorted per-cpu statistics. | |
141 | ||
142 | 2010-03-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
143 | ||
144 | * rawlog.c | |
145 | Struct stat size did not fit in short any more (modified to | |
146 | int) in the header of the raw file. | |
147 | ||
148 | 2010-02-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
149 | ||
150 | * showgeneric.c | |
151 | Bug-solution for systems with long uptime (float exception): | |
152 | increased buffer-length for call to val2elapstr. | |
153 | ||
154 | 2010-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
155 | ||
156 | * showlinux.c | |
157 | Modified priorities for system-level columns. | |
158 | ||
159 | 2010-01-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
160 | ||
161 | * showprocs.c, showlinux.c | |
162 | Minor changes in output-specification. | |
163 | ||
164 | 2010-01-16 JC van Winkel <jc@ATComputing.nl> | |
165 | ||
166 | * showprocs.c, showlinux.c | |
167 | Corrected counters for patched kernels (JC van Winkel). | |
168 | ||
169 | 2010-01-08 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
170 | ||
171 | * parseable.c | |
172 | Added label RESET in case of a sample with values since boot. | |
173 | ||
174 | 2010-01-08 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
175 | ||
176 | * showprocs.c | |
177 | Added policies batch, iso and idle for scheduling class. | |
178 | ||
179 | 2010-01-08 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
180 | ||
181 | * showprocs.c, showlinux.c | |
182 | Corrected column-width and priorities of network-stats. | |
183 | ||
184 | 2010-01-03 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
185 | ||
186 | * showprocs.c, showlinux.c | |
187 | Consistent naming of columns for process-related info. | |
188 | ||
189 | 2009-12-31 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
190 | ||
191 | * atop.c, deviate.c | |
192 | Avoid that CPU-consumption of some process is 497 days | |
193 | in case of kernels that supply wrong counters. | |
194 | ||
195 | 2009-12-19 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
196 | ||
197 | * parseable.c | |
198 | Add new counters to parseable output. | |
199 | ||
200 | 2009-12-19 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
201 | ||
202 | * atopsar.c | |
203 | Added category guest to CPU-report. | |
204 | ||
205 | 2009-12-19 JC van Winkel <jc@ATComputing.nl> | |
206 | ||
207 | * showprocs.c | |
208 | Alignment of CMD column. | |
209 | ||
210 | 2009-12-19 JC van Winkel <jc@ATComputing.nl> | |
211 | ||
212 | * showlinux.c | |
213 | Improved syntax checking for ownprocline keyword. | |
214 | ||
215 | 2009-12-17 Ben Pfaff <blp@cs.stanford.edu> | |
216 | ||
217 | * atopsar.c | |
218 | Bug-fixes to solve several cases of segmentation faults. | |
219 | ||
220 | 2009-12-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
221 | ||
222 | * deviate.c, showlinux.c, showsys.c, photosyst.c, atopsar.c | |
223 | Gather and display new counters: | |
224 | dirty cache and guest cpu usage. | |
225 | ||
226 | 2009-12-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
227 | ||
228 | * showgeneric.c, showlinux.c, atop.c | |
229 | Allow to define a private process line in the atoprc file | |
230 | and activate it with the 'o' key or flag. | |
231 | ||
232 | 2009-12-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
233 | ||
234 | * showgeneric.c | |
235 | Show messages on status line in color to draw attention. | |
236 | ||
237 | 2009-12-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
238 | ||
239 | * showsys.c | |
240 | If no colors wanted, use bold display for critical resources. | |
241 | ||
242 | 2009-12-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
243 | ||
244 | * various.c | |
245 | Express CPU-time usage in days and hours for large values. | |
246 | ||
247 | 2009-12-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
248 | ||
249 | * showgeneric.c, rawlog.c, atop.c, atopsar.c | |
250 | Introduce branch-key 'b' to go to specific time in raw file. | |
251 | ||
252 | 2009-12-17 JC van Winkel <jc@ATComputing.nl> | |
253 | ||
254 | * showprocs.c | |
255 | Correct scaling of system-statistics on wider window. | |
256 | ||
257 | 2009-12-12 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
258 | ||
259 | * showlinux.c, showprocs.c, acctproc.c | |
260 | Add ENDATE (end date) and ENTIME (end time) for process. | |
261 | ||
262 | 2009-12-12 JC van Winkel <jc@ATComputing.nl> | |
263 | ||
264 | * showlinux.c, showprocs.c, showgeneric.c | |
265 | Correct figures for RDDSK/WRDSK when accumulated for | |
266 | user/program. | |
267 | ||
268 | 2009-12-10 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
269 | ||
270 | * showlinux.c, showprocs.c | |
271 | Add EUID, SUID and FSUID besides existing RUID | |
272 | Add EGID, SGID and FGUID besides existing RGID | |
273 | ||
274 | 2009-12-10 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
275 | ||
276 | * showgeneric.c | |
277 | Show the active toggle-keys in the header line. | |
278 | ||
279 | 2009-12-10 JC van Winkel <jc@ATComputing.nl> | |
280 | ||
281 | * atop.c, showgeneric.c, showlinux.c, showsys.c, showprocs.c | |
282 | Major redesign of screen interface with support of | |
283 | variable number of columns when the window resizes. | |
284 | ||
285 | 2009-12-10 JC van Winkel <jc@ATComputing.nl> | |
286 | ||
287 | * various.c, showgeneric.c | |
288 | If the number of seconds elapsed time is too log, convert | |
289 | it to a string in format NNdNNhNNmNNs. | |
290 | ||
291 | 2009-11-27 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
292 | ||
293 | * rawlog.c, atop.c, atopsar.c: | |
294 | Add possibility to specify y[y..] als filename for -r flag | |
295 | to access file of yesterday, day before yesterday, etc. | |
296 | ||
297 | 2009-11-27 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
298 | ||
299 | * atop.c, atopsar.c: | |
300 | Give up the (setuid) root-priviliges at a very early stage | |
301 | to make the program safer during parameter-checking and | |
302 | reading of configuration-files. | |
303 | ||
304 | 2009-11-27 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
305 | ||
306 | * rawlog.c: | |
307 | If not all writes to the logfile succeed for one interval, | |
308 | all writes will be rolled back, not to leave the logfile | |
309 | in a corrupted state. | |
310 | ||
311 | 2009-11-27 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
312 | ||
313 | * atop.c: | |
314 | Introduction of system-wide configuration file /etc/atoprc | |
315 | ||
316 | 2009-11-27 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
317 | ||
318 | * photoproc.c: | |
319 | Register ruid/euid/suid/fsuid and rgid/egid/sgid/fsgid. | |
320 | ||
321 | 2008-03-27 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
322 | ||
323 | * showlinux.c: | |
324 | Recognize policies SCHED_BATCH and SCHED_IDLE. | |
325 | ||
326 | 2008-03-06 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
1 | 327 | |
2 | 328 | * photoproc.c, parseable.c, acctproc.c, showlinux.c: |
3 | 329 | Register/show PPID related to a process. |
6 | 332 | logfiles that were created by older versions of atop |
7 | 333 | is not reliable. |
8 | 334 | |
9 | 2008-02-25 Gerlof Langeveld <gerlof@ATComputing.nl> | |
335 | 2008-02-25 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
10 | 336 | |
11 | 337 | * atopsar.c, deviate.c: |
12 | 338 | Added experimental code for HTTP-statistics. |
13 | 339 | |
14 | 2008-02-11 Gerlof Langeveld <gerlof@ATComputing.nl> | |
340 | 2008-02-11 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
15 | 341 | |
16 | 342 | * showgeneric.c: |
17 | 343 | Bug-solution for segmentation-fault in case of |
18 | 344 | invalid regular expression. |
19 | 345 | |
20 | 2008-01-21 Gerlof Langeveld <gerlof@ATComputing.nl> | |
346 | 2008-01-21 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
21 | 347 | |
22 | 348 | * atopsar.c: |
23 | 349 | Add new reports to show top-3 processes consuming |
24 | 350 | most cpu, memory, disk and network resources. |
25 | 351 | |
26 | 2008-01-21 Gerlof Langeveld <gerlof@ATComputing.nl> | |
352 | 2008-01-21 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
27 | 353 | |
28 | 354 | * atopsar.c: |
29 | 355 | Add number of thread per state to output generated |
30 | 356 | by -P flag. |
31 | 357 | |
32 | 2008-01-18 Gerlof Langeveld <gerlof@ATComputing.nl> | |
358 | 2008-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
33 | 359 | |
34 | 360 | * showlinux.c, photoproc.c, parseable.c: |
35 | 361 | Gather and show information about the number of |
38 | 364 | This information is shown in the scheduling |
39 | 365 | report (keystroke 's') |
40 | 366 | |
41 | 2008-01-14 Gerlof Langeveld <gerlof@ATComputing.nl> | |
367 | 2008-01-14 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
42 | 368 | |
43 | 369 | * acctproc.c: |
44 | 370 | Specify the name of a specific process accounting file with |
45 | 371 | the environment variable ATOPACCT (or disable process |
46 | 372 | accounting when this variable has an empty contents). |
47 | 373 | |
48 | 2008-01-07 Gerlof Langeveld <gerlof@ATComputing.nl> | |
374 | 2008-01-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
49 | 375 | |
50 | 376 | * atopsar.c: |
51 | 377 | Rename forks/s into clones/s in report with flag -p. |
52 | 378 | |
53 | 2008-01-07 Gerlof Langeveld <gerlof@ATComputing.nl> | |
379 | 2008-01-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
54 | 380 | |
55 | 381 | * atopsar.c: |
56 | 382 | Show 100% per CPU instead of 100% for all CPUs in the |
57 | 383 | report shown with the -c flag of atopsar (similar to |
58 | 384 | the atop output). |
59 | 385 | |
60 | 2008-01-07 Gerlof Langeveld <gerlof@ATComputing.nl> | |
386 | 2008-01-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
61 | 387 | |
62 | 388 | * showlinux.c: |
63 | 389 | The network-interfaces should be sorted on their |
64 | 390 | busy-percentage and not on the number of transferred |
65 | 391 | packages. |
66 | 392 | |
67 | 2008-01-07 Gerlof Langeveld <gerlof@ATComputing.nl> | |
393 | 2008-01-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
68 | 394 | |
69 | 395 | * atopsar.c, deviate.c, atop.c: |
70 | 396 | Make summary-reports by packing N samples together in one |
71 | 397 | sample. The value N can be specified with the new flag -R. |
72 | 398 | |
73 | 2007-11-29 Gerlof Langeveld <gerlof@ATComputing.nl> | |
399 | 2007-11-29 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
74 | 400 | |
75 | 401 | * atopsar.c: |
76 | 402 | Repeat the header of a report every X lines (flag -H). |
77 | 403 | In case of output to a window, value X is determined |
78 | 404 | dynamically, depending on the window size. |
79 | 405 | |
80 | 2007-11-29 Gerlof Langeveld <gerlof@ATComputing.nl> | |
406 | 2007-11-29 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
81 | 407 | |
82 | 408 | * atopsar.c: |
83 | 409 | Added new report with flag -P for process-activity (number |
84 | 410 | of processes currently present and number of zombies, |
85 | 411 | number of thread creations and process exits). |
86 | 412 | |
87 | 2007-11-07 Gerlof Langeveld <gerlof@ATComputing.nl> | |
413 | 2007-11-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
88 | 414 | |
89 | 415 | * showlinux.c: |
90 | 416 | Modified format for avg1, avg5 and avg15 (CPL) |
91 | 417 | when counters become too large. |
92 | 418 | |
93 | 2007-11-06 Gerlof Langeveld <gerlof@ATComputing.nl> | |
419 | 2007-11-06 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
94 | 420 | |
95 | 421 | * atopsar.c: |
96 | 422 | Modify duplex indicator "fdx" to "f" and "hdx" to "h" |
97 | 423 | in the report about interfaces (line too long if |
98 | 424 | markers are added). |
99 | 425 | |
100 | 2007-11-06 Gerlof Langeveld <gerlof@ATComputing.nl> | |
426 | 2007-11-06 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
101 | 427 | |
102 | 428 | * atopsar.c, atop.c: |
103 | 429 | Add keyword atopsarflags to configuration-file ~/.atoprc |
104 | 430 | to specify personal defaults. |
105 | 431 | |
106 | 2007-11-06 Gerlof Langeveld <gerlof@ATComputing.nl> | |
432 | 2007-11-06 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
107 | 433 | |
108 | 434 | * atopsar.c: |
109 | 435 | Add support for colors/markers in case of (almost) |
110 | 436 | critical resource consumption (similar to atop). |
111 | 437 | This concerns the -x/-C/-M flags. |
112 | 438 | |
113 | 2007-11-05 Gerlof Langeveld <gerlof@ATComputing.nl> | |
439 | 2007-11-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
114 | 440 | |
115 | 441 | * photoproc.c: |
116 | 442 | Detect disappearing /proc/<pid>/stat file when |
117 | 443 | concerning process exits meanwhile (credits: Rene Rebe). |
118 | 444 | |
119 | 2007-11-05 Gerlof Langeveld <gerlof@ATComputing.nl> | |
445 | 2007-11-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
120 | 446 | |
121 | 447 | * procdbase.c, deviate.c: |
122 | 448 | Match processes not only on pid, but also on start time |
123 | 449 | to avoid wrong matches when a proces has exited and |
124 | 450 | a new proces reuses its pid within the same sample. |
125 | 451 | |
126 | 2007-11-05 Gerlof Langeveld <gerlof@ATComputing.nl> | |
452 | 2007-11-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
127 | 453 | |
128 | 454 | * showlinux.c, deviate.c: |
129 | 455 | Bug-solution for new-process indicator on 64-bits machines. |
130 | 456 | |
131 | 2007-11-05 Gerlof Langeveld <gerlof@ATComputing.nl> | |
457 | 2007-11-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
132 | 458 | |
133 | 459 | * showlinux.c: |
134 | 460 | Bug-solution for huge exit codes for 64-bits machines. |
135 | 461 | |
136 | 2007-10-04 Gerlof Langeveld <gerlof@ATComputing.nl> | |
462 | 2007-10-04 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
137 | 463 | |
138 | 464 | * atopsar.c: |
139 | 465 | Use line-buffering on stdout, even for pipes and files. |
140 | 466 | |
141 | 2007-08-17 Gerlof Langeveld <gerlof@ATComputing.nl> | |
467 | 2007-08-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
142 | 468 | |
143 | 469 | * atopsar.c: |
144 | 470 | Cosmetic changes to counter names. |
145 | 471 | |
146 | 2007-08-17 Gerlof Langeveld <gerlof@ATComputing.nl> | |
472 | 2007-08-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
147 | 473 | |
148 | 474 | * acctproc.c: |
149 | 475 | Verify if private accounting used before switching |
150 | 476 | off accounting. |
151 | 477 | |
152 | 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl> | |
478 | 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
153 | 479 | |
154 | 480 | * atop.c: |
155 | 481 | Add support for atopsar reporting (mainly |
156 | 482 | calling of atopsar). |
157 | 483 | |
158 | 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl> | |
484 | 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
159 | 485 | |
160 | 486 | * atopsar.c: |
161 | 487 | New source file to implement the atopsar command |
162 | 488 | as a (symbolic) link to the atop command. Most of |
163 | 489 | the source code has been copied from the atsar command. |
164 | 490 | |
165 | 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl> | |
491 | 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
166 | 492 | |
167 | 493 | * deviate.c: |
168 | 494 | Add support for atopsar reporting (lot of |
169 | 495 | counters added). |
170 | 496 | |
171 | 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl> | |
497 | 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
172 | 498 | |
173 | 499 | * parseable.c: |
174 | 500 | Add support for atopsar reporting (handling of |
175 | 501 | certain network counters modified). |
176 | 502 | |
177 | 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl> | |
503 | 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
178 | 504 | |
179 | 505 | * photosyst.c: |
180 | 506 | Add support for atopsar reporting (gather more counters, |
181 | 507 | mainly related to networking). |
182 | 508 | |
183 | 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl> | |
509 | 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
184 | 510 | |
185 | 511 | * rawlog.c: |
186 | 512 | Add support for atopsar reporting (gather more counters, |
187 | 513 | mainly related to networking). |
188 | 514 | |
189 | 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl> | |
515 | 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
190 | 516 | |
191 | 517 | * showlinux.c: |
192 | 518 | Add support for atopsar reporting (handling of |
193 | 519 | certain network counters modified). |
194 | 520 | |
195 | 2007-07-04 Gerlof Langeveld <gerlof@ATComputing.nl> | |
521 | 2007-07-04 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
196 | 522 | |
197 | 523 | * showlinux.c: |
198 | 524 | Bug-solution: divide by zero problem. |
199 | 525 | |
200 | 2007-03-27 Gerlof Langeveld <gerlof@ATComputing.nl> | |
526 | 2007-03-27 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
201 | 527 | |
202 | 528 | * photoproc.c: |
203 | 529 | Only allow check for IOSTAT when patches are not installed. |
204 | 530 | |
205 | 2007-03-24 Gerlof Langeveld <gerlof@ATComputing.nl> | |
531 | 2007-03-24 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
206 | 532 | |
207 | 533 | * atop.spec, atop.daily, accs_atop, accu_atop: |
208 | 534 | Remove time-hole from 23.50 till 00.00 for daily logging. |
209 | 535 | |
210 | 2007-03-22 Gerlof Langeveld <gerlof@ATComputing.nl> | |
536 | 2007-03-22 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
211 | 537 | |
212 | 538 | * atop.spec, atop.daily, accs_atop, accu_atop: |
213 | 539 | Improve automatic startup independent of the fact |
214 | 540 | that the RPM `psacct' is installed. |
215 | 541 | The script `atop.24hours' has been removed. |
216 | 542 | |
217 | 2007-03-22 Gerlof Langeveld <gerlof@ATComputing.nl> | |
543 | 2007-03-22 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
218 | 544 | |
219 | 545 | * photoproc.c, deviate.c, showlinux.c, showgeneric.c: |
220 | 546 | Introduce counters from /proc/pid/io for disk activity. |
221 | 547 | |
222 | 2007-03-20 Gerlof Langeveld <gerlof@ATComputing.nl> | |
548 | 2007-03-20 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
223 | 549 | |
224 | 550 | * rawlog.c: |
225 | 551 | Avoid loop when incompatible raw file is read. |
226 | 552 | Verify return code of compress/uncompress functions. |
227 | 553 | Verify success of malloc's. |
228 | 554 | |
229 | 2007-03-09 Gerlof Langeveld <gerlof@ATComputing.nl> | |
555 | 2007-03-09 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
230 | 556 | |
231 | 557 | * showgeneric.c: |
232 | 558 | Bug-solution: only allow key 'N' when kernel patch |
233 | 559 | is installed, and key 'D' when kernel patch is installed |
234 | 560 | or /proc/pid/io is available. |
235 | 561 | |
236 | 2007-02-23 Gerlof Langeveld <gerlof@ATComputing.nl> | |
562 | 2007-02-23 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
237 | 563 | |
238 | 564 | * rawlog.c: |
239 | 565 | Bug-solution: allow more than 65535 processes to be logged |
240 | 566 | per interval. |
241 | 567 | |
242 | 2007-02-13 Gerlof Langeveld <gerlof@ATComputing.nl> | |
568 | 2007-02-13 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
243 | 569 | |
244 | 570 | * acctproc.c: |
245 | 571 | New boolean introduced to indicate if accounting is active. |
246 | 572 | |
247 | 2007-01-26 Gerlof Langeveld <gerlof@ATComputing.nl> | |
573 | 2007-01-26 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
248 | 574 | |
249 | 575 | * atop.c, showlinux.c: |
250 | 576 | Add configuration-value 'swoutcritsec'. |
251 | 577 | |
252 | 2007-01-26 Gerlof Langeveld <gerlof@ATComputing.nl> | |
578 | 2007-01-26 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
253 | 579 | |
254 | 580 | * showlinux.c: |
255 | 581 | Support steal-percentage. |
256 | 582 | Avoid that interfaces are colored without reason. |
257 | 583 | |
258 | 2007-01-22 Gerlof Langeveld <gerlof@ATComputing.nl> | |
584 | 2007-01-22 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
259 | 585 | |
260 | 586 | * photosyst.c: |
261 | 587 | Support of special disks used by virtual machines. |
262 | 588 | |
263 | 2007-01-22 Gerlof Langeveld <gerlof@ATComputing.nl> | |
589 | 2007-01-22 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
264 | 590 | |
265 | 591 | * photosyst.c, deviate.c: |
266 | 592 | Support steal-time from /proc/stat. |
267 | 593 | |
268 | 2007-01-19 Gerlof Langeveld <gerlof@ATComputing.nl> | |
594 | 2007-01-19 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
269 | 595 | |
270 | 596 | * ifprop.c: |
271 | 597 | Added typedef u64 for SuSE distributions. |
272 | 598 | |
273 | 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl> | |
599 | 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
274 | 600 | |
275 | 601 | * deviate.c: |
276 | 602 | Support for network-interface busy-percentage. |
277 | 603 | |
278 | 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl> | |
604 | 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
279 | 605 | |
280 | 606 | * showgeneric.c: |
281 | 607 | Add support for colors and automatic determination of most |
282 | 608 | critical resource. |
283 | 609 | |
284 | 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl> | |
610 | 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
285 | 611 | |
286 | 612 | * showlinux.c: |
287 | 613 | Add support for colors, automatic determination of most |
288 | 614 | critical resource and parsing of new arguments in ~/.atoprc |
289 | 615 | |
290 | 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl> | |
616 | 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
291 | 617 | |
292 | 618 | * ifprop.c: |
293 | 619 | New functions to fetch the properties of a network |
294 | 620 | interface (mainly speed and half/full duplex). |
295 | 621 | |
296 | 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl> | |
622 | 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
297 | 623 | |
298 | 624 | * atop.c: |
299 | 625 | Improved syntax-checking for ~/.atoprc file. |
300 | 626 | Support for network-interface busy-percentage. |
301 | 627 | |
302 | 2007-01-15 Gerlof Langeveld <gerlof@ATComputing.nl> | |
628 | 2007-01-15 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
303 | 629 | |
304 | 630 | * photoproc.c: |
305 | 631 | Add new function to count actual number of processes. |
306 | 632 | |
307 | 2006-11-13 Gerlof Langeveld <gerlof@ATComputing.nl> | |
633 | 2006-11-13 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
308 | 634 | |
309 | 635 | * showlinux.c: |
310 | 636 | Modify network-speed counters (divide by 1000 i.s.o. 1024 |
311 | 637 | and postpone switch from Mbps to Gbps as suggested |
312 | 638 | by T. Lindgren). |
313 | 639 | |
314 | 2006-07-24 Gerlof Langeveld <gerlof@ATComputing.nl> | |
640 | 2006-07-24 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
315 | 641 | |
316 | 642 | * photosyst.h, photosyst.c, deviate.c, showlinux.c: |
317 | 643 | Add a new system-level line ('CPL') showing CPU load |
318 | 644 | information like load average (last 1, 5, 15 minutes) |
319 | 645 | number of context switches and number of interrupts. |
320 | 646 | |
321 | 2006-05-15 Gerlof Langeveld <gerlof@ATComputing.nl> | |
647 | 2006-05-15 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
322 | 648 | |
323 | 649 | * showgeneric.c: |
324 | 650 | Allow a numerical UID to be specified with the |
325 | 651 | function 'U'. |
326 | 652 | |
327 | 2006-05-15 Gerlof Langeveld <gerlof@ATComputing.nl> | |
653 | 2006-05-15 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
328 | 654 | |
329 | 655 | * showlinux.c: |
330 | 656 | When there is no user/group name which corresponds to a |
331 | 657 | numerical UID/GID, show the numerical value i.s.o. "unknown". |
332 | 658 | |
333 | 2006-04-19 Gerlof Langeveld <gerlof@ATComputing.nl> | |
659 | 2006-04-19 Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
334 | 660 | |
335 | 661 | * setup of ChangeLog |
0 | 0 | # Makefile for System & Process Monitor ATOP (Linux version) |
1 | 1 | # |
2 | # Gerlof Langeveld - AT Computing - Nijmegen, The Netherlands | |
3 | # (gerlof@ATComputing.nl) | |
2 | # Gerlof Langeveld - gerlof.langeveld@atoptool.nl | |
4 | 3 | # |
5 | DESTDIR = | |
4 | DESTDIR = | |
6 | 5 | |
7 | BINPATH = /usr/bin | |
8 | SCRPATH = /etc/atop | |
9 | LOGPATH = /var/log/atop | |
10 | MANPATH = /usr/share/man/man1 | |
11 | INIPATH = /etc/rc.d/init.d | |
12 | CRNPATH = /etc/cron.d | |
13 | ROTPATH = /etc/logrotate.d | |
6 | BINPATH = /usr/bin | |
7 | SCRPATH = /etc/atop | |
8 | LOGPATH = /var/log/atop | |
9 | MAN1PATH = /usr/share/man/man1 | |
10 | MAN5PATH = /usr/share/man/man5 | |
11 | INIPATH = /etc/rc.d/init.d | |
12 | CRNPATH = /etc/cron.d | |
13 | ROTPATH = /etc/logrotate.d | |
14 | PMPATH1 = /usr/lib/pm-utils/sleep.d | |
15 | PMPATH2 = /usr/lib64/pm-utils/sleep.d | |
14 | 16 | |
15 | CFLAGS = -O -I. -Wall # -DHTTPSTATS | |
16 | LDFLAGS = -lncurses -lm -lz | |
17 | OBJMOD0 = version.o | |
18 | OBJMOD1 = various.o deviate.o procdbase.o | |
19 | OBJMOD2 = acctproc.o photoproc.o photosyst.o rawlog.o ifprop.o parseable.o | |
20 | OBJMOD3 = showgeneric.o showlinux.o | |
21 | OBJMOD4 = atopsar.o | |
22 | ALLMODS = $(OBJMOD0) $(OBJMOD1) $(OBJMOD2) $(OBJMOD3) $(OBJMOD4) | |
17 | CFLAGS += -O2 -I. -Wall # -DHTTPSTATS | |
18 | LDFLAGS += -lncurses -lm -lz | |
19 | OBJMOD0 = version.o | |
20 | OBJMOD1 = various.o deviate.o procdbase.o | |
21 | OBJMOD2 = acctproc.o photoproc.o photosyst.o rawlog.o ifprop.o parseable.o | |
22 | OBJMOD3 = showgeneric.o showlinux.o showsys.o showprocs.o | |
23 | OBJMOD4 = atopsar.o | |
24 | ALLMODS = $(OBJMOD0) $(OBJMOD1) $(OBJMOD2) $(OBJMOD3) $(OBJMOD4) | |
25 | ||
26 | VERS = $(shell ./atop -V 2>/dev/null| sed -e 's/^[^ ]* //' -e 's/ .*//') | |
23 | 27 | |
24 | 28 | all: atop |
25 | 29 | |
26 | 30 | atop: atop.o $(ALLMODS) Makefile |
27 | cc atop.o $(ALLMODS) -o atop $(LDFLAGS) | |
31 | $(CC) atop.o $(ALLMODS) -o atop $(LDFLAGS) | |
28 | 32 | |
29 | 33 | clean: |
30 | 34 | rm -f *.o |
31 | 35 | |
32 | 36 | install: atop |
33 | if [ ! -d $(DESTDIR)$(LOGPATH) ]; then mkdir -p $(DESTDIR)$(LOGPATH); fi | |
34 | if [ ! -d $(DESTDIR)$(BINPATH) ]; then mkdir -p $(DESTDIR)$(BINPATH); fi | |
35 | if [ ! -d $(DESTDIR)$(SCRPATH) ]; then mkdir -p $(DESTDIR)$(SCRPATH); fi | |
36 | if [ ! -d $(DESTDIR)$(MANPATH) ]; then mkdir -p $(DESTDIR)$(MANPATH); fi | |
37 | if [ ! -d $(DESTDIR)$(INIPATH) ]; then mkdir -p $(DESTDIR)$(INIPATH); fi | |
38 | if [ ! -d $(DESTDIR)$(CRNPATH) ]; then mkdir -p $(DESTDIR)$(CRNPATH); fi | |
39 | if [ ! -d $(DESTDIR)$(ROTPATH) ]; then mkdir -p $(DESTDIR)$(ROTPATH); fi | |
40 | cp atop $(DESTDIR)$(BINPATH)/atop | |
41 | chown root $(DESTDIR)$(BINPATH)/atop | |
42 | chmod 04711 $(DESTDIR)$(BINPATH)/atop | |
43 | -rm $(DESTDIR)$(BINPATH)/atopsar | |
44 | ln -s atop $(DESTDIR)$(BINPATH)/atopsar | |
45 | cp atop.daily $(DESTDIR)$(SCRPATH) | |
46 | chmod 0711 $(DESTDIR)$(SCRPATH)/atop.daily | |
47 | cp man/atop.1 $(DESTDIR)$(MANPATH) | |
48 | cp man/atopsar.1 $(DESTDIR)$(MANPATH) | |
49 | cp atop.init $(DESTDIR)$(INIPATH)/atop | |
50 | cp atop.cron $(DESTDIR)$(CRNPATH)/atop | |
51 | cp psaccs_atop $(DESTDIR)$(ROTPATH)/psaccs_atop | |
52 | cp psaccu_atop $(DESTDIR)$(ROTPATH)/psaccu_atop | |
53 | touch $(DESTDIR)$(LOGPATH)/dummy_before | |
54 | touch $(DESTDIR)$(LOGPATH)/dummy_after | |
37 | if [ ! -d $(DESTDIR)$(LOGPATH) ]; \ | |
38 | then mkdir -p $(DESTDIR)$(LOGPATH); fi | |
39 | if [ ! -d $(DESTDIR)$(BINPATH) ]; \ | |
40 | then mkdir -p $(DESTDIR)$(BINPATH); fi | |
41 | if [ ! -d $(DESTDIR)$(SCRPATH) ]; \ | |
42 | then mkdir -p $(DESTDIR)$(SCRPATH); fi | |
43 | if [ ! -d $(DESTDIR)$(MAN1PATH) ]; \ | |
44 | then mkdir -p $(DESTDIR)$(MAN1PATH); fi | |
45 | if [ ! -d $(DESTDIR)$(MAN5PATH) ]; \ | |
46 | then mkdir -p $(DESTDIR)$(MAN5PATH); fi | |
47 | if [ ! -d $(DESTDIR)$(INIPATH) ]; \ | |
48 | then mkdir -p $(DESTDIR)$(INIPATH); fi | |
49 | if [ ! -d $(DESTDIR)$(CRNPATH) ]; \ | |
50 | then mkdir -p $(DESTDIR)$(CRNPATH); fi | |
51 | if [ ! -d $(DESTDIR)$(ROTPATH) ]; \ | |
52 | then mkdir -p $(DESTDIR)$(ROTPATH); fi | |
53 | if [ -d $(DESTDIR)$(PMPATH1) ]; \ | |
54 | then cp 45atoppm $(DESTDIR)$(PMPATH1); \ | |
55 | chmod 0711 $(DESTDIR)$(PMPATH1)/45atoppm; fi | |
56 | if [ -d $(DESTDIR)$(PMPATH2) ]; \ | |
57 | then cp 45atoppm $(DESTDIR)$(PMPATH2); \ | |
58 | chmod 0711 $(DESTDIR)$(PMPATH2)/45atoppm; fi | |
59 | # | |
60 | cp atop $(DESTDIR)$(BINPATH)/atop | |
61 | chown root $(DESTDIR)$(BINPATH)/atop | |
62 | chmod 04711 $(DESTDIR)$(BINPATH)/atop | |
63 | ln -sf atop $(DESTDIR)$(BINPATH)/atopsar | |
64 | cp atop $(DESTDIR)$(BINPATH)/atop-$(VERS) | |
65 | ln -sf atop-$(VERS) $(DESTDIR)$(BINPATH)/atopsar-$(VERS) | |
66 | cp atop.daily $(DESTDIR)$(SCRPATH) | |
67 | chmod 0711 $(DESTDIR)$(SCRPATH)/atop.daily | |
68 | cp man/atop.1 $(DESTDIR)$(MAN1PATH) | |
69 | cp man/atopsar.1 $(DESTDIR)$(MAN1PATH) | |
70 | cp man/atoprc.5 $(DESTDIR)$(MAN5PATH) | |
71 | cp atop.init $(DESTDIR)$(INIPATH)/atop | |
72 | cp atop.cron $(DESTDIR)$(CRNPATH)/atop | |
73 | cp psaccs_atop $(DESTDIR)$(ROTPATH)/psaccs_atop | |
74 | cp psaccu_atop $(DESTDIR)$(ROTPATH)/psaccu_atop | |
75 | touch $(DESTDIR)$(LOGPATH)/dummy_before | |
76 | touch $(DESTDIR)$(LOGPATH)/dummy_after | |
55 | 77 | if [ -z "$(DESTDIR)" ]; then /sbin/chkconfig --add atop; fi |
56 | ||
57 | distr: | |
58 | rm -f *.o | |
78 | distr: rm -f *.o | |
59 | 79 | tar czvf /tmp/atop.tar.gz * |
60 | 80 | ########################################################################## |
61 | 81 | |
62 | 82 | atop.o: atop.h photoproc.h photosyst.h acctproc.h showgeneric.h |
63 | 83 | atopsar.o: atop.h photoproc.h photosyst.h |
64 | rawlog.o: atop.h photoproc.h photosyst.h | |
84 | rawlog.o: atop.h photoproc.h photosyst.h showgeneric.h | |
65 | 85 | various.o: atop.h acctproc.h |
66 | 86 | ifprop.o: atop.h photosyst.h ifprop.h |
67 | 87 | parseable.o: atop.h photoproc.h photosyst.h parseable.h |
70 | 90 | acctproc.o: atop.h photoproc.h acctproc.h |
71 | 91 | photoproc.o: atop.h photoproc.h |
72 | 92 | photosyst.o: atop.h photosyst.h |
73 | showgeneric.o: atop.h photoproc.h photosyst.h showgeneric.h | |
74 | showlinux.o: atop.h photoproc.h photosyst.h showgeneric.h | |
93 | showgeneric.o: atop.h photoproc.h photosyst.h showgeneric.h showlinux.h | |
94 | showlinux.o: atop.h photoproc.h photosyst.h showgeneric.h showlinux.h | |
95 | showsys.o: atop.h photoproc.h photosyst.h showgeneric.h | |
96 | showprocs.o: atop.h photoproc.h photosyst.h showgeneric.h showlinux.h |
6 | 6 | description in the manual-page. |
7 | 7 | |
8 | 8 | Gerlof Langeveld |
9 | AT Computing | |
10 | Nijmegen, The Netherlands | |
11 | gerlof@ATComputing.nl | |
9 | gerlof@atoptool.nl |
6 | 6 | ** This source-file contains functions to manipulate with process-accounting |
7 | 7 | ** features (switch it on/off and read the process-accounting records). |
8 | 8 | ** ================================================================ |
9 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: gerlof@ATComputing.nl | |
9 | ** Author: Gerlof Langeveld | |
10 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | 11 | ** Date: November 1996 |
12 | 12 | ** LINUX-port: June 2000 |
13 | 13 | ** |
22 | 22 | ** See the GNU General Public License for more details. |
23 | 23 | ** |
24 | 24 | ** $Log: acctproc.c,v $ |
25 | ** Revision 1.28 2010/04/23 12:20:19 gerlof | |
26 | ** Modified mail-address in header. | |
27 | ** | |
28 | ** Revision 1.27 2009/12/12 10:12:01 gerlof | |
29 | ** Register and display end date and end time for process. | |
30 | ** | |
25 | 31 | ** Revision 1.26 2008/03/06 08:37:25 gerlof |
26 | 32 | ** Register/show ppid of a process. |
27 | 33 | ** |
106 | 112 | ** |
107 | 113 | */ |
108 | 114 | |
109 | static const char rcsid[] = "$Id: acctproc.c,v 1.26 2008/03/06 08:37:25 gerlof Exp $"; | |
115 | static const char rcsid[] = "$Id: acctproc.c,v 1.28 2010/04/23 12:20:19 gerlof Exp $"; | |
110 | 116 | |
111 | 117 | #include <sys/types.h> |
112 | 118 | #include <stdio.h> |
630 | 636 | api->gen.ruid = acctrec.ac_uid16; |
631 | 637 | api->gen.rgid = acctrec.ac_gid16; |
632 | 638 | api->gen.btime = acctrec.ac_btime; |
639 | api->gen.elaps = acctrec.ac_etime; | |
633 | 640 | api->cpu.stime = acctexp(acctrec.ac_stime); |
634 | 641 | api->cpu.utime = acctexp(acctrec.ac_utime); |
635 | 642 | api->mem.minflt = acctexp(acctrec.ac_minflt); |
654 | 661 | api->gen.ruid = acctrec_v3.ac_uid; |
655 | 662 | api->gen.rgid = acctrec_v3.ac_gid; |
656 | 663 | api->gen.btime = acctrec_v3.ac_btime; |
664 | api->gen.elaps = acctrec_v3.ac_etime; | |
657 | 665 | api->cpu.stime = acctexp(acctrec_v3.ac_stime); |
658 | 666 | api->cpu.utime = acctexp(acctrec_v3.ac_utime); |
659 | 667 | api->mem.minflt = acctexp(acctrec_v3.ac_minflt); |
678 | 686 | api->gen.ruid = acctrec_atop.ac_uid; |
679 | 687 | api->gen.rgid = acctrec_atop.ac_gid; |
680 | 688 | api->gen.btime = acctrec_atop.ac_btime; |
689 | api->gen.elaps = acctrec_atop.ac_etime; | |
681 | 690 | api->cpu.stime = acctexp (acctrec_atop.ac_stime); |
682 | 691 | api->cpu.utime = acctexp (acctrec_atop.ac_utime); |
683 | 692 | api->mem.minflt = acctexp (acctrec_atop.ac_minflt); |
5 | 5 | ** |
6 | 6 | ** Include-file for process-accounting functions. |
7 | 7 | ** ================================================================ |
8 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
9 | ** E-mail: gerlof@ATComputing.nl | |
8 | ** Author: Gerlof Langeveld | |
9 | ** E-mail: gerlof.langeveld@atoptool.nl | |
10 | 10 | ** Date: November 1996 |
11 | 11 | ** LINUX-port: June 2000 |
12 | 12 | ** |
10 | 10 | ** process-level counters and the deviations are calculated and |
11 | 11 | ** visualized for the user. |
12 | 12 | ** ========================================================================== |
13 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
14 | ** E-mail: gerlof@ATComputing.nl | |
13 | ** Author: Gerlof Langeveld | |
14 | ** E-mail: gerlof.langeveld@atoptool.nl | |
15 | 15 | ** Date: November 1996 |
16 | 16 | ** Linux-port: June 2000 |
17 | 17 | ** Modified: May 2001 - Ported to kernel 2.4 |
18 | 18 | ** -------------------------------------------------------------------------- |
19 | ** Copyright (C) 2000-2005 Gerlof Langeveld | |
19 | ** Copyright (C) 2000-2010 Gerlof Langeveld | |
20 | 20 | ** |
21 | 21 | ** This program is free software; you can redistribute it and/or modify it |
22 | 22 | ** under the terms of the GNU General Public License as published by the |
114 | 114 | ** at runtime. |
115 | 115 | ** |
116 | 116 | ** $Log: atop.c,v $ |
117 | ** Revision 1.49 2010/10/23 14:01:00 gerlof | |
118 | ** Show counters for total number of running and sleep (S and D) threads. | |
119 | ** | |
120 | ** Revision 1.48 2010/10/23 08:18:15 gerlof | |
121 | ** Catch signal SIGUSR2 to take a final sample and stop. | |
122 | ** Needed for improved of suspend/hibernate. | |
123 | ** | |
124 | ** Revision 1.47 2010/04/23 12:20:19 gerlof | |
125 | ** Modified mail-address in header. | |
126 | ** | |
127 | ** Revision 1.46 2010/04/23 09:57:28 gerlof | |
128 | ** Version (flag -V) handled earlier after startup. | |
129 | ** | |
130 | ** Revision 1.45 2010/04/17 17:19:41 gerlof | |
131 | ** Allow modifying the layout of the columns in the system lines. | |
132 | ** | |
133 | ** Revision 1.44 2010/04/16 13:00:23 gerlof | |
134 | ** Automatically start another version of atop if the logfile to | |
135 | ** be read has not been created by the current version. | |
136 | ** | |
137 | ** Revision 1.43 2010/03/04 10:51:10 gerlof | |
138 | ** Support I/O-statistics on logical volumes and MD devices. | |
139 | ** | |
140 | ** Revision 1.42 2009/12/31 11:33:33 gerlof | |
141 | ** Sanity-check to bypass kernel-bug showing 497 days of CPU-consumption. | |
142 | ** | |
143 | ** Revision 1.41 2009/12/17 10:51:31 gerlof | |
144 | ** Allow own defined process line with key 'o' and a definition | |
145 | ** in the atoprc file. | |
146 | ** | |
147 | ** Revision 1.40 2009/12/17 08:15:15 gerlof | |
148 | ** Introduce branch-key to go to specific time in raw file. | |
149 | ** | |
150 | ** Revision 1.39 2009/12/10 13:34:32 gerlof | |
151 | ** Cosmetical changes. | |
152 | ** | |
153 | ** Revision 1.38 2009/12/10 11:55:38 gerlof | |
154 | ** Introduce -L flag for line length. | |
155 | ** | |
156 | ** Revision 1.37 2009/12/10 10:43:33 gerlof | |
157 | ** Correct calculation of node name. | |
158 | ** | |
159 | ** Revision 1.36 2009/12/10 09:19:06 gerlof | |
160 | ** Various changes related to redesign of user-interface. | |
161 | ** Made by JC van Winkel. | |
162 | ** | |
163 | ** Revision 1.35 2009/11/27 15:11:55 gerlof | |
164 | ** *** empty log message *** | |
165 | ** | |
166 | ** Revision 1.34 2009/11/27 15:07:25 gerlof | |
167 | ** Give up root-priviliges at a earlier stage. | |
168 | ** | |
169 | ** Revision 1.33 2009/11/27 14:01:01 gerlof | |
170 | ** Introduce system-wide configuration file /etc/atoprc | |
171 | ** | |
117 | 172 | ** Revision 1.32 2008/01/07 10:16:13 gerlof |
118 | 173 | ** Implement summaries for atopsar. |
119 | 174 | ** |
215 | 270 | ** |
216 | 271 | */ |
217 | 272 | |
218 | static const char rcsid[] = "$Id: atop.c,v 1.32 2008/01/07 10:16:13 gerlof Exp $"; | |
273 | static const char rcsid[] = "$Id: atop.c,v 1.49 2010/10/23 14:01:00 gerlof Exp $"; | |
219 | 274 | |
220 | 275 | #include <sys/types.h> |
221 | 276 | #include <sys/param.h> |
242 | 297 | #include "showgeneric.h" |
243 | 298 | #include "parseable.h" |
244 | 299 | |
245 | #define allflags "ab:cde:fghijklmnopqrstuvwxyz1ABCDEFGHIJKLMNOP:QRSTUVWXYZ" | |
300 | #define allflags "ab:cde:fghijklmnopqrstuvwxyz1ABCDEFGHIJKL:MNOP:QRSTUVWXYZ" | |
246 | 301 | #define PROCCHUNK 50 /* process-entries for future expansion */ |
247 | 302 | #define MAXFL 64 /* maximum number of command-line flags */ |
248 | 303 | |
250 | 305 | ** declaration of global variables |
251 | 306 | */ |
252 | 307 | struct utsname utsname; |
308 | int utsnodenamelen; | |
253 | 309 | time_t pretime; /* timing info */ |
254 | 310 | time_t curtime; /* timing info */ |
255 | 311 | unsigned long interval = 10; |
256 | 312 | unsigned long sampcnt; |
257 | 313 | char screen; |
314 | int linelen = 80; | |
258 | 315 | char acctactive; /* accounting active (boolean) */ |
259 | 316 | char rawname[RAWNAMESZ]; |
260 | 317 | char rawreadflag; |
318 | unsigned int begintime, endtime; | |
261 | 319 | char flaglist[MAXFL]; |
262 | 320 | char deviatonly = 1; |
263 | 321 | unsigned short hertz; |
267 | 325 | int ossub; |
268 | 326 | |
269 | 327 | int supportflags; /* supported features */ |
328 | char **argvp; | |
329 | ||
270 | 330 | |
271 | 331 | struct visualize vis = {generic_samp, generic_error, |
272 | 332 | generic_end, generic_usage}; |
277 | 337 | static char awaittrigger; /* boolean: awaiting trigger */ |
278 | 338 | static unsigned int nsamples = 0xffffffff; |
279 | 339 | static char midnightflag; |
280 | static unsigned int begintime, endtime; | |
281 | ||
282 | /* | |
283 | ** interpretation of defaults-file $HOME/.atop | |
284 | */ | |
285 | void do_flags(char *); | |
286 | void do_interval(char *); | |
287 | void do_username(char *); | |
288 | void do_procname(char *); | |
289 | void do_maxcpu(char *); | |
290 | void do_maxdisk(char *); | |
291 | void do_maxintf(char *); | |
292 | void do_cpucritperc(char *); | |
293 | void do_memcritperc(char *); | |
294 | void do_swpcritperc(char *); | |
295 | void do_dskcritperc(char *); | |
296 | void do_netcritperc(char *); | |
297 | void do_swoutcritsec(char *); | |
298 | void do_almostcrit(char *); | |
299 | void do_atopsarflags(char *); | |
340 | ||
341 | /* | |
342 | ** interpretation of defaults-file /etc/atoprc and $HOME/.atop | |
343 | */ | |
344 | static void readrc(char *); | |
345 | ||
346 | void do_flags(char *, char *); | |
347 | void do_interval(char *, char *); | |
348 | void do_linelength(char *, char *); | |
349 | void do_username(char *, char *); | |
350 | void do_procname(char *, char *); | |
351 | void do_maxcpu(char *, char *); | |
352 | void do_maxdisk(char *, char *); | |
353 | void do_maxmdd(char *, char *); | |
354 | void do_maxlvm(char *, char *); | |
355 | void do_maxintf(char *, char *); | |
356 | void do_ownsysprcline(char *, char *); | |
357 | void do_ownallcpuline(char *, char *); | |
358 | void do_ownindivcpuline(char *, char *); | |
359 | void do_owncplline(char *, char *); | |
360 | void do_ownmemline(char *, char *); | |
361 | void do_ownswpline(char *, char *); | |
362 | void do_ownpagline(char *, char *); | |
363 | void do_owndskline(char *, char *); | |
364 | void do_ownnettransportline(char *, char *); | |
365 | void do_ownnetnetline(char *, char *); | |
366 | void do_ownnetinterfaceline(char *, char *); | |
367 | void do_ownprocline(char *, char *); | |
368 | void do_cpucritperc(char *, char *); | |
369 | void do_memcritperc(char *, char *); | |
370 | void do_swpcritperc(char *, char *); | |
371 | void do_dskcritperc(char *, char *); | |
372 | void do_netcritperc(char *, char *); | |
373 | void do_swoutcritsec(char *, char *); | |
374 | void do_almostcrit(char *, char *); | |
375 | void do_atopsarflags(char *, char *); | |
300 | 376 | |
301 | 377 | static struct { |
302 | 378 | char *tag; |
303 | void (*func)(char *); | |
379 | void (*func)(char *, char *); | |
304 | 380 | } manrc[] = { |
305 | 381 | { "flags", do_flags }, |
306 | 382 | { "interval", do_interval }, |
383 | { "linelen", do_linelength }, | |
307 | 384 | { "username", do_username }, |
308 | 385 | { "procname", do_procname }, |
309 | 386 | { "maxlinecpu", do_maxcpu }, |
310 | 387 | { "maxlinedisk", do_maxdisk }, |
388 | { "maxlinemdd", do_maxmdd }, | |
389 | { "maxlinelvm", do_maxlvm }, | |
311 | 390 | { "maxlineintf", do_maxintf }, |
391 | { "ownallcpuline", do_ownallcpuline }, | |
392 | { "ownonecpuline", do_ownindivcpuline }, | |
393 | { "owncplline", do_owncplline }, | |
394 | { "ownmemline", do_ownmemline }, | |
395 | { "ownswpline", do_ownswpline }, | |
396 | { "ownpagline", do_ownpagline }, | |
397 | { "owndskline", do_owndskline }, | |
398 | { "ownnettrline", do_ownnettransportline }, | |
399 | { "ownnetnetline", do_ownnetnetline }, | |
400 | { "ownnetifline", do_ownnetinterfaceline }, | |
401 | { "ownprocline", do_ownprocline }, | |
402 | { "ownsysprcline", do_ownsysprcline }, | |
403 | { "owndskline", do_owndskline }, | |
312 | 404 | { "cpucritperc", do_cpucritperc }, |
313 | 405 | { "memcritperc", do_memcritperc }, |
314 | 406 | { "swpcritperc", do_swpcritperc }, |
328 | 420 | main(int argc, char *argv[]) |
329 | 421 | { |
330 | 422 | register int i; |
331 | int c, nr, line=0; | |
423 | int c; | |
332 | 424 | char *p; |
333 | 425 | struct rlimit rlim; |
334 | 426 | |
335 | 427 | /* |
336 | ** check if defaults-file $HOME/.atoprc present; | |
337 | ** if so, set defaults specified in this file | |
338 | */ | |
428 | ** since priviliged actions will be done later on, at this stage | |
429 | ** the root-priviliges are dropped by switching effective user-id | |
430 | ** to real user-id (security reasons) | |
431 | */ | |
432 | seteuid ( getuid() ); | |
433 | ||
434 | /* | |
435 | ** preserve command arguments to allow restart of other version | |
436 | */ | |
437 | argvp = argv; | |
438 | ||
439 | /* | |
440 | ** read defaults-files /etc/atoprc en $HOME/.atoprc (if any) | |
441 | */ | |
442 | readrc("/etc/atoprc"); | |
443 | ||
339 | 444 | if ( (p = getenv("HOME")) ) |
340 | 445 | { |
341 | 446 | char path[1024]; |
342 | 447 | |
343 | 448 | snprintf(path, sizeof path, "%s/.atoprc", p); |
344 | 449 | |
345 | /* | |
346 | ** check if this file is readable with the user's | |
347 | ** *real uid/gid* with syscall access() | |
348 | */ | |
349 | if ( access(path, R_OK) == 0) | |
350 | { | |
351 | FILE *fp; | |
352 | char linebuf[256], tagname[16], tagvalue[16]; | |
353 | ||
354 | fp = fopen(path, "r"); | |
355 | ||
356 | while ( fgets(linebuf, sizeof linebuf, fp) ) | |
357 | { | |
358 | line++; | |
359 | ||
360 | nr = sscanf(linebuf, "%15s %15s", | |
361 | tagname, tagvalue); | |
362 | ||
363 | switch (nr) | |
364 | { | |
365 | case 0: | |
366 | continue; | |
367 | ||
368 | case 1: | |
369 | if (tagname[0] == '#') | |
370 | continue; | |
371 | ||
372 | fprintf(stderr, | |
373 | "~/.atoprc: syntax error line " | |
374 | "%d (no value specified)\n", | |
375 | line); | |
376 | ||
377 | cleanstop(1); | |
378 | break; /* not reached */ | |
379 | ||
380 | default: | |
381 | if (tagname[0] == '#') | |
382 | continue; | |
383 | ||
384 | if (tagvalue[0] != '#') | |
385 | break; | |
386 | ||
387 | fprintf(stderr, | |
388 | "~/.atoprc: syntax error line " | |
389 | "%d (no value specified)\n", | |
390 | line); | |
391 | ||
392 | cleanstop(1); | |
393 | } | |
394 | ||
395 | /* | |
396 | ** tag name and tag value found | |
397 | ** try to recognize tag name | |
398 | */ | |
399 | for (i=0; i < sizeof manrc/sizeof manrc[0]; i++) | |
400 | { | |
401 | if ( strcmp(tagname, manrc[i].tag) ==0) | |
402 | { | |
403 | manrc[i].func(tagvalue); | |
404 | break; | |
405 | } | |
406 | } | |
407 | ||
408 | /* | |
409 | ** tag name not recognized | |
410 | */ | |
411 | if (i == sizeof manrc/sizeof manrc[0]) | |
412 | { | |
413 | fprintf(stderr, | |
414 | "~/.atoprc: syntax error line " | |
415 | "%d (tag name %s not valid)\n", | |
416 | line, tagname); | |
417 | ||
418 | cleanstop(1); | |
419 | } | |
420 | } | |
421 | ||
422 | fclose(fp); | |
423 | } | |
450 | readrc(path); | |
424 | 451 | } |
425 | 452 | |
426 | 453 | /* |
432 | 459 | else |
433 | 460 | p = argv[0]; |
434 | 461 | |
435 | if ( strcmp(p, "atopsar") == 0) | |
462 | if ( memcmp(p, "atopsar", 7) == 0) | |
436 | 463 | return atopsar(argc, argv); |
437 | ||
438 | 464 | |
439 | 465 | /* |
440 | 466 | ** interpret command-line arguments & flags |
457 | 483 | prusage(argv[0]); |
458 | 484 | break; |
459 | 485 | |
486 | case 'V': /* version wanted ? */ | |
487 | printf("%s\n", getstrvers()); | |
488 | exit(0); | |
489 | ||
460 | 490 | case 'w': /* writing of raw data ? */ |
461 | 491 | if (optind >= argc) |
462 | 492 | prusage(argv[0]); |
496 | 526 | prusage(argv[0]); |
497 | 527 | |
498 | 528 | vis.show_samp = parseout; |
529 | break; | |
530 | ||
531 | case 'L': /* line length */ | |
532 | if ( !numeric(optarg) ) | |
533 | prusage(argv[0]); | |
534 | ||
535 | linelen = atoi(optarg); | |
499 | 536 | break; |
500 | 537 | |
501 | 538 | default: /* gather other flags */ |
535 | 572 | if ( (p = strchr(utsname.nodename, '.')) ) |
536 | 573 | *p = '\0'; |
537 | 574 | |
575 | utsnodenamelen = strlen(utsname.nodename); | |
576 | ||
538 | 577 | sscanf(utsname.release, "%d.%d.%d", &osrel, &osvers, &ossub); |
539 | 578 | |
540 | 579 | /* |
548 | 587 | */ |
549 | 588 | if (rawreadflag) |
550 | 589 | { |
551 | seteuid( getuid() ); | |
552 | rawread(begintime, endtime); | |
590 | rawread(); | |
553 | 591 | cleanstop(0); |
554 | 592 | } |
555 | 593 | |
557 | 595 | ** determine start-time for gathering current statistics |
558 | 596 | */ |
559 | 597 | curtime = getboot(); |
598 | ||
599 | /* | |
600 | ** catch signals for proper close-down | |
601 | */ | |
602 | signal(SIGHUP, cleanstop); | |
603 | signal(SIGTERM, cleanstop); | |
604 | ||
605 | /* | |
606 | ** regain the root-priviliges that we dropped at the beginning | |
607 | ** to do some priviliged work | |
608 | */ | |
609 | seteuid(0); | |
560 | 610 | |
561 | 611 | /* |
562 | 612 | ** lock ATOP in memory to get reliable samples (also when |
577 | 627 | (void) nice(-20); |
578 | 628 | |
579 | 629 | /* |
580 | ** catch signals for proper close-down | |
581 | */ | |
582 | signal(SIGHUP, cleanstop); | |
583 | signal(SIGTERM, cleanstop); | |
584 | ||
585 | /* | |
586 | 630 | ** switch-on the process-accounting mechanism to register the |
587 | 631 | ** (remaining) resource-usage by processes which have finished |
588 | 632 | */ |
598 | 642 | ** need to keep running under root-priviliges, so switch |
599 | 643 | ** effective user-id to real user-id |
600 | 644 | */ |
601 | seteuid ( getuid() ); | |
645 | seteuid( getuid() ); | |
602 | 646 | |
603 | 647 | /* |
604 | 648 | ** start the engine now ..... |
618 | 662 | { |
619 | 663 | struct sigaction sigact; |
620 | 664 | static time_t timelimit; |
621 | void getusr1(int); | |
665 | void getusr1(int), getusr2(int); | |
622 | 666 | |
623 | 667 | /* |
624 | 668 | ** reserve space for system-level statistics |
637 | 681 | struct pstat *curpexit; /* exitted process list */ |
638 | 682 | struct pstat *devpstat; /* deviation list */ |
639 | 683 | |
640 | int npresent, nexit, n, nzombie; | |
684 | int npresent, nexit, n; | |
685 | int ntrun, ntslpi, ntslpu, nzombie; | |
641 | 686 | |
642 | 687 | /* |
643 | 688 | ** initialization: allocate required memory dynamically |
656 | 701 | } |
657 | 702 | |
658 | 703 | /* |
659 | ** install the signal-handler for ALARM and SIGUSR1 (both triggers | |
704 | ** install the signal-handler for ALARM, USR1 and USR2 (triggers | |
660 | 705 | * for the next sample) |
661 | 706 | */ |
662 | 707 | memset(&sigact, 0, sizeof sigact); |
663 | 708 | sigact.sa_handler = getusr1; |
664 | 709 | sigaction(SIGUSR1, &sigact, (struct sigaction *)0); |
710 | ||
711 | memset(&sigact, 0, sizeof sigact); | |
712 | sigact.sa_handler = getusr2; | |
713 | sigaction(SIGUSR2, &sigact, (struct sigaction *)0); | |
665 | 714 | |
666 | 715 | memset(&sigact, 0, sizeof sigact); |
667 | 716 | sigact.sa_handler = getalarm; |
710 | 759 | |
711 | 760 | /* |
712 | 761 | ** wait for alarm-signal to arrive (except first sample) |
713 | ** or wait for SIGUSR1 in case of an interval of 0. | |
762 | ** or wait for SIGUSR1/SIGUSR2 | |
714 | 763 | */ |
715 | 764 | if (sampcnt > 0 && awaittrigger) |
716 | 765 | pause(); |
780 | 829 | devpstat = malloc((npresent+nexit) * sizeof(struct pstat)); |
781 | 830 | |
782 | 831 | n = deviatproc(curpact, npresent, curpexit, nexit, |
783 | deviatonly, devpstat, &nzombie); | |
832 | deviatonly, devpstat, devsstat, | |
833 | &ntrun, &ntslpi, &ntslpu, &nzombie); | |
784 | 834 | |
785 | 835 | /* |
786 | 836 | ** activate the installed print-function to visualize |
789 | 839 | lastcmd = (vis.show_samp)( curtime, |
790 | 840 | curtime-pretime > 0 ? curtime-pretime : 1, |
791 | 841 | devsstat, devpstat, n, npresent, |
792 | nzombie, nexit, sampcnt==0); | |
842 | ntrun, ntslpi, ntslpu, nzombie, | |
843 | nexit, sampcnt==0); | |
793 | 844 | |
794 | 845 | /* |
795 | 846 | ** release dynamically allocated memory |
834 | 885 | printf("\t -%c show or log all processes (i.s.o. active processes " |
835 | 886 | "only)\n", MALLPROC); |
836 | 887 | printf("\t -P generate parseable output for specified label(s)\n"); |
888 | printf("\t -L alternate line length (default 80) in case of " | |
889 | "non-screen output\n"); | |
837 | 890 | |
838 | 891 | (*vis.show_usage)(); |
839 | 892 | |
841 | 894 | printf("\tspecific flags for raw logfiles:\n"); |
842 | 895 | printf("\t -w write raw data to file (compressed)\n"); |
843 | 896 | printf("\t -r read raw data from file (compressed)\n"); |
897 | printf("\t special file: y[y...] for yesterday (repeated)\n"); | |
844 | 898 | printf("\t -S finish atop automatically before midnight " |
845 | 899 | "(i.s.o. #samples)\n"); |
846 | 900 | printf("\t -b begin showing data from specified time\n"); |
854 | 908 | " (kill -USR1 pid_atop)\n"); |
855 | 909 | printf("or with the keystroke '%c' in interactive mode.\n", MSAMPNEXT); |
856 | 910 | |
857 | ||
858 | 911 | cleanstop(1); |
859 | 912 | } |
860 | 913 | |
880 | 933 | } |
881 | 934 | |
882 | 935 | /* |
936 | ** handler for USR2-signal | |
937 | */ | |
938 | void | |
939 | getusr2(int sig) | |
940 | { | |
941 | awaittrigger=0; | |
942 | nsamples = sampcnt; // force stop after next sample | |
943 | } | |
944 | ||
945 | /* | |
883 | 946 | ** functions to handle a particular tag in the .atoprc file |
884 | 947 | */ |
948 | extern int get_posval(char *name, char *val); | |
949 | ||
885 | 950 | void |
886 | do_interval(char *val) | |
951 | do_interval(char *name, char *val) | |
887 | 952 | { |
888 | if (numeric(val)) | |
953 | interval = get_posval(name, val); | |
954 | } | |
955 | ||
956 | void | |
957 | do_linelength(char *name, char *val) | |
958 | { | |
959 | linelen = get_posval(name, val); | |
960 | } | |
961 | ||
962 | /* | |
963 | ** read RC-file and modify defaults accordingly | |
964 | */ | |
965 | static void | |
966 | readrc(char *path) | |
967 | { | |
968 | int i, nr, line=0, errorcnt = 0; | |
969 | ||
970 | /* | |
971 | ** check if this file is readable with the user's | |
972 | ** *real uid/gid* with syscall access() | |
973 | */ | |
974 | if ( access(path, R_OK) == 0) | |
889 | 975 | { |
890 | interval = atoi(val); | |
891 | } | |
892 | else | |
893 | { | |
894 | fprintf(stderr, ".atoprc: interval value not numeric\n"); | |
895 | exit(1); | |
976 | FILE *fp; | |
977 | char linebuf[256], tagname[20], tagvalue[256]; | |
978 | ||
979 | fp = fopen(path, "r"); | |
980 | ||
981 | while ( fgets(linebuf, sizeof linebuf, fp) ) | |
982 | { | |
983 | line++; | |
984 | ||
985 | i = strlen(linebuf); | |
986 | ||
987 | if (i > 0 && linebuf[i-1] == '\n') | |
988 | linebuf[i-1] = 0; | |
989 | ||
990 | nr = sscanf(linebuf, "%19s %255[^#]", | |
991 | tagname, tagvalue); | |
992 | ||
993 | switch (nr) | |
994 | { | |
995 | case 0: | |
996 | continue; | |
997 | ||
998 | case 1: | |
999 | if (tagname[0] == '#') | |
1000 | continue; | |
1001 | ||
1002 | fprintf(stderr, | |
1003 | "%s: syntax error line " | |
1004 | "%d (no value specified)\n", | |
1005 | path, line); | |
1006 | ||
1007 | cleanstop(1); | |
1008 | break; /* not reached */ | |
1009 | ||
1010 | default: | |
1011 | if (tagname[0] == '#') | |
1012 | continue; | |
1013 | ||
1014 | if (tagvalue[0] != '#') | |
1015 | break; | |
1016 | ||
1017 | fprintf(stderr, | |
1018 | "%s: syntax error line " | |
1019 | "%d (no value specified)\n", | |
1020 | path, line); | |
1021 | ||
1022 | cleanstop(1); | |
1023 | } | |
1024 | ||
1025 | /* | |
1026 | ** tag name and tag value found | |
1027 | ** try to recognize tag name | |
1028 | */ | |
1029 | for (i=0; i < sizeof manrc/sizeof manrc[0]; i++) | |
1030 | { | |
1031 | if ( strcmp(tagname, manrc[i].tag) ==0) | |
1032 | { | |
1033 | manrc[i].func(tagname, tagvalue); | |
1034 | break; | |
1035 | } | |
1036 | } | |
1037 | ||
1038 | /* | |
1039 | ** tag name not recognized | |
1040 | */ | |
1041 | if (i == sizeof manrc/sizeof manrc[0]) | |
1042 | { | |
1043 | fprintf(stderr, | |
1044 | "%s: warning at line %2d " | |
1045 | "- tag name %s not valid\n", | |
1046 | path, line, tagname); | |
1047 | ||
1048 | errorcnt++; | |
1049 | } | |
1050 | } | |
1051 | ||
1052 | if (errorcnt) | |
1053 | sleep(2); | |
1054 | ||
1055 | fclose(fp); | |
896 | 1056 | } |
897 | 1057 | } |
8 | 8 | # |
9 | 9 | if [ -e $PIDFILE ] && ps -p `cat $PIDFILE` | grep 'atop$' > /dev/null |
10 | 10 | then |
11 | kill -USR1 `cat $PIDFILE` # take final sample | |
12 | sleep 3 | |
13 | kill -TERM `cat $PIDFILE` | |
11 | kill -USR2 `cat $PIDFILE` # final sample and terminate | |
12 | ||
13 | CNT=0 | |
14 | ||
15 | while ps -p `cat $PIDFILE` > /dev/null | |
16 | do | |
17 | let CNT+=1 | |
18 | ||
19 | if [ $CNT -gt 5 ] | |
20 | then | |
21 | break; | |
22 | fi | |
23 | ||
24 | sleep 1 | |
25 | done | |
26 | ||
14 | 27 | rm $PIDFILE |
15 | sleep 1 | |
16 | 28 | fi |
17 | 29 | |
18 | 30 | # start atop for all processes with interval of 10 minutes |
5 | 5 | ** |
6 | 6 | ** Include-file describing miscellaneous constants and function-prototypes. |
7 | 7 | ** ================================================================ |
8 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
9 | ** E-mail: gerlof@ATComputing.nl | |
8 | ** Author: Gerlof Langeveld | |
9 | ** E-mail: gerlof.langeveld@atoptool.nl | |
10 | 10 | ** Date: November 1996 |
11 | 11 | ** LINUX-port: June 2000 |
12 | 12 | ** |
31 | 31 | #define KBFORMAT 1 |
32 | 32 | #define MBFORMAT 2 |
33 | 33 | #define GBFORMAT 3 |
34 | #define TBFORMAT 4 | |
34 | 35 | #define OVFORMAT 9 |
35 | 36 | |
36 | 37 | typedef long long count_t; |
46 | 47 | |
47 | 48 | struct visualize { |
48 | 49 | char (*show_samp) (time_t, int, struct sstat *, struct pstat *, |
49 | int, int, int, int, char); | |
50 | int, int, int, int, int, int, int, char); | |
50 | 51 | void (*show_error) (const char *, ...); |
51 | 52 | void (*show_end) (void); |
52 | 53 | void (*show_usage) (void); |
56 | 57 | ** external values |
57 | 58 | */ |
58 | 59 | extern struct utsname utsname; |
60 | extern int utsnodenamelen; | |
59 | 61 | extern time_t pretime; |
60 | 62 | extern time_t curtime; |
61 | 63 | extern unsigned long interval; |
62 | 64 | extern unsigned long sampcnt; |
63 | 65 | extern char screen; |
66 | extern int linelen; | |
64 | 67 | extern char deviatonly; |
65 | 68 | extern char rawname[]; |
66 | 69 | extern char rawreadflag; |
70 | extern unsigned int begintime, endtime; | |
67 | 71 | extern char flaglist[]; |
68 | 72 | extern struct visualize vis; |
69 | 73 | |
95 | 99 | /* |
96 | 100 | ** structure containing the start-addresses of functions for visualization |
97 | 101 | */ |
98 | char generic_samp(time_t, int, struct sstat *, struct pstat *, | |
99 | int, int, int, int, char); | |
102 | char generic_samp (time_t, int, struct sstat *, struct pstat *, | |
103 | int, int, int, int, int, int, int, char); | |
100 | 104 | void generic_error(const char *, ...); |
101 | void generic_end(void); | |
105 | void generic_end (void); | |
102 | 106 | void generic_usage(void); |
103 | 107 | |
104 | 108 | /* |
113 | 117 | char *val2valstr(count_t, char *, int, int, int); |
114 | 118 | char *val2memstr(count_t, char *, int, int, int); |
115 | 119 | char *val2cpustr(count_t, char *); |
120 | char *val2Hzstr(count_t, char *); | |
121 | int val2elapstr(int, char *); | |
116 | 122 | |
117 | 123 | int compcpu(const void *, const void *); |
118 | 124 | int compdsk(const void *, const void *); |
126 | 132 | int intfcompar(const void *, const void *); |
127 | 133 | |
128 | 134 | count_t subcount(count_t, count_t); |
129 | void rawread(unsigned int, unsigned int); | |
135 | void rawread(void); | |
130 | 136 | char rawwrite(time_t, int, struct sstat *, struct pstat *, |
131 | int, int, int, int, char); | |
137 | int, int, int, int, int, int, int, char); | |
132 | 138 | |
133 | 139 | int numeric(char *); |
134 | 140 | void getalarm(int); |
30 | 30 | # |
31 | 31 | if [ -e $PIDFILE ] && ps -p `cat $PIDFILE` | grep 'atop$' > /dev/null |
32 | 32 | then |
33 | kill -USR1 `cat $PIDFILE` # take final sample | |
34 | sleep 3 | |
35 | kill -TERM `cat $PIDFILE` | |
33 | kill -USR2 `cat $PIDFILE` # final sample and terminate | |
34 | ||
35 | CNT=0 | |
36 | ||
37 | while ps -p `cat $PIDFILE` > /dev/null | |
38 | do | |
39 | let CNT+=1 | |
40 | ||
41 | if [ $CNT -gt 5 ] | |
42 | then | |
43 | break; | |
44 | fi | |
45 | ||
46 | sleep 1 | |
47 | done | |
48 | ||
36 | 49 | rm $PIDFILE |
37 | sleep 1 | |
38 | 50 | fi |
39 | 51 | ;; |
40 | 52 |
6 | 6 | ** This source-file contains the 'atopsar'-functionality, that makes use |
7 | 7 | ** of the 'atop'-framework. |
8 | 8 | ** ========================================================================== |
9 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: gerlof@ATComputing.nl | |
9 | ** Author: Gerlof Langeveld | |
10 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | 11 | ** Date: July 2007 |
12 | 12 | ** -------------------------------------------------------------------------- |
13 | ** Copyright (C) 2007, 2008 Gerlof Langeveld | |
13 | ** Copyright (C) 2007-2010 Gerlof Langeveld | |
14 | 14 | ** |
15 | 15 | ** This program is free software; you can redistribute it and/or modify it |
16 | 16 | ** under the terms of the GNU General Public License as published by the |
29 | 29 | ** |
30 | 30 | */ |
31 | 31 | |
32 | static const char rcsid[] = "$Id: atopsar.c,v 1.17 2008/02/26 13:44:53 gerlof Exp $"; | |
32 | static const char rcsid[] = "$Id: atopsar.c,v 1.27 2010/10/23 14:16:57 gerlof Exp $"; | |
33 | 33 | |
34 | 34 | #include <sys/types.h> |
35 | 35 | #include <sys/param.h> |
69 | 69 | ** miscellaneous values |
70 | 70 | */ |
71 | 71 | static unsigned int nsamples = 9999999; |
72 | static unsigned int begintime, endtime; | |
73 | 72 | static char stampalways; |
74 | 73 | static char usecolors = 't'; |
75 | 74 | static char usemarkers; |
105 | 104 | static void engine(void); |
106 | 105 | static void pratopsaruse(char *); |
107 | 106 | static void reportlive(time_t, int, struct sstat *); |
108 | static char reportraw (time_t, int, struct sstat *, | |
109 | struct pstat *, int, int, int, int, char); | |
107 | static char reportraw (time_t, int, struct sstat *, struct pstat *, | |
108 | int, int, int, int, int, int, int, char); | |
110 | 109 | static void reportheader(struct utsname *, time_t); |
111 | 110 | static time_t daylimit(time_t); |
112 | 111 | |
291 | 290 | */ |
292 | 291 | if (rawreadflag) |
293 | 292 | { |
294 | seteuid( getuid() ); /* get rid of root privileges */ | |
295 | ||
296 | 293 | /* |
297 | 294 | ** select own reportraw-function to be called |
298 | 295 | ** by the rawread function |
305 | 302 | { |
306 | 303 | prinow = i; |
307 | 304 | daylim = 0; |
308 | rawread(begintime, endtime); | |
305 | rawread(); | |
309 | 306 | printf("\n"); |
310 | 307 | } |
311 | 308 | } |
336 | 333 | ** determine start-time for gathering current statistics |
337 | 334 | */ |
338 | 335 | curtime = time(0); |
336 | ||
337 | /* | |
338 | ** regain the root-priviliges that we dropped at the beginning | |
339 | ** to do some priviliged work now | |
340 | */ | |
341 | seteuid(0); | |
339 | 342 | |
340 | 343 | /* |
341 | 344 | ** lock in memory to get reliable samples (also when |
519 | 522 | numsecs, numsecs*hertz, hertz, |
520 | 523 | osvers, osrel, ossub, |
521 | 524 | stampalways ? timebuf : " ", |
522 | 0, 0, 0) ) | |
525 | 0, 0, 0, 0, 0, 0) ) | |
523 | 526 | { |
524 | 527 | /* |
525 | 528 | ** print line has failed; |
588 | 591 | numsecs, numsecs*hertz, hertz, |
589 | 592 | osvers, osrel, ossub, |
590 | 593 | stampalways ? timebuf : " ", |
591 | 0, 0, 0) ) ) | |
594 | 0, 0, 0, 0, 0, 0) ) ) | |
592 | 595 | { |
593 | 596 | /* |
594 | 597 | ** print line has failed; |
629 | 632 | static char |
630 | 633 | reportraw(time_t curtime, int numsecs, |
631 | 634 | struct sstat *ss, struct pstat *ps, |
632 | int nlist, int npresent, int nzombie, | |
633 | int nexit, char flags) | |
635 | int nlist, int npresent, int ntrun, int ntslpi, int ntslpu, | |
636 | int nzombie, int nexit, char flags) | |
634 | 637 | { |
635 | 638 | static char firstcall = 1; |
636 | 639 | char timebuf[16], datebuf[16]; |
637 | 640 | unsigned int rv; |
638 | 641 | static unsigned int curline, headline, sampsum, |
639 | totalsec, totalexit, | |
640 | lastnpres, lastnzomb; | |
642 | totalsec, totalexit, lastnpres, | |
643 | lastntrun, lastntslpi, lastntslpu, lastnzomb; | |
641 | 644 | static time_t lasttime; |
642 | 645 | static struct sstat totsyst; |
643 | 646 | |
733 | 736 | totalsec, totalsec*hertz, hertz, |
734 | 737 | osvers, osrel, ossub, |
735 | 738 | stampalways ? timebuf : " ", |
736 | lastnpres, totalexit, lastnzomb); | |
739 | lastnpres, lastntrun, lastntslpi, lastntslpu, | |
740 | totalexit, lastnzomb); | |
737 | 741 | |
738 | 742 | if (rv == 0) |
739 | 743 | { |
783 | 787 | numsecs, numsecs*hertz, hertz, |
784 | 788 | osvers, osrel, ossub, |
785 | 789 | stampalways ? timebuf : " ", |
786 | npresent, nexit, nzombie); | |
790 | nlist, ntrun, ntslpi, ntslpu, nexit, nzombie); | |
787 | 791 | |
788 | 792 | if (rv == 0) |
789 | 793 | { |
820 | 824 | */ |
821 | 825 | lasttime = curtime; |
822 | 826 | lastnpres = npresent; |
827 | lastntrun = ntrun; | |
828 | lastntslpi = ntslpi; | |
829 | lastntslpu = ntslpu; | |
823 | 830 | lastnzomb = nzombie; |
824 | 831 | |
825 | 832 | /* |
837 | 844 | totalsec, totalsec*hertz, hertz, |
838 | 845 | osvers, osrel, ossub, |
839 | 846 | stampalways ? timebuf : " ", |
840 | npresent, totalexit, nzombie); | |
847 | nlist, ntrun, ntslpi, ntslpu, | |
848 | totalexit, nzombie); | |
841 | 849 | |
842 | 850 | if (rv == 0) |
843 | 851 | { |
919 | 927 | fprintf(stderr, |
920 | 928 | "\t -r read statistical data from specific atop logfile\n"); |
921 | 929 | fprintf(stderr, |
922 | "\t (pathname, or date in format YYYYMMDD)\n"); | |
930 | "\t (pathname, or date in format YYYYMMDD, or y[y..])\n"); | |
923 | 931 | fprintf(stderr, |
924 | 932 | "\t -R summarize <cnt> samples into one sample\n"); |
925 | 933 | fprintf(stderr, |
1105 | 1113 | static void |
1106 | 1114 | cpuhead(int osvers, int osrel, int ossub) |
1107 | 1115 | { |
1108 | printf("cpu %%usr %%nice %%sys %%irq %%softirq %%steal " | |
1109 | " %%wait %%idle _cpu_"); | |
1116 | printf("cpu %%usr %%nice %%sys %%irq %%softirq %%steal %%guest " | |
1117 | " %%wait %%idle _cpu_"); | |
1110 | 1118 | } |
1111 | 1119 | |
1112 | 1120 | static int |
1113 | 1121 | cpuline(struct sstat *ss, struct pstat *ps, int nproc, |
1114 | 1122 | time_t deltasec, time_t deltatic, time_t hz, |
1115 | 1123 | int osvers, int osrel, int ossub, char *tstamp, |
1116 | int ppres, int pexit, int pzombie) | |
1124 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1117 | 1125 | { |
1118 | 1126 | register int i, nlines = 1; |
1119 | 1127 | count_t cputot; |
1125 | 1133 | cputot = ss->cpu.all.stime + ss->cpu.all.utime + |
1126 | 1134 | ss->cpu.all.ntime + ss->cpu.all.itime + |
1127 | 1135 | ss->cpu.all.wtime + ss->cpu.all.Itime + |
1128 | ss->cpu.all.Stime + ss->cpu.all.steal; | |
1136 | ss->cpu.all.Stime + ss->cpu.all.steal + | |
1137 | ss->cpu.all.guest; | |
1129 | 1138 | |
1130 | 1139 | if (cputot == 0) |
1131 | 1140 | cputot = 1; /* avoid divide-by-zero */ |
1138 | 1147 | |
1139 | 1148 | preprint(badness); |
1140 | 1149 | |
1141 | printf("all %6.0lf %6.0lf %6.0lf %5.0lf %8.0lf %8.0f %6.0lf %6.0lf", | |
1150 | printf("all %5.0lf %5.0lf %4.0lf %4.0lf %8.0lf %7.0f %6.0f %6.0lf %5.0lf", | |
1142 | 1151 | (double) (ss->cpu.all.utime * 100.0) / cputot * ss->cpu.nrcpu, |
1143 | 1152 | (double) (ss->cpu.all.ntime * 100.0) / cputot * ss->cpu.nrcpu, |
1144 | 1153 | (double) (ss->cpu.all.stime * 100.0) / cputot * ss->cpu.nrcpu, |
1145 | 1154 | (double) (ss->cpu.all.Itime * 100.0) / cputot * ss->cpu.nrcpu, |
1146 | 1155 | (double) (ss->cpu.all.Stime * 100.0) / cputot * ss->cpu.nrcpu, |
1147 | 1156 | (double) (ss->cpu.all.steal * 100.0) / cputot * ss->cpu.nrcpu, |
1157 | (double) (ss->cpu.all.guest * 100.0) / cputot * ss->cpu.nrcpu, | |
1148 | 1158 | (double) (ss->cpu.all.wtime * 100.0) / cputot * ss->cpu.nrcpu, |
1149 | 1159 | (double) (ss->cpu.all.itime * 100.0) / cputot * ss->cpu.nrcpu); |
1150 | 1160 | |
1160 | 1170 | cputot = ss->cpu.cpu[i].stime + ss->cpu.cpu[i].utime + |
1161 | 1171 | ss->cpu.cpu[i].ntime + ss->cpu.cpu[i].itime + |
1162 | 1172 | ss->cpu.cpu[i].wtime + ss->cpu.cpu[i].Itime + |
1163 | ss->cpu.cpu[i].Stime + ss->cpu.cpu[i].steal; | |
1173 | ss->cpu.cpu[i].Stime + ss->cpu.cpu[i].steal + | |
1174 | ss->cpu.cpu[i].guest; | |
1164 | 1175 | |
1165 | 1176 | if (cputot == 0) |
1166 | 1177 | cputot = 1; /* avoid divide-by-zero */ |
1176 | 1187 | |
1177 | 1188 | preprint(badness); |
1178 | 1189 | |
1179 | printf("%4d %6.0lf %6.0lf %6.0lf %5.0lf %8.0lf " | |
1180 | "%8.0f %6.0lf %6.0lf", | |
1190 | printf("%4d %5.0lf %5.0lf %4.0lf %4.0lf %8.0lf " | |
1191 | "%7.0f %6.0lf %6.0lf %5.0lf", | |
1181 | 1192 | i, |
1182 | 1193 | (double)(ss->cpu.cpu[i].utime * 100.0) / cputot, |
1183 | 1194 | (double)(ss->cpu.cpu[i].ntime * 100.0) / cputot, |
1185 | 1196 | (double)(ss->cpu.cpu[i].Itime * 100.0) / cputot, |
1186 | 1197 | (double)(ss->cpu.cpu[i].Stime * 100.0) / cputot, |
1187 | 1198 | (double)(ss->cpu.cpu[i].steal * 100.0) / cputot, |
1199 | (double)(ss->cpu.cpu[i].guest * 100.0) / cputot, | |
1188 | 1200 | (double)(ss->cpu.cpu[i].wtime * 100.0) / cputot, |
1189 | 1201 | (double)(ss->cpu.cpu[i].itime * 100.0) / cputot); |
1190 | 1202 | |
1211 | 1223 | procline(struct sstat *ss, struct pstat *ps, int nproc, |
1212 | 1224 | time_t deltasec, time_t deltatic, time_t hz, |
1213 | 1225 | int osvers, int osrel, int ossub, char *tstamp, |
1214 | int ppres, int pexit, int pzombie) | |
1226 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1215 | 1227 | { |
1216 | 1228 | printf("%7.0lf %9.0lf %9.2lf %8.2lf %8.2lf %8.2lf\n", |
1217 | 1229 | (double)ss->cpu.csw / deltasec, |
1235 | 1247 | taskline(struct sstat *ss, struct pstat *ps, int nproc, |
1236 | 1248 | time_t deltasec, time_t deltatic, time_t hz, |
1237 | 1249 | int osvers, int osrel, int ossub, char *tstamp, |
1238 | int ppres, int pexit, int pzombie) | |
1250 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1239 | 1251 | { |
1240 | 1252 | if (ppres == 0) |
1241 | 1253 | { |
1245 | 1257 | |
1246 | 1258 | if (ps) /* process statistics available */ |
1247 | 1259 | { |
1248 | int i; | |
1249 | long int trun, tslpi, tslpu; | |
1250 | ||
1251 | /* | |
1252 | ** accumulate number of threads per state | |
1253 | */ | |
1254 | for (i=0, trun=tslpi=tslpu=0; i < nproc; i++) | |
1255 | { | |
1256 | trun += (ps+i)->gen.nthrrun; | |
1257 | tslpi += (ps+i)->gen.nthrslpi; | |
1258 | tslpu += (ps+i)->gen.nthrslpu; | |
1259 | } | |
1260 | ||
1261 | printf("%8.2lf %7.2lf %7d %7d %6ld %7ld %7ld\n", | |
1260 | printf("%8.2lf %7.2lf %7d %7d %6d %7d %7d\n", | |
1262 | 1261 | (double)ss->cpu.nprocs / deltasec, |
1263 | 1262 | (double)pexit / deltasec, |
1264 | ppres, pzombie, trun, tslpi, tslpu); | |
1263 | ppres, pzombie, ntrun, ntslpi, ntslpu); | |
1265 | 1264 | } |
1266 | 1265 | else |
1267 | 1266 | { |
1280 | 1279 | static void |
1281 | 1280 | memhead(int osvers, int osrel, int ossub) |
1282 | 1281 | { |
1283 | printf("memtotal memfree buffers cached slabmem" | |
1284 | " swptotal swpfree _mem_" ); | |
1282 | printf("memtotal memfree buffers cached dirty slabmem" | |
1283 | " swptotal swpfree _mem_" ); | |
1285 | 1284 | } |
1286 | 1285 | |
1287 | 1286 | static int |
1288 | 1287 | memline(struct sstat *ss, struct pstat *ps, int nproc, |
1289 | 1288 | time_t deltasec, time_t deltatic, time_t hz, |
1290 | 1289 | int osvers, int osrel, int ossub, char *tstamp, |
1291 | int ppres, int pexit, int pzombie) | |
1290 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1292 | 1291 | { |
1293 | 1292 | unsigned int mbadness, sbadness; |
1294 | 1293 | |
1309 | 1308 | |
1310 | 1309 | preprint(mbadness >= sbadness ? mbadness : sbadness); |
1311 | 1310 | |
1312 | printf("%7lldM %6lldM %6lldM %7lldM %7lldM %7lldM %6lldM", | |
1311 | printf("%7lldM %6lldM %6lldM %5lldM %4lldM %6lldM %7lldM %6lldM", | |
1313 | 1312 | ss->mem.physmem * (pagesize / 1024) /1024, |
1314 | 1313 | ss->mem.freemem * (pagesize / 1024) /1024, |
1315 | 1314 | ss->mem.buffermem * (pagesize / 1024) /1024, |
1316 | 1315 | ss->mem.cachemem * (pagesize / 1024) /1024, |
1316 | ss->mem.cachedrt * (pagesize / 1024) /1024, | |
1317 | 1317 | ss->mem.slabmem * (pagesize / 1024) /1024, |
1318 | 1318 | ss->mem.totswap * (pagesize / 1024) /1024, |
1319 | 1319 | ss->mem.freeswap * (pagesize / 1024) /1024); |
1337 | 1337 | swapline(struct sstat *ss, struct pstat *ps, int nproc, |
1338 | 1338 | time_t deltasec, time_t deltatic, time_t hz, |
1339 | 1339 | int osvers, int osrel, int ossub, char *tstamp, |
1340 | int ppres, int pexit, int pzombie) | |
1340 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1341 | 1341 | { |
1342 | 1342 | unsigned int badness; |
1343 | 1343 | |
1376 | 1376 | ** disk statistics |
1377 | 1377 | */ |
1378 | 1378 | static void |
1379 | diskhead(int osvers, int osrel, int ossub) | |
1380 | { | |
1381 | printf("disk busy read/s KB/read " | |
1382 | "write/s KB/writ avque avserv _disk_"); | |
1383 | } | |
1384 | ||
1385 | static int | |
1386 | diskline(struct sstat *ss, struct pstat *ps, int nproc, | |
1387 | time_t deltasec, time_t deltatic, time_t hz, | |
1388 | int osvers, int osrel, int ossub, char *tstamp, | |
1389 | int ppres, int pexit, int pzombie) | |
1379 | lvmhead(int osvers, int osrel, int ossub) | |
1380 | { | |
1381 | printf("disk busy read/s KB/read " | |
1382 | "writ/s KB/writ avque avserv _lvm_"); | |
1383 | } | |
1384 | ||
1385 | static void | |
1386 | mddhead(int osvers, int osrel, int ossub) | |
1387 | { | |
1388 | printf("disk busy read/s KB/read " | |
1389 | "writ/s KB/writ avque avserv _mdd_"); | |
1390 | } | |
1391 | ||
1392 | static void | |
1393 | dskhead(int osvers, int osrel, int ossub) | |
1394 | { | |
1395 | printf("disk busy read/s KB/read " | |
1396 | "writ/s KB/writ avque avserv _dsk_"); | |
1397 | } | |
1398 | ||
1399 | static int | |
1400 | gendskline(struct sstat *ss, char *tstamp, char selector) | |
1390 | 1401 | { |
1391 | 1402 | static char firstcall = 1; |
1392 | register int i, nlines = 0; | |
1403 | register int i, nlines = 0, nunit = 0; | |
1393 | 1404 | count_t mstot, iotot; |
1394 | struct perxdsk *dp = ss->xdsk.xdsk; | |
1405 | struct perdsk *dp; | |
1395 | 1406 | unsigned int badness; |
1407 | ||
1408 | switch (selector) | |
1409 | { | |
1410 | case 'l': | |
1411 | dp = ss->dsk.lvm; | |
1412 | nunit = ss->dsk.nlvm; | |
1413 | break; | |
1414 | ||
1415 | case 'm': | |
1416 | dp = ss->dsk.mdd; | |
1417 | nunit = ss->dsk.nmdd; | |
1418 | break; | |
1419 | ||
1420 | case 'd': | |
1421 | dp = ss->dsk.dsk; | |
1422 | nunit = ss->dsk.ndsk; | |
1423 | break; | |
1424 | ||
1425 | default: | |
1426 | return 0; | |
1427 | } | |
1396 | 1428 | |
1397 | 1429 | mstot = (ss->cpu.all.stime + ss->cpu.all.utime + |
1398 | 1430 | ss->cpu.all.ntime + ss->cpu.all.itime + |
1399 | 1431 | ss->cpu.all.wtime + ss->cpu.all.Itime + |
1400 | ss->cpu.all.Stime + ss->cpu.all.steal ) | |
1432 | ss->cpu.all.Stime + ss->cpu.all.steal + | |
1433 | ss->cpu.all.guest ) | |
1401 | 1434 | * (count_t)1000 / hertz / ss->cpu.nrcpu; |
1402 | 1435 | |
1403 | for (i=0; i < ss->xdsk.nrxdsk; i++, dp++) | |
1404 | { | |
1436 | for (i=0; i < nunit; i++, dp++) | |
1437 | { | |
1438 | char buf[32]; | |
1439 | char *pn; | |
1440 | int len; | |
1441 | ||
1405 | 1442 | if ( (iotot = dp->nread + dp->nwrite) == 0 && |
1406 | 1443 | !firstcall && !allresources ) |
1407 | 1444 | continue; /* no activity on this disk */ |
1413 | 1450 | printf("%s ", tstamp); |
1414 | 1451 | |
1415 | 1452 | if (dskbadness) |
1416 | badness = (ss->xdsk.xdsk[i].io_ms * 100.0 / mstot) | |
1417 | * 100 / dskbadness; | |
1453 | badness = (dp->io_ms * 100.0 / mstot) * 100/dskbadness; | |
1418 | 1454 | else |
1419 | 1455 | badness = 0; |
1420 | 1456 | |
1421 | 1457 | preprint(badness); |
1422 | 1458 | |
1423 | printf("%-7s %3.0lf%% %8.2lf %7.1lf %9.2lf %7.1lf " | |
1424 | "%7.2lf %6.2lf ms", | |
1425 | dp->name, | |
1459 | if ( (len = strlen(dp->name)) > 14) | |
1460 | pn = dp->name + len - 14; | |
1461 | else | |
1462 | pn = dp->name; | |
1463 | ||
1464 | sprintf(buf, "%12.12s", pn); | |
1465 | printf("%-14s %3.0lf%% %6.1lf %7.1lf %7.1lf %7.1lf " | |
1466 | "%5.1lf %6.2lf ms", | |
1467 | pn, | |
1426 | 1468 | mstot ? (double)dp->io_ms * 100.0 / mstot : 0.0, |
1427 | 1469 | mstot ? (double)dp->nread * 1000.0 / mstot : 0.0, |
1428 | 1470 | dp->nread ? |
1443 | 1485 | } |
1444 | 1486 | |
1445 | 1487 | firstcall = 0; |
1488 | ||
1446 | 1489 | return nlines; |
1490 | } | |
1491 | ||
1492 | static int | |
1493 | lvmline(struct sstat *ss, struct pstat *ps, int nproc, | |
1494 | time_t deltasec, time_t deltatic, time_t hz, | |
1495 | int osvers, int osrel, int ossub, char *tstamp, | |
1496 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1497 | { | |
1498 | return gendskline(ss, tstamp, 'l'); | |
1499 | } | |
1500 | ||
1501 | static int | |
1502 | mddline(struct sstat *ss, struct pstat *ps, int nproc, | |
1503 | time_t deltasec, time_t deltatic, time_t hz, | |
1504 | int osvers, int osrel, int ossub, char *tstamp, | |
1505 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1506 | { | |
1507 | return gendskline(ss, tstamp, 'm'); | |
1508 | } | |
1509 | ||
1510 | static int | |
1511 | dskline(struct sstat *ss, struct pstat *ps, int nproc, | |
1512 | time_t deltasec, time_t deltatic, time_t hz, | |
1513 | int osvers, int osrel, int ossub, char *tstamp, | |
1514 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1515 | { | |
1516 | return gendskline(ss, tstamp, 'd'); | |
1447 | 1517 | } |
1448 | 1518 | |
1449 | 1519 | /* |
1460 | 1530 | ifline(struct sstat *ss, struct pstat *ps, int nproc, |
1461 | 1531 | time_t deltasec, time_t deltatic, time_t hz, |
1462 | 1532 | int osvers, int osrel, int ossub, char *tstamp, |
1463 | int ppres, int pexit, int pzombie) | |
1533 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1464 | 1534 | { |
1465 | 1535 | static char firstcall = 1; |
1466 | 1536 | register long i, nlines = 0; |
1566 | 1636 | IFline(struct sstat *ss, struct pstat *ps, int nproc, |
1567 | 1637 | time_t deltasec, time_t deltatic, time_t hz, |
1568 | 1638 | int osvers, int osrel, int ossub, char *tstamp, |
1569 | int ppres, int pexit, int pzombie) | |
1639 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1570 | 1640 | { |
1571 | 1641 | static char firstcall = 1; |
1572 | 1642 | register long i, nlines = 0; |
1621 | 1691 | ipv4line(struct sstat *ss, struct pstat *ps, int nproc, |
1622 | 1692 | time_t deltasec, time_t deltatic, time_t hz, |
1623 | 1693 | int osvers, int osrel, int ossub, char *tstamp, |
1624 | int ppres, int pexit, int pzombie) | |
1694 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1625 | 1695 | { |
1626 | 1696 | printf("%8.1lf %8.1lf %11.1lf %9.1lf %9.1lf %11.1lf\n", |
1627 | 1697 | (double)ss->net.ipv4.InReceives / deltasec, |
1644 | 1714 | IPv4line(struct sstat *ss, struct pstat *ps, int nproc, |
1645 | 1715 | time_t deltasec, time_t deltatic, time_t hz, |
1646 | 1716 | int osvers, int osrel, int ossub, char *tstamp, |
1647 | int ppres, int pexit, int pzombie) | |
1717 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1648 | 1718 | { |
1649 | 1719 | printf(" %5.1lf %6.1lf %6.1lf %6.1lf %7.1lf %7.1lf " |
1650 | 1720 | " %5.1lf %5.1lf\n", |
1673 | 1743 | icmpv4line(struct sstat *ss, struct pstat *ps, int nproc, |
1674 | 1744 | time_t deltasec, time_t deltatic, time_t hz, |
1675 | 1745 | int osvers, int osrel, int ossub, char *tstamp, |
1676 | int ppres, int pexit, int pzombie) | |
1746 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1677 | 1747 | { |
1678 | 1748 | printf("%7.1lf %8.1lf %8.2lf %8.2lf %8.2lf %8.2lf\n", |
1679 | 1749 | (double)ss->net.icmpv4.InMsgs / deltasec, |
1696 | 1766 | ICMPv4line(struct sstat *ss, struct pstat *ps, int nproc, |
1697 | 1767 | time_t deltasec, time_t deltatic, time_t hz, |
1698 | 1768 | int osvers, int osrel, int ossub, char *tstamp, |
1699 | int ppres, int pexit, int pzombie) | |
1769 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1700 | 1770 | { |
1701 | 1771 | printf("%6.2lf %5.2lf %5.2lf %5.2lf %5.2lf " |
1702 | 1772 | "%6.2lf %5.2lf %5.2lf %5.2lf %5.2lf\n", |
1727 | 1797 | udpv4line(struct sstat *ss, struct pstat *ps, int nproc, |
1728 | 1798 | time_t deltasec, time_t deltatic, time_t hz, |
1729 | 1799 | int osvers, int osrel, int ossub, char *tstamp, |
1730 | int ppres, int pexit, int pzombie) | |
1800 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1731 | 1801 | { |
1732 | 1802 | printf("%9.1lf %10.1lf %7.2lf %9.2lf\n", |
1733 | 1803 | (double)ss->net.udpv4.InDatagrams / deltasec, |
1751 | 1821 | ipv6line(struct sstat *ss, struct pstat *ps, int nproc, |
1752 | 1822 | time_t deltasec, time_t deltatic, time_t hz, |
1753 | 1823 | int osvers, int osrel, int ossub, char *tstamp, |
1754 | int ppres, int pexit, int pzombie) | |
1824 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1755 | 1825 | { |
1756 | 1826 | printf("%8.1lf %8.1lf %6.1lf %7.1lf %9.1lf %9.1lf %9.1lf\n", |
1757 | 1827 | (double)ss->net.ipv6.Ip6InReceives / deltasec, |
1775 | 1845 | IPv6line(struct sstat *ss, struct pstat *ps, int nproc, |
1776 | 1846 | time_t deltasec, time_t deltatic, time_t hz, |
1777 | 1847 | int osvers, int osrel, int ossub, char *tstamp, |
1778 | int ppres, int pexit, int pzombie) | |
1848 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1779 | 1849 | { |
1780 | 1850 | printf(" %5.1lf %6.1lf %6.1lf %6.1lf %7.1lf %7.1lf " |
1781 | 1851 | " %5.1lf %5.1lf\n", |
1804 | 1874 | icmpv6line(struct sstat *ss, struct pstat *ps, int nproc, |
1805 | 1875 | time_t deltasec, time_t deltatic, time_t hz, |
1806 | 1876 | int osvers, int osrel, int ossub, char *tstamp, |
1807 | int ppres, int pexit, int pzombie) | |
1877 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1808 | 1878 | { |
1809 | 1879 | printf("%7.1lf %8.1lf %7.2lf %8.2lf %8.2lf %8.2lf %8.2lf\n", |
1810 | 1880 | (double)ss->net.icmpv6.Icmp6InMsgs / deltasec, |
1829 | 1899 | ICMPv6line(struct sstat *ss, struct pstat *ps, int nproc, |
1830 | 1900 | time_t deltasec, time_t deltatic, time_t hz, |
1831 | 1901 | int osvers, int osrel, int ossub, char *tstamp, |
1832 | int ppres, int pexit, int pzombie) | |
1902 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1833 | 1903 | { |
1834 | 1904 | printf("%7.2lf %7.2lf %7.2lf %5.2lf %5.2lf " |
1835 | 1905 | "%5.2lf %5.2lf %5.2lf %5.2lf\n", |
1859 | 1929 | udpv6line(struct sstat *ss, struct pstat *ps, int nproc, |
1860 | 1930 | time_t deltasec, time_t deltatic, time_t hz, |
1861 | 1931 | int osvers, int osrel, int ossub, char *tstamp, |
1862 | int ppres, int pexit, int pzombie) | |
1932 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1863 | 1933 | { |
1864 | 1934 | printf("%9.1lf %10.1lf %7.2lf %9.2lf\n", |
1865 | 1935 | (double)ss->net.udpv6.Udp6InDatagrams / deltasec, |
1883 | 1953 | tcpline(struct sstat *ss, struct pstat *ps, int nproc, |
1884 | 1954 | time_t deltasec, time_t deltatic, time_t hz, |
1885 | 1955 | int osvers, int osrel, int ossub, char *tstamp, |
1886 | int ppres, int pexit, int pzombie) | |
1956 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1887 | 1957 | { |
1888 | 1958 | printf("%8.1lf %9.1lf %9.1lf %9.1lf %7lld\n", |
1889 | 1959 | (double)ss->net.tcp.InSegs / deltasec, |
1905 | 1975 | TCPline(struct sstat *ss, struct pstat *ps, int nproc, |
1906 | 1976 | time_t deltasec, time_t deltatic, time_t hz, |
1907 | 1977 | int osvers, int osrel, int ossub, char *tstamp, |
1908 | int ppres, int pexit, int pzombie) | |
1978 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1909 | 1979 | { |
1910 | 1980 | printf("%7.1lf %9.1lf %9.1lf %12.1lf %10.1lf\n", |
1911 | 1981 | (double)ss->net.tcp.InErrs / deltasec, |
1928 | 1998 | httpline(struct sstat *ss, struct pstat *ps, int nproc, |
1929 | 1999 | time_t deltasec, time_t deltatic, time_t hz, |
1930 | 2000 | int osvers, int osrel, int ossub, char *tstamp, |
1931 | int ppres, int pexit, int pzombie) | |
2001 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1932 | 2002 | { |
1933 | 2003 | printf("%10.2lf %8.2lf %9.2lf %11d %11d\n", |
1934 | 2004 | (double)ss->www.accesses / deltasec, |
1956 | 2026 | topcline(struct sstat *ss, struct pstat *ps, int nproc, |
1957 | 2027 | time_t deltasec, time_t deltatic, time_t hz, |
1958 | 2028 | int osvers, int osrel, int ossub, char *tstamp, |
1959 | int ppres, int pexit, int pzombie) | |
2029 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
1960 | 2030 | { |
1961 | 2031 | count_t availcpu; |
1962 | 2032 | |
1969 | 2039 | /* |
1970 | 2040 | ** sort process list in cpu order |
1971 | 2041 | */ |
1972 | qsort(ps, nproc, sizeof(struct pstat), compcpu); | |
2042 | qsort(ps, ppres, sizeof(struct pstat), compcpu); | |
1973 | 2043 | |
1974 | 2044 | availcpu = ss->cpu.all.stime + ss->cpu.all.utime + |
1975 | 2045 | ss->cpu.all.ntime + ss->cpu.all.itime + |
1976 | 2046 | ss->cpu.all.wtime + ss->cpu.all.Itime + |
1977 | ss->cpu.all.Stime + ss->cpu.all.steal; | |
2047 | ss->cpu.all.Stime + ss->cpu.all.steal + | |
2048 | ss->cpu.all.guest; | |
1978 | 2049 | |
1979 | 2050 | availcpu /= ss->cpu.nrcpu; |
1980 | 2051 | |
2007 | 2078 | topmline(struct sstat *ss, struct pstat *ps, int nproc, |
2008 | 2079 | time_t deltasec, time_t deltatic, time_t hz, |
2009 | 2080 | int osvers, int osrel, int ossub, char *tstamp, |
2010 | int ppres, int pexit, int pzombie) | |
2081 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
2011 | 2082 | { |
2012 | 2083 | count_t availmem; |
2013 | 2084 | |
2020 | 2091 | /* |
2021 | 2092 | ** sort process list in memory order |
2022 | 2093 | */ |
2023 | qsort(ps, nproc, sizeof(struct pstat), compmem); | |
2094 | qsort(ps, ppres, sizeof(struct pstat), compmem); | |
2024 | 2095 | |
2025 | 2096 | availmem = ss->mem.physmem * pagesize/1024; |
2026 | 2097 | |
2050 | 2121 | topdline(struct sstat *ss, struct pstat *ps, int nproc, |
2051 | 2122 | time_t deltasec, time_t deltatic, time_t hz, |
2052 | 2123 | int osvers, int osrel, int ossub, char *tstamp, |
2053 | int ppres, int pexit, int pzombie) | |
2124 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
2054 | 2125 | { |
2055 | 2126 | int i; |
2056 | 2127 | count_t availdsk; |
2081 | 2152 | /* |
2082 | 2153 | ** sort process list in disk order |
2083 | 2154 | */ |
2084 | qsort(ps, nproc, sizeof(struct pstat), compdsk); | |
2155 | qsort(ps, ppres, sizeof(struct pstat), compdsk); | |
2085 | 2156 | |
2086 | 2157 | printf("%5d %-8.8s %3.0lf%% | %5d %-8.8s %3.0lf%% | " |
2087 | 2158 | "%5d %-8.8s %3.0lf%%\n", |
2109 | 2180 | topnline(struct sstat *ss, struct pstat *ps, int nproc, |
2110 | 2181 | time_t deltasec, time_t deltatic, time_t hz, |
2111 | 2182 | int osvers, int osrel, int ossub, char *tstamp, |
2112 | int ppres, int pexit, int pzombie) | |
2183 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) | |
2113 | 2184 | { |
2114 | 2185 | int i; |
2115 | 2186 | count_t availnet; |
2142 | 2213 | /* |
2143 | 2214 | ** sort process list in network order |
2144 | 2215 | */ |
2145 | qsort(ps, nproc, sizeof(struct pstat), compnet); | |
2216 | qsort(ps, ppres, sizeof(struct pstat), compnet); | |
2146 | 2217 | |
2147 | 2218 | printf("%5d %-8.8s %3.0lf%% | %5d %-8.8s %3.0lf%% | " |
2148 | 2219 | "%5d %-8.8s %3.0lf%%\n", |
2208 | 2279 | {0, "c", 'P', taskhead, taskline, "processes & threads", }, |
2209 | 2280 | {0, "m", 'm', memhead, memline, "memory & swapspace", }, |
2210 | 2281 | {0, "m", 's', swaphead, swapline, "swap rate", }, |
2211 | {0, "cd", 'd', diskhead, diskline, "disk activity", }, | |
2282 | {0, "cd", 'l', lvmhead, lvmline, "logical volume activity", }, | |
2283 | {0, "cd", 'f', mddhead, mddline, "multiple device activity",}, | |
2284 | {0, "cd", 'd', dskhead, dskline, "disk activity", }, | |
2212 | 2285 | {0, "n", 'i', ifhead, ifline, "net-interf (general)", }, |
2213 | 2286 | {0, "n", 'I', IFhead, IFline, "net-interf (errors)", }, |
2214 | 2287 | {0, "n", 'w', ipv4head, ipv4line, "ip v4 (general)", }, |
6 | 6 | ** This source-file contains functions to calculate the differences for |
7 | 7 | ** the system-level and process-level counters since the previous sample. |
8 | 8 | ** ========================================================================== |
9 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: gerlof@ATComputing.nl | |
9 | ** Author: Gerlof Langeveld | |
10 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | 11 | ** Date: November 1996 |
12 | 12 | ** LINUX-port: June 2000 |
13 | 13 | ** -------------------------------------------------------------------------- |
14 | ** Copyright (C) 2000-2005 Gerlof Langeveld | |
14 | ** Copyright (C) 2000-2010 Gerlof Langeveld | |
15 | 15 | ** |
16 | 16 | ** This program is free software; you can redistribute it and/or modify it |
17 | 17 | ** under the terms of the GNU General Public License as published by the |
29 | 29 | ** -------------------------------------------------------------------------- |
30 | 30 | ** |
31 | 31 | ** $Log: deviate.c,v $ |
32 | ** Revision 1.45 2010/10/23 14:02:03 gerlof | |
33 | ** Show counters for total number of running and sleep (S and D) threads. | |
34 | ** | |
35 | ** Revision 1.44 2010/05/18 19:19:43 gerlof | |
36 | ** Introduce CPU frequency and scaling (JC van Winkel). | |
37 | ** | |
38 | ** Revision 1.43 2010/04/23 12:19:35 gerlof | |
39 | ** Modified mail-address in header. | |
40 | ** | |
41 | ** Revision 1.42 2010/03/04 10:52:08 gerlof | |
42 | ** Support I/O-statistics on logical volumes and MD devices. | |
43 | ** | |
44 | ** Revision 1.41 2009/12/31 11:34:21 gerlof | |
45 | ** Sanity-check to bypass kernel-bug showing 497 days of CPU-consumption. | |
46 | ** | |
47 | ** Revision 1.40 2009/12/17 11:58:25 gerlof | |
48 | ** Gather and display new counters: dirty cache and guest cpu usage. | |
49 | ** | |
32 | 50 | ** Revision 1.39 2008/02/25 14:51:18 gerlof |
33 | 51 | ** Experimental code for HTTP-statistics. |
34 | 52 | ** |
149 | 167 | ** |
150 | 168 | */ |
151 | 169 | |
152 | static const char rcsid[] = "$Id: deviate.c,v 1.39 2008/02/25 14:51:18 gerlof Exp $"; | |
170 | static const char rcsid[] = "$Id: deviate.c,v 1.45 2010/10/23 14:02:03 gerlof Exp $"; | |
153 | 171 | |
154 | 172 | #include <sys/types.h> |
155 | 173 | #include <sys/param.h> |
177 | 195 | int |
178 | 196 | deviatproc(struct pstat *aproc, int npresent, |
179 | 197 | struct pstat *eproc, int nexit, int deviatonly, |
180 | struct pstat *dproc, int *nzombie) | |
198 | struct pstat *dproc, struct sstat *dstat, | |
199 | int *ntrun, int *ntslpi, int *ntslpu, int *nzombie) | |
181 | 200 | { |
182 | 201 | register int c, d; |
183 | 202 | register struct pstat *curstat, *devstat; |
184 | 203 | struct pstat prestat; |
185 | 204 | struct pinfo *pinfo; |
205 | count_t totusedcpu; | |
206 | ||
207 | /* | |
208 | ** needed for sanity check later on... | |
209 | */ | |
210 | totusedcpu = dstat->cpu.all.stime + dstat->cpu.all.utime + | |
211 | dstat->cpu.all.ntime + dstat->cpu.all.itime + | |
212 | dstat->cpu.all.wtime + dstat->cpu.all.Itime + | |
213 | dstat->cpu.all.Stime + dstat->cpu.all.steal + | |
214 | dstat->cpu.all.guest; | |
186 | 215 | |
187 | 216 | /* |
188 | 217 | ** make new list of all processes in the process-database; |
194 | 223 | /* |
195 | 224 | ** calculate deviations per present process |
196 | 225 | */ |
197 | for (c=0, d=0, *nzombie=0; c < npresent; c++) | |
226 | *ntrun=*ntslpi=*ntslpu=*nzombie= 0; | |
227 | ||
228 | for (c=0, d=0; c < npresent; c++) | |
198 | 229 | { |
199 | 230 | char newproc = 0; |
200 | 231 | |
201 | 232 | curstat = aproc+c; |
202 | 233 | |
203 | 234 | if (curstat->gen.state == 'Z') |
235 | { | |
204 | 236 | (*nzombie)++; |
237 | } | |
238 | else | |
239 | { | |
240 | *ntrun += curstat->gen.nthrrun; | |
241 | *ntslpi += curstat->gen.nthrslpi; | |
242 | *ntslpu += curstat->gen.nthrslpu; | |
243 | } | |
205 | 244 | |
206 | 245 | /* |
207 | 246 | ** get previous figures from process-database |
271 | 310 | devstat->cpu.utime = |
272 | 311 | subcount(curstat->cpu.utime, prestat.cpu.utime); |
273 | 312 | |
313 | /* | |
314 | ** sometimes particular kernel versions supply a smaller | |
315 | ** amount for consumed CPU-ticks than a previous sample; | |
316 | ** with unsigned calculations this results in 497 days of | |
317 | ** CPU-consumption so a sanity-check is needed here... | |
318 | */ | |
319 | if (devstat->cpu.stime > totusedcpu) | |
320 | devstat->cpu.stime = 1; | |
321 | ||
322 | if (devstat->cpu.utime > totusedcpu) | |
323 | devstat->cpu.utime = 1; | |
324 | ||
325 | /* | |
326 | ** do further calculations | |
327 | */ | |
274 | 328 | devstat->dsk.rio = |
275 | 329 | subcount(curstat->dsk.rio, prestat.dsk.rio); |
276 | 330 | devstat->dsk.rsz = |
513 | 567 | void |
514 | 568 | deviatsyst(struct sstat *cur, struct sstat *pre, struct sstat *dev) |
515 | 569 | { |
516 | register int i; | |
570 | register int i, j; | |
517 | 571 | count_t *cdev, *ccur, *cpre; |
518 | 572 | |
519 | 573 | dev->cpu.nrcpu = cur->cpu.nrcpu; |
530 | 584 | dev->cpu.all.Stime = subcount(cur->cpu.all.Stime, pre->cpu.all.Stime); |
531 | 585 | |
532 | 586 | dev->cpu.all.steal = subcount(cur->cpu.all.steal, pre->cpu.all.steal); |
533 | ||
534 | if (dev->cpu.nrcpu == 1) | |
587 | dev->cpu.all.guest = subcount(cur->cpu.all.guest, pre->cpu.all.guest); | |
588 | ||
589 | for (i=0; i < dev->cpu.nrcpu; i++) | |
535 | 590 | { |
536 | dev->cpu.cpu[0] = dev->cpu.all; | |
537 | } | |
538 | else | |
539 | { | |
540 | for (i=0; i < dev->cpu.nrcpu; i++) | |
541 | { | |
542 | dev->cpu.cpu[i].cpunr = cur->cpu.cpu[i].cpunr; | |
543 | dev->cpu.cpu[i].stime = subcount(cur->cpu.cpu[i].stime, | |
544 | pre->cpu.cpu[i].stime); | |
545 | dev->cpu.cpu[i].utime = subcount(cur->cpu.cpu[i].utime, | |
546 | pre->cpu.cpu[i].utime); | |
547 | dev->cpu.cpu[i].ntime = subcount(cur->cpu.cpu[i].ntime, | |
548 | pre->cpu.cpu[i].ntime); | |
549 | dev->cpu.cpu[i].itime = subcount(cur->cpu.cpu[i].itime, | |
550 | pre->cpu.cpu[i].itime); | |
551 | dev->cpu.cpu[i].wtime = subcount(cur->cpu.cpu[i].wtime, | |
552 | pre->cpu.cpu[i].wtime); | |
553 | dev->cpu.cpu[i].Itime = subcount(cur->cpu.cpu[i].Itime, | |
554 | pre->cpu.cpu[i].Itime); | |
555 | dev->cpu.cpu[i].Stime = subcount(cur->cpu.cpu[i].Stime, | |
556 | pre->cpu.cpu[i].Stime); | |
557 | ||
558 | dev->cpu.cpu[i].steal = subcount(cur->cpu.cpu[i].steal, | |
559 | pre->cpu.cpu[i].steal); | |
560 | } | |
591 | count_t ticks; | |
592 | ||
593 | dev->cpu.cpu[i].cpunr = cur->cpu.cpu[i].cpunr; | |
594 | dev->cpu.cpu[i].stime = subcount(cur->cpu.cpu[i].stime, | |
595 | pre->cpu.cpu[i].stime); | |
596 | dev->cpu.cpu[i].utime = subcount(cur->cpu.cpu[i].utime, | |
597 | pre->cpu.cpu[i].utime); | |
598 | dev->cpu.cpu[i].ntime = subcount(cur->cpu.cpu[i].ntime, | |
599 | pre->cpu.cpu[i].ntime); | |
600 | dev->cpu.cpu[i].itime = subcount(cur->cpu.cpu[i].itime, | |
601 | pre->cpu.cpu[i].itime); | |
602 | dev->cpu.cpu[i].wtime = subcount(cur->cpu.cpu[i].wtime, | |
603 | pre->cpu.cpu[i].wtime); | |
604 | dev->cpu.cpu[i].Itime = subcount(cur->cpu.cpu[i].Itime, | |
605 | pre->cpu.cpu[i].Itime); | |
606 | dev->cpu.cpu[i].Stime = subcount(cur->cpu.cpu[i].Stime, | |
607 | pre->cpu.cpu[i].Stime); | |
608 | ||
609 | dev->cpu.cpu[i].steal = subcount(cur->cpu.cpu[i].steal, | |
610 | pre->cpu.cpu[i].steal); | |
611 | dev->cpu.cpu[i].guest = subcount(cur->cpu.cpu[i].guest, | |
612 | pre->cpu.cpu[i].guest); | |
613 | ||
614 | ticks = cur->cpu.cpu[i].freqcnt.ticks; | |
615 | ||
616 | dev->cpu.cpu[i].freqcnt.maxfreq = | |
617 | cur->cpu.cpu[i].freqcnt.maxfreq; | |
618 | dev->cpu.cpu[i].freqcnt.cnt = ticks ? | |
619 | subcount(cur->cpu.cpu[i].freqcnt.cnt, | |
620 | pre->cpu.cpu[i].freqcnt.cnt) | |
621 | : cur->cpu.cpu[i].freqcnt.cnt; | |
622 | ||
623 | dev->cpu.cpu[i].freqcnt.ticks = ticks ? | |
624 | subcount(cur->cpu.cpu[i].freqcnt.ticks, | |
625 | pre->cpu.cpu[i].freqcnt.ticks) | |
626 | : cur->cpu.cpu[i].freqcnt.ticks; | |
561 | 627 | } |
562 | 628 | |
563 | 629 | dev->cpu.lavg1 = cur->cpu.lavg1; |
571 | 637 | dev->mem.committed = cur->mem.committed; |
572 | 638 | dev->mem.commitlim = cur->mem.commitlim; |
573 | 639 | dev->mem.cachemem = cur->mem.cachemem; |
640 | dev->mem.cachedrt = cur->mem.cachedrt; | |
574 | 641 | dev->mem.totswap = cur->mem.totswap; |
575 | 642 | dev->mem.freeswap = cur->mem.freeswap; |
576 | 643 | |
582 | 649 | |
583 | 650 | /* |
584 | 651 | ** structures with network-related counters are considered |
585 | ** as tabels of frequency-counters that have to be subtracte; | |
652 | ** as tables of frequency-counters that have to be subtracted; | |
586 | 653 | ** values that do not represent a frequency are corrected afterwards |
587 | 654 | */ |
588 | 655 | for (cdev = (count_t *)&dev->net.ipv4, |
771 | 838 | /* |
772 | 839 | ** calculate deviations for disks |
773 | 840 | */ |
774 | for (i=0; cur->xdsk.xdsk[i].name[0]; i++) | |
841 | for (i=j=0; cur->dsk.dsk[i].name[0]; i++) | |
775 | 842 | { |
776 | strcpy(dev->xdsk.xdsk[i].name, cur->xdsk.xdsk[i].name); | |
777 | ||
778 | dev->xdsk.xdsk[i].nread = subcount(cur->xdsk.xdsk[i].nread, | |
779 | pre->xdsk.xdsk[i].nread); | |
780 | dev->xdsk.xdsk[i].nwrite = subcount(cur->xdsk.xdsk[i].nwrite, | |
781 | pre->xdsk.xdsk[i].nwrite); | |
782 | dev->xdsk.xdsk[i].nrsect = subcount(cur->xdsk.xdsk[i].nrsect, | |
783 | pre->xdsk.xdsk[i].nrsect); | |
784 | dev->xdsk.xdsk[i].nwsect = subcount(cur->xdsk.xdsk[i].nwsect, | |
785 | pre->xdsk.xdsk[i].nwsect); | |
786 | dev->xdsk.xdsk[i].io_ms = subcount(cur->xdsk.xdsk[i].io_ms, | |
787 | pre->xdsk.xdsk[i].io_ms); | |
788 | dev->xdsk.xdsk[i].avque = subcount(cur->xdsk.xdsk[i].avque, | |
789 | pre->xdsk.xdsk[i].avque); | |
843 | int realj = j; | |
844 | ||
845 | /* | |
846 | ** check if disk has been added or removed since | |
847 | ** previous interval | |
848 | */ | |
849 | if ( strcmp(cur->dsk.dsk[i].name, pre->dsk.dsk[j].name) != 0) | |
850 | { | |
851 | for (j++; pre->dsk.dsk[j].name[0]; j++) | |
852 | { | |
853 | if ( strcmp(cur->dsk.dsk[i].name, | |
854 | pre->dsk.dsk[j].name) == 0) | |
855 | break; | |
856 | } | |
857 | ||
858 | /* | |
859 | ** either the corresponding entry has been found | |
860 | ** in the case that a disk has been removed, or | |
861 | ** an empty entry has been found (all counters | |
862 | ** on zero) in the case that a disk has been added | |
863 | ** during the last sample | |
864 | */ | |
865 | } | |
866 | ||
867 | strcpy(dev->dsk.dsk[i].name, cur->dsk.dsk[i].name); | |
868 | ||
869 | dev->dsk.dsk[i].nread = subcount(cur->dsk.dsk[i].nread, | |
870 | pre->dsk.dsk[j].nread); | |
871 | dev->dsk.dsk[i].nwrite = subcount(cur->dsk.dsk[i].nwrite, | |
872 | pre->dsk.dsk[j].nwrite); | |
873 | dev->dsk.dsk[i].nrsect = subcount(cur->dsk.dsk[i].nrsect, | |
874 | pre->dsk.dsk[j].nrsect); | |
875 | dev->dsk.dsk[i].nwsect = subcount(cur->dsk.dsk[i].nwsect, | |
876 | pre->dsk.dsk[j].nwsect); | |
877 | dev->dsk.dsk[i].io_ms = subcount(cur->dsk.dsk[i].io_ms, | |
878 | pre->dsk.dsk[j].io_ms); | |
879 | dev->dsk.dsk[i].avque = subcount(cur->dsk.dsk[i].avque, | |
880 | pre->dsk.dsk[j].avque); | |
881 | ||
882 | /* | |
883 | ** determine new j | |
884 | */ | |
885 | if (pre->dsk.dsk[j].name) // existing matching entry | |
886 | j++; | |
887 | else | |
888 | j = realj; // empty entry: stick to old j | |
790 | 889 | } |
791 | 890 | |
792 | dev->xdsk.xdsk[i].name[0] = '\0'; | |
793 | dev->xdsk.nrxdsk = i; | |
891 | dev->dsk.dsk[i].name[0] = '\0'; | |
892 | dev->dsk.ndsk = i; | |
893 | ||
894 | /* | |
895 | ** calculate deviations for multiple devices | |
896 | */ | |
897 | for (i=j=0; cur->dsk.mdd[i].name[0]; i++) | |
898 | { | |
899 | int realj = j; | |
900 | ||
901 | /* | |
902 | ** check if md has been added or removed since | |
903 | ** previous interval | |
904 | */ | |
905 | if ( strcmp(cur->dsk.mdd[i].name, pre->dsk.mdd[j].name) != 0) | |
906 | { | |
907 | for (j++; pre->dsk.mdd[j].name[0]; j++) | |
908 | { | |
909 | if ( strcmp(cur->dsk.mdd[i].name, | |
910 | pre->dsk.mdd[j].name) == 0) | |
911 | break; | |
912 | } | |
913 | ||
914 | /* | |
915 | ** either the corresponding entry has been found | |
916 | ** in the case that a md has been removed, or | |
917 | ** an empty entry has been found (all counters | |
918 | ** on zero) in the case that a md has been added | |
919 | ** during the last sample | |
920 | */ | |
921 | } | |
922 | ||
923 | strcpy(dev->dsk.mdd[i].name, cur->dsk.mdd[i].name); | |
924 | ||
925 | dev->dsk.mdd[i].nread = subcount(cur->dsk.mdd[i].nread, | |
926 | pre->dsk.mdd[j].nread); | |
927 | dev->dsk.mdd[i].nwrite = subcount(cur->dsk.mdd[i].nwrite, | |
928 | pre->dsk.mdd[j].nwrite); | |
929 | dev->dsk.mdd[i].nrsect = subcount(cur->dsk.mdd[i].nrsect, | |
930 | pre->dsk.mdd[j].nrsect); | |
931 | dev->dsk.mdd[i].nwsect = subcount(cur->dsk.mdd[i].nwsect, | |
932 | pre->dsk.mdd[j].nwsect); | |
933 | dev->dsk.mdd[i].io_ms = subcount(cur->dsk.mdd[i].io_ms, | |
934 | pre->dsk.mdd[j].io_ms); | |
935 | dev->dsk.mdd[i].avque = subcount(cur->dsk.mdd[i].avque, | |
936 | pre->dsk.mdd[j].avque); | |
937 | ||
938 | /* | |
939 | ** determine new j | |
940 | */ | |
941 | if (pre->dsk.mdd[j].name) // existing matching entry | |
942 | j++; | |
943 | else | |
944 | j = realj; // empty entry: stick to old j | |
945 | } | |
946 | ||
947 | dev->dsk.mdd[i].name[0] = '\0'; | |
948 | dev->dsk.nmdd = i; | |
949 | ||
950 | /* | |
951 | ** calculate deviations for LVM logical volumes | |
952 | */ | |
953 | for (i=j=0; cur->dsk.lvm[i].name[0]; i++) | |
954 | { | |
955 | int realj = j; | |
956 | ||
957 | /* | |
958 | ** check if logical volume has been added or removed since | |
959 | ** previous interval | |
960 | */ | |
961 | if ( strcmp(cur->dsk.lvm[i].name, pre->dsk.lvm[j].name) != 0) | |
962 | { | |
963 | for (j++; pre->dsk.lvm[j].name[0]; j++) | |
964 | { | |
965 | if ( strcmp(cur->dsk.lvm[i].name, | |
966 | pre->dsk.lvm[j].name) == 0) | |
967 | break; | |
968 | } | |
969 | ||
970 | /* | |
971 | ** either the corresponding entry has been found | |
972 | ** in the case that a logical volume has been removed, | |
973 | ** or an empty entry has been found (all counters | |
974 | ** on zero) in the case that a logical volume has | |
975 | ** been added during the last sample | |
976 | */ | |
977 | } | |
978 | ||
979 | strcpy(dev->dsk.lvm[i].name, cur->dsk.lvm[i].name); | |
980 | ||
981 | dev->dsk.lvm[i].nread = subcount(cur->dsk.lvm[i].nread, | |
982 | pre->dsk.lvm[j].nread); | |
983 | dev->dsk.lvm[i].nwrite = subcount(cur->dsk.lvm[i].nwrite, | |
984 | pre->dsk.lvm[j].nwrite); | |
985 | dev->dsk.lvm[i].nrsect = subcount(cur->dsk.lvm[i].nrsect, | |
986 | pre->dsk.lvm[j].nrsect); | |
987 | dev->dsk.lvm[i].nwsect = subcount(cur->dsk.lvm[i].nwsect, | |
988 | pre->dsk.lvm[j].nwsect); | |
989 | dev->dsk.lvm[i].io_ms = subcount(cur->dsk.lvm[i].io_ms, | |
990 | pre->dsk.lvm[j].io_ms); | |
991 | dev->dsk.lvm[i].avque = subcount(cur->dsk.lvm[i].avque, | |
992 | pre->dsk.lvm[j].avque); | |
993 | ||
994 | /* | |
995 | ** determine new j | |
996 | */ | |
997 | if (pre->dsk.lvm[j].name) // existing matching entry | |
998 | j++; | |
999 | else | |
1000 | j = realj; // empty entry: stick to old j | |
1001 | } | |
1002 | ||
1003 | dev->dsk.lvm[i].name[0] = '\0'; | |
1004 | dev->dsk.nlvm = i; | |
794 | 1005 | |
795 | 1006 | /* |
796 | 1007 | ** application-specific counters |
840 | 1051 | tot->cpu.all.Itime += new->cpu.all.Itime; |
841 | 1052 | tot->cpu.all.Stime += new->cpu.all.Stime; |
842 | 1053 | tot->cpu.all.steal += new->cpu.all.steal; |
1054 | tot->cpu.all.guest += new->cpu.all.guest; | |
843 | 1055 | |
844 | 1056 | if (new->cpu.nrcpu == 1) |
845 | 1057 | { |
858 | 1070 | tot->cpu.cpu[i].Itime += new->cpu.cpu[i].Itime; |
859 | 1071 | tot->cpu.cpu[i].Stime += new->cpu.cpu[i].Stime; |
860 | 1072 | tot->cpu.cpu[i].steal += new->cpu.cpu[i].steal; |
1073 | tot->cpu.cpu[i].guest += new->cpu.cpu[i].guest; | |
861 | 1074 | } |
862 | 1075 | } |
863 | 1076 | |
874 | 1087 | tot->mem.committed = new->mem.committed; |
875 | 1088 | tot->mem.commitlim = new->mem.commitlim; |
876 | 1089 | tot->mem.cachemem = new->mem.cachemem; |
1090 | tot->mem.cachedrt = new->mem.cachedrt; | |
877 | 1091 | tot->mem.totswap = new->mem.totswap; |
878 | 1092 | tot->mem.freeswap = new->mem.freeswap; |
879 | 1093 | |
886 | 1100 | case 'n': /* accumulate network-related counters */ |
887 | 1101 | /* |
888 | 1102 | ** structures with network-related counters are considered |
889 | ** as tabels of frequency-counters that will be accumulated; | |
1103 | ** as tables of frequency-counters that will be accumulated; | |
890 | 1104 | ** values that do not represent a frequency are corrected |
891 | 1105 | ** afterwards |
892 | 1106 | */ |
1020 | 1234 | break; |
1021 | 1235 | |
1022 | 1236 | case 'd': /* accumulate disk-related counters */ |
1023 | for (i=0; new->xdsk.xdsk[i].name[0]; i++) | |
1024 | { | |
1025 | strcpy(tot->xdsk.xdsk[i].name, new->xdsk.xdsk[i].name); | |
1026 | ||
1027 | tot->xdsk.xdsk[i].nread += new->xdsk.xdsk[i].nread; | |
1028 | tot->xdsk.xdsk[i].nwrite += new->xdsk.xdsk[i].nwrite; | |
1029 | tot->xdsk.xdsk[i].nrsect += new->xdsk.xdsk[i].nrsect; | |
1030 | tot->xdsk.xdsk[i].nwsect += new->xdsk.xdsk[i].nwsect; | |
1031 | tot->xdsk.xdsk[i].io_ms += new->xdsk.xdsk[i].io_ms; | |
1032 | tot->xdsk.xdsk[i].avque += new->xdsk.xdsk[i].avque; | |
1033 | } | |
1034 | ||
1035 | tot->xdsk.xdsk[i].name[0] = '\0'; | |
1036 | tot->xdsk.nrxdsk = i; | |
1237 | for (i=0; new->dsk.dsk[i].name[0]; i++) | |
1238 | { | |
1239 | strcpy(tot->dsk.dsk[i].name, new->dsk.dsk[i].name); | |
1240 | ||
1241 | tot->dsk.dsk[i].nread += new->dsk.dsk[i].nread; | |
1242 | tot->dsk.dsk[i].nwrite += new->dsk.dsk[i].nwrite; | |
1243 | tot->dsk.dsk[i].nrsect += new->dsk.dsk[i].nrsect; | |
1244 | tot->dsk.dsk[i].nwsect += new->dsk.dsk[i].nwsect; | |
1245 | tot->dsk.dsk[i].io_ms += new->dsk.dsk[i].io_ms; | |
1246 | tot->dsk.dsk[i].avque += new->dsk.dsk[i].avque; | |
1247 | } | |
1248 | ||
1249 | tot->dsk.dsk[i].name[0] = '\0'; | |
1250 | tot->dsk.ndsk = i; | |
1251 | ||
1252 | for (i=0; new->dsk.lvm[i].name[0]; i++) | |
1253 | { | |
1254 | strcpy(tot->dsk.lvm[i].name, new->dsk.lvm[i].name); | |
1255 | ||
1256 | tot->dsk.lvm[i].nread += new->dsk.lvm[i].nread; | |
1257 | tot->dsk.lvm[i].nwrite += new->dsk.lvm[i].nwrite; | |
1258 | tot->dsk.lvm[i].nrsect += new->dsk.lvm[i].nrsect; | |
1259 | tot->dsk.lvm[i].nwsect += new->dsk.lvm[i].nwsect; | |
1260 | tot->dsk.lvm[i].io_ms += new->dsk.lvm[i].io_ms; | |
1261 | tot->dsk.lvm[i].avque += new->dsk.lvm[i].avque; | |
1262 | } | |
1263 | ||
1264 | tot->dsk.lvm[i].name[0] = '\0'; | |
1265 | tot->dsk.nlvm = i; | |
1266 | ||
1267 | for (i=0; new->dsk.mdd[i].name[0]; i++) | |
1268 | { | |
1269 | strcpy(tot->dsk.mdd[i].name, new->dsk.mdd[i].name); | |
1270 | ||
1271 | tot->dsk.mdd[i].nread += new->dsk.mdd[i].nread; | |
1272 | tot->dsk.mdd[i].nwrite += new->dsk.mdd[i].nwrite; | |
1273 | tot->dsk.mdd[i].nrsect += new->dsk.mdd[i].nrsect; | |
1274 | tot->dsk.mdd[i].nwsect += new->dsk.mdd[i].nwsect; | |
1275 | tot->dsk.mdd[i].io_ms += new->dsk.mdd[i].io_ms; | |
1276 | tot->dsk.mdd[i].avque += new->dsk.mdd[i].avque; | |
1277 | } | |
1278 | ||
1279 | tot->dsk.mdd[i].name[0] = '\0'; | |
1280 | tot->dsk.nmdd = i; | |
1037 | 1281 | break; |
1038 | 1282 | } |
1039 | 1283 | } |
4 | 4 | ** the system on system-level as well as process-level. |
5 | 5 | ** |
6 | 6 | ** ========================================================================== |
7 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
8 | ** E-mail: gerlof@ATComputing.nl | |
7 | ** Author: Gerlof Langeveld | |
8 | ** E-mail: gerlof.langeveld@atoptool.nl | |
9 | 9 | ** Date: January 2007 |
10 | 10 | ** -------------------------------------------------------------------------- |
11 | ** Copyright (C) 2007 Gerlof Langeveld | |
11 | ** Copyright (C) 2007-2010 Gerlof Langeveld | |
12 | 12 | ** |
13 | 13 | ** This program is free software; you can redistribute it and/or modify it |
14 | 14 | ** under the terms of the GNU General Public License as published by the |
25 | 25 | ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
26 | 26 | ** -------------------------------------------------------------------------- |
27 | 27 | ** |
28 | ** $Id: ifprop.c,v 1.4 2007/02/13 10:34:06 gerlof Exp $ | |
28 | ** $Id: ifprop.c,v 1.5 2010/04/23 12:19:35 gerlof Exp $ | |
29 | 29 | ** $Log: ifprop.c,v $ |
30 | ** Revision 1.5 2010/04/23 12:19:35 gerlof | |
31 | ** Modified mail-address in header. | |
32 | ** | |
30 | 33 | ** Revision 1.4 2007/02/13 10:34:06 gerlof |
31 | 34 | ** Removal of external declarations. |
32 | 35 | ** |
0 | .TH ATOP 1 "March 2008" "AT Computing" | |
0 | .TH ATOP 1 "April 2010" "AT Computing" | |
1 | 1 | .SH NAME |
2 | 2 | .B atop |
3 | 3 | - AT Computing's System & Process Monitor |
5 | 5 | Interactive usage: |
6 | 6 | .P |
7 | 7 | .B atop |
8 | [-g|-m|-d|-n|-u|-p|-s|-c|-v] [-C|-M|-D|-N|-A] [-af1x] [-Plabel[,label]...] | |
8 | [-g|-m|-d|-n|-u|-p|-s|-c|-v|-o] [-C|-M|-D|-N|-A] [-af1x] [-L linelen] [-Plabel[,label]...] | |
9 | 9 | [ |
10 | 10 | .I interval |
11 | 11 | [ |
31 | 31 | .I hh:mm |
32 | 32 | ] [-e |
33 | 33 | .I hh:mm |
34 | ] [-g|-m|-d|-n|-u|-p|-s|-c|-v] [-C|-M|-D|-N|-A] [-f1x] [-Plabel[,label]...] | |
34 | ] [-g|-m|-d|-n|-u|-p|-s|-c|-v|-o] [-C|-M|-D|-N|-A] [-f1x] [-L linelen] [-Plabel[,label]...] | |
35 | 35 | .SH DESCRIPTION |
36 | 36 | The program |
37 | 37 | .I atop |
41 | 41 | and network. |
42 | 42 | .br |
43 | 43 | It also shows which processes are responsible for the indicated |
44 | load with respect to cpu- and memory load on process level; | |
45 | disk- and network load is only shown per process if a kernel patch | |
44 | load with respect to cpu- and memory load on process level. | |
45 | Disk load is shown if per process "storage accounting" is active in the kernel | |
46 | or if the kernel patch `cnt' has been installed. | |
47 | Network load is only shown per process if the kernel patch `cnt' | |
46 | 48 | has been installed. |
47 | 49 | .PP |
48 | 50 | Every |
64 | 66 | .I atop |
65 | 67 | is started, it checks whether the standard output channel is connected to a |
66 | 68 | screen, or to a file/pipe. In the first case it produces screen control |
67 | codes (via the curses library) and behaves interactively; in the second case | |
69 | codes (via the ncurses library) and behaves interactively; in the second case | |
68 | 70 | it produces flat ASCII-output. |
69 | 71 | .PP |
70 | 72 | In interactive mode, the output of |
73 | .I atop | |
74 | scales dynamically to the current dimensions of the screen/window. | |
75 | .br | |
76 | If the window is resized horizontally, columns will be added or removed | |
77 | automatically. For this purpose, every column has a particular weight. The | |
78 | columns with the highest weigths that fit within the current width will | |
79 | be shown. | |
80 | .br | |
81 | If the window is resized vertically, lines of the process-list | |
82 | will be added or removed automatically. | |
83 | .PP | |
84 | Furthermore in interactive mode the output of | |
71 | 85 | .I atop |
72 | 86 | can be controlled by pressing particular keys. |
73 | 87 | However it is also possible to specify such key as |
111 | 125 | accounting file can be specified (accounting should have been activated |
112 | 126 | on beforehand). When this environment variable is present but its |
113 | 127 | contents is empty, process accounting will not be used at all. |
128 | .PP | |
129 | Notice that root-privileges are required to switch on process accounting | |
130 | in the kernel. You can start | |
131 | .I atop | |
132 | as root or specify setuid-root privileges to the executable file. | |
133 | In the latter case, | |
134 | .I atop | |
135 | switches on process accounting and immediately drops the root-privileges | |
136 | again. | |
114 | 137 | .SH COLORS |
115 | 138 | For the resource consumption on system level, |
116 | 139 | .I atop |
159 | 182 | it is not critical from a performance point-of-view. |
160 | 183 | .PP |
161 | 184 | These default values can be modified in the configuration file |
162 | (see section CONFIGURATION FILE). | |
185 | (see separate man-page of atoprc). | |
163 | 186 | .PP |
164 | 187 | When a resource exceeded its critical occupation percentage, the entire |
165 | 188 | screen line is colored red. |
168 | 191 | (so it is almost critical), the entire screen line |
169 | 192 | is colored cyan. This `almost critical percentage' (one value |
170 | 193 | for all resources) can be modified in the configuration file |
171 | (see section CONFIGURATION FILE). | |
194 | (see separate man-page of atoprc). | |
172 | 195 | .PP |
173 | 196 | With the key 'x' (or flag -x), line coloring can be suppressed. |
174 | 197 | .SH INTERACTIVE COMMANDS |
183 | 206 | .B g |
184 | 207 | Show generic output (default). |
185 | 208 | |
186 | Per process the following fields are shown: process-id, cpu consumption during | |
209 | Per process the following fields are shown in case of a window-width | |
210 | of 80 positions: | |
211 | process-id, cpu consumption during | |
187 | 212 | the last interval in system- and user mode, the virtual and resident |
188 | 213 | memory growth of the process. |
189 | 214 | .br |
192 | 217 | number of read- and write transfers on disk, and the number of received and |
193 | 218 | transmitted network packets are shown for each process. |
194 | 219 | When the kernel patch is not installed and the kernel supports |
195 | per-process io statistics (>= 2.6.20), the data transfer for read/write | |
220 | "storage accounting" (>= 2.6.20), the data transfer for read/write | |
196 | 221 | on disk, the status and exit code are shown for each process. |
197 | 222 | When the kernel patch is not installed and the kernel does not support |
198 | per-process io statistics, the username, number of threads in the | |
223 | "storage accounting", the username, number of threads in the | |
199 | 224 | thread group, the status and exit code are shown. |
200 | 225 | .br |
201 | 226 | The last columns contain the state, the occupation percentage for the |
202 | 227 | choosen resource (default: cpu) and the process name. |
228 | ||
229 | When more than 80 positions are available, other information is added. | |
203 | 230 | .PP |
204 | 231 | .TP 5 |
205 | 232 | .B m |
206 | 233 | Show memory related output. |
207 | 234 | |
208 | Per process the following fields are shown: process-id, minor and major | |
235 | Per process the following fields are shown in case of a window-width | |
236 | of 80 positions: | |
237 | process-id, minor and major | |
209 | 238 | memory faults, size of virtual shared text, total virtual |
210 | 239 | process size, total resident process size, virtual and resident growth during |
211 | 240 | last interval, memory occupation percentage and process name. |
241 | ||
242 | When more than 80 positions are available, other information is added. | |
212 | 243 | .PP |
213 | 244 | .TP 5 |
214 | 245 | .B d |
215 | 246 | Show disk-related output. |
216 | 247 | |
217 | Per process the following fields are shown: process-id, number of | |
248 | When "storage accounting" is active in the kernel, the following | |
249 | fields are shown: | |
250 | process-id, amount of data read from disk, amount of data written to disk, | |
251 | amount of data that was written but has been withdrawn again (WCANCL), | |
252 | disk occupation percentage and process name. | |
253 | ||
254 | When the kernel patch `cnt' is installed in the kernel, the following | |
255 | fields are shown: | |
256 | process-id, number of | |
218 | 257 | physical disk reads, average size per read (bytes), total size for |
219 | 258 | read transfers, |
220 | 259 | physical disk writes, average size per write (bytes), total size for |
221 | 260 | write transfers, disk occupation percentage and process name. |
222 | .br | |
223 | This information can only be shown when kernel patch `cnt' is installed. | |
224 | 261 | .PP |
225 | 262 | .TP 5 |
226 | 263 | .B n |
227 | 264 | Show network related output. |
228 | 265 | |
229 | Per process the following fields are shown: process-id, | |
266 | Per process the following fields are shown in case of a window-width | |
267 | of 80 positions: | |
268 | process-id, | |
230 | 269 | number of received TCP packets with the average size per packet (in bytes), |
231 | 270 | number of sent TCP packets with the average size per packet (in bytes), |
232 | 271 | number of received UDP packets with the average size per packet (in bytes), |
233 | 272 | number of sent UDP packets with the average size per packet (in bytes), |
234 | and received and send raw packets (e.g. ICMP) in one column, | |
273 | and received and sent raw packets (e.g. ICMP) in one column, | |
235 | 274 | the network occupation percentage and process name. |
236 | 275 | .br |
237 | 276 | This information can only be shown when kernel patch `cnt' is installed. |
277 | ||
278 | When more than 80 positions are available, other information is added. | |
238 | 279 | .PP |
239 | 280 | .TP 5 |
240 | 281 | .B s |
241 | 282 | Show scheduling characteristics. |
242 | 283 | |
243 | Per process the following fields are shown: | |
284 | Per process the following fields are shown in case of a window-width | |
285 | of 80 positions: | |
244 | 286 | process-id, |
245 | 287 | number of threads in state 'running' (R), |
246 | 288 | number of threads in state 'interruptible sleeping' (S), |
249 | 291 | nice value, priority, realtime priority, current processor, |
250 | 292 | status, exit code, state, the occupation percentage for the choosen |
251 | 293 | resource and the process name. |
294 | ||
295 | When more than 80 positions are available, other information is added. | |
252 | 296 | .PP |
253 | 297 | .TP 5 |
254 | 298 | .B v |
255 | 299 | Show various process characteristics. |
256 | 300 | |
257 | Per process the following fields are shown: process-id, user name and group, | |
301 | Per process the following fields are shown in case of a window-width | |
302 | of 80 positions: | |
303 | process-id, user name and group, | |
258 | 304 | start date and time, status (e.g. exit code if the process has finished), |
259 | 305 | state, the occupation percentage for the choosen resource and the process name. |
306 | ||
307 | When more than 80 positions are available, other information is added. | |
260 | 308 | .PP |
261 | 309 | .TP 5 |
262 | 310 | .B c |
265 | 313 | Per process the following fields are shown: process-id, |
266 | 314 | the occupation percentage for the choosen resource and the |
267 | 315 | command line including arguments. |
316 | .PP | |
317 | .TP 5 | |
318 | .B o | |
319 | Show the user-defined line of the process. | |
320 | ||
321 | In the configuration file the keyword | |
322 | .I ownprocline | |
323 | can be specified with the description of a user-defined output-line. | |
324 | .br | |
325 | Refer to the man-page of | |
326 | .B atoprc | |
327 | for a detailed description. | |
268 | 328 | .PP |
269 | 329 | .TP 5 |
270 | 330 | .B u |
276 | 336 | the current virtual and resident memory space consumed by active processes |
277 | 337 | (or all processes of the user if combined with command `a'). |
278 | 338 | .br |
279 | When the kernel patch `cnt' has been installed, the accumulated | |
280 | number of read- and write transfers on disk, and the number of received and | |
281 | sent network packets are shown. When the kernel patch is not installed, | |
282 | these counters are zero. | |
339 | When the kernel patch `cnt' has been installed or "storage accounting" is | |
340 | active, the accumulated read- and write throughput on disk is shown. | |
341 | When the kernel patch `cnt' has been installed, | |
342 | the number of received and sent network packets are shown. | |
283 | 343 | .br |
284 | 344 | The last columns contain the accumulated occupation percentage for the |
285 | 345 | choosen resource (default: cpu) and the user name. |
294 | 354 | the current virtual and resident memory space consumed by active processes |
295 | 355 | (or all processes of the user if combined with command `a'). |
296 | 356 | .br |
297 | When the kernel patch `cnt' has been installed, the accumulated | |
298 | number of read- and write transfers on disk, and the number of received and | |
299 | sent network packets are shown. When the kernel patch is not installed, | |
300 | these counters are zero. | |
357 | When the kernel patch `cnt' has been installed or "storage accounting" is | |
358 | active, the accumulated read- and write throughput on disk is shown. | |
359 | When the kernel patch `cnt' has been installed, | |
360 | the number of received and sent network packets are shown. | |
301 | 361 | .br |
302 | 362 | The last columns contain the accumulated occupation percentage for the |
303 | 363 | choosen resource (default: cpu) and the program name. |
335 | 395 | This option remains valid until |
336 | 396 | another sorting-order is explicitly selected again. |
337 | 397 | .br |
338 | A sorting-order for disk or network is only possible when kernel patch `cnt' | |
398 | A sorting-order for disk is only possible when the kernel patch `cnt' | |
399 | is installed or "storage accounting" is active. | |
400 | A sorting-order for network is only possible when the kernel patch `cnt' | |
339 | 401 | is installed. |
340 | 402 | .PP |
341 | 403 | Miscellaneous interactive commands: |
350 | 412 | .PP |
351 | 413 | .TP 5 |
352 | 414 | .B x |
353 | Use colors to highlight critical resources (toggle). | |
415 | Suppress colors to highlight critical resources (toggle). | |
416 | .br | |
417 | Whether this key is active or not can be seen in the header line. | |
354 | 418 | .PP |
355 | 419 | .TP 5 |
356 | 420 | .B z |
385 | 449 | .B T |
386 | 450 | When viewing the contents of a raw file, this key can be used to show the |
387 | 451 | previous sample from the file. |
452 | .PP | |
453 | .TP 5 | |
454 | .B b | |
455 | When viewing the contents of a raw file, this key can be used to branch | |
456 | to a certain timestamp within the file (either forward or backward). | |
388 | 457 | .PP |
389 | 458 | .TP 5 |
390 | 459 | .B r |
402 | 471 | The system statistics are still system wide. |
403 | 472 | If the Enter-key is pressed without specifying a name, active |
404 | 473 | processes of all users will be shown again. |
474 | .br | |
475 | Whether this key is active or not can be seen in the header line. | |
405 | 476 | .PP |
406 | 477 | .TP 5 |
407 | 478 | .B P |
411 | 482 | The system statistics are still system wide. |
412 | 483 | If the Enter-key is pressed without specifying a name, all active |
413 | 484 | processes will be shown again. |
485 | .br | |
486 | Whether this key is active or not can be seen in the header line. | |
414 | 487 | .PP |
415 | 488 | .TP 5 |
416 | 489 | .B a |
417 | 490 | The `all/active' key can be used to toggle between only showing/accumulating |
418 | 491 | the processes that were active during the last interval (default) or |
419 | 492 | showing/accumulating all processes. |
493 | .br | |
494 | Whether this key is active or not can be seen in the header line. | |
420 | 495 | .PP |
421 | 496 | .TP 5 |
422 | 497 | .B f |
426 | 501 | With this key you can force |
427 | 502 | .I atop |
428 | 503 | to show lines of inactive resources as well. |
504 | .br | |
505 | Whether this key is active or not can be seen in the header line. | |
429 | 506 | .PP |
430 | 507 | .TP 5 |
431 | 508 | .B 1 |
432 | 509 | Show relevant counters as an average per second (in the format `..../s') |
433 | 510 | instead of as a total during the interval (toggle). |
511 | .br | |
512 | Whether this key is active or not can be seen in the header line. | |
434 | 513 | .PP |
435 | 514 | .TP 5 |
436 | 515 | .B l |
453 | 532 | .PP |
454 | 533 | .TP 5 |
455 | 534 | .B k |
456 | Send a signal to an active process (aka kill a process). | |
535 | Send a signal to an active process (a.k.a. kill a process). | |
457 | 536 | .PP |
458 | 537 | .TP 5 |
459 | 538 | .B q |
460 | Quit the monitor program. | |
539 | Quit the program. | |
461 | 540 | .PP |
462 | 541 | .TP 5 |
463 | 542 | .B ^F |
466 | 545 | .TP 5 |
467 | 546 | .B ^B |
468 | 547 | Show the previous page of the process list (backward). |
548 | .PP | |
549 | .TP 5 | |
550 | .B ^L | |
551 | Redraw the screen. | |
469 | 552 | .SH RAW DATA STORAGE |
470 | 553 | In order to store system- and process level statistics for long-term |
471 | 554 | analysis (e.g. to check the system load and the active processes running |
503 | 586 | date), the file |
504 | 587 | .BI /var/log/atop/atop_ YYYYMMDD |
505 | 588 | is opened. |
589 | If a filename with the symbolic name | |
590 | .BI y | |
591 | is specified, yesterday's daily logfile is opened | |
592 | (this can be repeated so 'yyyy' indicates the logfile of four days ago). | |
506 | 593 | .br |
507 | 594 | The samples from the file can be viewed interactively by using the key 't' |
508 | to show the next sample and the key 'T' to show the previous sample. | |
595 | to show the next sample, the key 'T' to show the previous sample, the | |
596 | key 'b' to branch to a particular time or the key 'r' to rewind to | |
597 | the begin of the file. | |
598 | .br | |
509 | 599 | When output is redirected to a file or pipe, |
510 | 600 | .B atop |
511 | prints all samples in plain ASCII. | |
601 | prints all samples in plain ASCII. The default line length is 80 characters | |
602 | in that case; with the flag | |
603 | .B -L | |
604 | followed by an alternate line length, more (or less) columns will be shown. | |
512 | 605 | .br |
513 | 606 | With the flag |
514 | 607 | .B -b |
557 | 650 | have no effect. |
558 | 651 | .SH OUTPUT DESCRIPTION |
559 | 652 | The first sample shows the system level activity since boot |
560 | (the elapsed time in the header shows the number of seconds since boot). | |
653 | (the elapsed time in the header shows the time since boot). | |
561 | 654 | Note that particular counters could have reached their maximum |
562 | 655 | value (several times) and started by zero again, |
563 | 656 | so do not rely on these figures. |
583 | 676 | (Mb instead of Kb, Gb instead of Mb). |
584 | 677 | For other values, a kind of exponent notation is used (value 123456789 |
585 | 678 | shown in a column of 5 positions gives 123e6). |
586 | .PP | |
679 | .SH OUTPUT DESCRIPTION - SYSTEM LEVEL | |
587 | 680 | The system level information consists of the following output lines: |
588 | 681 | .PP |
589 | 682 | .TP 5 |
593 | 686 | This line contains the total cpu time consumed |
594 | 687 | in system mode (`sys') and in user mode (`user'), |
595 | 688 | the total number of processes present at this moment (`#proc'), |
596 | the number of zombie processes (`#zombie') and | |
689 | the total number of threads present at this moment in state `running' (`#trun'), | |
690 | `sleeping interruptible' (`#tslpi') and `sleeping uninterruptible' (`#tslpu'), | |
691 | the number of zombie processes (`#zombie'), | |
692 | the number of clone system calls (`clones'), and | |
597 | 693 | the number of processes that ended during the interval |
598 | 694 | (`#exit', which shows `?' if process accounting is not used). |
695 | .br | |
696 | If the screen-width does not allow all of these counters, | |
697 | only a relevant subset is shown. | |
599 | 698 | .PP |
600 | 699 | .TP 5 |
601 | 700 | .B CPU |
608 | 707 | sorted on activity. Inactive cpu's will not be shown by default. |
609 | 708 | The lines showing the per-cpu occupation contain the cpu number in |
610 | 709 | the last field. |
611 | .br | |
710 | ||
612 | 711 | Every line contains the percentage of cpu time spent in |
613 | 712 | kernel mode by all active processes (`sys'), |
614 | 713 | the percentage of cpu time consumed in user mode (`user') for all |
622 | 721 | In case of per-cpu occupation, the last column shows the cpu number and |
623 | 722 | the wait percentage (`w') for that cpu. |
624 | 723 | The number of lines showing the per-cpu occupation can be limited. |
625 | .br | |
626 | For virtual machines a second line labelled `CPU' is shown as an extension | |
627 | of the first line. This second line contains the steal-percentage | |
628 | for all processors (`steal') completing the categories shown in the first | |
629 | line (`sys`, `user`, `irq', `idle' and `wait'). | |
630 | It concerns the percentage of cpu time stolen by other virtual machines | |
724 | ||
725 | For virtual machines the steal-percentage is shown (`steal'), reflecting | |
726 | the percentage of cpu time stolen by other virtual machines | |
631 | 727 | running on the same hardware. |
632 | Furthermore the average steal-percentage per processor is shown (`stl/cpu'). | |
633 | For single-processor systems this percentage is equal to the overall | |
634 | steal-percentage. | |
728 | .br | |
729 | For physical machines hosting one or more virtual machines, | |
730 | the guest-percentage is shown (`guest'), reflecting | |
731 | the percentage of cpu time used by the virtual machines. | |
732 | ||
733 | In case of frequency-scaling, all previously mentioned CPU-percentages | |
734 | are relative to the used scaling of the CPU during the interval. | |
735 | If e.g. a CPU has been active for 50% in user mode during the interval | |
736 | while the frequency-scaling of that was 40%, then only 20% of the full | |
737 | capacity of the CPU has been used in user mode. | |
738 | .br | |
739 | In case that the kernel module `cpufreq_stats' is active | |
740 | (after issueing `modprobe cpufreq_stats'), the | |
741 | .I average | |
742 | frequency (`avgf') and the | |
743 | .I average | |
744 | scaling percentage (`avgscal') is shown. Otherwise the | |
745 | .I current | |
746 | frequency (`curf') and the | |
747 | .I current | |
748 | scaling percentage (`curscal') is shown at the moment that the sample | |
749 | is taken. | |
750 | ||
751 | If the screen-width does not allow all of these counters, | |
752 | only a relevant subset is shown. | |
635 | 753 | .PP |
636 | 754 | .TP 5 |
637 | 755 | .B CPL |
642 | 760 | or that are waiting for disk I/O. These figures are averaged over |
643 | 761 | 1 (`avg1'), 5 (`avg5') and 15 (`avg15') minutes. |
644 | 762 | .br |
645 | Furthermore the number of context switches (`csw') and the number | |
646 | of serviced interrupts (`intr') are shown. | |
763 | Furthermore the number of context switches (`csw'), the number | |
764 | of serviced interrupts (`intr') and the number of available cpu's are shown. | |
765 | ||
766 | If the screen-width does not allow all of these counters, | |
767 | only a relevant subset is shown. | |
647 | 768 | .PP |
648 | 769 | .TP 5 |
649 | 770 | .B MEM |
652 | 773 | This line contains the total amount of physical memory |
653 | 774 | (`tot'), the amount of memory which is currently free (`free'), |
654 | 775 | the amount of memory in use as page cache (`cache'), |
776 | the amount of memory within the page cache that has to be flushed to disk | |
777 | (`dirty'), | |
655 | 778 | the amount of memory used for filesystem meta data (`buff') and the amount of |
656 | 779 | memory being used for kernel malloc's (`slab' - always 0 for kernel 2.4). |
780 | ||
781 | If the screen-width does not allow all of these counters, | |
782 | only a relevant subset is shown. | |
657 | 783 | .PP |
658 | 784 | .TP 5 |
659 | 785 | .B SWP |
683 | 809 | are shown. |
684 | 810 | .PP |
685 | 811 | .TP 5 |
686 | .B DSK | |
687 | Disk utilization. | |
688 | .br | |
689 | Per active disk one line is produced, sorted on disk activity. | |
690 | Such line shows the name of the disk (e.g. hda | |
691 | or sda), the busy percentage i.e. the portion of time that the | |
692 | disk was busy handling requests (`busy'), the number of read requests issued | |
693 | (`read'), the number of write requests issued (`write') and the average | |
694 | number of milliseconds needed by a request (`avio') for seek, | |
695 | latency and data transfer. | |
696 | ||
697 | The number of lines showing the disk occupation can be limited. | |
812 | .B LVM/MDD/DSK | |
813 | Logical volume/multiple device/disk utilization. | |
814 | .br | |
815 | Per active unit one line is produced, sorted on unit activity. | |
816 | Such line shows the name (e.g. VolGroup00-lvtmp for a logical volume or | |
817 | sda for a hard disk), the busy percentage i.e. the portion of time that the | |
818 | unit was busy handling requests (`busy'), the number of read requests issued | |
819 | (`read'), the number of write requests issued (`write'), | |
820 | the number of KiBytes per read (`KiB/r'), | |
821 | the number of KiBytes per write (`KiB/w'), | |
822 | the number of MiBytes per second throughput for reads (`MBr/s'), | |
823 | the number of MiBytes per second throughput for writes (`MBw/s'), | |
824 | the average queue depth (`avq') | |
825 | and the average number of milliseconds needed by a request (`avio') | |
826 | for seek, latency and data transfer. | |
827 | .br | |
828 | If the screen-width does not allow all of these counters, | |
829 | only a relevant subset is shown. | |
830 | ||
831 | The number of lines showing the units can be limited per class (LVM, MDD or | |
832 | DSK) with the 'l' key or statically (see separate man-page of atoprc). | |
833 | By specifying the value 0 for a particular class, no lines will be | |
834 | shown any more for that class. | |
698 | 835 | .PP |
699 | 836 | .TP 5 |
700 | 837 | .B NET |
705 | 842 | .br |
706 | 843 | For the transport layer, |
707 | 844 | counters are shown concerning the number of received TCP segments |
708 | including those | |
709 | received in error (`tcpi'), the number of transmitted TCP segments excluding | |
845 | including those received in error (`tcpi'), | |
846 | the number of transmitted TCP segments excluding | |
710 | 847 | those containing only retransmitted octets (`tcpo'), the number of |
711 | UDP datagrams received (`udpi') and the number of UDP datagrams | |
712 | transmitted (`udpo'). | |
713 | These counters are related to IPv4 and IPv6. | |
714 | .br | |
848 | UDP datagrams received (`udpi'), | |
849 | the number of UDP datagrams transmitted (`udpo'), | |
850 | the number of active TCP opens (`tcpao'), | |
851 | the number of passive TCP opens (`tcppo'), | |
852 | the number of TCP output retransmissions (`tcprs'), | |
853 | the number of TCP input errors (`tcpie'), | |
854 | the number of TCP output resets (`tcpie'), | |
855 | the number of TCP output retransmissions (`tcpor'), | |
856 | the number of UDP no ports (`udpnp'), and | |
857 | the number of UDP input errors (`tcpie'). | |
858 | .br | |
859 | If the screen-width does not allow all of these counters, | |
860 | only a relevant subset is shown. | |
861 | .br | |
862 | These counters are related to IPv4 and IPv6 combined. | |
863 | ||
715 | 864 | For the IP layer, counters are shown concerning the number of IP datagrams |
716 | 865 | received from interfaces, including those received in error (`ipi'), |
717 | 866 | the number of IP datagrams that local higher-layer protocols offered for |
718 | 867 | transmission (`ipo'), the number of received IP datagrams which were |
719 | forwarded to other interfaces (`ipfrw') and the number of IP datagrams which | |
720 | were delivered to local higher-layer protocols (`deliv'). | |
721 | These counters are related to IPv4 and IPv6. | |
722 | .br | |
868 | forwarded to other interfaces (`ipfrw'), the number of IP datagrams which | |
869 | were delivered to local higher-layer protocols (`deliv'), | |
870 | the number of received ICMP datagrams (`icmpi'), and | |
871 | the number of transmitted ICMP datagrams (`icmpo'). | |
872 | .br | |
873 | If the screen-width does not allow all of these counters, | |
874 | only a relevant subset is shown. | |
875 | .br | |
876 | These counters are related to IPv4 and IPv6 combined. | |
877 | ||
723 | 878 | For every active network interface one line is shown, |
724 | 879 | sorted on the interface activity. |
725 | 880 | Such line shows the name of the interface and its busy percentage |
731 | 886 | When the interface speed can not be determined (e.g. for the loopback |
732 | 887 | interface), `---' is shown instead of the percentage. |
733 | 888 | .br |
734 | Furthermore the number of received packets (`pcki'), the number of transmitted | |
735 | packets (`pcko'), the effective amount of bits received per second | |
736 | (`si') and the effective amount of bits transmitted per second (`so'). | |
737 | ||
889 | Furthermore the number of received packets (`pcki'), | |
890 | the number of transmitted packets (`pcko'), | |
891 | the effective amount of bits received per second (`si'), | |
892 | the effective amount of bits transmitted per second (`so'), | |
893 | the number of collisions (`coll'), | |
894 | the number of received multicast packets (`mlti'), | |
895 | the number of errors while receiving a packet (`erri'), | |
896 | the number of errors while transmitting a packet (`erro'), | |
897 | the number of received packets dropped (`drpi'), and | |
898 | the number of transmitted packets dropped (`drpo'). | |
899 | .br | |
900 | If the screen-width does not allow all of these counters, | |
901 | only a relevant subset is shown. | |
902 | .br | |
738 | 903 | The number of lines showing the network interfaces can be limited. |
739 | .PP | |
904 | .SH OUTPUT DESCRIPTION - PROCESS LEVEL | |
740 | 905 | Following the system level information, the processes are shown from which the |
741 | 906 | resource utilization has changed during the last interval. These processes |
742 | 907 | might have used cpu time or issued disk- or network requests. However a process |
745 | 910 | .PP |
746 | 911 | Per process the following fields may be shown (in alphabetical order), |
747 | 912 | depending on the current output mode as described in the section |
748 | INTERACTIVE COMMANDS: | |
913 | INTERACTIVE COMMANDS and depending on the current width of your window: | |
914 | .PP | |
915 | .TP 9 | |
916 | .B AVGRSZ | |
917 | The average size of one read-action on disk. | |
918 | .PP | |
919 | .TP 9 | |
920 | .B AVGWSZ | |
921 | The average size of one write-action on disk. | |
749 | 922 | .PP |
750 | 923 | .TP 9 |
751 | 924 | .B CMD |
774 | 947 | for this resource on system level. |
775 | 948 | .PP |
776 | 949 | .TP 9 |
950 | .B CPUNR | |
951 | The identification of the CPU the main thread of the process is running on | |
952 | or has recently been running on. | |
953 | .PP | |
954 | .TP 9 | |
777 | 955 | .B DSK |
778 | 956 | The occupation percentage of this process related to the total load that |
779 | 957 | is produced by all processes (i.e. total disk accesses |
780 | 958 | by all processes during the last interval). |
781 | 959 | .br |
782 | This information can only be shown when kernel patch `cnt' is installed. | |
960 | This information is shown when per process "storage accounting" is active | |
961 | in the kernel or when the kernel patch `cnt' has been installed. | |
962 | .PP | |
963 | .TP 9 | |
964 | .B EGID | |
965 | Effective group-id under which this process executes. | |
966 | .PP | |
967 | .TP 9 | |
968 | .B ENDATE | |
969 | Date that the process has been finished. If the process is still running, | |
970 | this field shows `active'. | |
971 | .PP | |
972 | .TP 9 | |
973 | .B ENTIME | |
974 | Time that the process has been finished. If the process is still running, | |
975 | this field shows `active'. | |
976 | .PP | |
977 | .TP 9 | |
978 | .B EUID | |
979 | Effective user-id under which this process executes. | |
783 | 980 | .PP |
784 | 981 | .TP 9 |
785 | 982 | .B EXC |
787 | 984 | or the fatal signal number (second position of column `ST' is S or C). |
788 | 985 | .PP |
789 | 986 | .TP 9 |
790 | .B GROUP | |
791 | The real primary group identity under which the process runs. | |
987 | .B FSGID | |
988 | Filesystem group-id under which this process executes. | |
989 | .PP | |
990 | .TP 9 | |
991 | .B FSUID | |
992 | Filesystem user-id under which this process executes. | |
792 | 993 | .PP |
793 | 994 | .TP 9 |
794 | 995 | .B MAJFLT |
795 | The number of page faults issued by this process. | |
996 | The number of page faults issued by this process that have been solved | |
997 | by creating/loading the requested memory page. | |
796 | 998 | .PP |
797 | 999 | .TP 9 |
798 | 1000 | .B MEM |
801 | 1003 | .PP |
802 | 1004 | .TP 9 |
803 | 1005 | .B MINFLT |
804 | The number of page reclaims issued by this process. | |
1006 | The number of page faults issued by this process that have been solved | |
1007 | by reclaiming the requested memory page from the free list of pages. | |
805 | 1008 | .PP |
806 | 1009 | .TP 9 |
807 | 1010 | .B NET |
810 | 1013 | by all processes during the last interval). |
811 | 1014 | .br |
812 | 1015 | This information can only be shown when kernel patch `cnt' is installed. |
1016 | .PP | |
1017 | .TP 9 | |
1018 | .B NICE | |
1019 | The more or less static priority that can be given to a proces on a | |
1020 | scale from -20 (high priority) to +19 (low priority). | |
813 | 1021 | .PP |
814 | 1022 | .TP 9 |
815 | 1023 | .B NPROCS |
827 | 1035 | .PP |
828 | 1036 | .TP 9 |
829 | 1037 | .B POLI |
830 | Policy 'norm' (normal, which is SCHED_OTHER) refers to a timesharing | |
831 | process, 'fifo' (SCHED_FIFO) and 'rr' (round robin, which is SCHED_RR) | |
832 | refer to a realtime process. | |
1038 | The policies 'norm' (normal, which is SCHED_OTHER), 'btch' (batch) | |
1039 | and 'idle' refer to timesharing processes. | |
1040 | The policies 'fifo' (SCHED_FIFO) and 'rr' (round robin, which is SCHED_RR) | |
1041 | refer to realtime processes. | |
833 | 1042 | .PP |
834 | 1043 | .TP 9 |
835 | 1044 | .B PPID |
849 | 1058 | CPU consumption and the nice value). |
850 | 1059 | .PP |
851 | 1060 | .TP 9 |
852 | .B RAWRS | |
853 | The number of raw datagrams received and sent by this process. | |
1061 | .B RAWRCV | |
1062 | The number of raw datagrams received by this process. | |
854 | 1063 | This information can only be shown when kernel patch `cnt' is installed. |
855 | 1064 | .br |
856 | 1065 | If a process has finished during the last interval, no value is shown |
860 | 1069 | shown. |
861 | 1070 | .PP |
862 | 1071 | .TP 9 |
1072 | .B RAWSND | |
1073 | The number of raw datagrams sent by this process. | |
1074 | This information can only be shown when kernel patch `cnt' is installed. | |
1075 | .br | |
1076 | If a process has finished during the last interval, no value is shown | |
1077 | since network counters are not registered in the standard | |
1078 | process accounting record. | |
1079 | However when the kernel patch `acct' is installed, this value will be | |
1080 | shown. | |
1081 | .PP | |
1082 | .TP 9 | |
863 | 1083 | .B RDDSK |
1084 | When the kernel maintains standard io statistics (>= 2.6.20): | |
1085 | .br | |
1086 | The read data transfer issued physically on disk (so reading from the | |
1087 | disk cache is not accounted for). | |
1088 | ||
864 | 1089 | When the kernel patch `cnt' is installed: |
1090 | .br | |
865 | 1091 | The number of read accesses issued physically on disk (so reading from the |
866 | 1092 | disk cache is not accounted for). |
867 | .br | |
868 | When the kernel patch `cnt' is not installed, but the kernel maintains | |
869 | standard io statistics (>= 2.6.20): | |
870 | The read data transfer issued physically on disk (so reading from the | |
871 | disk cache is not accounted for). | |
1093 | .PP | |
1094 | .TP 9 | |
1095 | .B RGID | |
1096 | The real group-id under which the process executes. | |
872 | 1097 | .PP |
873 | 1098 | .TP 9 |
874 | 1099 | .B RGROW |
910 | 1135 | .TP 9 |
911 | 1136 | .B RTPR |
912 | 1137 | Realtime priority according the POSIX standard. |
913 | Value can be 0 for a timesharing process (policy 'norm') or ranges | |
914 | from 1 (lowest) till 99 (highest) for a realtime process (policy 'rr' | |
915 | or 'fifo'). | |
1138 | Value can be 0 for a timesharing process (policy 'norm', 'btch' or 'idle') | |
1139 | or ranges from 1 (lowest) till 99 (highest) for a realtime process | |
1140 | (policy 'rr' or 'fifo'). | |
1141 | .PP | |
1142 | .TP 9 | |
1143 | .B RUID | |
1144 | The real user-id under which the process executes. | |
916 | 1145 | .PP |
917 | 1146 | .TP 9 |
918 | 1147 | .B S |
919 | The current state of the process: `R' for running (currently processing or in | |
920 | the run queue), `S' for sleeping interruptable (wait for an event to occur), | |
921 | `D' for sleeping non-interruptable, `Z' for zombie (waiting to be synchronized | |
1148 | The current state of the main thread of the process: `R' for running | |
1149 | (currently processing or in the runqueue), `S' for sleeping interruptible | |
1150 | (wait for an event to occur), | |
1151 | `D' for sleeping non-interruptible, `Z' for zombie (waiting to be synchronized | |
922 | 1152 | with its parent process), `T' for stopped (suspended or traced), `W' for |
923 | 1153 | swapping, and `E' (exit) for processes which have finished during the last |
924 | 1154 | interval. |
1155 | .PP | |
1156 | .TP 9 | |
1157 | .B SGID | |
1158 | The saved group-id of the process. | |
925 | 1159 | .PP |
926 | 1160 | .TP 9 |
927 | 1161 | .B SNET |
970 | 1204 | The start time of the process. |
971 | 1205 | .PP |
972 | 1206 | .TP 9 |
1207 | .B SUID | |
1208 | The saved user-id of the process. | |
1209 | .PP | |
1210 | .TP 9 | |
973 | 1211 | .B SYSCPU |
974 | 1212 | CPU time consumption of this process in system mode (kernel mode), usually |
975 | 1213 | due to system call handling. |
976 | 1214 | .PP |
977 | 1215 | .TP 9 |
1216 | .B TCPRASZ | |
1217 | The average size of a received TCP buffer in bytes (by the process). | |
1218 | This information can only be shown when kernel patch `cnt' is installed. | |
1219 | When the kernel patch `acct' is installed as well, this value will also be | |
1220 | shown when a process has finished during the last interval. | |
1221 | .PP | |
1222 | .TP 9 | |
978 | 1223 | .B TCPRCV |
979 | The number of receive requests issued by this process for TCP sockets, | |
980 | and the average size per transfer in bytes. | |
1224 | The number of receive requests issued by this process for TCP sockets. | |
981 | 1225 | This information can only be shown when kernel patch `cnt' is installed. |
982 | .br | |
983 | If a process has finished during the last interval, no value is shown | |
984 | since network counters are not registered in the standard | |
985 | process accounting record. | |
986 | However when the kernel patch `acct' is installed, this value will be | |
987 | shown. | |
1226 | When the kernel patch `acct' is installed as well, this value will also be | |
1227 | shown when a process has finished during the last interval. | |
1228 | .PP | |
1229 | .TP 9 | |
1230 | .B TCPSASZ | |
1231 | The average size of a transmitted TCP buffer in bytes (by the process). | |
1232 | This information can only be shown when kernel patch `cnt' is installed. | |
1233 | When the kernel patch `acct' is installed as well, this value will also be | |
1234 | shown when a process has finished during the last interval. | |
988 | 1235 | .PP |
989 | 1236 | .TP 9 |
990 | 1237 | .B TCPSND |
991 | 1238 | The number of send requests issued by this process for TCP sockets, |
992 | 1239 | and the average size per transfer in bytes. |
993 | 1240 | This information can only be shown when kernel patch `cnt' is installed. |
994 | .br | |
995 | If a process has finished during the last interval, no value is shown | |
996 | since network counters are not registered in the standard | |
997 | process accounting record. | |
998 | However when the kernel patch `acct' is installed, this value will be | |
999 | shown. | |
1241 | When the kernel patch `acct' is installed as well, this value will also be | |
1242 | shown when a process has finished during the last interval. | |
1000 | 1243 | .PP |
1001 | 1244 | .TP 9 |
1002 | 1245 | .B THR |
1012 | 1255 | as a separate line. |
1013 | 1256 | .PP |
1014 | 1257 | .TP 9 |
1258 | .B TOTRSZ | |
1259 | The total amount of data physically read from disk. | |
1260 | This information can only be shown when kernel patch `cnt' is installed. | |
1261 | .PP | |
1262 | .TP 9 | |
1263 | .B TOTWSZ | |
1264 | The total amount of data physically written to disk. | |
1265 | This information can only be shown when kernel patch `cnt' is installed. | |
1266 | .PP | |
1267 | .TP 9 | |
1015 | 1268 | .B TRUN |
1016 | 1269 | Number of threads within this process that are in the state 'running' (R). |
1017 | 1270 | .PP |
1026 | 1279 | state 'uninterruptible sleeping' (D). |
1027 | 1280 | .PP |
1028 | 1281 | .TP 9 |
1282 | .B UDPRASZ | |
1283 | The average size of a received UDP packet in bytes. | |
1284 | This information can only be shown when kernel patch `cnt' is installed. | |
1285 | When the kernel patch `acct' is installed as well, this value will also be | |
1286 | shown when a process has finished during the last interval. | |
1287 | .PP | |
1288 | .TP 9 | |
1029 | 1289 | .B UDPRCV |
1030 | The number of UDP datagrams received by this process, | |
1290 | The number of receive requests issued by this process for UDP sockets. | |
1291 | This information can only be shown when kernel patch `cnt' is installed. | |
1292 | When the kernel patch `acct' is installed as well, this value will also be | |
1293 | shown when a process has finished during the last interval. | |
1294 | .PP | |
1295 | .TP 9 | |
1296 | .B UDPSASZ | |
1297 | The average size of a transmitted UDP packets in bytes. | |
1298 | This information can only be shown when kernel patch `cnt' is installed. | |
1299 | When the kernel patch `acct' is installed as well, this value will also be | |
1300 | shown when a process has finished during the last interval. | |
1301 | .PP | |
1302 | .TP 9 | |
1303 | .B UDPSND | |
1304 | The number of send requests issued by this process for TCP sockets, | |
1031 | 1305 | and the average size per transfer in bytes. |
1032 | 1306 | This information can only be shown when kernel patch `cnt' is installed. |
1033 | .br | |
1034 | If a process has finished during the last interval, no value is shown | |
1035 | since network counters are not registered in the standard | |
1036 | process accounting record. | |
1037 | However when the kernel patch `acct' is installed, this value will be | |
1038 | shown. | |
1039 | .PP | |
1040 | .TP 9 | |
1041 | .B UDPSND | |
1042 | The number of UDP datagrams transmitted by this process, | |
1043 | and the average size per transfer in bytes. | |
1044 | This information can only be shown when kernel patch `cnt' is installed. | |
1045 | .br | |
1046 | If a process has finished during the last interval, no value is shown | |
1047 | since network counters are not registered in the standard | |
1048 | process accounting record. | |
1049 | However when the kernel patch `acct' is installed, this value will be | |
1050 | shown. | |
1051 | .PP | |
1052 | .TP 9 | |
1053 | .B USERNAME | |
1054 | The real user identity under which the process runs. | |
1307 | When the kernel patch `acct' is installed as well, this value will also be | |
1308 | shown when a process has finished during the last interval. | |
1055 | 1309 | .PP |
1056 | 1310 | .TP 9 |
1057 | 1311 | .B USRCPU |
1089 | 1343 | .PP |
1090 | 1344 | .TP 9 |
1091 | 1345 | .B WRDSK |
1346 | When the kernel maintains standard io statistics (>= 2.6.20): | |
1347 | .br | |
1348 | The write data transfer issued physically on disk (so writing to the | |
1349 | disk cache is not accounted for). | |
1350 | This counter is maintained for the application process that writes its | |
1351 | data to the cache (assuming that this data is physically transferred | |
1352 | to disk later on). Notice that disk I/O needed for swapping is | |
1353 | not taken into account. | |
1354 | ||
1092 | 1355 | When the kernel patch `cnt' is installed: |
1356 | .br | |
1093 | 1357 | The number of write accesses issued physically on disk (so writing to the |
1094 | 1358 | disk cache is not accounted for). Usually application processes just transfer |
1095 | 1359 | their data to the cache, while the physical write accesses are done later on |
1100 | 1364 | process has finished during the last interval. |
1101 | 1365 | However when the kernel patch `acct' is installed, these values will be |
1102 | 1366 | shown separately. |
1103 | .br | |
1367 | .PP | |
1368 | .TP 9 | |
1369 | .B WCANCL | |
1104 | 1370 | When the kernel patch `cnt' is not installed, but the kernel maintains |
1105 | 1371 | standard io statistics (>= 2.6.20): |
1106 | The write data transfer issued physically on disk (so writing to the | |
1107 | disk cache is not accounted for). | |
1108 | This counter is maintained for the application process that writes its | |
1109 | data to the cache (assuming that this data is physically transferred | |
1110 | to disk later on). Notice that disk I/O needed for swapping is | |
1111 | not taken into account. | |
1112 | .PP | |
1113 | .TP 9 | |
1114 | .B WRDSK_CANCEL | |
1115 | When the kernel patch `cnt' is not installed, but the kernel maintains | |
1116 | standard io statistics (>= 2.6.20): | |
1372 | .br | |
1117 | 1373 | The write data transfer previously accounted for this process |
1118 | 1374 | or another process that has been cancelled. |
1119 | E.g. when a process writes new data to a file and that data is removed | |
1375 | Suppose that a process writes new data to a file and that data is removed | |
1120 | 1376 | again before the cache buffers have been flushed to disk. |
1121 | The original process shows the written data as WRDSK, while | |
1377 | Then the original process shows the written data as WRDSK, while | |
1122 | 1378 | the process that removes/truncates the file shows |
1123 | the unflushed removed data as WRDSK_CANCEL. | |
1379 | the unflushed removed data as WCANCL. | |
1124 | 1380 | .SH PARSEABLE OUTPUT |
1125 | 1381 | With the flag |
1126 | 1382 | .B -P |
1129 | 1385 | The labels that can be specified for system-level statistics |
1130 | 1386 | correspond to the labels (first verb of each line) |
1131 | 1387 | that can be found in the interactive output: |
1132 | "CPU", "cpu" "CPL" "MEM", "SWP", "PAG", "DSK" and "NET". | |
1388 | "CPU", "cpu" "CPL" "MEM", "SWP", "PAG", "LVM", "MDD", "DSK" and "NET". | |
1133 | 1389 | .br |
1134 | 1390 | For process-level statistics special labels are introduced: |
1135 | 1391 | "PRG" (general), "PRC" (cpu), "PRM" (memory), "PRD" (disk, only if |
1142 | 1398 | .B atop |
1143 | 1399 | shows a line just containing the label "SEP" as a separator before the |
1144 | 1400 | lines for the next sample are generated. |
1401 | .br | |
1402 | When a sample contains the values since boot, | |
1403 | .B atop | |
1404 | shows a line just containing the label "RESET" before the | |
1405 | lines for this sample are generated. | |
1145 | 1406 | .PP |
1146 | 1407 | The first part of each output-line consists of the following six fields: |
1147 | 1408 | .B label |
1170 | 1431 | consumption for all CPU's in idle mode (clock-ticks), |
1171 | 1432 | consumption for all CPU's in wait mode (clock-ticks), |
1172 | 1433 | consumption for all CPU's in irq mode (clock-ticks), |
1173 | consumption for all CPU's in softirq mode (clock-ticks), and | |
1174 | consumption for all CPU's in steal mode (clock-ticks). | |
1434 | consumption for all CPU's in softirq mode (clock-ticks), | |
1435 | consumption for all CPU's in steal mode (clock-ticks), and | |
1436 | consumption for all CPU's in guest mode (clock-ticks). | |
1175 | 1437 | .TP 9 |
1176 | 1438 | .B cpu |
1177 | 1439 | Subsequent fields: |
1183 | 1445 | consumption for this CPU in idle mode (clock-ticks), |
1184 | 1446 | consumption for this CPU in wait mode (clock-ticks), |
1185 | 1447 | consumption for this CPU in irq mode (clock-ticks), |
1186 | consumption for this CPU in softirq mode (clock-ticks), and | |
1187 | consumption for this CPU in steal mode (clock-ticks). | |
1448 | consumption for this CPU in softirq mode (clock-ticks), | |
1449 | consumption for this CPU in steal mode (clock-ticks), and | |
1450 | consumption for this CPU in guest mode (clock-ticks). | |
1188 | 1451 | .TP 9 |
1189 | 1452 | .B CPL |
1190 | 1453 | Subsequent fields: |
1201 | 1464 | size of physical memory (pages), |
1202 | 1465 | size of free memory (pages), |
1203 | 1466 | size of page cache (pages), |
1204 | size of buffer cache (pages), and | |
1205 | size of slab (pages). | |
1467 | size of buffer cache (pages), | |
1468 | size of slab (pages), and | |
1469 | number of dirty pages in cache. | |
1206 | 1470 | .TP 9 |
1207 | 1471 | .B SWP |
1208 | 1472 | Subsequent fields: |
1222 | 1486 | number of swapins, and |
1223 | 1487 | number of swapouts. |
1224 | 1488 | .TP 9 |
1225 | .B DSK | |
1226 | For every disk one line is shown. | |
1489 | .B LVM/MDD/DSK | |
1490 | For every logical volume/multiple device/hard disk one line is shown. | |
1227 | 1491 | .br |
1228 | 1492 | Subsequent fields: |
1229 | name of disk, | |
1493 | name, | |
1230 | 1494 | number of milliseconds spent for I/O, |
1231 | 1495 | number of reads issued, |
1232 | 1496 | number of sectors transferred for reads, |
1268 | 1532 | exit code, start time (epoch), |
1269 | 1533 | full command line (between brackets), PPID, |
1270 | 1534 | number of threads in state 'running' (R), |
1271 | number of threads in state 'interruptible sleeping' (S), and | |
1272 | number of threads in state 'uninterruptible sleeping' (D). | |
1535 | number of threads in state 'interruptible sleeping' (S), | |
1536 | number of threads in state 'uninterruptible sleeping' (D), | |
1537 | effective uid, effective gid, | |
1538 | saved uid, saved gid, | |
1539 | filesystem uid, filesystem gid, and elapsed time (hertz). | |
1273 | 1540 | .TP 9 |
1274 | 1541 | .B PRC |
1275 | 1542 | For every process one line is shown. |
1362 | 1629 | .PP |
1363 | 1630 | .B \ atop -PCPU,DSK -r /tmp/atop.raw |
1364 | 1631 | .PP |
1365 | .SH CONFIGURATION FILE | |
1366 | .PP | |
1367 | The default values used by | |
1368 | .B atop | |
1369 | can be overruled by a personal configuration file. | |
1370 | This file, called | |
1371 | .B ~/.atoprc | |
1372 | contains a keyword-value pair on every line (blank lines | |
1373 | and lines starting with a #-sign are skipped). | |
1374 | The following keywords can be specified: | |
1375 | .PP | |
1376 | .TP 9 | |
1377 | .B flags | |
1378 | A list of default flags for | |
1379 | .B atop | |
1380 | can be defined here. The flags which are allowed | |
1381 | are 'g', 'm', 'd', 'n', 'u', 'p', 's', 'c', 'v', 'C', 'M', 'D', 'N', 'A', 'a', 'f', '1' and 'x'. | |
1382 | .PP | |
1383 | .TP 9 | |
1384 | .B interval | |
1385 | The default interval value in seconds. | |
1386 | .PP | |
1387 | .TP 9 | |
1388 | .B username | |
1389 | The default regular expression for the users for which active | |
1390 | processes will be shown. | |
1391 | .PP | |
1392 | .TP 9 | |
1393 | .B procname | |
1394 | The default regular expression for the process names to be shown. | |
1395 | .PP | |
1396 | .TP 9 | |
1397 | .B maxlinecpu | |
1398 | The maximum number of active CPU's which will be shown. | |
1399 | .PP | |
1400 | .TP 9 | |
1401 | .B maxlinedisk | |
1402 | The maximum number of active disks which will be shown. | |
1403 | .PP | |
1404 | .TP 9 | |
1405 | .B maxlineintf | |
1406 | The maximum number of active network interfaces which will be shown. | |
1407 | .PP | |
1408 | .TP 9 | |
1409 | .B cpucritperc | |
1410 | The busy percentage considered critical for a processor | |
1411 | (see section COLORS). | |
1412 | This percentage is used to determine | |
1413 | a weighted percentage for line coloring and sorting of active processes. | |
1414 | When this value is zero, no line coloring or automatic sorting is performed | |
1415 | for this resource. | |
1416 | .PP | |
1417 | .TP 9 | |
1418 | .B dskcritperc | |
1419 | The busy percentage considered critical for a disk | |
1420 | (see section COLORS). | |
1421 | This percentage is used to determine | |
1422 | a weighted percentage for line coloring and sorting of active processes. | |
1423 | When this value is zero, no line coloring or automatic sorting is performed | |
1424 | for this resource. | |
1425 | .PP | |
1426 | .TP 9 | |
1427 | .B netcritperc | |
1428 | The busy percentage considered critical for a network interface | |
1429 | (see section COLORS). | |
1430 | This percentage is used to determine | |
1431 | a weighted percentage for line coloring and sorting of active processes. | |
1432 | When this value is zero, no line coloring or automatic sorting is performed | |
1433 | for this resource. | |
1434 | .PP | |
1435 | .TP 9 | |
1436 | .B memcritperc | |
1437 | The percentage considered critical for memory utilization | |
1438 | (see section COLORS). | |
1439 | This percentage is used to determine | |
1440 | a weighted percentage for line coloring and sorting of active processes. | |
1441 | When this value is zero, no line coloring or automatic sorting is performed | |
1442 | for this resource. | |
1443 | .PP | |
1444 | .TP 9 | |
1445 | .B swpcritperc | |
1446 | The occupation percentage considered critical for swap space | |
1447 | (see section COLORS). | |
1448 | This percentage is used to determine | |
1449 | a weighted percentage for line coloring and sorting of active processes. | |
1450 | When this value is zero, no line coloring or automatic sorting is performed | |
1451 | for this resource. | |
1452 | .PP | |
1453 | .TP 9 | |
1454 | .B swoutcritsec | |
1455 | The number of pages swapped out per second considered critical for | |
1456 | for memory utilization (see section COLORS). | |
1457 | This threshold is used in combination with 'memcritperc' to determine a | |
1458 | weighted percentage for line coloring and sorting of active processes. | |
1459 | When this value is zero, no line coloring or automatic sorting is performed | |
1460 | for this resource. | |
1461 | .PP | |
1462 | .TP 9 | |
1463 | .B almostcrit | |
1464 | A percentage of the critical percentage to determine if the resource | |
1465 | is almost critical (see section COLORS). | |
1466 | When this value is zero, no line coloring for `almost critical' is | |
1467 | performed. | |
1468 | .PP | |
1469 | .TP 9 | |
1470 | .B atopsarflags | |
1471 | A list of default flags for | |
1472 | .B atopsar | |
1473 | can be defined here (see description in related man-page). | |
1474 | .PP | |
1475 | An example of the | |
1476 | .B ~/.atoprc | |
1477 | file: | |
1478 | .TP 12 | |
1479 | \ | |
1480 | .br | |
1481 | flags\ \ \ \ \ \ \ \ \ Aaf | |
1482 | .br | |
1483 | interval\ \ \ \ \ \ 5 | |
1484 | .br | |
1485 | username | |
1486 | .br | |
1487 | procname | |
1488 | .br | |
1489 | maxlinecpu\ \ \ \ 4 | |
1490 | .br | |
1491 | maxlinedisk\ \ \ 10 | |
1492 | .br | |
1493 | maxlineintf\ \ \ 5 | |
1494 | .br | |
1495 | cpucritperc\ \ \ 80 | |
1496 | .br | |
1497 | almostcrit\ \ \ \ 90 | |
1498 | .br | |
1499 | atopsarflags\ \ CMH | |
1632 | View the contents of today's standard logfile interactively: | |
1633 | .PP | |
1634 | .B \ atop -r | |
1635 | .PP | |
1636 | View the contents of the standard logfile of the day before yesterday | |
1637 | interactively: | |
1638 | .PP | |
1639 | .B \ atop -r yy | |
1640 | .PP | |
1641 | View the contents of the standard logfile of 2010, January 7 from | |
1642 | 02:00 PM onwards interactively: | |
1643 | .PP | |
1644 | .B \ atop -r 20100107 -b 14:00 | |
1500 | 1645 | .PP |
1501 | 1646 | .SH FILES |
1502 | 1647 | .PP |
1510 | 1655 | is not used. |
1511 | 1656 | .PP |
1512 | 1657 | .TP 5 |
1658 | .B /etc/atoprc | |
1659 | Configuration file containing system-wide default values. | |
1660 | See related man-page. | |
1661 | .PP | |
1662 | .TP 5 | |
1513 | 1663 | .B ~/.atoprc |
1514 | 1664 | Configuration file containing personal default values. |
1665 | See related man-page. | |
1515 | 1666 | .PP |
1516 | 1667 | .TP 5 |
1517 | 1668 | .BI /var/log/atop/atop_ YYYYMMDD |
1530 | 1681 | in compressed format. |
1531 | 1682 | .SH SEE ALSO |
1532 | 1683 | .B atopsar(1), |
1684 | .B atoprc(5), | |
1533 | 1685 | .B logrotate(8) |
1534 | 1686 | .br |
1535 | .B http://www.ATComputing.nl/Tools/atop | |
1687 | .B http://www.atoptool.nl | |
1536 | 1688 | .SH AUTHOR |
1537 | Gerlof Langeveld, AT Computing (gerlof@ATComputing.nl) | |
1689 | Gerlof Langeveld (gerlof.langeveld@atoptool.nl) | |
1690 | .br | |
1691 | JC van Winkel (jc@ATComputing.nl) |
0 | .TH ATOPRC 5 "April 2010" "AT Computing" | |
1 | .SH NAME | |
2 | .B atoprc | |
3 | - atop/atopsar related rcfile | |
4 | .SH DESCRIPTION | |
5 | This manual page documents the rcfile of the | |
6 | .I atop | |
7 | and | |
8 | .I atopsar | |
9 | commands. | |
10 | These commands can be used to monitor the system and process load on a | |
11 | Linux system. | |
12 | .PP | |
13 | The atoprc file contains the default settings. These settings are read | |
14 | during startup, first from the system-wide rcfile | |
15 | .I /etc/atoprc | |
16 | and after that from the user-specific rcfile | |
17 | .I ~/.atoprc | |
18 | (so system-wide settings can be overruled by an individual user). | |
19 | The options in both rcfiles are identical. | |
20 | .PP | |
21 | .SH OPTIONS | |
22 | .PP | |
23 | The rcfile contains keyword-value pairs, one on every line (blank lines | |
24 | and lines starting with a #-sign are ignored). | |
25 | .br | |
26 | The following keywords can be specified: | |
27 | .PP | |
28 | .TP 4 | |
29 | .B flags | |
30 | A list of default flags for | |
31 | .B atop | |
32 | can be defined here. The flags which are allowed | |
33 | are 'g', 'm', 'd', 'n', 'u', 'p', 's', 'c', 'v', 'C', 'M', 'D', 'N', 'A', 'a', 'f', '1' and 'x'. | |
34 | .PP | |
35 | .TP 4 | |
36 | .B interval | |
37 | The default interval value in seconds. | |
38 | .PP | |
39 | .TP 4 | |
40 | .B linelen | |
41 | The length of a screen line when sending output to a file or pipe (default 80). | |
42 | .PP | |
43 | .TP 4 | |
44 | .B username | |
45 | The default regular expression for the users for which active | |
46 | processes will be shown. | |
47 | .PP | |
48 | .TP 4 | |
49 | .B procname | |
50 | The default regular expression for the process names to be shown. | |
51 | .PP | |
52 | .TP 4 | |
53 | .B maxlinecpu | |
54 | The maximum number of active CPU's that will be shown. | |
55 | .PP | |
56 | .TP 4 | |
57 | .B maxlinelvm | |
58 | The maximum number of active logical volumes that will be shown. | |
59 | .PP | |
60 | .TP 4 | |
61 | .B maxlinemdd | |
62 | The maximum number of active multiple devices that will be shown. | |
63 | .PP | |
64 | .TP 4 | |
65 | .B maxlinedisk | |
66 | The maximum number of active disks that will be shown. | |
67 | .PP | |
68 | .TP 4 | |
69 | .B maxlineintf | |
70 | The maximum number of active network interfaces that will be shown. | |
71 | .PP | |
72 | .TP 4 | |
73 | .B cpucritperc | |
74 | The busy percentage considered critical for a processor | |
75 | (see section COLORS in the man-page of the | |
76 | .I atop | |
77 | command). | |
78 | This percentage is used to determine | |
79 | a weighted percentage for line coloring and sorting of active processes. | |
80 | When this value is zero, no line coloring or automatic sorting is performed | |
81 | for this resource. | |
82 | .PP | |
83 | .TP 4 | |
84 | .B dskcritperc | |
85 | The busy percentage considered critical for a disk | |
86 | (see section COLORS in the man-page of the | |
87 | .I atop | |
88 | command). | |
89 | This percentage is used to determine | |
90 | a weighted percentage for line coloring and sorting of active processes. | |
91 | When this value is zero, no line coloring or automatic sorting is performed | |
92 | for this resource. | |
93 | .PP | |
94 | .TP 4 | |
95 | .B netcritperc | |
96 | The busy percentage considered critical for a network interface | |
97 | (see section COLORS in the man-page of the | |
98 | .I atop | |
99 | command). | |
100 | This percentage is used to determine | |
101 | a weighted percentage for line coloring and sorting of active processes. | |
102 | When this value is zero, no line coloring or automatic sorting is performed | |
103 | for this resource. | |
104 | .PP | |
105 | .TP 4 | |
106 | .B memcritperc | |
107 | The percentage considered critical for memory utilization | |
108 | (see section COLORS in the man-page of the | |
109 | .I atop | |
110 | command). | |
111 | This percentage is used to determine | |
112 | a weighted percentage for line coloring and sorting of active processes. | |
113 | When this value is zero, no line coloring or automatic sorting is performed | |
114 | for this resource. | |
115 | .PP | |
116 | .TP 4 | |
117 | .B swpcritperc | |
118 | The occupation percentage considered critical for swap space | |
119 | (see section COLORS in the man-page of the | |
120 | .I atop | |
121 | command). | |
122 | This percentage is used to determine | |
123 | a weighted percentage for line coloring and sorting of active processes. | |
124 | When this value is zero, no line coloring or automatic sorting is performed | |
125 | for this resource. | |
126 | .PP | |
127 | .TP 4 | |
128 | .B swoutcritsec | |
129 | The number of pages swapped out per second considered critical for | |
130 | for memory utilization | |
131 | (see section COLORS in the man-page of the | |
132 | .I atop | |
133 | command). | |
134 | This threshold is used in combination with 'memcritperc' to determine a | |
135 | weighted percentage for line coloring and sorting of active processes. | |
136 | When this value is zero, no line coloring or automatic sorting is performed | |
137 | for this resource. | |
138 | .PP | |
139 | .TP 4 | |
140 | .B almostcrit | |
141 | A percentage of the critical percentage to determine if the resource | |
142 | is almost critical | |
143 | (see section COLORS in the man-page of the | |
144 | .I atop | |
145 | command). | |
146 | When this value is zero, no line coloring for `almost critical' is | |
147 | performed. | |
148 | .PP | |
149 | .TP 4 | |
150 | .B atopsarflags | |
151 | A list of default flags for | |
152 | .B atopsar | |
153 | can be defined here. The flags that are allowed | |
154 | are 'S', 'x', 'C', 'M', 'H', 'a', 'A' and the flags to select | |
155 | one or more specific reports. | |
156 | .PP | |
157 | An example of the | |
158 | .B /etc/atoprc | |
159 | or | |
160 | .B ~/.atoprc | |
161 | file: | |
162 | .TP 8 | |
163 | \ | |
164 | .br | |
165 | flags\ \ \ \ \ \ \ \ \ Aaf | |
166 | .br | |
167 | interval\ \ \ \ \ \ 5 | |
168 | .br | |
169 | username | |
170 | .br | |
171 | procname | |
172 | .br | |
173 | maxlinecpu\ \ \ \ 4 | |
174 | .br | |
175 | maxlinedisk\ \ \ 10 | |
176 | .br | |
177 | maxlineintf\ \ \ 5 | |
178 | .br | |
179 | cpucritperc\ \ \ 80 | |
180 | .br | |
181 | almostcrit\ \ \ \ 90 | |
182 | .br | |
183 | atopsarflags\ \ CMH | |
184 | .br | |
185 | ownprocline\ \ \ PID:50 VGROW:40 RGROW:45 COMMAND-LINE:50 | |
186 | .br | |
187 | ownpagline\ \ \ \ PAGSCAN:3 BLANKBOX:0 PAGSWIN:3 PAGSWOUT:7 | |
188 | .PP | |
189 | The keywords 'ownprocline' and 'ownpagline' are explained in the | |
190 | subsequent section. | |
191 | .SH OWN DEFINITION OF OUTPUT LINE | |
192 | Via the rcfile it is possible to define the layout of the output lines | |
193 | yourself, i.e. you can define the layout of one line with process information | |
194 | with the keyword 'ownprocline' (to be selected with the key 'o' | |
195 | or the flag -o) and you can redefine all lines with system information. | |
196 | .PP | |
197 | The layout of an output-line can be defined as follows | |
198 | (notice that this should be specified as one line in the rcfile): | |
199 | .PP | |
200 | \ \ \ keyword\ \ \ <columnid>:<prio> [<columnid>:<prio> ...] | |
201 | .PP | |
202 | The | |
203 | .B columnid | |
204 | is the symbolic name of a column that should shown at this position | |
205 | in the output line. | |
206 | .br | |
207 | The | |
208 | .B prio | |
209 | is a positive integer value that determines which columns have precedence | |
210 | whenever not all specified columns fit into the current screen-width. | |
211 | The higher value, the higher priority. | |
212 | .br | |
213 | The column-specifications should be separated by a space. The order | |
214 | in which columns have been specified is the order in which they will be | |
215 | shown, with respect to their priority (columns that do not fit, will be | |
216 | dropped dynamically). | |
217 | .PP | |
218 | A special columnid for system lines is 'BLANKBOX'. This indicates | |
219 | that an empty column is required at this position. Also this | |
220 | special columnid is followed by a priority (usually low). | |
221 | .PP | |
222 | The following definition can be specified for process information: | |
223 | .PP | |
224 | .TP 4 | |
225 | .B ownprocline | |
226 | The columnid's are the names of the columns that are shown in the | |
227 | normal output of the process-related lines that are shown by | |
228 | .I atop | |
229 | such as 'PID', 'CMD', 'S', .... | |
230 | The only exception is the special columnid 'SORTITEM' that is used to | |
231 | show one of the columns CPU%/DSK%/MEM%/NET%, depending on the chosen | |
232 | sort-criterium. | |
233 | .br | |
234 | An example of a user-defined process line: | |
235 | .PP | |
236 | .TP 8 | |
237 | \ | |
238 | ownprocline\ \ \ PID:20 PPID:10 SYSCPU:15 USRCPU:15 | |
239 | VGROW:14 VSIZE:12 RGROW:14 RSIZE:12 ST:8 EXC:7 S:11 SORTITEM:18 CMD:20 | |
240 | .PP | |
241 | The following definitions are used internally by | |
242 | .I atop | |
243 | as the default system lines (you can redefine each of them in the | |
244 | rcfile as one line): | |
245 | .PP | |
246 | .TP 4 | |
247 | .B ownsysprcline | |
248 | Redefinition of line labeled with 'PRC': | |
249 | .PP | |
250 | .TP 8 | |
251 | \ | |
252 | ownsysprcline\ \ \ PRCSYS:8 PRCUSER:8 BLANKBOX:0 PRCNPROC:7 PRCNZOMBIE:5 PRCCLONES:4 BLANKBOX:0 PRCNNEXIT:6 | |
253 | .PP | |
254 | .TP 4 | |
255 | .B ownallcpuline | |
256 | Redefinition of line labeled with 'CPU' for total CPU-utilization: | |
257 | .PP | |
258 | .TP 8 | |
259 | \ | |
260 | ownallcpuline\ \ \ CPUSYS:8 CPUUSER:7 CPUIRQ:4 BLANKBOX:0 CPUIDLE:5 CPUWAIT:6 BLANKBOX:0 CPUSTEAL:1 CPUGUEST:3 | |
261 | .PP | |
262 | .TP 4 | |
263 | .B ownonecpuline | |
264 | Redefinition of line labeled with 'CPU' for utilization of one CPU: | |
265 | .PP | |
266 | .TP 8 | |
267 | \ | |
268 | ownonecpuline\ \ \ CPUISYS:8 CPUIUSER:7 CPUIIRQ:4 BLANKBOX:0 CPUIIDLE:5 CPUIWAIT:6 BLANKBOX:0 CPUISTEAL:1 CPUIGUEST:3 | |
269 | .PP | |
270 | .TP 4 | |
271 | .B owncplline | |
272 | Redefinition of line labeled with 'CPL': | |
273 | .PP | |
274 | .TP 8 | |
275 | \ | |
276 | owncplline\ \ \ CPLAVG1:4 CPLAVG5:3 CPLAVG15:2 BLANKBOX:0 CPLCSW:6 CPLINTR:5 BLANKBOX:0 CPLNUMCPU:1 | |
277 | .PP | |
278 | .TP 4 | |
279 | .B ownmemline | |
280 | Redefinition of line labeled with 'MEM': | |
281 | .PP | |
282 | .TP 8 | |
283 | \ | |
284 | ownmemline\ \ \ MEMTOT:2 MEMFREE:5 MEMCACHE:3 MEMDIRTY:1 MEMBUFFER:3 MEMSLAB:3 BLANKBOX:0 BLANKBOX:0 BLANKBOX:0 BLANKBOX:0 | |
285 | .PP | |
286 | .TP 4 | |
287 | .B ownswpline | |
288 | Redefinition of line labeled with 'SWP': | |
289 | .PP | |
290 | .TP 8 | |
291 | \ | |
292 | ownswpline\ \ \ SWPTOT:3 SWPFREE:4 BLANKBOX:0 BLANKBOX:0 BLANKBOX:0 BLANKBOX:0 BLANKBOX:0 BLANKBOX:0 SWPCOMMITTED:5 SWPCOMMITLIM:6 | |
293 | .PP | |
294 | .TP 4 | |
295 | .B ownpagline | |
296 | Redefinition of line labeled with 'PAG': | |
297 | .PP | |
298 | .TP 8 | |
299 | \ | |
300 | ownpagline\ \ \ PAGSCAN:3 PAGSTALL:1 BLANKBOX:0 PAGSWIN:4 PAGSWOUT:3 | |
301 | .PP | |
302 | .TP 4 | |
303 | .B owndskline | |
304 | Redefinition of lines labeled with 'LVM', 'MDD' and 'DSK': | |
305 | .PP | |
306 | .TP 8 | |
307 | \ | |
308 | owndskline\ \ \ DSKNAME:8 DSKBUSY:7 DSKNREAD:6 DSKNWRITE:6 DSKKBPERRD:4 DSKKBPERWR:4 DSKMBPERSECRD:5 DSKMBPERSECWR:5 DSKAVQUEUE:1 DSKAVIO:5 | |
309 | .PP | |
310 | .TP 4 | |
311 | .B ownnettrline | |
312 | Redefinition of line labeled with 'NET' for transport: | |
313 | .PP | |
314 | .TP 8 | |
315 | \ | |
316 | ownnettrline\ \ \ NETTRANSPORT:9 NETTCPI:8 NETTCPO:8 NETUDPI:8 NETUDPO:8 NETTCPACTOPEN:6 NETTCPPASVOPEN:5 NETTCPRETRANS:4 NETTCPINERR:3 NETTCPORESET:20 NETUDPNOPORT:1 NETUDPINERR:3 | |
317 | .PP | |
318 | .TP 4 | |
319 | .B ownnetnetline | |
320 | Redefinition of line labeled with 'NET' for network: | |
321 | .PP | |
322 | .TP 8 | |
323 | \ | |
324 | ownnetnetline\ \ \ NETNETWORK:5 NETIPI:4 NETIPO:4 NETIPFRW:4 NETIPDELIV:4 BLANKBOX:0 BLANKBOX:0 BLANKBOX:0 NETICMPIN:1 NETICMPOUT:1 | |
325 | .PP | |
326 | .TP 4 | |
327 | .B ownnetifline | |
328 | Redefinition of line labeled with 'NET' for interfaces: | |
329 | .PP | |
330 | .TP 8 | |
331 | \ | |
332 | ownnetifline\ \ \ NETNAME:8 NETPCKI:7 NETPCKO:7 NETSPEEDIN:6 NETSPEEDOUT:6 NETCOLLIS:3 NETMULTICASTIN:2 NETRCVERR:5 NETSNDERR:5 NETRCVDROP:4 NETSNDDROP:4 | |
333 | .PP | |
334 | The lines above are shown in the order as shown by | |
335 | .I atop | |
336 | in combination with the | |
337 | .B -f | |
338 | flag (in a very wide window you should be able to see all of the columns). | |
339 | .SH SEE ALSO | |
340 | .B atop(1), | |
341 | .B atopsar(1), | |
342 | .B logrotate(8) | |
343 | .br | |
344 | .B http://www.atoptool.nl | |
345 | .SH AUTHOR | |
346 | Gerlof Langeveld (gerlof.langeveld@atoptool.nl) | |
347 | .br | |
348 | JC van Winkel (jc@ATComputing.nl) |
0 | .TH ATOPSAR 1 "March 2008" "AT Computing" | |
0 | .TH ATOPSAR 1 "April 2010" "AT Computing" | |
1 | 1 | .SH NAME |
2 | 2 | .B atopsar |
3 | 3 | - AT Computing's System Activity Report (atop related) |
50 | 50 | (where YYYYMMDD reflects the date), |
51 | 51 | the required date of the form YYYYMMDD can be specified with the |
52 | 52 | .B -r |
53 | option instead of the filename. | |
53 | option instead of the filename, or | |
54 | the symbolic name 'y' can be used for yesterday's daily logfile | |
55 | (this can be repeated so 'yyyy' indicates the logfile of four days ago). | |
54 | 56 | If the |
55 | 57 | .B -r |
56 | 58 | option is not specified at all, today's daily logfile is used by default. |
182 | 184 | Report about paging- and swapping-activity, and overcommitment. |
183 | 185 | .PP |
184 | 186 | .TP 5 |
187 | .B -l | |
188 | Report about utilization of logical volumes. | |
189 | .PP | |
190 | .TP 5 | |
191 | .B -f | |
192 | Report about utilization of multiple devices. | |
193 | .PP | |
194 | .TP 5 | |
185 | 195 | .B -d |
186 | Report about utilization of disks and disk-partitions. | |
196 | Report about utilization of disks. | |
187 | 197 | .PP |
188 | 198 | .TP 5 |
189 | 199 | .B -i |
292 | 302 | Percentage of cpu time stolen by other virtual machines |
293 | 303 | running on the same hardware. |
294 | 304 | .TP 12 |
305 | .B guest% | |
306 | Percentage of cpu time used by other virtual machines | |
307 | running on the same hardware. | |
308 | .TP 12 | |
295 | 309 | .B wait% |
296 | 310 | Percentage of unused cpu time while |
297 | 311 | at least one of the processes in wait-state awaits completion of disk I/O. |
373 | 387 | .B cached |
374 | 388 | Main memory used at this moment to cache data-blocks (snapshot). |
375 | 389 | .TP 12 |
390 | .B dirty | |
391 | Amount of memory in the page cache that still has to be flushed to disk | |
392 | at this moment (snapshot). | |
393 | .TP 12 | |
376 | 394 | .B slabmem |
377 | 395 | Main memory used at this moment for dynamically allocated memory |
378 | 396 | by the kernel (snapshot). |
408 | 426 | The kernel only verifies whether the committed space exceeds the limit |
409 | 427 | if strict overcommit handling is configured (vm.overcommit_memory is 2). |
410 | 428 | .PP |
411 | The output for the flag | |
412 | .B -d | |
413 | contains the following columns per active physical disk: | |
429 | The output for the flags | |
430 | .B -l | |
431 | (LVM), | |
432 | .B -f | |
433 | (MD), and | |
434 | .B -d | |
435 | (hard disk) contains the following columns per active unit: | |
414 | 436 | .TP 12 |
415 | 437 | .B disk |
416 | Disk name. | |
438 | Name. | |
417 | 439 | .TP 12 |
418 | 440 | .B busy |
419 | Busy-percentage of the physical disk (i.e. the portion of time that the | |
441 | Busy-percentage of the unit (i.e. the portion of time that the | |
420 | 442 | device was busy handling requests). |
421 | 443 | .TP 12 |
422 | 444 | .B read/s |
423 | Number of read-requests issued per second on this disk. | |
445 | Number of read-requests issued per second on this unit. | |
424 | 446 | .TP 12 |
425 | 447 | .B KB/read |
426 | Average number of Kbytes transferred per read-request for this disk. | |
427 | .TP 12 | |
428 | .B write/s | |
429 | Number of write-requests issued per second on this disk. | |
448 | Average number of Kbytes transferred per read-request for this unit. | |
449 | .TP 12 | |
450 | .B writ/s | |
451 | Number of write-requests issued per second on this unit. | |
430 | 452 | .TP 12 |
431 | 453 | .B KB/writ |
432 | Average number of Kbytes transferred per write-request for this disk. | |
454 | Average number of Kbytes transferred per write-request for this unit. | |
433 | 455 | .TP 12 |
434 | 456 | .B avque |
435 | Average number of disk-requests outstanding in the queue during the time | |
436 | that the disk is busy. | |
457 | Average number of requests outstanding in the queue during the time | |
458 | that the unit is busy. | |
437 | 459 | .TP 12 |
438 | 460 | .B avserv |
439 | Average number of milliseconds needed by a request on this physical disk | |
461 | Average number of milliseconds needed by a request on this unit | |
440 | 462 | (seek, latency and data-transfer). |
441 | 463 | .PP |
442 | 464 | The output for the flag |
973 | 995 | .TP 12 |
974 | 996 | .B \ atopsar |
975 | 997 | .PP |
976 | To see the memory occupation for November 24, 2008 between 10:00 and 12:30 | |
998 | To see the memory occupation for January 2, 2010 between 10:00 and 12:30 | |
977 | 999 | (supposed that |
978 | 1000 | .B atop |
979 | 1001 | has been logging daily in the background): |
980 | 1002 | .PP |
981 | 1003 | .TP 12 |
982 | .B \ atopsar -m -r /var/log/atop_20081124 -b 10:00 -e 12:30 | |
1004 | .B \ atopsar -m -r /var/log/atop_20100102 -b 10:00 -e 12:30 | |
1005 | .br | |
1006 | \ | |
983 | 1007 | .br |
984 | 1008 | or |
985 | 1009 | .TP 12 |
986 | .B \ atopsar -m -r 20081124 -b 10:00 -e 12:30 | |
1010 | .B \ atopsar -m -r 20100102 -b 10:00 -e 12:30 | |
1011 | .br | |
1012 | \ | |
1013 | .br | |
1014 | or, suppose it is January 5, 2010 at this moment | |
1015 | .TP 12 | |
1016 | .B \ atopsar -m -r yyy -b 10:00 -e 12:30 | |
987 | 1017 | .PP |
988 | 1018 | Write a logfile with |
989 | 1019 | .B atop |
1009 | 1039 | .TP 12 |
1010 | 1040 | .B \ atopsar -AM | grep '[_*+]$' |
1011 | 1041 | .PP |
1012 | .SH CONFIGURATION FILE | |
1013 | .PP | |
1014 | The default values used by | |
1015 | .B atop | |
1016 | and | |
1017 | .B atopsar | |
1018 | can be overruled by a personal configuration file. | |
1019 | This file, called | |
1020 | .B ~/.atoprc | |
1021 | contains a keyword-value pair on every line (blank lines | |
1022 | and lines starting with a #-sign are skipped). | |
1023 | The keywords related to the definition of critical percentages | |
1024 | also apply to | |
1025 | .B atopsar | |
1026 | (see description in the | |
1027 | .B atop | |
1028 | man-page). | |
1029 | .br | |
1030 | The following keyword can be specified for | |
1031 | .B atopsar | |
1032 | specifically: | |
1033 | .PP | |
1034 | .TP 9 | |
1035 | .B atopsarflags | |
1036 | A list of default flags for | |
1037 | .B atopsar | |
1038 | can be defined here. The flags that are allowed | |
1039 | are 'S', 'x', 'C', 'M', 'H', 'a', 'A' and the flags to select | |
1040 | one or more specific reports. | |
1041 | .PP | |
1042 | 1042 | .SH FILES |
1043 | .PP | |
1044 | .TP 5 | |
1045 | .B /etc/atoprc | |
1046 | Configuration file containing system-wide default values (mainly flags). | |
1047 | See related man-page. | |
1043 | 1048 | .PP |
1044 | 1049 | .TP 5 |
1045 | 1050 | .B ~/.atoprc |
1046 | 1051 | Configuration file containing personal default values (mainly flags). |
1052 | See related man-page. | |
1047 | 1053 | .PP |
1048 | 1054 | .TP 5 |
1049 | 1055 | .BI /var/log/atop/atop_ YYYYMMDD |
1051 | 1057 | .I YYYYMMDD |
1052 | 1058 | are digits representing the date. |
1053 | 1059 | .SH SEE ALSO |
1054 | .B atop(1) | |
1060 | .B atop(1), | |
1061 | .B atoprc(5), | |
1055 | 1062 | .br |
1056 | .B http://www.ATComputing.nl/Tools/atop | |
1063 | .B http://www.atoptool.nl | |
1057 | 1064 | .SH AUTHOR |
1058 | Gerlof Langeveld, AT Computing (gerlof@ATComputing.nl) | |
1065 | Gerlof Langeveld (gerlof.langeveld@atoptool.nl) |
4 | 4 | ** the system on system-level as well as process-level. |
5 | 5 | ** |
6 | 6 | ** ========================================================================== |
7 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
8 | ** E-mail: gerlof@ATComputing.nl | |
7 | ** Author: Gerlof Langeveld | |
8 | ** E-mail: gerlof.langeveld@atoptool.nl | |
9 | 9 | ** Date: February 2007 |
10 | 10 | ** -------------------------------------------------------------------------- |
11 | ** Copyright (C) 2007 Gerlof Langeveld | |
11 | ** Copyright (C) 2007-2010 Gerlof Langeveld | |
12 | 12 | ** |
13 | 13 | ** This program is free software; you can redistribute it and/or modify it |
14 | 14 | ** under the terms of the GNU General Public License as published by the |
25 | 25 | ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
26 | 26 | ** -------------------------------------------------------------------------- |
27 | 27 | ** |
28 | ** $Id: parseable.c,v 1.7 2008/03/06 09:08:29 gerlof Exp $ | |
28 | ** $Id: parseable.c,v 1.13 2010/10/23 14:02:19 gerlof Exp $ | |
29 | 29 | ** $Log: parseable.c,v $ |
30 | ** Revision 1.13 2010/10/23 14:02:19 gerlof | |
31 | ** Show counters for total number of running and sleep (S and D) threads. | |
32 | ** | |
33 | ** Revision 1.12 2010/05/18 19:20:55 gerlof | |
34 | ** Introduce CPU frequency and scaling (JC van Winkel). | |
35 | ** | |
36 | ** Revision 1.11 2010/04/23 12:19:35 gerlof | |
37 | ** Modified mail-address in header. | |
38 | ** | |
39 | ** Revision 1.10 2010/03/04 10:52:21 gerlof | |
40 | ** Support I/O-statistics on logical volumes and MD devices. | |
41 | ** | |
42 | ** Revision 1.9 2010/01/08 14:46:42 gerlof | |
43 | ** Added label RESET in case of a sample with values since boot. | |
44 | ** | |
45 | ** Revision 1.8 2009/12/19 22:32:14 gerlof | |
46 | ** Add new counters to parseable output. | |
47 | ** | |
30 | 48 | ** Revision 1.7 2008/03/06 09:08:29 gerlof |
31 | 49 | ** Bug-solution regarding parseable output of PPID. |
32 | 50 | ** |
69 | 87 | void print_MEM(); |
70 | 88 | void print_SWP(); |
71 | 89 | void print_PAG(); |
90 | void print_LVM(); | |
91 | void print_MDD(); | |
72 | 92 | void print_DSK(); |
73 | 93 | void print_NET(); |
74 | 94 | |
95 | 115 | { "MEM", 0, print_MEM }, |
96 | 116 | { "SWP", 0, print_SWP }, |
97 | 117 | { "PAG", 0, print_PAG }, |
118 | { "LVM", 0, print_LVM }, | |
119 | { "MDD", 0, print_MDD }, | |
98 | 120 | { "DSK", 0, print_DSK }, |
99 | 121 | { "NET", 0, print_NET }, |
100 | 122 | |
186 | 208 | char |
187 | 209 | parseout(time_t curtime, int numsecs, |
188 | 210 | struct sstat *ss, struct pstat *ps, |
189 | int nlist, int npresent, int nzombie, | |
211 | int nlist, int npresent, int trun, int tslpi, int tslpu, int nzombie, | |
190 | 212 | int nexit, char flag) |
191 | 213 | { |
192 | 214 | register int i; |
193 | 215 | char datestr[32], timestr[32], header[256]; |
216 | ||
217 | /* | |
218 | ** print reset-label for sample-values since boot | |
219 | */ | |
220 | if (flag&RRBOOT) | |
221 | printf("RESET\n"); | |
194 | 222 | |
195 | 223 | /* |
196 | 224 | ** search all labels which are selected before |
229 | 257 | /* |
230 | 258 | ** print functions for system-level statistics |
231 | 259 | */ |
260 | void | |
261 | calc_freqscale(count_t maxfreq, count_t cnt, count_t ticks, | |
262 | count_t *freq, int* freqperc) | |
263 | { | |
264 | // if ticks != 0, do full calcs | |
265 | if (ticks) | |
266 | { | |
267 | *freq=cnt/ticks; | |
268 | *freqperc=100* *freq / maxfreq; | |
269 | } | |
270 | else if (maxfreq) // max frequency is known so % can be calculated | |
271 | { | |
272 | *freq=cnt; | |
273 | *freqperc=100*cnt/maxfreq; | |
274 | } | |
275 | else if (cnt) // no max known, set % to 100 | |
276 | { | |
277 | *freq=cnt; | |
278 | *freqperc=100; | |
279 | } | |
280 | else // nothing is known: set freq to 0, % to 100 | |
281 | { | |
282 | *freq=0; | |
283 | *freqperc=100; | |
284 | } | |
285 | } | |
286 | ||
287 | ||
232 | 288 | void |
233 | 289 | print_CPU(char *hp, struct sstat *ss, struct pstat *ps, int nact) |
234 | 290 | { |
235 | printf("%s %u %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", | |
291 | count_t maxfreq=0; | |
292 | count_t cnt=0; | |
293 | count_t ticks=0; | |
294 | count_t freq; | |
295 | int freqperc; | |
296 | int i; | |
297 | ||
298 | // calculate average clock frequency | |
299 | for (i=0; i < ss->cpu.nrcpu; i++) | |
300 | { | |
301 | cnt += ss->cpu.cpu[i].freqcnt.cnt; | |
302 | ticks += ss->cpu.cpu[i].freqcnt.ticks; | |
303 | } | |
304 | maxfreq = ss->cpu.cpu[0].freqcnt.maxfreq; | |
305 | calc_freqscale(maxfreq, cnt, ticks, &freq, &freqperc); | |
306 | ||
307 | printf("%s %u %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %d\n", | |
236 | 308 | hp, |
237 | 309 | hertz, |
238 | 310 | ss->cpu.nrcpu, |
243 | 315 | ss->cpu.all.wtime, |
244 | 316 | ss->cpu.all.Itime, |
245 | 317 | ss->cpu.all.Stime, |
246 | ss->cpu.all.steal); | |
318 | ss->cpu.all.steal, | |
319 | ss->cpu.all.guest, | |
320 | freq, | |
321 | freqperc | |
322 | ); | |
247 | 323 | } |
248 | 324 | |
249 | 325 | void |
250 | 326 | print_cpu(char *hp, struct sstat *ss, struct pstat *ps, int nact) |
251 | 327 | { |
252 | 328 | register int i; |
329 | count_t maxfreq=0; | |
330 | count_t cnt=0; | |
331 | count_t ticks=0; | |
332 | count_t freq; | |
333 | int freqperc; | |
253 | 334 | |
254 | 335 | for (i=0; i < ss->cpu.nrcpu; i++) |
255 | 336 | { |
256 | printf("%s %u %d %lld %lld %lld %lld %lld %lld %lld %lld\n", | |
337 | cnt = ss->cpu.cpu[i].freqcnt.cnt; | |
338 | ticks = ss->cpu.cpu[i].freqcnt.ticks; | |
339 | maxfreq= ss->cpu.cpu[0].freqcnt.maxfreq; | |
340 | ||
341 | calc_freqscale(maxfreq, cnt, ticks, &freq, &freqperc); | |
342 | ||
343 | printf("%s %u %d %lld %lld %lld " | |
344 | "%lld %lld %lld %lld %lld %lld %lld %d\n", | |
257 | 345 | hp, hertz, i, |
258 | 346 | ss->cpu.cpu[i].stime, |
259 | 347 | ss->cpu.cpu[i].utime, |
262 | 350 | ss->cpu.cpu[i].wtime, |
263 | 351 | ss->cpu.cpu[i].Itime, |
264 | 352 | ss->cpu.cpu[i].Stime, |
265 | ss->cpu.cpu[i].steal); | |
353 | ss->cpu.cpu[i].steal, | |
354 | ss->cpu.cpu[i].guest, | |
355 | freq, | |
356 | freqperc); | |
266 | 357 | } |
267 | 358 | } |
268 | 359 | |
282 | 373 | void |
283 | 374 | print_MEM(char *hp, struct sstat *ss, struct pstat *ps, int nact) |
284 | 375 | { |
285 | printf( "%s %u %lld %lld %lld %lld %lld\n", | |
376 | printf( "%s %u %lld %lld %lld %lld %lld %lld\n", | |
286 | 377 | hp, |
287 | 378 | pagesize, |
288 | 379 | ss->mem.physmem, |
289 | 380 | ss->mem.freemem, |
290 | 381 | ss->mem.cachemem, |
291 | 382 | ss->mem.buffermem, |
292 | ss->mem.slabmem); | |
383 | ss->mem.slabmem, | |
384 | ss->mem.cachedrt); | |
293 | 385 | } |
294 | 386 | |
295 | 387 | void |
319 | 411 | } |
320 | 412 | |
321 | 413 | void |
414 | print_LVM(char *hp, struct sstat *ss, struct pstat *ps, int nact) | |
415 | { | |
416 | register int i; | |
417 | ||
418 | for (i=0; ss->dsk.lvm[i].name[0]; i++) | |
419 | { | |
420 | printf( "%s %s %lld %lld %lld %lld %lld\n", | |
421 | hp, | |
422 | ss->dsk.lvm[i].name, | |
423 | ss->dsk.lvm[i].io_ms, | |
424 | ss->dsk.lvm[i].nread, | |
425 | ss->dsk.lvm[i].nrsect, | |
426 | ss->dsk.lvm[i].nwrite, | |
427 | ss->dsk.lvm[i].nwsect); | |
428 | } | |
429 | } | |
430 | ||
431 | void | |
432 | print_MDD(char *hp, struct sstat *ss, struct pstat *ps, int nact) | |
433 | { | |
434 | register int i; | |
435 | ||
436 | for (i=0; ss->dsk.mdd[i].name[0]; i++) | |
437 | { | |
438 | printf( "%s %s %lld %lld %lld %lld %lld\n", | |
439 | hp, | |
440 | ss->dsk.mdd[i].name, | |
441 | ss->dsk.mdd[i].io_ms, | |
442 | ss->dsk.mdd[i].nread, | |
443 | ss->dsk.mdd[i].nrsect, | |
444 | ss->dsk.mdd[i].nwrite, | |
445 | ss->dsk.mdd[i].nwsect); | |
446 | } | |
447 | } | |
448 | ||
449 | void | |
322 | 450 | print_DSK(char *hp, struct sstat *ss, struct pstat *ps, int nact) |
323 | 451 | { |
324 | 452 | register int i; |
325 | 453 | |
326 | for (i=0; ss->xdsk.xdsk[i].name[0]; i++) | |
454 | for (i=0; ss->dsk.dsk[i].name[0]; i++) | |
327 | 455 | { |
328 | 456 | printf( "%s %s %lld %lld %lld %lld %lld\n", |
329 | 457 | hp, |
330 | ss->xdsk.xdsk[i].name, | |
331 | ss->xdsk.xdsk[i].io_ms, | |
332 | ss->xdsk.xdsk[i].nread, | |
333 | ss->xdsk.xdsk[i].nrsect, | |
334 | ss->xdsk.xdsk[i].nwrite, | |
335 | ss->xdsk.xdsk[i].nwsect); | |
458 | ss->dsk.dsk[i].name, | |
459 | ss->dsk.dsk[i].io_ms, | |
460 | ss->dsk.dsk[i].nread, | |
461 | ss->dsk.dsk[i].nrsect, | |
462 | ss->dsk.dsk[i].nwrite, | |
463 | ss->dsk.dsk[i].nwsect); | |
336 | 464 | } |
337 | 465 | } |
338 | 466 | |
383 | 511 | |
384 | 512 | for (i=0; i < nact; i++, ps++) |
385 | 513 | { |
386 | printf("%s %d (%s) %c %d %d %d %d %d %ld (%s) %d %d %d %d\n", | |
514 | printf("%s %d (%s) %c %d %d %d %d %d %ld (%s) %d %d %d %d " | |
515 | "%d %d %d %d %d %d %ld\n", | |
387 | 516 | hp, |
388 | 517 | ps->gen.pid, |
389 | 518 | ps->gen.name, |
398 | 527 | ps->gen.ppid, |
399 | 528 | ps->gen.nthrrun, |
400 | 529 | ps->gen.nthrslpi, |
401 | ps->gen.nthrslpu); | |
530 | ps->gen.nthrslpu, | |
531 | ps->gen.euid, | |
532 | ps->gen.egid, | |
533 | ps->gen.suid, | |
534 | ps->gen.sgid, | |
535 | ps->gen.fsuid, | |
536 | ps->gen.fsgid, | |
537 | ps->gen.elaps); | |
402 | 538 | } |
403 | 539 | } |
404 | 540 |
0 | 0 | int parsedef(char *); |
1 | 1 | char parseout(time_t, int, struct sstat *, struct pstat *, |
2 | int, int, int, int, char); | |
2 | int, int, int, int, int, int, int, char); |
7 | 7 | ** of every running process from kernel-space and extract the required |
8 | 8 | ** activity-counters. |
9 | 9 | ** ========================================================================== |
10 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
11 | ** E-mail: gerlof@ATComputing.nl | |
10 | ** Author: Gerlof Langeveld | |
11 | ** E-mail: gerlof.langeveld@atoptool.nl | |
12 | 12 | ** Date: November 1996 |
13 | 13 | ** LINUX-port: June 2000 |
14 | 14 | ** -------------------------------------------------------------------------- |
15 | ** Copyright (C) 2000-2005 Gerlof Langeveld | |
15 | ** Copyright (C) 2000-2010 Gerlof Langeveld | |
16 | 16 | ** |
17 | 17 | ** This program is free software; you can redistribute it and/or modify it |
18 | 18 | ** under the terms of the GNU General Public License as published by the |
30 | 30 | ** -------------------------------------------------------------------------- |
31 | 31 | ** |
32 | 32 | ** $Log: photoproc.c,v $ |
33 | ** Revision 1.33 2010/04/23 12:19:35 gerlof | |
34 | ** Modified mail-address in header. | |
35 | ** | |
36 | ** Revision 1.32 2009/11/27 13:44:00 gerlof | |
37 | ** euid, suid, fsuid, egid, sgid and fsgid also registered. | |
38 | ** | |
33 | 39 | ** Revision 1.31 2008/03/06 08:38:14 gerlof |
34 | 40 | ** Register/show ppid of a process. |
35 | 41 | ** |
129 | 135 | ** |
130 | 136 | */ |
131 | 137 | |
132 | static const char rcsid[] = "$Id: photoproc.c,v 1.31 2008/03/06 08:38:14 gerlof Exp $"; | |
138 | static const char rcsid[] = "$Id: photoproc.c,v 1.33 2010/04/23 12:19:35 gerlof Exp $"; | |
133 | 139 | |
134 | 140 | #include <sys/types.h> |
135 | 141 | #include <sys/param.h> |
294 | 300 | int nr; |
295 | 301 | char line[4096], *cmdhead, *cmdtail; |
296 | 302 | char command[64], state; |
297 | int pid, ppid, ruid, rgid, prio, policy, rtprio, nice, | |
303 | int pid, ppid, prio, policy, rtprio, nice, | |
304 | ruid, euid, suid, fsuid, rgid, egid, sgid, fsgid, | |
298 | 305 | curcpu, nthreads, sleepavg; |
299 | 306 | count_t utime, stime, starttime; |
300 | 307 | count_t minflt, majflt, size, rss, nswap, |
369 | 376 | |
370 | 377 | if (memcmp(line, "Uid:", 4)==0) |
371 | 378 | { |
372 | sscanf(line, "Uid: %d", &ruid); | |
379 | sscanf(line, "Uid: %d %d %d %d", | |
380 | &ruid, &euid, &suid, &fsuid); | |
373 | 381 | continue; |
374 | 382 | } |
375 | 383 | |
376 | 384 | if (memcmp(line, "Gid:", 4)==0) |
377 | 385 | { |
378 | sscanf(line, "Gid: %d", &rgid); | |
386 | sscanf(line, "Gid: %d %d %d %d", | |
387 | &rgid, &egid, &sgid, &fsgid); | |
379 | 388 | continue; |
380 | 389 | } |
381 | 390 | |
430 | 439 | ** store required info in process-structure |
431 | 440 | */ |
432 | 441 | curproc->gen.pid = pid; |
442 | curproc->gen.ppid = ppid; | |
433 | 443 | curproc->gen.ruid = ruid; |
444 | curproc->gen.euid = euid; | |
445 | curproc->gen.suid = suid; | |
446 | curproc->gen.fsuid = fsuid; | |
434 | 447 | curproc->gen.rgid = rgid; |
435 | curproc->gen.ppid = ppid; | |
448 | curproc->gen.egid = egid; | |
449 | curproc->gen.sgid = sgid; | |
450 | curproc->gen.fsgid = fsgid; | |
436 | 451 | curproc->gen.nthr = nthreads; |
437 | 452 | curproc->gen.state = state; |
438 | 453 |
6 | 6 | ** Include-file describing process-level counters maintained and functions |
7 | 7 | ** to access the process-database. |
8 | 8 | ** ================================================================ |
9 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: gerlof@ATComputing.nl | |
9 | ** Author: Gerlof Langeveld | |
10 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | 11 | ** Date: November 1996 |
12 | 12 | ** LINUX-port: June 2000 |
13 | 13 | ** |
23 | 23 | */ |
24 | 24 | |
25 | 25 | #define PNAMLEN 15 |
26 | #define CMDLEN 68 | |
26 | #define CMDLEN 150 | |
27 | 27 | |
28 | 28 | /* |
29 | 29 | ** structure containing only relevant process-info extracted |
33 | 33 | /* GENERAL PROCESS INFO */ |
34 | 34 | struct gen { |
35 | 35 | int pid; /* process identification */ |
36 | int ruid; /* real user identification */ | |
37 | int rgid; /* real group identification */ | |
38 | 36 | int ppid; /* parent process identification*/ |
37 | int ruid; /* real user identification */ | |
38 | int euid; /* eff. user identification */ | |
39 | int suid; /* saved user identification */ | |
40 | int fsuid; /* fs user identification */ | |
41 | int rgid; /* real group identification */ | |
42 | int egid; /* eff. group identification */ | |
43 | int sgid; /* saved group identification */ | |
44 | int fsgid; /* fs group identification */ | |
39 | 45 | int nthr; /* number of threads in tgroup */ |
40 | 46 | char name[PNAMLEN+1];/* process name string */ |
41 | 47 | char state; /* process state ('E' = exited) */ |
42 | 48 | int excode; /* process exit status */ |
43 | 49 | time_t btime; /* process start time (epoch) */ |
50 | time_t elaps; /* process elaps time (hertz) */ | |
44 | 51 | char cmdline[CMDLEN+1];/* command-line string */ |
45 | 52 | int nthrslpi; /* # threads in state 'S' */ |
46 | 53 | int nthrslpu; /* # threads in state 'D' */ |
124 | 131 | ** prototypes for raw process-statistics functions |
125 | 132 | */ |
126 | 133 | int deviatproc(struct pstat *, int, struct pstat *, int, int, |
127 | struct pstat *, int *); | |
134 | struct pstat *, struct sstat *, | |
135 | int *, int *, int *, int *); | |
128 | 136 | int photoproc(struct pstat *, int); |
129 | 137 | unsigned int countprocs(void); |
6 | 6 | ** This source-file contains functions to read all relevant system-level |
7 | 7 | ** figures. |
8 | 8 | ** ========================================================================== |
9 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: gerlof@ATComputing.nl | |
9 | ** Author: Gerlof Langeveld | |
10 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | 11 | ** Date: November 1996 |
12 | 12 | ** LINUX-port: June 2000 |
13 | 13 | ** -------------------------------------------------------------------------- |
14 | ** Copyright (C) 2000-2005 Gerlof Langeveld | |
14 | ** Copyright (C) 2000-2010 Gerlof Langeveld | |
15 | 15 | ** |
16 | 16 | ** This program is free software; you can redistribute it and/or modify it |
17 | 17 | ** under the terms of the GNU General Public License as published by the |
29 | 29 | ** -------------------------------------------------------------------------- |
30 | 30 | ** |
31 | 31 | ** $Log: photosyst.c,v $ |
32 | ** Revision 1.37 2010/11/14 06:42:18 gerlof | |
33 | ** After opening /proc/cpuinfo, the file descriptor was not closed any more. | |
34 | ** | |
35 | ** Revision 1.36 2010/10/23 14:09:50 gerlof | |
36 | ** Add support for mmcblk disks (MMC/SD cardreaders) | |
37 | ** Credits: Anssi Hannula | |
38 | ** | |
39 | ** Revision 1.35 2010/05/18 19:20:30 gerlof | |
40 | ** Introduce CPU frequency and scaling (JC van Winkel). | |
41 | ** | |
42 | ** Revision 1.34 2010/04/23 12:19:35 gerlof | |
43 | ** Modified mail-address in header. | |
44 | ** | |
45 | ** Revision 1.33 2010/03/04 10:58:05 gerlof | |
46 | ** Added recognition of device-type /dev/fio... | |
47 | ** | |
48 | ** Revision 1.32 2010/03/04 10:52:47 gerlof | |
49 | ** Support I/O-statistics on logical volumes and MD devices. | |
50 | ** | |
51 | ** Revision 1.31 2009/12/17 11:59:16 gerlof | |
52 | ** Gather and display new counters: dirty cache and guest cpu usage. | |
53 | ** | |
32 | 54 | ** Revision 1.30 2008/02/25 13:47:00 gerlof |
33 | 55 | ** Experimental code for HTTP statistics. |
34 | 56 | ** |
123 | 145 | ** |
124 | 146 | */ |
125 | 147 | |
126 | static const char rcsid[] = "$Id: photosyst.c,v 1.30 2008/02/25 13:47:00 gerlof Exp $"; | |
148 | static const char rcsid[] = "$Id: photosyst.c,v 1.37 2010/11/14 06:42:18 gerlof Exp $"; | |
127 | 149 | |
128 | 150 | #include <sys/types.h> |
129 | 151 | #include <stdio.h> |
131 | 153 | #include <unistd.h> |
132 | 154 | #include <stdlib.h> |
133 | 155 | #include <regex.h> |
156 | #include <sys/stat.h> | |
134 | 157 | #include <sys/times.h> |
135 | 158 | #include <sys/wait.h> |
136 | 159 | #include <time.h> |
137 | 160 | #include <signal.h> |
138 | 161 | #include <string.h> |
162 | #include <dirent.h> | |
139 | 163 | |
140 | 164 | #include <sys/socket.h> |
141 | 165 | #include <netinet/in.h> |
146 | 170 | |
147 | 171 | #define MAXCNT 64 |
148 | 172 | |
149 | static int isrealdisk(char *, char *, int); | |
173 | /* return value of isdisk() */ | |
174 | #define NONTYPE 0 | |
175 | #define DSKTYPE 1 | |
176 | #define MDDTYPE 2 | |
177 | #define LVMTYPE 3 | |
178 | ||
179 | static int isdisk(unsigned int, unsigned int, | |
180 | char *, struct perdsk *, int); | |
150 | 181 | |
151 | 182 | static struct ipv6_stats ipv6_tmp; |
152 | 183 | static struct icmpv6_stats icmpv6_tmp; |
234 | 265 | FILE *fp; |
235 | 266 | char linebuf[1024], nam[64], origdir[1024]; |
236 | 267 | static char part_stats = 1; /* per-partition statistics ? */ |
268 | unsigned int major, minor; | |
237 | 269 | #if HTTPSTATS |
238 | 270 | static int wwwvalid = 1; |
239 | 271 | #endif |
278 | 310 | |
279 | 311 | if (nr > 8) /* steal support */ |
280 | 312 | si->cpu.all.steal = cnts[7]; |
313 | ||
314 | if (nr > 9) /* guest support */ | |
315 | si->cpu.all.guest = cnts[8]; | |
281 | 316 | } |
282 | 317 | continue; |
283 | 318 | } |
300 | 335 | |
301 | 336 | if (nr > 8) /* steal support */ |
302 | 337 | si->cpu.cpu[i].steal = cnts[7]; |
338 | ||
339 | if (nr > 9) /* guest support */ | |
340 | si->cpu.cpu[i].guest = cnts[8]; | |
303 | 341 | } |
304 | 342 | |
305 | 343 | si->cpu.nrcpu++; |
357 | 395 | |
358 | 396 | fclose(fp); |
359 | 397 | } |
398 | ||
399 | /* | |
400 | ** gather frequency scaling info. | |
401 | ** sources (in order of preference): | |
402 | ** /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state | |
403 | ** or | |
404 | ** /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq | |
405 | ** /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq | |
406 | ** | |
407 | ** store them in binary form | |
408 | */ | |
409 | static char fn[80]; | |
410 | int didone=0; | |
411 | ||
412 | for (i = 0; i < si->cpu.nrcpu; ++i) | |
413 | { | |
414 | long long f=0; | |
415 | ||
416 | sprintf(fn, | |
417 | "/sys/devices/system/cpu/cpu%d/cpufreq/stats/time_in_state", | |
418 | i); | |
419 | ||
420 | if ((fp=fopen(fn, "r")) != 0) | |
421 | { | |
422 | long long hits=0; | |
423 | long long maxfreq=0; | |
424 | long long cnt=0; | |
425 | long long sum=0; | |
426 | ||
427 | while (fscanf(fp, "%lld %lld", &f, &cnt) == 2) | |
428 | { | |
429 | f /= 1000; | |
430 | sum += (f*cnt); | |
431 | hits += cnt; | |
432 | ||
433 | if (f > maxfreq) | |
434 | maxfreq=f; | |
435 | } | |
436 | ||
437 | si->cpu.cpu[i].freqcnt.maxfreq = maxfreq; | |
438 | si->cpu.cpu[i].freqcnt.cnt = sum; | |
439 | si->cpu.cpu[i].freqcnt.ticks = hits; | |
440 | ||
441 | fclose(fp); | |
442 | didone=1; | |
443 | } | |
444 | else | |
445 | { // governor statistics not available | |
446 | sprintf(fn, | |
447 | "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", | |
448 | i); | |
449 | ||
450 | if ((fp=fopen(fn, "r")) != 0) | |
451 | { | |
452 | if (fscanf(fp, "%lld", &f) == 1) | |
453 | { | |
454 | // convert KHz to MHz | |
455 | si->cpu.cpu[i].freqcnt.maxfreq =f/1000; | |
456 | } | |
457 | ||
458 | didone=1; | |
459 | fclose(fp); | |
460 | } | |
461 | else | |
462 | { | |
463 | si->cpu.cpu[i].freqcnt.maxfreq=0; | |
464 | } | |
465 | ||
466 | sprintf(fn, | |
467 | "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", | |
468 | i); | |
469 | ||
470 | if ((fp=fopen(fn, "r")) != 0) | |
471 | { | |
472 | if (fscanf(fp, "%lld", &f) == 1) | |
473 | { | |
474 | // convert KHz to MHz | |
475 | si->cpu.cpu[i].freqcnt.cnt = f/1000; | |
476 | si->cpu.cpu[i].freqcnt.ticks = 0; | |
477 | } | |
478 | ||
479 | fclose(fp); | |
480 | didone=1; | |
481 | } | |
482 | else | |
483 | { | |
484 | si->cpu.cpu[i].freqcnt.maxfreq = 0; | |
485 | si->cpu.cpu[i].freqcnt.cnt = 0; | |
486 | si->cpu.cpu[i].freqcnt.ticks = 0; | |
487 | break; // use cpuinfo | |
488 | } | |
489 | } | |
490 | } // for all CPUs | |
491 | ||
492 | if (!didone) // did not get processor freq statistics. | |
493 | // use /proc/cpuinfo | |
494 | { | |
495 | if ( (fp = fopen("cpuinfo", "r")) != NULL) | |
496 | { | |
497 | // get information from the lines | |
498 | // processor\t: 0 | |
499 | // cpu MHz\t\t: 800.000 | |
500 | ||
501 | int cpuno=-1; | |
502 | ||
503 | while ( fgets(linebuf, sizeof(linebuf), fp) != NULL) | |
504 | { | |
505 | if (memcmp(linebuf, "processor", 9)== EQ) | |
506 | sscanf(linebuf, "%*s %*s %d", &cpuno); | |
507 | ||
508 | if (memcmp(linebuf, "cpu MHz", 7) == EQ) | |
509 | { | |
510 | if (cpuno >= 0 && cpuno < si->cpu.nrcpu) | |
511 | { | |
512 | sscanf(linebuf, | |
513 | "%*s %*s %*s %lld", | |
514 | &(si->cpu.cpu[cpuno].freqcnt.cnt)); | |
515 | } | |
516 | } | |
517 | } | |
518 | ||
519 | fclose(fp); | |
520 | } | |
521 | ||
522 | } | |
360 | 523 | |
361 | 524 | /* |
362 | 525 | ** gather virtual memory statistics from the file /proc/vmstat and |
428 | 591 | |
429 | 592 | if ( (fp = fopen("meminfo", "r")) != NULL) |
430 | 593 | { |
431 | int nrfields = 9; /* number of fields to be filled */ | |
594 | int nrfields = 10; /* number of fields to be filled */ | |
432 | 595 | |
433 | 596 | while ( fgets(linebuf, sizeof(linebuf), fp) != NULL && |
434 | 597 | nrfields > 0) |
465 | 628 | cnts[0]*1024/pagesize; |
466 | 629 | nrfields--; |
467 | 630 | } |
631 | } | |
632 | else if (strcmp("Dirty:", nam) == EQ) | |
633 | { | |
634 | si->mem.cachedrt = | |
635 | cnts[0]*1024/pagesize; | |
636 | nrfields--; | |
468 | 637 | } |
469 | 638 | else if (strcmp("MemTotal:", nam) == EQ) |
470 | 639 | { |
711 | 880 | "%*d %*d %*d %255s %lld %*d %lld %*d " |
712 | 881 | "%lld %*d %lld %*d %*d %lld %lld", |
713 | 882 | diskname, |
714 | &(si->xdsk.xdsk[i].nread), | |
715 | &(si->xdsk.xdsk[i].nrsect), | |
716 | &(si->xdsk.xdsk[i].nwrite), | |
717 | &(si->xdsk.xdsk[i].nwsect), | |
718 | &(si->xdsk.xdsk[i].io_ms), | |
719 | &(si->xdsk.xdsk[i].avque) ); | |
883 | &(si->dsk.dsk[i].nread), | |
884 | &(si->dsk.dsk[i].nrsect), | |
885 | &(si->dsk.dsk[i].nwrite), | |
886 | &(si->dsk.dsk[i].nwsect), | |
887 | &(si->dsk.dsk[i].io_ms), | |
888 | &(si->dsk.dsk[i].avque) ); | |
720 | 889 | |
721 | 890 | /* |
722 | 891 | ** check if this line concerns the entire disk |
725 | 894 | */ |
726 | 895 | if (nr == 7) /* full stats-line ? */ |
727 | 896 | { |
728 | if ( !isrealdisk(diskname, | |
729 | si->xdsk.xdsk[i].name, | |
730 | MAXDKNAM) ) | |
897 | if ( isdisk(0, 0, diskname, | |
898 | &(si->dsk.dsk[i]), | |
899 | MAXDKNAM) != DSKTYPE) | |
731 | 900 | continue; |
732 | 901 | |
733 | 902 | if (++i >= MAXDSK-1) |
735 | 904 | } |
736 | 905 | } |
737 | 906 | |
738 | si->xdsk.xdsk[i].name[0] = '\0'; /* set terminator for table */ | |
739 | si->xdsk.nrxdsk = i; | |
907 | si->dsk.dsk[i].name[0] = '\0'; /* set terminator for table */ | |
908 | si->dsk.ndsk = i; | |
740 | 909 | |
741 | 910 | fclose(fp); |
742 | 911 | |
750 | 919 | */ |
751 | 920 | if ( (fp = fopen("diskstats", "r")) != NULL) |
752 | 921 | { |
753 | char diskname[256]; | |
754 | i = 0; | |
922 | char diskname[256]; | |
923 | struct perdsk tmpdsk; | |
924 | ||
925 | si->dsk.ndsk = 0; | |
926 | si->dsk.nmdd = 0; | |
927 | si->dsk.nlvm = 0; | |
755 | 928 | |
756 | 929 | while ( fgets(linebuf, sizeof(linebuf), fp) ) |
757 | 930 | { |
758 | 931 | nr = sscanf(linebuf, |
759 | "%*d %*d %255s %lld %*d %lld %*d " | |
932 | "%d %d %255s %lld %*d %lld %*d " | |
760 | 933 | "%lld %*d %lld %*d %*d %lld %lld", |
761 | diskname, | |
762 | &(si->xdsk.xdsk[i].nread), | |
763 | &(si->xdsk.xdsk[i].nrsect), | |
764 | &(si->xdsk.xdsk[i].nwrite), | |
765 | &(si->xdsk.xdsk[i].nwsect), | |
766 | &(si->xdsk.xdsk[i].io_ms), | |
767 | &(si->xdsk.xdsk[i].avque) ); | |
934 | &major, &minor, diskname, | |
935 | &tmpdsk.nread, &tmpdsk.nrsect, | |
936 | &tmpdsk.nwrite, &tmpdsk.nwsect, | |
937 | &tmpdsk.io_ms, &tmpdsk.avque ); | |
768 | 938 | |
769 | 939 | /* |
770 | 940 | ** check if this line concerns the entire disk |
771 | 941 | ** or just one of the partitions of a disk (to be |
772 | 942 | ** skipped) |
773 | 943 | */ |
774 | if (nr == 7) /* full stats-line ? */ | |
775 | { | |
776 | if ( !isrealdisk(diskname, | |
777 | si->xdsk.xdsk[i].name, | |
778 | MAXDKNAM) ) | |
944 | if (nr == 9) /* full stats-line ? */ | |
945 | { | |
946 | switch ( isdisk(major, minor, diskname, | |
947 | &tmpdsk, MAXDKNAM) ) | |
948 | { | |
949 | case NONTYPE: | |
779 | 950 | continue; |
780 | ||
781 | if (++i >= MAXDSK-1) | |
951 | ||
952 | case DSKTYPE: | |
953 | if (si->dsk.ndsk < MAXDSK-1) | |
954 | si->dsk.dsk[si->dsk.ndsk++] = tmpdsk; | |
782 | 955 | break; |
783 | } | |
784 | } | |
785 | ||
786 | si->xdsk.xdsk[i].name[0] = '\0'; /* set terminator for table */ | |
787 | si->xdsk.nrxdsk = i; | |
956 | ||
957 | case MDDTYPE: | |
958 | if (si->dsk.nmdd < MAXMDD-1) | |
959 | si->dsk.mdd[si->dsk.nmdd++] = tmpdsk; | |
960 | break; | |
961 | ||
962 | case LVMTYPE: | |
963 | if (si->dsk.nlvm < MAXLVM-1) | |
964 | si->dsk.lvm[si->dsk.nlvm++] = tmpdsk; | |
965 | break; | |
966 | } | |
967 | } | |
968 | } | |
969 | ||
970 | /* | |
971 | ** set terminator for table | |
972 | */ | |
973 | si->dsk.dsk[si->dsk.ndsk].name[0] = '\0'; | |
974 | si->dsk.mdd[si->dsk.nmdd].name[0] = '\0'; | |
975 | si->dsk.lvm[si->dsk.nlvm].name[0] = '\0'; | |
788 | 976 | |
789 | 977 | fclose(fp); |
790 | 978 | } |
802 | 990 | |
803 | 991 | /* |
804 | 992 | ** set of subroutines to determine which disks should be monitored |
805 | ** and to translate long name strings into short name strings | |
993 | ** and to translate name strings into (shorter) name strings | |
806 | 994 | */ |
807 | 995 | static void |
808 | nullmodname(char *curname, char *newname, int maxlen) | |
996 | nullmodname(unsigned int major, unsigned int minor, | |
997 | char *curname, struct perdsk *px, int maxlen) | |
809 | 998 | { |
810 | strncpy(newname, curname, maxlen-1); | |
811 | *(newname+maxlen-1) = 0; | |
999 | strncpy(px->name, curname, maxlen-1); | |
1000 | *(px->name+maxlen-1) = 0; | |
812 | 1001 | } |
813 | 1002 | |
814 | 1003 | static void |
815 | abbrevname1(char *curname, char *newname, int maxlen) | |
1004 | abbrevname1(unsigned int major, unsigned int minor, | |
1005 | char *curname, struct perdsk *px, int maxlen) | |
816 | 1006 | { |
817 | 1007 | char cutype[128]; |
818 | 1008 | int hostnum, busnum, targetnum, lunnum; |
820 | 1010 | sscanf(curname, "%[^/]/host%d/bus%d/target%d/lun%d", |
821 | 1011 | cutype, &hostnum, &busnum, &targetnum, &lunnum); |
822 | 1012 | |
823 | snprintf(newname, maxlen, "%c-h%db%dt%d", | |
1013 | snprintf(px->name, maxlen, "%c-h%db%dt%d", | |
824 | 1014 | cutype[0], hostnum, busnum, targetnum); |
825 | 1015 | } |
826 | 1016 | |
827 | 1017 | /* |
828 | ** table contains the names (in regexp format) of valid disks | |
829 | ** to be supported, together a function to modify the name-strings | |
830 | ** (i.e. to abbreviate long strings); | |
831 | ** this table is used in the function isrealdisk() | |
1018 | ** recognize LVM logical volumes | |
1019 | */ | |
1020 | #define NUMDMHASH 64 | |
1021 | #define DMHASH(x,y) (((x)+(y))%NUMDMHASH) | |
1022 | #define MAPDIR "/dev/mapper" | |
1023 | ||
1024 | struct devmap { | |
1025 | unsigned int major; | |
1026 | unsigned int minor; | |
1027 | char name[MAXDKNAM]; | |
1028 | struct devmap *next; | |
1029 | }; | |
1030 | ||
1031 | static void | |
1032 | lvmmapname(unsigned int major, unsigned int minor, | |
1033 | char *curname, struct perdsk *px, int maxlen) | |
1034 | { | |
1035 | static int firstcall = 1; | |
1036 | static struct devmap *devmaps[NUMDMHASH], *dmp; | |
1037 | int hashix; | |
1038 | ||
1039 | /* | |
1040 | ** setup a list of major-minor numbers of dm-devices with their | |
1041 | ** corresponding name | |
1042 | */ | |
1043 | if (firstcall) | |
1044 | { | |
1045 | DIR *dirp; | |
1046 | struct dirent *dentry; | |
1047 | struct stat statbuf; | |
1048 | char path[64]; | |
1049 | ||
1050 | if ( (dirp = opendir(MAPDIR)) ) | |
1051 | { | |
1052 | /* | |
1053 | ** read every directory-entry and search for | |
1054 | ** block devices | |
1055 | */ | |
1056 | while ( (dentry = readdir(dirp)) ) | |
1057 | { | |
1058 | snprintf(path, sizeof path, "%s/%s", | |
1059 | MAPDIR, dentry->d_name); | |
1060 | ||
1061 | if ( stat(path, &statbuf) == -1 ) | |
1062 | continue; | |
1063 | ||
1064 | if ( ! S_ISBLK(statbuf.st_mode) ) | |
1065 | continue; | |
1066 | /* | |
1067 | ** allocate struct to store name | |
1068 | */ | |
1069 | if ( !(dmp = malloc(sizeof (struct devmap)))) | |
1070 | continue; | |
1071 | ||
1072 | /* | |
1073 | ** store info in hash list | |
1074 | */ | |
1075 | strncpy(dmp->name, dentry->d_name, MAXDKNAM); | |
1076 | dmp->name[MAXDKNAM-1] = 0; | |
1077 | dmp->major = major(statbuf.st_rdev); | |
1078 | dmp->minor = minor(statbuf.st_rdev); | |
1079 | ||
1080 | hashix = DMHASH(dmp->major, dmp->minor); | |
1081 | ||
1082 | dmp->next = devmaps[hashix]; | |
1083 | ||
1084 | devmaps[hashix] = dmp; | |
1085 | } | |
1086 | ||
1087 | closedir(dirp); | |
1088 | } | |
1089 | ||
1090 | firstcall = 0; | |
1091 | } | |
1092 | ||
1093 | /* | |
1094 | ** find info in hash list | |
1095 | */ | |
1096 | hashix = DMHASH(major, minor); | |
1097 | dmp = devmaps[hashix]; | |
1098 | ||
1099 | while (dmp) | |
1100 | { | |
1101 | if (dmp->major == major && dmp->minor == minor) | |
1102 | { | |
1103 | /* | |
1104 | ** info found in hash list; fill proper name | |
1105 | */ | |
1106 | strncpy(px->name, dmp->name, maxlen-1); | |
1107 | *(px->name+maxlen-1) = 0; | |
1108 | return; | |
1109 | } | |
1110 | ||
1111 | dmp = dmp->next; | |
1112 | } | |
1113 | ||
1114 | /* | |
1115 | ** info not found in hash list; fill original name | |
1116 | */ | |
1117 | strncpy(px->name, curname, maxlen-1); | |
1118 | *(px->name+maxlen-1) = 0; | |
1119 | } | |
1120 | ||
1121 | /* | |
1122 | ** this table is used in the function isdisk() | |
1123 | ** | |
1124 | ** table contains the names (in regexp format) of disks | |
1125 | ** to be recognized, together with a function to modify | |
1126 | ** the name-strings (i.e. to abbreviate long strings); | |
1127 | ** some frequently found names (like 'loop' and 'ram') | |
1128 | ** are also recognized to skip them as fast as possible | |
832 | 1129 | */ |
833 | 1130 | static struct { |
834 | 1131 | char *regexp; |
835 | 1132 | regex_t compreg; |
836 | void (*modname)(char *, char *, int); | |
1133 | void (*modname)(unsigned int, unsigned int, | |
1134 | char *, struct perdsk *, int); | |
1135 | int retval; | |
837 | 1136 | } validdisk[] = { |
838 | { "^sd[a-z][a-z]*$", {0}, nullmodname, }, | |
839 | { "^hd[a-z]$", {0}, nullmodname, }, | |
840 | { "^rd/c[0-9][0-9]*d[0-9][0-9]*$", {0}, nullmodname, }, | |
841 | { "^cciss/c[0-9][0-9]*d[0-9][0-9]*$", {0}, nullmodname, }, | |
842 | { "/host.*/bus.*/target.*/lun.*/disc", {0}, abbrevname1, }, | |
843 | ||
844 | /* virtual disks */ | |
845 | { "^xvd[a-z][a-z]*$", {0}, nullmodname, }, | |
846 | { "^dasd[a-z][a-z]*$", {0}, nullmodname, }, | |
1137 | { "^ram[0-9][0-9]*$", {0}, (void *)0, NONTYPE, }, | |
1138 | { "^loop[0-9][0-9]*$", {0}, (void *)0, NONTYPE, }, | |
1139 | { "^sd[a-z][a-z]*$", {0}, nullmodname, DSKTYPE, }, | |
1140 | { "^dm-[0-9][0-9]*$", {0}, lvmmapname, LVMTYPE, }, | |
1141 | { "^md[0-9][0-9]*$", {0}, nullmodname, MDDTYPE, }, | |
1142 | { "^hd[a-z]$", {0}, nullmodname, DSKTYPE, }, | |
1143 | { "^rd/c[0-9][0-9]*d[0-9][0-9]*$", {0}, nullmodname, DSKTYPE, }, | |
1144 | { "^cciss/c[0-9][0-9]*d[0-9][0-9]*$", {0}, nullmodname, DSKTYPE, }, | |
1145 | { "^fio[a-z][a-z]*$", {0}, nullmodname, DSKTYPE, }, | |
1146 | { "/host.*/bus.*/target.*/lun.*/disc", {0}, abbrevname1, DSKTYPE, }, | |
1147 | { "^xvd[a-z][a-z]*$", {0}, nullmodname, DSKTYPE, }, | |
1148 | { "^dasd[a-z][a-z]*$", {0}, nullmodname, DSKTYPE, }, | |
1149 | { "^mmcblk[0-9][0-9]*$", {0}, nullmodname, DSKTYPE, }, | |
847 | 1150 | }; |
848 | 1151 | |
849 | 1152 | static int |
850 | isrealdisk(char *curname, char *newname, int maxlen) | |
1153 | isdisk(unsigned int major, unsigned int minor, | |
1154 | char *curname, struct perdsk *px, int maxlen) | |
851 | 1155 | { |
852 | 1156 | static int firstcall = 1; |
853 | 1157 | register int i; |
870 | 1174 | /* |
871 | 1175 | ** name-string recognized; modify name-string |
872 | 1176 | */ |
873 | (*validdisk[i].modname)(curname, newname, maxlen); | |
874 | ||
875 | return 1; | |
876 | } | |
877 | } | |
878 | ||
879 | return 0; | |
1177 | if (validdisk[i].retval != NONTYPE) | |
1178 | (*validdisk[i].modname)(major, minor, | |
1179 | curname, px, maxlen); | |
1180 | ||
1181 | return validdisk[i].retval; | |
1182 | } | |
1183 | } | |
1184 | ||
1185 | return NONTYPE; | |
880 | 1186 | } |
881 | 1187 | |
882 | 1188 | /* |
5 | 5 | ** |
6 | 6 | ** Include-file describing system-level counters maintained. |
7 | 7 | ** ================================================================ |
8 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
9 | ** E-mail: gerlof@ATComputing.nl | |
8 | ** Author: Gerlof Langeveld | |
9 | ** E-mail: gerlof.langeveld@atoptool.nl | |
10 | 10 | ** Date: November 1996 |
11 | 11 | ** LINUX-port: June 2000 |
12 | 12 | ** |
23 | 23 | #include "netstats.h" |
24 | 24 | |
25 | 25 | #define MAXCPU 64 |
26 | #define MAXDSK 128 | |
26 | #define MAXDSK 256 | |
27 | #define MAXLVM 256 | |
28 | #define MAXMDD 128 | |
27 | 29 | #define MAXDKNAM 32 |
28 | 30 | #define MAXINTF 32 |
29 | 31 | |
35 | 37 | count_t buffermem; /* number of buffer pages */ |
36 | 38 | count_t slabmem; /* number of slab pages */ |
37 | 39 | count_t cachemem; /* number of cache pages */ |
38 | count_t committed; /* number of reserved pages */ | |
40 | count_t cachedrt; /* number of cache pages (dirty) */ | |
39 | 41 | |
42 | count_t totswap; /* number of pages in swap */ | |
43 | count_t freeswap; /* number of free swap pages */ | |
44 | ||
45 | count_t pgscans; /* number of page scans */ | |
46 | count_t allocstall; /* try to free pages forced */ | |
40 | 47 | count_t swouts; /* number of pages swapped out */ |
41 | 48 | count_t swins; /* number of pages swapped in */ |
42 | 49 | |
43 | count_t totswap; /* number of pages in swap */ | |
44 | count_t freeswap; /* number of free swap pages */ | |
45 | count_t pgscans; /* number of page scans */ | |
46 | 50 | count_t commitlim; /* commit limit in pages */ |
47 | count_t allocstall; /* try to free pages forced */ | |
51 | count_t committed; /* number of reserved pages */ | |
48 | 52 | count_t cfuture[4]; /* reserved for future use */ |
49 | 53 | }; |
50 | 54 | |
64 | 68 | |
65 | 69 | /************************************************************************/ |
66 | 70 | |
71 | struct freqcnt { | |
72 | count_t maxfreq;/* frequency in MHz */ | |
73 | count_t cnt; /* number of clock ticks times state */ | |
74 | count_t ticks; /* number of total clock ticks */ | |
75 | /* if zero, cnt is actul freq */ | |
76 | }; | |
77 | ||
67 | 78 | struct percpu { |
68 | int cpunr; | |
69 | count_t stime; /* system time in clock ticks */ | |
70 | count_t utime; /* user time in clock ticks */ | |
71 | count_t ntime; /* nice time in clock ticks */ | |
72 | count_t itime; /* idle time in clock ticks */ | |
73 | count_t wtime; /* iowait time in clock ticks */ | |
74 | count_t Itime; /* irq time in clock ticks */ | |
75 | count_t Stime; /* softirq time in clock ticks */ | |
76 | count_t steal; /* steal time in clock ticks */ | |
77 | count_t cfuture[4]; /* reserved for future use */ | |
79 | int cpunr; | |
80 | count_t stime; /* system time in clock ticks */ | |
81 | count_t utime; /* user time in clock ticks */ | |
82 | count_t ntime; /* nice time in clock ticks */ | |
83 | count_t itime; /* idle time in clock ticks */ | |
84 | count_t wtime; /* iowait time in clock ticks */ | |
85 | count_t Itime; /* irq time in clock ticks */ | |
86 | count_t Stime; /* softirq time in clock ticks */ | |
87 | count_t steal; /* steal time in clock ticks */ | |
88 | count_t guest; /* guest time in clock ticks */ | |
89 | struct freqcnt freqcnt;/* frequency scaling info */ | |
90 | count_t cfuture[1]; /* reserved for future use */ | |
78 | 91 | }; |
79 | 92 | |
80 | 93 | struct cpustat { |
93 | 106 | |
94 | 107 | /************************************************************************/ |
95 | 108 | |
96 | struct perxdsk { | |
109 | struct perdsk { | |
97 | 110 | char name[MAXDKNAM]; /* empty string for last */ |
98 | 111 | count_t nread; /* number of read transfers */ |
99 | 112 | count_t nrsect; /* number of sectors read */ |
104 | 117 | count_t cfuture[4]; /* reserved for future use */ |
105 | 118 | }; |
106 | 119 | |
107 | struct xdskstat { | |
108 | int nrxdsk; | |
109 | struct perxdsk xdsk[MAXDSK]; | |
120 | struct dskstat { | |
121 | int ndsk; /* number of physical disks */ | |
122 | int nmdd; /* number of md volumes */ | |
123 | int nlvm; /* number of logical volumes */ | |
124 | struct perdsk dsk[MAXDSK]; | |
125 | struct perdsk mdd[MAXMDD]; | |
126 | struct perdsk lvm[MAXLVM]; | |
110 | 127 | }; |
111 | 128 | |
112 | 129 | /************************************************************************/ |
168 | 185 | struct memstat mem; |
169 | 186 | struct netstat net; |
170 | 187 | struct intfstat intf; |
171 | struct xdskstat xdsk; | |
188 | struct dskstat dsk; | |
172 | 189 | |
173 | 190 | struct wwwstat www; |
174 | 191 | }; |
8 | 8 | ** all running processes, needed to remember the process-counters from |
9 | 9 | ** the previous sample. |
10 | 10 | ** ========================================================================== |
11 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
12 | ** E-mail: gerlof@ATComputing.nl | |
11 | ** Author: Gerlof Langeveld | |
12 | ** E-mail: gerlof.langeveld@atoptool.nl | |
13 | 13 | ** Date: November 1996 |
14 | 14 | ** LINUX-port: June 2000 |
15 | 15 | ** -------------------------------------------------------------------------- |
16 | ** Copyright (C) 2000-2005 Gerlof Langeveld | |
16 | ** Copyright (C) 2000-2010 Gerlof Langeveld | |
17 | 17 | ** |
18 | 18 | ** This program is free software; you can redistribute it and/or modify it |
19 | 19 | ** under the terms of the GNU General Public License as published by the |
31 | 31 | ** -------------------------------------------------------------------------- |
32 | 32 | ** |
33 | 33 | ** $Log: procdbase.c,v $ |
34 | ** Revision 1.8 2010/04/23 12:19:35 gerlof | |
35 | ** Modified mail-address in header. | |
36 | ** | |
34 | 37 | ** Revision 1.7 2007/11/05 12:12:31 gerlof |
35 | 38 | ** Match processes not only on pid, but also on start time. |
36 | 39 | ** |
54 | 57 | ** |
55 | 58 | */ |
56 | 59 | |
57 | static const char rcsid[] = "$Id: procdbase.c,v 1.7 2007/11/05 12:12:31 gerlof Exp $"; | |
60 | static const char rcsid[] = "$Id: procdbase.c,v 1.8 2010/04/23 12:19:35 gerlof Exp $"; | |
58 | 61 | |
59 | 62 | #include <sys/types.h> |
60 | 63 | #include <sys/param.h> |
3 | 3 | ** The program 'atop' offers the possibility to view the activity of |
4 | 4 | ** the system on system-level as well as process-level. |
5 | 5 | ** ========================================================================== |
6 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
7 | ** E-mail: gerlof@ATComputing.nl | |
6 | ** Author: Gerlof Langeveld | |
7 | ** E-mail: gerlof.langeveld@atoptool.nl | |
8 | 8 | ** Date: September 2002 |
9 | 9 | ** -------------------------------------------------------------------------- |
10 | ** Copyright (C) 2000-2005 Gerlof Langeveld | |
10 | ** Copyright (C) 2000-2010 Gerlof Langeveld | |
11 | 11 | ** |
12 | 12 | ** This program is free software; you can redistribute it and/or modify it |
13 | 13 | ** under the terms of the GNU General Public License as published by the |
25 | 25 | ** -------------------------------------------------------------------------- |
26 | 26 | ** |
27 | 27 | ** $Log: rawlog.c,v $ |
28 | ** Revision 1.31 2010/11/17 12:43:31 gerlof | |
29 | ** The flag -r followed by exactly 8 'y' characters is not considered | |
30 | ** as 8 days ago, but as a literal filename. | |
31 | ** | |
32 | ** Revision 1.30 2010/10/23 14:03:03 gerlof | |
33 | ** Counters for total number of running and sleep threads (JC van Winkel). | |
34 | ** | |
35 | ** Revision 1.29 2010/04/23 13:55:52 gerlof | |
36 | ** Get rid of all setuid-root privs before activating other program. | |
37 | ** | |
38 | ** Revision 1.28 2010/04/23 12:19:35 gerlof | |
39 | ** Modified mail-address in header. | |
40 | ** | |
41 | ** Revision 1.27 2010/04/16 12:55:16 gerlof | |
42 | ** Automatically start another version of atop if the logfile to | |
43 | ** be read has not been created by the current version. | |
44 | ** | |
45 | ** Revision 1.26 2010/03/02 13:55:29 gerlof | |
46 | ** Struct stat size did not fit in short any more (modified to int). | |
47 | ** | |
48 | ** Revision 1.25 2009/12/17 08:16:06 gerlof | |
49 | ** Introduce branch-key to go to specific time in raw file. | |
50 | ** | |
51 | ** Revision 1.24 2009/11/27 15:26:29 gerlof | |
52 | ** Added possibility to specify y[y..] als filename for -r flag | |
53 | ** to access file of yesterday, day before yesterday, etc. | |
54 | ** | |
55 | ** Revision 1.23 2009/11/27 14:28:14 gerlof | |
56 | ** Rollback a "transaction" when not all parts could be | |
57 | ** written to the logfile (e.g. file system full) to avoid | |
58 | ** a corrupted logfile. | |
59 | ** | |
28 | 60 | ** Revision 1.22 2008/01/07 10:18:05 gerlof |
29 | 61 | ** Implement possibility to make summaries. |
30 | 62 | ** |
99 | 131 | ** |
100 | 132 | */ |
101 | 133 | |
102 | static const char rcsid[] = "$Id: rawlog.c,v 1.22 2008/01/07 10:18:05 gerlof Exp $"; | |
134 | static const char rcsid[] = "$Id: rawlog.c,v 1.31 2010/11/17 12:43:31 gerlof Exp $"; | |
103 | 135 | |
104 | 136 | #include <sys/types.h> |
105 | 137 | #include <sys/param.h> |
109 | 141 | #include <stdio.h> |
110 | 142 | #include <errno.h> |
111 | 143 | #include <fcntl.h> |
112 | #include <unistd.h> | |
113 | 144 | #include <stdlib.h> |
114 | 145 | #include <signal.h> |
115 | 146 | #include <ctype.h> |
116 | 147 | #include <sys/utsname.h> |
117 | 148 | #include <string.h> |
149 | #include <regex.h> | |
118 | 150 | #include <zlib.h> |
151 | #include <sys/time.h> | |
152 | #include <sys/resource.h> | |
153 | #include <unistd.h> | |
119 | 154 | |
120 | 155 | #include "atop.h" |
156 | #include "showgeneric.h" | |
121 | 157 | #include "photoproc.h" |
122 | 158 | #include "photosyst.h" |
123 | 159 | |
144 | 180 | unsigned int magic; |
145 | 181 | |
146 | 182 | unsigned short aversion; /* creator atop version with MSB */ |
147 | unsigned short sstatlen; /* length of struct sstat */ | |
148 | unsigned short pstatlen; /* length of struct pstat */ | |
183 | unsigned short future1; /* can be reused */ | |
184 | unsigned short future2; /* can be reused */ | |
149 | 185 | unsigned short rawheadlen; /* length of struct rawheader */ |
150 | 186 | unsigned short rawreclen; /* length of struct rawrecord */ |
151 | 187 | unsigned short hertz; /* clock interrupts per second */ |
152 | unsigned short sfuture[5]; /* future use */ | |
188 | unsigned short sfuture[6]; /* future use */ | |
189 | unsigned int sstatlen; /* length of struct sstat */ | |
190 | unsigned int pstatlen; /* length of struct pstat */ | |
153 | 191 | struct utsname utsname; /* info about this system */ |
154 | 192 | char cfuture[8]; /* future use */ |
155 | 193 | |
173 | 211 | unsigned int nlist; /* number of processes in list */ |
174 | 212 | unsigned int npresent; /* total number of processes */ |
175 | 213 | unsigned int nexit; /* number of exited processes */ |
214 | unsigned int ntrun; /* number of running threads */ | |
215 | unsigned int ntslpi; /* number of sleeping threads(S)*/ | |
216 | unsigned int ntslpu; /* number of sleeping threads(D)*/ | |
176 | 217 | unsigned int nzombie; /* number of zombie processes */ |
177 | 218 | unsigned int ifuture[6]; /* future use */ |
178 | 219 | }; |
183 | 224 | static int rawwopen(void); |
184 | 225 | static int lookslikedatetome(char *); |
185 | 226 | static void testcompval(int, char *); |
227 | static void try_other_version(int, int); | |
186 | 228 | |
187 | 229 | /* |
188 | 230 | ** write a raw record to file |
191 | 233 | char |
192 | 234 | rawwrite(time_t curtime, int numsecs, |
193 | 235 | struct sstat *ss, struct pstat *ps, |
194 | int nlist, int npresent, int nzombie, | |
195 | int nexit, char flag) | |
236 | int nlist, int npresent, int ntrun, int ntslpi, int ntslpu, | |
237 | int nzombie, int nexit, char flag) | |
196 | 238 | { |
197 | 239 | static int rawfd = -1; |
198 | 240 | struct rawrecord rr; |
199 | 241 | int rv; |
242 | struct stat filestat; | |
200 | 243 | |
201 | 244 | Byte scompbuf[sizeof(struct sstat)], *pcompbuf; |
202 | 245 | unsigned long scomplen = sizeof scompbuf; |
208 | 251 | */ |
209 | 252 | if (rawfd == -1) |
210 | 253 | rawfd = rawwopen(); |
254 | ||
255 | /* | |
256 | ** register current size of file in order to "roll back" | |
257 | ** writes that have been done while not *all* writes could | |
258 | ** succeed, e.g. when file system full | |
259 | */ | |
260 | (void) fstat(rawfd, &filestat); | |
211 | 261 | |
212 | 262 | /* |
213 | 263 | ** compress system- and process-level statistics |
237 | 287 | rr.flags = 0; |
238 | 288 | rr.nlist = nlist; |
239 | 289 | rr.npresent = npresent; |
290 | rr.ntrun = ntrun; | |
291 | rr.ntslpi = ntslpi; | |
292 | rr.ntslpu = ntslpu; | |
240 | 293 | rr.nzombie = nzombie; |
241 | 294 | rr.nexit = nexit; |
242 | 295 | rr.scomplen = scomplen; |
249 | 302 | { |
250 | 303 | fprintf(stderr, "%s - ", rawname); |
251 | 304 | perror("write raw record"); |
305 | (void) ftruncate(rawfd, filestat.st_size); | |
252 | 306 | cleanstop(7); |
253 | 307 | } |
254 | 308 | |
259 | 313 | { |
260 | 314 | fprintf(stderr, "%s - ", rawname); |
261 | 315 | perror("write raw status record"); |
316 | (void) ftruncate(rawfd, filestat.st_size); | |
262 | 317 | cleanstop(7); |
263 | 318 | } |
264 | 319 | |
269 | 324 | { |
270 | 325 | fprintf(stderr, "%s - ", rawname); |
271 | 326 | perror("write raw process record"); |
327 | (void) ftruncate(rawfd, filestat.st_size); | |
272 | 328 | cleanstop(7); |
273 | 329 | } |
274 | 330 | |
392 | 448 | #define OFFCHUNK 256 |
393 | 449 | |
394 | 450 | void |
395 | rawread(unsigned int begintime, unsigned int endtime) | |
451 | rawread(void) | |
396 | 452 | { |
397 | int rawfd; | |
453 | int rawfd, len; | |
454 | char *py; | |
398 | 455 | struct rawheader rh; |
399 | 456 | struct rawrecord rr; |
400 | 457 | struct sstat devsstat; |
414 | 471 | time_t timenow; |
415 | 472 | struct tm *tp; |
416 | 473 | |
417 | switch ( strlen(rawname) ) | |
474 | switch ( len = strlen(rawname) ) | |
418 | 475 | { |
419 | 476 | /* |
420 | 477 | ** if no filename is specified, assemble the name of the raw file |
448 | 505 | snprintf(rawname, RAWNAMESZ, "%s/atop_%s", |
449 | 506 | BASEPATH, |
450 | 507 | savedname); |
508 | break; | |
451 | 509 | } |
452 | break; | |
510 | ||
511 | /* | |
512 | ** if one or more 'y' (yesterday) characters are used and that | |
513 | ** string is not known as an existing file, the standard logfile | |
514 | ** is shown from N days ago (N is determined by the number | |
515 | ** of y's). | |
516 | */ | |
517 | default: | |
518 | if ( access(rawname, F_OK) == 0) | |
519 | break; /* existing file */ | |
520 | ||
521 | /* | |
522 | ** make a string existing of y's to compare with | |
523 | */ | |
524 | py = malloc(len+1); | |
525 | memset(py, 'y', len); | |
526 | *(py+len) = '\0'; | |
527 | ||
528 | if ( strcmp(rawname, py) == 0 ) | |
529 | { | |
530 | timenow = time(0); | |
531 | timenow -= len*3600*24; | |
532 | tp = localtime(&timenow); | |
533 | ||
534 | snprintf(rawname, RAWNAMESZ, "%s/atop_%04d%02d%02d", | |
535 | BASEPATH, | |
536 | tp->tm_year+1900, | |
537 | tp->tm_mon+1, | |
538 | tp->tm_mday); | |
539 | } | |
540 | ||
541 | free(py); | |
453 | 542 | } |
454 | 543 | |
455 | 544 | /* |
524 | 613 | "(created by version %d.%d - " |
525 | 614 | "current version %d.%d)\n", |
526 | 615 | (rh.aversion >> 8) & 0x7f, |
527 | rh.aversion & 0xff, | |
616 | rh.aversion & 0xff, | |
528 | 617 | getnumvers() >> 8, |
529 | 618 | getnumvers() & 0x7f); |
619 | } | |
620 | ||
621 | close(rawfd); | |
622 | ||
623 | if (((rh.aversion >> 8) & 0x7f) != (getnumvers() >> 8) || | |
624 | (rh.aversion & 0xff) != (getnumvers() & 0x7f) ) | |
625 | { | |
626 | try_other_version((rh.aversion >> 8) & 0x7f, | |
627 | rh.aversion & 0xff); | |
530 | 628 | } |
531 | 629 | |
532 | 630 | cleanstop(7); |
593 | 691 | ** check if this sample is within the time-range |
594 | 692 | ** specified with the -b and -e flags (if any) |
595 | 693 | */ |
596 | if ( (begintime && begintime > secsinday) || | |
597 | (endtime && endtime < secsinday) ) | |
694 | if ( (begintime && begintime > secsinday) ) | |
598 | 695 | { |
599 | lastcmd = '\0'; | |
696 | lastcmd = 1; | |
600 | 697 | lseek(rawfd, rr.scomplen+rr.pcomplen, SEEK_CUR); |
601 | 698 | continue; |
602 | 699 | } |
603 | ||
700 | ||
701 | begintime = 0; | |
702 | ||
703 | if ( (endtime && endtime < secsinday) ) | |
704 | { | |
705 | free(offlist); | |
706 | close(rawfd); | |
707 | return; | |
708 | } | |
709 | ||
604 | 710 | /* |
605 | 711 | ** allocate space, read compressed system-level |
606 | 712 | ** statistics and decompress |
640 | 746 | lastcmd = (vis.show_samp)(rr.curtime, rr.interval, |
641 | 747 | &devsstat, devpstat, |
642 | 748 | rr.nlist, rr.npresent, |
643 | rr.nzombie, rr.nexit, | |
644 | flags); | |
749 | rr.ntrun, rr.ntslpi, | |
750 | rr.ntslpu, rr.nzombie, | |
751 | rr.nexit, flags); | |
645 | 752 | free(devpstat); |
646 | 753 | |
647 | 754 | switch (lastcmd) |
648 | 755 | { |
649 | case 'T': | |
756 | case MSAMPPREV: | |
650 | 757 | if (offcur >= 2) |
651 | 758 | offcur-= 2; |
652 | 759 | else |
655 | 762 | lseek(rawfd, *(offlist+offcur), SEEK_SET); |
656 | 763 | break; |
657 | 764 | |
658 | case 'r': | |
765 | case MRESET: | |
659 | 766 | lseek(rawfd, *offlist, SEEK_SET); |
660 | 767 | offcur = 1; |
768 | break; | |
769 | ||
770 | case MSAMPBRANCH: | |
771 | if (begintime && begintime < secsinday) | |
772 | { | |
773 | lseek(rawfd, *offlist, SEEK_SET); | |
774 | offcur = 1; | |
775 | } | |
661 | 776 | } |
662 | 777 | } |
778 | ||
779 | begintime = 0; | |
663 | 780 | |
664 | 781 | if (offcur >= 1) |
665 | 782 | offcur--; |
792 | 909 | cleanstop(7); |
793 | 910 | } |
794 | 911 | } |
912 | ||
913 | /* | |
914 | ** try to activate another atop- or atopsar-version | |
915 | ** to read this logfile | |
916 | */ | |
917 | static void | |
918 | try_other_version(int majorversion, int minorversion) | |
919 | { | |
920 | char tmpbuf[1024], *p; | |
921 | extern char **argvp; | |
922 | int fds; | |
923 | struct rlimit rlimit; | |
924 | int setresuid(uid_t, uid_t, uid_t); | |
925 | ||
926 | /* | |
927 | ** prepare name of executable file | |
928 | ** the current pathname (if any) is stripped off | |
929 | */ | |
930 | snprintf(tmpbuf, sizeof tmpbuf, "%s-%d.%d", | |
931 | (p = strrchr(*argvp, '/')) ? p+1 : *argvp, | |
932 | majorversion, minorversion); | |
933 | ||
934 | fprintf(stderr, "trying to activate %s....\n", tmpbuf); | |
935 | ||
936 | /* | |
937 | ** be sure no open file descriptors are passed | |
938 | ** except stdin, stdout en stderr | |
939 | */ | |
940 | (void) getrlimit(RLIMIT_NOFILE, &rlimit); | |
941 | ||
942 | for (fds=3; fds < rlimit.rlim_cur; fds++) | |
943 | close(fds); | |
944 | ||
945 | /* | |
946 | ** be absolutely sure not to pass setuid-root privileges | |
947 | ** to the loaded program | |
948 | */ | |
949 | setresuid(getuid(), getuid(), getuid()); | |
950 | ||
951 | /* | |
952 | ** load alternative executable image | |
953 | ** at this moment the saved-uid might still be set | |
954 | ** to 'root' but this is reset at the moment of exec | |
955 | */ | |
956 | (void) execvp(tmpbuf, argvp); | |
957 | ||
958 | /* | |
959 | ** point of no return, except when exec failed | |
960 | */ | |
961 | fprintf(stderr, "activation of %s failed!\n", tmpbuf); | |
962 | } |
6 | 6 | ** This source-file contains the print-functions to visualize the calculated |
7 | 7 | ** figures. |
8 | 8 | ** ========================================================================== |
9 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: gerlof@ATComputing.nl | |
9 | ** Author: Gerlof Langeveld | |
10 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | 11 | ** Date: November 1996 |
12 | 12 | ** LINUX-port: June 2000 |
13 | 13 | ** -------------------------------------------------------------------------- |
14 | ** Copyright (C) 2000-2005 Gerlof Langeveld | |
14 | ** Copyright (C) 2000-2010 Gerlof Langeveld | |
15 | 15 | ** |
16 | 16 | ** This program is free software; you can redistribute it and/or modify it |
17 | 17 | ** under the terms of the GNU General Public License as published by the |
29 | 29 | ** -------------------------------------------------------------------------- |
30 | 30 | ** |
31 | 31 | ** $Log: showgeneric.c,v $ |
32 | ** Revision 1.71 2010/10/25 19:08:32 gerlof | |
33 | ** When the number of lines is too small for the system-level | |
34 | ** lines, limit the number of variable resources automatically | |
35 | ** to a minimum. | |
36 | ** | |
37 | ** Revision 1.70 2010/10/23 14:04:05 gerlof | |
38 | ** Counters for total number of running and sleep threads (JC van Winkel). | |
39 | ** | |
40 | ** Revision 1.69 2010/04/23 12:19:35 gerlof | |
41 | ** Modified mail-address in header. | |
42 | ** | |
43 | ** Revision 1.68 2010/04/23 09:58:11 gerlof | |
44 | ** Version (flag -V) handled earlier after startup. | |
45 | ** | |
46 | ** Revision 1.67 2010/04/23 07:57:32 gerlof | |
47 | ** Proper sorting of processes when switching from single process view | |
48 | ** to cumulative view (key 'u' or 'p') and vice versa. | |
49 | ** | |
50 | ** Revision 1.66 2010/04/17 17:20:26 gerlof | |
51 | ** Allow modifying the layout of the columns in the system lines. | |
52 | ** | |
53 | ** Revision 1.65 2010/03/16 21:13:38 gerlof | |
54 | ** Program and user selection can be combined with program and user | |
55 | ** accumulation. | |
56 | ** | |
57 | ** Revision 1.64 2010/03/16 20:18:46 gerlof | |
58 | ** Show in header-line if user selections and program selection are active. | |
59 | ** | |
60 | ** Revision 1.63 2010/03/16 20:08:51 gerlof | |
61 | ** Performance improvement: only sort system-resources once per interval. | |
62 | ** | |
63 | ** Revision 1.62 2010/03/04 10:53:01 gerlof | |
64 | ** Support I/O-statistics on logical volumes and MD devices. | |
65 | ** | |
66 | ** Revision 1.61 2009/12/17 10:55:07 gerlof | |
67 | ** *** empty log message *** | |
68 | ** | |
69 | ** Revision 1.60 2009/12/17 10:50:30 gerlof | |
70 | ** Allow own defined process line with key 'o' and a definition | |
71 | ** in the atoprc file. | |
72 | ** | |
73 | ** Revision 1.59 2009/12/17 09:03:26 gerlof | |
74 | ** Center message "....since boot" in status line on first screen. | |
75 | ** | |
76 | ** Revision 1.58 2009/12/17 08:55:15 gerlof | |
77 | ** Show messages on status line in color to draw attention. | |
78 | ** | |
79 | ** Revision 1.57 2009/12/17 08:16:14 gerlof | |
80 | ** Introduce branch-key to go to specific time in raw file. | |
81 | ** | |
82 | ** Revision 1.56 2009/12/12 09:06:39 gerlof | |
83 | ** Corrected cumulated disk I/O per user/program (JC van Winkel). | |
84 | ** | |
85 | ** Revision 1.55 2009/12/10 13:34:44 gerlof | |
86 | ** Show which toggle-keys are active in the header line. | |
87 | ** | |
88 | ** Revision 1.54 2009/12/10 11:55:03 gerlof | |
89 | ** Introduce system-wide /etc/atoprc | |
90 | ** | |
91 | ** Revision 1.53 2009/12/10 09:53:08 gerlof | |
92 | ** Improved display of header-line (JC van Winkel). | |
93 | ** | |
32 | 94 | ** Revision 1.52 2008/03/06 10:14:01 gerlof |
33 | 95 | ** Modified help-messages. |
34 | 96 | ** |
192 | 254 | ** |
193 | 255 | */ |
194 | 256 | |
195 | static const char rcsid[] = "$Id: showgeneric.c,v 1.52 2008/03/06 10:14:01 gerlof Exp $"; | |
257 | static const char rcsid[] = "$Id: showgeneric.c,v 1.71 2010/10/25 19:08:32 gerlof Exp $"; | |
196 | 258 | |
197 | 259 | #include <sys/types.h> |
198 | 260 | #include <sys/param.h> |
217 | 279 | #include "photoproc.h" |
218 | 280 | #include "photosyst.h" |
219 | 281 | #include "showgeneric.h" |
282 | #include "showlinux.h" | |
220 | 283 | |
221 | 284 | struct selection procsel = {"", {USERSTUB, }, "", 0, { 0, }}; |
222 | 285 | |
231 | 294 | |
232 | 295 | static int maxcpulines = 999; /* maximum cpu lines */ |
233 | 296 | static int maxdsklines = 999; /* maximum disk lines */ |
297 | static int maxmddlines = 999; /* maximum MDD lines */ | |
298 | static int maxlvmlines = 999; /* maximum LVM lines */ | |
234 | 299 | static int maxintlines = 999; /* maximum interface lines */ |
235 | ||
236 | static char *genhdr = "ATOP - %-18.18s " | |
237 | "%s %s %12ld seconds elapsed\n"; | |
238 | 300 | |
239 | 301 | static int cumusers(struct pstat *, struct pstat *, int); |
240 | 302 | static int cumprocs(struct pstat *, struct pstat *, int); |
303 | static void limitedlines(void); | |
241 | 304 | static long getnumval(char *, long, int); |
242 | 305 | |
243 | 306 | |
244 | 307 | static int (*procsort[])(const void *, const void *) = { |
245 | [MSORTCPU]=compcpu, | |
246 | [MSORTMEM]=compmem, | |
247 | [MSORTDSK]=compdsk, | |
248 | [MSORTNET]=compnet, | |
308 | [MSORTCPU&0x1f]=compcpu, | |
309 | [MSORTMEM&0x1f]=compmem, | |
310 | [MSORTDSK&0x1f]=compdsk, | |
311 | [MSORTNET&0x1f]=compnet, | |
249 | 312 | }; |
313 | ||
314 | extern proc_printpair ownprocs[]; | |
250 | 315 | |
251 | 316 | |
252 | 317 | /* |
255 | 320 | char |
256 | 321 | generic_samp(time_t curtime, int nsecs, |
257 | 322 | struct sstat *sstat, struct pstat *pstat, |
258 | int nact, int nproc, int nzomb, int nexit, char flag) | |
323 | int nact, int nproc, int ntrun, int ntslpi, int ntslpu, int nzomb, | |
324 | int nexit, char flag) | |
259 | 325 | { |
260 | 326 | static int callnr = 0; |
261 | 327 | |
262 | 328 | register int i, curline, statline; |
263 | 329 | int firstproc = 0, plistsz, alistsz, killpid, killsig; |
264 | 330 | int lastchar; |
265 | char format1[16], format2[16]; | |
266 | char *statmsg = NULL, curorder, autoorder; | |
331 | char format1[16], format2[16], hhmm[16]; | |
332 | char *statmsg = NULL, lastorder=0, curorder, autoorder; | |
333 | char buf[33]; | |
267 | 334 | struct passwd *pwd; |
268 | 335 | struct syscap syscap; |
336 | ||
337 | struct selection *cursel = &procsel; | |
338 | static struct selection emptysel = {"", {USERSTUB, }, "", 0, { 0, }}; | |
269 | 339 | |
270 | 340 | struct pstat *save_pstat = NULL; |
271 | 341 | int save_nact = 0; |
351 | 421 | showtype = MPROCARG; |
352 | 422 | break; |
353 | 423 | |
424 | case MPROCOWN: | |
425 | showtype = MPROCOWN; | |
426 | break; | |
427 | ||
354 | 428 | case MAVGVAL: |
355 | 429 | if (avgval) |
356 | 430 | avgval=0; |
381 | 455 | break; |
382 | 456 | |
383 | 457 | case MSYSLIMIT: |
384 | maxcpulines = 0; | |
385 | maxdsklines = 5; | |
386 | maxintlines = 3; | |
387 | break; | |
388 | ||
389 | case MVERSION: | |
390 | printf("%s\n", getstrvers()); | |
391 | cleanstop(0); | |
458 | limitedlines(); | |
459 | break; | |
392 | 460 | |
393 | 461 | default: |
394 | 462 | prusage("atop"); |
422 | 490 | cbreak(); |
423 | 491 | noecho(); |
424 | 492 | |
425 | if (COLS < 80) | |
493 | if (COLS < 30) | |
426 | 494 | { |
427 | 495 | printw("Not enough columns " |
428 | "(need at least %d columns)\n", 80); | |
496 | "(need at least %d columns)\n", 30); | |
429 | 497 | refresh(); |
430 | 498 | sleep(3); |
431 | 499 | cleanstop(1); |
457 | 525 | */ |
458 | 526 | totalcap(&syscap, sstat, pstat, nact); |
459 | 527 | |
528 | ||
529 | /* | |
530 | ** sort per-cpu statistics on busy percentage | |
531 | ** sort per-logical-volume statistics on busy percentage | |
532 | ** sort per-multiple-device statistics on busy percentage | |
533 | ** sort per-disk statistics on busy percentage | |
534 | ** sort per-interface statistics on busy percentage (if known) | |
535 | */ | |
536 | if (sstat->cpu.nrcpu > 1 && maxcpulines > 0) | |
537 | qsort(sstat->cpu.cpu, sstat->cpu.nrcpu, | |
538 | sizeof sstat->cpu.cpu[0], cpucompar); | |
539 | ||
540 | if (sstat->dsk.nlvm > 1 && maxlvmlines > 0) | |
541 | qsort(sstat->dsk.lvm, sstat->dsk.nlvm, | |
542 | sizeof sstat->dsk.lvm[0], diskcompar); | |
543 | ||
544 | if (sstat->dsk.nmdd > 1 && maxmddlines > 0) | |
545 | qsort(sstat->dsk.mdd, sstat->dsk.nmdd, | |
546 | sizeof sstat->dsk.mdd[0], diskcompar); | |
547 | ||
548 | if (sstat->dsk.ndsk > 1 && maxdsklines > 0) | |
549 | qsort(sstat->dsk.dsk, sstat->dsk.ndsk, | |
550 | sizeof sstat->dsk.dsk[0], diskcompar); | |
551 | ||
552 | if (sstat->intf.nrintf > 1 && maxintlines > 0) | |
553 | qsort(sstat->intf.intf, sstat->intf.nrintf, | |
554 | sizeof sstat->intf.intf[0], intfcompar); | |
555 | ||
460 | 556 | /* |
461 | 557 | ** loop in which the system resources and the list of active |
462 | 558 | ** processes is shown; the loop will be preempted by receiving |
483 | 579 | if (screen) |
484 | 580 | attron(A_REVERSE); |
485 | 581 | |
486 | printg(genhdr, utsname.nodename, format1, format2, nsecs); | |
582 | int seclen = val2elapstr(nsecs, buf); | |
583 | int lenavail = (screen ? COLS : linelen) - | |
584 | 41 - seclen - utsnodenamelen; | |
585 | int len1 = lenavail / 3; | |
586 | int len2 = lenavail - len1 - len1; | |
587 | ||
588 | printg("ATOP - %s%*s%s %s%*s%c%c%c%c%c%c%*s%s elapsed", | |
589 | utsname.nodename, len1, "", | |
590 | format1, format2, len1, "", | |
591 | fixedhead ? 'f' : '-', | |
592 | deviatonly ? '-' : 'a', | |
593 | usecolors ? '-' : 'x', | |
594 | avgval ? '1' : '-', | |
595 | procsel.userid[0] != USERSTUB ? 'U' : '-', | |
596 | procsel.procnamesz ? 'P' : '-', | |
597 | len2, "", buf); | |
487 | 598 | |
488 | 599 | if (screen) |
600 | { | |
489 | 601 | attroff(A_REVERSE); |
602 | attroff(A_REVERSE); | |
603 | } | |
604 | else | |
605 | { | |
606 | printg("\n"); | |
607 | } | |
490 | 608 | |
491 | 609 | /* |
492 | 610 | ** print cumulative system- and user-time for all processes |
493 | 611 | */ |
494 | pricumproc(pstat, nact, nproc, nzomb, nexit, avgval, nsecs); | |
495 | ||
496 | curline++; | |
497 | ||
498 | /* | |
499 | ** sort per-cpu statistics on busy percentage | |
500 | ** sort per-disk statistics on busy percentage | |
501 | ** sort per-interface statistics on busy percentage (if known) | |
502 | */ | |
503 | if (sstat->cpu.nrcpu > 1) | |
504 | qsort(sstat->cpu.cpu, sstat->cpu.nrcpu, | |
505 | sizeof sstat->cpu.cpu[0], cpucompar); | |
506 | ||
507 | if (sstat->xdsk.nrxdsk > 1) | |
508 | qsort(sstat->xdsk.xdsk, sstat->xdsk.nrxdsk, | |
509 | sizeof sstat->xdsk.xdsk[0], diskcompar); | |
510 | ||
511 | if (sstat->intf.nrintf > 1) | |
512 | qsort(sstat->intf.intf, sstat->intf.nrintf, | |
513 | sizeof sstat->intf.intf[0], intfcompar); | |
612 | pricumproc(pstat, sstat, nact, nproc, ntrun, ntslpi, ntslpu, | |
613 | nzomb, nexit, avgval, nsecs); | |
614 | curline=2; | |
514 | 615 | |
515 | 616 | /* |
516 | 617 | ** print other lines of system-wide statistics |
522 | 623 | |
523 | 624 | curline = prisyst(sstat, curline, nsecs, avgval, |
524 | 625 | fixedhead, usecolors, &autoorder, |
525 | maxcpulines, maxdsklines, maxintlines); | |
526 | ||
626 | maxcpulines, maxdsklines, maxmddlines, | |
627 | maxlvmlines, maxintlines); | |
628 | ||
629 | /* | |
630 | ** if system-wide statistics do not fit, | |
631 | ** limit the number of variable resource lines | |
632 | ** and try again | |
633 | */ | |
527 | 634 | if (screen && curline+2 > LINES) |
528 | 635 | { |
529 | move(0, 0); | |
636 | curline = 2; | |
637 | ||
638 | move(curline, 0); | |
530 | 639 | clrtobot(); |
531 | move(0, 0); | |
532 | printw("Not enough screen-lines available " | |
533 | "(need at least %d lines)\n", curline+2); | |
534 | move(1, 0); | |
535 | printw("Resize window or start atop with the -l flag" | |
536 | "to limit system-resources"); | |
537 | ||
538 | refresh(); | |
539 | sleep(4); | |
540 | cleanstop(1); | |
640 | move(curline, 0); | |
641 | ||
642 | limitedlines(); | |
643 | ||
644 | curline = prisyst(sstat, curline, nsecs, avgval, | |
645 | fixedhead, usecolors, &autoorder, | |
646 | maxcpulines, maxdsklines, maxmddlines, | |
647 | maxlvmlines, maxintlines); | |
648 | ||
649 | /* | |
650 | ** if system-wide statistics still do not fit, | |
651 | ** the window is really to small | |
652 | */ | |
653 | if (curline+2 > LINES) | |
654 | { | |
655 | move(0, 0); | |
656 | clrtobot(); | |
657 | move(0, 0); | |
658 | printw("Not enough screen-lines available " | |
659 | "(need at least %d lines)\n", curline+2); | |
660 | move(1, 0); | |
661 | printw("Please resize window...."); | |
662 | ||
663 | refresh(); | |
664 | sleep(4); | |
665 | cleanstop(1); | |
666 | } | |
667 | else | |
668 | { | |
669 | statmsg = "Number of variable resources" | |
670 | " limited to fit number of lines"; | |
671 | } | |
541 | 672 | } |
542 | 673 | |
543 | 674 | statline = curline; |
675 | ||
676 | if (screen) | |
677 | move(curline, 0); | |
544 | 678 | |
545 | 679 | if (statmsg) |
546 | 680 | { |
547 | 681 | clrtoeol(); |
682 | if (usecolors) | |
683 | attron(COLOR_PAIR(COLORLOW)); | |
684 | ||
548 | 685 | printg(statmsg); |
686 | ||
687 | if (usecolors) | |
688 | attroff(COLOR_PAIR(COLORLOW)); | |
689 | ||
549 | 690 | statmsg = NULL; |
550 | 691 | } |
551 | 692 | else |
553 | 694 | if (flag&RRBOOT) |
554 | 695 | { |
555 | 696 | if (screen) |
697 | { | |
698 | if (usecolors) | |
699 | attron(COLOR_PAIR(COLORLOW)); | |
556 | 700 | attron(A_BLINK); |
557 | 701 | |
558 | printg(" *** system and " | |
559 | "process activity since boot ***"); | |
702 | printg("%*s", (COLS-45)/2, " "); | |
703 | } | |
704 | else | |
705 | { | |
706 | printg(" "); | |
707 | } | |
708 | ||
709 | printg("*** system and process activity " | |
710 | "since boot ***"); | |
560 | 711 | |
561 | 712 | if (screen) |
713 | { | |
714 | if (usecolors) | |
715 | attroff(COLOR_PAIR(COLORLOW)); | |
562 | 716 | attroff(A_BLINK); |
717 | } | |
563 | 718 | } |
564 | 719 | } |
565 | 720 | |
580 | 735 | */ |
581 | 736 | save_pstat = pstat; |
582 | 737 | save_nact = nact; |
738 | cursel = &emptysel; | |
583 | 739 | |
584 | 740 | /* |
585 | 741 | ** allocate space for new (temporary) list with |
596 | 752 | case MCUMUSER: |
597 | 753 | nact = cumusers(save_pstat, pstat, save_nact); |
598 | 754 | break; |
755 | ||
599 | 756 | case MCUMPROC: |
600 | 757 | nact = cumprocs(save_pstat, pstat, save_nact); |
601 | 758 | break; |
602 | 759 | } |
760 | ||
761 | lastorder = 0; /* force new sort */ | |
603 | 762 | |
604 | 763 | if (screen) |
605 | 764 | plistsz = LINES-curline-2; |
618 | 777 | |
619 | 778 | if (nact > 0 && plistsz > 0) |
620 | 779 | { |
621 | qsort(pstat, nact, sizeof(struct pstat), | |
622 | procsort[(int)curorder]); | |
623 | ||
624 | if (screen) | |
780 | if (lastorder != curorder) | |
781 | { | |
782 | qsort(pstat, nact, sizeof(struct pstat), | |
783 | procsort[(int)curorder&0x1f]); | |
784 | ||
785 | lastorder = curorder; | |
786 | } | |
787 | ||
788 | if (screen) { | |
625 | 789 | attron(A_REVERSE); |
790 | move(curline+1, 0); | |
791 | } | |
626 | 792 | |
627 | 793 | /* |
628 | 794 | ** print the header |
644 | 810 | */ |
645 | 811 | priproc(pstat, firstproc, nact, curline+2, |
646 | 812 | firstproc/plistsz+1, (nact-1)/plistsz+1, |
647 | showtype, curorder, &syscap, &procsel, | |
813 | showtype, curorder, &syscap, cursel, | |
648 | 814 | nsecs, avgval); |
649 | 815 | } |
650 | 816 | |
658 | 824 | { |
659 | 825 | free(pstat); |
660 | 826 | |
661 | pstat = save_pstat; | |
662 | nact = save_nact; | |
827 | pstat = save_pstat; | |
828 | nact = save_nact; | |
829 | cursel = &procsel; | |
663 | 830 | } |
664 | 831 | |
665 | 832 | /* |
673 | 840 | */ |
674 | 841 | if (paused) |
675 | 842 | { |
676 | move(statline, 73); | |
843 | move(statline, COLS-6); | |
677 | 844 | attron(A_BLINK); |
678 | 845 | attron(A_REVERSE); |
679 | 846 | printw("PAUSED"); |
729 | 896 | |
730 | 897 | return lastchar; |
731 | 898 | |
899 | /* | |
900 | ** branch to certain time stamp | |
901 | */ | |
902 | case MSAMPBRANCH: | |
903 | if (!rawreadflag) | |
904 | { | |
905 | statmsg = "Only allowed when viewing " | |
906 | "raw file!"; | |
907 | beep(); | |
908 | break; | |
909 | } | |
910 | ||
911 | if (paused) | |
912 | break; | |
913 | ||
914 | echo(); | |
915 | move(statline, 0); | |
916 | clrtoeol(); | |
917 | printw("Enter new time (format hh:mm): "); | |
918 | ||
919 | hhmm[0] = '\0'; | |
920 | scanw("%15s\n", hhmm); | |
921 | noecho(); | |
922 | ||
923 | if ( !hhmm2secs(hhmm, &begintime) ) | |
924 | { | |
925 | move(statline, 0); | |
926 | clrtoeol(); | |
927 | statmsg = "Wrong time format!"; | |
928 | beep(); | |
929 | begintime = 0; | |
930 | break; | |
931 | } | |
932 | ||
933 | return lastchar; | |
934 | ||
732 | 935 | /* |
733 | 936 | ** sort order automatically depending on |
734 | 937 | ** most busy resource |
786 | 989 | ** general figures per process |
787 | 990 | */ |
788 | 991 | case MPROCGEN: |
992 | if (showtype ==MCUMUSER || showtype ==MCUMPROC) | |
993 | lastorder = 0; /* force new sort */ | |
994 | ||
789 | 995 | showtype = MPROCGEN; |
790 | 996 | |
791 | 997 | if (showorder != MSORTAUTO) |
798 | 1004 | ** memory-specific figures per process |
799 | 1005 | */ |
800 | 1006 | case MPROCMEM: |
1007 | if (showtype ==MCUMUSER || showtype ==MCUMPROC) | |
1008 | lastorder = 0; /* force new sort */ | |
1009 | ||
801 | 1010 | showtype = MPROCMEM; |
802 | 1011 | |
803 | 1012 | if (showorder != MSORTAUTO) |
816 | 1025 | "available; request ignored!"; |
817 | 1026 | break; |
818 | 1027 | } |
1028 | ||
1029 | if (showtype ==MCUMUSER || showtype ==MCUMPROC) | |
1030 | lastorder = 0; /* force new sort */ | |
1031 | ||
819 | 1032 | showtype = MPROCDSK; |
820 | 1033 | |
821 | 1034 | if (showorder != MSORTAUTO) |
834 | 1047 | "request ignored!"; |
835 | 1048 | break; |
836 | 1049 | } |
1050 | ||
1051 | if (showtype ==MCUMUSER || showtype ==MCUMPROC) | |
1052 | lastorder = 0; /* force new sort */ | |
1053 | ||
837 | 1054 | showtype = MPROCNET; |
838 | 1055 | |
839 | 1056 | if (showorder != MSORTAUTO) |
846 | 1063 | ** various info per process |
847 | 1064 | */ |
848 | 1065 | case MPROCVAR: |
1066 | if (showtype ==MCUMUSER || showtype ==MCUMPROC) | |
1067 | lastorder = 0; /* force new sort */ | |
1068 | ||
849 | 1069 | showtype = MPROCVAR; |
850 | 1070 | firstproc = 0; |
851 | 1071 | break; |
854 | 1074 | ** command-line per process |
855 | 1075 | */ |
856 | 1076 | case MPROCARG: |
1077 | if (showtype ==MCUMUSER || showtype ==MCUMPROC) | |
1078 | lastorder = 0; /* force new sort */ | |
1079 | ||
857 | 1080 | showtype = MPROCARG; |
858 | 1081 | firstproc = 0; |
859 | 1082 | break; |
860 | 1083 | |
861 | 1084 | /* |
1085 | ** own defined output per process | |
1086 | */ | |
1087 | case MPROCOWN: | |
1088 | if (! ownprocs[0].f) | |
1089 | { | |
1090 | statmsg = "Own process line is not " | |
1091 | "configured in rc-file; " | |
1092 | "request ignored"; | |
1093 | break; | |
1094 | } | |
1095 | ||
1096 | if (showtype ==MCUMUSER || showtype ==MCUMPROC) | |
1097 | lastorder = 0; /* force new sort */ | |
1098 | ||
1099 | showtype = MPROCOWN; | |
1100 | firstproc = 0; | |
1101 | break; | |
1102 | ||
1103 | /* | |
862 | 1104 | ** scheduling-values per process |
863 | 1105 | */ |
864 | 1106 | case MPROCSCH: |
1107 | if (showtype ==MCUMUSER || showtype ==MCUMPROC) | |
1108 | lastorder = 0; /* force new sort */ | |
1109 | ||
865 | 1110 | showtype = MPROCSCH; |
866 | 1111 | |
867 | 1112 | if (showorder != MSORTAUTO) |
877 | 1122 | statmsg = "Consumption per user; use 'a' to " |
878 | 1123 | "toggle between all/active processes"; |
879 | 1124 | |
1125 | if (showtype != MCUMUSER) | |
1126 | lastorder = 0; /* force new sort */ | |
1127 | ||
880 | 1128 | showtype = MCUMUSER; |
881 | 1129 | firstproc = 0; |
882 | 1130 | break; |
887 | 1135 | case MCUMPROC: |
888 | 1136 | statmsg = "Consumption per program; use 'a' to " |
889 | 1137 | "toggle between all/active processes"; |
1138 | ||
1139 | if (showtype != MCUMPROC) | |
1140 | lastorder = 0; /* force new sort */ | |
890 | 1141 | |
891 | 1142 | showtype = MCUMPROC; |
892 | 1143 | firstproc = 0; |
1245 | 1496 | "statistics (now %d): ", |
1246 | 1497 | maxcpulines, statline); |
1247 | 1498 | |
1499 | if (sstat->dsk.nlvm > 0) | |
1500 | { | |
1501 | maxlvmlines = | |
1502 | getnumval("Maximum lines for LVM " | |
1503 | "statistics (now %d): ", | |
1504 | maxlvmlines, statline); | |
1505 | } | |
1506 | ||
1507 | if (sstat->dsk.nmdd > 0) | |
1508 | { | |
1509 | maxmddlines = | |
1510 | getnumval("Maximum lines for MD " | |
1511 | "device statistics (now %d): ", | |
1512 | maxmddlines, statline); | |
1513 | } | |
1514 | ||
1248 | 1515 | maxdsklines = |
1249 | 1516 | getnumval("Maximum lines for disk " |
1250 | 1517 | "statistics (now %d): ", |
1277 | 1544 | break; |
1278 | 1545 | |
1279 | 1546 | /* |
1280 | ** handle forward | |
1547 | ** handle redraw request | |
1548 | */ | |
1549 | case MREDRAW: | |
1550 | wclear(stdscr); | |
1551 | break; | |
1552 | ||
1553 | /* | |
1554 | ** handle backward | |
1281 | 1555 | */ |
1282 | 1556 | case MLISTFW: |
1283 | 1557 | if (alistsz-firstproc > plistsz) |
1331 | 1605 | */ |
1332 | 1606 | for (numusers=i=0; i < numprocs; i++, curprocs++) |
1333 | 1607 | { |
1608 | if (procsuppress(curprocs, &procsel)) | |
1609 | continue; | |
1610 | ||
1334 | 1611 | if ( curusers->gen.ruid != curprocs->gen.ruid ) |
1335 | 1612 | { |
1336 | 1613 | if (curusers->gen.pid) |
1347 | 1624 | curusers->cpu.utime += curprocs->cpu.utime; |
1348 | 1625 | curusers->cpu.stime += curprocs->cpu.stime; |
1349 | 1626 | |
1627 | curusers->dsk.rsz += curprocs->dsk.rsz; | |
1628 | curusers->dsk.wsz += curprocs->dsk.wsz; | |
1629 | ||
1350 | 1630 | curusers->dsk.rio += curprocs->dsk.rio; |
1351 | 1631 | curusers->dsk.wio += curprocs->dsk.wio; |
1352 | 1632 | |
1391 | 1671 | */ |
1392 | 1672 | for (numprogs=i=0; i < numprocs; i++, curprocs++) |
1393 | 1673 | { |
1674 | if (procsuppress(curprocs, &procsel)) | |
1675 | continue; | |
1676 | ||
1394 | 1677 | if ( strcmp(curprogs->gen.name, curprocs->gen.name) != 0) |
1395 | 1678 | { |
1396 | 1679 | if (curprogs->gen.pid) |
1410 | 1693 | curprogs->dsk.rio += curprocs->dsk.rio; |
1411 | 1694 | curprogs->dsk.wio += curprocs->dsk.wio; |
1412 | 1695 | |
1696 | curprogs->dsk.rsz += curprocs->dsk.rsz; | |
1697 | curprogs->dsk.wsz += curprocs->dsk.wsz; | |
1698 | ||
1413 | 1699 | curprogs->net.tcpsnd += curprocs->net.tcpsnd; |
1414 | 1700 | curprogs->net.tcprcv += curprocs->net.tcprcv; |
1415 | 1701 | curprogs->net.udpsnd += curprocs->net.udpsnd; |
1430 | 1716 | numprogs++; |
1431 | 1717 | |
1432 | 1718 | return numprogs; |
1719 | } | |
1720 | ||
1721 | static void | |
1722 | limitedlines(void) | |
1723 | { | |
1724 | maxcpulines = 0; | |
1725 | maxdsklines = 3; | |
1726 | maxmddlines = 4; | |
1727 | maxlvmlines = 5; | |
1728 | maxintlines = 3; | |
1433 | 1729 | } |
1434 | 1730 | |
1435 | 1731 | /* |
1511 | 1807 | {"\t'%c' - various info (ppid, user/group, date/time, status, " |
1512 | 1808 | "exitcode)\n", MPROCVAR}, |
1513 | 1809 | {"\t'%c' - full command-line per process\n", MPROCARG}, |
1810 | {"\t'%c' - use own output line definition\n", MPROCOWN}, | |
1811 | {"\n", ' '}, | |
1812 | {"Sort list of processes in order of:\n", ' '}, | |
1813 | {"\t'%c' - cpu activity\n", MSORTCPU}, | |
1814 | {"\t'%c' - memory consumption\n", MSORTMEM}, | |
1815 | {"\t'%c' - disk activity\n", MSORTDSK}, | |
1816 | {"\t'%c' - network activity\n", MSORTNET}, | |
1817 | {"\t'%c' - most active system resource (auto mode)\n", MSORTAUTO}, | |
1514 | 1818 | {"\n", ' '}, |
1515 | 1819 | {"Accumulated figures:\n", ' '}, |
1516 | 1820 | {"\t'%c' - total resource consumption per user\n", MCUMUSER}, |
1517 | 1821 | {"\t'%c' - total resource consumption per program (i.e. same " |
1518 | 1822 | "process name)\n", MCUMPROC}, |
1519 | 1823 | {"\n", ' '}, |
1520 | {"Sort list of active processes in order of:\n", ' '}, | |
1521 | {"\t'%c' - cpu activity\n", MSORTCPU}, | |
1522 | {"\t'%c' - memory consumption\n", MSORTMEM}, | |
1523 | {"\t'%c' - disk activity\n", MSORTDSK}, | |
1524 | {"\t'%c' - network activity\n", MSORTNET}, | |
1525 | {"\t'%c' - most active system resource (auto mode)\n", MSORTAUTO}, | |
1526 | {"\n", ' '}, | |
1527 | {"Screen-handling:\n", ' '}, | |
1528 | {"\t^F - show next page in the process-list (forward)\n", ' '}, | |
1529 | {"\t^B - show previous page in the process-list (backward)\n", ' '}, | |
1530 | {"\n", ' '}, | |
1531 | {"Miscellaneous commands:\n", ' '}, | |
1532 | {"\t'%c' - change interval-timer (0 = only manual trigger)\n", | |
1533 | MINTERVAL}, | |
1534 | {"\t'%c' - manual trigger to finish interval\n", MSAMPNEXT}, | |
1535 | {"\t'%c' - show previous interval again (raw file viewing)\n", | |
1536 | MSAMPPREV}, | |
1537 | {"\t'%c' - reset counters to zero (or rewind for raw file viewing)\n", | |
1538 | MRESET}, | |
1539 | {"\n", ' '}, | |
1824 | {"Selections:\n", ' '}, | |
1540 | 1825 | {"\t'%c' - focus on specific user name (regular expression)\n", |
1541 | 1826 | MSELUSER}, |
1542 | 1827 | {"\t'%c' - focus on specific process name (regular expression)\n", |
1543 | 1828 | MSELPROC}, |
1544 | 1829 | {"\n", ' '}, |
1545 | {"\t'%c' - active processes only (default) or all processes (toggle)\n", | |
1830 | {"Screen-handling:\n", ' '}, | |
1831 | {"\t^L - redraw the screen \n", ' '}, | |
1832 | {"\t^F - show next page in the process-list (forward)\n", ' '}, | |
1833 | {"\t^B - show previous page in the process-list (backward)\n", ' '}, | |
1834 | {"\n", ' '}, | |
1835 | {"Presentation (these keys are shown in the header line):\n", ' '}, | |
1836 | {"\t'%c' - show all processes (default: active processes) (toggle)\n", | |
1546 | 1837 | MALLPROC}, |
1547 | {"\t'%c' - pause-button to freeze current sample (toggle)\n", | |
1548 | MPAUSE}, | |
1549 | 1838 | {"\t'%c' - fixate on static range of header-lines (toggle)\n", |
1550 | 1839 | MSYSFIXED}, |
1551 | {"\t'%c' - use colors to indicate high occupation (toggle)\n", | |
1840 | {"\t'%c' - no colors to indicate high occupation (toggle)\n", | |
1552 | 1841 | MCOLORS}, |
1553 | 1842 | {"\t'%c' - show average-per-second i.s.o. total values (toggle)\n", |
1554 | 1843 | MAVGVAL}, |
1844 | {"\n", ' '}, | |
1845 | {"Raw file viewing:\n", ' '}, | |
1846 | {"\t'%c' - show next sample in raw file\n", MSAMPNEXT}, | |
1847 | {"\t'%c' - show previous sample in raw file\n", MSAMPPREV}, | |
1848 | {"\t'%c' - branch to certain time in raw file)\n", MSAMPBRANCH}, | |
1849 | {"\t'%c' - rewind to begin of raw file)\n", MRESET}, | |
1850 | {"\n", ' '}, | |
1851 | {"Miscellaneous commands:\n", ' '}, | |
1852 | {"\t'%c' - change interval-timer (0 = only manual trigger)\n", | |
1853 | MINTERVAL}, | |
1854 | {"\t'%c' - manual trigger to force next sample\n", MSAMPNEXT}, | |
1855 | {"\t'%c' - reset counters to boot time values\n", MRESET}, | |
1856 | {"\t'%c' - pause-button to freeze current sample (toggle)\n", | |
1857 | MPAUSE}, | |
1858 | {"\n", ' '}, | |
1555 | 1859 | {"\t'%c' - limited lines for per-cpu, disk and interface resources\n", |
1556 | 1860 | MSYSLIMIT}, |
1557 | 1861 | {"\t'%c' - kill a process (i.e. send a signal)\n", MKILLPROC}, |
1661 | 1965 | "date/time)\n", MPROCVAR); |
1662 | 1966 | printf("\t -%c show command-line per process\n", |
1663 | 1967 | MPROCARG); |
1968 | printf("\t -%c show own defined process-info\n", | |
1969 | MPROCOWN); | |
1664 | 1970 | printf("\t -%c show cumulated process-info per user\n", |
1665 | 1971 | MCUMUSER); |
1666 | 1972 | printf("\t -%c show cumulated process-info per program " |
1681 | 1987 | } |
1682 | 1988 | |
1683 | 1989 | /* |
1684 | ** functions to handle a particular tag in the .atoprc file | |
1990 | ** functions to handle a particular tag in the /etc/atoprc and .atoprc file | |
1685 | 1991 | */ |
1686 | 1992 | void |
1687 | do_username(char *val) | |
1993 | do_username(char *name, char *val) | |
1688 | 1994 | { |
1689 | 1995 | struct passwd *pwd; |
1690 | 1996 | |
1699 | 2005 | if (regcomp(&userregex, procsel.username, REG_NOSUB)) |
1700 | 2006 | { |
1701 | 2007 | fprintf(stderr, |
1702 | ".atoprc: invalid regular expression %s\n", | |
1703 | val); | |
2008 | "atoprc - %s: invalid regular expression %s\n", | |
2009 | name, val); | |
1704 | 2010 | exit(1); |
1705 | 2011 | } |
1706 | 2012 | |
1732 | 2038 | else |
1733 | 2039 | { |
1734 | 2040 | fprintf(stderr, |
1735 | ".atoprc: user-names matching %s do " | |
1736 | "not exist\n", val); | |
2041 | "atoprc - %s: user-names matching %s " | |
2042 | "do not exist\n", name, val); | |
1737 | 2043 | exit(1); |
1738 | 2044 | } |
1739 | 2045 | } |
1745 | 2051 | } |
1746 | 2052 | |
1747 | 2053 | void |
1748 | do_procname(char *val) | |
2054 | do_procname(char *name, char *val) | |
1749 | 2055 | { |
1750 | 2056 | strncpy(procsel.procname, val, sizeof procsel.procname -1); |
1751 | 2057 | procsel.procnamesz = strlen(procsel.procname); |
1755 | 2061 | if (regcomp(&procsel.procregex, procsel.procname, REG_NOSUB)) |
1756 | 2062 | { |
1757 | 2063 | fprintf(stderr, |
1758 | ".atoprc: invalid regular expression %s\n", | |
1759 | val); | |
2064 | "atoprc - %s: invalid regular expression %s\n", | |
2065 | name, val); | |
1760 | 2066 | exit(1); |
1761 | 2067 | } |
1762 | 2068 | } |
1763 | 2069 | } |
1764 | 2070 | |
2071 | extern int get_posval(char *name, char *val); | |
2072 | ||
2073 | ||
1765 | 2074 | void |
1766 | do_maxcpu(char *val) | |
2075 | do_maxcpu(char *name, char *val) | |
1767 | 2076 | { |
1768 | if (numeric(val)) | |
1769 | { | |
1770 | maxcpulines = atoi(val); | |
1771 | } | |
1772 | else | |
1773 | { | |
1774 | fprintf(stderr, ".atoprc: maxcpu value not numeric\n"); | |
1775 | exit(1); | |
1776 | } | |
2077 | maxcpulines = get_posval(name, val); | |
1777 | 2078 | } |
1778 | 2079 | |
1779 | 2080 | void |
1780 | do_maxdisk(char *val) | |
2081 | do_maxdisk(char *name, char *val) | |
1781 | 2082 | { |
1782 | if (numeric(val)) | |
1783 | { | |
1784 | maxdsklines = atoi(val); | |
1785 | } | |
1786 | else | |
1787 | { | |
1788 | fprintf(stderr, ".atoprc: maxdisk value not numeric\n"); | |
1789 | exit(1); | |
1790 | } | |
2083 | maxdsklines = get_posval(name, val); | |
1791 | 2084 | } |
1792 | 2085 | |
1793 | 2086 | void |
1794 | do_maxintf(char *val) | |
2087 | do_maxmdd(char *name, char *val) | |
1795 | 2088 | { |
1796 | if (numeric(val)) | |
1797 | { | |
1798 | maxintlines = atoi(val); | |
1799 | } | |
1800 | else | |
1801 | { | |
1802 | fprintf(stderr, ".atoprc: maxintf value not numeric\n"); | |
1803 | exit(1); | |
1804 | } | |
2089 | maxmddlines = get_posval(name, val); | |
1805 | 2090 | } |
1806 | 2091 | |
1807 | 2092 | void |
1808 | do_flags(char *val) | |
2093 | do_maxlvm(char *name, char *val) | |
2094 | { | |
2095 | maxlvmlines = get_posval(name, val); | |
2096 | } | |
2097 | ||
2098 | void | |
2099 | do_maxintf(char *name, char *val) | |
2100 | { | |
2101 | maxintlines = get_posval(name, val); | |
2102 | } | |
2103 | ||
2104 | void | |
2105 | do_flags(char *name, char *val) | |
1809 | 2106 | { |
1810 | 2107 | int i; |
1811 | 2108 | |
1869 | 2166 | showtype = MPROCARG; |
1870 | 2167 | break; |
1871 | 2168 | |
2169 | case MPROCOWN: | |
2170 | showtype = MPROCOWN; | |
2171 | break; | |
2172 | ||
1872 | 2173 | case MCUMUSER: |
1873 | 2174 | showtype = MCUMUSER; |
1874 | 2175 | break; |
6 | 6 | ** Include-file describing prototypes and structures for visualization |
7 | 7 | ** of counters. |
8 | 8 | ** ================================================================ |
9 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: gerlof@ATComputing.nl | |
9 | ** Author: Gerlof Langeveld | |
10 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | 11 | ** Date: July 2002 |
12 | 12 | ** |
13 | 13 | ** This program is free software; you can redistribute it and/or modify it |
57 | 57 | #define MPROCSCH 's' |
58 | 58 | #define MPROCVAR 'v' |
59 | 59 | #define MPROCARG 'c' |
60 | #define MPROCOWN 'o' | |
60 | 61 | |
61 | 62 | #define MCUMUSER 'u' |
62 | 63 | #define MCUMPROC 'p' |
78 | 79 | #define MKILLPROC 'k' |
79 | 80 | #define MLISTFW 0x06 |
80 | 81 | #define MLISTBW 0x02 |
82 | #define MREDRAW 0x0c | |
81 | 83 | #define MINTERVAL 'i' |
82 | 84 | #define MPAUSE 'z' |
83 | 85 | #define MQUIT 'q' |
84 | 86 | #define MRESET 'r' |
85 | 87 | #define MSAMPNEXT 't' |
86 | 88 | #define MSAMPPREV 'T' |
89 | #define MSAMPBRANCH 'b' | |
87 | 90 | #define MVERSION 'V' |
88 | 91 | #define MAVGVAL '1' |
89 | 92 | #define MHELP1 '?' |
93 | 96 | ** general function prototypes |
94 | 97 | */ |
95 | 98 | void totalcap (struct syscap *, struct sstat *, struct pstat *, int); |
96 | void pricumproc (struct pstat *, int, int, int, int, int, int); | |
99 | void pricumproc (struct pstat *, struct sstat *, int, int, int, int, | |
100 | int, int, int, int, int); | |
97 | 101 | |
98 | 102 | void showgenproc(struct pstat *, double, int, int); |
99 | 103 | void showmemproc(struct pstat *, double, int, int); |
106 | 110 | |
107 | 111 | void printg (const char *, ...); |
108 | 112 | int prisyst(struct sstat *, int, int, int, int, int, char *, |
109 | int, int, int); | |
113 | int, int, int, int, int); | |
110 | 114 | int priproc(struct pstat *, int, int, int, int, int, char, char, |
111 | 115 | struct syscap *, struct selection *, int, int); |
112 | 116 | void priphead(int, int, char, char, char); |
6 | 6 | ** This source-file contains the Linux-specific functions to calculate |
7 | 7 | ** figures to be visualized. |
8 | 8 | ** ========================================================================== |
9 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: gerlof@ATComputing.nl | |
9 | ** Author: Gerlof Langeveld | |
10 | ** Original version. | |
11 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | 12 | ** Date: July 2002 |
13 | ** | |
14 | ** Author: JC van Winkel - AT Computing, Nijmegen, Holland | |
15 | ** Complete redesign. | |
16 | ** E-mail: jc@ATComputing.nl | |
17 | ** Date: November 2009 | |
12 | 18 | ** -------------------------------------------------------------------------- |
13 | ** Copyright (C) 2000-2007 Gerlof Langeveld | |
19 | ** Copyright (C) 2009-2010 JC van Winkel | |
14 | 20 | ** |
15 | 21 | ** This program is free software; you can redistribute it and/or modify it |
16 | 22 | ** under the terms of the GNU General Public License as published by the |
28 | 34 | ** -------------------------------------------------------------------------- |
29 | 35 | ** |
30 | 36 | ** $Log: showlinux.c,v $ |
37 | ** Revision 1.70 2010/10/23 14:04:12 gerlof | |
38 | ** Counters for total number of running and sleep threads (JC van Winkel). | |
39 | ** | |
40 | ** Revision 1.69 2010/05/18 19:20:08 gerlof | |
41 | ** Introduce CPU frequency and scaling (JC van Winkel). | |
42 | ** | |
43 | ** Revision 1.68 2010/04/23 12:19:35 gerlof | |
44 | ** Modified mail-address in header. | |
45 | ** | |
46 | ** Revision 1.67 2010/04/17 17:20:33 gerlof | |
47 | ** Allow modifying the layout of the columns in the system lines. | |
48 | ** | |
49 | ** Revision 1.66 2010/03/16 21:14:46 gerlof | |
50 | ** Program and user selection can be combined with program and user | |
51 | ** accumulation. | |
52 | ** | |
53 | ** Revision 1.65 2010/03/04 10:53:26 gerlof | |
54 | ** Support I/O-statistics on logical volumes and MD devices. | |
55 | ** | |
56 | ** Revision 1.64 2010/01/18 18:06:28 gerlof | |
57 | ** Modified priorities for system-level columns. | |
58 | ** | |
59 | ** Revision 1.63 2010/01/16 12:54:33 gerlof | |
60 | ** Corrected order of columns. | |
61 | ** | |
62 | ** Revision 1.62 2010/01/16 11:38:02 gerlof | |
63 | ** Corrected counters for patched kernels (JC van Winkel). | |
64 | ** | |
65 | ** Revision 1.61 2010/01/08 11:25:56 gerlof | |
66 | ** Corrected column-width and priorities of network-stats. | |
67 | ** | |
68 | ** Revision 1.60 2010/01/03 18:27:19 gerlof | |
69 | ** *** empty log message *** | |
70 | ** | |
71 | ** Revision 1.59 2009/12/19 21:01:28 gerlof | |
72 | ** Improved syntax checking for ownprocline keyword (JC van Winkel). | |
73 | ** | |
74 | ** Revision 1.58 2009/12/17 11:59:28 gerlof | |
75 | ** Gather and display new counters: dirty cache and guest cpu usage. | |
76 | ** | |
77 | ** Revision 1.57 2009/12/17 10:51:19 gerlof | |
78 | ** Allow own defined process line with key 'o' and a definition | |
79 | ** in the atoprc file. | |
80 | ** | |
81 | ** Revision 1.56 2009/12/17 09:13:19 gerlof | |
82 | ** Reformatted some fields for better grouping of info. | |
83 | ** | |
84 | ** Revision 1.55 2009/12/12 10:11:18 gerlof | |
85 | ** Register and display end date and end time for process. | |
86 | ** | |
87 | ** Revision 1.54 2009/12/12 09:06:48 gerlof | |
88 | ** \Corrected cumulated disk I/O per user/program (JC van Winkel). | |
89 | ** | |
90 | ** Revision 1.53 2009/12/10 14:02:39 gerlof | |
91 | ** Add EUID, SUID and FSUID (and similar for GID's). | |
92 | ** | |
93 | ** Revision 1.52 2009/12/10 11:56:34 gerlof | |
94 | ** Various bug-solutions. | |
95 | ** | |
96 | ** Revision 1.51 2009/12/10 10:08:01 gerlof | |
97 | ** Major redesign for improved user interface (variable number of columns). | |
98 | ** Made by JC van Winkel. | |
99 | ** | |
31 | 100 | ** Revision 1.49 2008/03/06 08:38:28 gerlof |
32 | 101 | ** Register/show ppid of a process. |
33 | 102 | ** |
192 | 261 | ** |
193 | 262 | */ |
194 | 263 | |
195 | static const char rcsid[] = "$Id: showlinux.c,v 1.49 2008/03/06 08:38:28 gerlof Exp $"; | |
264 | static const char rcsid[] = "$Id: showlinux.c,v 1.70 2010/10/23 14:04:12 gerlof Exp $"; | |
196 | 265 | |
197 | 266 | #include <sys/types.h> |
198 | 267 | #include <sys/param.h> |
216 | 285 | #include "photoproc.h" |
217 | 286 | #include "photosyst.h" |
218 | 287 | #include "showgeneric.h" |
288 | #include "showlinux.h" | |
219 | 289 | |
220 | 290 | /* |
221 | 291 | ** critical percentages for occupation-percentage; |
222 | 292 | ** these defaults can be overruled via the config-file |
223 | 293 | */ |
224 | int cpubadness = 90; /* percentage */ | |
225 | int membadness = 90; /* percentage */ | |
226 | int swpbadness = 80; /* percentage */ | |
227 | int dskbadness = 70; /* percentage */ | |
228 | int netbadness = 90; /* percentage */ | |
229 | int pagbadness = 10; /* number per second */ | |
230 | ||
231 | int almostcrit = 80; /* percentage */ | |
294 | int cpubadness = 90; /* percentage */ | |
295 | int membadness = 90; /* percentage */ | |
296 | int swpbadness = 80; /* percentage */ | |
297 | int dskbadness = 70; /* percentage */ | |
298 | int netbadness = 90; /* percentage */ | |
299 | int pagbadness = 10; /* number per second */ | |
300 | ||
301 | int almostcrit = 80; /* percentage */ | |
232 | 302 | |
233 | 303 | /* |
234 | ** table with column headers for sorted process list | |
304 | * tables with all sys_printdefs | |
305 | */ | |
306 | sys_printdef *prcsyspdefs[] = { | |
307 | &syspdef_PRCSYS, | |
308 | &syspdef_PRCUSER, | |
309 | &syspdef_PRCNPROC, | |
310 | &syspdef_PRCNRUNNING, | |
311 | &syspdef_PRCNSLEEPING, | |
312 | &syspdef_PRCNDSLEEPING, | |
313 | &syspdef_PRCNZOMBIE, | |
314 | &syspdef_PRCCLONES, | |
315 | &syspdef_PRCNNEXIT, | |
316 | &syspdef_BLANKBOX, | |
317 | 0 | |
318 | }; | |
319 | sys_printdef *cpusyspdefs[] = { | |
320 | &syspdef_CPUSYS, | |
321 | &syspdef_CPUUSER, | |
322 | &syspdef_CPUIRQ, | |
323 | &syspdef_CPUIDLE, | |
324 | &syspdef_CPUWAIT, | |
325 | &syspdef_BLANKBOX, | |
326 | &syspdef_CPUFREQ, | |
327 | &syspdef_CPUSCALE, | |
328 | &syspdef_CPUSTEAL, | |
329 | &syspdef_CPUGUEST, | |
330 | &syspdef_BLANKBOX, | |
331 | 0 | |
332 | }; | |
333 | sys_printdef *cpisyspdefs[] = { | |
334 | &syspdef_CPUISYS, | |
335 | &syspdef_CPUIUSER, | |
336 | &syspdef_CPUIIRQ, | |
337 | &syspdef_CPUIIDLE, | |
338 | &syspdef_CPUIWAIT, | |
339 | &syspdef_BLANKBOX, | |
340 | &syspdef_CPUIFREQ, | |
341 | &syspdef_CPUISCALE, | |
342 | &syspdef_CPUISTEAL, | |
343 | &syspdef_CPUIGUEST, | |
344 | &syspdef_BLANKBOX, | |
345 | 0 | |
346 | }; | |
347 | sys_printdef *cplsyspdefs[] = { | |
348 | &syspdef_CPLAVG1, | |
349 | &syspdef_CPLAVG5, | |
350 | &syspdef_CPLAVG15, | |
351 | &syspdef_CPLCSW, | |
352 | &syspdef_CPLNUMCPU, | |
353 | &syspdef_CPLINTR, | |
354 | &syspdef_BLANKBOX, | |
355 | 0 | |
356 | }; | |
357 | sys_printdef *memsyspdefs[] = { | |
358 | &syspdef_MEMTOT, | |
359 | &syspdef_MEMFREE, | |
360 | &syspdef_MEMCACHE, | |
361 | &syspdef_MEMDIRTY, | |
362 | &syspdef_MEMBUFFER, | |
363 | &syspdef_MEMSLAB, | |
364 | &syspdef_BLANKBOX, | |
365 | 0 | |
366 | }; | |
367 | sys_printdef *swpsyspdefs[] = { | |
368 | &syspdef_SWPTOT, | |
369 | &syspdef_SWPFREE, | |
370 | &syspdef_SWPCOMMITTED, | |
371 | &syspdef_SWPCOMMITLIM, | |
372 | &syspdef_BLANKBOX, | |
373 | 0 | |
374 | }; | |
375 | sys_printdef *pagsyspdefs[] = { | |
376 | &syspdef_PAGSCAN, | |
377 | &syspdef_PAGSTALL, | |
378 | &syspdef_PAGSWIN, | |
379 | &syspdef_PAGSWOUT, | |
380 | &syspdef_BLANKBOX, | |
381 | 0 | |
382 | }; | |
383 | sys_printdef *dsksyspdefs[] = { | |
384 | &syspdef_DSKNAME, | |
385 | &syspdef_DSKBUSY, | |
386 | &syspdef_DSKNREAD, | |
387 | &syspdef_DSKNWRITE, | |
388 | &syspdef_DSKMBPERSECWR, | |
389 | &syspdef_DSKMBPERSECRD, | |
390 | &syspdef_DSKKBPERWR, | |
391 | &syspdef_DSKKBPERRD, | |
392 | &syspdef_DSKAVQUEUE, | |
393 | &syspdef_DSKAVIO, | |
394 | &syspdef_BLANKBOX, | |
395 | 0 | |
396 | }; | |
397 | sys_printdef *nettranssyspdefs[] = { | |
398 | &syspdef_NETTRANSPORT, | |
399 | &syspdef_NETTCPI, | |
400 | &syspdef_NETTCPO, | |
401 | &syspdef_NETUDPI, | |
402 | &syspdef_NETUDPO, | |
403 | &syspdef_NETTCPACTOPEN, | |
404 | &syspdef_NETTCPPASVOPEN, | |
405 | &syspdef_NETTCPRETRANS, | |
406 | &syspdef_NETTCPINERR, | |
407 | &syspdef_NETTCPORESET, | |
408 | &syspdef_NETUDPNOPORT, | |
409 | &syspdef_NETUDPINERR, | |
410 | &syspdef_BLANKBOX, | |
411 | 0 | |
412 | }; | |
413 | sys_printdef *netnetsyspdefs[] = { | |
414 | &syspdef_NETNETWORK, | |
415 | &syspdef_NETIPI, | |
416 | &syspdef_NETIPO, | |
417 | &syspdef_NETIPFRW, | |
418 | &syspdef_NETIPDELIV, | |
419 | &syspdef_NETICMPIN, | |
420 | &syspdef_NETICMPOUT, | |
421 | &syspdef_BLANKBOX, | |
422 | 0 | |
423 | }; | |
424 | sys_printdef *netintfsyspdefs[] = { | |
425 | &syspdef_NETNAME, | |
426 | &syspdef_NETPCKI, | |
427 | &syspdef_NETPCKO, | |
428 | &syspdef_NETSPEEDIN, | |
429 | &syspdef_NETSPEEDOUT, | |
430 | &syspdef_NETCOLLIS, | |
431 | &syspdef_NETMULTICASTIN, | |
432 | &syspdef_NETRCVERR, | |
433 | &syspdef_NETSNDERR, | |
434 | &syspdef_NETRCVDROP, | |
435 | &syspdef_NETSNDDROP, | |
436 | &syspdef_BLANKBOX, | |
437 | 0 | |
438 | }; | |
439 | ||
440 | /* | |
441 | * table with all proc_printdefs | |
442 | */ | |
443 | proc_printdef *allprocpdefs[]= | |
444 | { | |
445 | &procprt_PID, | |
446 | &procprt_PPID, | |
447 | &procprt_SYSCPU, | |
448 | &procprt_USRCPU, | |
449 | &procprt_VGROW, | |
450 | &procprt_RGROW, | |
451 | &procprt_MINFLT, | |
452 | &procprt_MAJFLT, | |
453 | &procprt_VSTEXT, | |
454 | &procprt_VSIZE, | |
455 | &procprt_RSIZE, | |
456 | &procprt_CMD, | |
457 | &procprt_RUID, | |
458 | &procprt_EUID, | |
459 | &procprt_SUID, | |
460 | &procprt_FSUID, | |
461 | &procprt_RGID, | |
462 | &procprt_EGID, | |
463 | &procprt_SGID, | |
464 | &procprt_FSGID, | |
465 | &procprt_STDATE, | |
466 | &procprt_STTIME, | |
467 | &procprt_ENDATE, | |
468 | &procprt_ENTIME, | |
469 | &procprt_THR, | |
470 | &procprt_TRUN, | |
471 | &procprt_TSLPI, | |
472 | &procprt_TSLPU, | |
473 | &procprt_POLI, | |
474 | &procprt_NICE, | |
475 | &procprt_PRI, | |
476 | &procprt_RTPR, | |
477 | &procprt_CURCPU, | |
478 | &procprt_ST, | |
479 | &procprt_EXC, | |
480 | &procprt_S, | |
481 | &procprt_COMMAND_LINE, | |
482 | &procprt_NPROCS, | |
483 | &procprt_RDDSK, // refers to correct disk display routines | |
484 | &procprt_WRDSK, // refers to correct disk display routines | |
485 | &procprt_WCANCEL_IOSTAT, | |
486 | &procprt_AVGRSZ, | |
487 | &procprt_AVGWSZ, | |
488 | &procprt_TOTRSZ, | |
489 | &procprt_TOTWSZ, | |
490 | &procprt_TCPRCV, | |
491 | &procprt_TCPRASZ, | |
492 | &procprt_TCPSND, | |
493 | &procprt_TCPSASZ, | |
494 | &procprt_UDPRCV, | |
495 | &procprt_UDPRASZ, | |
496 | &procprt_UDPSND, | |
497 | &procprt_UDPSASZ, | |
498 | &procprt_RAWSND, | |
499 | &procprt_RAWRCV, | |
500 | &procprt_RNET, | |
501 | &procprt_SNET, | |
502 | &procprt_SORTITEM, | |
503 | 0 | |
504 | }; | |
505 | ||
506 | ||
507 | /***************************************************************/ | |
508 | /* | |
509 | * output definitions for process data | |
510 | * these should be user configurable | |
511 | */ | |
512 | proc_printpair userprocs[MAXITEMS]; | |
513 | proc_printpair memprocs[MAXITEMS]; | |
514 | proc_printpair schedprocs[MAXITEMS]; | |
515 | proc_printpair genprocs[MAXITEMS]; | |
516 | proc_printpair dskprocs[MAXITEMS]; | |
517 | proc_printpair netprocs[MAXITEMS]; | |
518 | proc_printpair varprocs[MAXITEMS]; | |
519 | proc_printpair cmdprocs[MAXITEMS]; | |
520 | proc_printpair ownprocs[MAXITEMS]; | |
521 | proc_printpair totusers[MAXITEMS]; | |
522 | proc_printpair totprocs[MAXITEMS]; | |
523 | ||
524 | ||
525 | /*****************************************************************/ | |
526 | /* | |
527 | * output definitions for system data | |
528 | * these should be user configurable | |
529 | */ | |
530 | sys_printpair sysprcline[MAXITEMS]; | |
531 | sys_printpair allcpuline[MAXITEMS]; | |
532 | sys_printpair indivcpuline[MAXITEMS]; | |
533 | sys_printpair cplline[MAXITEMS]; | |
534 | sys_printpair memline[MAXITEMS]; | |
535 | sys_printpair swpline[MAXITEMS]; | |
536 | sys_printpair pagline[MAXITEMS]; | |
537 | sys_printpair dskline[MAXITEMS]; | |
538 | sys_printpair nettransportline[MAXITEMS]; | |
539 | sys_printpair netnetline[MAXITEMS]; | |
540 | sys_printpair netinterfaceline[MAXITEMS]; | |
541 | ||
542 | typedef struct { | |
543 | const char *name; | |
544 | int prio; | |
545 | } name_prio; | |
546 | ||
547 | /* | |
548 | ** make an string,int pair array from a string. chop based on spaces/tabs | |
549 | ** example: input: "ABCD:3 EFG:1 QWE:16" | |
550 | ** output: { { "ABCD", 3 }, {"EFG", 1}, { "QWE", 16}, { 0, 0 } } | |
235 | 551 | */ |
236 | static char *columnhead[] = { | |
237 | [MSORTCPU]= "CPU", [MSORTMEM]= "MEM", | |
238 | [MSORTDSK]= "DSK", [MSORTNET]= "NET", | |
239 | }; | |
552 | name_prio * | |
553 | makeargv(char *line, const char *linename) | |
554 | { | |
555 | int i=0; | |
556 | char *p=line; | |
557 | static name_prio vec[MAXITEMS]; // max MAXITEMS items | |
558 | ||
559 | char *name=0; | |
560 | char *prio=0; | |
561 | ||
562 | // find pair and scan it | |
563 | while (*p && i<MAXITEMS-1) | |
564 | { | |
565 | // skip initial spaces | |
566 | while (*p && (*p==' ' || *p=='\t')) | |
567 | { | |
568 | ++p; | |
569 | } | |
570 | if (! *p) | |
571 | { | |
572 | break; | |
573 | } | |
574 | name=p; | |
575 | // found a new word; let's chop! | |
576 | while (*p && *p !=':') | |
577 | { | |
578 | ++p; | |
579 | } | |
580 | if (*p==':') | |
581 | { | |
582 | *p=0; | |
583 | } | |
584 | else | |
585 | { | |
586 | fprintf(stderr, | |
587 | "atoprc - %s: no name:prio pair for " | |
588 | "`%s'\n", name, linename); | |
589 | cleanstop(1); | |
590 | } | |
591 | ||
592 | /* now get number */ | |
593 | p++; | |
594 | prio=p; | |
595 | errno = 0; /* To distinguish success/failure after call */ | |
596 | ||
597 | long lprio=strtol(p, &p, 10); | |
598 | ||
599 | if (prio==p || errno == ERANGE || lprio >= INT_MAX || lprio <0) | |
600 | { | |
601 | fprintf(stderr, | |
602 | "atoprc - %s: item `%s` has " | |
603 | "invalid priority `", linename, name); | |
604 | while (*prio && *prio !=' ') { | |
605 | fputc(*prio, stderr); | |
606 | prio++; | |
607 | } | |
608 | fprintf(stderr, "'\n"); | |
609 | cleanstop(1); | |
610 | } | |
611 | vec[i].name=name; | |
612 | vec[i].prio=lprio; | |
613 | ||
614 | ++i; | |
615 | } | |
616 | ||
617 | vec[i].name=0; | |
618 | return vec; | |
619 | ||
620 | } | |
621 | ||
240 | 622 | |
241 | 623 | /* |
242 | ** function protoypes | |
243 | */ | |
244 | static int syscolorlabel(char *, int, unsigned int); | |
245 | static void syscoloroff (char); | |
624 | * make_sys_prints: make array of sys_printpairs | |
625 | * input: string, sys_printpair array, maxentries | |
626 | */ | |
627 | void | |
628 | make_sys_prints(sys_printpair *ar, int maxn, const char *pairs, | |
629 | sys_printdef *permissables[], const char *linename) | |
630 | { | |
631 | name_prio *items; | |
632 | int n=strlen(pairs); | |
633 | ||
634 | char str[n+1]; | |
635 | strcpy(str, pairs); | |
636 | ||
637 | items=makeargv(str, linename); | |
638 | ||
639 | int i; | |
640 | for(i=0; items[i].name && i<maxn-1; ++i) | |
641 | { | |
642 | const char *name=items[i].name; | |
643 | int j; | |
644 | for (j=0; permissables[j] != 0; ++j) | |
645 | { | |
646 | if (strcmp(permissables[j]->configname, name)==0) | |
647 | { | |
648 | ar[i].f=permissables[j]; | |
649 | ar[i].prio=items[i].prio; | |
650 | break; | |
651 | } | |
652 | } | |
653 | if (permissables[j]==0) | |
654 | { | |
655 | fprintf(stderr, | |
656 | "atoprc - own system line: item %s invalid in %s line!\n", | |
657 | name, linename); | |
658 | cleanstop(1); | |
659 | } | |
660 | } | |
661 | ar[i].f=0; | |
662 | ar[i].prio=0; | |
663 | } | |
664 | ||
246 | 665 | |
247 | 666 | /* |
248 | ** format-lines for printing | |
249 | */ | |
250 | char *prcline = "PRC | sys %s | user %s | #proc %s | #zombie %s |" | |
251 | " #exit %s |\n"; | |
252 | /***************************************************************************/ | |
253 | char *genprochdr1 = "\n PID SYSCPU USRCPU VGROW RGROW RDDSK WRDSK " | |
254 | "RNET SNET S %c%s CMD %4d/%-4d\n"; | |
255 | char *genproclina1 = "%5d %s %s %s %s %s %s %s %s %c %3.0lf%% %.14s\n"; | |
256 | char *genprocline1 = "%s %s 0K 0K (r&w %s) - " | |
257 | "- E %3.0lf%% <%.12s>\n"; | |
258 | char *genprocline1p = "%s %s %s %s %s %s %s %s E %3.0lf%% <%.12s>\n"; | |
259 | ||
260 | char *genprochdr2 = "\n PID SYSCPU USRCPU VGROW RGROW RDDSK WRDSK " | |
261 | " ST EXC S %c%s CMD %4d/%-4d\n"; | |
262 | char *genproclina2 = "%5d %s %s %s %s %s %s %c%c - %c %3.0lf%% " | |
263 | "%.14s\n"; | |
264 | char *genprocline2 = "%s %s 0K 0K - - %c%c %3d " | |
265 | "E %3.0lf%% <%.12s>\n"; | |
266 | ||
267 | char *genprochdr3 = "\n PID SYSCPU USRCPU VGROW RGROW USERNAME THR " | |
268 | "ST EXC S %c%s CMD %4d/%-4d\n"; | |
269 | char *genproclina3 = "%5d %s %s %s %s %-8.8s %3d %c%c - %c %3.0lf%% " | |
270 | "%.14s\n"; | |
271 | char *genprocline3 = "%s %s 0K 0K %-8.8s 0 %c%c %3d " | |
272 | "E %3.0lf%% <%.12s>\n"; | |
273 | /***************************************************************************/ | |
274 | char *memprochdr = "\n PID MINFLT MAJFLT VSTEXT " | |
275 | " VSIZE RSIZE VGROW RGROW %c%s CMD %4d/%-4d\n"; | |
276 | char *memproclina = "%5d %s %s %s %s %s %s %s %3.0lf%% %.14s\n"; | |
277 | char *memprocline = "%s %s 0K 0K 0K 0K 0K" | |
278 | " %3.0lf%% <%.12s>\n"; | |
279 | char *memproclinep = "%5d %s %s 0K %s %s %s %s %3.0lf%% " | |
280 | "<%.12s>\n"; | |
281 | /***************************************************************************/ | |
282 | char *dskprochdr1 = "\n PID READDISK AVGSIZE TOTSIZE WRITEDISK " | |
283 | "AVGSIZE TOTSIZE %c%s CMD %4d/%-4d\n"; | |
284 | char *dskproclina1 = "%5d %s %s %s %s %s %s %3.0lf%% %.14s\n"; | |
285 | char *dskprocline1 = " (reads&writes %s) " | |
286 | " %3.0lf%% <%.12s>\n"; | |
287 | char *dskprocline1p = "%5d %s %s %s %s %s %s %3.0lf%% <%.12s>\n"; | |
288 | ||
289 | char *dskprochdr2 = "\n PID RDDSK WRDSK WRDSK_CANCEL " | |
290 | " %c%s CMD %4d/%-4d\n"; | |
291 | char *dskproclina2 = "%5d %s %s %s " | |
292 | "%3.0lf%% %.14s\n"; | |
293 | char *dskprocline2 = " - - - " | |
294 | " %3.0lf%% <%.12s>\n"; | |
295 | /***************************************************************************/ | |
296 | char *netprochdr = "\n PID TCPRCV AVSZ|TCPSND AVSZ|UDPRCV AVSZ" | |
297 | "|UDPSND AVSZ|RAWRS|%c%s CMD %4d/%-4d\n"; | |
298 | char *netproclina = "%5d %s %s|%s %s|%s %s|%s %s|%2llu %2llu|" | |
299 | "%3.0lf%% %.14s\n"; | |
300 | char *netprocline = " " | |
301 | " %3.0lf%% <%.12s>\n"; | |
302 | char *netproclinep = "%5d %s %s|%s %s|%s %s|%s %s|%2llu %2llu|" | |
303 | "%3.0lf%% <%.12s>\n"; | |
304 | /***************************************************************************/ | |
305 | char *varprochdr = "\n PID PPID USERNAME GROUP " | |
306 | "STDATE STTIME ST EXC S %c%s CMD %4d/%-4d\n"; | |
307 | char *varproclina = "%5d %5d %-8.8s %-8.8s %s %s %c%c - %c %3.0lf%% " | |
308 | "%.14s\n"; | |
309 | char *varprocline = "%5d %-8.8s %-8.8s %s %s %c%c %3d E %3.0lf%% " | |
310 | "<%.12s>\n"; | |
311 | /***************************************************************************/ | |
312 | char *cmdprochdr = "\n PID %c%s COMMAND-LINE " | |
313 | " %4d/%-4d\n"; | |
314 | char *cmdproclina = "%5d %3.0lf%% %s\n"; | |
315 | char *cmdprocline = "%3.0lf%% <%.66s>\n"; | |
316 | /***************************************************************************/ | |
317 | char *schprochdr = "\n PID TRUN TSLPI TSLPU POLI NICE PRI RTPR " | |
318 | "CURCPU ST EXC S %c%s CMD %4d/%-4d\n"; | |
319 | char *schproclina = "%5d %4d %5d %5d %-4s %4d %3d %4d %6d %-2s - " | |
320 | "%c %3.0lf%% %.14s\n"; | |
321 | char *schprocline = " 0 0 0 - - - - - " | |
322 | "%c%c %3d E %3.0lf%% <%.12s>\n"; | |
323 | /***************************************************************************/ | |
324 | char *totuserhdr = "\nNPROCS SYSCPU USRCPU VSIZE RSIZE RDDSK " | |
325 | "WRDSK RNET SNET %c%s USER %4d/%-4d\n"; | |
326 | char *totuserlin = "%s %s %s %s %s %s %s %s %s " | |
327 | "%3.0lf%% %.14s\n"; | |
328 | /***************************************************************************/ | |
329 | char *totprochdr = "\nNPROCS SYSCPU USRCPU VSIZE RSIZE RDDSK " | |
330 | "WRDSK RNET SNET %c%s CMD %4d/%-4d\n"; | |
331 | char *totproclin = "%s %s %s %s %s %s %s %s %s " | |
332 | "%3.0lf%% %.14s\n"; | |
333 | /***************************************************************************/ | |
667 | * make_proc_prints: make array of proc_printpairs | |
668 | * input: string, proc_printpair array, maxentries | |
669 | */ | |
670 | void | |
671 | make_proc_prints(proc_printpair *ar, int maxn, const char *pairs, | |
672 | const char *linename) | |
673 | { | |
674 | name_prio *items; | |
675 | int n=strlen(pairs); | |
676 | ||
677 | char str[n+1]; | |
678 | strcpy(str, pairs); | |
679 | ||
680 | items=makeargv(str, linename); | |
681 | ||
682 | int i; | |
683 | for(i=0; items[i].name && i<maxn-1; ++i) | |
684 | { | |
685 | const char *name=items[i].name; | |
686 | int j; | |
687 | for (j=0; allprocpdefs[j] != 0; ++j) | |
688 | { | |
689 | if (strcmp(allprocpdefs[j]->configname, name)==0) | |
690 | { | |
691 | ar[i].f=allprocpdefs[j]; | |
692 | ar[i].prio=items[i].prio; | |
693 | break; | |
694 | } | |
695 | } | |
696 | if (allprocpdefs[j]==0) | |
697 | { | |
698 | fprintf(stderr, | |
699 | "atoprc - ownprocline: item %s invalid!\n", | |
700 | name); | |
701 | cleanstop(1); | |
702 | } | |
703 | } | |
704 | ar[i].f=0; | |
705 | ar[i].prio=0; | |
706 | } | |
334 | 707 | |
335 | 708 | /* |
336 | 709 | ** calculate the total consumption on system-level for the |
339 | 712 | void |
340 | 713 | totalcap(struct syscap *psc, struct sstat *sstat, struct pstat *pstat, int nact) |
341 | 714 | { |
342 | register int i; | |
343 | ||
344 | psc->nrcpu = sstat->cpu.nrcpu; | |
345 | psc->availcpu = sstat->cpu.all.stime + | |
346 | sstat->cpu.all.utime + | |
347 | sstat->cpu.all.ntime + | |
348 | sstat->cpu.all.itime + | |
349 | sstat->cpu.all.wtime + | |
350 | sstat->cpu.all.Itime + | |
351 | sstat->cpu.all.Stime + | |
352 | sstat->cpu.all.steal; | |
353 | ||
354 | psc->availmem = sstat->mem.physmem * pagesize/1024; | |
355 | ||
356 | if (supportflags & PATCHSTAT) | |
357 | { | |
358 | /* | |
359 | ** calculate total number of accesses which have been | |
360 | ** issued by the active processes for disk and for network | |
361 | */ | |
362 | for (psc->availnet=psc->availdsk=0, i=0; i < nact; i++) | |
363 | { | |
364 | psc->availnet += (pstat+i)->net.tcpsnd; | |
365 | psc->availnet += (pstat+i)->net.tcprcv; | |
366 | psc->availnet += (pstat+i)->net.udpsnd; | |
367 | psc->availnet += (pstat+i)->net.udprcv; | |
368 | psc->availnet += (pstat+i)->net.rawsnd; | |
369 | psc->availnet += (pstat+i)->net.rawrcv; | |
370 | ||
371 | psc->availdsk += (pstat+i)->dsk.rio; | |
372 | psc->availdsk += (pstat+i)->dsk.wio; | |
373 | } | |
374 | } | |
375 | else | |
376 | { | |
377 | for (psc->availnet=psc->availdsk=0, i=0; i < nact; i++) | |
378 | { | |
379 | psc->availdsk += (pstat+i)->dsk.rsz; | |
380 | psc->availdsk += (pstat+i)->dsk.wsz; | |
381 | } | |
382 | } | |
715 | register int i; | |
716 | ||
717 | psc->nrcpu = sstat->cpu.nrcpu; | |
718 | psc->availcpu = sstat->cpu.all.stime + | |
719 | sstat->cpu.all.utime + | |
720 | sstat->cpu.all.ntime + | |
721 | sstat->cpu.all.itime + | |
722 | sstat->cpu.all.wtime + | |
723 | sstat->cpu.all.Itime + | |
724 | sstat->cpu.all.Stime + | |
725 | sstat->cpu.all.steal + | |
726 | sstat->cpu.all.guest; | |
727 | ||
728 | psc->availmem = sstat->mem.physmem * pagesize/1024; | |
729 | ||
730 | if (supportflags & PATCHSTAT) | |
731 | { | |
732 | /* | |
733 | ** calculate total number of accesses which have been | |
734 | ** issued by the active processes for disk and for network | |
735 | */ | |
736 | for (psc->availnet=psc->availdsk=0, i=0; i < nact; i++) | |
737 | { | |
738 | psc->availnet += (pstat+i)->net.tcpsnd; | |
739 | psc->availnet += (pstat+i)->net.tcprcv; | |
740 | psc->availnet += (pstat+i)->net.udpsnd; | |
741 | psc->availnet += (pstat+i)->net.udprcv; | |
742 | psc->availnet += (pstat+i)->net.rawsnd; | |
743 | psc->availnet += (pstat+i)->net.rawrcv; | |
744 | ||
745 | psc->availdsk += (pstat+i)->dsk.rio; | |
746 | psc->availdsk += (pstat+i)->dsk.wio; | |
747 | } | |
748 | } | |
749 | else | |
750 | { | |
751 | for (psc->availnet=psc->availdsk=0, i=0; i < nact; i++) | |
752 | { | |
753 | psc->availdsk += (pstat+i)->dsk.rsz; | |
754 | psc->availdsk += (pstat+i)->dsk.wsz; | |
755 | } | |
756 | } | |
383 | 757 | } |
384 | 758 | |
385 | 759 | /* |
386 | 760 | ** calculate cumulative system- and user-time for all active processes |
387 | 761 | */ |
388 | 762 | void |
389 | pricumproc(struct pstat *pstat, int nact, int nproc, int nzomb, int nexit, | |
390 | int avgval, int nsecs) | |
391 | { | |
392 | int i; | |
393 | count_t totut, totst; | |
394 | char format1[16], format2[16], format3[16]; | |
395 | char format4[16], format5[16]; | |
396 | ||
397 | for (i=totut=totst=0; i < nact; i++) | |
398 | { | |
399 | totut += (pstat+i)->cpu.utime; | |
400 | totst += (pstat+i)->cpu.stime; | |
401 | } | |
402 | ||
403 | printg(prcline, val2cpustr(totst * 1000/hertz, format1), | |
404 | val2cpustr(totut * 1000/hertz, format2), | |
405 | val2valstr(nproc, format3, 6, 0, 0), | |
406 | val2valstr(nzomb, format4, 4, 0, 0), | |
407 | supportflags & ACCTACTIVE ? | |
408 | val2valstr(nexit, format5, 6, avgval, nsecs): | |
409 | " ?"); | |
410 | } | |
411 | ||
412 | /* | |
413 | ** print a line of general figures about one process | |
414 | */ | |
415 | void | |
416 | showgenproc(struct pstat *curstat, double perc, int nsecs, int avgval) | |
417 | { | |
418 | struct passwd *pwd; | |
419 | char *username, usname[16], exittype; | |
420 | ||
421 | char format1[16], format2[16]; | |
422 | char format3[16], format4[16]; | |
423 | char format5[16], format6[16]; | |
424 | char format7[16], format8[16]; | |
425 | ||
426 | if (curstat->gen.state != 'E') | |
427 | { | |
428 | if (supportflags & PATCHSTAT) | |
429 | { | |
430 | /* | |
431 | ** show active processes for patched kernel | |
432 | */ | |
433 | printg(genproclina1, | |
434 | curstat->gen.pid, | |
435 | val2cpustr(curstat->cpu.stime*1000/hertz, format1), | |
436 | val2cpustr(curstat->cpu.utime*1000/hertz, format2), | |
437 | val2memstr(curstat->mem.vgrow*1024, | |
438 | format3, KBFORMAT, 0, 0), | |
439 | val2memstr(curstat->mem.rgrow*1024, | |
440 | format4, KBFORMAT, 0, 0), | |
441 | val2valstr(curstat->dsk.rio, format5, 5, | |
442 | avgval, nsecs), | |
443 | val2valstr(curstat->dsk.wio, format6, 5, | |
444 | avgval, nsecs), | |
445 | val2valstr(curstat->net.tcprcv + | |
446 | curstat->net.udprcv + | |
447 | curstat->net.rawrcv, format7, 4, | |
448 | avgval, nsecs), | |
449 | val2valstr(curstat->net.tcpsnd + | |
450 | curstat->net.udpsnd + | |
451 | curstat->net.rawsnd, format8, 4, | |
452 | avgval, nsecs), | |
453 | curstat->gen.state, | |
454 | perc, curstat->gen.name); | |
455 | } | |
456 | else | |
457 | { | |
458 | if (supportflags & IOSTAT) | |
459 | { | |
460 | /* | |
461 | ** show active processes for kernel with iostats | |
462 | */ | |
463 | printg(genproclina2, | |
464 | curstat->gen.pid, | |
465 | val2cpustr(curstat->cpu.stime*1000/hertz, | |
466 | format1), | |
467 | val2cpustr(curstat->cpu.utime*1000/hertz, | |
468 | format2), | |
469 | val2memstr(curstat->mem.vgrow*1024, | |
470 | format3, KBFORMAT, 0, 0), | |
471 | val2memstr(curstat->mem.rgrow*1024, | |
472 | format4, KBFORMAT, 0, 0), | |
473 | val2memstr(curstat->dsk.rsz*512, | |
474 | format5, KBFORMAT, 0, 0), | |
475 | val2memstr(curstat->dsk.wsz*512, | |
476 | format6, KBFORMAT, 0, 0), | |
477 | curstat->gen.excode & ~(INT_MAX) ? | |
478 | 'N' : '-', | |
479 | '-', | |
480 | curstat->gen.state, | |
481 | perc, curstat->gen.name); | |
482 | } | |
483 | else | |
484 | { | |
485 | /* | |
486 | ** show active processes for conventional kernel | |
487 | ** | |
488 | ** determine the user-name of process | |
489 | */ | |
490 | if ( (pwd = getpwuid(curstat->gen.ruid)) ) | |
491 | { | |
492 | username = pwd->pw_name; | |
493 | } | |
494 | else | |
495 | { | |
496 | snprintf(usname, sizeof usname, "%d", | |
497 | curstat->gen.ruid); | |
498 | username = usname; | |
499 | } | |
500 | ||
501 | printg(genproclina3, | |
502 | curstat->gen.pid, | |
503 | val2cpustr(curstat->cpu.stime*1000/hertz, | |
504 | format1), | |
505 | val2cpustr(curstat->cpu.utime*1000/hertz, | |
506 | format2), | |
507 | val2memstr(curstat->mem.vgrow*1024, | |
508 | format3, KBFORMAT, 0, 0), | |
509 | val2memstr(curstat->mem.rgrow*1024, | |
510 | format4, KBFORMAT, 0, 0), | |
511 | username, | |
512 | curstat->gen.nthr, | |
513 | curstat->gen.excode & ~(INT_MAX) ? 'N' : '-', | |
514 | '-', | |
515 | curstat->gen.state, | |
516 | perc, curstat->gen.name); | |
517 | } | |
518 | } | |
519 | } | |
520 | else | |
521 | { | |
522 | /* | |
523 | ** show exited processes | |
524 | */ | |
525 | if (curstat->gen.pid == 0) | |
526 | printg(" ? "); | |
527 | else | |
528 | printg("%5d ", curstat->gen.pid); | |
529 | ||
530 | if (supportflags & PATCHSTAT) | |
531 | { | |
532 | /* | |
533 | ** show exited processes for patched kernel | |
534 | */ | |
535 | if (supportflags & PATCHACCT) | |
536 | { | |
537 | /* | |
538 | ** show exited processes for patched kernel | |
539 | ** including patches for accounting | |
540 | */ | |
541 | printg(genprocline1p, | |
542 | val2cpustr(curstat->cpu.stime*1000/hertz, | |
543 | format1), | |
544 | val2cpustr(curstat->cpu.utime*1000/hertz, | |
545 | format2), | |
546 | val2memstr(curstat->mem.vgrow*1024, | |
547 | format3, KBFORMAT, 0, 0), | |
548 | val2memstr(curstat->mem.rgrow*1024, | |
549 | format4, KBFORMAT, 0, 0), | |
550 | val2valstr(curstat->dsk.rio, | |
551 | format5, 5, avgval, nsecs), | |
552 | val2valstr(curstat->dsk.wio, | |
553 | format6, 5, avgval, nsecs), | |
554 | val2valstr(curstat->net.tcprcv + | |
555 | curstat->net.udprcv + | |
556 | curstat->net.rawrcv, | |
557 | format7, 4, avgval, nsecs), | |
558 | val2valstr(curstat->net.tcpsnd + | |
559 | curstat->net.udpsnd + | |
560 | curstat->net.rawsnd, | |
561 | format8, 4, avgval, nsecs), | |
562 | perc, curstat->gen.name); | |
563 | } | |
564 | else | |
565 | { | |
566 | /* | |
567 | ** show exited processes for patched kernel | |
568 | ** without patches for accounting | |
569 | */ | |
570 | printg(genprocline1, | |
571 | val2cpustr(curstat->cpu.stime*1000/hertz, | |
572 | format1), | |
573 | val2cpustr(curstat->cpu.utime*1000/hertz, | |
574 | format2), | |
575 | val2valstr(curstat->dsk.rio, | |
576 | format3, 6, avgval, nsecs), | |
577 | perc, curstat->gen.name); | |
578 | } | |
579 | } | |
580 | else | |
581 | { | |
582 | if (curstat->gen.excode & 0xff) | |
583 | { | |
584 | if (curstat->gen.excode & 0x80) | |
585 | exittype = 'C'; | |
586 | else | |
587 | exittype = 'S'; | |
588 | } | |
589 | else | |
590 | { | |
591 | exittype = 'E'; | |
592 | } | |
593 | ||
594 | if (supportflags & IOSTAT) | |
595 | { | |
596 | /* | |
597 | ** show exited processes for kernel with iostats | |
598 | */ | |
599 | printg(genprocline2, | |
600 | val2cpustr(curstat->cpu.stime*1000/hertz, | |
601 | format1), | |
602 | val2cpustr(curstat->cpu.utime*1000/hertz, | |
603 | format2), | |
604 | curstat->gen.excode & ~(INT_MAX) ? 'N' : '-', | |
605 | exittype, | |
606 | curstat->gen.excode & 0xff ? | |
607 | curstat->gen.excode & 0x7f : | |
608 | (curstat->gen.excode>>8) & 0xff, | |
609 | perc, curstat->gen.name); | |
610 | } | |
611 | else | |
612 | { | |
613 | /* | |
614 | ** show active processes for conventional kernel | |
615 | ** | |
616 | ** determine the user-name of process | |
617 | */ | |
618 | if ( (pwd = getpwuid(curstat->gen.ruid)) ) | |
619 | { | |
620 | username = pwd->pw_name; | |
621 | } | |
622 | else | |
623 | { | |
624 | snprintf(usname, sizeof usname, "%d", | |
625 | curstat->gen.ruid); | |
626 | username = usname; | |
627 | } | |
628 | ||
629 | printg(genprocline3, | |
630 | val2cpustr(curstat->cpu.stime*1000/hertz, | |
631 | format1), | |
632 | val2cpustr(curstat->cpu.utime*1000/hertz, | |
633 | format2), | |
634 | username, | |
635 | curstat->gen.excode & ~(INT_MAX) ? 'N' : '-', | |
636 | exittype, | |
637 | curstat->gen.excode & 0xff ? | |
638 | curstat->gen.excode & 0x7f : | |
639 | (curstat->gen.excode>>8) & 0xff, | |
640 | perc, curstat->gen.name); | |
641 | } | |
642 | } | |
643 | } | |
644 | } | |
645 | ||
646 | /* | |
647 | ** print a line of memory-figures about one process | |
648 | */ | |
649 | void | |
650 | showmemproc(struct pstat *curstat, double perc, int nsecs, int avgval) | |
651 | { | |
652 | char format1[16], format2[16]; | |
653 | char format3[16], format4[16]; | |
654 | char format5[16], format6[16]; | |
655 | char format7[16]; | |
656 | ||
657 | if (curstat->gen.state != 'E') | |
658 | { | |
659 | /* | |
660 | ** show process-info of active process | |
661 | */ | |
662 | printg(memproclina, | |
663 | curstat->gen.pid, | |
664 | val2valstr(curstat->mem.minflt, format1, 6, | |
665 | avgval, nsecs), | |
666 | val2valstr(curstat->mem.majflt, format2, 6, | |
667 | avgval, nsecs), | |
668 | val2memstr(curstat->mem.shtext*1024, format3, KBFORMAT, 0, 0), | |
669 | val2memstr(curstat->mem.vmem *1024, format4, KBFORMAT, 0, 0), | |
670 | val2memstr(curstat->mem.rmem *1024, format5, KBFORMAT, 0, 0), | |
671 | val2memstr(curstat->mem.vgrow *1024, format6, KBFORMAT, 0, 0), | |
672 | val2memstr(curstat->mem.rgrow *1024, format7, KBFORMAT, 0, 0), | |
673 | perc, curstat->gen.name); | |
674 | } | |
675 | else | |
676 | { | |
677 | /* | |
678 | ** show process-info of exited process | |
679 | */ | |
680 | if (supportflags & PATCHACCT) | |
681 | { | |
682 | printg(memproclinep, | |
683 | curstat->gen.pid, | |
684 | val2valstr(curstat->mem.minflt, format1, 6, | |
685 | avgval, nsecs), | |
686 | val2valstr(curstat->mem.majflt, format2, 6, | |
687 | avgval, nsecs), | |
688 | val2memstr(curstat->mem.vmem *1024, format3, KBFORMAT, 0, 0), | |
689 | val2memstr(curstat->mem.rmem *1024, format4, KBFORMAT, 0, 0), | |
690 | val2memstr(curstat->mem.vgrow *1024, format5, KBFORMAT, 0, 0), | |
691 | val2memstr(curstat->mem.rgrow *1024, format6, KBFORMAT, 0, 0), | |
692 | perc, curstat->gen.name); | |
693 | } | |
694 | else | |
695 | { | |
696 | if (curstat->gen.pid == 0) | |
697 | printg(" ? "); | |
698 | else | |
699 | printg("%5d ", curstat->gen.pid); | |
700 | ||
701 | printg(memprocline, | |
702 | val2valstr(curstat->mem.minflt, format1, 6, | |
703 | avgval, nsecs), | |
704 | val2valstr(curstat->mem.majflt, format2, 6, | |
705 | avgval, nsecs), | |
706 | perc, curstat->gen.name); | |
707 | } | |
708 | } | |
709 | } | |
710 | ||
711 | /* | |
712 | ** print a line of disk-figures about one process | |
713 | */ | |
714 | void | |
715 | showdskproc(struct pstat *curstat, double perc, int nsecs, int avgval) | |
716 | { | |
717 | char format1[16], format2[16], format3[16]; | |
718 | char format4[16], format5[16], format6[16]; | |
719 | unsigned int avgrsz, avgwsz; | |
720 | ||
721 | if (supportflags & PATCHSTAT) | |
722 | { | |
723 | avgrsz = curstat->dsk.rio ? | |
724 | curstat->dsk.rsz * 512LL / curstat->dsk.rio : 0; | |
725 | avgwsz = curstat->dsk.wio ? | |
726 | curstat->dsk.wsz * 512LL / curstat->dsk.wio : 0; | |
727 | ||
728 | if (curstat->gen.state != 'E') | |
729 | { | |
730 | /* | |
731 | ** show process-info of active process | |
732 | */ | |
733 | printg(dskproclina1, | |
734 | curstat->gen.pid, | |
735 | val2valstr(curstat->dsk.rio, | |
736 | format1, 9, avgval, nsecs), | |
737 | val2valstr(avgrsz, format2, 7, 0, 0), | |
738 | val2memstr(curstat->dsk.rsz*512LL, | |
739 | format3, KBFORMAT, avgval, nsecs), | |
740 | val2valstr(curstat->dsk.wio, | |
741 | format4, 9, avgval, nsecs), | |
742 | val2valstr(avgwsz, format5, 7, 0, 0), | |
743 | val2memstr(curstat->dsk.wsz*512LL, | |
744 | format6, KBFORMAT, avgval, nsecs), | |
745 | perc, curstat->gen.name); | |
746 | } | |
747 | else | |
748 | { | |
749 | /* | |
750 | ** show process-info of exited process | |
751 | */ | |
752 | if (supportflags & PATCHACCT) | |
753 | { | |
754 | printg(dskprocline1p, | |
755 | curstat->gen.pid, | |
756 | val2valstr(curstat->dsk.rio, | |
757 | format1, 9, avgval, nsecs), | |
758 | val2valstr(avgrsz, format2, 7, 0, 0), | |
759 | val2memstr(curstat->dsk.rsz * 512LL, | |
760 | format3, KBFORMAT, avgval, nsecs), | |
761 | val2valstr(curstat->dsk.wio, | |
762 | format4, 9, avgval, nsecs), | |
763 | val2valstr(avgwsz, format5, 7, 0, 0), | |
764 | val2memstr(curstat->dsk.wsz * 512LL, | |
765 | format6, KBFORMAT, avgval, nsecs), | |
766 | perc, curstat->gen.name); | |
767 | } | |
768 | else | |
769 | { | |
770 | if (curstat->gen.pid == 0) | |
771 | printg(" ? "); | |
772 | else | |
773 | printg("%5d ", curstat->gen.pid); | |
774 | ||
775 | printg(dskprocline1, | |
776 | val2valstr(curstat->dsk.rio, | |
777 | format1, 9, avgval, nsecs), | |
778 | perc, curstat->gen.name); | |
779 | } | |
780 | } | |
781 | } | |
782 | else | |
783 | { | |
784 | if (supportflags & IOSTAT) | |
785 | { | |
786 | if (curstat->gen.state != 'E') | |
787 | { | |
788 | /* | |
789 | ** show process-info of active process | |
790 | */ | |
791 | printg(dskproclina2, | |
792 | curstat->gen.pid, | |
793 | val2memstr(curstat->dsk.rsz*512LL, | |
794 | format1, KBFORMAT, avgval, nsecs), | |
795 | val2memstr(curstat->dsk.wsz*512LL, | |
796 | format2, KBFORMAT, avgval, nsecs), | |
797 | val2memstr(curstat->dsk.cwsz*512LL, | |
798 | format3, KBFORMAT, avgval, nsecs), | |
799 | perc, curstat->gen.name); | |
800 | } | |
801 | else | |
802 | { | |
803 | /* | |
804 | ** show process-info of exited process | |
805 | */ | |
806 | if (curstat->gen.pid == 0) | |
807 | printg(" ? "); | |
808 | else | |
809 | printg("%5d ", curstat->gen.pid); | |
810 | ||
811 | printg(dskprocline2, | |
812 | perc, curstat->gen.name); | |
813 | } | |
814 | } | |
815 | } | |
816 | } | |
817 | ||
818 | /* | |
819 | ** print a line of network-figures about one process | |
820 | */ | |
821 | void | |
822 | shownetproc(struct pstat *curstat, double perc, int nsecs, int avgval) | |
823 | { | |
824 | char format1[16], format2[16], format3[16], format4[16]; | |
825 | char format5[16], format6[16], format7[16], format8[16]; | |
826 | int avgtcpr, avgtcps, avgudpr, avgudps; | |
827 | ||
828 | avgtcpr = curstat->net.tcprcv ? | |
829 | curstat->net.tcprsz / curstat->net.tcprcv : 0; | |
830 | avgtcps = curstat->net.tcpsnd ? | |
831 | curstat->net.tcpssz / curstat->net.tcpsnd : 0; | |
832 | avgudpr = curstat->net.udprcv ? | |
833 | curstat->net.udprsz / curstat->net.udprcv : 0; | |
834 | avgudps = curstat->net.udpsnd ? | |
835 | curstat->net.udpssz / curstat->net.udpsnd : 0; | |
836 | ||
837 | if (curstat->gen.state != 'E') | |
838 | { | |
839 | /* | |
840 | ** show process-info of active process | |
841 | */ | |
842 | printg(netproclina, | |
843 | curstat->gen.pid, | |
844 | val2valstr(curstat->net.tcprcv, format1, 6, | |
845 | avgval, nsecs), | |
846 | val2valstr(avgtcpr, format2, 4, 0, 0), | |
847 | val2valstr(curstat->net.tcpsnd, format3, 6, | |
848 | avgval, nsecs), | |
849 | val2valstr(avgtcps, format4, 4, 0, 0), | |
850 | val2valstr(curstat->net.udprcv, format5, 6, | |
851 | avgval, nsecs), | |
852 | val2valstr(avgudpr, format6, 4, 0, 0), | |
853 | val2valstr(curstat->net.udpsnd, format7, 6, | |
854 | avgval, nsecs), | |
855 | val2valstr(avgudps, format8, 4, 0, 0), | |
856 | curstat->net.rawrcv, | |
857 | curstat->net.rawsnd, | |
858 | perc, curstat->gen.name); | |
859 | } | |
860 | else | |
861 | { | |
862 | /* | |
863 | ** show process-info of exited process | |
864 | */ | |
865 | if (supportflags & PATCHACCT) | |
866 | { | |
867 | printg(netproclinep, | |
868 | curstat->gen.pid, | |
869 | val2valstr(curstat->net.tcprcv, format1, 6, | |
870 | avgval, nsecs), | |
871 | val2valstr(avgtcpr, format2, 4, 0, 0), | |
872 | val2valstr(curstat->net.tcpsnd, format3, 6, | |
873 | avgval, nsecs), | |
874 | val2valstr(avgtcps, format4, 4, 0, 0), | |
875 | val2valstr(curstat->net.udprcv, format5, 6, | |
876 | avgval, nsecs), | |
877 | val2valstr(avgudpr, format6, 4, 0, 0), | |
878 | val2valstr(curstat->net.udpsnd, format7, 6, | |
879 | avgval, nsecs), | |
880 | val2valstr(avgudps, format8, 4, 0, 0), | |
881 | curstat->net.rawrcv, | |
882 | curstat->net.rawsnd, | |
883 | perc, curstat->gen.name); | |
884 | } | |
885 | else | |
886 | { | |
887 | if (curstat->gen.pid == 0) | |
888 | printg(" ? "); | |
889 | else | |
890 | printg("%5d ", curstat->gen.pid); | |
891 | ||
892 | printg(netprocline, perc, curstat->gen.name); | |
893 | } | |
894 | } | |
895 | } | |
896 | ||
897 | /* | |
898 | ** print a line of total resource consumption per user | |
899 | */ | |
900 | void | |
901 | showtotuser(struct pstat *curstat, double perc, int nsecs, int avgval) | |
902 | { | |
903 | struct passwd *pwd; | |
904 | char numuser[16], *username; | |
905 | ||
906 | char format1[16], format2[16]; | |
907 | char format3[16], format4[16]; | |
908 | char format5[16], format6[16]; | |
909 | char format7[16], format8[16]; | |
910 | char format9[16]; | |
911 | ||
912 | /* | |
913 | ** determine the user-name of process | |
914 | */ | |
915 | if ( (pwd = getpwuid(curstat->gen.ruid)) == NULL) | |
916 | { | |
917 | snprintf(numuser, sizeof numuser, "%u", curstat->gen.ruid); | |
918 | username = numuser; | |
919 | } | |
920 | else | |
921 | { | |
922 | username = pwd->pw_name; | |
923 | } | |
924 | ||
925 | printg(totuserlin, | |
926 | val2valstr(curstat->gen.pid, format1, 6, 0, 0), | |
927 | val2cpustr(curstat->cpu.stime*1000/hertz, format2), | |
928 | val2cpustr(curstat->cpu.utime*1000/hertz, format3), | |
929 | val2memstr(curstat->mem.vmem *1024, format4, KBFORMAT, 0, 0), | |
930 | val2memstr(curstat->mem.rmem *1024, format5, KBFORMAT, 0, 0), | |
931 | val2valstr(curstat->dsk.rio, format6, 5, | |
932 | avgval, nsecs), | |
933 | val2valstr(curstat->dsk.wio, format7, 5, | |
934 | avgval, nsecs), | |
935 | val2valstr(curstat->net.tcprcv + | |
936 | curstat->net.udprcv + | |
937 | curstat->net.rawrcv, format8, 4, | |
938 | avgval, nsecs), | |
939 | val2valstr(curstat->net.tcpsnd + | |
940 | curstat->net.udpsnd + | |
941 | curstat->net.rawsnd, format9, 4, | |
942 | avgval, nsecs), | |
943 | perc, username); | |
944 | } | |
945 | ||
946 | /* | |
947 | ** print a line of total resource consumption per program (process name) | |
948 | */ | |
949 | void | |
950 | showtotproc(struct pstat *curstat, double perc, int nsecs, int avgval) | |
951 | { | |
952 | char format1[16], format2[16]; | |
953 | char format3[16], format4[16]; | |
954 | char format5[16], format6[16]; | |
955 | char format7[16], format8[16]; | |
956 | char format9[16]; | |
957 | ||
958 | printg(totproclin, | |
959 | val2valstr(curstat->gen.pid, format1, 6, 0, 0), | |
960 | val2cpustr(curstat->cpu.stime*1000/hertz, format2), | |
961 | val2cpustr(curstat->cpu.utime*1000/hertz, format3), | |
962 | val2memstr(curstat->mem.vmem *1024, format4, KBFORMAT, 0, 0), | |
963 | val2memstr(curstat->mem.rmem *1024, format5, KBFORMAT, 0, 0), | |
964 | val2valstr(curstat->dsk.rio, format6, 5, | |
965 | avgval, nsecs), | |
966 | val2valstr(curstat->dsk.wio, format7, 5, | |
967 | avgval, nsecs), | |
968 | val2valstr(curstat->net.tcprcv + | |
969 | curstat->net.udprcv + | |
970 | curstat->net.rawrcv, format8, 4, | |
971 | avgval, nsecs), | |
972 | val2valstr(curstat->net.tcpsnd + | |
973 | curstat->net.udpsnd + | |
974 | curstat->net.rawsnd, format9, 4, | |
975 | avgval, nsecs), | |
976 | perc, curstat->gen.name); | |
977 | } | |
978 | ||
979 | /* | |
980 | ** print a line of (more or less) static info about one process | |
981 | */ | |
982 | void | |
983 | showvarproc(struct pstat *curstat, double perc, int nsecs, int avgval) | |
984 | { | |
985 | char format1[16], format2[16]; | |
986 | struct passwd *pwd; | |
987 | struct group *grp; | |
988 | char *username, *groupname; | |
989 | char usname[16], grname[16]; | |
990 | char exittype; | |
991 | ||
992 | /* | |
993 | ** determine the user- and group-name of the process | |
994 | */ | |
995 | if ( (pwd = getpwuid(curstat->gen.ruid)) ) | |
996 | { | |
997 | username = pwd->pw_name; | |
998 | } | |
999 | else | |
1000 | { | |
1001 | snprintf(usname, sizeof usname, "%d", curstat->gen.ruid); | |
1002 | username = usname; | |
1003 | } | |
1004 | ||
1005 | if ( (grp = getgrgid(curstat->gen.rgid)) ) | |
1006 | { | |
1007 | groupname = grp->gr_name; | |
1008 | } | |
1009 | else | |
1010 | { | |
1011 | snprintf(grname, sizeof grname, "%d", curstat->gen.rgid); | |
1012 | groupname = grname; | |
1013 | } | |
1014 | ||
1015 | /* | |
1016 | ** show process-info | |
1017 | */ | |
1018 | if (curstat->gen.state != 'E') | |
1019 | { | |
1020 | /* | |
1021 | ** show process-info of active process | |
1022 | */ | |
1023 | printg(varproclina, | |
1024 | curstat->gen.pid, | |
1025 | curstat->gen.ppid, | |
1026 | username, | |
1027 | groupname, | |
1028 | convdate(curstat->gen.btime, format1), | |
1029 | convtime(curstat->gen.btime, format2), | |
1030 | curstat->gen.excode & ~(INT_MAX) ? 'N' : '-', | |
1031 | '-', | |
1032 | curstat->gen.state, | |
1033 | perc, curstat->gen.name); | |
1034 | } | |
1035 | else | |
1036 | { | |
1037 | /* | |
1038 | ** show process-info of exited process | |
1039 | */ | |
1040 | if (curstat->gen.pid == 0) | |
1041 | printg(" ? "); | |
1042 | else | |
1043 | printg("%5d ", curstat->gen.pid); | |
1044 | ||
1045 | if (curstat->gen.excode & 0xff) | |
1046 | { | |
1047 | if (curstat->gen.excode & 0x80) | |
1048 | exittype = 'C'; | |
1049 | else | |
1050 | exittype = 'S'; | |
1051 | } | |
1052 | else | |
1053 | { | |
1054 | exittype = 'E'; | |
1055 | } | |
1056 | ||
1057 | printg(varprocline, | |
1058 | curstat->gen.ppid, | |
1059 | username, | |
1060 | groupname, | |
1061 | convdate(curstat->gen.btime, format1), | |
1062 | convtime(curstat->gen.btime, format2), | |
1063 | curstat->gen.excode & ~(INT_MAX) ? 'N' : '-', | |
1064 | exittype, | |
1065 | curstat->gen.excode & 0xff ? | |
1066 | curstat->gen.excode & 0x7f : | |
1067 | (curstat->gen.excode>>8) & 0xff, | |
1068 | perc, curstat->gen.name); | |
1069 | } | |
1070 | } | |
1071 | ||
1072 | /* | |
1073 | ** print a line containing the (almost) full command line | |
1074 | */ | |
1075 | void | |
1076 | showcmdproc(struct pstat *curstat, double perc, int nsecs, int avgval) | |
1077 | { | |
1078 | /* | |
1079 | ** show process-info | |
1080 | */ | |
1081 | if (curstat->gen.state != 'E') | |
1082 | { | |
1083 | /* | |
1084 | ** show process-info of active process | |
1085 | */ | |
1086 | printg(cmdproclina, | |
1087 | curstat->gen.pid, | |
1088 | perc, | |
1089 | curstat->gen.cmdline[0] ? | |
1090 | curstat->gen.cmdline : curstat->gen.name); | |
1091 | } | |
1092 | else | |
1093 | { | |
1094 | /* | |
1095 | ** show process-info of exited process | |
1096 | */ | |
1097 | if (curstat->gen.pid == 0) | |
1098 | printg(" ? "); | |
1099 | else | |
1100 | printg("%5d ", curstat->gen.pid); | |
1101 | ||
1102 | printg(cmdprocline, | |
1103 | perc, | |
1104 | curstat->gen.cmdline[0] ? | |
1105 | curstat->gen.cmdline : curstat->gen.name); | |
1106 | } | |
1107 | } | |
1108 | ||
1109 | /* | |
1110 | ** print a line of scheduling info about one process | |
1111 | */ | |
1112 | #define SCHED_NORMAL 0 | |
1113 | #define SCHED_FIFO 1 | |
1114 | #define SCHED_RR 2 | |
1115 | ||
1116 | void | |
1117 | showschproc(struct pstat *curstat, double perc, int nsecs, int avgval) | |
1118 | { | |
1119 | char *pol, exittype; | |
1120 | ||
1121 | switch (curstat->cpu.policy) | |
1122 | { | |
1123 | case SCHED_NORMAL: | |
1124 | pol = "norm"; | |
1125 | break; | |
1126 | case SCHED_RR: | |
1127 | pol = "rr "; | |
1128 | break; | |
1129 | case SCHED_FIFO: | |
1130 | pol = "fifo"; | |
1131 | break; | |
1132 | default: | |
1133 | pol = "?"; | |
1134 | } | |
1135 | ||
1136 | /* | |
1137 | ** show process-info | |
1138 | */ | |
1139 | if (curstat->gen.state != 'E') | |
1140 | { | |
1141 | /* | |
1142 | ** show process-info of active process | |
1143 | */ | |
1144 | printg(schproclina, | |
1145 | curstat->gen.pid, | |
1146 | curstat->gen.nthrrun, | |
1147 | curstat->gen.nthrslpi, | |
1148 | curstat->gen.nthrslpu, | |
1149 | pol, | |
1150 | curstat->cpu.nice, | |
1151 | curstat->cpu.prio, | |
1152 | curstat->cpu.rtprio, | |
1153 | curstat->cpu.curcpu, | |
1154 | curstat->gen.excode & ~(INT_MAX) ? "N-" : "--", | |
1155 | curstat->gen.state, | |
1156 | perc, curstat->gen.name); | |
1157 | } | |
1158 | else | |
1159 | { | |
1160 | /* | |
1161 | ** show process-info of exited process | |
1162 | */ | |
1163 | if (curstat->gen.pid == 0) | |
1164 | printg(" ?"); | |
1165 | else | |
1166 | printg("%5d", curstat->gen.pid); | |
1167 | ||
1168 | if (curstat->gen.excode & 0xff) | |
1169 | { | |
1170 | if (curstat->gen.excode & 0x80) | |
1171 | exittype = 'C'; | |
1172 | else | |
1173 | exittype = 'S'; | |
1174 | } | |
1175 | else | |
1176 | { | |
1177 | exittype = 'E'; | |
1178 | } | |
1179 | ||
1180 | printg(schprocline, | |
1181 | curstat->gen.excode & ~(INT_MAX) ? 'N' : '-', | |
1182 | exittype, | |
1183 | curstat->gen.excode & 0xff ? | |
1184 | curstat->gen.excode & 0x7f : | |
1185 | (curstat->gen.excode>>8) & 0xff, | |
1186 | perc, curstat->gen.name); | |
1187 | } | |
763 | pricumproc(struct pstat *pstat, struct sstat *sstat, | |
764 | int nact, int nproc, int ntrun, int ntslpi, int ntslpu, int nzomb, | |
765 | int nexit, int avgval, int nsecs) | |
766 | { | |
767 | ||
768 | static int firsttime=1; | |
769 | ||
770 | if (firsttime) | |
771 | { | |
772 | firsttime=0; | |
773 | ||
774 | if (sysprcline[0].f == 0) | |
775 | { | |
776 | make_sys_prints(sysprcline, MAXITEMS, | |
777 | "PRCSYS:8 " | |
778 | "PRCUSER:8 " | |
779 | "BLANKBOX:0 " | |
780 | "PRCNPROC:7 " | |
781 | "PRCNRUNNING:5 " | |
782 | "PRCNSLEEPING:5 " | |
783 | "PRCNDSLEEPING:5 " | |
784 | "PRCNZOMBIE:5 " | |
785 | "PRCCLONES:4 " | |
786 | "BLANKBOX:0 " | |
787 | "PRCNNEXIT:6", prcsyspdefs, "built in sysprcline"); | |
788 | } | |
789 | if (allcpuline[0].f == 0) | |
790 | { | |
791 | make_sys_prints(allcpuline, MAXITEMS, | |
792 | "CPUSYS:9 " | |
793 | "CPUUSER:8 " | |
794 | "CPUIRQ:5 " | |
795 | "BLANKBOX:0 " | |
796 | "CPUIDLE:6 " | |
797 | "CPUWAIT:6 " | |
798 | "BLANKBOX:0 " | |
799 | "CPUSTEAL:2 " | |
800 | "CPUGUEST:3 " | |
801 | "CPUFREQ:4 " | |
802 | "CPUSCALE:4 ", cpusyspdefs, "built in allcpuline"); | |
803 | } | |
804 | ||
805 | if (indivcpuline[0].f == 0) | |
806 | { | |
807 | make_sys_prints(indivcpuline, MAXITEMS, | |
808 | "CPUISYS:9 " | |
809 | "CPUIUSER:8 " | |
810 | "CPUIIRQ:5 " | |
811 | "BLANKBOX:0 " | |
812 | "CPUIIDLE:6 " | |
813 | "CPUIWAIT:6 " | |
814 | "BLANKBOX:0 " | |
815 | "CPUISTEAL:2 " | |
816 | "CPUIGUEST:3 " | |
817 | "CPUIFREQ:4 " | |
818 | "CPUISCALE:4 ", cpisyspdefs, "built in indivcpuline"); | |
819 | } | |
820 | ||
821 | if (cplline[0].f == 0) | |
822 | { | |
823 | make_sys_prints(cplline, MAXITEMS, | |
824 | "CPLAVG1:4 " | |
825 | "CPLAVG5:3 " | |
826 | "CPLAVG15:2 " | |
827 | "BLANKBOX:0 " | |
828 | "CPLCSW:6 " | |
829 | "CPLINTR:5 " | |
830 | "BLANKBOX:0 " | |
831 | "CPLNUMCPU:1", cplsyspdefs, "built in cplline"); | |
832 | } | |
833 | ||
834 | if (memline[0].f == 0) | |
835 | { | |
836 | make_sys_prints(memline, MAXITEMS, | |
837 | "MEMTOT:2 " | |
838 | "MEMFREE:5 " | |
839 | "MEMCACHE:3 " | |
840 | "MEMDIRTY:1 " | |
841 | "MEMBUFFER:3 " | |
842 | "MEMSLAB:3 " | |
843 | "BLANKBOX:0 " | |
844 | "BLANKBOX:0 " | |
845 | "BLANKBOX:0 " | |
846 | "BLANKBOX:0", memsyspdefs, "built in memline"); | |
847 | } | |
848 | if (swpline[0].f == 0) | |
849 | { | |
850 | make_sys_prints(swpline, MAXITEMS, | |
851 | "SWPTOT:3 " | |
852 | "SWPFREE:4 " | |
853 | "BLANKBOX:0 " | |
854 | "BLANKBOX:0 " | |
855 | "BLANKBOX:0 " | |
856 | "BLANKBOX:0 " | |
857 | "BLANKBOX:0 " | |
858 | "BLANKBOX:0 " | |
859 | "SWPCOMMITTED:5 " | |
860 | "SWPCOMMITLIM:6", swpsyspdefs, "built in swpline"); | |
861 | } | |
862 | if (pagline[0].f == 0) | |
863 | { | |
864 | make_sys_prints(pagline, MAXITEMS, | |
865 | "PAGSCAN:3 " | |
866 | "PAGSTALL:1 " | |
867 | "BLANKBOX:0 " | |
868 | "PAGSWIN:4 " | |
869 | "PAGSWOUT:3", pagsyspdefs, "built in pagline"); | |
870 | } | |
871 | if (dskline[0].f == 0) | |
872 | { | |
873 | make_sys_prints(dskline, MAXITEMS, | |
874 | "DSKNAME:8 " | |
875 | "DSKBUSY:7 " | |
876 | "DSKNREAD:6 " | |
877 | "DSKNWRITE:6 " | |
878 | "DSKKBPERRD:4 " | |
879 | "DSKKBPERWR:4 " | |
880 | "DSKMBPERSECRD:5 " | |
881 | "DSKMBPERSECWR:5 " | |
882 | "DSKAVQUEUE:1 " | |
883 | "DSKAVIO:5", dsksyspdefs, "built in dskline"); | |
884 | } | |
885 | if (nettransportline[0].f == 0) | |
886 | { | |
887 | make_sys_prints(nettransportline, MAXITEMS, | |
888 | "NETTRANSPORT:9 " | |
889 | "NETTCPI:8 " | |
890 | "NETTCPO:8 " | |
891 | "NETUDPI:8 " | |
892 | "NETUDPO:8 " | |
893 | "NETTCPACTOPEN:6 " | |
894 | "NETTCPPASVOPEN:5 " | |
895 | "NETTCPRETRANS:4 " | |
896 | "NETTCPINERR:3 " | |
897 | "NETTCPORESET:2 " | |
898 | "NETUDPNOPORT:1 " | |
899 | "NETUDPINERR:3", nettranssyspdefs, "built in nettransportline"); | |
900 | } | |
901 | if (netnetline[0].f == 0) | |
902 | { | |
903 | make_sys_prints(netnetline, MAXITEMS, | |
904 | "NETNETWORK:5 " | |
905 | "NETIPI:4 " | |
906 | "NETIPO:4 " | |
907 | "NETIPFRW:4 " | |
908 | "NETIPDELIV:4 " | |
909 | "BLANKBOX:0 " | |
910 | "BLANKBOX:0 " | |
911 | "BLANKBOX:0 " | |
912 | "NETICMPIN:1 " | |
913 | "NETICMPOUT:1 ", netnetsyspdefs, "built in netnetline"); | |
914 | } | |
915 | if (netinterfaceline[0].f == 0) | |
916 | { | |
917 | make_sys_prints(netinterfaceline, MAXITEMS, | |
918 | "NETNAME:8 " | |
919 | "NETPCKI:7 " | |
920 | "NETPCKO:7 " | |
921 | "NETSPEEDIN:6 " | |
922 | "NETSPEEDOUT:6 " | |
923 | "NETCOLLIS:3 " | |
924 | "NETMULTICASTIN:2 " | |
925 | "NETRCVERR:5 " | |
926 | "NETSNDERR:5 " | |
927 | "NETRCVDROP:4 " | |
928 | "NETSNDDROP:4", netintfsyspdefs, "built in netinterfaceline"); | |
929 | } | |
930 | } // firsttime | |
931 | ||
932 | ||
933 | int i; | |
934 | extraparam extra; | |
935 | ||
936 | ||
937 | for (i=0, extra.totut=extra.totst=0; i < nact; i++) | |
938 | { | |
939 | extra.totut += (pstat+i)->cpu.utime; | |
940 | extra.totst += (pstat+i)->cpu.stime; | |
941 | } | |
942 | ||
943 | extra.nproc = nproc; | |
944 | extra.ntrun = ntrun; | |
945 | extra.ntslpi = ntslpi; | |
946 | extra.ntslpu = ntslpu; | |
947 | extra.nzomb = nzomb; | |
948 | extra.nexit = nexit; | |
949 | extra.avgval = avgval; | |
950 | extra.nsecs = nsecs; | |
951 | ||
952 | move(1,0); | |
953 | showsysline(sysprcline, sstat, &extra, "PRC", 0, 0); | |
954 | } | |
955 | ||
956 | void | |
957 | setunavailactive(proc_printdef *item) | |
958 | { | |
959 | switch (item->width) | |
960 | { | |
961 | case 4: | |
962 | item->doactiveconvert=procprt_NOTAVAIL_4; | |
963 | break; | |
964 | case 5: | |
965 | item->doactiveconvert=procprt_NOTAVAIL_5; | |
966 | break; | |
967 | case 6: | |
968 | item->doactiveconvert=procprt_NOTAVAIL_6; | |
969 | break; | |
970 | case 7: | |
971 | item->doactiveconvert=procprt_NOTAVAIL_7; | |
972 | break; | |
973 | } | |
974 | } | |
975 | ||
976 | void | |
977 | setunavailexit(proc_printdef *item) | |
978 | { | |
979 | switch (item->width) | |
980 | { | |
981 | case 4: | |
982 | item->doexitconvert=procprt_NOTAVAIL_4; | |
983 | break; | |
984 | case 5: | |
985 | item->doexitconvert=procprt_NOTAVAIL_5; | |
986 | break; | |
987 | case 6: | |
988 | item->doexitconvert=procprt_NOTAVAIL_6; | |
989 | break; | |
990 | case 7: | |
991 | item->doexitconvert=procprt_NOTAVAIL_7; | |
992 | break; | |
993 | } | |
994 | } | |
995 | ||
996 | ||
997 | void | |
998 | setunavail(proc_printdef *item) | |
999 | { | |
1000 | setunavailactive(item); | |
1001 | setunavailexit(item); | |
1188 | 1002 | } |
1189 | 1003 | |
1190 | 1004 | /* |
1193 | 1007 | void |
1194 | 1008 | priphead(int curlist, int totlist, char showtype, char showorder, char autosort) |
1195 | 1009 | { |
1196 | char columnprefix; | |
1197 | int order = showorder; | |
1198 | ||
1199 | /* | |
1200 | ** determine the prefix for the sorting-column | |
1201 | ** to indicate automatic mode | |
1202 | */ | |
1203 | if (autosort) | |
1204 | columnprefix = 'A'; | |
1205 | else | |
1206 | columnprefix = ' '; | |
1207 | ||
1208 | /* | |
1209 | ** print the header line | |
1210 | */ | |
1211 | switch (showtype) | |
1212 | { | |
1213 | case MPROCGEN: | |
1214 | if (supportflags & PATCHSTAT) | |
1215 | { | |
1216 | printg(genprochdr1, columnprefix, | |
1217 | columnhead[order], curlist, totlist); | |
1218 | } | |
1219 | else | |
1220 | { | |
1221 | if (supportflags & IOSTAT) | |
1222 | printg(genprochdr2, columnprefix, | |
1223 | columnhead[order], curlist, totlist); | |
1224 | else | |
1225 | printg(genprochdr3, columnprefix, | |
1226 | columnhead[order], curlist, totlist); | |
1227 | } | |
1228 | break; | |
1229 | ||
1230 | case MPROCMEM: | |
1231 | printg(memprochdr, columnprefix, columnhead[order], | |
1232 | curlist, totlist); | |
1233 | break; | |
1234 | ||
1235 | case MPROCDSK: | |
1236 | if (supportflags & PATCHSTAT) | |
1237 | { | |
1238 | printg(dskprochdr1, columnprefix, columnhead[order], | |
1239 | curlist, totlist); | |
1240 | } | |
1241 | else | |
1242 | { | |
1243 | if (supportflags & IOSTAT) | |
1244 | printg(dskprochdr2, columnprefix, | |
1245 | columnhead[order], curlist, totlist); | |
1246 | } | |
1247 | break; | |
1248 | ||
1249 | case MPROCNET: | |
1250 | printg(netprochdr, columnprefix, columnhead[order], | |
1251 | curlist, totlist); | |
1252 | break; | |
1253 | ||
1254 | case MPROCVAR: | |
1255 | printg(varprochdr, columnprefix, columnhead[order], | |
1256 | curlist, totlist); | |
1257 | break; | |
1258 | ||
1259 | case MPROCARG: | |
1260 | printg(cmdprochdr, columnprefix, columnhead[order], | |
1261 | curlist, totlist); | |
1262 | break; | |
1263 | ||
1264 | case MPROCSCH: | |
1265 | printg(schprochdr, columnprefix, columnhead[order], | |
1266 | curlist, totlist); | |
1267 | break; | |
1268 | ||
1269 | case MCUMUSER: | |
1270 | printg(totuserhdr, columnprefix, columnhead[order], | |
1271 | curlist, totlist); | |
1272 | break; | |
1273 | ||
1274 | case MCUMPROC: | |
1275 | printg(totprochdr, columnprefix, columnhead[order], | |
1276 | curlist, totlist); | |
1277 | break; | |
1278 | } | |
1010 | char columnprefix; | |
1011 | static int firsttime=1; | |
1012 | ||
1013 | if (firsttime) | |
1014 | { | |
1015 | // select disk, net functions | |
1016 | if (supportflags & PATCHACCT) | |
1017 | { | |
1018 | // disk/net patch and accounting patch | |
1019 | make_proc_prints(genprocs, MAXITEMS, | |
1020 | "PID:10 SYSCPU:9 USRCPU:9 " | |
1021 | "VGROW:8 RGROW:8 " | |
1022 | "RDDSK:7 WRDSK:7 " | |
1023 | "RNET:6 SNET:6 " | |
1024 | "S:5 SORTITEM:10 CMD:10", | |
1025 | "built-in genprocs"); | |
1026 | make_proc_prints(dskprocs, MAXITEMS, | |
1027 | "PID:10 RDDSK:9 AVGRSZ:8 TOTRSZ:7 " | |
1028 | "WRDSK:9 AVGWSZ:8 TOTWSZ:7 " | |
1029 | "SORTITEM:10 CMD:10", | |
1030 | "built-in dskprocs"); | |
1031 | ||
1032 | /* Set correct disk routines */ | |
1033 | procprt_RDDSK.doactiveconvert=procprt_NRDDSK_ae; | |
1034 | procprt_RDDSK.doexitconvert=procprt_NRDDSK_ae; | |
1035 | procprt_WRDSK.doactiveconvert=procprt_NWRDSK_a; | |
1036 | procprt_WRDSK.doexitconvert=procprt_NWRDSK_a; | |
1037 | ||
1038 | /* make IOSTAT items unavailable */ | |
1039 | setunavail(&procprt_WCANCEL_IOSTAT); | |
1040 | ||
1041 | /* Set correct net routines */ | |
1042 | procprt_RNET.doexitconvert=procprt_RNET_a; | |
1043 | procprt_SNET.doexitconvert=procprt_SNET_a; | |
1044 | procprt_TCPSND.doexitconvert=procprt_TCPSND_a; | |
1045 | procprt_TCPRCV.doexitconvert=procprt_TCPRCV_a; | |
1046 | procprt_RAWSND.doexitconvert=procprt_RAWSND_a; | |
1047 | procprt_RAWRCV.doexitconvert=procprt_RAWRCV_a; | |
1048 | procprt_UDPSND.doexitconvert=procprt_UDPSND_a; | |
1049 | procprt_UDPRCV.doexitconvert=procprt_UDPRCV_a; | |
1050 | procprt_TCPSASZ.doexitconvert=procprt_TCPSASZ_a; | |
1051 | procprt_TCPRASZ.doexitconvert=procprt_TCPRASZ_a; | |
1052 | procprt_UDPSASZ.doexitconvert=procprt_UDPSASZ_a; | |
1053 | procprt_UDPRASZ.doexitconvert=procprt_UDPRASZ_a; | |
1054 | } | |
1055 | else if (supportflags & PATCHSTAT) | |
1056 | { | |
1057 | // just the disk/net patch, NO accounting patch | |
1058 | make_proc_prints(genprocs, MAXITEMS, | |
1059 | "PID:10 SYSCPU:9 USRCPU:9 " | |
1060 | "VGROW:8 RGROW:8 " | |
1061 | "RDDSK:7 WRDSK:7 " | |
1062 | "RNET:6 SNET:6 S:5 " | |
1063 | "SORTITEM:10 CMD:10", | |
1064 | "built-in genprocs"); | |
1065 | make_proc_prints(dskprocs, MAXITEMS, | |
1066 | "PID:10 RDDSK:9 AVGRSZ:8 TOTRSZ:7 " | |
1067 | "WRDSK:9 AVGWSZ:8 TOTWSZ:7 " | |
1068 | "SORTITEM:10 CMD:10", | |
1069 | "built-in dskprocs"); | |
1070 | ||
1071 | /* Set correct disk routines */ | |
1072 | procprt_RDDSK.doactiveconvert=procprt_NRDDSK_ae; | |
1073 | procprt_RDDSK.doexitconvert=procprt_NRDDSK_e; | |
1074 | procprt_WRDSK.doactiveconvert=procprt_NWRDSK_a; | |
1075 | procprt_WRDSK.doexitconvert=procprt_NWRDSK_e; | |
1076 | ||
1077 | /* make IOSTAT items unavailable */ | |
1078 | setunavail(&procprt_WCANCEL_IOSTAT); | |
1079 | ||
1080 | /* make exit disk data unavailable */ | |
1081 | setunavailexit(&procprt_TOTRSZ); | |
1082 | setunavailexit(&procprt_TOTWSZ); | |
1083 | ||
1084 | /* Set correct net routines */ | |
1085 | procprt_RNET.doexitconvert=procprt_RNET_e; | |
1086 | procprt_SNET.doexitconvert=procprt_SNET_e; | |
1087 | procprt_TCPSND.doexitconvert=procprt_TCPSND_e; | |
1088 | procprt_TCPRCV.doexitconvert=procprt_TCPRCV_e; | |
1089 | procprt_RAWSND.doexitconvert=procprt_RAWSND_e; | |
1090 | procprt_RAWRCV.doexitconvert=procprt_RAWRCV_e; | |
1091 | procprt_UDPSND.doexitconvert=procprt_UDPSND_e; | |
1092 | procprt_UDPRCV.doexitconvert=procprt_UDPRCV_e; | |
1093 | procprt_TCPSASZ.doexitconvert=procprt_TCPSASZ_e; | |
1094 | procprt_TCPRASZ.doexitconvert=procprt_TCPRASZ_e; | |
1095 | procprt_UDPSASZ.doexitconvert=procprt_UDPSASZ_e; | |
1096 | procprt_UDPRASZ.doexitconvert=procprt_UDPRASZ_e; | |
1097 | } | |
1098 | else if (supportflags & IOSTAT) | |
1099 | { | |
1100 | // No patches, iostat data is available | |
1101 | make_proc_prints(genprocs, MAXITEMS, | |
1102 | "PID:10 RUID:3 EUID:2 THR:4 " | |
1103 | "SYSCPU:9 USRCPU:9 " | |
1104 | "VGROW:8 RGROW:8 " | |
1105 | "RDDSK:7 WRDSK:7 " | |
1106 | "ST:6 EXC:6 S:6 " | |
1107 | "CPUNR:5 SORTITEM:10 CMD:10", | |
1108 | "built-in genprocs"); | |
1109 | make_proc_prints(dskprocs, MAXITEMS, | |
1110 | "PID:10 RDDSK:9 " | |
1111 | "WRDSK:9 WCANCL:8 " | |
1112 | "SORTITEM:10 CMD:10", | |
1113 | "built-in dskprocs"); | |
1114 | ||
1115 | /* make path based data unavailable */ | |
1116 | procprt_RDDSK.doactiveconvert=procprt_RDDSK_IOSTAT_a; | |
1117 | procprt_RDDSK.doexitconvert=procprt_RDDSK_IOSTAT_e; | |
1118 | procprt_WRDSK.doactiveconvert=procprt_WRDSK_IOSTAT_a; | |
1119 | procprt_WRDSK.doexitconvert=procprt_WRDSK_IOSTAT_e; | |
1120 | setunavail(&procprt_TOTRSZ); | |
1121 | setunavail(&procprt_TOTWSZ); | |
1122 | setunavail(&procprt_AVGRSZ); | |
1123 | setunavail(&procprt_AVGWSZ); | |
1124 | setunavail(&procprt_TCPRCV); | |
1125 | setunavail(&procprt_TCPRASZ); | |
1126 | setunavail(&procprt_TCPSND); | |
1127 | setunavail(&procprt_TCPSASZ); | |
1128 | setunavail(&procprt_RAWRCV); | |
1129 | setunavail(&procprt_RAWSND); | |
1130 | setunavail(&procprt_UDPRCV); | |
1131 | setunavail(&procprt_UDPRASZ); | |
1132 | setunavail(&procprt_UDPSND); | |
1133 | setunavail(&procprt_UDPSASZ); | |
1134 | setunavail(&procprt_RNET); | |
1135 | setunavail(&procprt_SNET); | |
1136 | } | |
1137 | else | |
1138 | { | |
1139 | // No patches, no iostat data available | |
1140 | make_proc_prints(genprocs, MAXITEMS, | |
1141 | "PID:10 SYSCPU:9 USRCPU:9 " | |
1142 | "VGROW:8 RGROW:8 RUID:4 EUID:3 " | |
1143 | "THR:7 ST:7 EXC:7 S:7 " | |
1144 | "SORTITEM:10 CMD:10", | |
1145 | "built-in genprocs"); | |
1146 | ||
1147 | /* disable iostat and patch based items */ | |
1148 | setunavail(&procprt_RDDSK); | |
1149 | setunavail(&procprt_WRDSK); | |
1150 | setunavail(&procprt_WCANCEL_IOSTAT); | |
1151 | setunavailexit(&procprt_TOTRSZ); | |
1152 | setunavailexit(&procprt_TOTWSZ); | |
1153 | setunavail(&procprt_TOTRSZ); | |
1154 | setunavail(&procprt_TOTWSZ); | |
1155 | setunavail(&procprt_AVGRSZ); | |
1156 | setunavail(&procprt_AVGWSZ); | |
1157 | setunavail(&procprt_TCPRCV); | |
1158 | setunavail(&procprt_TCPRASZ); | |
1159 | setunavail(&procprt_TCPSND); | |
1160 | setunavail(&procprt_TCPSASZ); | |
1161 | setunavail(&procprt_RAWRCV); | |
1162 | setunavail(&procprt_RAWSND); | |
1163 | setunavail(&procprt_UDPRCV); | |
1164 | setunavail(&procprt_UDPRASZ); | |
1165 | setunavail(&procprt_UDPSND); | |
1166 | setunavail(&procprt_UDPSASZ); | |
1167 | setunavail(&procprt_RNET); | |
1168 | setunavail(&procprt_SNET); | |
1169 | } | |
1170 | ||
1171 | make_proc_prints(memprocs, MAXITEMS, | |
1172 | "PID:10 MINFLT:2 MAJFLT:3 VSTEXT:4 " | |
1173 | "VSIZE:5 RSIZE:6 VGROW:7 RGROW:8 RUID:1 EUID:0 " | |
1174 | "SORTITEM:9 CMD:10", | |
1175 | "built-in memprocs"); | |
1176 | ||
1177 | make_proc_prints(schedprocs, MAXITEMS, | |
1178 | "PID:10 TRUN:7 TSLPI:7 TSLPU:7 POLI:8 " | |
1179 | "NICE:9 PRI:9 RTPR:9 CPUNR:8 ST:8 EXC:8 " | |
1180 | "S:8 SORTITEM:10 CMD:10", | |
1181 | "built-in schedprocs"); | |
1182 | ||
1183 | make_proc_prints(netprocs, MAXITEMS, | |
1184 | "PID:10 TCPRCV:9 TCPRASZ:4 TCPSND:9 " | |
1185 | "TCPSASZ:4 UDPRCV:8 UDPRASZ:3 UDPSND:8 UDPSASZ:3 " | |
1186 | "RAWRCV:7 RAWSND:7 SORTITEM:10 CMD:10", | |
1187 | "built-in netprocs"); | |
1188 | ||
1189 | make_proc_prints(varprocs, MAXITEMS, | |
1190 | "PID:10 PPID:9 RUID:8 RGID:8 EUID:5 EGID:4 " | |
1191 | "SUID:3 SGID:2 FSUID:3 FSGID:2 " | |
1192 | "STDATE:7 STTIME:7 ENDATE:5 ENTIME:5 " | |
1193 | "ST:6 EXC:6 S:6 SORTITEM:10 CMD:10", | |
1194 | "built-in varprocs"); | |
1195 | ||
1196 | make_proc_prints(cmdprocs, MAXITEMS, | |
1197 | "PID:10 SORTITEM:10 COMMAND-LINE:10", | |
1198 | "built-in cmdprocs"); | |
1199 | ||
1200 | make_proc_prints(totusers, MAXITEMS, | |
1201 | "NPROCS:10 SYSCPU:9 USRCPU:9 VSIZE:8 " | |
1202 | "RSIZE:8 RDDSK:7 WRDSK:7 RNET:6 SNET:6 " | |
1203 | "SORTITEM:10 RUID:10", | |
1204 | "built-in totusers"); | |
1205 | ||
1206 | make_proc_prints(totprocs, MAXITEMS, | |
1207 | "NPROCS:10 SYSCPU:9 USRCPU:9 VSIZE:8" | |
1208 | "RSIZE:8 RDDSK:7 WRDSK:7 RNET:6 SNET:6" | |
1209 | "SORTITEM:10 CMD:10", | |
1210 | "built-in totprocs"); | |
1211 | } | |
1212 | ||
1213 | /* | |
1214 | ** determine the prefix for the sorting-column | |
1215 | ** to indicate automatic mode | |
1216 | */ | |
1217 | if (autosort) | |
1218 | columnprefix = 'A'; | |
1219 | else | |
1220 | columnprefix = ' '; | |
1221 | ||
1222 | /* | |
1223 | ** print the header line | |
1224 | */ | |
1225 | switch (showtype) | |
1226 | { | |
1227 | case MPROCGEN: | |
1228 | showhdrline(genprocs, curlist, totlist, showorder, autosort); | |
1229 | break; | |
1230 | ||
1231 | case MPROCMEM: | |
1232 | showhdrline(memprocs, curlist, totlist, showorder, autosort); | |
1233 | break; | |
1234 | ||
1235 | case MPROCDSK: | |
1236 | showhdrline(dskprocs, curlist, totlist, showorder, autosort); | |
1237 | break; | |
1238 | ||
1239 | case MPROCNET: | |
1240 | showhdrline(netprocs, curlist, totlist, showorder, autosort); | |
1241 | break; | |
1242 | ||
1243 | case MPROCVAR: | |
1244 | showhdrline(varprocs, curlist, totlist, showorder, autosort); | |
1245 | break; | |
1246 | ||
1247 | case MPROCARG: | |
1248 | showhdrline(cmdprocs, curlist, totlist, showorder, autosort); | |
1249 | break; | |
1250 | ||
1251 | case MPROCOWN: | |
1252 | showhdrline(ownprocs, curlist, totlist, showorder, autosort); | |
1253 | break; | |
1254 | ||
1255 | case MPROCSCH: | |
1256 | showhdrline(schedprocs, curlist, totlist, showorder, autosort); | |
1257 | break; | |
1258 | ||
1259 | case MCUMUSER: | |
1260 | showhdrline(totusers, curlist, totlist, showorder, autosort); | |
1261 | break; | |
1262 | ||
1263 | case MCUMPROC: | |
1264 | showhdrline(totprocs, curlist, totlist, showorder, autosort); | |
1265 | break; | |
1266 | } | |
1279 | 1267 | } |
1280 | 1268 | |
1281 | 1269 | |
1284 | 1272 | */ |
1285 | 1273 | int |
1286 | 1274 | priproc(struct pstat *pstat, int firstproc, int lastproc, int curline, |
1287 | int curlist, int totlist, char showtype, char showorder, | |
1288 | struct syscap *sb, struct selection *sel, int nsecs, int avgval) | |
1289 | { | |
1290 | register int i; | |
1291 | register struct pstat *curstat; | |
1292 | double perc; | |
1293 | ||
1294 | /* | |
1295 | ** print info per actual process and maintain totals | |
1296 | */ | |
1297 | for (i=firstproc; i < lastproc; i++) | |
1298 | { | |
1299 | if (screen && curline >= LINES) /* screen filled entirely ? */ | |
1300 | break; | |
1301 | ||
1302 | curstat = pstat+i; | |
1275 | int curlist, int totlist, char showtype, char showorder, | |
1276 | struct syscap *sb, struct selection *sel, int nsecs, int avgval) | |
1277 | { | |
1278 | register int i; | |
1279 | register struct pstat *curstat; | |
1280 | double perc; | |
1281 | ||
1282 | /* | |
1283 | ** print info per actual process and maintain totals | |
1284 | */ | |
1285 | for (i=firstproc; i < lastproc; i++) | |
1286 | { | |
1287 | if (screen && curline >= LINES) /* screen filled entirely ? */ | |
1288 | break; | |
1289 | ||
1290 | curstat = pstat+i; | |
1291 | ||
1292 | /* | |
1293 | ** calculate occupation-percentage of this process | |
1294 | ** depending on selected resource | |
1295 | */ | |
1296 | switch (showorder) | |
1297 | { | |
1298 | case MSORTCPU: | |
1299 | perc = 0.0; | |
1300 | ||
1301 | if (sb->availcpu) | |
1302 | { | |
1303 | perc = (double)(curstat->cpu.stime + | |
1304 | curstat->cpu.utime ) * | |
1305 | 100.0 / | |
1306 | (sb->availcpu / sb->nrcpu); | |
1307 | ||
1308 | if (perc > 100.0 * sb->nrcpu) | |
1309 | perc = 100.0 * sb->nrcpu; | |
1310 | ||
1311 | if (perc > 100.0 * curstat->gen.nthr) | |
1312 | perc = 100.0 * curstat->gen.nthr; | |
1313 | } | |
1314 | break; | |
1315 | ||
1316 | case MSORTMEM: | |
1317 | perc = 0.0; | |
1318 | ||
1319 | if (sb->availmem) | |
1320 | { | |
1321 | perc = (double)curstat->mem.rmem * | |
1322 | 100.0 / sb->availmem; | |
1323 | ||
1324 | if (perc > 100.0) | |
1325 | perc = 100.0; | |
1326 | } | |
1327 | break; | |
1328 | ||
1329 | case MSORTDSK: | |
1330 | perc = 0.0; | |
1331 | ||
1332 | if (supportflags & PATCHSTAT) | |
1333 | { | |
1334 | if (sb->availdsk) | |
1335 | { | |
1336 | perc = (double)(curstat->dsk.rio + | |
1337 | curstat->dsk.wio ) * | |
1338 | 100.0 / sb->availdsk; | |
1339 | ||
1340 | if (perc > 100.0) | |
1341 | perc = 100.0; | |
1342 | } | |
1343 | } | |
1344 | else | |
1345 | { | |
1346 | if (sb->availdsk) | |
1347 | { | |
1348 | perc = (double)(curstat->dsk.rsz + | |
1349 | curstat->dsk.wsz ) * | |
1350 | 100.0 / sb->availdsk; | |
1351 | ||
1352 | if (perc > 100.0) | |
1353 | perc = 100.0; | |
1354 | } | |
1355 | } | |
1356 | break; | |
1357 | ||
1358 | case MSORTNET: | |
1359 | perc = 0.0; | |
1360 | ||
1361 | if (sb->availnet) | |
1362 | { | |
1363 | perc = (double)(curstat->net.tcpsnd + | |
1364 | curstat->net.tcprcv + | |
1365 | curstat->net.udpsnd + | |
1366 | curstat->net.udprcv + | |
1367 | curstat->net.rawsnd + | |
1368 | curstat->net.rawrcv ) * | |
1369 | 100.0 / sb->availnet; | |
1370 | ||
1371 | if (perc > 100.0) | |
1372 | perc = 100.0; | |
1373 | } | |
1374 | break; | |
1375 | ||
1376 | default: | |
1377 | perc = 0.0; | |
1378 | } | |
1303 | 1379 | |
1304 | 1380 | /* |
1305 | ** calculate occupation-percentage of this process | |
1306 | ** depending on selected resource | |
1307 | */ | |
1308 | switch (showorder) | |
1309 | { | |
1310 | case MSORTCPU: | |
1311 | perc = 0.0; | |
1312 | ||
1313 | if (sb->availcpu) | |
1314 | { | |
1315 | perc = (double)(curstat->cpu.stime + | |
1316 | curstat->cpu.utime ) * | |
1317 | 100.0 / | |
1318 | (sb->availcpu / sb->nrcpu); | |
1319 | ||
1320 | if (perc > 100.0 * sb->nrcpu) | |
1321 | perc = 100.0 * sb->nrcpu; | |
1322 | ||
1323 | if (perc > 100.0 * curstat->gen.nthr) | |
1324 | perc = 100.0 * curstat->gen.nthr; | |
1325 | } | |
1326 | break; | |
1327 | ||
1328 | case MSORTMEM: | |
1329 | perc = 0.0; | |
1330 | ||
1331 | if (sb->availmem) | |
1332 | { | |
1333 | perc = (double)curstat->mem.rmem * | |
1334 | 100.0 / sb->availmem; | |
1335 | ||
1336 | if (perc > 100.0) | |
1337 | perc = 100.0; | |
1338 | } | |
1339 | break; | |
1340 | ||
1341 | case MSORTDSK: | |
1342 | perc = 0.0; | |
1343 | ||
1344 | if (supportflags & PATCHSTAT) | |
1345 | { | |
1346 | if (sb->availdsk) | |
1347 | { | |
1348 | perc = (double)(curstat->dsk.rio + | |
1349 | curstat->dsk.wio ) * | |
1350 | 100.0 / sb->availdsk; | |
1351 | ||
1352 | if (perc > 100.0) | |
1353 | perc = 100.0; | |
1354 | } | |
1355 | } | |
1356 | else | |
1357 | { | |
1358 | if (sb->availdsk) | |
1359 | { | |
1360 | perc = (double)(curstat->dsk.rsz + | |
1361 | curstat->dsk.wsz ) * | |
1362 | 100.0 / sb->availdsk; | |
1363 | ||
1364 | if (perc > 100.0) | |
1365 | perc = 100.0; | |
1366 | } | |
1367 | } | |
1368 | break; | |
1369 | ||
1370 | case MSORTNET: | |
1371 | perc = 0.0; | |
1372 | ||
1373 | if (sb->availnet) | |
1374 | { | |
1375 | perc = (double)(curstat->net.tcpsnd + | |
1376 | curstat->net.tcprcv + | |
1377 | curstat->net.udpsnd + | |
1378 | curstat->net.udprcv + | |
1379 | curstat->net.rawsnd + | |
1380 | curstat->net.rawrcv ) * | |
1381 | 100.0 / sb->availnet; | |
1382 | ||
1383 | if (perc > 100.0) | |
1384 | perc = 100.0; | |
1385 | } | |
1386 | break; | |
1387 | ||
1388 | default: | |
1389 | perc = 0.0; | |
1390 | } | |
1391 | ||
1392 | /* | |
1393 | ** check if only processes of a particular user | |
1394 | ** should be shown | |
1395 | */ | |
1396 | if (sel->userid[0] != USERSTUB) | |
1397 | { | |
1398 | int u = 0; | |
1399 | ||
1400 | while (sel->userid[u] != USERSTUB) | |
1401 | { | |
1402 | if (sel->userid[u] == curstat->gen.ruid) | |
1403 | break; | |
1404 | u++; | |
1405 | } | |
1406 | ||
1407 | if (sel->userid[u] != curstat->gen.ruid) | |
1408 | continue; | |
1409 | } | |
1410 | ||
1411 | /* | |
1412 | ** check if only processes with a particular name | |
1413 | ** should be shown | |
1414 | */ | |
1415 | if (sel->procnamesz && | |
1416 | regexec(&(sel->procregex), curstat->gen.name, 0, NULL, 0)) | |
1381 | ** check if the process-filter or user-filter suppresses | |
1382 | ** this process | |
1383 | */ | |
1384 | if (procsuppress(curstat, sel)) | |
1417 | 1385 | continue; |
1418 | 1386 | |
1419 | /* | |
1420 | ** now do the formatting of output | |
1421 | */ | |
1422 | switch (showtype) | |
1423 | { | |
1424 | case MPROCGEN: | |
1425 | showgenproc(curstat, perc, nsecs, avgval); | |
1426 | break; | |
1427 | ||
1428 | case MPROCMEM: | |
1429 | showmemproc(curstat, perc, nsecs, avgval); | |
1430 | break; | |
1431 | ||
1432 | case MPROCDSK: | |
1433 | showdskproc(curstat, perc, nsecs, avgval); | |
1434 | break; | |
1435 | ||
1436 | case MPROCNET: | |
1437 | shownetproc(curstat, perc, nsecs, avgval); | |
1438 | break; | |
1439 | ||
1440 | case MPROCVAR: | |
1441 | showvarproc(curstat, perc, nsecs, avgval); | |
1442 | break; | |
1443 | ||
1444 | case MPROCARG: | |
1445 | showcmdproc(curstat, perc, nsecs, avgval); | |
1446 | break; | |
1447 | ||
1448 | case MPROCSCH: | |
1449 | showschproc(curstat, perc, nsecs, avgval); | |
1450 | break; | |
1451 | ||
1452 | case MCUMUSER: | |
1453 | showtotuser(curstat, perc, nsecs, avgval); | |
1454 | break; | |
1455 | ||
1456 | case MCUMPROC: | |
1457 | showtotproc(curstat, perc, nsecs, avgval); | |
1458 | break; | |
1459 | } | |
1460 | ||
1461 | curline++; | |
1462 | } | |
1463 | ||
1464 | return curline; | |
1387 | /* | |
1388 | ** now do the formatting of output | |
1389 | */ | |
1390 | if (screen) { | |
1391 | move(curline,0); | |
1392 | } | |
1393 | ||
1394 | switch (showtype) | |
1395 | { | |
1396 | case MPROCGEN: | |
1397 | showprocline(genprocs, curstat, perc, nsecs, avgval); | |
1398 | break; | |
1399 | ||
1400 | case MPROCMEM: | |
1401 | showprocline(memprocs, curstat, perc, nsecs, avgval); | |
1402 | break; | |
1403 | ||
1404 | case MPROCDSK: | |
1405 | showprocline(dskprocs, curstat, perc, nsecs, avgval); | |
1406 | break; | |
1407 | ||
1408 | case MPROCNET: | |
1409 | showprocline(netprocs, curstat, perc, nsecs, avgval); | |
1410 | break; | |
1411 | ||
1412 | case MPROCVAR: | |
1413 | showprocline(varprocs, curstat, perc, nsecs, avgval); | |
1414 | break; | |
1415 | ||
1416 | case MPROCARG: | |
1417 | showprocline(cmdprocs, curstat, perc, nsecs, avgval); | |
1418 | break; | |
1419 | ||
1420 | case MPROCOWN: | |
1421 | showprocline(ownprocs, curstat, perc, nsecs, avgval); | |
1422 | break; | |
1423 | ||
1424 | case MPROCSCH: | |
1425 | showprocline(schedprocs, curstat, perc, nsecs, avgval); | |
1426 | break; | |
1427 | ||
1428 | case MCUMUSER: | |
1429 | showprocline(totusers, curstat, perc, nsecs, avgval); | |
1430 | break; | |
1431 | ||
1432 | case MCUMPROC: | |
1433 | showprocline(totprocs, curstat, perc, nsecs, avgval); | |
1434 | break; | |
1435 | } | |
1436 | ||
1437 | curline++; | |
1438 | } | |
1439 | ||
1440 | return curline; | |
1465 | 1441 | } |
1466 | 1442 | |
1467 | 1443 | |
1468 | 1444 | /* |
1469 | 1445 | ** print the system-wide statistics |
1470 | 1446 | */ |
1447 | static void pridisklike(extraparam *, struct perdsk *, char *, | |
1448 | char *, int, unsigned int *, int *, int, int); | |
1471 | 1449 | int |
1472 | 1450 | prisyst(struct sstat *sstat, int curline, int nsecs, int avgval, |
1473 | 1451 | int fixedhead, int usecolors, char *highorderp, |
1474 | int maxcpulines, int maxdsklines, int maxintlines) | |
1475 | { | |
1476 | register int i, lin; | |
1477 | count_t cputot, percputot, mstot, busy; | |
1478 | count_t udpin, udpout, ipin, ipout, ipfrw, ipindel; | |
1479 | unsigned int badness, highbadness=0; | |
1480 | char format1[16], format2[16], format3[16]; | |
1481 | char format4[16], format5[16]; | |
1482 | char busyval[5], coloron=0; | |
1483 | ||
1452 | int maxcpulines, int maxdsklines, int maxmddlines, | |
1453 | int maxlvmlines, int maxintlines) | |
1454 | { | |
1455 | extraparam extra; | |
1456 | int lin; | |
1457 | count_t busy; | |
1458 | unsigned int badness, highbadness=0; | |
1459 | ||
1460 | extra.nsecs=nsecs; | |
1461 | extra.avgval=avgval; | |
1462 | /* | |
1463 | ** CPU statistics | |
1464 | */ | |
1465 | extra.cputot = sstat->cpu.all.stime + sstat->cpu.all.utime + | |
1466 | sstat->cpu.all.ntime + sstat->cpu.all.itime + | |
1467 | sstat->cpu.all.wtime + sstat->cpu.all.Itime + | |
1468 | sstat->cpu.all.Stime + sstat->cpu.all.steal + | |
1469 | sstat->cpu.all.guest; | |
1470 | ||
1471 | busy = (extra.cputot - sstat->cpu.all.itime - sstat->cpu.all.wtime) | |
1472 | * 100.0 / extra.cputot; | |
1473 | ||
1474 | if (cpubadness) | |
1475 | badness = busy * 100 / cpubadness; | |
1476 | else | |
1477 | badness = 0; | |
1478 | ||
1479 | if (highbadness < badness) | |
1480 | { | |
1481 | highbadness = badness; | |
1482 | *highorderp = MSORTCPU; | |
1483 | } | |
1484 | ||
1485 | if (extra.cputot == 0) | |
1486 | extra.cputot = 1; /* avoid divide-by-zero */ | |
1487 | ||
1488 | extra.percputot = extra.cputot / sstat->cpu.nrcpu; | |
1489 | ||
1490 | if (extra.percputot == 0) | |
1491 | extra.percputot = 1; /* avoid divide-by-zero */ | |
1492 | ||
1493 | move(curline, 0); | |
1494 | showsysline(allcpuline, sstat, &extra, "CPU", usecolors, badness); | |
1495 | curline++; | |
1496 | ||
1497 | if (sstat->cpu.nrcpu > 1) | |
1498 | { | |
1499 | for (extra.index=lin=0; | |
1500 | extra.index < sstat->cpu.nrcpu && lin < maxcpulines; | |
1501 | extra.index++) | |
1502 | { | |
1503 | extra.percputot = sstat->cpu.cpu[extra.index].stime + | |
1504 | sstat->cpu.cpu[extra.index].utime + | |
1505 | sstat->cpu.cpu[extra.index].ntime + | |
1506 | sstat->cpu.cpu[extra.index].itime + | |
1507 | sstat->cpu.cpu[extra.index].wtime + | |
1508 | sstat->cpu.cpu[extra.index].Itime + | |
1509 | sstat->cpu.cpu[extra.index].Stime + | |
1510 | sstat->cpu.cpu[extra.index].steal + | |
1511 | sstat->cpu.cpu[extra.index].guest; | |
1512 | ||
1513 | if (extra.percputot == | |
1514 | (sstat->cpu.cpu[extra.index].itime + | |
1515 | sstat->cpu.cpu[extra.index].wtime ) && | |
1516 | !fixedhead ) | |
1517 | continue; /* inactive cpu */ | |
1518 | ||
1519 | busy = (extra.percputot - | |
1520 | sstat->cpu.cpu[extra.index].itime - | |
1521 | sstat->cpu.cpu[extra.index].wtime) | |
1522 | * 100.0 / extra.percputot; | |
1523 | ||
1524 | if (cpubadness) | |
1525 | badness = busy * 100 / cpubadness; | |
1526 | else | |
1527 | badness = 0; | |
1528 | ||
1529 | if (highbadness < badness) | |
1530 | { | |
1531 | highbadness = badness; | |
1532 | *highorderp = MSORTCPU; | |
1533 | } | |
1534 | ||
1535 | if (extra.percputot == 0) | |
1536 | extra.percputot = 1; /* avoid divide-by-zero */ | |
1537 | ||
1538 | ||
1539 | move(curline, 0); | |
1540 | showsysline(indivcpuline, sstat, &extra, "cpu", | |
1541 | usecolors, badness); | |
1542 | curline++; | |
1543 | lin++; | |
1544 | } | |
1545 | } | |
1546 | ||
1547 | /* | |
1548 | ** other CPU-related statistics | |
1549 | */ | |
1550 | move(curline, 0); | |
1551 | showsysline(cplline, sstat, &extra, "CPL", 0, 0); | |
1552 | curline++; | |
1553 | ||
1554 | /* | |
1555 | ** MEMORY statistics | |
1556 | */ | |
1557 | busy = (sstat->mem.physmem - sstat->mem.freemem | |
1558 | - sstat->mem.cachemem | |
1559 | - sstat->mem.buffermem) | |
1560 | * 100.0 / sstat->mem.physmem; | |
1561 | ||
1562 | if (membadness) | |
1563 | badness = busy * 100 / membadness; | |
1564 | else | |
1565 | badness = 0; | |
1566 | ||
1567 | if (highbadness < badness) | |
1568 | { | |
1569 | highbadness = badness; | |
1570 | *highorderp = MSORTMEM; | |
1571 | } | |
1572 | ||
1573 | move(curline, 0); | |
1574 | showsysline(memline, sstat, &extra, "MEM", usecolors, badness); | |
1575 | curline++; | |
1576 | ||
1577 | /* | |
1578 | ** SWAP statistics | |
1579 | */ | |
1580 | busy = (sstat->mem.totswap - sstat->mem.freeswap) | |
1581 | * 100.0 / sstat->mem.totswap; | |
1582 | ||
1583 | if (swpbadness) | |
1584 | { | |
1585 | badness = busy * 100 / swpbadness; | |
1586 | } | |
1587 | else | |
1588 | { | |
1589 | badness = 0; | |
1590 | } | |
1591 | ||
1592 | if (highbadness < badness) | |
1593 | { | |
1594 | highbadness = badness; | |
1595 | *highorderp = MSORTMEM; | |
1596 | } | |
1597 | ||
1598 | if (sstat->mem.commitlim && sstat->mem.committed > sstat->mem.commitlim) | |
1599 | badness = 100; /* force colored output */ | |
1600 | ||
1601 | move(curline, 0); | |
1602 | showsysline(swpline, sstat, &extra, "SWP", usecolors, badness); | |
1603 | curline++; | |
1604 | ||
1605 | /* | |
1606 | ** PAGING statistics | |
1607 | */ | |
1608 | if (fixedhead || | |
1609 | sstat->mem.pgscans || | |
1610 | sstat->mem.allocstall || | |
1611 | sstat->mem.swins || | |
1612 | sstat->mem.swouts ) | |
1613 | { | |
1614 | busy = sstat->mem.swouts / nsecs * pagbadness; | |
1615 | ||
1616 | if (busy > 100) | |
1617 | busy = 100; | |
1618 | ||
1619 | if (membadness) | |
1620 | badness = busy * 100 / membadness; | |
1621 | else | |
1622 | badness = 0; | |
1623 | ||
1624 | if (highbadness < badness) | |
1625 | { | |
1626 | highbadness = badness; | |
1627 | *highorderp = MSORTMEM; | |
1628 | } | |
1629 | ||
1630 | /* | |
1631 | ** take care that this line is anyhow colored for | |
1632 | ** 'almost critical' in case of swapouts > 1 per second | |
1633 | */ | |
1634 | if (sstat->mem.swouts / nsecs > 0 && | |
1635 | pagbadness && almostcrit && badness < almostcrit) | |
1636 | badness = almostcrit; | |
1637 | ||
1638 | move(curline, 0); | |
1639 | showsysline(pagline, sstat, &extra,"PAG", usecolors, badness); | |
1640 | curline++; | |
1641 | } | |
1642 | ||
1643 | /* | |
1644 | ** DISK statistics | |
1645 | */ | |
1646 | extra.mstot = extra.cputot * 1000 / hertz / sstat->cpu.nrcpu; | |
1647 | ||
1648 | pridisklike(&extra, sstat->dsk.lvm, "LVM", highorderp, maxlvmlines, | |
1649 | &highbadness, &curline, fixedhead, usecolors); | |
1650 | ||
1651 | pridisklike(&extra, sstat->dsk.mdd, "MDD", highorderp, maxmddlines, | |
1652 | &highbadness, &curline, fixedhead, usecolors); | |
1653 | ||
1654 | pridisklike(&extra, sstat->dsk.dsk, "DSK", highorderp, maxdsklines, | |
1655 | &highbadness, &curline, fixedhead, usecolors); | |
1656 | ||
1657 | /* | |
1658 | ** NET statistics | |
1659 | */ | |
1660 | if (sstat->net.tcp.InSegs || | |
1661 | sstat->net.tcp.OutSegs || | |
1662 | sstat->net.udpv4.InDatagrams || | |
1663 | sstat->net.udpv6.Udp6InDatagrams || | |
1664 | sstat->net.udpv4.OutDatagrams || | |
1665 | sstat->net.udpv6.Udp6OutDatagrams || | |
1666 | fixedhead ) | |
1667 | { | |
1668 | move(curline, 0); | |
1669 | showsysline(nettransportline, sstat, &extra, "NET", 0, 0); | |
1670 | curline++; | |
1671 | } | |
1672 | ||
1673 | if (sstat->net.ipv4.InReceives || | |
1674 | sstat->net.ipv6.Ip6InReceives || | |
1675 | sstat->net.ipv4.OutRequests || | |
1676 | sstat->net.ipv6.Ip6OutRequests || | |
1677 | fixedhead ) | |
1678 | { | |
1679 | move(curline, 0); | |
1680 | showsysline(netnetline, sstat, &extra, "NET", 0, 0); | |
1681 | curline++; | |
1682 | } | |
1683 | ||
1684 | for (extra.index=0, lin=0; | |
1685 | sstat->intf.intf[extra.index].name[0] && lin < maxintlines; | |
1686 | extra.index++) | |
1687 | { | |
1688 | if (sstat->intf.intf[extra.index].rpack || | |
1689 | sstat->intf.intf[extra.index].spack || fixedhead) | |
1690 | { | |
1691 | /* | |
1692 | ** calculate busy-percentage for interface | |
1693 | */ | |
1694 | ||
1695 | count_t ival, oval; | |
1696 | ||
1697 | /* | |
1698 | ** convert byte-transfers to bit-transfers (* 8) | |
1699 | ** convert bit-transfers to kilobit-transfers (/ 1000) | |
1700 | ** per second | |
1701 | */ | |
1702 | ival = sstat->intf.intf[extra.index].rbyte/125/nsecs; | |
1703 | oval = sstat->intf.intf[extra.index].sbyte/125/nsecs; | |
1704 | ||
1705 | /* speed known? */ | |
1706 | if (sstat->intf.intf[extra.index].speed) | |
1707 | { | |
1708 | if (sstat->intf.intf[extra.index].duplex) | |
1709 | busy = (ival > oval ? ival : oval) / | |
1710 | (sstat->intf.intf[extra.index].speed | |
1711 | *10); | |
1712 | else | |
1713 | busy = (ival + oval) / | |
1714 | (sstat->intf.intf[extra.index].speed | |
1715 | *10); | |
1716 | ||
1717 | } | |
1718 | else | |
1719 | { | |
1720 | busy = 0; | |
1721 | } | |
1722 | ||
1723 | if (netbadness) | |
1724 | badness = busy * 100 / netbadness; | |
1725 | else | |
1726 | badness = 0; | |
1727 | ||
1728 | if (highbadness < badness && | |
1729 | (supportflags & PATCHSTAT) ) | |
1730 | { | |
1731 | highbadness = badness; | |
1732 | *highorderp = MSORTNET; | |
1733 | } | |
1734 | ||
1735 | move(curline, 0); | |
1736 | showsysline(netinterfaceline, sstat, &extra, | |
1737 | "NET", usecolors, badness); | |
1738 | curline++; | |
1739 | lin++; | |
1740 | } | |
1741 | } | |
1742 | ||
1743 | /* | |
1744 | ** application statistics | |
1745 | ** | |
1746 | ** WWW: notice that we cause one access ourselves by fetching | |
1747 | ** the statistical counters | |
1748 | */ | |
1749 | #if HTTPSTATS | |
1750 | if (sstat->www.accesses > 1 || fixedhead ) | |
1751 | { | |
1752 | move(curline, 0); | |
1753 | printg("WWW | reqs %s | totKB %s | byt/rq %s | iwork %s |" | |
1754 | " bwork %s |", | |
1755 | val2valstr(sstat->www.accesses, format1, 6, | |
1756 | avgval, nsecs), | |
1757 | val2valstr(sstat->www.totkbytes, format2, 6, | |
1758 | avgval, nsecs), | |
1759 | val2valstr(sstat->www.accesses ? | |
1760 | sstat->www.totkbytes*1024/sstat->www.accesses : 0, | |
1761 | format3, 5, 0, 0), | |
1762 | val2valstr(sstat->www.iworkers, format4, 6, 0, 0), | |
1763 | val2valstr(sstat->www.bworkers, format5, 6, 0, 0) ); | |
1764 | if (!screen) | |
1765 | { | |
1766 | printg("\n"); | |
1767 | } | |
1768 | curline++; | |
1769 | } | |
1770 | #endif | |
1771 | ||
1772 | /* | |
1773 | ** if the system is hardly loaded, still CPU-ordering of | |
1774 | ** processes is most interesting (instead of memory) | |
1775 | */ | |
1776 | if (highbadness < 70 && *highorderp == MSORTMEM) | |
1777 | *highorderp = MSORTCPU; | |
1778 | ||
1779 | return curline; | |
1780 | } | |
1781 | ||
1782 | /* | |
1783 | ** handle all instances of a specific disk-like device | |
1784 | */ | |
1785 | static void | |
1786 | pridisklike(extraparam *ep, struct perdsk *dp, char *lp, char *highorderp, | |
1787 | int maxlines, unsigned int *highbadp, int *curlinp, | |
1788 | int fixedhead, int usecolors) | |
1789 | { | |
1790 | int lin; | |
1791 | count_t busy; | |
1792 | unsigned int badness; | |
1793 | ||
1794 | for (ep->perdsk = dp, ep->index=0, lin=0; | |
1795 | ep->perdsk[ep->index].name[0] && lin < maxlines; ep->index++) | |
1796 | { | |
1797 | ep->iotot = ep->perdsk[ep->index].nread + | |
1798 | ep->perdsk[ep->index].nwrite; | |
1799 | ||
1800 | busy = (double)(ep->perdsk[ep->index].io_ms * | |
1801 | 100.0 / ep->mstot); | |
1802 | ||
1803 | if (dskbadness) | |
1804 | badness = busy * 100 / dskbadness; | |
1805 | else | |
1806 | badness = 0; | |
1807 | ||
1808 | if (*highbadp < badness && (supportflags & (PATCHSTAT|IOSTAT)) ) | |
1809 | { | |
1810 | *highbadp = badness; | |
1811 | *highorderp = MSORTDSK; | |
1812 | } | |
1813 | ||
1814 | if (ep->iotot || fixedhead) | |
1815 | { | |
1816 | move(*curlinp, 0); | |
1817 | showsysline(dskline, 0, ep, lp, usecolors, badness); | |
1818 | (*curlinp)++; | |
1819 | lin++; | |
1820 | } | |
1821 | } | |
1822 | } | |
1823 | ||
1824 | ||
1825 | /* | |
1826 | ** function that checks if the current process is selected or suppressed; | |
1827 | ** returns 1 (suppress) or 0 (do not suppress) | |
1828 | */ | |
1829 | int | |
1830 | procsuppress(struct pstat *curstat, struct selection *sel) | |
1831 | { | |
1484 | 1832 | /* |
1485 | ** CPU statistics | |
1833 | ** check if only processes of a particular user | |
1834 | ** should be shown | |
1486 | 1835 | */ |
1487 | cputot = sstat->cpu.all.stime + sstat->cpu.all.utime + | |
1488 | sstat->cpu.all.ntime + sstat->cpu.all.itime + | |
1489 | sstat->cpu.all.wtime + sstat->cpu.all.Itime + | |
1490 | sstat->cpu.all.Stime + sstat->cpu.all.steal; | |
1491 | ||
1492 | busy = (cputot - sstat->cpu.all.itime - sstat->cpu.all.wtime) | |
1493 | * 100.0 / cputot; | |
1494 | ||
1495 | if (cpubadness) | |
1496 | badness = busy * 100 / cpubadness; | |
1497 | else | |
1498 | badness = 0; | |
1499 | ||
1500 | if (highbadness < badness) | |
1836 | if (sel->userid[0] != USERSTUB) | |
1501 | 1837 | { |
1502 | highbadness = badness; | |
1503 | *highorderp = MSORTCPU; | |
1838 | int u = 0; | |
1839 | ||
1840 | while (sel->userid[u] != USERSTUB) | |
1841 | { | |
1842 | if (sel->userid[u] == curstat->gen.ruid) | |
1843 | break; | |
1844 | u++; | |
1845 | } | |
1846 | ||
1847 | if (sel->userid[u] != curstat->gen.ruid) | |
1848 | return 1; | |
1504 | 1849 | } |
1505 | 1850 | |
1506 | if (cputot == 0) | |
1507 | cputot = 1; /* avoid divide-by-zero */ | |
1508 | ||
1509 | percputot = cputot / sstat->cpu.nrcpu; | |
1510 | ||
1511 | if (percputot == 0) | |
1512 | percputot = 1; /* avoid divide-by-zero */ | |
1513 | ||
1514 | coloron = syscolorlabel("CPU", usecolors, badness); | |
1515 | ||
1516 | printg(" | sys %6.0f%% | user %6.0f%% | " | |
1517 | "irq %6.0f%% | idle %6.0f%% | wait %6.0f%% |\n", | |
1518 | (double) (sstat->cpu.all.stime * 100.0) / percputot, | |
1519 | (double)((sstat->cpu.all.utime + sstat->cpu.all.ntime) | |
1520 | * 100.0) / percputot, | |
1521 | (double)((sstat->cpu.all.Itime + sstat->cpu.all.Stime) | |
1522 | * 100.0) / percputot, | |
1523 | (double) (sstat->cpu.all.itime * 100.0) / percputot, | |
1524 | (double) (sstat->cpu.all.wtime * 100.0) / percputot); | |
1525 | ||
1526 | if (coloron) | |
1527 | syscoloroff(coloron); | |
1528 | ||
1529 | curline++; | |
1530 | ||
1531 | if (sstat->cpu.all.steal) /* only for virtual machines ... */ | |
1532 | { | |
1533 | coloron = syscolorlabel("CPU", usecolors, badness); | |
1534 | ||
1535 | printg(" | steal %4.0f%% | stl/cpu %3.0f%% | " | |
1536 | " | | |\n", | |
1537 | (double) (sstat->cpu.all.steal * 100.0) / percputot, | |
1538 | (double) (sstat->cpu.all.steal * 100.0) / cputot); | |
1539 | ||
1540 | if (coloron) | |
1541 | syscoloroff(coloron); | |
1542 | ||
1543 | curline++; | |
1544 | } | |
1545 | ||
1546 | if (sstat->cpu.nrcpu > 1) | |
1547 | { | |
1548 | for (i=lin=0; i < sstat->cpu.nrcpu && lin < maxcpulines; i++) | |
1549 | { | |
1550 | percputot = sstat->cpu.cpu[i].stime + | |
1551 | sstat->cpu.cpu[i].utime + | |
1552 | sstat->cpu.cpu[i].ntime + | |
1553 | sstat->cpu.cpu[i].itime + | |
1554 | sstat->cpu.cpu[i].wtime + | |
1555 | sstat->cpu.cpu[i].Itime + | |
1556 | sstat->cpu.cpu[i].Stime + | |
1557 | sstat->cpu.cpu[i].steal; | |
1558 | ||
1559 | if (percputot == (sstat->cpu.cpu[i].itime + | |
1560 | sstat->cpu.cpu[i].wtime ) && | |
1561 | !fixedhead ) | |
1562 | continue; /* inactive cpu */ | |
1563 | ||
1564 | busy = (percputot - sstat->cpu.cpu[i].itime | |
1565 | - sstat->cpu.cpu[i].wtime) | |
1566 | * 100.0 / percputot; | |
1567 | ||
1568 | if (cpubadness) | |
1569 | badness = busy * 100 / cpubadness; | |
1570 | else | |
1571 | badness = 0; | |
1572 | ||
1573 | if (highbadness < badness) | |
1574 | { | |
1575 | highbadness = badness; | |
1576 | *highorderp = MSORTCPU; | |
1577 | } | |
1578 | ||
1579 | if (percputot == 0) | |
1580 | percputot = 1; /* avoid divide-by-zero */ | |
1581 | ||
1582 | ||
1583 | coloron = syscolorlabel("cpu", usecolors, badness); | |
1584 | ||
1585 | printg(" | sys %6.0f%% | " | |
1586 | "user %6.0f%% | irq %6.0f%% | " | |
1587 | "idle %6.0f%% | cpu%03d w%3.0f%% |\n", | |
1588 | (double) (sstat->cpu.cpu[i].stime | |
1589 | * 100.0) / percputot, | |
1590 | (double)((sstat->cpu.cpu[i].utime + | |
1591 | sstat->cpu.cpu[i].ntime) | |
1592 | * 100.0) / percputot, | |
1593 | (double)((sstat->cpu.cpu[i].Itime + | |
1594 | sstat->cpu.cpu[i].Stime) | |
1595 | * 100.0) / percputot, | |
1596 | (double) (sstat->cpu.cpu[i].itime | |
1597 | * 100.0) / percputot, | |
1598 | sstat->cpu.cpu[i].cpunr, | |
1599 | (double) (sstat->cpu.cpu[i].wtime | |
1600 | * 100.0) / percputot); | |
1601 | ||
1602 | if (coloron) | |
1603 | syscoloroff(coloron); | |
1604 | ||
1605 | curline++; | |
1606 | lin++; | |
1607 | } | |
1608 | } | |
1609 | ||
1610 | 1851 | /* |
1611 | ** other CPU-related statistics | |
1852 | ** check if only processes with a particular name | |
1853 | ** should be shown | |
1612 | 1854 | */ |
1613 | if (sstat->cpu.lavg1 > 999.0 || | |
1614 | sstat->cpu.lavg5 > 9999.0 || | |
1615 | sstat->cpu.lavg15 > 999.0 ) | |
1616 | { | |
1617 | printg("CPL | avg1 %6.0f | avg5 %7.0f | avg15 %6.0f | csw %s" | |
1618 | " | intr %s |\n", | |
1619 | sstat->cpu.lavg1, | |
1620 | sstat->cpu.lavg5, | |
1621 | sstat->cpu.lavg15, | |
1622 | val2valstr(sstat->cpu.csw, format1, 8,avgval,nsecs), | |
1623 | val2valstr(sstat->cpu.devint, format2, 7,avgval,nsecs)); | |
1624 | } | |
1625 | else | |
1626 | { | |
1627 | printg("CPL | avg1 %6.2f | avg5 %7.2f | avg15 %6.2f | csw %s" | |
1628 | " | intr %s |\n", | |
1629 | sstat->cpu.lavg1, | |
1630 | sstat->cpu.lavg5, | |
1631 | sstat->cpu.lavg15, | |
1632 | val2valstr(sstat->cpu.csw, format1, 8,avgval,nsecs), | |
1633 | val2valstr(sstat->cpu.devint, format2, 7,avgval,nsecs)); | |
1634 | } | |
1635 | ||
1636 | curline++; | |
1637 | ||
1638 | /* | |
1639 | ** MEMORY statistics | |
1640 | */ | |
1641 | busy = (sstat->mem.physmem - sstat->mem.freemem | |
1642 | - sstat->mem.cachemem | |
1643 | - sstat->mem.buffermem) | |
1644 | * 100.0 / sstat->mem.physmem; | |
1645 | ||
1646 | if (membadness) | |
1647 | badness = busy * 100 / membadness; | |
1648 | else | |
1649 | badness = 0; | |
1650 | ||
1651 | if (highbadness < badness) | |
1652 | { | |
1653 | highbadness = badness; | |
1654 | *highorderp = MSORTMEM; | |
1655 | } | |
1656 | ||
1657 | coloron = syscolorlabel("MEM", usecolors, badness); | |
1658 | ||
1659 | printg(" | tot %s | free %s | cache %s | buff %s | slab %s |\n", | |
1660 | val2memstr(sstat->mem.physmem * pagesize, format1, | |
1661 | MBFORMAT, 0, 0), | |
1662 | val2memstr(sstat->mem.freemem * pagesize, format2, | |
1663 | MBFORMAT, 0, 0), | |
1664 | val2memstr(sstat->mem.cachemem * pagesize, format3, | |
1665 | MBFORMAT, 0, 0), | |
1666 | val2memstr(sstat->mem.buffermem * pagesize, format4, | |
1667 | MBFORMAT, 0, 0), | |
1668 | val2memstr(sstat->mem.slabmem * pagesize, format5, | |
1669 | MBFORMAT, 0, 0)); | |
1670 | ||
1671 | if (coloron) | |
1672 | syscoloroff(coloron); | |
1673 | ||
1674 | curline++; | |
1675 | ||
1676 | /* | |
1677 | ** SWAP statistics | |
1678 | */ | |
1679 | busy = (sstat->mem.totswap - sstat->mem.freeswap) | |
1680 | * 100.0 / sstat->mem.totswap; | |
1681 | ||
1682 | if (swpbadness) | |
1683 | badness = busy * 100 / swpbadness; | |
1684 | else | |
1685 | badness = 0; | |
1686 | ||
1687 | if (highbadness < badness) | |
1688 | { | |
1689 | highbadness = badness; | |
1690 | *highorderp = MSORTMEM; | |
1691 | } | |
1692 | ||
1693 | if (sstat->mem.commitlim && sstat->mem.committed > sstat->mem.commitlim) | |
1694 | badness = 100; /* force colored output */ | |
1695 | ||
1696 | coloron = syscolorlabel("SWP", usecolors, badness); | |
1697 | ||
1698 | printg(" | tot %s | free %s | " | |
1699 | "| vmcom %s | vmlim %s |\n", | |
1700 | val2memstr(sstat->mem.totswap * pagesize, format1, | |
1701 | MBFORMAT, 0, 0), | |
1702 | val2memstr(sstat->mem.freeswap * pagesize, format2, | |
1703 | MBFORMAT, 0, 0), | |
1704 | val2memstr(sstat->mem.committed * pagesize, format3, | |
1705 | MBFORMAT, 0, 0), | |
1706 | val2memstr(sstat->mem.commitlim * pagesize, format4, | |
1707 | MBFORMAT, 0, 0)); | |
1708 | ||
1709 | if (coloron) | |
1710 | syscoloroff(coloron); | |
1711 | ||
1712 | curline++; | |
1713 | ||
1714 | /* | |
1715 | ** PAGING statistics | |
1716 | */ | |
1717 | if (fixedhead || | |
1718 | sstat->mem.pgscans || | |
1719 | sstat->mem.allocstall || | |
1720 | sstat->mem.swins || | |
1721 | sstat->mem.swouts ) | |
1722 | { | |
1723 | busy = sstat->mem.swouts / nsecs * pagbadness; | |
1724 | ||
1725 | if (busy > 100) | |
1726 | busy = 100; | |
1727 | ||
1728 | if (membadness) | |
1729 | badness = busy * 100 / membadness; | |
1730 | else | |
1731 | badness = 0; | |
1732 | ||
1733 | if (highbadness < badness) | |
1734 | { | |
1735 | highbadness = badness; | |
1736 | *highorderp = MSORTMEM; | |
1737 | } | |
1738 | ||
1739 | /* | |
1740 | ** take care that this line is anyhow colored for | |
1741 | ** 'almost critical' in case of swapouts > 1 per second | |
1742 | */ | |
1743 | if (sstat->mem.swouts / nsecs > 0 && | |
1744 | pagbadness && almostcrit && badness < almostcrit) | |
1745 | badness = almostcrit; | |
1746 | ||
1747 | coloron = syscolorlabel("PAG", usecolors, badness); | |
1748 | ||
1749 | printg(" | scan %s | stall %s | " | |
1750 | " | swin %s | swout %s |\n", | |
1751 | val2valstr(sstat->mem.pgscans, format1, 6, | |
1752 | avgval, nsecs), | |
1753 | val2valstr(sstat->mem.allocstall, format2, 6, | |
1754 | avgval, nsecs), | |
1755 | val2valstr(sstat->mem.swins, format3, 7, | |
1756 | avgval, nsecs), | |
1757 | val2valstr(sstat->mem.swouts, format4, 6, | |
1758 | avgval, nsecs)); | |
1759 | ||
1760 | if (coloron) | |
1761 | syscoloroff(coloron); | |
1762 | ||
1763 | curline++; | |
1764 | } | |
1765 | ||
1766 | /* | |
1767 | ** DISK statistics | |
1768 | ** | |
1769 | ** If extended disk-stats's are supported, take them | |
1770 | */ | |
1771 | mstot = cputot * 1000 / hertz / sstat->cpu.nrcpu; | |
1772 | ||
1773 | for (i=0, lin=0; sstat->xdsk.xdsk[i].name[0] && lin < maxdsklines; i++) | |
1774 | { | |
1775 | count_t iotot; | |
1776 | ||
1777 | iotot = sstat->xdsk.xdsk[i].nread + sstat->xdsk.xdsk[i].nwrite; | |
1778 | ||
1779 | busy = (double)(sstat->xdsk.xdsk[i].io_ms * 100.0 / mstot); | |
1780 | ||
1781 | if (dskbadness) | |
1782 | badness = busy * 100 / dskbadness; | |
1783 | else | |
1784 | badness = 0; | |
1785 | ||
1786 | if (highbadness < badness && | |
1787 | (supportflags & (PATCHSTAT|IOSTAT)) ) | |
1788 | { | |
1789 | highbadness = badness; | |
1790 | *highorderp = MSORTDSK; | |
1791 | } | |
1792 | ||
1793 | if (iotot || fixedhead) | |
1794 | { | |
1795 | coloron = syscolorlabel("DSK", usecolors, badness); | |
1796 | ||
1797 | printg(" | %11.11s | busy %6.0lf%% | read %s |" | |
1798 | " write %s | avio %4.0lf ms |\n", | |
1799 | sstat->xdsk.xdsk[i].name, | |
1800 | (double)(sstat->xdsk.xdsk[i].io_ms * 100.0 / mstot), | |
1801 | val2valstr(sstat->xdsk.xdsk[i].nread, format1, 7, | |
1802 | avgval, nsecs), | |
1803 | val2valstr(sstat->xdsk.xdsk[i].nwrite, format2, 6, | |
1804 | avgval, nsecs), | |
1805 | iotot?(double)(sstat->xdsk.xdsk[i].io_ms/iotot):0.0); | |
1806 | ||
1807 | if (coloron) | |
1808 | syscoloroff(coloron); | |
1809 | ||
1810 | curline++; | |
1811 | lin++; | |
1812 | } | |
1813 | } | |
1814 | ||
1815 | /* | |
1816 | ** NET statistics | |
1817 | */ | |
1818 | udpin = sstat->net.udpv4.InDatagrams + | |
1819 | sstat->net.udpv6.Udp6InDatagrams; | |
1820 | udpout = sstat->net.udpv4.OutDatagrams + | |
1821 | sstat->net.udpv6.Udp6OutDatagrams; | |
1822 | ||
1823 | if (sstat->net.tcp.InSegs || sstat->net.tcp.OutSegs || | |
1824 | udpin || udpout || fixedhead ) | |
1825 | { | |
1826 | printg("NET | transport | tcpi %s | tcpo %s |" | |
1827 | " udpi %s | udpo %s |\n", | |
1828 | val2valstr(sstat->net.tcp.InSegs, format1, 7, | |
1829 | avgval, nsecs), | |
1830 | val2valstr(sstat->net.tcp.OutSegs, format2, 7, | |
1831 | avgval, nsecs), | |
1832 | val2valstr(udpin, format3, 7, avgval, nsecs), | |
1833 | val2valstr(udpout, format4, 7, avgval, nsecs)); | |
1834 | curline++; | |
1835 | } | |
1836 | ||
1837 | ipin = sstat->net.ipv4.InReceives + | |
1838 | sstat->net.ipv6.Ip6InReceives; | |
1839 | ipout = sstat->net.ipv4.OutRequests + | |
1840 | sstat->net.ipv6.Ip6OutRequests; | |
1841 | ipindel = sstat->net.ipv4.InDelivers + | |
1842 | sstat->net.ipv6.Ip6InDelivers; | |
1843 | ipfrw = sstat->net.ipv4.ForwDatagrams + | |
1844 | sstat->net.ipv6.Ip6OutForwDatagrams; | |
1845 | ||
1846 | if (ipin || ipout || fixedhead ) | |
1847 | { | |
1848 | printg("NET | network | ipi %s | ipo %s | ipfrw %s |" | |
1849 | " deliv %s |\n", | |
1850 | val2valstr(ipin, format1, 8, avgval, nsecs), | |
1851 | val2valstr(ipout, format2, 8, avgval, nsecs), | |
1852 | val2valstr(ipfrw, format3, 6, avgval, nsecs), | |
1853 | val2valstr(ipindel, format4, 6, avgval, nsecs)); | |
1854 | ||
1855 | curline++; | |
1856 | } | |
1857 | ||
1858 | for (i=0, lin=0; sstat->intf.intf[i].name[0] && lin < maxintlines; i++) | |
1859 | { | |
1860 | if (sstat->intf.intf[i].rpack || | |
1861 | sstat->intf.intf[i].spack || fixedhead) | |
1862 | { | |
1863 | char *iform = "Kbps"; | |
1864 | char *oform = "Kbps"; | |
1865 | count_t ival, ipres, oval, opres; | |
1866 | ||
1867 | /* | |
1868 | ** convert byte-transfers to bit-transfers (* 8) | |
1869 | ** convert bit-transfers to kilobit-transfers (/ 1000) | |
1870 | ** per second | |
1871 | */ | |
1872 | ival = sstat->intf.intf[i].rbyte/125/nsecs; | |
1873 | oval = sstat->intf.intf[i].sbyte/125/nsecs; | |
1874 | ||
1875 | if (ival >= 10000) /* input value 4 positions */ | |
1876 | { | |
1877 | if (ival < 10000000) | |
1878 | { | |
1879 | ipres = ival / 1000; | |
1880 | iform = "Mbps"; | |
1881 | } | |
1882 | else | |
1883 | { | |
1884 | ipres = ival / 1000000; | |
1885 | iform = "Gbps"; | |
1886 | } | |
1887 | } | |
1888 | else | |
1889 | { | |
1890 | ipres = ival; | |
1891 | } | |
1892 | ||
1893 | if (oval >= 10000) /* input value 4 positions */ | |
1894 | { | |
1895 | if (oval < 10000000) | |
1896 | { | |
1897 | opres = oval / 1000; | |
1898 | oform = "Mbps"; | |
1899 | } | |
1900 | else | |
1901 | { | |
1902 | opres = oval / 1000000; | |
1903 | oform = "Gbps"; | |
1904 | } | |
1905 | } | |
1906 | else | |
1907 | { | |
1908 | opres = oval; | |
1909 | } | |
1910 | ||
1911 | /* | |
1912 | ** calculate busy-percentage for interface | |
1913 | */ | |
1914 | if (sstat->intf.intf[i].speed) /* speed known? */ | |
1915 | { | |
1916 | if (sstat->intf.intf[i].duplex) | |
1917 | busy = (ival > oval ? ival : oval) / | |
1918 | (sstat->intf.intf[i].speed *10); | |
1919 | else | |
1920 | busy = (ival + oval) / | |
1921 | (sstat->intf.intf[i].speed *10); | |
1922 | ||
1923 | snprintf(busyval, sizeof busyval, | |
1924 | "%3lld%%", busy); | |
1925 | } | |
1926 | else | |
1927 | { | |
1928 | strcpy(busyval, "----"); /* speed unknown */ | |
1929 | ||
1930 | busy = 0; | |
1931 | } | |
1932 | ||
1933 | if (netbadness) | |
1934 | badness = busy * 100 / netbadness; | |
1935 | else | |
1936 | badness = 0; | |
1937 | ||
1938 | if (highbadness < badness && | |
1939 | (supportflags & PATCHSTAT) ) | |
1940 | { | |
1941 | highbadness = badness; | |
1942 | *highorderp = MSORTNET; | |
1943 | } | |
1944 | ||
1945 | coloron = syscolorlabel("NET", usecolors, badness); | |
1946 | ||
1947 | printg(" | %-6.6s %4s | pcki %s | pcko %s |" | |
1948 | " si %4lld %s | so %4lld %s |\n", | |
1949 | sstat->intf.intf[i].name, | |
1950 | busyval, | |
1951 | val2valstr(sstat->intf.intf[i].rpack, | |
1952 | format1, 7, avgval, nsecs), | |
1953 | val2valstr(sstat->intf.intf[i].spack, | |
1954 | format2, 7, avgval, nsecs), | |
1955 | ipres, iform, | |
1956 | opres, oform); | |
1957 | ||
1958 | if (coloron) | |
1959 | syscoloroff(coloron); | |
1960 | ||
1961 | curline++; | |
1962 | lin++; | |
1963 | } | |
1964 | } | |
1965 | ||
1966 | /* | |
1967 | ** application statistics | |
1968 | ** | |
1969 | ** WWW: notice that we cause one access ourselves by fetching | |
1970 | ** the statistical counters | |
1971 | */ | |
1972 | #if HTTPSTATS | |
1973 | if (sstat->www.accesses > 1 || fixedhead ) | |
1974 | { | |
1975 | printg("WWW | reqs %s | totKB %s | byt/rq %s | iwork %s |" | |
1976 | " bwork %s |\n", | |
1977 | val2valstr(sstat->www.accesses, format1, 6, | |
1978 | avgval, nsecs), | |
1979 | val2valstr(sstat->www.totkbytes, format2, 6, | |
1980 | avgval, nsecs), | |
1981 | val2valstr(sstat->www.accesses ? | |
1982 | sstat->www.totkbytes*1024/sstat->www.accesses : 0, | |
1983 | format3, 5, 0, 0), | |
1984 | val2valstr(sstat->www.iworkers, format4, 6, 0, 0), | |
1985 | val2valstr(sstat->www.bworkers, format5, 6, 0, 0) ); | |
1986 | curline++; | |
1987 | } | |
1988 | #endif | |
1989 | ||
1990 | /* | |
1991 | ** if the system is hardly loaded, still CPU-ordering of | |
1992 | ** processes is most interesting (instead of memory) | |
1993 | */ | |
1994 | if (highbadness < 70 && *highorderp == MSORTMEM) | |
1995 | *highorderp = MSORTCPU; | |
1996 | ||
1997 | return curline; | |
1998 | } | |
1855 | if (sel->procnamesz && | |
1856 | regexec(&(sel->procregex), curstat->gen.name, 0, NULL, 0)) | |
1857 | return 1; | |
1858 | ||
1859 | return 0; | |
1860 | } | |
1861 | ||
1999 | 1862 | |
2000 | 1863 | /* |
2001 | 1864 | ** sort-functions |
2003 | 1866 | int |
2004 | 1867 | compcpu(const void *a, const void *b) |
2005 | 1868 | { |
2006 | register count_t acpu = ((struct pstat *)a)->cpu.stime + | |
2007 | ((struct pstat *)a)->cpu.utime; | |
2008 | register count_t bcpu = ((struct pstat *)b)->cpu.stime + | |
2009 | ((struct pstat *)b)->cpu.utime; | |
2010 | ||
2011 | if (acpu < bcpu) return 1; | |
2012 | if (acpu > bcpu) return -1; | |
2013 | return compmem(a, b); | |
1869 | register count_t acpu = ((struct pstat *)a)->cpu.stime + | |
1870 | ((struct pstat *)a)->cpu.utime; | |
1871 | register count_t bcpu = ((struct pstat *)b)->cpu.stime + | |
1872 | ((struct pstat *)b)->cpu.utime; | |
1873 | ||
1874 | if (acpu < bcpu) return 1; | |
1875 | if (acpu > bcpu) return -1; | |
1876 | return compmem(a, b); | |
2014 | 1877 | } |
2015 | 1878 | |
2016 | 1879 | int |
2017 | 1880 | compdsk(const void *a, const void *b) |
2018 | 1881 | { |
2019 | register count_t adsk = ((struct pstat *)a)->dsk.rio + | |
2020 | ((struct pstat *)a)->dsk.wio; | |
2021 | register count_t bdsk = ((struct pstat *)b)->dsk.rio + | |
2022 | ((struct pstat *)b)->dsk.wio; | |
2023 | ||
2024 | if (adsk < bdsk) return 1; | |
2025 | if (adsk > bdsk) return -1; | |
2026 | return compcpu(a, b); | |
1882 | register count_t adsk = ((struct pstat *)a)->dsk.rio + | |
1883 | ((struct pstat *)a)->dsk.wio; | |
1884 | register count_t bdsk = ((struct pstat *)b)->dsk.rio + | |
1885 | ((struct pstat *)b)->dsk.wio; | |
1886 | ||
1887 | if (adsk < bdsk) return 1; | |
1888 | if (adsk > bdsk) return -1; | |
1889 | return compcpu(a, b); | |
2027 | 1890 | } |
2028 | 1891 | |
2029 | 1892 | int |
2030 | 1893 | compmem(const void *a, const void *b) |
2031 | 1894 | { |
2032 | register count_t amem = ((struct pstat *)a)->mem.rmem; | |
2033 | register count_t bmem = ((struct pstat *)b)->mem.rmem; | |
2034 | ||
2035 | if (amem < bmem) return 1; | |
2036 | if (amem > bmem) return -1; | |
2037 | return 0; | |
1895 | register count_t amem = ((struct pstat *)a)->mem.rmem; | |
1896 | register count_t bmem = ((struct pstat *)b)->mem.rmem; | |
1897 | ||
1898 | if (amem < bmem) return 1; | |
1899 | if (amem > bmem) return -1; | |
1900 | return 0; | |
2038 | 1901 | } |
2039 | 1902 | |
2040 | 1903 | int |
2041 | 1904 | compnet(const void *a, const void *b) |
2042 | 1905 | { |
2043 | register count_t anet = ((struct pstat *)a)->net.tcpsnd + | |
2044 | ((struct pstat *)a)->net.tcprcv + | |
2045 | ((struct pstat *)a)->net.udpsnd + | |
2046 | ((struct pstat *)a)->net.udprcv + | |
2047 | ((struct pstat *)a)->net.rawsnd + | |
2048 | ((struct pstat *)a)->net.rawrcv ; | |
2049 | register count_t bnet = ((struct pstat *)b)->net.tcpsnd + | |
2050 | ((struct pstat *)b)->net.tcprcv + | |
2051 | ((struct pstat *)b)->net.udpsnd + | |
2052 | ((struct pstat *)b)->net.udprcv + | |
2053 | ((struct pstat *)b)->net.rawsnd + | |
2054 | ((struct pstat *)b)->net.rawrcv ; | |
2055 | ||
2056 | if (anet < bnet) return 1; | |
2057 | if (anet > bnet) return -1; | |
2058 | return compcpu(a, b); | |
1906 | register count_t anet = ((struct pstat *)a)->net.tcpsnd + | |
1907 | ((struct pstat *)a)->net.tcprcv + | |
1908 | ((struct pstat *)a)->net.udpsnd + | |
1909 | ((struct pstat *)a)->net.udprcv + | |
1910 | ((struct pstat *)a)->net.rawsnd + | |
1911 | ((struct pstat *)a)->net.rawrcv ; | |
1912 | register count_t bnet = ((struct pstat *)b)->net.tcpsnd + | |
1913 | ((struct pstat *)b)->net.tcprcv + | |
1914 | ((struct pstat *)b)->net.udpsnd + | |
1915 | ((struct pstat *)b)->net.udprcv + | |
1916 | ((struct pstat *)b)->net.rawsnd + | |
1917 | ((struct pstat *)b)->net.rawrcv ; | |
1918 | ||
1919 | if (anet < bnet) return 1; | |
1920 | if (anet > bnet) return -1; | |
1921 | return compcpu(a, b); | |
2059 | 1922 | } |
2060 | 1923 | |
2061 | 1924 | int |
2062 | 1925 | cpucompar(const void *a, const void *b) |
2063 | 1926 | { |
2064 | register count_t aidle = ((struct percpu *)a)->itime + | |
2065 | ((struct percpu *)a)->wtime; | |
2066 | register count_t bidle = ((struct percpu *)b)->itime + | |
2067 | ((struct percpu *)b)->wtime; | |
2068 | ||
2069 | if (aidle < bidle) return -1; | |
2070 | if (aidle > bidle) return 1; | |
2071 | return 0; | |
1927 | register count_t aidle = ((struct percpu *)a)->itime + | |
1928 | ((struct percpu *)a)->wtime; | |
1929 | register count_t bidle = ((struct percpu *)b)->itime + | |
1930 | ((struct percpu *)b)->wtime; | |
1931 | ||
1932 | if (aidle < bidle) return -1; | |
1933 | if (aidle > bidle) return 1; | |
1934 | return 0; | |
2072 | 1935 | } |
2073 | 1936 | |
2074 | 1937 | int |
2075 | 1938 | diskcompar(const void *a, const void *b) |
2076 | 1939 | { |
2077 | register count_t amsio = ((struct perxdsk *)a)->io_ms; | |
2078 | register count_t bmsio = ((struct perxdsk *)b)->io_ms; | |
2079 | ||
2080 | if (amsio < bmsio) return 1; | |
2081 | if (amsio > bmsio) return -1; | |
2082 | return 0; | |
1940 | register count_t amsio = ((struct perdsk *)a)->io_ms; | |
1941 | register count_t bmsio = ((struct perdsk *)b)->io_ms; | |
1942 | ||
1943 | if (amsio < bmsio) return 1; | |
1944 | if (amsio > bmsio) return -1; | |
1945 | return 0; | |
2083 | 1946 | } |
2084 | 1947 | |
2085 | 1948 | int |
2086 | 1949 | intfcompar(const void *a, const void *b) |
2087 | 1950 | { |
2088 | register count_t afactor=0, bfactor=0; | |
2089 | ||
2090 | count_t aspeed = ((struct perintf *)a)->speed; | |
2091 | count_t bspeed = ((struct perintf *)b)->speed; | |
2092 | char aduplex = ((struct perintf *)a)->duplex; | |
2093 | char bduplex = ((struct perintf *)b)->duplex; | |
2094 | count_t arbyte = ((struct perintf *)a)->rbyte; | |
2095 | count_t brbyte = ((struct perintf *)b)->rbyte; | |
2096 | count_t asbyte = ((struct perintf *)a)->sbyte; | |
2097 | count_t bsbyte = ((struct perintf *)b)->sbyte; | |
2098 | ||
2099 | ||
2100 | /* | |
2101 | ** if speed of first interface known, calculate busy factor | |
2102 | */ | |
2103 | if (aspeed) | |
2104 | { | |
2105 | if (aduplex) | |
2106 | afactor = (arbyte > asbyte ? arbyte : asbyte) / | |
2107 | (aspeed / 10); | |
2108 | else | |
2109 | afactor = (arbyte + asbyte) / (aspeed / 10); | |
2110 | } | |
2111 | ||
2112 | /* | |
2113 | ** if speed of second interface known, calculate busy factor | |
2114 | */ | |
2115 | if (bspeed) | |
2116 | { | |
2117 | if (bduplex) | |
2118 | bfactor = (brbyte > bsbyte ? brbyte : bsbyte) / | |
2119 | (bspeed / 10); | |
2120 | else | |
2121 | bfactor = (brbyte + bsbyte) / (bspeed / 10); | |
2122 | } | |
2123 | ||
2124 | /* | |
2125 | ** compare interfaces | |
2126 | */ | |
2127 | if (aspeed && bspeed) | |
2128 | { | |
2129 | if (afactor < bfactor) return 1; | |
2130 | if (afactor > bfactor) return -1; | |
2131 | return 0; | |
2132 | } | |
2133 | ||
2134 | if (!aspeed && !bspeed) | |
2135 | { | |
2136 | if ((arbyte + asbyte) < (brbyte + bsbyte)) return 1; | |
2137 | if ((arbyte + asbyte) > (brbyte + bsbyte)) return -1; | |
2138 | return 0; | |
2139 | } | |
2140 | ||
2141 | if (aspeed) | |
2142 | return -1; | |
2143 | else | |
2144 | return 1; | |
1951 | register count_t afactor=0, bfactor=0; | |
1952 | ||
1953 | count_t aspeed = ((struct perintf *)a)->speed; | |
1954 | count_t bspeed = ((struct perintf *)b)->speed; | |
1955 | char aduplex = ((struct perintf *)a)->duplex; | |
1956 | char bduplex = ((struct perintf *)b)->duplex; | |
1957 | count_t arbyte = ((struct perintf *)a)->rbyte; | |
1958 | count_t brbyte = ((struct perintf *)b)->rbyte; | |
1959 | count_t asbyte = ((struct perintf *)a)->sbyte; | |
1960 | count_t bsbyte = ((struct perintf *)b)->sbyte; | |
1961 | ||
1962 | ||
1963 | /* | |
1964 | ** if speed of first interface known, calculate busy factor | |
1965 | */ | |
1966 | if (aspeed) | |
1967 | { | |
1968 | if (aduplex) | |
1969 | afactor = (arbyte > asbyte ? arbyte : asbyte) / | |
1970 | (aspeed / 10); | |
1971 | else | |
1972 | afactor = (arbyte + asbyte) / (aspeed / 10); | |
1973 | } | |
1974 | ||
1975 | /* | |
1976 | ** if speed of second interface known, calculate busy factor | |
1977 | */ | |
1978 | if (bspeed) | |
1979 | { | |
1980 | if (bduplex) | |
1981 | bfactor = (brbyte > bsbyte ? brbyte : bsbyte) / | |
1982 | (bspeed / 10); | |
1983 | else | |
1984 | bfactor = (brbyte + bsbyte) / (bspeed / 10); | |
1985 | } | |
1986 | ||
1987 | /* | |
1988 | ** compare interfaces | |
1989 | */ | |
1990 | if (aspeed && bspeed) | |
1991 | { | |
1992 | if (afactor < bfactor) return 1; | |
1993 | if (afactor > bfactor) return -1; | |
1994 | return 0; | |
1995 | } | |
1996 | ||
1997 | if (!aspeed && !bspeed) | |
1998 | { | |
1999 | if ((arbyte + asbyte) < (brbyte + bsbyte)) return 1; | |
2000 | if ((arbyte + asbyte) > (brbyte + bsbyte)) return -1; | |
2001 | return 0; | |
2002 | } | |
2003 | ||
2004 | if (aspeed) | |
2005 | return -1; | |
2006 | else | |
2007 | return 1; | |
2145 | 2008 | } |
2146 | 2009 | |
2147 | 2010 | int |
2148 | 2011 | compusr(const void *a, const void *b) |
2149 | 2012 | { |
2150 | register int uida = ((struct pstat *)a)->gen.ruid; | |
2151 | register int uidb = ((struct pstat *)b)->gen.ruid; | |
2152 | ||
2153 | if (uida > uidb) return 1; | |
2154 | if (uida < uidb) return -1; | |
2155 | return 0; | |
2013 | register int uida = ((struct pstat *)a)->gen.ruid; | |
2014 | register int uidb = ((struct pstat *)b)->gen.ruid; | |
2015 | ||
2016 | if (uida > uidb) return 1; | |
2017 | if (uida < uidb) return -1; | |
2018 | return 0; | |
2156 | 2019 | } |
2157 | 2020 | |
2158 | 2021 | int |
2159 | 2022 | compnam(const void *a, const void *b) |
2160 | 2023 | { |
2161 | register char *nama = ((struct pstat *)a)->gen.name; | |
2162 | register char *namb = ((struct pstat *)b)->gen.name; | |
2163 | ||
2164 | return strcmp(nama, namb); | |
2024 | register char *nama = ((struct pstat *)a)->gen.name; | |
2025 | register char *namb = ((struct pstat *)b)->gen.name; | |
2026 | ||
2027 | return strcmp(nama, namb); | |
2165 | 2028 | } |
2166 | 2029 | |
2167 | 2030 | /* |
2168 | ** print the label of a system-statistics line and switch on | |
2169 | ** colors if needed | |
2031 | ** handle modifications from the /etc/atoprc and ~/.atoprc file | |
2170 | 2032 | */ |
2171 | static int | |
2172 | syscolorlabel(char *labeltext, int usecolors, unsigned int badness) | |
2173 | { | |
2174 | if (usecolors) | |
2175 | { | |
2176 | if (badness >= 100) | |
2177 | { | |
2178 | attron(A_BOLD); | |
2179 | attron(COLOR_PAIR(COLORHIGH)); | |
2180 | attron (A_BLINK); | |
2181 | printg(labeltext); | |
2182 | attroff(A_BLINK); | |
2183 | return COLORHIGH; | |
2184 | } | |
2185 | ||
2186 | if (almostcrit && badness >= almostcrit) | |
2187 | { | |
2188 | attron(A_BOLD); | |
2189 | attron(COLOR_PAIR(COLORMED)); | |
2190 | printg(labeltext); | |
2191 | return COLORMED; | |
2192 | } | |
2193 | } | |
2194 | ||
2195 | /* | |
2196 | ** no colors required or no reason to show colors | |
2197 | */ | |
2198 | printg(labeltext); | |
2199 | return 0; | |
2200 | } | |
2201 | ||
2202 | static void | |
2203 | syscoloroff(char curcolor) | |
2204 | { | |
2205 | attroff(A_BOLD); | |
2206 | attroff(COLOR_PAIR(curcolor)); | |
2207 | } | |
2208 | ||
2209 | /* | |
2210 | ** handle modifications from the ~/.atoprc file | |
2211 | */ | |
2212 | void | |
2213 | do_cpucritperc(char *val) | |
2214 | { | |
2215 | int value = atoi(val); | |
2216 | ||
2217 | if ( !numeric(val)) | |
2218 | { | |
2219 | fprintf(stderr, ".atoprc: cpucritperc value not numeric\n"); | |
2220 | exit(1); | |
2221 | } | |
2222 | ||
2223 | if (value < 0 || value > 100) | |
2224 | { | |
2225 | fprintf(stderr, | |
2226 | ".atoprc: cpucritperc value not in range 0-100\n"); | |
2227 | exit(1); | |
2228 | } | |
2229 | ||
2230 | cpubadness = value; | |
2231 | } | |
2232 | ||
2233 | void | |
2234 | do_memcritperc(char *val) | |
2235 | { | |
2236 | int value = atoi(val); | |
2237 | ||
2238 | if ( !numeric(val)) | |
2239 | { | |
2240 | fprintf(stderr, ".atoprc: memcritperc value not numeric\n"); | |
2241 | exit(1); | |
2242 | } | |
2243 | ||
2244 | if (value < 0 || value > 100) | |
2245 | { | |
2246 | fprintf(stderr, | |
2247 | ".atoprc: memcritperc value not in range 0-100\n"); | |
2248 | exit(1); | |
2249 | } | |
2250 | ||
2251 | membadness = value; | |
2252 | } | |
2253 | ||
2254 | void | |
2255 | do_swpcritperc(char *val) | |
2256 | { | |
2257 | int value = atoi(val); | |
2258 | ||
2259 | if ( !numeric(val)) | |
2260 | { | |
2261 | fprintf(stderr, ".atoprc: swpcritperc value not numeric\n"); | |
2262 | exit(1); | |
2263 | } | |
2264 | ||
2265 | if (value < 0 || value > 100) | |
2266 | { | |
2267 | fprintf(stderr, | |
2268 | ".atoprc: swpcritperc value not in range 0-100\n"); | |
2269 | exit(1); | |
2270 | } | |
2271 | ||
2272 | swpbadness = value; | |
2273 | } | |
2274 | ||
2275 | void | |
2276 | do_dskcritperc(char *val) | |
2277 | { | |
2278 | int value = atoi(val); | |
2279 | ||
2280 | if ( !numeric(val)) | |
2281 | { | |
2282 | fprintf(stderr, ".atoprc: dskcritperc value not numeric\n"); | |
2283 | exit(1); | |
2284 | } | |
2285 | ||
2286 | if (value < 0 || value > 100) | |
2287 | { | |
2288 | fprintf(stderr, | |
2289 | ".atoprc: dskcritperc value not in range 0-100\n"); | |
2290 | exit(1); | |
2291 | } | |
2292 | ||
2293 | dskbadness = value; | |
2294 | } | |
2295 | ||
2296 | void | |
2297 | do_netcritperc(char *val) | |
2298 | { | |
2299 | int value = atoi(val); | |
2300 | ||
2301 | if ( !numeric(val)) | |
2302 | { | |
2303 | fprintf(stderr, ".atoprc: netcritperc value not numeric\n"); | |
2304 | exit(1); | |
2305 | } | |
2306 | ||
2307 | if (value < 0 || value > 100) | |
2308 | { | |
2309 | fprintf(stderr, | |
2310 | ".atoprc: netcritperc value not in range 0-100\n"); | |
2311 | exit(1); | |
2312 | } | |
2313 | ||
2314 | netbadness = value; | |
2315 | } | |
2316 | ||
2317 | void | |
2318 | do_swoutcritsec(char *val) | |
2319 | { | |
2320 | int value = atoi(val); | |
2321 | ||
2322 | if ( !numeric(val)) | |
2323 | { | |
2324 | fprintf(stderr, ".atoprc: swoutcritsec value not numeric\n"); | |
2325 | exit(1); | |
2326 | } | |
2327 | ||
2328 | if (value < 0) | |
2329 | { | |
2330 | fprintf(stderr, | |
2331 | ".atoprc: swoutcritsec value less then 0\n"); | |
2332 | exit(1); | |
2333 | } | |
2334 | ||
2335 | pagbadness = value; | |
2336 | } | |
2337 | ||
2338 | void | |
2339 | do_almostcrit(char *val) | |
2340 | { | |
2341 | int value = atoi(val); | |
2342 | ||
2343 | if ( !numeric(val)) | |
2344 | { | |
2345 | fprintf(stderr, ".atoprc: almostcrit value not numeric\n"); | |
2346 | exit(1); | |
2347 | } | |
2348 | ||
2349 | if (value < 0 || value > 99) | |
2350 | { | |
2351 | fprintf(stderr, | |
2352 | ".atoprc: almostcrit value not in range 0-99\n"); | |
2353 | exit(1); | |
2354 | } | |
2355 | ||
2356 | almostcrit = value; | |
2357 | } | |
2033 | int | |
2034 | get_posval(char *name, char *val) | |
2035 | { | |
2036 | int value = atoi(val); | |
2037 | ||
2038 | if ( !numeric(val)) | |
2039 | { | |
2040 | fprintf(stderr, "atoprc: %s value %s not a (positive) numeric\n", | |
2041 | name, val); | |
2042 | exit(1); | |
2043 | } | |
2044 | ||
2045 | if (value < 0) | |
2046 | { | |
2047 | fprintf(stderr, | |
2048 | "atoprc: %s value %d not positive\n", | |
2049 | name, value); | |
2050 | exit(1); | |
2051 | } | |
2052 | ||
2053 | return value; | |
2054 | } | |
2055 | ||
2056 | int | |
2057 | get_perc(char *name, char *val) | |
2058 | { | |
2059 | int value = get_posval(name, val); | |
2060 | ||
2061 | if (value < 0 || value > 100) | |
2062 | { | |
2063 | fprintf(stderr, "atoprc: %s value %d not in range 0-100\n", | |
2064 | name, value); | |
2065 | exit(1); | |
2066 | } | |
2067 | ||
2068 | return value; | |
2069 | } | |
2070 | ||
2071 | void | |
2072 | do_cpucritperc(char *name, char *val) | |
2073 | { | |
2074 | cpubadness = get_perc(name, val); | |
2075 | } | |
2076 | ||
2077 | void | |
2078 | do_memcritperc(char *name, char *val) | |
2079 | { | |
2080 | membadness = get_perc(name, val); | |
2081 | } | |
2082 | ||
2083 | void | |
2084 | do_swpcritperc(char *name, char *val) | |
2085 | { | |
2086 | swpbadness = get_perc(name, val); | |
2087 | } | |
2088 | ||
2089 | void | |
2090 | do_dskcritperc(char *name, char *val) | |
2091 | { | |
2092 | dskbadness = get_perc(name, val); | |
2093 | } | |
2094 | ||
2095 | void | |
2096 | do_netcritperc(char *name, char *val) | |
2097 | { | |
2098 | netbadness = get_perc(name, val); | |
2099 | } | |
2100 | ||
2101 | void | |
2102 | do_swoutcritsec(char *name, char *val) | |
2103 | { | |
2104 | pagbadness = get_posval(name, val); | |
2105 | } | |
2106 | ||
2107 | void | |
2108 | do_almostcrit(char *name, char *val) | |
2109 | { | |
2110 | almostcrit = get_perc(name, val); | |
2111 | } | |
2112 | ||
2113 | void | |
2114 | do_ownsysprcline(char *name, char *val) | |
2115 | { | |
2116 | make_sys_prints(sysprcline, MAXITEMS, val, prcsyspdefs, name); | |
2117 | } | |
2118 | ||
2119 | void | |
2120 | do_ownallcpuline(char *name, char *val) | |
2121 | { | |
2122 | make_sys_prints(allcpuline, MAXITEMS, val, cpusyspdefs, name); | |
2123 | } | |
2124 | ||
2125 | void | |
2126 | do_ownindivcpuline(char *name, char *val) | |
2127 | { | |
2128 | make_sys_prints(indivcpuline, MAXITEMS, val, cpisyspdefs, name); | |
2129 | } | |
2130 | ||
2131 | void | |
2132 | do_owncplline(char *name, char *val) | |
2133 | { | |
2134 | make_sys_prints(cplline, MAXITEMS, val, cplsyspdefs, name); | |
2135 | } | |
2136 | ||
2137 | void | |
2138 | do_ownmemline(char *name, char *val) | |
2139 | { | |
2140 | make_sys_prints(memline, MAXITEMS, val, memsyspdefs, name); | |
2141 | } | |
2142 | ||
2143 | void | |
2144 | do_ownswpline(char *name, char *val) | |
2145 | { | |
2146 | make_sys_prints(swpline, MAXITEMS, val, swpsyspdefs, name); | |
2147 | } | |
2148 | ||
2149 | void | |
2150 | do_ownpagline(char *name, char *val) | |
2151 | { | |
2152 | make_sys_prints(pagline, MAXITEMS, val, pagsyspdefs, name); | |
2153 | } | |
2154 | ||
2155 | void | |
2156 | do_owndskline(char *name, char *val) | |
2157 | { | |
2158 | make_sys_prints(dskline, MAXITEMS, val, dsksyspdefs, name); | |
2159 | } | |
2160 | ||
2161 | void | |
2162 | do_ownnettransportline(char *name, char *val) | |
2163 | { | |
2164 | make_sys_prints(nettransportline, MAXITEMS, val, nettranssyspdefs, name); | |
2165 | } | |
2166 | ||
2167 | void | |
2168 | do_ownnetnetline(char *name, char *val) | |
2169 | { | |
2170 | make_sys_prints(netnetline, MAXITEMS, val, netnetsyspdefs, name); | |
2171 | } | |
2172 | ||
2173 | void | |
2174 | do_ownnetinterfaceline(char *name, char *val) | |
2175 | { | |
2176 | make_sys_prints(netinterfaceline, MAXITEMS, val, netintfsyspdefs, name); | |
2177 | } | |
2178 | ||
2179 | void | |
2180 | do_ownprocline(char *name, char *val) | |
2181 | { | |
2182 | make_proc_prints(ownprocs, MAXITEMS, val, name); | |
2183 | } |
0 | /* | |
1 | ** ATOP - System & Process Monitor | |
2 | ** | |
3 | ** The program 'atop' offers the possibility to view the activity of | |
4 | ** the system on system-level as well as process-level. | |
5 | ** | |
6 | ** This source-file contains the Linux-specific functions to calculate | |
7 | ** figures to be visualized. | |
8 | ** ========================================================================== | |
9 | ** Author: JC van Winkel - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: jc@ATComputing.nl | |
11 | ** Date: November 2009 | |
12 | ** -------------------------------------------------------------------------- | |
13 | ** Copyright (C) 2009 JC van Winkel | |
14 | ** | |
15 | ** This program is free software; you can redistribute it and/or modify it | |
16 | ** under the terms of the GNU General Public License as published by the | |
17 | ** Free Software Foundation; either version 2, or (at your option) any | |
18 | ** later version. | |
19 | ** | |
20 | ** This program is distributed in the hope that it will be useful, but | |
21 | ** WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
23 | ** See the GNU General Public License for more details. | |
24 | ** | |
25 | ** You should have received a copy of the GNU General Public License | |
26 | ** along with this program; if not, write to the Free Software | |
27 | ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
28 | ** -------------------------------------------------------------------------- | |
29 | ** | |
30 | ** $Log: showlinux.h,v $ | |
31 | ** Initial revision | |
32 | ** | |
33 | ** Initial | |
34 | ** | |
35 | */ | |
36 | #define MAXITEMS 80 /* The maximum number of items per line */ | |
37 | ||
38 | /* | |
39 | * structure for extra parameters for system related data | |
40 | */ | |
41 | typedef struct { | |
42 | count_t totut; | |
43 | count_t totst; | |
44 | int nact; | |
45 | int nproc; | |
46 | int ntrun; | |
47 | int ntslpi; | |
48 | int ntslpu; | |
49 | int nzomb; | |
50 | int nexit; | |
51 | int avgval; | |
52 | int nsecs; | |
53 | count_t mstot; | |
54 | count_t iotot; | |
55 | struct perdsk *perdsk; | |
56 | int index; | |
57 | count_t cputot; | |
58 | count_t percputot; | |
59 | } extraparam; | |
60 | ||
61 | /***************************************************************/ | |
62 | /* | |
63 | * structure for system print-list | |
64 | */ | |
65 | typedef struct { | |
66 | char *configname; // name as used to | |
67 | // config print line | |
68 | char* (*doconvert)(void *, void *); // pointer to conv function | |
69 | } sys_printdef; | |
70 | ||
71 | ||
72 | /* | |
73 | * structure for system print-list with priority | |
74 | * in case of leck of screen space, lowest priority items will be | |
75 | * removed first | |
76 | */ | |
77 | typedef struct | |
78 | { | |
79 | sys_printdef *f; | |
80 | int prio; | |
81 | } sys_printpair; | |
82 | ||
83 | ||
84 | ||
85 | /* | |
86 | ** structure for process print-list | |
87 | */ | |
88 | typedef struct | |
89 | { | |
90 | char *head; // column header | |
91 | char *configname; // name as used to config print line | |
92 | char *(*doactiveconvert)(struct pstat *,int,int); | |
93 | // pointer to conv function | |
94 | // for active process | |
95 | char *(*doexitconvert) (struct pstat *,int,int); | |
96 | // pointer to conv function | |
97 | // for exited process | |
98 | int width; // required width | |
99 | int varwidth; // width may grow (eg cmd params) | |
100 | } proc_printdef; | |
101 | ||
102 | ||
103 | typedef struct | |
104 | { | |
105 | proc_printdef *f; | |
106 | int prio; | |
107 | } proc_printpair; | |
108 | ||
109 | void showsysline(sys_printpair* elemptr, | |
110 | struct sstat* sstat, extraparam *extra, | |
111 | char *labeltext, int usecolors, unsigned int badness); | |
112 | ||
113 | ||
114 | void showhdrline(proc_printpair* elemptr, int curlist, int totlist, | |
115 | char showorder, char autosort) ; | |
116 | void showprocline(proc_printpair* elemptr, struct pstat *curstat, | |
117 | double perc, int nsecs, int avgval) ; | |
118 | int procsuppress(struct pstat *, struct selection *); | |
119 | ||
120 | extern sys_printdef *prcsyspdefs[]; | |
121 | extern sys_printdef *cpusyspdefs[]; | |
122 | extern sys_printdef *cpisyspdefs[]; | |
123 | extern sys_printdef *cplsyspdefs[]; | |
124 | extern sys_printdef *memsyspdefs[]; | |
125 | extern sys_printdef *swpsyspdefs[]; | |
126 | extern sys_printdef *pagsyspdefs[]; | |
127 | extern sys_printdef *dsksyspdefs[]; | |
128 | extern sys_printdef *nettranssyspdefs[]; | |
129 | extern sys_printdef *netnetsyspdefs[]; | |
130 | extern sys_printdef *netintfsyspdefs[]; | |
131 | ||
132 | extern sys_printdef syspdef_PRCSYS; | |
133 | extern sys_printdef syspdef_PRCUSER; | |
134 | extern sys_printdef syspdef_PRCNPROC; | |
135 | extern sys_printdef syspdef_PRCNRUNNING; | |
136 | extern sys_printdef syspdef_PRCNSLEEPING; | |
137 | extern sys_printdef syspdef_PRCNDSLEEPING; | |
138 | extern sys_printdef syspdef_PRCNZOMBIE; | |
139 | extern sys_printdef syspdef_PRCCLONES; | |
140 | extern sys_printdef syspdef_PRCNNEXIT; | |
141 | extern sys_printdef syspdef_CPUSYS; | |
142 | extern sys_printdef syspdef_CPUUSER; | |
143 | extern sys_printdef syspdef_CPUIRQ; | |
144 | extern sys_printdef syspdef_CPUIDLE; | |
145 | extern sys_printdef syspdef_CPUWAIT; | |
146 | extern sys_printdef syspdef_CPUISYS; | |
147 | extern sys_printdef syspdef_CPUIUSER; | |
148 | extern sys_printdef syspdef_CPUIIRQ; | |
149 | extern sys_printdef syspdef_CPUIIDLE; | |
150 | extern sys_printdef syspdef_CPUIWAIT; | |
151 | extern sys_printdef syspdef_CPUISTEAL; | |
152 | extern sys_printdef syspdef_CPUIFREQ; | |
153 | extern sys_printdef syspdef_CPUFREQ; | |
154 | extern sys_printdef syspdef_CPUSCALE; | |
155 | extern sys_printdef syspdef_CPUISCALE; | |
156 | extern sys_printdef syspdef_CPUSTEAL; | |
157 | extern sys_printdef syspdef_CPUISTEAL; | |
158 | extern sys_printdef syspdef_CPUGUEST; | |
159 | extern sys_printdef syspdef_CPUIGUEST; | |
160 | extern sys_printdef syspdef_CPLAVG1; | |
161 | extern sys_printdef syspdef_CPLAVG5; | |
162 | extern sys_printdef syspdef_CPLAVG15; | |
163 | extern sys_printdef syspdef_CPLCSW; | |
164 | extern sys_printdef syspdef_CPLNUMCPU; | |
165 | extern sys_printdef syspdef_CPLINTR; | |
166 | extern sys_printdef syspdef_MEMTOT; | |
167 | extern sys_printdef syspdef_MEMFREE; | |
168 | extern sys_printdef syspdef_MEMCACHE; | |
169 | extern sys_printdef syspdef_MEMDIRTY; | |
170 | extern sys_printdef syspdef_MEMBUFFER; | |
171 | extern sys_printdef syspdef_MEMSLAB; | |
172 | extern sys_printdef syspdef_SWPTOT; | |
173 | extern sys_printdef syspdef_SWPFREE; | |
174 | extern sys_printdef syspdef_SWPCOMMITTED; | |
175 | extern sys_printdef syspdef_SWPCOMMITLIM; | |
176 | extern sys_printdef syspdef_PAGSCAN; | |
177 | extern sys_printdef syspdef_PAGSTALL; | |
178 | extern sys_printdef syspdef_PAGSWIN; | |
179 | extern sys_printdef syspdef_PAGSWOUT; | |
180 | extern sys_printdef syspdef_DSKNAME; | |
181 | extern sys_printdef syspdef_DSKBUSY; | |
182 | extern sys_printdef syspdef_DSKNREAD; | |
183 | extern sys_printdef syspdef_DSKNWRITE; | |
184 | extern sys_printdef syspdef_DSKMBPERSECWR; | |
185 | extern sys_printdef syspdef_DSKMBPERSECRD; | |
186 | extern sys_printdef syspdef_DSKKBPERWR; | |
187 | extern sys_printdef syspdef_DSKKBPERRD; | |
188 | extern sys_printdef syspdef_DSKAVQUEUE; | |
189 | extern sys_printdef syspdef_DSKAVIO; | |
190 | extern sys_printdef syspdef_NETTRANSPORT; | |
191 | extern sys_printdef syspdef_NETTCPI; | |
192 | extern sys_printdef syspdef_NETTCPO; | |
193 | extern sys_printdef syspdef_NETTCPACTOPEN; | |
194 | extern sys_printdef syspdef_NETTCPPASVOPEN; | |
195 | extern sys_printdef syspdef_NETTCPRETRANS; | |
196 | extern sys_printdef syspdef_NETTCPINERR; | |
197 | extern sys_printdef syspdef_NETTCPORESET; | |
198 | extern sys_printdef syspdef_NETUDPNOPORT; | |
199 | extern sys_printdef syspdef_NETUDPINERR; | |
200 | extern sys_printdef syspdef_NETUDPI; | |
201 | extern sys_printdef syspdef_NETUDPO; | |
202 | extern sys_printdef syspdef_NETNETWORK; | |
203 | extern sys_printdef syspdef_NETIPI; | |
204 | extern sys_printdef syspdef_NETIPO; | |
205 | extern sys_printdef syspdef_NETIPFRW; | |
206 | extern sys_printdef syspdef_NETIPDELIV; | |
207 | extern sys_printdef syspdef_NETICMPIN; | |
208 | extern sys_printdef syspdef_NETICMPOUT; | |
209 | extern sys_printdef syspdef_NETNAME; | |
210 | extern sys_printdef syspdef_NETPCKI; | |
211 | extern sys_printdef syspdef_NETPCKO; | |
212 | extern sys_printdef syspdef_NETSPEEDIN; | |
213 | extern sys_printdef syspdef_NETSPEEDOUT; | |
214 | extern sys_printdef syspdef_NETCOLLIS; | |
215 | extern sys_printdef syspdef_NETMULTICASTIN; | |
216 | extern sys_printdef syspdef_NETRCVERR; | |
217 | extern sys_printdef syspdef_NETSNDERR; | |
218 | extern sys_printdef syspdef_NETRCVDROP; | |
219 | extern sys_printdef syspdef_NETSNDDROP; | |
220 | extern sys_printdef syspdef_BLANKBOX; | |
221 | ||
222 | ||
223 | /* | |
224 | ** functions that print ???? for unavailable data | |
225 | */ | |
226 | char *procprt_NOTAVAIL_4(struct pstat *curstat, int avgval, int nsecs); | |
227 | char *procprt_NOTAVAIL_5(struct pstat *curstat, int avgval, int nsecs); | |
228 | char *procprt_NOTAVAIL_6(struct pstat *curstat, int avgval, int nsecs); | |
229 | char *procprt_NOTAVAIL_7(struct pstat *curstat, int avgval, int nsecs); | |
230 | ||
231 | extern proc_printdef *allprocpdefs[]; | |
232 | extern proc_printdef procprt_PID; | |
233 | extern proc_printdef procprt_PPID; | |
234 | extern proc_printdef procprt_SYSCPU; | |
235 | extern proc_printdef procprt_USRCPU; | |
236 | extern proc_printdef procprt_VGROW; | |
237 | extern proc_printdef procprt_RGROW; | |
238 | extern proc_printdef procprt_MINFLT; | |
239 | extern proc_printdef procprt_MAJFLT; | |
240 | extern proc_printdef procprt_VSTEXT; | |
241 | extern proc_printdef procprt_VSIZE; | |
242 | extern proc_printdef procprt_RSIZE; | |
243 | extern proc_printdef procprt_CMD; | |
244 | extern proc_printdef procprt_RUID; | |
245 | extern proc_printdef procprt_EUID; | |
246 | extern proc_printdef procprt_SUID; | |
247 | extern proc_printdef procprt_FSUID; | |
248 | extern proc_printdef procprt_RGID; | |
249 | extern proc_printdef procprt_EGID; | |
250 | extern proc_printdef procprt_SGID; | |
251 | extern proc_printdef procprt_FSGID; | |
252 | extern proc_printdef procprt_STDATE; | |
253 | extern proc_printdef procprt_STTIME; | |
254 | extern proc_printdef procprt_ENDATE; | |
255 | extern proc_printdef procprt_ENTIME; | |
256 | extern proc_printdef procprt_THR; | |
257 | extern proc_printdef procprt_TRUN; | |
258 | extern proc_printdef procprt_TSLPI; | |
259 | extern proc_printdef procprt_TSLPU; | |
260 | extern proc_printdef procprt_POLI; | |
261 | extern proc_printdef procprt_NICE; | |
262 | extern proc_printdef procprt_PRI; | |
263 | extern proc_printdef procprt_RTPR; | |
264 | extern proc_printdef procprt_CURCPU; | |
265 | extern proc_printdef procprt_ST; | |
266 | extern proc_printdef procprt_EXC; | |
267 | extern proc_printdef procprt_S; | |
268 | extern proc_printdef procprt_COMMAND_LINE; | |
269 | extern proc_printdef procprt_NPROCS; | |
270 | extern proc_printdef procprt_RDDSK; | |
271 | extern proc_printdef procprt_WRDSK; | |
272 | extern proc_printdef procprt_NRDDSK_NOACCT; | |
273 | extern proc_printdef procprt_NWRDSK_NOACCT; | |
274 | extern proc_printdef procprt_RDDSK_IOSTAT; | |
275 | extern proc_printdef procprt_WRDSK_IOSTAT; | |
276 | extern proc_printdef procprt_WCANCEL_IOSTAT; | |
277 | extern proc_printdef procprt_AVGRSZ; | |
278 | extern proc_printdef procprt_AVGWSZ; | |
279 | extern proc_printdef procprt_TOTRSZ; | |
280 | extern proc_printdef procprt_TOTWSZ; | |
281 | extern proc_printdef procprt_TOTRSZ_NOACCT; | |
282 | extern proc_printdef procprt_TOTWSZ_NOACCT; | |
283 | extern proc_printdef procprt_TCPRCV; | |
284 | extern proc_printdef procprt_TCPRASZ; | |
285 | extern proc_printdef procprt_TCPSND; | |
286 | extern proc_printdef procprt_TCPSASZ; | |
287 | extern proc_printdef procprt_UDPRCV; | |
288 | extern proc_printdef procprt_UDPRASZ; | |
289 | extern proc_printdef procprt_UDPSND; | |
290 | extern proc_printdef procprt_UDPSASZ; | |
291 | extern proc_printdef procprt_RNET; | |
292 | extern proc_printdef procprt_SORTITEM; | |
293 | extern proc_printdef procprt_SNET; | |
294 | extern proc_printdef procprt_RAWRCV; | |
295 | extern proc_printdef procprt_RAWSND; | |
296 | ||
297 | ||
298 | ||
299 | extern char *procprt_NRDDSK_ae(struct pstat *, int, int); | |
300 | extern char *procprt_NWRDSK_a(struct pstat *, int, int); | |
301 | extern char *procprt_NRDDSK_e(struct pstat *, int, int); | |
302 | extern char *procprt_NWRDSK_e(struct pstat *, int, int); | |
303 | extern char *procprt_RDDSK_IOSTAT_a(struct pstat *, int, int); | |
304 | extern char *procprt_RDDSK_IOSTAT_e(struct pstat *, int, int); | |
305 | extern char *procprt_WRDSK_IOSTAT_a(struct pstat *, int, int); | |
306 | extern char *procprt_WRDSK_IOSTAT_e(struct pstat *, int, int); | |
307 | ||
308 | extern char *procprt_SNET_a(struct pstat *, int, int); | |
309 | extern char *procprt_SNET_e(struct pstat *, int, int); | |
310 | extern char *procprt_RNET_a(struct pstat *, int, int); | |
311 | extern char *procprt_RNET_e(struct pstat *, int, int); | |
312 | extern char *procprt_TCPSND_a(struct pstat *, int, int); | |
313 | extern char *procprt_TCPRCV_a(struct pstat *, int, int); | |
314 | extern char *procprt_UDPSND_a(struct pstat *, int, int); | |
315 | extern char *procprt_UDPRCV_a(struct pstat *, int, int); | |
316 | extern char *procprt_TCPSASZ_a(struct pstat *, int, int); | |
317 | extern char *procprt_TCPRASZ_a(struct pstat *, int, int); | |
318 | extern char *procprt_UDPSASZ_a(struct pstat *, int, int); | |
319 | extern char *procprt_UDPRASZ_a(struct pstat *, int, int); | |
320 | extern char *procprt_TCPSND_e(struct pstat *, int, int); | |
321 | extern char *procprt_TCPRCV_e(struct pstat *, int, int); | |
322 | extern char *procprt_UDPSND_e(struct pstat *, int, int); | |
323 | extern char *procprt_UDPRCV_e(struct pstat *, int, int); | |
324 | extern char *procprt_TCPSASZ_e(struct pstat *, int, int); | |
325 | extern char *procprt_TCPRASZ_e(struct pstat *, int, int); | |
326 | extern char *procprt_UDPSASZ_e(struct pstat *, int, int); | |
327 | extern char *procprt_UDPRASZ_e(struct pstat *, int, int); | |
328 | extern char *procprt_RAWSND_e(struct pstat *, int, int); | |
329 | extern char *procprt_RAWRCV_e(struct pstat *, int, int); | |
330 | extern char *procprt_RAWSND_a(struct pstat *, int, int); | |
331 | extern char *procprt_RAWRCV_a(struct pstat *, int, int); |
0 | /* | |
1 | ** ATOP - System & Process Monitor | |
2 | ** | |
3 | ** The program 'atop' offers the possibility to view the activity of | |
4 | ** the system on system-level as well as process-level. | |
5 | ** | |
6 | ** This source-file contains the Linux-specific functions to calculate | |
7 | ** figures to be visualized. | |
8 | ** ========================================================================== | |
9 | ** Author: JC van Winkel - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: jc@ATComputing.nl | |
11 | ** Date: November 2009 | |
12 | ** -------------------------------------------------------------------------- | |
13 | ** Copyright (C) 2009 JC van Winkel | |
14 | ** | |
15 | ** This program is free software; you can redistribute it and/or modify it | |
16 | ** under the terms of the GNU General Public License as published by the | |
17 | ** Free Software Foundation; either version 2, or (at your option) any | |
18 | ** later version. | |
19 | ** | |
20 | ** This program is distributed in the hope that it will be useful, but | |
21 | ** WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
23 | ** See the GNU General Public License for more details. | |
24 | ** | |
25 | ** You should have received a copy of the GNU General Public License | |
26 | ** along with this program; if not, write to the Free Software | |
27 | ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
28 | ** -------------------------------------------------------------------------- | |
29 | ** | |
30 | ** $Log: showprocs.c,v $ | |
31 | ** Revision 1.13 2010/11/12 06:11:58 gerlof | |
32 | ** Sometimes segmentation-fault on particular CPU-types | |
33 | ** due to memcpy i.s.o. memmove when moving memory in overlap. | |
34 | ** | |
35 | ** Revision 1.12 2010/04/23 14:06:42 gerlof | |
36 | ** Added special routined for uid/gid not available for exited processes. | |
37 | ** | |
38 | ** Revision 1.11 2010/01/16 12:54:08 gerlof | |
39 | ** Minor change for CPUNR. | |
40 | ** | |
41 | ** Revision 1.10 2010/01/16 11:37:25 gerlof | |
42 | ** Corrected counters for patched kernels (JC van Winkel). | |
43 | ** | |
44 | ** Revision 1.9 2010/01/08 13:44:47 gerlof | |
45 | ** Added policies batch, iso and idle for scheduling class. | |
46 | ** | |
47 | ** Revision 1.8 2010/01/08 11:25:13 gerlof | |
48 | ** Corrected column-width and priorities of network-stats. | |
49 | ** | |
50 | ** Revision 1.7 2010/01/03 18:26:53 gerlof | |
51 | ** Consistent naming of columns for process-related info. | |
52 | ** | |
53 | ** Revision 1.6 2009/12/19 21:03:21 gerlof | |
54 | ** Alignment of CMD column (JC van Winkel). | |
55 | ** | |
56 | ** Revision 1.5 2009/12/12 10:11:49 gerlof | |
57 | ** Register and display end date and end time for process. | |
58 | ** | |
59 | ** Revision 1.4 2009/12/12 09:05:56 gerlof | |
60 | ** Corrected cumulated disk I/O per user/program (JC van Winkel). | |
61 | ** | |
62 | ** Revision 1.3 2009/12/10 14:01:52 gerlof | |
63 | ** Add EUID, SUID and FSUID (and similar for GID's). | |
64 | ** | |
65 | ** Revision 1.2 2009/12/10 11:56:22 gerlof | |
66 | ** Various bug-solutions. | |
67 | ** | |
68 | ** Revision 1.1 2009/12/10 09:31:23 gerlof | |
69 | ** Initial revision | |
70 | ** | |
71 | ** Initial revision | |
72 | ** | |
73 | ** | |
74 | ** Initial | |
75 | ** | |
76 | */ | |
77 | ||
78 | static const char rcsid[] = "$Id: showprocs.c,v 1.13 2010/11/12 06:11:58 gerlof Exp $"; | |
79 | ||
80 | #include <sys/types.h> | |
81 | #include <sys/param.h> | |
82 | #include <sys/stat.h> | |
83 | #include <signal.h> | |
84 | #include <time.h> | |
85 | #include <stdio.h> | |
86 | #include <stdlib.h> | |
87 | #include <string.h> | |
88 | #include <errno.h> | |
89 | #include <fcntl.h> | |
90 | #include <termio.h> | |
91 | #include <unistd.h> | |
92 | #include <stdarg.h> | |
93 | #include <curses.h> | |
94 | #include <pwd.h> | |
95 | #include <grp.h> | |
96 | #include <regex.h> | |
97 | ||
98 | #include "atop.h" | |
99 | #include "photoproc.h" | |
100 | #include "photosyst.h" | |
101 | #include "showgeneric.h" | |
102 | #include "showlinux.h" | |
103 | ||
104 | ||
105 | static char *columnhead[] = { | |
106 | [MSORTCPU]= "CPU", [MSORTMEM]= "MEM", | |
107 | [MSORTDSK]= "DSK", [MSORTNET]= "NET", | |
108 | }; | |
109 | ||
110 | ||
111 | /***************************************************************/ | |
112 | static int *colspacings; // ugly static var, | |
113 | // but saves a lot of recomputations | |
114 | // points to table with intercolumn | |
115 | // spacings | |
116 | static proc_printpair newelems[MAXITEMS]; | |
117 | // ugly static var, | |
118 | // but saves a lot of recomputations | |
119 | // contains the actual list of items to | |
120 | // be printed | |
121 | // | |
122 | // | |
123 | /***************************************************************/ | |
124 | /* | |
125 | * gettotwidth: calculate the sum of widths and number of columns | |
126 | * Also copys the printpair elements to the static array newelems | |
127 | * for later removal of lower priority elements. | |
128 | * Params: | |
129 | * elemptr: the array of what to print | |
130 | * nitems: (ref) returns the number of printitems in the array | |
131 | * sumwidth: (ref) returns the total width of the printitems in the array | |
132 | * varwidth: (ref) returns the number of variable width items in the array | |
133 | */ | |
134 | void | |
135 | gettotwidth(proc_printpair* elemptr, int *nitems, int *sumwidth, int* varwidth) | |
136 | { | |
137 | int i; | |
138 | int col; | |
139 | int varw=0; | |
140 | ||
141 | for (i=0, col=0; elemptr[i].f!=0; ++i) | |
142 | { | |
143 | col += (elemptr[i].f->varwidth ? 0 : elemptr[i].f->width); | |
144 | varw += elemptr[i].f->varwidth; | |
145 | newelems[i]=elemptr[i]; // copy element | |
146 | } | |
147 | newelems[i].f=0; | |
148 | *nitems=i; | |
149 | *sumwidth=col; | |
150 | *varwidth=varw; | |
151 | } | |
152 | ||
153 | ||
154 | ||
155 | /***************************************************************/ | |
156 | /* | |
157 | * getspacings: determine how much extra space there is for | |
158 | * inter-column space. | |
159 | * returns an int array this number of spaces to add after each column | |
160 | * also removes items from the newelems array if the available width | |
161 | * is lower than what is needed. The lowest priority columns are | |
162 | * removed first. | |
163 | * | |
164 | * Note: this function is only to be called when screen is true. | |
165 | */ | |
166 | int * | |
167 | getspacings(proc_printpair* elemptr) | |
168 | { | |
169 | static int spacings[MAXITEMS]; | |
170 | ||
171 | int col=0; | |
172 | int nitems; | |
173 | int varwidth=0; | |
174 | int j; | |
175 | int maxw=screen ? COLS : linelen; // for non screen: 80 columns max | |
176 | ||
177 | // get width etc; copy elemptr array to static newelms | |
178 | gettotwidth(elemptr, &nitems, &col, &varwidth); | |
179 | ||
180 | /* cases: | |
181 | * 1) nitems==1: just one column, no spacing needed. Done | |
182 | * | |
183 | * 2) total width is more than COLS: remove low prio columns | |
184 | * 2a) a varwidth column: no spacing needed | |
185 | * 2b) total width is less than COLS: compute inter spacing | |
186 | */ | |
187 | ||
188 | if (nitems==1) // no inter column spacing if 1 column | |
189 | { | |
190 | spacings[0]=0; | |
191 | return spacings; | |
192 | } | |
193 | ||
194 | // Check if available width is less than required. | |
195 | // If so, delete columns to make things fit | |
196 | // space required: | |
197 | // width + (nitems-1) * 1 space + 12 for a varwidth column. | |
198 | while (col + nitems-1+ 12*varwidth > maxw) | |
199 | { | |
200 | int lowestprio=999999; | |
201 | int lowestprio_index=-1; | |
202 | int i; | |
203 | for (i=0; i<nitems; ++i) | |
204 | { | |
205 | if (newelems[i].prio < lowestprio) | |
206 | { | |
207 | lowestprio=newelems[i].prio; | |
208 | lowestprio_index=i; | |
209 | } | |
210 | } | |
211 | ||
212 | // lowest priority item found, remove from newelems; | |
213 | col -= newelems[lowestprio_index].f->width; | |
214 | varwidth -= newelems[lowestprio_index].f->varwidth; | |
215 | memmove(newelems+lowestprio_index, | |
216 | newelems+lowestprio_index+1, | |
217 | (nitems-lowestprio_index)* sizeof(proc_printpair)); | |
218 | // also copies final 0 entry | |
219 | nitems--; | |
220 | } | |
221 | ||
222 | ||
223 | /* if there is a var width column, handle that separately */ | |
224 | if (varwidth) | |
225 | { | |
226 | for (j=0; j<nitems; ++j) | |
227 | { | |
228 | spacings[j]=1; | |
229 | if (elemptr[j].f->varwidth) | |
230 | { | |
231 | elemptr[j].f->width=maxw-col-(nitems-1); | |
232 | // only nitems-1 in-between spaces | |
233 | // needed | |
234 | } | |
235 | ||
236 | } | |
237 | return spacings; | |
238 | } | |
239 | ||
240 | ||
241 | /* fixed columns, spread whitespace over columns */ | |
242 | double over=(0.0+maxw-col)/(nitems-1); | |
243 | double todo=over; | |
244 | ||
245 | for (j=0; j<nitems-1; ++j) // last column gets no space appended | |
246 | { | |
247 | spacings[j]=(int)todo+0.5; | |
248 | todo-=spacings[j]; | |
249 | todo+=over; | |
250 | } | |
251 | spacings[j]=0; | |
252 | return spacings; | |
253 | } | |
254 | ||
255 | ||
256 | /* | |
257 | * showhdrline: show header line for processes. | |
258 | * if in interactive mode, also add a page numer | |
259 | * if in interactive mode, columns are aligned to fill out rows | |
260 | */ | |
261 | void | |
262 | showhdrline(proc_printpair* elemptr, int curlist, int totlist, | |
263 | char showorder, char autosort) | |
264 | { | |
265 | proc_printpair curelem; | |
266 | ||
267 | char *chead=""; | |
268 | char *autoindic=""; | |
269 | int order=showorder; | |
270 | int col=0; | |
271 | int allign; | |
272 | char pagindic[10]; | |
273 | int pagindiclen; | |
274 | int n=0; | |
275 | int bufsz; | |
276 | int maxw=screen ? COLS : linelen; // for non screen: 80 columns max | |
277 | ||
278 | colspacings=getspacings(elemptr); | |
279 | bufsz=maxw+1; | |
280 | ||
281 | elemptr=newelems; // point to adjusted array | |
282 | char buf[bufsz+2]; // long live dynamically sized auto arrays... | |
283 | ||
284 | if (!screen) | |
285 | { | |
286 | printg("\n"); | |
287 | } | |
288 | ||
289 | while ((curelem=*elemptr).f!=0) | |
290 | { | |
291 | if (curelem.f->head==0) // empty header==special: SORTITEM | |
292 | { | |
293 | chead=columnhead[order]; | |
294 | autoindic= autosort ? "A" : " "; | |
295 | } | |
296 | else | |
297 | { | |
298 | chead=curelem.f->head; | |
299 | autoindic=""; | |
300 | } | |
301 | ||
302 | if (screen) | |
303 | { | |
304 | col += sprintf(buf+col, "%s%s%*s", autoindic, chead, | |
305 | colspacings[n], ""); | |
306 | } | |
307 | else | |
308 | { | |
309 | col += sprintf(buf+col, "%s%s ", autoindic, chead); | |
310 | } | |
311 | ||
312 | elemptr++; | |
313 | n++; | |
314 | } | |
315 | ||
316 | if (screen) // add page number, eat from last header if needed... | |
317 | { | |
318 | pagindiclen=sprintf(pagindic,"%d/%d", curlist, totlist); | |
319 | allign=COLS-col-pagindiclen; // extra spaces needed | |
320 | ||
321 | if (allign >= 0) // allign by adding spaces | |
322 | { | |
323 | sprintf(buf+col, "%*s", allign+pagindiclen, pagindic); | |
324 | } | |
325 | else | |
326 | { // allign by removing from the right | |
327 | sprintf(buf+col+allign, "%s", pagindic); | |
328 | } | |
329 | } | |
330 | ||
331 | printg("%s", buf); | |
332 | ||
333 | if (!screen) | |
334 | { | |
335 | printg("\n"); | |
336 | } | |
337 | } | |
338 | ||
339 | ||
340 | ||
341 | /***************************************************************/ | |
342 | /* | |
343 | * showprocline: show line for processes. | |
344 | * if in interactive mode, columns are aligned to fill out rows | |
345 | * params: | |
346 | * elemptr: pointer to array of print definitcion structs ptrs | |
347 | * curstat: the process to print | |
348 | * perc: the sort order used | |
349 | * nsecs: number of seconds elapsed between previous and this sample | |
350 | * avgval: is averaging out per second needed? | |
351 | */ | |
352 | void | |
353 | showprocline(proc_printpair* elemptr, struct pstat *curstat, | |
354 | double perc, int nsecs, int avgval) | |
355 | { | |
356 | proc_printpair curelem; | |
357 | ||
358 | elemptr=newelems; // point to static array | |
359 | int n=0; | |
360 | while ((curelem=*elemptr).f!=0) | |
361 | { | |
362 | // what to print? SORTITEM, or active process or | |
363 | // exited process? | |
364 | ||
365 | if (curelem.f->head==0) // empty string=sortitem | |
366 | { | |
367 | printg("%3.0lf%%", perc); // cannot pass perc | |
368 | } | |
369 | else if (curstat->gen.state != 'E') // active process | |
370 | { | |
371 | printg("%s", curelem.f->doactiveconvert(curstat, | |
372 | avgval, nsecs)); | |
373 | } | |
374 | else // exited process | |
375 | { | |
376 | printg("%s", curelem.f->doexitconvert(curstat, | |
377 | avgval, nsecs)); | |
378 | } | |
379 | ||
380 | if (screen) | |
381 | { | |
382 | printg("%*s",colspacings[n], ""); | |
383 | } | |
384 | else | |
385 | { | |
386 | printg(" "); | |
387 | } | |
388 | ||
389 | elemptr++; | |
390 | n++; | |
391 | } | |
392 | if (!screen) | |
393 | { | |
394 | printg("\n"); | |
395 | } | |
396 | } | |
397 | ||
398 | ||
399 | /*******************************************************************/ | |
400 | /* PROCESS PRINT FUNCTIONS */ | |
401 | /***************************************************************/ | |
402 | char * | |
403 | procprt_NOTAVAIL_4(struct pstat *curstat, int avgval, int nsecs) | |
404 | { | |
405 | return " ?"; | |
406 | } | |
407 | ||
408 | char * | |
409 | procprt_NOTAVAIL_5(struct pstat *curstat, int avgval, int nsecs) | |
410 | { | |
411 | return " ?"; | |
412 | } | |
413 | ||
414 | char * | |
415 | procprt_NOTAVAIL_6(struct pstat *curstat, int avgval, int nsecs) | |
416 | { | |
417 | return " ?"; | |
418 | } | |
419 | ||
420 | char * | |
421 | procprt_NOTAVAIL_7(struct pstat *curstat, int avgval, int nsecs) | |
422 | { | |
423 | return " ?"; | |
424 | } | |
425 | ||
426 | char * | |
427 | procprt_PID_a(struct pstat *curstat, int avgval, int nsecs) | |
428 | { | |
429 | static char buf[10]; | |
430 | ||
431 | sprintf(buf, "%5d", curstat->gen.pid); | |
432 | return buf; | |
433 | } | |
434 | ||
435 | char * | |
436 | procprt_PID_e(struct pstat *curstat, int avgval, int nsecs) | |
437 | { | |
438 | static char buf[10]; | |
439 | ||
440 | if (curstat->gen.pid == 0) | |
441 | return " ?"; | |
442 | ||
443 | sprintf(buf, "%5d", curstat->gen.pid); | |
444 | return buf; | |
445 | } | |
446 | ||
447 | proc_printdef procprt_PID = | |
448 | { " PID", "PID", procprt_PID_a, procprt_PID_e, 5 }; | |
449 | ||
450 | /***************************************************************/ | |
451 | char * | |
452 | procprt_PPID_a(struct pstat *curstat, int avgval, int nsecs) | |
453 | { | |
454 | static char buf[10]; | |
455 | ||
456 | sprintf(buf, "%5d", curstat->gen.ppid); | |
457 | return buf; | |
458 | } | |
459 | ||
460 | ||
461 | char * | |
462 | procprt_PPID_e(struct pstat *curstat, int avgval, int nsecs) | |
463 | { | |
464 | return " "; | |
465 | } | |
466 | ||
467 | proc_printdef procprt_PPID = | |
468 | { " PPID", "PPID", procprt_PPID_a, procprt_PPID_e, 5 }; | |
469 | ||
470 | /***************************************************************/ | |
471 | char * | |
472 | procprt_SYSCPU_ae(struct pstat *curstat, int avgval, int nsecs) | |
473 | { | |
474 | static char buf[10]; | |
475 | ||
476 | val2cpustr(curstat->cpu.stime*1000/hertz, buf); | |
477 | return buf; | |
478 | } | |
479 | ||
480 | proc_printdef procprt_SYSCPU = | |
481 | { " SYSCPU", "SYSCPU", procprt_SYSCPU_ae, procprt_SYSCPU_ae, 7 }; | |
482 | /***************************************************************/ | |
483 | char * | |
484 | procprt_USRCPU_ae(struct pstat *curstat, int avgval, int nsecs) | |
485 | { | |
486 | static char buf[10]; | |
487 | ||
488 | val2cpustr(curstat->cpu.utime*1000/hertz, buf); | |
489 | return buf; | |
490 | } | |
491 | ||
492 | proc_printdef procprt_USRCPU = | |
493 | { " USRCPU", "USRCPU", procprt_USRCPU_ae, procprt_USRCPU_ae, 7 }; | |
494 | /***************************************************************/ | |
495 | char * | |
496 | procprt_VGROW_a(struct pstat *curstat, int avgval, int nsecs) | |
497 | { | |
498 | static char buf[10]; | |
499 | ||
500 | val2memstr(curstat->mem.vgrow*1024, buf, KBFORMAT, 0, 0); | |
501 | return buf; | |
502 | } | |
503 | ||
504 | char * | |
505 | procprt_VGROW_e(struct pstat *curstat, int avgval, int nsecs) | |
506 | { | |
507 | return " 0K"; | |
508 | } | |
509 | ||
510 | proc_printdef procprt_VGROW = | |
511 | { " VGROW", "VGROW", procprt_VGROW_a, procprt_VGROW_e, 6 }; | |
512 | /***************************************************************/ | |
513 | char * | |
514 | procprt_RGROW_a(struct pstat *curstat, int avgval, int nsecs) | |
515 | { | |
516 | static char buf[10]; | |
517 | ||
518 | val2memstr(curstat->mem.rgrow*1024, buf, KBFORMAT, 0, 0); | |
519 | return buf; | |
520 | } | |
521 | ||
522 | char * | |
523 | procprt_RGROW_e(struct pstat *curstat, int avgval, int nsecs) | |
524 | { | |
525 | return " 0K"; | |
526 | } | |
527 | ||
528 | proc_printdef procprt_RGROW = | |
529 | { " RGROW", "RGROW", procprt_RGROW_a, procprt_RGROW_e, 6 }; | |
530 | /***************************************************************/ | |
531 | char * | |
532 | procprt_MINFLT_ae(struct pstat *curstat, int avgval, int nsecs) | |
533 | { | |
534 | static char buf[10]; | |
535 | ||
536 | val2valstr(curstat->mem.minflt, buf, 6, avgval, nsecs); | |
537 | return buf; | |
538 | } | |
539 | ||
540 | proc_printdef procprt_MINFLT = | |
541 | { "MINFLT", "MINFLT", procprt_MINFLT_ae, procprt_MINFLT_ae, 6 }; | |
542 | /***************************************************************/ | |
543 | char * | |
544 | procprt_MAJFLT_ae(struct pstat *curstat, int avgval, int nsecs) | |
545 | { | |
546 | static char buf[10]; | |
547 | ||
548 | val2valstr(curstat->mem.majflt, buf, 6, avgval, nsecs); | |
549 | return buf; | |
550 | } | |
551 | ||
552 | proc_printdef procprt_MAJFLT = | |
553 | { "MAJFLT", "MAJFLT", procprt_MAJFLT_ae, procprt_MAJFLT_ae, 6 }; | |
554 | /***************************************************************/ | |
555 | char * | |
556 | procprt_VSTEXT_a(struct pstat *curstat, int avgval, int nsecs) | |
557 | { | |
558 | static char buf[10]; | |
559 | ||
560 | val2memstr(curstat->mem.shtext*1024, buf, KBFORMAT, 0, 0); | |
561 | return buf; | |
562 | } | |
563 | ||
564 | char * | |
565 | procprt_VSTEXT_e(struct pstat *curstat, int avgval, int nsecs) | |
566 | { | |
567 | return " 0K"; | |
568 | } | |
569 | ||
570 | proc_printdef procprt_VSTEXT = | |
571 | { "VSTEXT", "VSTEXT", procprt_VSTEXT_a, procprt_VSTEXT_e, 6 }; | |
572 | /***************************************************************/ | |
573 | char * | |
574 | procprt_VSIZE_a(struct pstat *curstat, int avgval, int nsecs) | |
575 | { | |
576 | static char buf[10]; | |
577 | ||
578 | val2memstr(curstat->mem.vmem*1024, buf, KBFORMAT, 0, 0); | |
579 | return buf; | |
580 | } | |
581 | ||
582 | char * | |
583 | procprt_VSIZE_e(struct pstat *curstat, int avgval, int nsecs) | |
584 | { | |
585 | return " 0K"; | |
586 | } | |
587 | ||
588 | proc_printdef procprt_VSIZE = | |
589 | { " VSIZE", "VSIZE", procprt_VSIZE_a, procprt_VSIZE_e, 6 }; | |
590 | /***************************************************************/ | |
591 | char * | |
592 | procprt_RSIZE_a(struct pstat *curstat, int avgval, int nsecs) | |
593 | { | |
594 | static char buf[10]; | |
595 | ||
596 | val2memstr(curstat->mem.rmem*1024, buf, KBFORMAT, 0, 0); | |
597 | return buf; | |
598 | } | |
599 | ||
600 | char * | |
601 | procprt_RSIZE_e(struct pstat *curstat, int avgval, int nsecs) | |
602 | { | |
603 | return " 0K"; | |
604 | } | |
605 | ||
606 | proc_printdef procprt_RSIZE = | |
607 | { " RSIZE", "RSIZE", procprt_RSIZE_a, procprt_RSIZE_e, 6 }; | |
608 | /***************************************************************/ | |
609 | char * | |
610 | procprt_CMD_a(struct pstat *curstat, int avgval, int nsecs) | |
611 | { | |
612 | static char buf[15]; | |
613 | ||
614 | sprintf(buf, "%-14.14s", curstat->gen.name); | |
615 | return buf; | |
616 | } | |
617 | ||
618 | char * | |
619 | procprt_CMD_e(struct pstat *curstat, int avgval, int nsecs) | |
620 | { | |
621 | static char buf[15]="<"; | |
622 | char helpbuf[15]; | |
623 | ||
624 | sprintf(helpbuf, "<%.12s>", curstat->gen.name); | |
625 | sprintf(buf, "%-14.14s", helpbuf); | |
626 | return buf; | |
627 | } | |
628 | ||
629 | proc_printdef procprt_CMD = | |
630 | { "CMD ", "CMD", procprt_CMD_a, procprt_CMD_e, 14 }; | |
631 | /***************************************************************/ | |
632 | char * | |
633 | procprt_RUID_ae(struct pstat *curstat, int avgval, int nsecs) | |
634 | { | |
635 | static char buf[9]; | |
636 | struct passwd *pwd; | |
637 | ||
638 | if ( (pwd = getpwuid(curstat->gen.ruid)) ) | |
639 | { | |
640 | sprintf(buf, "%-8.8s", pwd->pw_name); | |
641 | } | |
642 | else | |
643 | { | |
644 | snprintf(buf, sizeof buf, "%-8d", curstat->gen.ruid); | |
645 | } | |
646 | return buf; | |
647 | } | |
648 | ||
649 | proc_printdef procprt_RUID = | |
650 | { "RUID ", "RUID", procprt_RUID_ae, procprt_RUID_ae, 8 }; | |
651 | /***************************************************************/ | |
652 | char * | |
653 | procprt_EUID_a(struct pstat *curstat, int avgval, int nsecs) | |
654 | { | |
655 | static char buf[9]; | |
656 | struct passwd *pwd; | |
657 | ||
658 | if ( (pwd = getpwuid(curstat->gen.euid)) ) | |
659 | { | |
660 | sprintf(buf, "%-8.8s", pwd->pw_name); | |
661 | } | |
662 | else | |
663 | { | |
664 | snprintf(buf, sizeof buf, "%-8d", curstat->gen.euid); | |
665 | } | |
666 | return buf; | |
667 | } | |
668 | ||
669 | char * | |
670 | procprt_EUID_e(struct pstat *curstat, int avgval, int nsecs) | |
671 | { | |
672 | return "- "; | |
673 | } | |
674 | ||
675 | proc_printdef procprt_EUID = | |
676 | { "EUID ", "EUID", procprt_EUID_a, procprt_EUID_e, 8 }; | |
677 | /***************************************************************/ | |
678 | char * | |
679 | procprt_SUID_a(struct pstat *curstat, int avgval, int nsecs) | |
680 | { | |
681 | static char buf[9]; | |
682 | struct passwd *pwd; | |
683 | ||
684 | if ( (pwd = getpwuid(curstat->gen.suid)) ) | |
685 | { | |
686 | sprintf(buf, "%-8.8s", pwd->pw_name); | |
687 | } | |
688 | else | |
689 | { | |
690 | snprintf(buf, sizeof buf, "%-8d", curstat->gen.suid); | |
691 | } | |
692 | return buf; | |
693 | } | |
694 | ||
695 | char * | |
696 | procprt_SUID_e(struct pstat *curstat, int avgval, int nsecs) | |
697 | { | |
698 | return "- "; | |
699 | } | |
700 | ||
701 | proc_printdef procprt_SUID = | |
702 | { "SUID ", "SUID", procprt_SUID_a, procprt_SUID_e, 8 }; | |
703 | /***************************************************************/ | |
704 | char * | |
705 | procprt_FSUID_a(struct pstat *curstat, int avgval, int nsecs) | |
706 | { | |
707 | static char buf[9]; | |
708 | struct passwd *pwd; | |
709 | ||
710 | if ( (pwd = getpwuid(curstat->gen.fsuid)) ) | |
711 | { | |
712 | sprintf(buf, "%-8.8s", pwd->pw_name); | |
713 | } | |
714 | else | |
715 | { | |
716 | snprintf(buf, sizeof buf, "%-8d", curstat->gen.fsuid); | |
717 | } | |
718 | return buf; | |
719 | } | |
720 | ||
721 | char * | |
722 | procprt_FSUID_e(struct pstat *curstat, int avgval, int nsecs) | |
723 | { | |
724 | return "- "; | |
725 | } | |
726 | ||
727 | proc_printdef procprt_FSUID = | |
728 | { "FSUID ", "FSUID", procprt_FSUID_a, procprt_FSUID_e, 8 }; | |
729 | /***************************************************************/ | |
730 | char * | |
731 | procprt_RGID_ae(struct pstat *curstat, int avgval, int nsecs) | |
732 | { | |
733 | static char buf[10]; | |
734 | struct group *grp; | |
735 | char *groupname; | |
736 | char grname[16]; | |
737 | ||
738 | if ( (grp = getgrgid(curstat->gen.rgid)) ) | |
739 | { | |
740 | groupname = grp->gr_name; | |
741 | } | |
742 | else | |
743 | { | |
744 | snprintf(grname, sizeof grname, "%d",curstat->gen.rgid); | |
745 | groupname = grname; | |
746 | } | |
747 | ||
748 | sprintf(buf, "%-8.8s", groupname); | |
749 | return buf; | |
750 | } | |
751 | ||
752 | proc_printdef procprt_RGID = | |
753 | { "RGID ", "RGID", procprt_RGID_ae, procprt_RGID_ae, 8 }; | |
754 | /***************************************************************/ | |
755 | char * | |
756 | procprt_EGID_a(struct pstat *curstat, int avgval, int nsecs) | |
757 | { | |
758 | static char buf[10]; | |
759 | struct group *grp; | |
760 | char *groupname; | |
761 | char grname[16]; | |
762 | ||
763 | if ( (grp = getgrgid(curstat->gen.egid)) ) | |
764 | { | |
765 | groupname = grp->gr_name; | |
766 | } | |
767 | else | |
768 | { | |
769 | snprintf(grname, sizeof grname, "%d",curstat->gen.egid); | |
770 | groupname = grname; | |
771 | } | |
772 | ||
773 | sprintf(buf, "%-8.8s", groupname); | |
774 | return buf; | |
775 | } | |
776 | ||
777 | char * | |
778 | procprt_EGID_e(struct pstat *curstat, int avgval, int nsecs) | |
779 | { | |
780 | return "- "; | |
781 | } | |
782 | ||
783 | proc_printdef procprt_EGID = | |
784 | { "EGID ", "EGID", procprt_EGID_a, procprt_EGID_e, 8 }; | |
785 | /***************************************************************/ | |
786 | char * | |
787 | procprt_SGID_a(struct pstat *curstat, int avgval, int nsecs) | |
788 | { | |
789 | static char buf[10]; | |
790 | struct group *grp; | |
791 | char *groupname; | |
792 | char grname[16]; | |
793 | ||
794 | if ( (grp = getgrgid(curstat->gen.sgid)) ) | |
795 | { | |
796 | groupname = grp->gr_name; | |
797 | } | |
798 | else | |
799 | { | |
800 | snprintf(grname, sizeof grname, "%d",curstat->gen.sgid); | |
801 | groupname = grname; | |
802 | } | |
803 | ||
804 | sprintf(buf, "%-8.8s", groupname); | |
805 | return buf; | |
806 | } | |
807 | ||
808 | char * | |
809 | procprt_SGID_e(struct pstat *curstat, int avgval, int nsecs) | |
810 | { | |
811 | return "- "; | |
812 | } | |
813 | ||
814 | proc_printdef procprt_SGID = | |
815 | { "SGID ", "SGID", procprt_SGID_a, procprt_SGID_e, 8 }; | |
816 | /***************************************************************/ | |
817 | char * | |
818 | procprt_FSGID_a(struct pstat *curstat, int avgval, int nsecs) | |
819 | { | |
820 | static char buf[10]; | |
821 | struct group *grp; | |
822 | char *groupname; | |
823 | char grname[16]; | |
824 | ||
825 | if ( (grp = getgrgid(curstat->gen.fsgid)) ) | |
826 | { | |
827 | groupname = grp->gr_name; | |
828 | } | |
829 | else | |
830 | { | |
831 | snprintf(grname, sizeof grname,"%d",curstat->gen.fsgid); | |
832 | groupname = grname; | |
833 | } | |
834 | ||
835 | sprintf(buf, "%-8.8s", groupname); | |
836 | return buf; | |
837 | } | |
838 | ||
839 | char * | |
840 | procprt_FSGID_e(struct pstat *curstat, int avgval, int nsecs) | |
841 | { | |
842 | return "- "; | |
843 | } | |
844 | ||
845 | proc_printdef procprt_FSGID = | |
846 | { "FSGID ", "FSGID", procprt_FSGID_a, procprt_FSGID_e, 8 }; | |
847 | /***************************************************************/ | |
848 | char * | |
849 | procprt_STDATE_ae(struct pstat *curstat, int avgval, int nsecs) | |
850 | { | |
851 | static char buf[11]; | |
852 | ||
853 | convdate(curstat->gen.btime, buf); | |
854 | return buf; | |
855 | } | |
856 | ||
857 | proc_printdef procprt_STDATE = | |
858 | { " STDATE ", "STDATE", procprt_STDATE_ae, procprt_STDATE_ae, 10 }; | |
859 | /***************************************************************/ | |
860 | char * | |
861 | procprt_STTIME_ae(struct pstat *curstat, int avgval, int nsecs) | |
862 | { | |
863 | static char buf[9]; | |
864 | ||
865 | convtime(curstat->gen.btime, buf); | |
866 | return buf; | |
867 | } | |
868 | ||
869 | proc_printdef procprt_STTIME = | |
870 | { " STTIME ", "STTIME", procprt_STTIME_ae, procprt_STTIME_ae, 8 }; | |
871 | /***************************************************************/ | |
872 | char * | |
873 | procprt_ENDATE_a(struct pstat *curstat, int avgval, int nsecs) | |
874 | { | |
875 | static char buf[11]; | |
876 | ||
877 | strcpy(buf, " active "); | |
878 | ||
879 | return buf; | |
880 | } | |
881 | ||
882 | char * | |
883 | procprt_ENDATE_e(struct pstat *curstat, int avgval, int nsecs) | |
884 | { | |
885 | static char buf[11]; | |
886 | ||
887 | convdate(curstat->gen.btime + curstat->gen.elaps/hertz, buf); | |
888 | ||
889 | return buf; | |
890 | } | |
891 | ||
892 | proc_printdef procprt_ENDATE = | |
893 | { " ENDATE ", "ENDATE", procprt_ENDATE_a, procprt_ENDATE_e, 10 }; | |
894 | /***************************************************************/ | |
895 | char * | |
896 | procprt_ENTIME_a(struct pstat *curstat, int avgval, int nsecs) | |
897 | { | |
898 | static char buf[9]; | |
899 | ||
900 | strcpy(buf, " active "); | |
901 | ||
902 | return buf; | |
903 | } | |
904 | ||
905 | char * | |
906 | procprt_ENTIME_e(struct pstat *curstat, int avgval, int nsecs) | |
907 | { | |
908 | static char buf[9]; | |
909 | ||
910 | convtime(curstat->gen.btime + curstat->gen.elaps/hertz, buf); | |
911 | ||
912 | return buf; | |
913 | } | |
914 | ||
915 | proc_printdef procprt_ENTIME = | |
916 | { " ENTIME ", "ENTIME", procprt_ENTIME_a, procprt_ENTIME_e, 8 }; | |
917 | /***************************************************************/ | |
918 | char * | |
919 | procprt_THR_a(struct pstat *curstat, int avgval, int nsecs) | |
920 | { | |
921 | static char buf[15]; | |
922 | ||
923 | sprintf(buf, "%4d", curstat->gen.nthr); | |
924 | return buf; | |
925 | } | |
926 | ||
927 | char * | |
928 | procprt_THR_e(struct pstat *curstat, int avgval, int nsecs) | |
929 | { | |
930 | return " 0"; | |
931 | } | |
932 | ||
933 | proc_printdef procprt_THR = | |
934 | { " THR", "THR", procprt_THR_a, procprt_THR_e, 4 }; | |
935 | /***************************************************************/ | |
936 | char * | |
937 | procprt_TRUN_a(struct pstat *curstat, int avgval, int nsecs) | |
938 | { | |
939 | static char buf[15]; | |
940 | ||
941 | sprintf(buf, "%4d", curstat->gen.nthrrun); | |
942 | return buf; | |
943 | } | |
944 | ||
945 | char * | |
946 | procprt_TRUN_e(struct pstat *curstat, int avgval, int nsecs) | |
947 | { | |
948 | return " 0"; | |
949 | } | |
950 | ||
951 | proc_printdef procprt_TRUN = | |
952 | { "TRUN", "TRUN", procprt_TRUN_a, procprt_TRUN_e, 4 }; | |
953 | /***************************************************************/ | |
954 | char * | |
955 | procprt_TSLPI_a(struct pstat *curstat, int avgval, int nsecs) | |
956 | { | |
957 | static char buf[15]; | |
958 | ||
959 | sprintf(buf, "%5d", curstat->gen.nthrslpi); | |
960 | return buf; | |
961 | } | |
962 | ||
963 | char * | |
964 | procprt_TSLPI_e(struct pstat *curstat, int avgval, int nsecs) | |
965 | { | |
966 | return " 0"; | |
967 | } | |
968 | ||
969 | proc_printdef procprt_TSLPI = | |
970 | { "TSLPI", "TSLPI", procprt_TSLPI_a, procprt_TSLPI_e, 5 }; | |
971 | /***************************************************************/ | |
972 | char * | |
973 | procprt_TSLPU_a(struct pstat *curstat, int avgval, int nsecs) | |
974 | { | |
975 | static char buf[15]; | |
976 | ||
977 | sprintf(buf, "%5d", curstat->gen.nthrslpu); | |
978 | return buf; | |
979 | } | |
980 | ||
981 | char * | |
982 | procprt_TSLPU_e(struct pstat *curstat, int avgval, int nsecs) | |
983 | { | |
984 | return " 0"; | |
985 | } | |
986 | ||
987 | proc_printdef procprt_TSLPU = | |
988 | { "TSLPU", "TSLPU", procprt_TSLPU_a, procprt_TSLPU_e, 5 }; | |
989 | /***************************************************************/ | |
990 | #define SCHED_NORMAL 0 | |
991 | #define SCHED_FIFO 1 | |
992 | #define SCHED_RR 2 | |
993 | #define SCHED_BATCH 3 | |
994 | #define SCHED_ISO 4 | |
995 | #define SCHED_IDLE 5 | |
996 | ||
997 | char * | |
998 | procprt_POLI_a(struct pstat *curstat, int avgval, int nsecs) | |
999 | { | |
1000 | switch (curstat->cpu.policy) | |
1001 | { | |
1002 | case SCHED_NORMAL: | |
1003 | return "norm"; | |
1004 | break; | |
1005 | case SCHED_FIFO: | |
1006 | return "fifo"; | |
1007 | break; | |
1008 | case SCHED_RR: | |
1009 | return "rr "; | |
1010 | break; | |
1011 | case SCHED_BATCH: | |
1012 | return "btch"; | |
1013 | break; | |
1014 | case SCHED_ISO: | |
1015 | return "iso "; | |
1016 | break; | |
1017 | case SCHED_IDLE: | |
1018 | return "idle"; | |
1019 | break; | |
1020 | } | |
1021 | return "? "; | |
1022 | } | |
1023 | ||
1024 | char * | |
1025 | procprt_POLI_e(struct pstat *curstat, int avgval, int nsecs) | |
1026 | { | |
1027 | return "- "; | |
1028 | } | |
1029 | ||
1030 | proc_printdef procprt_POLI = | |
1031 | { "POLI", "POLI", procprt_POLI_a, procprt_POLI_e, 4 }; | |
1032 | /***************************************************************/ | |
1033 | char * | |
1034 | procprt_NICE_a(struct pstat *curstat, int avgval, int nsecs) | |
1035 | { | |
1036 | static char buf[15]; | |
1037 | ||
1038 | sprintf(buf, "%4d", curstat->cpu.nice); | |
1039 | return buf; | |
1040 | } | |
1041 | ||
1042 | char * | |
1043 | procprt_NICE_e(struct pstat *curstat, int avgval, int nsecs) | |
1044 | { | |
1045 | return " -"; | |
1046 | } | |
1047 | ||
1048 | proc_printdef procprt_NICE = | |
1049 | { "NICE", "NICE", procprt_NICE_a, procprt_NICE_e, 4 }; | |
1050 | /***************************************************************/ | |
1051 | char * | |
1052 | procprt_PRI_a(struct pstat *curstat, int avgval, int nsecs) | |
1053 | { | |
1054 | static char buf[15]; | |
1055 | ||
1056 | sprintf(buf, "%3d", curstat->cpu.prio); | |
1057 | return buf; | |
1058 | } | |
1059 | ||
1060 | char * | |
1061 | procprt_PRI_e(struct pstat *curstat, int avgval, int nsecs) | |
1062 | { | |
1063 | return " -"; | |
1064 | } | |
1065 | ||
1066 | proc_printdef procprt_PRI = | |
1067 | { "PRI", "PRI", procprt_PRI_a, procprt_PRI_e, 3 }; | |
1068 | /***************************************************************/ | |
1069 | char * | |
1070 | procprt_RTPR_a(struct pstat *curstat, int avgval, int nsecs) | |
1071 | { | |
1072 | static char buf[15]; | |
1073 | ||
1074 | sprintf(buf, "%4d", curstat->cpu.rtprio); | |
1075 | return buf; | |
1076 | } | |
1077 | ||
1078 | char * | |
1079 | procprt_RTPR_e(struct pstat *curstat, int avgval, int nsecs) | |
1080 | { | |
1081 | return " -"; | |
1082 | } | |
1083 | ||
1084 | proc_printdef procprt_RTPR = | |
1085 | { "RTPR", "RTPR", procprt_RTPR_a, procprt_RTPR_e, 4 }; | |
1086 | /***************************************************************/ | |
1087 | char * | |
1088 | procprt_CURCPU_a(struct pstat *curstat, int avgval, int nsecs) | |
1089 | { | |
1090 | static char buf[15]; | |
1091 | ||
1092 | sprintf(buf, "%5d", curstat->cpu.curcpu); | |
1093 | return buf; | |
1094 | } | |
1095 | ||
1096 | char * | |
1097 | procprt_CURCPU_e(struct pstat *curstat, int avgval, int nsecs) | |
1098 | { | |
1099 | return " -"; | |
1100 | } | |
1101 | ||
1102 | proc_printdef procprt_CURCPU = | |
1103 | { "CPUNR", "CPUNR", procprt_CURCPU_a, procprt_CURCPU_e, 5 }; | |
1104 | /***************************************************************/ | |
1105 | char * | |
1106 | procprt_ST_a(struct pstat *curstat, int avgval, int nsecs) | |
1107 | { | |
1108 | static char buf[3]="--"; | |
1109 | if (curstat->gen.excode & ~(INT_MAX)) | |
1110 | { | |
1111 | buf[0]='N'; | |
1112 | } | |
1113 | else | |
1114 | { | |
1115 | buf[0]='-'; | |
1116 | } | |
1117 | return buf; | |
1118 | } | |
1119 | ||
1120 | char * | |
1121 | procprt_ST_e(struct pstat *curstat, int avgval, int nsecs) | |
1122 | { | |
1123 | static char buf[3]; | |
1124 | if (curstat->gen.excode & ~(INT_MAX)) | |
1125 | { | |
1126 | buf[0]='N'; | |
1127 | } | |
1128 | else | |
1129 | { | |
1130 | buf[0]='-'; | |
1131 | } | |
1132 | if (curstat->gen.excode & 0xff) | |
1133 | { | |
1134 | if (curstat->gen.excode & 0x80) | |
1135 | buf[1] = 'C'; | |
1136 | else | |
1137 | buf[1] = 'S'; | |
1138 | } | |
1139 | else | |
1140 | { | |
1141 | buf[1] = 'E'; | |
1142 | } | |
1143 | return buf; | |
1144 | } | |
1145 | ||
1146 | proc_printdef procprt_ST = | |
1147 | { "ST", "ST", procprt_ST_a, procprt_ST_e, 2 }; | |
1148 | /***************************************************************/ | |
1149 | char * | |
1150 | procprt_EXC_a(struct pstat *curstat, int avgval, int nsecs) | |
1151 | { | |
1152 | return " -"; | |
1153 | } | |
1154 | ||
1155 | char * | |
1156 | procprt_EXC_e(struct pstat *curstat, int avgval, int nsecs) | |
1157 | { | |
1158 | static char buf[4]; | |
1159 | ||
1160 | ||
1161 | sprintf(buf, "%3d", | |
1162 | curstat->gen.excode & 0xff ? | |
1163 | curstat->gen.excode & 0x7f : | |
1164 | (curstat->gen.excode>>8) & 0xff); | |
1165 | return buf; | |
1166 | } | |
1167 | ||
1168 | ||
1169 | proc_printdef procprt_EXC = | |
1170 | { "EXC", "EXC", procprt_EXC_a, procprt_EXC_e, 3 }; | |
1171 | /***************************************************************/ | |
1172 | char * | |
1173 | procprt_S_a(struct pstat *curstat, int avgval, int nsecs) | |
1174 | { | |
1175 | static char buf[2]="E"; | |
1176 | ||
1177 | buf[0]=curstat->gen.state; | |
1178 | return buf; | |
1179 | } | |
1180 | ||
1181 | char * | |
1182 | procprt_S_e(struct pstat *curstat, int avgval, int nsecs) | |
1183 | { | |
1184 | return "E"; | |
1185 | ||
1186 | } | |
1187 | ||
1188 | proc_printdef procprt_S = | |
1189 | { "S", "S", procprt_S_a, procprt_S_e, 1 }; | |
1190 | ||
1191 | /***************************************************************/ | |
1192 | char * | |
1193 | procprt_COMMAND_LINE_ae(struct pstat *curstat, int avgval, int nsecs) | |
1194 | { | |
1195 | extern proc_printdef procprt_COMMAND_LINE; | |
1196 | static char buf[CMDLEN+1]; | |
1197 | ||
1198 | int len=procprt_COMMAND_LINE.width; | |
1199 | if (len > CMDLEN) len=CMDLEN; | |
1200 | ||
1201 | if (screen) | |
1202 | { | |
1203 | sprintf(buf, "%-*.*s", len, len, | |
1204 | curstat->gen.cmdline[0] ? | |
1205 | curstat->gen.cmdline : curstat->gen.name); | |
1206 | } | |
1207 | else | |
1208 | { | |
1209 | sprintf(buf, "%.*s", CMDLEN, | |
1210 | curstat->gen.cmdline[0] ? | |
1211 | curstat->gen.cmdline : curstat->gen.name); | |
1212 | } | |
1213 | return buf; | |
1214 | } | |
1215 | ||
1216 | proc_printdef procprt_COMMAND_LINE = | |
1217 | { "COMMAND-LINE ", "COMMAND-LINE", | |
1218 | procprt_COMMAND_LINE_ae, procprt_COMMAND_LINE_ae, 0, 1 }; | |
1219 | /***************************************************************/ | |
1220 | char * | |
1221 | procprt_NPROCS_ae(struct pstat *curstat, int avgval, int nsecs) | |
1222 | { | |
1223 | static char buf[10]; | |
1224 | ||
1225 | val2valstr(curstat->gen.pid, buf, 6, 0, 0); // pid abused as proc counter | |
1226 | return buf; | |
1227 | } | |
1228 | ||
1229 | proc_printdef procprt_NPROCS = | |
1230 | { "NPROCS", "NPROCS", procprt_NPROCS_ae, procprt_NPROCS_ae, 6 }; | |
1231 | /***************************************************************/ | |
1232 | char * | |
1233 | procprt_NRDDSK_ae(struct pstat *curstat, int avgval, int nsecs) // with patches && acct | |
1234 | { | |
1235 | static char buf[10]; | |
1236 | val2valstr(curstat->dsk.rio, buf, 6, avgval, nsecs); | |
1237 | ||
1238 | return buf; | |
1239 | } | |
1240 | ||
1241 | proc_printdef procprt_RDDSK = | |
1242 | { " RDDSK", "RDDSK", procprt_NRDDSK_ae, procprt_NRDDSK_ae, 6 }; | |
1243 | /***************************************************************/ | |
1244 | char * | |
1245 | procprt_NWRDSK_a(struct pstat *curstat, int avgval, int nsecs) // with patches && ACCT | |
1246 | { | |
1247 | static char buf[10]; | |
1248 | val2valstr(curstat->dsk.wio, buf, 6, avgval, nsecs); | |
1249 | ||
1250 | return buf; | |
1251 | } | |
1252 | ||
1253 | proc_printdef procprt_WRDSK = | |
1254 | { " WRDSK", "WRDSK", procprt_NWRDSK_a, procprt_NWRDSK_a, 6 }; | |
1255 | /***************************************************************/ | |
1256 | char * | |
1257 | procprt_NRDDSK_e(struct pstat *curstat, int avgval, int nsecs) // with patches, no ACCT | |
1258 | { | |
1259 | return " (r&w)"; | |
1260 | } | |
1261 | /***************************************************************/ | |
1262 | char * | |
1263 | procprt_NWRDSK_e(struct pstat *curstat, int avgval, int nsecs) // patches, no ACCT | |
1264 | { | |
1265 | static char buf[10]; | |
1266 | val2valstr(curstat->dsk.rio, buf, 6, avgval, nsecs); // r and w! | |
1267 | return buf; | |
1268 | } | |
1269 | /***************************************************************/ | |
1270 | char * | |
1271 | procprt_RDDSK_IOSTAT_a(struct pstat *curstat, int avgval, int nsecs) // IOSTAT based | |
1272 | { | |
1273 | static char buf[10]; | |
1274 | val2memstr(curstat->dsk.rsz*512, buf, KBFORMAT, 0, 0); | |
1275 | ||
1276 | return buf; | |
1277 | } | |
1278 | ||
1279 | char * | |
1280 | procprt_RDDSK_IOSTAT_e(struct pstat *curstat, int avgval, int nsecs) | |
1281 | { | |
1282 | return " -"; | |
1283 | } | |
1284 | /***************************************************************/ | |
1285 | char * | |
1286 | procprt_WRDSK_IOSTAT_a(struct pstat *curstat, int avgval, int nsecs) // IOSTAT based | |
1287 | { | |
1288 | static char buf[10]; | |
1289 | val2memstr(curstat->dsk.wsz*512, buf, KBFORMAT, 0, 0); | |
1290 | ||
1291 | return buf; | |
1292 | } | |
1293 | ||
1294 | char * | |
1295 | procprt_WRDSK_IOSTAT_e(struct pstat *curstat, int avgval, int nsecs) | |
1296 | { | |
1297 | return " -"; | |
1298 | } | |
1299 | /***************************************************************/ | |
1300 | char * | |
1301 | procprt_WCANCEL_IOSTAT_a(struct pstat *curstat, int avgval, int nsecs) // IOSTAT based */ | |
1302 | { | |
1303 | static char buf[10]; | |
1304 | val2memstr(curstat->dsk.cwsz*512, buf, KBFORMAT, 0, 0); | |
1305 | ||
1306 | return buf; | |
1307 | } | |
1308 | ||
1309 | char * | |
1310 | procprt_WCANCEL_IOSTAT_e(struct pstat *curstat, int avgval, int nsecs) | |
1311 | { | |
1312 | return " -"; | |
1313 | } | |
1314 | ||
1315 | proc_printdef procprt_WCANCEL_IOSTAT = | |
1316 | { "WCANCL", "WCANCL", procprt_WCANCEL_IOSTAT_a, procprt_WCANCEL_IOSTAT_e, 6 }; | |
1317 | /***************************************************************/ | |
1318 | char * | |
1319 | procprt_AVGRSZ_PATCH_ae(struct pstat *curstat, int avgval, int nsecs) // patch based | |
1320 | { | |
1321 | static char buf[10]; | |
1322 | int avgrsz = curstat->dsk.rio ? | |
1323 | curstat->dsk.rsz * 512LL / curstat->dsk.rio : 0; | |
1324 | val2valstr(avgrsz, buf, 7, 0, 0); | |
1325 | ||
1326 | return buf; | |
1327 | } | |
1328 | ||
1329 | proc_printdef procprt_AVGRSZ = | |
1330 | { " AVGRSZ", "AVGRSZ", procprt_AVGRSZ_PATCH_ae, procprt_AVGRSZ_PATCH_ae, 7 }; | |
1331 | /***************************************************************/ | |
1332 | char * | |
1333 | procprt_AVGWSZ_PATCH_ae(struct pstat *curstat, int avgval, int nsecs) | |
1334 | { | |
1335 | static char buf[10]; | |
1336 | int avgwsz = curstat->dsk.wio ? | |
1337 | curstat->dsk.wsz * 512LL / curstat->dsk.wio : 0; | |
1338 | val2valstr(avgwsz, buf, 7, 0, 0); | |
1339 | ||
1340 | return buf; | |
1341 | } | |
1342 | ||
1343 | proc_printdef procprt_AVGWSZ = | |
1344 | { " AVGWSZ", "AVGWSZ", procprt_AVGWSZ_PATCH_ae, procprt_AVGWSZ_PATCH_ae, 7 }; | |
1345 | /***************************************************************/ | |
1346 | char * | |
1347 | procprt_TOTRSZ_ae(struct pstat *curstat, int avgval, int nsecs) // patch and ACCT | |
1348 | { | |
1349 | static char buf[10]; | |
1350 | val2memstr(curstat->dsk.rsz*512LL, buf, KBFORMAT, avgval, nsecs); | |
1351 | ||
1352 | return buf; | |
1353 | } | |
1354 | ||
1355 | proc_printdef procprt_TOTRSZ = | |
1356 | { "TOTRSZ", "TOTRSZ", procprt_TOTRSZ_ae, procprt_TOTRSZ_ae, 6 }; | |
1357 | /***************************************************************/ | |
1358 | char * | |
1359 | procprt_TOTWSZ_ae(struct pstat *curstat, int avgval, int nsecs) // patch and ACCT | |
1360 | { | |
1361 | static char buf[10]; | |
1362 | val2memstr(curstat->dsk.wsz*512LL, buf, KBFORMAT, avgval, nsecs); | |
1363 | ||
1364 | return buf; | |
1365 | } | |
1366 | ||
1367 | proc_printdef procprt_TOTWSZ = | |
1368 | { "TOTWSZ", "TOTWSZ", procprt_TOTWSZ_ae, procprt_TOTWSZ_ae, 6 }; | |
1369 | /***************************************************************/ | |
1370 | char * | |
1371 | procprt_TOTRSZ_NOACCT_e(struct pstat *curstat, int avgval, int nsecs) // patch noACCT | |
1372 | { | |
1373 | static char buf[10]; | |
1374 | val2memstr(curstat->dsk.rsz*512LL, buf, KBFORMAT, avgval, nsecs); | |
1375 | ||
1376 | return buf; | |
1377 | } | |
1378 | /***************************************************************/ | |
1379 | char * | |
1380 | procprt_TOTWSZ_NOACCT_e(struct pstat *curstat, int avgval, int nsecs) // patch noACCT | |
1381 | { | |
1382 | return "(r & w)"; | |
1383 | } | |
1384 | /***************************************************************/ | |
1385 | char * | |
1386 | procprt_TCPRCV_a(struct pstat *curstat, int avgval, int nsecs) | |
1387 | { | |
1388 | static char buf[10]; | |
1389 | ||
1390 | val2valstr(curstat->net.tcprcv, buf, 6, avgval, nsecs); | |
1391 | ||
1392 | return buf; | |
1393 | } | |
1394 | ||
1395 | char * | |
1396 | procprt_TCPRCV_e(struct pstat *curstat, int avgval, int nsecs) | |
1397 | { | |
1398 | return " -"; | |
1399 | } | |
1400 | ||
1401 | ||
1402 | proc_printdef procprt_TCPRCV = | |
1403 | { "TCPRCV", "TCPRCV", procprt_TCPRCV_a, procprt_TCPRCV_e, 6 }; | |
1404 | /***************************************************************/ | |
1405 | char * | |
1406 | procprt_TCPRASZ_a(struct pstat *curstat, int avgval, int nsecs) | |
1407 | { | |
1408 | static char buf[10]; | |
1409 | ||
1410 | int avgtcpr = curstat->net.tcprcv ? | |
1411 | curstat->net.tcprsz / curstat->net.tcprcv : 0; | |
1412 | ||
1413 | val2valstr(avgtcpr, buf, 7, 0, 0); | |
1414 | return buf; | |
1415 | } | |
1416 | ||
1417 | char * | |
1418 | procprt_TCPRASZ_e(struct pstat *curstat, int avgval, int nsecs) | |
1419 | { | |
1420 | return " -"; | |
1421 | } | |
1422 | ||
1423 | proc_printdef procprt_TCPRASZ = | |
1424 | { "TCPRASZ", "TCPRASZ", procprt_TCPRASZ_a, procprt_TCPRASZ_e, 7 }; | |
1425 | /***************************************************************/ | |
1426 | char * | |
1427 | procprt_TCPSND_a(struct pstat *curstat, int avgval, int nsecs) | |
1428 | { | |
1429 | static char buf[10]; | |
1430 | ||
1431 | val2valstr(curstat->net.tcpsnd, buf, 6, avgval, nsecs); | |
1432 | ||
1433 | return buf; | |
1434 | } | |
1435 | ||
1436 | char * | |
1437 | procprt_TCPSND_e(struct pstat *curstat, int avgval, int nsecs) | |
1438 | { | |
1439 | return " -"; | |
1440 | } | |
1441 | ||
1442 | proc_printdef procprt_TCPSND = | |
1443 | { "TCPSND", "TCPSND", procprt_TCPSND_a, procprt_TCPSND_e, 6 }; | |
1444 | /***************************************************************/ | |
1445 | char * | |
1446 | procprt_TCPSASZ_a(struct pstat *curstat, int avgval, int nsecs) | |
1447 | { | |
1448 | static char buf[10]; | |
1449 | ||
1450 | int avgtcps = curstat->net.tcpsnd ? | |
1451 | curstat->net.tcpssz / curstat->net.tcpsnd : 0; | |
1452 | ||
1453 | val2valstr(avgtcps, buf, 7, 0, 0); | |
1454 | return buf; | |
1455 | } | |
1456 | ||
1457 | char * | |
1458 | procprt_TCPSASZ_e(struct pstat *curstat, int avgval, int nsecs) | |
1459 | { | |
1460 | return " -"; | |
1461 | } | |
1462 | ||
1463 | ||
1464 | proc_printdef procprt_TCPSASZ = | |
1465 | { "TCPSASZ", "TCPSASZ", procprt_TCPSASZ_a, procprt_TCPSASZ_e, 7 }; | |
1466 | /***************************************************************/ | |
1467 | char * | |
1468 | procprt_UDPRCV_a(struct pstat *curstat, int avgval, int nsecs) | |
1469 | { | |
1470 | static char buf[10]; | |
1471 | ||
1472 | val2valstr(curstat->net.udprcv, buf, 6, avgval, nsecs); | |
1473 | ||
1474 | return buf; | |
1475 | } | |
1476 | ||
1477 | char * | |
1478 | procprt_UDPRCV_e(struct pstat *curstat, int avgval, int nsecs) | |
1479 | { | |
1480 | return " -"; | |
1481 | } | |
1482 | ||
1483 | ||
1484 | proc_printdef procprt_UDPRCV = | |
1485 | { "UDPRCV", "UDPRCV", procprt_UDPRCV_a, procprt_UDPRCV_e, 6 }; | |
1486 | /***************************************************************/ | |
1487 | char * | |
1488 | procprt_UDPRASZ_a(struct pstat *curstat, int avgval, int nsecs) | |
1489 | { | |
1490 | static char buf[10]; | |
1491 | ||
1492 | int avgudpr = curstat->net.udprcv ? | |
1493 | curstat->net.udprsz / curstat->net.udprcv : 0; | |
1494 | ||
1495 | val2valstr(avgudpr, buf, 7, 0, 0); | |
1496 | return buf; | |
1497 | } | |
1498 | ||
1499 | char * | |
1500 | procprt_UDPRASZ_e(struct pstat *curstat, int avgval, int nsecs) | |
1501 | { | |
1502 | return " -"; | |
1503 | } | |
1504 | ||
1505 | ||
1506 | proc_printdef procprt_UDPRASZ = | |
1507 | { "UDPRASZ", "UDPRASZ", procprt_UDPRASZ_a, procprt_UDPRASZ_e, 7 }; | |
1508 | /***************************************************************/ | |
1509 | char * | |
1510 | procprt_UDPSND_a(struct pstat *curstat, int avgval, int nsecs) | |
1511 | { | |
1512 | static char buf[10]; | |
1513 | ||
1514 | val2valstr(curstat->net.udpsnd, buf, 6, avgval, nsecs); | |
1515 | ||
1516 | return buf; | |
1517 | } | |
1518 | ||
1519 | char * | |
1520 | procprt_UDPSND_e(struct pstat *curstat, int avgval, int nsecs) | |
1521 | { | |
1522 | return " -"; | |
1523 | } | |
1524 | ||
1525 | proc_printdef procprt_UDPSND = | |
1526 | { "UDPSND", "UDPSND", procprt_UDPSND_a, procprt_UDPSND_e, 6 }; | |
1527 | /***************************************************************/ | |
1528 | char * | |
1529 | procprt_UDPSASZ_a(struct pstat *curstat, int avgval, int nsecs) | |
1530 | { | |
1531 | static char buf[10]; | |
1532 | ||
1533 | int avgudps = curstat->net.udpsnd ? | |
1534 | curstat->net.udpssz / curstat->net.udpsnd : 0; | |
1535 | ||
1536 | val2valstr(avgudps, buf, 7, 0, 0); | |
1537 | return buf; | |
1538 | } | |
1539 | ||
1540 | char * | |
1541 | procprt_UDPSASZ_e(struct pstat *curstat, int avgval, int nsecs) | |
1542 | { | |
1543 | return " -"; | |
1544 | } | |
1545 | ||
1546 | ||
1547 | proc_printdef procprt_UDPSASZ = | |
1548 | { "UDPSASZ", "UDPSASZ", procprt_UDPSASZ_a, procprt_UDPSASZ_e, 7 }; | |
1549 | /***************************************************************/ | |
1550 | char * | |
1551 | procprt_RAWSND_a(struct pstat *curstat, int avgval, int nsecs) | |
1552 | { | |
1553 | static char buf[10]; | |
1554 | ||
1555 | val2valstr(curstat->net.rawsnd, buf, 6, avgval, nsecs); | |
1556 | ||
1557 | return buf; | |
1558 | } | |
1559 | ||
1560 | char * | |
1561 | procprt_RAWSND_e(struct pstat *curstat, int avgval, int nsecs) | |
1562 | { | |
1563 | return " -"; | |
1564 | } | |
1565 | ||
1566 | proc_printdef procprt_RAWSND = | |
1567 | { "RAWSND", "RAWSND", procprt_RAWSND_a, procprt_RAWSND_e, 6 }; | |
1568 | /***************************************************************/ | |
1569 | char * | |
1570 | procprt_RAWRCV_a(struct pstat *curstat, int avgval, int nsecs) | |
1571 | { | |
1572 | static char buf[10]; | |
1573 | ||
1574 | val2valstr(curstat->net.rawrcv, buf, 6, avgval, nsecs); | |
1575 | ||
1576 | return buf; | |
1577 | } | |
1578 | ||
1579 | char * | |
1580 | procprt_RAWRCV_e(struct pstat *curstat, int avgval, int nsecs) | |
1581 | { | |
1582 | return " -"; | |
1583 | } | |
1584 | ||
1585 | proc_printdef procprt_RAWRCV = | |
1586 | { "RAWRCV", "RAWRCV", procprt_RAWRCV_a, procprt_RAWRCV_e, 6 }; | |
1587 | /***************************************************************/ | |
1588 | char * | |
1589 | procprt_RNET_a(struct pstat *curstat, int avgval, int nsecs) | |
1590 | { | |
1591 | static char buf[10]; | |
1592 | ||
1593 | val2valstr(curstat->net.tcprcv + curstat->net.udprcv + | |
1594 | curstat->net.rawrcv, buf, 4, avgval, nsecs); | |
1595 | ||
1596 | return buf; | |
1597 | } | |
1598 | ||
1599 | char * | |
1600 | procprt_RNET_e(struct pstat *curstat, int avgval, int nsecs) | |
1601 | { | |
1602 | return " -"; | |
1603 | } | |
1604 | ||
1605 | proc_printdef procprt_RNET = | |
1606 | { "RNET", "RNET", procprt_RNET_a, procprt_RNET_e, 4 }; | |
1607 | /***************************************************************/ | |
1608 | char * | |
1609 | procprt_SORTITEM_ae(struct pstat *curstat, int avgval, int nsecs) | |
1610 | { | |
1611 | return ""; // dummy function | |
1612 | } | |
1613 | ||
1614 | proc_printdef procprt_SORTITEM = | |
1615 | { 0, "SORTITEM", procprt_SORTITEM_ae, procprt_SORTITEM_ae, 4 }; | |
1616 | /***************************************************************/ | |
1617 | char * | |
1618 | procprt_SNET_a(struct pstat *curstat, int avgval, int nsecs) | |
1619 | { | |
1620 | static char buf[10]; | |
1621 | ||
1622 | val2valstr(curstat->net.tcpsnd + curstat->net.udpsnd + | |
1623 | curstat->net.rawsnd, buf, 4, avgval, nsecs); | |
1624 | ||
1625 | return buf; | |
1626 | } | |
1627 | ||
1628 | char * | |
1629 | procprt_SNET_e(struct pstat *curstat, int avgval, int nsecs) | |
1630 | { | |
1631 | return " -"; | |
1632 | } | |
1633 | ||
1634 | proc_printdef procprt_SNET = | |
1635 | { "SNET", "SNET", procprt_SNET_a, procprt_SNET_e, 4 }; |
0 | /* | |
1 | ** ATOP - System & Process Monitor | |
2 | ** | |
3 | ** The program 'atop' offers the possibility to view the activity of | |
4 | ** the system on system-level as well as process-level. | |
5 | ** | |
6 | ** This source-file contains the Linux-specific functions to calculate | |
7 | ** figures to be visualized. | |
8 | ** ========================================================================== | |
9 | ** Author: JC van Winkel - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: jc@ATComputing.nl | |
11 | ** Date: November 2009 | |
12 | ** -------------------------------------------------------------------------- | |
13 | ** Copyright (C) 2009 JC van Winkel | |
14 | ** | |
15 | ** This program is free software; you can redistribute it and/or modify it | |
16 | ** under the terms of the GNU General Public License as published by the | |
17 | ** Free Software Foundation; either version 2, or (at your option) any | |
18 | ** later version. | |
19 | ** | |
20 | ** This program is distributed in the hope that it will be useful, but | |
21 | ** WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
23 | ** See the GNU General Public License for more details. | |
24 | ** | |
25 | ** You should have received a copy of the GNU General Public License | |
26 | ** along with this program; if not, write to the Free Software | |
27 | ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
28 | ** -------------------------------------------------------------------------- | |
29 | ** | |
30 | ** $Log: showsys.c,v $ | |
31 | ** Revision 1.10 2010/11/12 06:06:43 gerlof | |
32 | ** Sometimes segmentation-fault on particular CPU-types | |
33 | ** due to memcpy i.s.o. memmove when moving memory in overlap. | |
34 | ** | |
35 | ** Revision 1.9 2010/10/23 14:04:20 gerlof | |
36 | ** Counters for total number of running and sleep threads (JC van Winkel). | |
37 | ** | |
38 | ** Revision 1.8 2010/05/18 19:20:02 gerlof | |
39 | ** Introduce CPU frequency and scaling (JC van Winkel). | |
40 | ** | |
41 | ** Revision 1.7 2010/04/23 08:16:58 gerlof | |
42 | ** Field 'avque' modified to 'avq' to be able to show higher values | |
43 | ** (especially on LVM-level). | |
44 | ** | |
45 | ** Revision 1.6 2010/03/04 10:53:37 gerlof | |
46 | ** Support I/O-statistics on logical volumes and MD devices. | |
47 | ** | |
48 | ** Revision 1.5 2009/12/17 11:59:36 gerlof | |
49 | ** Gather and display new counters: dirty cache and guest cpu usage. | |
50 | ** | |
51 | ** Revision 1.4 2009/12/17 08:53:03 gerlof | |
52 | ** If no coclors wanted, use bold display for critical resources. | |
53 | ** | |
54 | ** Revision 1.3 2009/12/17 07:33:05 gerlof | |
55 | ** Scale system-statistics properly when modifying window size (JC van Winkel). | |
56 | ** | |
57 | ** Revision 1.2 2009/12/10 11:56:08 gerlof | |
58 | ** Various bug-solutions. | |
59 | ** | |
60 | ** Revision 1.1 2009/12/10 09:46:16 gerlof | |
61 | ** Initial revision | |
62 | ** | |
63 | ** Initial revision | |
64 | ** | |
65 | ** | |
66 | ** Initial | |
67 | ** | |
68 | */ | |
69 | ||
70 | static const char rcsid[] = "XXXXXX"; | |
71 | ||
72 | #include <sys/types.h> | |
73 | #include <sys/param.h> | |
74 | #include <sys/stat.h> | |
75 | #include <signal.h> | |
76 | #include <time.h> | |
77 | #include <stdio.h> | |
78 | #include <stdlib.h> | |
79 | #include <string.h> | |
80 | #include <errno.h> | |
81 | #include <fcntl.h> | |
82 | #include <termio.h> | |
83 | #include <unistd.h> | |
84 | #include <stdarg.h> | |
85 | #include <curses.h> | |
86 | #include <pwd.h> | |
87 | #include <grp.h> | |
88 | #include <regex.h> | |
89 | ||
90 | #include "atop.h" | |
91 | #include "photoproc.h" | |
92 | #include "photosyst.h" | |
93 | #include "showgeneric.h" | |
94 | #include "showlinux.h" | |
95 | ||
96 | /*******************************************************************/ | |
97 | /* | |
98 | ** print the label of a system-statistics line and switch on | |
99 | ** colors if needed | |
100 | */ | |
101 | static int | |
102 | syscolorlabel(char *labeltext, int usecolors, unsigned int badness) | |
103 | { | |
104 | if (screen) | |
105 | { | |
106 | if (badness >= 100) | |
107 | { | |
108 | attron (A_BLINK); | |
109 | ||
110 | if (usecolors) | |
111 | attron(COLOR_PAIR(COLORHIGH)); | |
112 | else | |
113 | attron(A_BOLD); | |
114 | ||
115 | printg(labeltext); | |
116 | ||
117 | attroff(A_BLINK); | |
118 | ||
119 | return COLORHIGH; | |
120 | } | |
121 | ||
122 | if (almostcrit && badness >= almostcrit) | |
123 | { | |
124 | if (usecolors) | |
125 | attron(COLOR_PAIR(COLORMED)); | |
126 | else | |
127 | attron(A_BOLD); | |
128 | ||
129 | printg(labeltext); | |
130 | ||
131 | return COLORMED; | |
132 | } | |
133 | } | |
134 | ||
135 | /* | |
136 | ** no colors required or no reason to show colors | |
137 | */ | |
138 | printg(labeltext); | |
139 | return 0; | |
140 | } | |
141 | ||
142 | char * | |
143 | sysprt_BLANKBOX(void *p, void *notused); | |
144 | ||
145 | void | |
146 | addblanks(double *charslackused, double *charslackover) | |
147 | { | |
148 | *charslackused+=*charslackover; | |
149 | while (*charslackused>0.5) | |
150 | { | |
151 | printg(" "); | |
152 | *charslackused-=1; | |
153 | } | |
154 | } | |
155 | ||
156 | /* | |
157 | * showsysline | |
158 | * print an array of sys_printpair things. If the screen contains to | |
159 | * few character columns, lower priority items are removed | |
160 | * | |
161 | */ | |
162 | void showsysline(sys_printpair* elemptr, | |
163 | struct sstat* sstat, extraparam *extra, | |
164 | char *labeltext, int usecolors, unsigned int badness | |
165 | ) | |
166 | { | |
167 | sys_printdef *curelem; | |
168 | char coloron=0; | |
169 | int maxw = screen ? COLS : linelen; | |
170 | ||
171 | // every 15-char item is printed as: | |
172 | // >>>> | datadatadata<<<<< | |
173 | // 012345678901234 | |
174 | ||
175 | /* how items will fit on one line? */ | |
176 | int avail = (maxw-5)/15; | |
177 | ||
178 | ||
179 | coloron = syscolorlabel(labeltext, usecolors, badness); | |
180 | ||
181 | /* count number of items */ | |
182 | sys_printpair newelems[40]; // MURPHY | |
183 | int nitems; | |
184 | for (nitems=0; elemptr[nitems].f != 0; ++nitems) | |
185 | { | |
186 | newelems[nitems]=elemptr[nitems]; | |
187 | } | |
188 | newelems[nitems].f=0; | |
189 | ||
190 | /* remove lowest priority box to make room as needed */ | |
191 | while (nitems > avail) | |
192 | { | |
193 | int lowestprio=999999; | |
194 | int lowestprio_index=-1; | |
195 | int i; | |
196 | for (i=0; i<nitems; ++i) | |
197 | { | |
198 | if (newelems[i].prio < lowestprio) | |
199 | { | |
200 | lowestprio=newelems[i].prio; | |
201 | lowestprio_index=i; | |
202 | } | |
203 | } | |
204 | ||
205 | // lowest priority item found, remove from newelems; | |
206 | memmove(newelems+lowestprio_index, | |
207 | newelems+lowestprio_index+1, | |
208 | (nitems-lowestprio_index)* sizeof(sys_printpair)); | |
209 | // also copies final 0 entry | |
210 | nitems--; | |
211 | ||
212 | } | |
213 | ||
214 | /* | |
215 | * ``item shortage'' is used to make entire blank boxes | |
216 | * these boxes are spread out as much as possible | |
217 | * remaining slack is used to add spaces around the vertical | |
218 | * bars | |
219 | */ | |
220 | double slackitemsover; | |
221 | if (nitems >1) | |
222 | { | |
223 | slackitemsover=(double)(avail-nitems)/(nitems-1); | |
224 | } | |
225 | else | |
226 | { | |
227 | slackitemsover=(avail-nitems)/2; | |
228 | } | |
229 | ||
230 | ||
231 | // charslack: the slack in characters after using as many | |
232 | // items as possible | |
233 | double charslackover = screen ? ((COLS - 5) % 15) : 0.0; | |
234 | ||
235 | ||
236 | // two places per items where blanks can be added | |
237 | charslackover /= (avail * 2); | |
238 | ||
239 | ||
240 | double charslackused=0.0; | |
241 | double itemslackused=0.0; | |
242 | elemptr=newelems; | |
243 | while ((curelem=elemptr->f)!=0) | |
244 | { | |
245 | printg(" | "); | |
246 | addblanks(&charslackused, &charslackover); | |
247 | printg("%s", curelem->doconvert(sstat, extra)); | |
248 | if (screen) | |
249 | { | |
250 | itemslackused+=slackitemsover; | |
251 | while (itemslackused>0.5) | |
252 | { | |
253 | addblanks(&charslackused, &charslackover); | |
254 | printg(" | "); | |
255 | printg("%s", sysprt_BLANKBOX(0, 0)); | |
256 | addblanks(&charslackused, &charslackover); | |
257 | itemslackused-=1; | |
258 | } | |
259 | } | |
260 | elemptr++; | |
261 | ||
262 | addblanks(&charslackused, &charslackover); | |
263 | } | |
264 | ||
265 | printg(" |"); | |
266 | ||
267 | if (coloron) | |
268 | { | |
269 | if (screen) | |
270 | { | |
271 | if (usecolors) | |
272 | attroff(COLOR_PAIR(coloron)); | |
273 | else | |
274 | attroff(A_BOLD); | |
275 | } | |
276 | } | |
277 | ||
278 | if (!screen) | |
279 | { | |
280 | printg("\n"); | |
281 | } | |
282 | } | |
283 | ||
284 | /*******************************************************************/ | |
285 | /* SYSTEM PRINT FUNCTIONS */ | |
286 | /*******************************************************************/ | |
287 | char * | |
288 | sysprt_PRCSYS(void *notused, void *q) | |
289 | { | |
290 | extraparam *as=q; | |
291 | static char buf[15]="sys "; | |
292 | val2cpustr(as->totst * 1000/hertz, buf+5); | |
293 | return buf; | |
294 | } | |
295 | ||
296 | sys_printdef syspdef_PRCSYS = | |
297 | { "PRCSYS", sysprt_PRCSYS }; | |
298 | /*******************************************************************/ | |
299 | char * | |
300 | sysprt_PRCUSER(void *notused, void *q) | |
301 | { | |
302 | extraparam *as=q; | |
303 | static char buf[15]="user "; | |
304 | val2cpustr(as->totut * 1000/hertz, buf+5); | |
305 | return buf; | |
306 | } | |
307 | ||
308 | sys_printdef syspdef_PRCUSER = | |
309 | { "PRCUSER", sysprt_PRCUSER }; | |
310 | /*******************************************************************/ | |
311 | char * | |
312 | sysprt_PRCNPROC(void *notused, void *q) | |
313 | { | |
314 | extraparam *as=q; | |
315 | static char buf[15]="#proc "; | |
316 | val2valstr(as->nproc, buf+6, 6, 0, 0); | |
317 | return buf; | |
318 | } | |
319 | ||
320 | sys_printdef syspdef_PRCNPROC = | |
321 | { "PRCNPROC", sysprt_PRCNPROC }; | |
322 | /*******************************************************************/ | |
323 | char * | |
324 | sysprt_PRCNRUNNING(void *notused, void *q) | |
325 | { | |
326 | extraparam *as=q; | |
327 | static char buf[15]="#trun "; | |
328 | val2valstr(as->ntrun, buf+6, 6, 0, 0); | |
329 | return buf; | |
330 | } | |
331 | ||
332 | sys_printdef syspdef_PRCNRUNNING = | |
333 | { "PRCNRUNNING", sysprt_PRCNRUNNING }; | |
334 | /*******************************************************************/ | |
335 | char * | |
336 | sysprt_PRCNSLEEPING(void *notused, void *q) | |
337 | { | |
338 | extraparam *as=q; | |
339 | static char buf[15]="#tslpi "; | |
340 | val2valstr(as->ntslpi, buf+8, 4, 0, 0); | |
341 | return buf; | |
342 | } | |
343 | ||
344 | sys_printdef syspdef_PRCNSLEEPING = | |
345 | { "PRCNSLEEPING", sysprt_PRCNSLEEPING }; | |
346 | /*******************************************************************/ | |
347 | char * | |
348 | sysprt_PRCNDSLEEPING(void *notused, void *q) | |
349 | { | |
350 | extraparam *as=q; | |
351 | static char buf[15]="#tslpu "; | |
352 | val2valstr(as->ntslpu, buf+8, 4, 0, 0); | |
353 | return buf; | |
354 | } | |
355 | ||
356 | sys_printdef syspdef_PRCNDSLEEPING = | |
357 | { "PRCNDSLEEPING", sysprt_PRCNDSLEEPING }; | |
358 | /*******************************************************************/ | |
359 | char * | |
360 | sysprt_PRCNZOMBIE(void *notused, void *q) | |
361 | { | |
362 | extraparam *as=q; | |
363 | static char buf[15]="#zombie "; | |
364 | val2valstr(as->nzomb, buf+8, 4, 0, 0); | |
365 | return buf; | |
366 | } | |
367 | ||
368 | sys_printdef syspdef_PRCNZOMBIE = | |
369 | { "PRCNZOMBIE", sysprt_PRCNZOMBIE }; | |
370 | /*******************************************************************/ | |
371 | char * | |
372 | sysprt_PRCNNEXIT(void *notused, void *q) | |
373 | { | |
374 | extraparam *as=q; | |
375 | static char buf[15]="#exit "; | |
376 | if (supportflags & ACCTACTIVE) | |
377 | { | |
378 | val2valstr(as->nexit, buf+6, 6, as->avgval, as->nsecs); | |
379 | return buf; | |
380 | } | |
381 | else | |
382 | { | |
383 | return "#exit ?"; | |
384 | } | |
385 | return buf; | |
386 | } | |
387 | ||
388 | sys_printdef syspdef_PRCNNEXIT = | |
389 | { "PRCNNEXIT", sysprt_PRCNNEXIT }; | |
390 | /*******************************************************************/ | |
391 | char * | |
392 | sysprt_CPUSYS(void *p, void *q) | |
393 | { | |
394 | struct sstat *sstat=p; | |
395 | extraparam *as=q; | |
396 | static char buf[15]; | |
397 | sprintf(buf, "sys %6.0f%%", (sstat->cpu.all.stime | |
398 | * 100.0) / as->percputot); | |
399 | return buf; | |
400 | } | |
401 | ||
402 | sys_printdef syspdef_CPUSYS = | |
403 | { "CPUSYS", sysprt_CPUSYS }; | |
404 | /*******************************************************************/ | |
405 | char * | |
406 | sysprt_CPUUSER(void *p, void *q) | |
407 | { | |
408 | struct sstat *sstat=p; | |
409 | extraparam *as=q; | |
410 | static char buf[15]; | |
411 | sprintf(buf, "user %6.0f%%", | |
412 | ((sstat->cpu.all.utime + sstat->cpu.all.ntime) | |
413 | * 100.0) / as->percputot); | |
414 | return buf; | |
415 | } | |
416 | ||
417 | sys_printdef syspdef_CPUUSER = | |
418 | { "CPUUSER", sysprt_CPUUSER }; | |
419 | /*******************************************************************/ | |
420 | char * | |
421 | sysprt_CPUIRQ(void *p, void *q) | |
422 | { | |
423 | struct sstat *sstat=p; | |
424 | extraparam *as=q; | |
425 | static char buf[15]; | |
426 | sprintf(buf, "irq %6.0f%%", | |
427 | ((sstat->cpu.all.Itime + sstat->cpu.all.Stime) | |
428 | * 100.0) / as->percputot); | |
429 | return buf; | |
430 | } | |
431 | ||
432 | sys_printdef syspdef_CPUIRQ = | |
433 | { "CPUIRQ", sysprt_CPUIRQ }; | |
434 | /*******************************************************************/ | |
435 | char * | |
436 | sysprt_CPUIDLE(void *p, void *q) | |
437 | { | |
438 | struct sstat *sstat=p; | |
439 | extraparam *as=q; | |
440 | static char buf[15]; | |
441 | sprintf(buf, "idle %6.0f%%", | |
442 | (sstat->cpu.all.itime * 100.0) / as->percputot); | |
443 | return buf; | |
444 | } | |
445 | ||
446 | sys_printdef syspdef_CPUIDLE = | |
447 | { "CPUIDLE", sysprt_CPUIDLE }; | |
448 | /*******************************************************************/ | |
449 | char * | |
450 | sysprt_CPUWAIT(void *p, void *q) | |
451 | { | |
452 | struct sstat *sstat=p; | |
453 | extraparam *as=q; | |
454 | static char buf[15]; | |
455 | sprintf(buf, "wait %6.0f%%", | |
456 | (sstat->cpu.all.wtime * 100.0) / as->percputot); | |
457 | return buf; | |
458 | } | |
459 | ||
460 | sys_printdef syspdef_CPUWAIT = | |
461 | { "CPUWAIT", sysprt_CPUWAIT }; | |
462 | /*******************************************************************/ | |
463 | char * | |
464 | sysprt_CPUISYS(void *p, void *q) | |
465 | { | |
466 | struct sstat *sstat=p; | |
467 | extraparam *as=q; | |
468 | static char buf[15]; | |
469 | sprintf(buf, "sys %6.0f%%", (sstat->cpu.cpu[as->index].stime | |
470 | * 100.0) / as->percputot); | |
471 | return buf; | |
472 | } | |
473 | ||
474 | sys_printdef syspdef_CPUISYS = | |
475 | { "CPUISYS", sysprt_CPUISYS }; | |
476 | /*******************************************************************/ | |
477 | char * | |
478 | sysprt_CPUIUSER(void *p, void *q) | |
479 | { | |
480 | struct sstat *sstat=p; | |
481 | extraparam *as=q; | |
482 | static char buf[15]; | |
483 | sprintf(buf, "user %6.0f%%", | |
484 | ((sstat->cpu.cpu[as->index].utime + | |
485 | sstat->cpu.cpu[as->index].ntime) * 100.0) / as->percputot); | |
486 | return buf; | |
487 | } | |
488 | ||
489 | sys_printdef syspdef_CPUIUSER = | |
490 | { "CPUIUSER", sysprt_CPUIUSER }; | |
491 | /*******************************************************************/ | |
492 | char * | |
493 | sysprt_CPUIIRQ(void *p, void *q) | |
494 | { | |
495 | struct sstat *sstat=p; | |
496 | extraparam *as=q; | |
497 | static char buf[15]; | |
498 | sprintf(buf, "irq %6.0f%%", | |
499 | ((sstat->cpu.cpu[as->index].Itime + | |
500 | sstat->cpu.cpu[as->index].Stime) * 100.0) / as->percputot); | |
501 | return buf; | |
502 | } | |
503 | ||
504 | sys_printdef syspdef_CPUIIRQ = | |
505 | { "CPUIIRQ", sysprt_CPUIIRQ }; | |
506 | /*******************************************************************/ | |
507 | char * | |
508 | sysprt_CPUIIDLE(void *p, void *q) | |
509 | { | |
510 | struct sstat *sstat=p; | |
511 | extraparam *as=q; | |
512 | static char buf[15]; | |
513 | sprintf(buf, "idle %6.0f%%", | |
514 | (sstat->cpu.cpu[as->index].itime * 100.0) / as->percputot); | |
515 | return buf; | |
516 | } | |
517 | ||
518 | sys_printdef syspdef_CPUIIDLE = | |
519 | { "CPUIIDLE", sysprt_CPUIIDLE }; | |
520 | /*******************************************************************/ | |
521 | char * | |
522 | sysprt_CPUIWAIT(void *p, void *q) | |
523 | { | |
524 | struct sstat *sstat=p; | |
525 | extraparam *as=q; | |
526 | static char buf[15]; | |
527 | sprintf(buf, "cpu%03d w%3.0f%%", | |
528 | sstat->cpu.cpu[as->index].cpunr, | |
529 | (sstat->cpu.cpu[as->index].wtime * 100.0) / as->percputot); | |
530 | return buf; | |
531 | } | |
532 | ||
533 | sys_printdef syspdef_CPUIWAIT = | |
534 | { "CPUIWAIT", sysprt_CPUIWAIT }; | |
535 | /*******************************************************************/ | |
536 | void dofmt_cpufreq(char *buf, count_t maxfreq, count_t cnt, count_t ticks) | |
537 | { | |
538 | // >>>> | datadatadata<<<<< | |
539 | // 012345678901234 | |
540 | // curf 2.12GHz | |
541 | // avgf 2.12GHz | |
542 | ||
543 | // if ticks != 0, do full output | |
544 | if (ticks) | |
545 | { | |
546 | count_t curfreq = cnt/ticks; | |
547 | strcpy(buf, "avgf "); | |
548 | val2Hzstr(curfreq, buf+5); | |
549 | } | |
550 | else if (cnt) // no max, no %. if freq is known: print it | |
551 | { | |
552 | strcpy(buf, "curf "); | |
553 | val2Hzstr(cnt, buf+5); | |
554 | } | |
555 | else // nothing is known: print ????? | |
556 | { | |
557 | strcpy(buf, "curf ?MHz"); | |
558 | } | |
559 | } | |
560 | ||
561 | ||
562 | /* | |
563 | * sumscaling: sum scaling info for all processors | |
564 | * | |
565 | */ | |
566 | void sumscaling(struct sstat *sstat, count_t *maxfreq, | |
567 | count_t *cnt, count_t *ticks) | |
568 | { | |
569 | count_t mymaxfreq=0; | |
570 | count_t mycnt=0; | |
571 | count_t myticks=0; | |
572 | ||
573 | int n=sstat->cpu.nrcpu; | |
574 | int i; | |
575 | ||
576 | for (i=0; i < n; ++i) | |
577 | { | |
578 | mymaxfreq+= sstat->cpu.cpu[i].freqcnt.maxfreq; | |
579 | mycnt += sstat->cpu.cpu[i].freqcnt.cnt; | |
580 | myticks += sstat->cpu.cpu[i].freqcnt.ticks; | |
581 | } | |
582 | *maxfreq=mymaxfreq; | |
583 | *cnt =mycnt; | |
584 | *ticks =myticks; | |
585 | } | |
586 | ||
587 | ||
588 | void dofmt_cpuscale(char *buf, count_t maxfreq, count_t cnt, count_t ticks) | |
589 | { | |
590 | if (ticks) | |
591 | { | |
592 | count_t curfreq = cnt/ticks; | |
593 | int perc = 100 * curfreq / maxfreq; | |
594 | strcpy(buf, "avgscal "); | |
595 | sprintf(buf+7, "%4d%%", perc); | |
596 | } | |
597 | else if (maxfreq) // max frequency is known so % can be calculated | |
598 | { | |
599 | strcpy(buf, "curscal "); | |
600 | sprintf(buf+7, "%4lld%%", 100*cnt/maxfreq); | |
601 | } | |
602 | else // nothing is known: print ????? | |
603 | { | |
604 | strcpy(buf, "curscal ?%"); | |
605 | } | |
606 | } | |
607 | ||
608 | /*******************************************************************/ | |
609 | char * | |
610 | sysprt_CPUIFREQ(void *p, void *q) | |
611 | { | |
612 | ||
613 | struct sstat *sstat=p; | |
614 | extraparam *as=q; | |
615 | static char buf[15]; | |
616 | ||
617 | count_t maxfreq=sstat->cpu.cpu[as->index].freqcnt.maxfreq; | |
618 | count_t cnt=sstat->cpu.cpu[as->index].freqcnt.cnt; | |
619 | count_t ticks=sstat->cpu.cpu[as->index].freqcnt.ticks; | |
620 | ||
621 | dofmt_cpufreq(buf, maxfreq, cnt, ticks); | |
622 | return buf; | |
623 | } | |
624 | ||
625 | sys_printdef syspdef_CPUIFREQ = | |
626 | { "CPUIFREQ", sysprt_CPUIFREQ }; | |
627 | /*******************************************************************/ | |
628 | char * | |
629 | sysprt_CPUFREQ(void *p, void *q) | |
630 | { | |
631 | ||
632 | struct sstat *sstat=p; | |
633 | static char buf[15]; | |
634 | ||
635 | count_t maxfreq; | |
636 | count_t cnt; | |
637 | count_t ticks; | |
638 | int n=sstat->cpu.nrcpu; | |
639 | ||
640 | sumscaling(sstat, &maxfreq, &cnt, &ticks); | |
641 | dofmt_cpufreq(buf, maxfreq/n, cnt/n, ticks/n); | |
642 | return buf; | |
643 | } | |
644 | ||
645 | sys_printdef syspdef_CPUFREQ = | |
646 | { "CPUFREQ", sysprt_CPUFREQ }; | |
647 | /*******************************************************************/ | |
648 | char * | |
649 | sysprt_CPUISCALE(void *p, void *q) | |
650 | { | |
651 | ||
652 | struct sstat *sstat=p; | |
653 | extraparam *as=q; | |
654 | static char buf[15]; | |
655 | ||
656 | count_t maxfreq=sstat->cpu.cpu[as->index].freqcnt.maxfreq; | |
657 | count_t cnt=sstat->cpu.cpu[as->index].freqcnt.cnt; | |
658 | count_t ticks=sstat->cpu.cpu[as->index].freqcnt.ticks; | |
659 | ||
660 | dofmt_cpuscale(buf, maxfreq, cnt, ticks); | |
661 | return buf; | |
662 | } | |
663 | ||
664 | sys_printdef syspdef_CPUISCALE = | |
665 | { "CPUISCALE", sysprt_CPUISCALE }; | |
666 | /*******************************************************************/ | |
667 | char * | |
668 | sysprt_CPUSCALE(void *p, void *q) | |
669 | { | |
670 | ||
671 | struct sstat *sstat=p; | |
672 | static char buf[15]; | |
673 | ||
674 | count_t maxfreq; | |
675 | count_t cnt; | |
676 | count_t ticks; | |
677 | int n=sstat->cpu.nrcpu; | |
678 | ||
679 | sumscaling(sstat, &maxfreq, &cnt, &ticks); | |
680 | dofmt_cpuscale(buf, maxfreq/n, cnt/n, ticks/n); | |
681 | return buf; | |
682 | } | |
683 | ||
684 | sys_printdef syspdef_CPUSCALE = | |
685 | { "CPUSCALE", sysprt_CPUSCALE }; | |
686 | /*******************************************************************/ | |
687 | char * | |
688 | sysprt_CPUSTEAL(void *p, void *q) | |
689 | { | |
690 | struct sstat *sstat=p; | |
691 | extraparam *as=q; | |
692 | static char buf[15]; | |
693 | sprintf(buf, "steal %5.0f%%", | |
694 | (sstat->cpu.all.steal * 100.0) / as->percputot); | |
695 | return buf; | |
696 | } | |
697 | ||
698 | sys_printdef syspdef_CPUSTEAL = | |
699 | { "CPUSTEAL", sysprt_CPUSTEAL }; | |
700 | /*******************************************************************/ | |
701 | char * | |
702 | sysprt_CPUISTEAL(void *p, void *q) | |
703 | { | |
704 | struct sstat *sstat=p; | |
705 | extraparam *as=q; | |
706 | static char buf[15]; | |
707 | sprintf(buf, "steal %5.0f%%", | |
708 | (sstat->cpu.cpu[as->index].steal * 100.0) / as->percputot); | |
709 | return buf; | |
710 | } | |
711 | ||
712 | sys_printdef syspdef_CPUISTEAL = | |
713 | { "CPUISTEAL", sysprt_CPUISTEAL }; | |
714 | /*******************************************************************/ | |
715 | char * | |
716 | sysprt_CPUGUEST(void *p, void *q) | |
717 | { | |
718 | struct sstat *sstat=p; | |
719 | extraparam *as=q; | |
720 | static char buf[15]; | |
721 | sprintf(buf, "guest %5.0f%%", | |
722 | (sstat->cpu.all.guest * 100.0) / as->percputot); | |
723 | return buf; | |
724 | } | |
725 | ||
726 | sys_printdef syspdef_CPUGUEST = | |
727 | { "CPUGUEST", sysprt_CPUGUEST }; | |
728 | /*******************************************************************/ | |
729 | char * | |
730 | sysprt_CPUIGUEST(void *p, void *q) | |
731 | { | |
732 | struct sstat *sstat=p; | |
733 | extraparam *as=q; | |
734 | static char buf[15]; | |
735 | sprintf(buf, "guest %5.0f%%", | |
736 | (sstat->cpu.cpu[as->index].guest * 100.0) / as->percputot); | |
737 | return buf; | |
738 | } | |
739 | ||
740 | sys_printdef syspdef_CPUIGUEST = | |
741 | { "CPUIGUEST", sysprt_CPUIGUEST }; | |
742 | /*******************************************************************/ | |
743 | char * | |
744 | sysprt_CPLAVG1(void *p, void *notused) | |
745 | { | |
746 | struct sstat *sstat=p; | |
747 | static char buf[15]="avg1 "; | |
748 | ||
749 | if (sstat->cpu.lavg1 > 999.0) | |
750 | { | |
751 | sprintf(buf+5, "%7.0f", sstat->cpu.lavg1); | |
752 | } | |
753 | else | |
754 | { | |
755 | sprintf(buf+5, "%7.2f", sstat->cpu.lavg1); | |
756 | } | |
757 | return buf; | |
758 | } | |
759 | ||
760 | sys_printdef syspdef_CPLAVG1 = | |
761 | { "CPLAVG1", sysprt_CPLAVG1 }; | |
762 | /*******************************************************************/ | |
763 | char * | |
764 | sysprt_CPLAVG5(void *p, void *notused) | |
765 | { | |
766 | struct sstat *sstat=p; | |
767 | static char buf[15]="avg5 "; | |
768 | ||
769 | if (sstat->cpu.lavg5 > 999.0) | |
770 | { | |
771 | sprintf(buf+5, "%7.0f", sstat->cpu.lavg5); | |
772 | } | |
773 | else | |
774 | { | |
775 | sprintf(buf+5, "%7.2f", sstat->cpu.lavg5); | |
776 | } | |
777 | return buf; | |
778 | } | |
779 | ||
780 | sys_printdef syspdef_CPLAVG5 = | |
781 | { "CPLAVG5", sysprt_CPLAVG5 }; | |
782 | /*******************************************************************/ | |
783 | char * | |
784 | sysprt_CPLAVG15(void *p, void *notused) | |
785 | { | |
786 | struct sstat *sstat=p; | |
787 | static char buf[15]="avg15 "; | |
788 | ||
789 | if (sstat->cpu.lavg15 > 999.0) | |
790 | { | |
791 | sprintf(buf+6, "%6.0f", sstat->cpu.lavg15); | |
792 | } | |
793 | else | |
794 | { | |
795 | sprintf(buf+6, "%6.2f", sstat->cpu.lavg15); | |
796 | } | |
797 | return buf; | |
798 | } | |
799 | ||
800 | sys_printdef syspdef_CPLAVG15 = | |
801 | { "CPLAVG15", sysprt_CPLAVG15 }; | |
802 | /*******************************************************************/ | |
803 | char * | |
804 | sysprt_CPLCSW(void *p, void *q) | |
805 | { | |
806 | struct sstat *sstat=p; | |
807 | extraparam *as=q; | |
808 | static char buf[16]="csw "; | |
809 | ||
810 | val2valstr(sstat->cpu.csw, buf+4 , 8,as->avgval,as->nsecs); | |
811 | return buf; | |
812 | } | |
813 | ||
814 | sys_printdef syspdef_CPLCSW = | |
815 | { "CPLCSW", sysprt_CPLCSW }; | |
816 | /*******************************************************************/ | |
817 | char * | |
818 | sysprt_PRCCLONES(void *p, void *q) | |
819 | { | |
820 | struct sstat *sstat=p; | |
821 | extraparam *as=q; | |
822 | static char buf[16]="clones "; | |
823 | ||
824 | val2valstr(sstat->cpu.nprocs, buf+7 , 5,as->avgval,as->nsecs); | |
825 | return buf; | |
826 | } | |
827 | ||
828 | sys_printdef syspdef_PRCCLONES = | |
829 | { "PRCCLONES", sysprt_PRCCLONES }; | |
830 | /*******************************************************************/ | |
831 | char * | |
832 | sysprt_CPLNUMCPU(void *p, void *q) | |
833 | { | |
834 | struct sstat *sstat=p; | |
835 | extraparam *as=q; | |
836 | static char buf[16]="numcpu "; | |
837 | ||
838 | val2valstr(sstat->cpu.nrcpu, buf+7 , 5,0,as->nsecs); | |
839 | return buf; | |
840 | } | |
841 | ||
842 | sys_printdef syspdef_CPLNUMCPU = | |
843 | { "CPLNUMCPU", sysprt_CPLNUMCPU }; | |
844 | /*******************************************************************/ | |
845 | char * | |
846 | sysprt_CPLINTR(void *p, void *q) | |
847 | { | |
848 | struct sstat *sstat=p; | |
849 | extraparam *as=q; | |
850 | static char buf[16]="intr "; | |
851 | ||
852 | val2valstr(sstat->cpu.devint, buf+5 , 7,as->avgval,as->nsecs); | |
853 | return buf; | |
854 | } | |
855 | ||
856 | sys_printdef syspdef_CPLINTR = | |
857 | { "CPLINTR", sysprt_CPLINTR }; | |
858 | /*******************************************************************/ | |
859 | char * | |
860 | sysprt_MEMTOT(void *p, void *notused) | |
861 | { | |
862 | struct sstat *sstat=p; | |
863 | static char buf[16]="tot "; | |
864 | val2memstr(sstat->mem.physmem * pagesize, buf+6, MBFORMAT, 0, 0); | |
865 | return buf; | |
866 | } | |
867 | ||
868 | sys_printdef syspdef_MEMTOT = | |
869 | { "MEMTOT", sysprt_MEMTOT }; | |
870 | /*******************************************************************/ | |
871 | char * | |
872 | sysprt_MEMFREE(void *p, void *notused) | |
873 | { | |
874 | struct sstat *sstat=p; | |
875 | static char buf[16]="free "; | |
876 | val2memstr(sstat->mem.freemem * pagesize, buf+6, MBFORMAT, 0, 0); | |
877 | return buf; | |
878 | } | |
879 | ||
880 | sys_printdef syspdef_MEMFREE = | |
881 | { "MEMFREE", sysprt_MEMFREE }; | |
882 | /*******************************************************************/ | |
883 | char * | |
884 | sysprt_MEMCACHE(void *p, void *notused) | |
885 | { | |
886 | struct sstat *sstat=p; | |
887 | static char buf[16]="cache "; | |
888 | val2memstr(sstat->mem.cachemem * pagesize, buf+6, MBFORMAT, 0, 0); | |
889 | return buf; | |
890 | } | |
891 | ||
892 | sys_printdef syspdef_MEMCACHE = | |
893 | { "MEMCACHE", sysprt_MEMCACHE }; | |
894 | /*******************************************************************/ | |
895 | char * | |
896 | sysprt_MEMDIRTY(void *p, void *notused) | |
897 | { | |
898 | struct sstat *sstat=p; | |
899 | static char buf[16] = "dirty "; | |
900 | ||
901 | val2memstr(sstat->mem.cachedrt * pagesize, buf+6, MBFORMAT, 0, 0); | |
902 | ||
903 | return buf; | |
904 | } | |
905 | ||
906 | sys_printdef syspdef_MEMDIRTY = | |
907 | { "MEMDIRTY", sysprt_MEMDIRTY }; | |
908 | /*******************************************************************/ | |
909 | char * | |
910 | sysprt_MEMBUFFER(void *p, void *notused) | |
911 | { | |
912 | struct sstat *sstat=p; | |
913 | static char buf[16]="buff "; | |
914 | val2memstr(sstat->mem.buffermem * pagesize, buf+6, MBFORMAT, 0, 0); | |
915 | return buf; | |
916 | } | |
917 | ||
918 | sys_printdef syspdef_MEMBUFFER = | |
919 | { "MEMBUFFER", sysprt_MEMBUFFER }; | |
920 | /*******************************************************************/ | |
921 | char * | |
922 | sysprt_MEMSLAB(void *p, void *notused) | |
923 | { | |
924 | struct sstat *sstat=p; | |
925 | static char buf[16]="slab "; | |
926 | val2memstr(sstat->mem.slabmem * pagesize, buf+6, MBFORMAT, 0, 0); | |
927 | return buf; | |
928 | } | |
929 | ||
930 | sys_printdef syspdef_MEMSLAB = | |
931 | { "MEMSLAB", sysprt_MEMSLAB }; | |
932 | /*******************************************************************/ | |
933 | char * | |
934 | sysprt_SWPTOT(void *p, void *notused) | |
935 | { | |
936 | struct sstat *sstat=p; | |
937 | static char buf[16]="tot "; | |
938 | val2memstr(sstat->mem.totswap * pagesize, buf+6, MBFORMAT, 0, 0); | |
939 | return buf; | |
940 | } | |
941 | ||
942 | sys_printdef syspdef_SWPTOT = | |
943 | { "SWPTOT", sysprt_SWPTOT }; | |
944 | /*******************************************************************/ | |
945 | char * | |
946 | sysprt_SWPFREE(void *p, void *notused) | |
947 | { | |
948 | struct sstat *sstat=p; | |
949 | static char buf[16]="free "; | |
950 | val2memstr(sstat->mem.freeswap * pagesize, buf+6, MBFORMAT, 0, 0); | |
951 | return buf; | |
952 | } | |
953 | ||
954 | sys_printdef syspdef_SWPFREE = | |
955 | { "SWPFREE", sysprt_SWPFREE }; | |
956 | /*******************************************************************/ | |
957 | char * | |
958 | sysprt_SWPCOMMITTED(void *p, void *notused) | |
959 | { | |
960 | struct sstat *sstat=p; | |
961 | static char buf[16]="vmcom "; | |
962 | val2memstr(sstat->mem.committed * pagesize, buf+6, MBFORMAT, 0, 0); | |
963 | return buf; | |
964 | } | |
965 | ||
966 | sys_printdef syspdef_SWPCOMMITTED = | |
967 | { "SWPCOMMITTED", sysprt_SWPCOMMITTED }; | |
968 | /*******************************************************************/ | |
969 | char * | |
970 | sysprt_SWPCOMMITLIM(void *p, void *notused) | |
971 | { | |
972 | struct sstat *sstat=p; | |
973 | static char buf[16]="vmlim "; | |
974 | val2memstr(sstat->mem.commitlim * pagesize, buf+6, MBFORMAT, 0, 0); | |
975 | return buf; | |
976 | } | |
977 | ||
978 | sys_printdef syspdef_SWPCOMMITLIM = | |
979 | { "SWPCOMMITLIM", sysprt_SWPCOMMITLIM }; | |
980 | /*******************************************************************/ | |
981 | char * | |
982 | sysprt_PAGSCAN(void *p, void *q) | |
983 | { | |
984 | struct sstat *sstat=p; | |
985 | extraparam *as=q; | |
986 | static char buf[16]="scan "; | |
987 | val2valstr(sstat->mem.pgscans, buf+ 6, 6, as->avgval, as->nsecs); | |
988 | return buf; | |
989 | } | |
990 | ||
991 | sys_printdef syspdef_PAGSCAN = | |
992 | { "PAGSCAN", sysprt_PAGSCAN }; | |
993 | /*******************************************************************/ | |
994 | char * | |
995 | sysprt_PAGSTALL(void *p, void *q) | |
996 | { | |
997 | struct sstat *sstat=p; | |
998 | extraparam *as=q; | |
999 | static char buf[16]="stall "; | |
1000 | val2valstr(sstat->mem.allocstall, buf+6, 6, as->avgval, as->nsecs); | |
1001 | return buf; | |
1002 | } | |
1003 | ||
1004 | sys_printdef syspdef_PAGSTALL = | |
1005 | { "PAGSTALL", sysprt_PAGSTALL }; | |
1006 | /*******************************************************************/ | |
1007 | char * | |
1008 | sysprt_PAGSWIN(void *p, void *q) | |
1009 | { | |
1010 | struct sstat *sstat=p; | |
1011 | extraparam *as=q; | |
1012 | static char buf[16]="swin "; | |
1013 | val2valstr(sstat->mem.swins, buf+5, 7, as->avgval, as->nsecs); | |
1014 | return buf; | |
1015 | } | |
1016 | ||
1017 | sys_printdef syspdef_PAGSWIN = | |
1018 | { "PAGSWIN", sysprt_PAGSWIN }; | |
1019 | /*******************************************************************/ | |
1020 | char * | |
1021 | sysprt_PAGSWOUT(void *p, void *q) | |
1022 | { | |
1023 | struct sstat *sstat=p; | |
1024 | extraparam *as=q; | |
1025 | static char buf[16]="swout "; | |
1026 | val2valstr(sstat->mem.swouts, buf+6, 6, as->avgval, as->nsecs); | |
1027 | return buf; | |
1028 | } | |
1029 | ||
1030 | sys_printdef syspdef_PAGSWOUT = | |
1031 | { "PAGSWOUT", sysprt_PAGSWOUT }; | |
1032 | /*******************************************************************/ | |
1033 | char * | |
1034 | sysprt_DSKNAME(void *p, void *q) | |
1035 | { | |
1036 | extraparam *as=q; | |
1037 | static char buf[16]; | |
1038 | char *pn; | |
1039 | int len; | |
1040 | ||
1041 | if ( (len = strlen(as->perdsk[as->index].name)) > 12) | |
1042 | pn = as->perdsk[as->index].name + len - 12; | |
1043 | else | |
1044 | pn = as->perdsk[as->index].name; | |
1045 | ||
1046 | sprintf(buf, "%12.12s", pn); | |
1047 | return buf; | |
1048 | } | |
1049 | ||
1050 | sys_printdef syspdef_DSKNAME = | |
1051 | { "DSKNAME", sysprt_DSKNAME }; | |
1052 | /*******************************************************************/ | |
1053 | char * | |
1054 | sysprt_DSKBUSY(void *p, void *q) | |
1055 | { | |
1056 | extraparam *as=q; | |
1057 | static char buf[16]="busy "; | |
1058 | ||
1059 | sprintf(buf+5,"%6.0lf%%", | |
1060 | (as->perdsk[as->index].io_ms * 100.0 / as->mstot)); | |
1061 | return buf; | |
1062 | } | |
1063 | ||
1064 | sys_printdef syspdef_DSKBUSY = | |
1065 | { "DSKBUSY", sysprt_DSKBUSY }; | |
1066 | /*******************************************************************/ | |
1067 | char * | |
1068 | sysprt_DSKNREAD(void *p, void *q) | |
1069 | { | |
1070 | extraparam *as=q; | |
1071 | static char buf[16]="read "; | |
1072 | ||
1073 | val2valstr(as->perdsk[as->index].nread, | |
1074 | buf+5, 7, as->avgval, as->nsecs); | |
1075 | return buf; | |
1076 | } | |
1077 | ||
1078 | sys_printdef syspdef_DSKNREAD = | |
1079 | { "DSKNREAD", sysprt_DSKNREAD }; | |
1080 | /*******************************************************************/ | |
1081 | char * | |
1082 | sysprt_DSKNWRITE(void *p, void *q) | |
1083 | { | |
1084 | extraparam *as=q; | |
1085 | static char buf[16]="write "; | |
1086 | ||
1087 | val2valstr(as->perdsk[as->index].nwrite, | |
1088 | buf+6, 6, as->avgval, as->nsecs); | |
1089 | return buf; | |
1090 | } | |
1091 | ||
1092 | sys_printdef syspdef_DSKNWRITE = | |
1093 | { "DSKNWRITE", sysprt_DSKNWRITE }; | |
1094 | /*******************************************************************/ | |
1095 | char * | |
1096 | sysprt_DSKKBPERWR(void *p, void *q) | |
1097 | { | |
1098 | extraparam *as=q; | |
1099 | static char buf[16]="KiB/w "; | |
1100 | struct perdsk *dp = &(as->perdsk[as->index]); | |
1101 | ||
1102 | val2valstr(dp->nwrite ? dp->nwsect / dp->nwrite / 2 : 0, | |
1103 | buf+6, 6, 0, as->nsecs); | |
1104 | return buf; | |
1105 | } | |
1106 | ||
1107 | sys_printdef syspdef_DSKKBPERWR = | |
1108 | { "DSKKBPERWR", sysprt_DSKKBPERWR }; | |
1109 | /*******************************************************************/ | |
1110 | char * | |
1111 | sysprt_DSKKBPERRD(void *p, void *q) | |
1112 | { | |
1113 | extraparam *as=q; | |
1114 | static char buf[16]="KiB/r "; | |
1115 | struct perdsk *dp = &(as->perdsk[as->index]); | |
1116 | ||
1117 | val2valstr(dp->nread ? dp->nrsect / dp->nread / 2 : 0, | |
1118 | buf+6, 6, 0, as->nsecs); | |
1119 | return buf; | |
1120 | } | |
1121 | ||
1122 | sys_printdef syspdef_DSKKBPERRD = | |
1123 | { "DSKKBPERRD", sysprt_DSKKBPERRD }; | |
1124 | /*******************************************************************/ | |
1125 | char * | |
1126 | sysprt_DSKMBPERSECWR(void *p, void *q) | |
1127 | { | |
1128 | extraparam *as=q; | |
1129 | static char buf[16]="MBw/s "; | |
1130 | struct perdsk *dp = &(as->perdsk[as->index]); | |
1131 | ||
1132 | sprintf(buf+6, "%6.2lf", dp->nwsect / 2.0 / 1024 / as->nsecs); | |
1133 | ||
1134 | return buf; | |
1135 | } | |
1136 | ||
1137 | sys_printdef syspdef_DSKMBPERSECWR = | |
1138 | { "DSKMBPERSECWR", sysprt_DSKMBPERSECWR }; | |
1139 | /*******************************************************************/ | |
1140 | char * | |
1141 | sysprt_DSKMBPERSECRD(void *p, void *q) | |
1142 | { | |
1143 | extraparam *as=q; | |
1144 | static char buf[16]="MBr/s "; | |
1145 | struct perdsk *dp = &(as->perdsk[as->index]); | |
1146 | ||
1147 | sprintf(buf+6, "%6.2lf", dp->nrsect / 2.0 / 1024 / as->nsecs); | |
1148 | return buf; | |
1149 | } | |
1150 | ||
1151 | sys_printdef syspdef_DSKMBPERSECRD = | |
1152 | { "DSKMBPERSECRD", sysprt_DSKMBPERSECRD }; | |
1153 | /*******************************************************************/ | |
1154 | char * | |
1155 | sysprt_DSKAVQUEUE(void *p, void *q) | |
1156 | { | |
1157 | extraparam *as=q; | |
1158 | static char buf[16]="avq "; | |
1159 | struct perdsk *dp = &(as->perdsk[as->index]); | |
1160 | ||
1161 | sprintf(buf+4, "%8.2f", dp->io_ms ? | |
1162 | (double)dp->avque / dp->io_ms : 0.0); | |
1163 | return buf; | |
1164 | } | |
1165 | ||
1166 | sys_printdef syspdef_DSKAVQUEUE = | |
1167 | { "DSKAVQUEUE", sysprt_DSKAVQUEUE }; | |
1168 | /*******************************************************************/ | |
1169 | char * | |
1170 | sysprt_DSKAVIO(void *p, void *q) | |
1171 | { | |
1172 | extraparam *as=q; | |
1173 | static char buf[16]="avio "; | |
1174 | double tim= as->iotot ? | |
1175 | (double)(as->perdsk[as->index].io_ms) / as->iotot : 0; | |
1176 | ||
1177 | if (tim > 100.0) | |
1178 | { | |
1179 | sprintf(buf+5, "%4.0lf ms", tim); | |
1180 | } | |
1181 | else if (tim > 10.0) | |
1182 | { | |
1183 | sprintf(buf+5, "%4.1lf ms", tim); | |
1184 | } | |
1185 | else | |
1186 | { | |
1187 | sprintf(buf+5, "%4.2lf ms", tim); | |
1188 | } | |
1189 | ||
1190 | return buf; | |
1191 | } | |
1192 | ||
1193 | sys_printdef syspdef_DSKAVIO = | |
1194 | { "DSKAVIO", sysprt_DSKAVIO }; | |
1195 | /*******************************************************************/ | |
1196 | char * | |
1197 | sysprt_NETTRANSPORT(void *p, void *notused) | |
1198 | { | |
1199 | return "transport "; | |
1200 | } | |
1201 | ||
1202 | sys_printdef syspdef_NETTRANSPORT = | |
1203 | { "NETTRANSPORT", sysprt_NETTRANSPORT }; | |
1204 | /*******************************************************************/ | |
1205 | char * | |
1206 | sysprt_NETTCPI(void *p, void *q) | |
1207 | { | |
1208 | struct sstat *sstat=p; | |
1209 | extraparam *as=q; | |
1210 | static char buf[16]="tcpi "; | |
1211 | val2valstr(sstat->net.tcp.InSegs, buf+5, 7, as->avgval, as->nsecs); | |
1212 | return buf; | |
1213 | } | |
1214 | ||
1215 | sys_printdef syspdef_NETTCPI = | |
1216 | { "NETTCPI", sysprt_NETTCPI }; | |
1217 | /*******************************************************************/ | |
1218 | char * | |
1219 | sysprt_NETTCPO(void *p, void *q) | |
1220 | { | |
1221 | struct sstat *sstat=p; | |
1222 | extraparam *as=q; | |
1223 | static char buf[16]="tcpo "; | |
1224 | val2valstr(sstat->net.tcp.OutSegs, buf+5, 7, as->avgval, as->nsecs); | |
1225 | return buf; | |
1226 | } | |
1227 | ||
1228 | sys_printdef syspdef_NETTCPO = | |
1229 | { "NETTCPO", sysprt_NETTCPO }; | |
1230 | /*******************************************************************/ | |
1231 | char * | |
1232 | sysprt_NETTCPACTOPEN(void *p, void *q) | |
1233 | { | |
1234 | struct sstat *sstat=p; | |
1235 | extraparam *as=q; | |
1236 | static char buf[16]="tcpao "; | |
1237 | val2valstr(sstat->net.tcp.ActiveOpens, buf+6, 6, as->avgval, as->nsecs); | |
1238 | return buf; | |
1239 | } | |
1240 | ||
1241 | sys_printdef syspdef_NETTCPACTOPEN = | |
1242 | { "NETTCPACTOPEN", sysprt_NETTCPACTOPEN }; | |
1243 | /*******************************************************************/ | |
1244 | char * | |
1245 | sysprt_NETTCPPASVOPEN(void *p, void *q) | |
1246 | { | |
1247 | struct sstat *sstat=p; | |
1248 | extraparam *as=q; | |
1249 | static char buf[16]="tcppo "; | |
1250 | val2valstr(sstat->net.tcp.PassiveOpens, buf+6, 6, as->avgval, as->nsecs); | |
1251 | return buf; | |
1252 | } | |
1253 | ||
1254 | sys_printdef syspdef_NETTCPPASVOPEN = | |
1255 | { "NETTCPPASVOPEN", sysprt_NETTCPPASVOPEN }; | |
1256 | /*******************************************************************/ | |
1257 | char * | |
1258 | sysprt_NETTCPRETRANS(void *p, void *q) | |
1259 | { | |
1260 | struct sstat *sstat=p; | |
1261 | extraparam *as=q; | |
1262 | static char buf[16]="tcprs "; | |
1263 | val2valstr(sstat->net.tcp.RetransSegs, buf+6, 6, as->avgval, as->nsecs); | |
1264 | return buf; | |
1265 | } | |
1266 | ||
1267 | sys_printdef syspdef_NETTCPRETRANS = | |
1268 | { "NETTCPRETRANS", sysprt_NETTCPRETRANS }; | |
1269 | /*******************************************************************/ | |
1270 | char * | |
1271 | sysprt_NETTCPINERR(void *p, void *q) | |
1272 | { | |
1273 | struct sstat *sstat=p; | |
1274 | extraparam *as=q; | |
1275 | static char buf[16]="tcpie "; | |
1276 | val2valstr(sstat->net.tcp.InErrs, buf+6, 6, as->avgval, as->nsecs); | |
1277 | return buf; | |
1278 | } | |
1279 | ||
1280 | sys_printdef syspdef_NETTCPINERR = | |
1281 | { "NETTCPINERR", sysprt_NETTCPINERR }; | |
1282 | /*******************************************************************/ | |
1283 | char * | |
1284 | sysprt_NETTCPORESET(void *p, void *q) | |
1285 | { | |
1286 | struct sstat *sstat=p; | |
1287 | extraparam *as=q; | |
1288 | static char buf[16]="tcpor "; | |
1289 | val2valstr(sstat->net.tcp.OutRsts, buf+6, 6, as->avgval, as->nsecs); | |
1290 | return buf; | |
1291 | } | |
1292 | ||
1293 | sys_printdef syspdef_NETTCPORESET = | |
1294 | { "NETTCPORESET", sysprt_NETTCPORESET }; | |
1295 | /*******************************************************************/ | |
1296 | char * | |
1297 | sysprt_NETUDPNOPORT(void *p, void *q) | |
1298 | { | |
1299 | struct sstat *sstat=p; | |
1300 | extraparam *as=q; | |
1301 | static char buf[16]="udpnp "; | |
1302 | val2valstr(sstat->net.udpv4.NoPorts, buf+6, 6, as->avgval, as->nsecs); | |
1303 | return buf; | |
1304 | } | |
1305 | ||
1306 | sys_printdef syspdef_NETUDPNOPORT = | |
1307 | { "NETUDPNOPORT", sysprt_NETUDPNOPORT }; | |
1308 | /*******************************************************************/ | |
1309 | char * | |
1310 | sysprt_NETUDPINERR(void *p, void *q) | |
1311 | { | |
1312 | struct sstat *sstat=p; | |
1313 | extraparam *as=q; | |
1314 | static char buf[16]="udpip "; | |
1315 | val2valstr(sstat->net.udpv4.InErrors, buf+6, 6, as->avgval, as->nsecs); | |
1316 | return buf; | |
1317 | } | |
1318 | ||
1319 | sys_printdef syspdef_NETUDPINERR = | |
1320 | { "NETUDPINERR", sysprt_NETUDPINERR }; | |
1321 | /*******************************************************************/ | |
1322 | char * | |
1323 | sysprt_NETUDPI(void *p, void *q) | |
1324 | { | |
1325 | struct sstat *sstat=p; | |
1326 | extraparam *as=q; | |
1327 | static char buf[16]="udpi "; | |
1328 | count_t udpin = sstat->net.udpv4.InDatagrams + | |
1329 | sstat->net.udpv6.Udp6InDatagrams; | |
1330 | val2valstr(udpin, buf+5, 7, as->avgval, as->nsecs); | |
1331 | return buf; | |
1332 | } | |
1333 | ||
1334 | sys_printdef syspdef_NETUDPI = | |
1335 | { "NETUDPI", sysprt_NETUDPI }; | |
1336 | /*******************************************************************/ | |
1337 | char * | |
1338 | sysprt_NETUDPO(void *p, void *q) | |
1339 | { | |
1340 | struct sstat *sstat=p; | |
1341 | extraparam *as=q; | |
1342 | static char buf[16]="udpo "; | |
1343 | count_t udpout = sstat->net.udpv4.OutDatagrams + | |
1344 | sstat->net.udpv6.Udp6OutDatagrams; | |
1345 | val2valstr(udpout, buf+5, 7, as->avgval, as->nsecs); | |
1346 | return buf; | |
1347 | } | |
1348 | ||
1349 | sys_printdef syspdef_NETUDPO = | |
1350 | { "NETUDPO", sysprt_NETUDPO }; | |
1351 | /*******************************************************************/ | |
1352 | char * | |
1353 | sysprt_NETNETWORK(void *p, void *notused) | |
1354 | { | |
1355 | return "network "; | |
1356 | } | |
1357 | ||
1358 | sys_printdef syspdef_NETNETWORK = | |
1359 | { "NETNETWORK", sysprt_NETNETWORK }; | |
1360 | /*******************************************************************/ | |
1361 | char * | |
1362 | sysprt_NETIPI(void *p, void *q) | |
1363 | { | |
1364 | struct sstat *sstat=p; | |
1365 | extraparam *as=q; | |
1366 | static char buf[16]="ipi "; | |
1367 | count_t ipin = sstat->net.ipv4.InReceives + | |
1368 | sstat->net.ipv6.Ip6InReceives; | |
1369 | val2valstr(ipin, buf+4, 8, as->avgval, as->nsecs); | |
1370 | return buf; | |
1371 | } | |
1372 | ||
1373 | sys_printdef syspdef_NETIPI = | |
1374 | { "NETIPI", sysprt_NETIPI }; | |
1375 | /*******************************************************************/ | |
1376 | char * | |
1377 | sysprt_NETIPO(void *p, void *q) | |
1378 | { | |
1379 | struct sstat *sstat=p; | |
1380 | extraparam *as=q; | |
1381 | static char buf[16]="ipo "; | |
1382 | count_t ipout = sstat->net.ipv4.OutRequests + | |
1383 | sstat->net.ipv6.Ip6OutRequests; | |
1384 | val2valstr(ipout, buf+4, 8, as->avgval, as->nsecs); | |
1385 | return buf; | |
1386 | } | |
1387 | ||
1388 | sys_printdef syspdef_NETIPO = | |
1389 | { "NETIPO", sysprt_NETIPO }; | |
1390 | /*******************************************************************/ | |
1391 | char * | |
1392 | sysprt_NETIPFRW(void *p, void *q) | |
1393 | { | |
1394 | struct sstat *sstat=p; | |
1395 | extraparam *as=q; | |
1396 | static char buf[16]="ipfrw "; | |
1397 | count_t ipfrw = sstat->net.ipv4.ForwDatagrams + | |
1398 | sstat->net.ipv6.Ip6OutForwDatagrams; | |
1399 | val2valstr(ipfrw, buf+6, 6, as->avgval, as->nsecs); | |
1400 | return buf; | |
1401 | } | |
1402 | ||
1403 | sys_printdef syspdef_NETIPFRW = | |
1404 | { "NETIPFRW", sysprt_NETIPFRW }; | |
1405 | /*******************************************************************/ | |
1406 | char * | |
1407 | sysprt_NETIPDELIV(void *p, void *q) | |
1408 | { | |
1409 | struct sstat *sstat=p; | |
1410 | extraparam *as=q; | |
1411 | static char buf[16]="deliv "; | |
1412 | count_t ipindel = sstat->net.ipv4.InDelivers + | |
1413 | sstat->net.ipv6.Ip6InDelivers; | |
1414 | val2valstr(ipindel, buf+6, 6, as->avgval, as->nsecs); | |
1415 | return buf; | |
1416 | } | |
1417 | ||
1418 | sys_printdef syspdef_NETIPDELIV = | |
1419 | { "NETIPDELIV", sysprt_NETIPDELIV }; | |
1420 | /*******************************************************************/ | |
1421 | char * | |
1422 | sysprt_NETICMPIN(void *p, void *q) | |
1423 | { | |
1424 | struct sstat *sstat=p; | |
1425 | extraparam *as=q; | |
1426 | static char buf[16]="icmpi "; | |
1427 | count_t icmpin = sstat->net.icmpv4.InMsgs+ | |
1428 | sstat->net.icmpv6.Icmp6InMsgs; | |
1429 | val2valstr(icmpin , buf+6, 6, as->avgval, as->nsecs); | |
1430 | return buf; | |
1431 | } | |
1432 | ||
1433 | sys_printdef syspdef_NETICMPIN = | |
1434 | { "NETICMPIN", sysprt_NETICMPIN }; | |
1435 | /*******************************************************************/ | |
1436 | char * | |
1437 | sysprt_NETICMPOUT(void *p, void *q) | |
1438 | { | |
1439 | struct sstat *sstat=p; | |
1440 | extraparam *as=q; | |
1441 | static char buf[16]="icmpo "; | |
1442 | count_t icmpin = sstat->net.icmpv4.OutMsgs+ | |
1443 | sstat->net.icmpv6.Icmp6OutMsgs; | |
1444 | val2valstr(icmpin , buf+6, 6, as->avgval, as->nsecs); | |
1445 | return buf; | |
1446 | } | |
1447 | ||
1448 | sys_printdef syspdef_NETICMPOUT = | |
1449 | { "NETICMPOUT", sysprt_NETICMPOUT }; | |
1450 | /*******************************************************************/ | |
1451 | char * | |
1452 | sysprt_NETNAME(void *p, void *q) | |
1453 | { | |
1454 | struct sstat *sstat=p; | |
1455 | extraparam *as=q; | |
1456 | count_t busy; | |
1457 | count_t ival = sstat->intf.intf[as->index].rbyte/125/as->nsecs; | |
1458 | count_t oval = sstat->intf.intf[as->index].sbyte/125/as->nsecs; | |
1459 | ||
1460 | static char buf[16]="ethxxxx ----"; | |
1461 | // 012345678901 | |
1462 | ||
1463 | if (sstat->intf.intf[as->index].speed) /* speed known? */ | |
1464 | { | |
1465 | if (sstat->intf.intf[as->index].duplex) | |
1466 | busy = (ival > oval ? ival : oval) / | |
1467 | (sstat->intf.intf[as->index].speed *10); | |
1468 | else | |
1469 | busy = (ival + oval) / | |
1470 | (sstat->intf.intf[as->index].speed *10); | |
1471 | snprintf(buf, sizeof(buf)-1, "%-7.7s %3lld%%", | |
1472 | sstat->intf.intf[as->index].name, busy); | |
1473 | ||
1474 | } | |
1475 | else | |
1476 | { | |
1477 | snprintf(buf, sizeof(buf)-1, "%-7.7s ----", | |
1478 | sstat->intf.intf[as->index].name); | |
1479 | strcpy(buf+8, "----"); | |
1480 | } | |
1481 | return buf; | |
1482 | } | |
1483 | ||
1484 | sys_printdef syspdef_NETNAME = | |
1485 | { "NETNAME", sysprt_NETNAME }; | |
1486 | /*******************************************************************/ | |
1487 | char * | |
1488 | sysprt_NETPCKI(void *p, void *q) | |
1489 | { | |
1490 | struct sstat *sstat=p; | |
1491 | extraparam *as=q; | |
1492 | static char buf[16]="pcki "; | |
1493 | val2valstr(sstat->intf.intf[as->index].rpack, | |
1494 | buf+5, 7, as->avgval, as->nsecs); | |
1495 | return buf; | |
1496 | } | |
1497 | ||
1498 | sys_printdef syspdef_NETPCKI = | |
1499 | { "NETPCKI", sysprt_NETPCKI }; | |
1500 | /*******************************************************************/ | |
1501 | char * | |
1502 | sysprt_NETPCKO(void *p, void *q) | |
1503 | { | |
1504 | struct sstat *sstat=p; | |
1505 | extraparam *as=q; | |
1506 | static char buf[16]="pcko "; | |
1507 | val2valstr(sstat->intf.intf[as->index].spack, | |
1508 | buf+5, 7, as->avgval, as->nsecs); | |
1509 | return buf; | |
1510 | } | |
1511 | ||
1512 | sys_printdef syspdef_NETPCKO = | |
1513 | { "NETPCKO", sysprt_NETPCKO }; | |
1514 | /*******************************************************************/ | |
1515 | /* | |
1516 | ** convert byte-transfers to bit-transfers (* 8) | |
1517 | ** convert bit-transfers to kilobit-transfers (/ 1000) | |
1518 | ** per second | |
1519 | */ | |
1520 | char *makenetspeed(count_t val, int nsecs) | |
1521 | { | |
1522 | char c; | |
1523 | static char buf[16]="si ?bps"; | |
1524 | // 012345678901 | |
1525 | ||
1526 | val=val/125/nsecs; // convert to Kbps | |
1527 | ||
1528 | if (val < 10000) | |
1529 | { | |
1530 | c='K'; | |
1531 | } | |
1532 | else if (val < (count_t)10000 * 1000) | |
1533 | { | |
1534 | val/=1000; | |
1535 | c = 'M'; | |
1536 | } | |
1537 | else if (val < (count_t)10000 * 1000 * 1000) | |
1538 | { | |
1539 | val/=1000 * 1000; | |
1540 | c = 'G'; | |
1541 | } | |
1542 | else | |
1543 | { | |
1544 | val = val / 1000 / 1000 / 1000; | |
1545 | c = 'T'; | |
1546 | } | |
1547 | ||
1548 | sprintf(buf+3, "%4lld %cbps", val, c); | |
1549 | ||
1550 | return buf; | |
1551 | } | |
1552 | /*******************************************************************/ | |
1553 | ||
1554 | char * | |
1555 | sysprt_NETSPEEDIN(void *p, void *q) | |
1556 | { | |
1557 | struct sstat *sstat=p; | |
1558 | extraparam *as=q; | |
1559 | char *pr=makenetspeed(sstat->intf.intf[as->index].rbyte,as->nsecs); | |
1560 | pr[1]='i'; | |
1561 | return pr; | |
1562 | } | |
1563 | ||
1564 | sys_printdef syspdef_NETSPEEDIN = | |
1565 | { "NETSPEEDIN", sysprt_NETSPEEDIN }; | |
1566 | /*******************************************************************/ | |
1567 | char * | |
1568 | sysprt_NETSPEEDOUT(void *p, void *q) | |
1569 | { | |
1570 | struct sstat *sstat=p; | |
1571 | extraparam *as=q; | |
1572 | char *ps=makenetspeed(sstat->intf.intf[as->index].sbyte,as->nsecs); | |
1573 | ps[1]='o'; | |
1574 | return ps; | |
1575 | } | |
1576 | ||
1577 | sys_printdef syspdef_NETSPEEDOUT = | |
1578 | { "NETSPEEDOUT", sysprt_NETSPEEDOUT }; | |
1579 | /*******************************************************************/ | |
1580 | char * | |
1581 | sysprt_NETCOLLIS(void *p, void *q) | |
1582 | { | |
1583 | struct sstat *sstat=p; | |
1584 | extraparam *as=q; | |
1585 | static char buf[16]="coll "; | |
1586 | val2valstr(sstat->intf.intf[as->index].scollis, | |
1587 | buf+5, 7, as->avgval, as->nsecs); | |
1588 | return buf; | |
1589 | } | |
1590 | ||
1591 | sys_printdef syspdef_NETCOLLIS = | |
1592 | { "NETCOLLIS", sysprt_NETCOLLIS }; | |
1593 | /*******************************************************************/ | |
1594 | char * | |
1595 | sysprt_NETMULTICASTIN(void *p, void *q) | |
1596 | { | |
1597 | struct sstat *sstat=p; | |
1598 | extraparam *as=q; | |
1599 | static char buf[16]="mlti "; | |
1600 | val2valstr(sstat->intf.intf[as->index].rmultic, | |
1601 | buf+5, 7, as->avgval, as->nsecs); | |
1602 | return buf; | |
1603 | } | |
1604 | ||
1605 | sys_printdef syspdef_NETMULTICASTIN = | |
1606 | { "NETMULTICASTIN", sysprt_NETMULTICASTIN }; | |
1607 | /*******************************************************************/ | |
1608 | char * | |
1609 | sysprt_NETRCVERR(void *p, void *q) | |
1610 | { | |
1611 | struct sstat *sstat=p; | |
1612 | extraparam *as=q; | |
1613 | static char buf[16]="erri "; | |
1614 | val2valstr(sstat->intf.intf[as->index].rerrs, | |
1615 | buf+5, 7, as->avgval, as->nsecs); | |
1616 | return buf; | |
1617 | } | |
1618 | ||
1619 | sys_printdef syspdef_NETRCVERR = | |
1620 | { "NETRCVERR", sysprt_NETRCVERR }; | |
1621 | /*******************************************************************/ | |
1622 | char * | |
1623 | sysprt_NETSNDERR(void *p, void *q) | |
1624 | { | |
1625 | struct sstat *sstat=p; | |
1626 | extraparam *as=q; | |
1627 | static char buf[16]="erro "; | |
1628 | val2valstr(sstat->intf.intf[as->index].serrs, | |
1629 | buf+5, 7, as->avgval, as->nsecs); | |
1630 | return buf; | |
1631 | } | |
1632 | ||
1633 | sys_printdef syspdef_NETSNDERR = | |
1634 | { "NETSNDERR", sysprt_NETSNDERR }; | |
1635 | /*******************************************************************/ | |
1636 | char * | |
1637 | sysprt_NETRCVDROP(void *p, void *q) | |
1638 | { | |
1639 | struct sstat *sstat=p; | |
1640 | extraparam *as=q; | |
1641 | static char buf[16]="drpi "; | |
1642 | val2valstr(sstat->intf.intf[as->index].rdrop, | |
1643 | buf+5, 7, as->avgval, as->nsecs); | |
1644 | return buf; | |
1645 | } | |
1646 | ||
1647 | sys_printdef syspdef_NETRCVDROP = | |
1648 | { "NETRCVDROP", sysprt_NETRCVDROP }; | |
1649 | /*******************************************************************/ | |
1650 | char * | |
1651 | sysprt_NETSNDDROP(void *p, void *q) | |
1652 | { | |
1653 | struct sstat *sstat=p; | |
1654 | extraparam *as=q; | |
1655 | static char buf[16]="drpo "; | |
1656 | val2valstr(sstat->intf.intf[as->index].sdrop, | |
1657 | buf+5, 7, as->avgval, as->nsecs); | |
1658 | return buf; | |
1659 | } | |
1660 | ||
1661 | sys_printdef syspdef_NETSNDDROP = | |
1662 | { "NETSNDDROP", sysprt_NETSNDDROP }; | |
1663 | /*******************************************************************/ | |
1664 | char * | |
1665 | sysprt_BLANKBOX(void *p, void *notused) | |
1666 | { | |
1667 | return " "; | |
1668 | } | |
1669 | ||
1670 | sys_printdef syspdef_BLANKBOX = | |
1671 | { "BLANKBOX", sysprt_BLANKBOX }; |
6 | 6 | ** This source-file contains various functions to a.o. format the |
7 | 7 | ** time-of-day, the cpu-time consumption and the memory-occupation. |
8 | 8 | ** ========================================================================== |
9 | ** Author: Gerlof Langeveld - AT Computing, Nijmegen, Holland | |
10 | ** E-mail: gerlof@ATComputing.nl | |
9 | ** Author: Gerlof Langeveld | |
10 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | 11 | ** Date: November 1996 |
12 | 12 | ** LINUX-port: June 2000 |
13 | 13 | ** -------------------------------------------------------------------------- |
14 | ** Copyright (C) 2000-2005 Gerlof Langeveld | |
14 | ** Copyright (C) 2000-2010 Gerlof Langeveld | |
15 | 15 | ** |
16 | 16 | ** This program is free software; you can redistribute it and/or modify it |
17 | 17 | ** under the terms of the GNU General Public License as published by the |
29 | 29 | ** -------------------------------------------------------------------------- |
30 | 30 | ** |
31 | 31 | ** $Log: various.c,v $ |
32 | ** Revision 1.21 2010/11/12 06:16:16 gerlof | |
33 | ** Show all parts of timestamp in header line, even when zero. | |
34 | ** | |
35 | ** Revision 1.20 2010/05/18 19:21:08 gerlof | |
36 | ** Introduce CPU frequency and scaling (JC van Winkel). | |
37 | ** | |
38 | ** Revision 1.19 2010/04/28 18:21:11 gerlof | |
39 | ** Cast value larger than 4GB to long long. | |
40 | ** | |
41 | ** Revision 1.18 2010/04/23 12:19:35 gerlof | |
42 | ** Modified mail-address in header. | |
43 | ** | |
44 | ** Revision 1.17 2010/03/26 11:52:45 gerlof | |
45 | ** Introduced unit of Tbytes for memory-usage. | |
46 | ** | |
47 | ** Revision 1.16 2009/12/17 08:28:38 gerlof | |
48 | ** Express CPU-time usage in days and hours for large values. | |
49 | ** | |
50 | ** Revision 1.15 2009/12/10 08:50:39 gerlof | |
51 | ** Introduction of a new function to convert number of seconds | |
52 | ** to a string indicating days, hours, minutes and seconds. | |
53 | ** | |
32 | 54 | ** Revision 1.14 2007/02/13 10:32:47 gerlof |
33 | 55 | ** Removal of external declarations. |
34 | 56 | ** Removal of function getpagesz(). |
75 | 97 | ** |
76 | 98 | */ |
77 | 99 | |
78 | static const char rcsid[] = "$Id: various.c,v 1.14 2007/02/13 10:32:47 gerlof Exp $"; | |
100 | static const char rcsid[] = "$Id: various.c,v 1.21 2010/11/12 06:16:16 gerlof Exp $"; | |
79 | 101 | |
80 | 102 | #include <sys/types.h> |
81 | 103 | #include <sys/param.h> |
240 | 262 | return strvalue; |
241 | 263 | } |
242 | 264 | |
265 | #define DAYSECS (24*60*60) | |
266 | #define HOURSECS (60*60) | |
267 | #define MINSECS (60) | |
268 | ||
269 | /* | |
270 | ** Function val2elapstr() converts a value (number of seconds) | |
271 | ** to an ascii-string of up to max 13 positions in NNNdNNhNNmNNs | |
272 | ** stored in strvalue (at least 14 positions). | |
273 | ** returnvalue: number of bytes stored | |
274 | */ | |
275 | int | |
276 | val2elapstr(int value, char *strvalue) | |
277 | { | |
278 | char *p=strvalue, doshow=0; | |
279 | ||
280 | if (value > DAYSECS) | |
281 | { | |
282 | p+=sprintf(p, "%dd", value/DAYSECS); | |
283 | value %= DAYSECS; | |
284 | doshow = 1; | |
285 | } | |
286 | ||
287 | if (value > HOURSECS || doshow) | |
288 | { | |
289 | p+=sprintf(p, "%dh", value/HOURSECS); | |
290 | value %= HOURSECS; | |
291 | doshow = 1; | |
292 | } | |
293 | ||
294 | if (value > MINSECS || doshow) | |
295 | { | |
296 | p+=sprintf(p, "%dm", value/MINSECS); | |
297 | value %= MINSECS; | |
298 | doshow = 1; | |
299 | } | |
300 | ||
301 | if (value || doshow) | |
302 | { | |
303 | p+=sprintf(p, "%ds", value); | |
304 | doshow = 1; | |
305 | } | |
306 | ||
307 | return p-strvalue; | |
308 | } | |
309 | ||
310 | ||
243 | 311 | /* |
244 | 312 | ** Function val2cpustr() converts a value (number of milliseconds) |
245 | 313 | ** to an ascii-string of 7 positions in milliseconds or minute-seconds or |
247 | 315 | */ |
248 | 316 | #define MAXMSEC (count_t)100000 |
249 | 317 | #define MAXSEC (count_t)60000 |
318 | #define MAXMIN (count_t)60000 | |
250 | 319 | |
251 | 320 | char * |
252 | 321 | val2cpustr(count_t value, char *strvalue) |
257 | 326 | } |
258 | 327 | else |
259 | 328 | { |
260 | /* | |
261 | ** millisecs irrelevant; round to seconds | |
262 | */ | |
263 | value = (value + 500) / 1000; | |
264 | ||
265 | if (value < MAXSEC) | |
266 | { | |
267 | sprintf(strvalue, "%3lldm%02llds", value/60, value%60); | |
329 | /* | |
330 | ** millisecs irrelevant; round to seconds | |
331 | */ | |
332 | value = (value + 500) / 1000; | |
333 | ||
334 | if (value < MAXSEC) | |
335 | { | |
336 | sprintf(strvalue, "%3lldm%02llds", value/60, value%60); | |
268 | 337 | } |
269 | 338 | else |
270 | 339 | { |
273 | 342 | */ |
274 | 343 | value = (value + 30) / 60; |
275 | 344 | |
276 | sprintf(strvalue, "%3lldh%02lldm", value/60, value%60); | |
345 | if (value < MAXMIN) | |
346 | { | |
347 | sprintf(strvalue, "%3lldh%02lldm", | |
348 | value/60, value%60); | |
349 | } | |
350 | else | |
351 | { | |
352 | /* | |
353 | ** minutes irrelevant; round to hours | |
354 | */ | |
355 | value = (value + 30) / 60; | |
356 | ||
357 | sprintf(strvalue, "%3lldd%02lldh", | |
358 | value/24, value%24); | |
359 | } | |
277 | 360 | } |
278 | 361 | } |
279 | 362 | |
363 | return strvalue; | |
364 | } | |
365 | ||
366 | /* | |
367 | ** Function val2Hzstr() converts a value (in MHz) | |
368 | ** to an ascii-string. | |
369 | ** The result-string is placed in the area pointed to strvalue, | |
370 | ** which should be able to contain at least 8 positions. | |
371 | */ | |
372 | char * | |
373 | val2Hzstr(count_t value, char *strvalue) | |
374 | { | |
375 | if (value < 1000) | |
376 | { | |
377 | sprintf(strvalue, "%4lldMHz", value); | |
378 | } | |
379 | else | |
380 | { | |
381 | double fval=value/1000.0; // fval is double in GHz | |
382 | char prefix='G'; | |
383 | ||
384 | if (fval >= 1000.0) // prepare for the future | |
385 | { | |
386 | prefix='T'; | |
387 | fval /= 1000.0; | |
388 | } | |
389 | sprintf(strvalue, "%4.2f%cHz", fval, prefix); | |
390 | } | |
280 | 391 | return strvalue; |
281 | 392 | } |
282 | 393 | |
290 | 401 | #define ONEKBYTE 1024 |
291 | 402 | #define ONEMBYTE 1048576 |
292 | 403 | #define ONEGBYTE 1073741824L |
404 | #define ONETBYTE 1099511627776LL | |
293 | 405 | |
294 | 406 | #define MAXBYTE 1024 |
295 | 407 | #define MAXKBYTE ONEKBYTE*99999L |
296 | 408 | #define MAXMBYTE ONEMBYTE*999L |
409 | #define MAXGBYTE ONEGBYTE*999LL | |
297 | 410 | |
298 | 411 | char * |
299 | 412 | val2memstr(count_t value, char *strvalue, int pformat, int avgval, int nsecs) |
337 | 450 | if (verifyval <= MAXMBYTE) /* mbytes ? */ |
338 | 451 | aformat = MBFORMAT; |
339 | 452 | else |
340 | aformat = GBFORMAT; | |
453 | if (verifyval <= MAXGBYTE) /* mbytes ? */ | |
454 | aformat = GBFORMAT; | |
455 | else | |
456 | aformat = TBFORMAT; | |
341 | 457 | |
342 | 458 | /* |
343 | 459 | ** check if this is also the preferred format |
365 | 481 | case GBFORMAT: |
366 | 482 | sprintf(strvalue, "%*.1lfG%s", |
367 | 483 | basewidth-1, (double)((double)value/ONEGBYTE), suffix); |
484 | break; | |
485 | ||
486 | case TBFORMAT: | |
487 | sprintf(strvalue, "%*.1lfT%s", | |
488 | basewidth-1, (double)((double)value/ONETBYTE), suffix); | |
368 | 489 | break; |
369 | 490 | |
370 | 491 | default: |
1 | 1 | #include <stdio.h> |
2 | 2 | #include <string.h> |
3 | 3 | |
4 | static const char rcsid[] = "$Id: version.c,v 1.23 2008/03/06 09:11:09 root Exp root $"; | |
4 | static const char rcsid[] = "$Id: version.c,v 1.26 2010/11/17 13:42:37 root Exp root $"; | |
5 | 5 | |
6 | static char atoprevision[] = "$Revision: 1.23 $"; | |
7 | static char atopdate[] = "$Date: 2008/03/06 09:11:09 $"; | |
6 | static char atoprevision[] = "$Revision: 1.26 $"; | |
7 | static char atopdate[] = "$Date: 2010/11/17 13:42:37 $"; | |
8 | 8 | |
9 | 9 | char * |
10 | 10 | getstrvers(void) |
15 | 15 | atopdate [sizeof atopdate - 3] = '\0'; |
16 | 16 | |
17 | 17 | snprintf(vers, sizeof vers, |
18 | "Version:%s -%s < gerlof@ATComputing.nl >", | |
18 | "Version:%s -%s < gerlof.langeveld@atoptool.nl >", | |
19 | 19 | strchr(atoprevision, ' '), |
20 | 20 | strchr(atopdate , ' ')); |
21 | 21 |