Codebase list atop / upstream/1.26
Imported Upstream version 1.26 Marc Haber 11 years ago
34 changed file(s) with 9111 addition(s) and 3118 deletion(s). Raw diff Collapse all Expand all
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 Gerlof Langeveld <gerlof@ATComputing.nl>
0 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
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>
1327
2328 * photoproc.c, parseable.c, acctproc.c, showlinux.c:
3329 Register/show PPID related to a process.
6332 logfiles that were created by older versions of atop
7333 is not reliable.
8334
9 2008-02-25 Gerlof Langeveld <gerlof@ATComputing.nl>
335 2008-02-25 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
10336
11337 * atopsar.c, deviate.c:
12338 Added experimental code for HTTP-statistics.
13339
14 2008-02-11 Gerlof Langeveld <gerlof@ATComputing.nl>
340 2008-02-11 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
15341
16342 * showgeneric.c:
17343 Bug-solution for segmentation-fault in case of
18344 invalid regular expression.
19345
20 2008-01-21 Gerlof Langeveld <gerlof@ATComputing.nl>
346 2008-01-21 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
21347
22348 * atopsar.c:
23349 Add new reports to show top-3 processes consuming
24350 most cpu, memory, disk and network resources.
25351
26 2008-01-21 Gerlof Langeveld <gerlof@ATComputing.nl>
352 2008-01-21 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
27353
28354 * atopsar.c:
29355 Add number of thread per state to output generated
30356 by -P flag.
31357
32 2008-01-18 Gerlof Langeveld <gerlof@ATComputing.nl>
358 2008-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
33359
34360 * showlinux.c, photoproc.c, parseable.c:
35361 Gather and show information about the number of
38364 This information is shown in the scheduling
39365 report (keystroke 's')
40366
41 2008-01-14 Gerlof Langeveld <gerlof@ATComputing.nl>
367 2008-01-14 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
42368
43369 * acctproc.c:
44370 Specify the name of a specific process accounting file with
45371 the environment variable ATOPACCT (or disable process
46372 accounting when this variable has an empty contents).
47373
48 2008-01-07 Gerlof Langeveld <gerlof@ATComputing.nl>
374 2008-01-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
49375
50376 * atopsar.c:
51377 Rename forks/s into clones/s in report with flag -p.
52378
53 2008-01-07 Gerlof Langeveld <gerlof@ATComputing.nl>
379 2008-01-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
54380
55381 * atopsar.c:
56382 Show 100% per CPU instead of 100% for all CPUs in the
57383 report shown with the -c flag of atopsar (similar to
58384 the atop output).
59385
60 2008-01-07 Gerlof Langeveld <gerlof@ATComputing.nl>
386 2008-01-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
61387
62388 * showlinux.c:
63389 The network-interfaces should be sorted on their
64390 busy-percentage and not on the number of transferred
65391 packages.
66392
67 2008-01-07 Gerlof Langeveld <gerlof@ATComputing.nl>
393 2008-01-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
68394
69395 * atopsar.c, deviate.c, atop.c:
70396 Make summary-reports by packing N samples together in one
71397 sample. The value N can be specified with the new flag -R.
72398
73 2007-11-29 Gerlof Langeveld <gerlof@ATComputing.nl>
399 2007-11-29 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
74400
75401 * atopsar.c:
76402 Repeat the header of a report every X lines (flag -H).
77403 In case of output to a window, value X is determined
78404 dynamically, depending on the window size.
79405
80 2007-11-29 Gerlof Langeveld <gerlof@ATComputing.nl>
406 2007-11-29 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
81407
82408 * atopsar.c:
83409 Added new report with flag -P for process-activity (number
84410 of processes currently present and number of zombies,
85411 number of thread creations and process exits).
86412
87 2007-11-07 Gerlof Langeveld <gerlof@ATComputing.nl>
413 2007-11-07 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
88414
89415 * showlinux.c:
90416 Modified format for avg1, avg5 and avg15 (CPL)
91417 when counters become too large.
92418
93 2007-11-06 Gerlof Langeveld <gerlof@ATComputing.nl>
419 2007-11-06 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
94420
95421 * atopsar.c:
96422 Modify duplex indicator "fdx" to "f" and "hdx" to "h"
97423 in the report about interfaces (line too long if
98424 markers are added).
99425
100 2007-11-06 Gerlof Langeveld <gerlof@ATComputing.nl>
426 2007-11-06 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
101427
102428 * atopsar.c, atop.c:
103429 Add keyword atopsarflags to configuration-file ~/.atoprc
104430 to specify personal defaults.
105431
106 2007-11-06 Gerlof Langeveld <gerlof@ATComputing.nl>
432 2007-11-06 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
107433
108434 * atopsar.c:
109435 Add support for colors/markers in case of (almost)
110436 critical resource consumption (similar to atop).
111437 This concerns the -x/-C/-M flags.
112438
113 2007-11-05 Gerlof Langeveld <gerlof@ATComputing.nl>
439 2007-11-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
114440
115441 * photoproc.c:
116442 Detect disappearing /proc/<pid>/stat file when
117443 concerning process exits meanwhile (credits: Rene Rebe).
118444
119 2007-11-05 Gerlof Langeveld <gerlof@ATComputing.nl>
445 2007-11-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
120446
121447 * procdbase.c, deviate.c:
122448 Match processes not only on pid, but also on start time
123449 to avoid wrong matches when a proces has exited and
124450 a new proces reuses its pid within the same sample.
125451
126 2007-11-05 Gerlof Langeveld <gerlof@ATComputing.nl>
452 2007-11-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
127453
128454 * showlinux.c, deviate.c:
129455 Bug-solution for new-process indicator on 64-bits machines.
130456
131 2007-11-05 Gerlof Langeveld <gerlof@ATComputing.nl>
457 2007-11-05 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
132458
133459 * showlinux.c:
134460 Bug-solution for huge exit codes for 64-bits machines.
135461
136 2007-10-04 Gerlof Langeveld <gerlof@ATComputing.nl>
462 2007-10-04 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
137463
138464 * atopsar.c:
139465 Use line-buffering on stdout, even for pipes and files.
140466
141 2007-08-17 Gerlof Langeveld <gerlof@ATComputing.nl>
467 2007-08-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
142468
143469 * atopsar.c:
144470 Cosmetic changes to counter names.
145471
146 2007-08-17 Gerlof Langeveld <gerlof@ATComputing.nl>
472 2007-08-17 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
147473
148474 * acctproc.c:
149475 Verify if private accounting used before switching
150476 off accounting.
151477
152 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl>
478 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
153479
154480 * atop.c:
155481 Add support for atopsar reporting (mainly
156482 calling of atopsar).
157483
158 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl>
484 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
159485
160486 * atopsar.c:
161487 New source file to implement the atopsar command
162488 as a (symbolic) link to the atop command. Most of
163489 the source code has been copied from the atsar command.
164490
165 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl>
491 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
166492
167493 * deviate.c:
168494 Add support for atopsar reporting (lot of
169495 counters added).
170496
171 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl>
497 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
172498
173499 * parseable.c:
174500 Add support for atopsar reporting (handling of
175501 certain network counters modified).
176502
177 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl>
503 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
178504
179505 * photosyst.c:
180506 Add support for atopsar reporting (gather more counters,
181507 mainly related to networking).
182508
183 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl>
509 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
184510
185511 * rawlog.c:
186512 Add support for atopsar reporting (gather more counters,
187513 mainly related to networking).
188514
189 2007-08-16 Gerlof Langeveld <gerlof@ATComputing.nl>
515 2007-08-16 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
190516
191517 * showlinux.c:
192518 Add support for atopsar reporting (handling of
193519 certain network counters modified).
194520
195 2007-07-04 Gerlof Langeveld <gerlof@ATComputing.nl>
521 2007-07-04 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
196522
197523 * showlinux.c:
198524 Bug-solution: divide by zero problem.
199525
200 2007-03-27 Gerlof Langeveld <gerlof@ATComputing.nl>
526 2007-03-27 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
201527
202528 * photoproc.c:
203529 Only allow check for IOSTAT when patches are not installed.
204530
205 2007-03-24 Gerlof Langeveld <gerlof@ATComputing.nl>
531 2007-03-24 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
206532
207533 * atop.spec, atop.daily, accs_atop, accu_atop:
208534 Remove time-hole from 23.50 till 00.00 for daily logging.
209535
210 2007-03-22 Gerlof Langeveld <gerlof@ATComputing.nl>
536 2007-03-22 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
211537
212538 * atop.spec, atop.daily, accs_atop, accu_atop:
213539 Improve automatic startup independent of the fact
214540 that the RPM `psacct' is installed.
215541 The script `atop.24hours' has been removed.
216542
217 2007-03-22 Gerlof Langeveld <gerlof@ATComputing.nl>
543 2007-03-22 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
218544
219545 * photoproc.c, deviate.c, showlinux.c, showgeneric.c:
220546 Introduce counters from /proc/pid/io for disk activity.
221547
222 2007-03-20 Gerlof Langeveld <gerlof@ATComputing.nl>
548 2007-03-20 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
223549
224550 * rawlog.c:
225551 Avoid loop when incompatible raw file is read.
226552 Verify return code of compress/uncompress functions.
227553 Verify success of malloc's.
228554
229 2007-03-09 Gerlof Langeveld <gerlof@ATComputing.nl>
555 2007-03-09 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
230556
231557 * showgeneric.c:
232558 Bug-solution: only allow key 'N' when kernel patch
233559 is installed, and key 'D' when kernel patch is installed
234560 or /proc/pid/io is available.
235561
236 2007-02-23 Gerlof Langeveld <gerlof@ATComputing.nl>
562 2007-02-23 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
237563
238564 * rawlog.c:
239565 Bug-solution: allow more than 65535 processes to be logged
240566 per interval.
241567
242 2007-02-13 Gerlof Langeveld <gerlof@ATComputing.nl>
568 2007-02-13 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
243569
244570 * acctproc.c:
245571 New boolean introduced to indicate if accounting is active.
246572
247 2007-01-26 Gerlof Langeveld <gerlof@ATComputing.nl>
573 2007-01-26 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
248574
249575 * atop.c, showlinux.c:
250576 Add configuration-value 'swoutcritsec'.
251577
252 2007-01-26 Gerlof Langeveld <gerlof@ATComputing.nl>
578 2007-01-26 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
253579
254580 * showlinux.c:
255581 Support steal-percentage.
256582 Avoid that interfaces are colored without reason.
257583
258 2007-01-22 Gerlof Langeveld <gerlof@ATComputing.nl>
584 2007-01-22 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
259585
260586 * photosyst.c:
261587 Support of special disks used by virtual machines.
262588
263 2007-01-22 Gerlof Langeveld <gerlof@ATComputing.nl>
589 2007-01-22 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
264590
265591 * photosyst.c, deviate.c:
266592 Support steal-time from /proc/stat.
267593
268 2007-01-19 Gerlof Langeveld <gerlof@ATComputing.nl>
594 2007-01-19 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
269595
270596 * ifprop.c:
271597 Added typedef u64 for SuSE distributions.
272598
273 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl>
599 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
274600
275601 * deviate.c:
276602 Support for network-interface busy-percentage.
277603
278 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl>
604 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
279605
280606 * showgeneric.c:
281607 Add support for colors and automatic determination of most
282608 critical resource.
283609
284 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl>
610 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
285611
286612 * showlinux.c:
287613 Add support for colors, automatic determination of most
288614 critical resource and parsing of new arguments in ~/.atoprc
289615
290 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl>
616 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
291617
292618 * ifprop.c:
293619 New functions to fetch the properties of a network
294620 interface (mainly speed and half/full duplex).
295621
296 2007-01-18 Gerlof Langeveld <gerlof@ATComputing.nl>
622 2007-01-18 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
297623
298624 * atop.c:
299625 Improved syntax-checking for ~/.atoprc file.
300626 Support for network-interface busy-percentage.
301627
302 2007-01-15 Gerlof Langeveld <gerlof@ATComputing.nl>
628 2007-01-15 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
303629
304630 * photoproc.c:
305631 Add new function to count actual number of processes.
306632
307 2006-11-13 Gerlof Langeveld <gerlof@ATComputing.nl>
633 2006-11-13 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
308634
309635 * showlinux.c:
310636 Modify network-speed counters (divide by 1000 i.s.o. 1024
311637 and postpone switch from Mbps to Gbps as suggested
312638 by T. Lindgren).
313639
314 2006-07-24 Gerlof Langeveld <gerlof@ATComputing.nl>
640 2006-07-24 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
315641
316642 * photosyst.h, photosyst.c, deviate.c, showlinux.c:
317643 Add a new system-level line ('CPL') showing CPU load
318644 information like load average (last 1, 5, 15 minutes)
319645 number of context switches and number of interrupts.
320646
321 2006-05-15 Gerlof Langeveld <gerlof@ATComputing.nl>
647 2006-05-15 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
322648
323649 * showgeneric.c:
324650 Allow a numerical UID to be specified with the
325651 function 'U'.
326652
327 2006-05-15 Gerlof Langeveld <gerlof@ATComputing.nl>
653 2006-05-15 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
328654
329655 * showlinux.c:
330656 When there is no user/group name which corresponds to a
331657 numerical UID/GID, show the numerical value i.s.o. "unknown".
332658
333 2006-04-19 Gerlof Langeveld <gerlof@ATComputing.nl>
659 2006-04-19 Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
334660
335661 * setup of ChangeLog
00 # Makefile for System & Process Monitor ATOP (Linux version)
11 #
2 # Gerlof Langeveld - AT Computing - Nijmegen, The Netherlands
3 # (gerlof@ATComputing.nl)
2 # Gerlof Langeveld - gerlof.langeveld@atoptool.nl
43 #
5 DESTDIR =
4 DESTDIR =
65
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
1416
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/ .*//')
2327
2428 all: atop
2529
2630 atop: atop.o $(ALLMODS) Makefile
27 cc atop.o $(ALLMODS) -o atop $(LDFLAGS)
31 $(CC) atop.o $(ALLMODS) -o atop $(LDFLAGS)
2832
2933 clean:
3034 rm -f *.o
3135
3236 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
5577 if [ -z "$(DESTDIR)" ]; then /sbin/chkconfig --add atop; fi
56
57 distr:
58 rm -f *.o
78 distr: rm -f *.o
5979 tar czvf /tmp/atop.tar.gz *
6080 ##########################################################################
6181
6282 atop.o: atop.h photoproc.h photosyst.h acctproc.h showgeneric.h
6383 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
6585 various.o: atop.h acctproc.h
6686 ifprop.o: atop.h photosyst.h ifprop.h
6787 parseable.o: atop.h photoproc.h photosyst.h parseable.h
7090 acctproc.o: atop.h photoproc.h acctproc.h
7191 photoproc.o: atop.h photoproc.h
7292 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
66 description in the manual-page.
77
88 Gerlof Langeveld
9 AT Computing
10 Nijmegen, The Netherlands
11 gerlof@ATComputing.nl
9 gerlof@atoptool.nl
66 ** This source-file contains functions to manipulate with process-accounting
77 ** features (switch it on/off and read the process-accounting records).
88 ** ================================================================
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
1111 ** Date: November 1996
1212 ** LINUX-port: June 2000
1313 **
2222 ** See the GNU General Public License for more details.
2323 **
2424 ** $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 **
2531 ** Revision 1.26 2008/03/06 08:37:25 gerlof
2632 ** Register/show ppid of a process.
2733 **
106112 **
107113 */
108114
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 $";
110116
111117 #include <sys/types.h>
112118 #include <stdio.h>
630636 api->gen.ruid = acctrec.ac_uid16;
631637 api->gen.rgid = acctrec.ac_gid16;
632638 api->gen.btime = acctrec.ac_btime;
639 api->gen.elaps = acctrec.ac_etime;
633640 api->cpu.stime = acctexp(acctrec.ac_stime);
634641 api->cpu.utime = acctexp(acctrec.ac_utime);
635642 api->mem.minflt = acctexp(acctrec.ac_minflt);
654661 api->gen.ruid = acctrec_v3.ac_uid;
655662 api->gen.rgid = acctrec_v3.ac_gid;
656663 api->gen.btime = acctrec_v3.ac_btime;
664 api->gen.elaps = acctrec_v3.ac_etime;
657665 api->cpu.stime = acctexp(acctrec_v3.ac_stime);
658666 api->cpu.utime = acctexp(acctrec_v3.ac_utime);
659667 api->mem.minflt = acctexp(acctrec_v3.ac_minflt);
678686 api->gen.ruid = acctrec_atop.ac_uid;
679687 api->gen.rgid = acctrec_atop.ac_gid;
680688 api->gen.btime = acctrec_atop.ac_btime;
689 api->gen.elaps = acctrec_atop.ac_etime;
681690 api->cpu.stime = acctexp (acctrec_atop.ac_stime);
682691 api->cpu.utime = acctexp (acctrec_atop.ac_utime);
683692 api->mem.minflt = acctexp (acctrec_atop.ac_minflt);
55 **
66 ** Include-file for process-accounting functions.
77 ** ================================================================
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
1010 ** Date: November 1996
1111 ** LINUX-port: June 2000
1212 **
atop less more
Binary diff not shown
+295
-135
atop.c less more
1010 ** process-level counters and the deviations are calculated and
1111 ** visualized for the user.
1212 ** ==========================================================================
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
1515 ** Date: November 1996
1616 ** Linux-port: June 2000
1717 ** Modified: May 2001 - Ported to kernel 2.4
1818 ** --------------------------------------------------------------------------
19 ** Copyright (C) 2000-2005 Gerlof Langeveld
19 ** Copyright (C) 2000-2010 Gerlof Langeveld
2020 **
2121 ** This program is free software; you can redistribute it and/or modify it
2222 ** under the terms of the GNU General Public License as published by the
114114 ** at runtime.
115115 **
116116 ** $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 **
117172 ** Revision 1.32 2008/01/07 10:16:13 gerlof
118173 ** Implement summaries for atopsar.
119174 **
215270 **
216271 */
217272
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 $";
219274
220275 #include <sys/types.h>
221276 #include <sys/param.h>
242297 #include "showgeneric.h"
243298 #include "parseable.h"
244299
245 #define allflags "ab:cde:fghijklmnopqrstuvwxyz1ABCDEFGHIJKLMNOP:QRSTUVWXYZ"
300 #define allflags "ab:cde:fghijklmnopqrstuvwxyz1ABCDEFGHIJKL:MNOP:QRSTUVWXYZ"
246301 #define PROCCHUNK 50 /* process-entries for future expansion */
247302 #define MAXFL 64 /* maximum number of command-line flags */
248303
250305 ** declaration of global variables
251306 */
252307 struct utsname utsname;
308 int utsnodenamelen;
253309 time_t pretime; /* timing info */
254310 time_t curtime; /* timing info */
255311 unsigned long interval = 10;
256312 unsigned long sampcnt;
257313 char screen;
314 int linelen = 80;
258315 char acctactive; /* accounting active (boolean) */
259316 char rawname[RAWNAMESZ];
260317 char rawreadflag;
318 unsigned int begintime, endtime;
261319 char flaglist[MAXFL];
262320 char deviatonly = 1;
263321 unsigned short hertz;
267325 int ossub;
268326
269327 int supportflags; /* supported features */
328 char **argvp;
329
270330
271331 struct visualize vis = {generic_samp, generic_error,
272332 generic_end, generic_usage};
277337 static char awaittrigger; /* boolean: awaiting trigger */
278338 static unsigned int nsamples = 0xffffffff;
279339 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 *);
300376
301377 static struct {
302378 char *tag;
303 void (*func)(char *);
379 void (*func)(char *, char *);
304380 } manrc[] = {
305381 { "flags", do_flags },
306382 { "interval", do_interval },
383 { "linelen", do_linelength },
307384 { "username", do_username },
308385 { "procname", do_procname },
309386 { "maxlinecpu", do_maxcpu },
310387 { "maxlinedisk", do_maxdisk },
388 { "maxlinemdd", do_maxmdd },
389 { "maxlinelvm", do_maxlvm },
311390 { "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 },
312404 { "cpucritperc", do_cpucritperc },
313405 { "memcritperc", do_memcritperc },
314406 { "swpcritperc", do_swpcritperc },
328420 main(int argc, char *argv[])
329421 {
330422 register int i;
331 int c, nr, line=0;
423 int c;
332424 char *p;
333425 struct rlimit rlim;
334426
335427 /*
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
339444 if ( (p = getenv("HOME")) )
340445 {
341446 char path[1024];
342447
343448 snprintf(path, sizeof path, "%s/.atoprc", p);
344449
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);
424451 }
425452
426453 /*
432459 else
433460 p = argv[0];
434461
435 if ( strcmp(p, "atopsar") == 0)
462 if ( memcmp(p, "atopsar", 7) == 0)
436463 return atopsar(argc, argv);
437
438464
439465 /*
440466 ** interpret command-line arguments & flags
457483 prusage(argv[0]);
458484 break;
459485
486 case 'V': /* version wanted ? */
487 printf("%s\n", getstrvers());
488 exit(0);
489
460490 case 'w': /* writing of raw data ? */
461491 if (optind >= argc)
462492 prusage(argv[0]);
496526 prusage(argv[0]);
497527
498528 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);
499536 break;
500537
501538 default: /* gather other flags */
535572 if ( (p = strchr(utsname.nodename, '.')) )
536573 *p = '\0';
537574
575 utsnodenamelen = strlen(utsname.nodename);
576
538577 sscanf(utsname.release, "%d.%d.%d", &osrel, &osvers, &ossub);
539578
540579 /*
548587 */
549588 if (rawreadflag)
550589 {
551 seteuid( getuid() );
552 rawread(begintime, endtime);
590 rawread();
553591 cleanstop(0);
554592 }
555593
557595 ** determine start-time for gathering current statistics
558596 */
559597 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);
560610
561611 /*
562612 ** lock ATOP in memory to get reliable samples (also when
577627 (void) nice(-20);
578628
579629 /*
580 ** catch signals for proper close-down
581 */
582 signal(SIGHUP, cleanstop);
583 signal(SIGTERM, cleanstop);
584
585 /*
586630 ** switch-on the process-accounting mechanism to register the
587631 ** (remaining) resource-usage by processes which have finished
588632 */
598642 ** need to keep running under root-priviliges, so switch
599643 ** effective user-id to real user-id
600644 */
601 seteuid ( getuid() );
645 seteuid( getuid() );
602646
603647 /*
604648 ** start the engine now .....
618662 {
619663 struct sigaction sigact;
620664 static time_t timelimit;
621 void getusr1(int);
665 void getusr1(int), getusr2(int);
622666
623667 /*
624668 ** reserve space for system-level statistics
637681 struct pstat *curpexit; /* exitted process list */
638682 struct pstat *devpstat; /* deviation list */
639683
640 int npresent, nexit, n, nzombie;
684 int npresent, nexit, n;
685 int ntrun, ntslpi, ntslpu, nzombie;
641686
642687 /*
643688 ** initialization: allocate required memory dynamically
656701 }
657702
658703 /*
659 ** install the signal-handler for ALARM and SIGUSR1 (both triggers
704 ** install the signal-handler for ALARM, USR1 and USR2 (triggers
660705 * for the next sample)
661706 */
662707 memset(&sigact, 0, sizeof sigact);
663708 sigact.sa_handler = getusr1;
664709 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);
665714
666715 memset(&sigact, 0, sizeof sigact);
667716 sigact.sa_handler = getalarm;
710759
711760 /*
712761 ** 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
714763 */
715764 if (sampcnt > 0 && awaittrigger)
716765 pause();
780829 devpstat = malloc((npresent+nexit) * sizeof(struct pstat));
781830
782831 n = deviatproc(curpact, npresent, curpexit, nexit,
783 deviatonly, devpstat, &nzombie);
832 deviatonly, devpstat, devsstat,
833 &ntrun, &ntslpi, &ntslpu, &nzombie);
784834
785835 /*
786836 ** activate the installed print-function to visualize
789839 lastcmd = (vis.show_samp)( curtime,
790840 curtime-pretime > 0 ? curtime-pretime : 1,
791841 devsstat, devpstat, n, npresent,
792 nzombie, nexit, sampcnt==0);
842 ntrun, ntslpi, ntslpu, nzombie,
843 nexit, sampcnt==0);
793844
794845 /*
795846 ** release dynamically allocated memory
834885 printf("\t -%c show or log all processes (i.s.o. active processes "
835886 "only)\n", MALLPROC);
836887 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");
837890
838891 (*vis.show_usage)();
839892
841894 printf("\tspecific flags for raw logfiles:\n");
842895 printf("\t -w write raw data to file (compressed)\n");
843896 printf("\t -r read raw data from file (compressed)\n");
897 printf("\t special file: y[y...] for yesterday (repeated)\n");
844898 printf("\t -S finish atop automatically before midnight "
845899 "(i.s.o. #samples)\n");
846900 printf("\t -b begin showing data from specified time\n");
854908 " (kill -USR1 pid_atop)\n");
855909 printf("or with the keystroke '%c' in interactive mode.\n", MSAMPNEXT);
856910
857
858911 cleanstop(1);
859912 }
860913
880933 }
881934
882935 /*
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 /*
883946 ** functions to handle a particular tag in the .atoprc file
884947 */
948 extern int get_posval(char *name, char *val);
949
885950 void
886 do_interval(char *val)
951 do_interval(char *name, char *val)
887952 {
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)
889975 {
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);
8961056 }
8971057 }
88 #
99 if [ -e $PIDFILE ] && ps -p `cat $PIDFILE` | grep 'atop$' > /dev/null
1010 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
1427 rm $PIDFILE
15 sleep 1
1628 fi
1729
1830 # start atop for all processes with interval of 10 minutes
55 **
66 ** Include-file describing miscellaneous constants and function-prototypes.
77 ** ================================================================
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
1010 ** Date: November 1996
1111 ** LINUX-port: June 2000
1212 **
3131 #define KBFORMAT 1
3232 #define MBFORMAT 2
3333 #define GBFORMAT 3
34 #define TBFORMAT 4
3435 #define OVFORMAT 9
3536
3637 typedef long long count_t;
4647
4748 struct visualize {
4849 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);
5051 void (*show_error) (const char *, ...);
5152 void (*show_end) (void);
5253 void (*show_usage) (void);
5657 ** external values
5758 */
5859 extern struct utsname utsname;
60 extern int utsnodenamelen;
5961 extern time_t pretime;
6062 extern time_t curtime;
6163 extern unsigned long interval;
6264 extern unsigned long sampcnt;
6365 extern char screen;
66 extern int linelen;
6467 extern char deviatonly;
6568 extern char rawname[];
6669 extern char rawreadflag;
70 extern unsigned int begintime, endtime;
6771 extern char flaglist[];
6872 extern struct visualize vis;
6973
9599 /*
96100 ** structure containing the start-addresses of functions for visualization
97101 */
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);
100104 void generic_error(const char *, ...);
101 void generic_end(void);
105 void generic_end (void);
102106 void generic_usage(void);
103107
104108 /*
113117 char *val2valstr(count_t, char *, int, int, int);
114118 char *val2memstr(count_t, char *, int, int, int);
115119 char *val2cpustr(count_t, char *);
120 char *val2Hzstr(count_t, char *);
121 int val2elapstr(int, char *);
116122
117123 int compcpu(const void *, const void *);
118124 int compdsk(const void *, const void *);
126132 int intfcompar(const void *, const void *);
127133
128134 count_t subcount(count_t, count_t);
129 void rawread(unsigned int, unsigned int);
135 void rawread(void);
130136 char rawwrite(time_t, int, struct sstat *, struct pstat *,
131 int, int, int, int, char);
137 int, int, int, int, int, int, int, char);
132138
133139 int numeric(char *);
134140 void getalarm(int);
3030 #
3131 if [ -e $PIDFILE ] && ps -p `cat $PIDFILE` | grep 'atop$' > /dev/null
3232 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
3649 rm $PIDFILE
37 sleep 1
3850 fi
3951 ;;
4052
66 ** This source-file contains the 'atopsar'-functionality, that makes use
77 ** of the 'atop'-framework.
88 ** ==========================================================================
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
1111 ** Date: July 2007
1212 ** --------------------------------------------------------------------------
13 ** Copyright (C) 2007, 2008 Gerlof Langeveld
13 ** Copyright (C) 2007-2010 Gerlof Langeveld
1414 **
1515 ** This program is free software; you can redistribute it and/or modify it
1616 ** under the terms of the GNU General Public License as published by the
2929 **
3030 */
3131
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 $";
3333
3434 #include <sys/types.h>
3535 #include <sys/param.h>
6969 ** miscellaneous values
7070 */
7171 static unsigned int nsamples = 9999999;
72 static unsigned int begintime, endtime;
7372 static char stampalways;
7473 static char usecolors = 't';
7574 static char usemarkers;
105104 static void engine(void);
106105 static void pratopsaruse(char *);
107106 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);
110109 static void reportheader(struct utsname *, time_t);
111110 static time_t daylimit(time_t);
112111
291290 */
292291 if (rawreadflag)
293292 {
294 seteuid( getuid() ); /* get rid of root privileges */
295
296293 /*
297294 ** select own reportraw-function to be called
298295 ** by the rawread function
305302 {
306303 prinow = i;
307304 daylim = 0;
308 rawread(begintime, endtime);
305 rawread();
309306 printf("\n");
310307 }
311308 }
336333 ** determine start-time for gathering current statistics
337334 */
338335 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);
339342
340343 /*
341344 ** lock in memory to get reliable samples (also when
519522 numsecs, numsecs*hertz, hertz,
520523 osvers, osrel, ossub,
521524 stampalways ? timebuf : " ",
522 0, 0, 0) )
525 0, 0, 0, 0, 0, 0) )
523526 {
524527 /*
525528 ** print line has failed;
588591 numsecs, numsecs*hertz, hertz,
589592 osvers, osrel, ossub,
590593 stampalways ? timebuf : " ",
591 0, 0, 0) ) )
594 0, 0, 0, 0, 0, 0) ) )
592595 {
593596 /*
594597 ** print line has failed;
629632 static char
630633 reportraw(time_t curtime, int numsecs,
631634 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)
634637 {
635638 static char firstcall = 1;
636639 char timebuf[16], datebuf[16];
637640 unsigned int rv;
638641 static unsigned int curline, headline, sampsum,
639 totalsec, totalexit,
640 lastnpres, lastnzomb;
642 totalsec, totalexit, lastnpres,
643 lastntrun, lastntslpi, lastntslpu, lastnzomb;
641644 static time_t lasttime;
642645 static struct sstat totsyst;
643646
733736 totalsec, totalsec*hertz, hertz,
734737 osvers, osrel, ossub,
735738 stampalways ? timebuf : " ",
736 lastnpres, totalexit, lastnzomb);
739 lastnpres, lastntrun, lastntslpi, lastntslpu,
740 totalexit, lastnzomb);
737741
738742 if (rv == 0)
739743 {
783787 numsecs, numsecs*hertz, hertz,
784788 osvers, osrel, ossub,
785789 stampalways ? timebuf : " ",
786 npresent, nexit, nzombie);
790 nlist, ntrun, ntslpi, ntslpu, nexit, nzombie);
787791
788792 if (rv == 0)
789793 {
820824 */
821825 lasttime = curtime;
822826 lastnpres = npresent;
827 lastntrun = ntrun;
828 lastntslpi = ntslpi;
829 lastntslpu = ntslpu;
823830 lastnzomb = nzombie;
824831
825832 /*
837844 totalsec, totalsec*hertz, hertz,
838845 osvers, osrel, ossub,
839846 stampalways ? timebuf : " ",
840 npresent, totalexit, nzombie);
847 nlist, ntrun, ntslpi, ntslpu,
848 totalexit, nzombie);
841849
842850 if (rv == 0)
843851 {
919927 fprintf(stderr,
920928 "\t -r read statistical data from specific atop logfile\n");
921929 fprintf(stderr,
922 "\t (pathname, or date in format YYYYMMDD)\n");
930 "\t (pathname, or date in format YYYYMMDD, or y[y..])\n");
923931 fprintf(stderr,
924932 "\t -R summarize <cnt> samples into one sample\n");
925933 fprintf(stderr,
11051113 static void
11061114 cpuhead(int osvers, int osrel, int ossub)
11071115 {
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_");
11101118 }
11111119
11121120 static int
11131121 cpuline(struct sstat *ss, struct pstat *ps, int nproc,
11141122 time_t deltasec, time_t deltatic, time_t hz,
11151123 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)
11171125 {
11181126 register int i, nlines = 1;
11191127 count_t cputot;
11251133 cputot = ss->cpu.all.stime + ss->cpu.all.utime +
11261134 ss->cpu.all.ntime + ss->cpu.all.itime +
11271135 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;
11291138
11301139 if (cputot == 0)
11311140 cputot = 1; /* avoid divide-by-zero */
11381147
11391148 preprint(badness);
11401149
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",
11421151 (double) (ss->cpu.all.utime * 100.0) / cputot * ss->cpu.nrcpu,
11431152 (double) (ss->cpu.all.ntime * 100.0) / cputot * ss->cpu.nrcpu,
11441153 (double) (ss->cpu.all.stime * 100.0) / cputot * ss->cpu.nrcpu,
11451154 (double) (ss->cpu.all.Itime * 100.0) / cputot * ss->cpu.nrcpu,
11461155 (double) (ss->cpu.all.Stime * 100.0) / cputot * ss->cpu.nrcpu,
11471156 (double) (ss->cpu.all.steal * 100.0) / cputot * ss->cpu.nrcpu,
1157 (double) (ss->cpu.all.guest * 100.0) / cputot * ss->cpu.nrcpu,
11481158 (double) (ss->cpu.all.wtime * 100.0) / cputot * ss->cpu.nrcpu,
11491159 (double) (ss->cpu.all.itime * 100.0) / cputot * ss->cpu.nrcpu);
11501160
11601170 cputot = ss->cpu.cpu[i].stime + ss->cpu.cpu[i].utime +
11611171 ss->cpu.cpu[i].ntime + ss->cpu.cpu[i].itime +
11621172 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;
11641175
11651176 if (cputot == 0)
11661177 cputot = 1; /* avoid divide-by-zero */
11761187
11771188 preprint(badness);
11781189
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",
11811192 i,
11821193 (double)(ss->cpu.cpu[i].utime * 100.0) / cputot,
11831194 (double)(ss->cpu.cpu[i].ntime * 100.0) / cputot,
11851196 (double)(ss->cpu.cpu[i].Itime * 100.0) / cputot,
11861197 (double)(ss->cpu.cpu[i].Stime * 100.0) / cputot,
11871198 (double)(ss->cpu.cpu[i].steal * 100.0) / cputot,
1199 (double)(ss->cpu.cpu[i].guest * 100.0) / cputot,
11881200 (double)(ss->cpu.cpu[i].wtime * 100.0) / cputot,
11891201 (double)(ss->cpu.cpu[i].itime * 100.0) / cputot);
11901202
12111223 procline(struct sstat *ss, struct pstat *ps, int nproc,
12121224 time_t deltasec, time_t deltatic, time_t hz,
12131225 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)
12151227 {
12161228 printf("%7.0lf %9.0lf %9.2lf %8.2lf %8.2lf %8.2lf\n",
12171229 (double)ss->cpu.csw / deltasec,
12351247 taskline(struct sstat *ss, struct pstat *ps, int nproc,
12361248 time_t deltasec, time_t deltatic, time_t hz,
12371249 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)
12391251 {
12401252 if (ppres == 0)
12411253 {
12451257
12461258 if (ps) /* process statistics available */
12471259 {
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",
12621261 (double)ss->cpu.nprocs / deltasec,
12631262 (double)pexit / deltasec,
1264 ppres, pzombie, trun, tslpi, tslpu);
1263 ppres, pzombie, ntrun, ntslpi, ntslpu);
12651264 }
12661265 else
12671266 {
12801279 static void
12811280 memhead(int osvers, int osrel, int ossub)
12821281 {
1283 printf("memtotal memfree buffers cached slabmem"
1284 " swptotal swpfree _mem_" );
1282 printf("memtotal memfree buffers cached dirty slabmem"
1283 " swptotal swpfree _mem_" );
12851284 }
12861285
12871286 static int
12881287 memline(struct sstat *ss, struct pstat *ps, int nproc,
12891288 time_t deltasec, time_t deltatic, time_t hz,
12901289 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)
12921291 {
12931292 unsigned int mbadness, sbadness;
12941293
13091308
13101309 preprint(mbadness >= sbadness ? mbadness : sbadness);
13111310
1312 printf("%7lldM %6lldM %6lldM %7lldM %7lldM %7lldM %6lldM",
1311 printf("%7lldM %6lldM %6lldM %5lldM %4lldM %6lldM %7lldM %6lldM",
13131312 ss->mem.physmem * (pagesize / 1024) /1024,
13141313 ss->mem.freemem * (pagesize / 1024) /1024,
13151314 ss->mem.buffermem * (pagesize / 1024) /1024,
13161315 ss->mem.cachemem * (pagesize / 1024) /1024,
1316 ss->mem.cachedrt * (pagesize / 1024) /1024,
13171317 ss->mem.slabmem * (pagesize / 1024) /1024,
13181318 ss->mem.totswap * (pagesize / 1024) /1024,
13191319 ss->mem.freeswap * (pagesize / 1024) /1024);
13371337 swapline(struct sstat *ss, struct pstat *ps, int nproc,
13381338 time_t deltasec, time_t deltatic, time_t hz,
13391339 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)
13411341 {
13421342 unsigned int badness;
13431343
13761376 ** disk statistics
13771377 */
13781378 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)
13901401 {
13911402 static char firstcall = 1;
1392 register int i, nlines = 0;
1403 register int i, nlines = 0, nunit = 0;
13931404 count_t mstot, iotot;
1394 struct perxdsk *dp = ss->xdsk.xdsk;
1405 struct perdsk *dp;
13951406 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 }
13961428
13971429 mstot = (ss->cpu.all.stime + ss->cpu.all.utime +
13981430 ss->cpu.all.ntime + ss->cpu.all.itime +
13991431 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 )
14011434 * (count_t)1000 / hertz / ss->cpu.nrcpu;
14021435
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
14051442 if ( (iotot = dp->nread + dp->nwrite) == 0 &&
14061443 !firstcall && !allresources )
14071444 continue; /* no activity on this disk */
14131450 printf("%s ", tstamp);
14141451
14151452 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;
14181454 else
14191455 badness = 0;
14201456
14211457 preprint(badness);
14221458
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,
14261468 mstot ? (double)dp->io_ms * 100.0 / mstot : 0.0,
14271469 mstot ? (double)dp->nread * 1000.0 / mstot : 0.0,
14281470 dp->nread ?
14431485 }
14441486
14451487 firstcall = 0;
1488
14461489 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');
14471517 }
14481518
14491519 /*
14601530 ifline(struct sstat *ss, struct pstat *ps, int nproc,
14611531 time_t deltasec, time_t deltatic, time_t hz,
14621532 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)
14641534 {
14651535 static char firstcall = 1;
14661536 register long i, nlines = 0;
15661636 IFline(struct sstat *ss, struct pstat *ps, int nproc,
15671637 time_t deltasec, time_t deltatic, time_t hz,
15681638 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)
15701640 {
15711641 static char firstcall = 1;
15721642 register long i, nlines = 0;
16211691 ipv4line(struct sstat *ss, struct pstat *ps, int nproc,
16221692 time_t deltasec, time_t deltatic, time_t hz,
16231693 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)
16251695 {
16261696 printf("%8.1lf %8.1lf %11.1lf %9.1lf %9.1lf %11.1lf\n",
16271697 (double)ss->net.ipv4.InReceives / deltasec,
16441714 IPv4line(struct sstat *ss, struct pstat *ps, int nproc,
16451715 time_t deltasec, time_t deltatic, time_t hz,
16461716 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)
16481718 {
16491719 printf(" %5.1lf %6.1lf %6.1lf %6.1lf %7.1lf %7.1lf "
16501720 " %5.1lf %5.1lf\n",
16731743 icmpv4line(struct sstat *ss, struct pstat *ps, int nproc,
16741744 time_t deltasec, time_t deltatic, time_t hz,
16751745 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)
16771747 {
16781748 printf("%7.1lf %8.1lf %8.2lf %8.2lf %8.2lf %8.2lf\n",
16791749 (double)ss->net.icmpv4.InMsgs / deltasec,
16961766 ICMPv4line(struct sstat *ss, struct pstat *ps, int nproc,
16971767 time_t deltasec, time_t deltatic, time_t hz,
16981768 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)
17001770 {
17011771 printf("%6.2lf %5.2lf %5.2lf %5.2lf %5.2lf "
17021772 "%6.2lf %5.2lf %5.2lf %5.2lf %5.2lf\n",
17271797 udpv4line(struct sstat *ss, struct pstat *ps, int nproc,
17281798 time_t deltasec, time_t deltatic, time_t hz,
17291799 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)
17311801 {
17321802 printf("%9.1lf %10.1lf %7.2lf %9.2lf\n",
17331803 (double)ss->net.udpv4.InDatagrams / deltasec,
17511821 ipv6line(struct sstat *ss, struct pstat *ps, int nproc,
17521822 time_t deltasec, time_t deltatic, time_t hz,
17531823 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)
17551825 {
17561826 printf("%8.1lf %8.1lf %6.1lf %7.1lf %9.1lf %9.1lf %9.1lf\n",
17571827 (double)ss->net.ipv6.Ip6InReceives / deltasec,
17751845 IPv6line(struct sstat *ss, struct pstat *ps, int nproc,
17761846 time_t deltasec, time_t deltatic, time_t hz,
17771847 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)
17791849 {
17801850 printf(" %5.1lf %6.1lf %6.1lf %6.1lf %7.1lf %7.1lf "
17811851 " %5.1lf %5.1lf\n",
18041874 icmpv6line(struct sstat *ss, struct pstat *ps, int nproc,
18051875 time_t deltasec, time_t deltatic, time_t hz,
18061876 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)
18081878 {
18091879 printf("%7.1lf %8.1lf %7.2lf %8.2lf %8.2lf %8.2lf %8.2lf\n",
18101880 (double)ss->net.icmpv6.Icmp6InMsgs / deltasec,
18291899 ICMPv6line(struct sstat *ss, struct pstat *ps, int nproc,
18301900 time_t deltasec, time_t deltatic, time_t hz,
18311901 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)
18331903 {
18341904 printf("%7.2lf %7.2lf %7.2lf %5.2lf %5.2lf "
18351905 "%5.2lf %5.2lf %5.2lf %5.2lf\n",
18591929 udpv6line(struct sstat *ss, struct pstat *ps, int nproc,
18601930 time_t deltasec, time_t deltatic, time_t hz,
18611931 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)
18631933 {
18641934 printf("%9.1lf %10.1lf %7.2lf %9.2lf\n",
18651935 (double)ss->net.udpv6.Udp6InDatagrams / deltasec,
18831953 tcpline(struct sstat *ss, struct pstat *ps, int nproc,
18841954 time_t deltasec, time_t deltatic, time_t hz,
18851955 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)
18871957 {
18881958 printf("%8.1lf %9.1lf %9.1lf %9.1lf %7lld\n",
18891959 (double)ss->net.tcp.InSegs / deltasec,
19051975 TCPline(struct sstat *ss, struct pstat *ps, int nproc,
19061976 time_t deltasec, time_t deltatic, time_t hz,
19071977 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)
19091979 {
19101980 printf("%7.1lf %9.1lf %9.1lf %12.1lf %10.1lf\n",
19111981 (double)ss->net.tcp.InErrs / deltasec,
19281998 httpline(struct sstat *ss, struct pstat *ps, int nproc,
19291999 time_t deltasec, time_t deltatic, time_t hz,
19302000 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)
19322002 {
19332003 printf("%10.2lf %8.2lf %9.2lf %11d %11d\n",
19342004 (double)ss->www.accesses / deltasec,
19562026 topcline(struct sstat *ss, struct pstat *ps, int nproc,
19572027 time_t deltasec, time_t deltatic, time_t hz,
19582028 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)
19602030 {
19612031 count_t availcpu;
19622032
19692039 /*
19702040 ** sort process list in cpu order
19712041 */
1972 qsort(ps, nproc, sizeof(struct pstat), compcpu);
2042 qsort(ps, ppres, sizeof(struct pstat), compcpu);
19732043
19742044 availcpu = ss->cpu.all.stime + ss->cpu.all.utime +
19752045 ss->cpu.all.ntime + ss->cpu.all.itime +
19762046 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;
19782049
19792050 availcpu /= ss->cpu.nrcpu;
19802051
20072078 topmline(struct sstat *ss, struct pstat *ps, int nproc,
20082079 time_t deltasec, time_t deltatic, time_t hz,
20092080 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)
20112082 {
20122083 count_t availmem;
20132084
20202091 /*
20212092 ** sort process list in memory order
20222093 */
2023 qsort(ps, nproc, sizeof(struct pstat), compmem);
2094 qsort(ps, ppres, sizeof(struct pstat), compmem);
20242095
20252096 availmem = ss->mem.physmem * pagesize/1024;
20262097
20502121 topdline(struct sstat *ss, struct pstat *ps, int nproc,
20512122 time_t deltasec, time_t deltatic, time_t hz,
20522123 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)
20542125 {
20552126 int i;
20562127 count_t availdsk;
20812152 /*
20822153 ** sort process list in disk order
20832154 */
2084 qsort(ps, nproc, sizeof(struct pstat), compdsk);
2155 qsort(ps, ppres, sizeof(struct pstat), compdsk);
20852156
20862157 printf("%5d %-8.8s %3.0lf%% | %5d %-8.8s %3.0lf%% | "
20872158 "%5d %-8.8s %3.0lf%%\n",
21092180 topnline(struct sstat *ss, struct pstat *ps, int nproc,
21102181 time_t deltasec, time_t deltatic, time_t hz,
21112182 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)
21132184 {
21142185 int i;
21152186 count_t availnet;
21422213 /*
21432214 ** sort process list in network order
21442215 */
2145 qsort(ps, nproc, sizeof(struct pstat), compnet);
2216 qsort(ps, ppres, sizeof(struct pstat), compnet);
21462217
21472218 printf("%5d %-8.8s %3.0lf%% | %5d %-8.8s %3.0lf%% | "
21482219 "%5d %-8.8s %3.0lf%%\n",
22082279 {0, "c", 'P', taskhead, taskline, "processes & threads", },
22092280 {0, "m", 'm', memhead, memline, "memory & swapspace", },
22102281 {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", },
22122285 {0, "n", 'i', ifhead, ifline, "net-interf (general)", },
22132286 {0, "n", 'I', IFhead, IFline, "net-interf (errors)", },
22142287 {0, "n", 'w', ipv4head, ipv4line, "ip v4 (general)", },
66 ** This source-file contains functions to calculate the differences for
77 ** the system-level and process-level counters since the previous sample.
88 ** ==========================================================================
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
1111 ** Date: November 1996
1212 ** LINUX-port: June 2000
1313 ** --------------------------------------------------------------------------
14 ** Copyright (C) 2000-2005 Gerlof Langeveld
14 ** Copyright (C) 2000-2010 Gerlof Langeveld
1515 **
1616 ** This program is free software; you can redistribute it and/or modify it
1717 ** under the terms of the GNU General Public License as published by the
2929 ** --------------------------------------------------------------------------
3030 **
3131 ** $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 **
3250 ** Revision 1.39 2008/02/25 14:51:18 gerlof
3351 ** Experimental code for HTTP-statistics.
3452 **
149167 **
150168 */
151169
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 $";
153171
154172 #include <sys/types.h>
155173 #include <sys/param.h>
177195 int
178196 deviatproc(struct pstat *aproc, int npresent,
179197 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)
181200 {
182201 register int c, d;
183202 register struct pstat *curstat, *devstat;
184203 struct pstat prestat;
185204 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;
186215
187216 /*
188217 ** make new list of all processes in the process-database;
194223 /*
195224 ** calculate deviations per present process
196225 */
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++)
198229 {
199230 char newproc = 0;
200231
201232 curstat = aproc+c;
202233
203234 if (curstat->gen.state == 'Z')
235 {
204236 (*nzombie)++;
237 }
238 else
239 {
240 *ntrun += curstat->gen.nthrrun;
241 *ntslpi += curstat->gen.nthrslpi;
242 *ntslpu += curstat->gen.nthrslpu;
243 }
205244
206245 /*
207246 ** get previous figures from process-database
271310 devstat->cpu.utime =
272311 subcount(curstat->cpu.utime, prestat.cpu.utime);
273312
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 */
274328 devstat->dsk.rio =
275329 subcount(curstat->dsk.rio, prestat.dsk.rio);
276330 devstat->dsk.rsz =
513567 void
514568 deviatsyst(struct sstat *cur, struct sstat *pre, struct sstat *dev)
515569 {
516 register int i;
570 register int i, j;
517571 count_t *cdev, *ccur, *cpre;
518572
519573 dev->cpu.nrcpu = cur->cpu.nrcpu;
530584 dev->cpu.all.Stime = subcount(cur->cpu.all.Stime, pre->cpu.all.Stime);
531585
532586 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++)
535590 {
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;
561627 }
562628
563629 dev->cpu.lavg1 = cur->cpu.lavg1;
571637 dev->mem.committed = cur->mem.committed;
572638 dev->mem.commitlim = cur->mem.commitlim;
573639 dev->mem.cachemem = cur->mem.cachemem;
640 dev->mem.cachedrt = cur->mem.cachedrt;
574641 dev->mem.totswap = cur->mem.totswap;
575642 dev->mem.freeswap = cur->mem.freeswap;
576643
582649
583650 /*
584651 ** 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;
586653 ** values that do not represent a frequency are corrected afterwards
587654 */
588655 for (cdev = (count_t *)&dev->net.ipv4,
771838 /*
772839 ** calculate deviations for disks
773840 */
774 for (i=0; cur->xdsk.xdsk[i].name[0]; i++)
841 for (i=j=0; cur->dsk.dsk[i].name[0]; i++)
775842 {
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
790889 }
791890
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;
7941005
7951006 /*
7961007 ** application-specific counters
8401051 tot->cpu.all.Itime += new->cpu.all.Itime;
8411052 tot->cpu.all.Stime += new->cpu.all.Stime;
8421053 tot->cpu.all.steal += new->cpu.all.steal;
1054 tot->cpu.all.guest += new->cpu.all.guest;
8431055
8441056 if (new->cpu.nrcpu == 1)
8451057 {
8581070 tot->cpu.cpu[i].Itime += new->cpu.cpu[i].Itime;
8591071 tot->cpu.cpu[i].Stime += new->cpu.cpu[i].Stime;
8601072 tot->cpu.cpu[i].steal += new->cpu.cpu[i].steal;
1073 tot->cpu.cpu[i].guest += new->cpu.cpu[i].guest;
8611074 }
8621075 }
8631076
8741087 tot->mem.committed = new->mem.committed;
8751088 tot->mem.commitlim = new->mem.commitlim;
8761089 tot->mem.cachemem = new->mem.cachemem;
1090 tot->mem.cachedrt = new->mem.cachedrt;
8771091 tot->mem.totswap = new->mem.totswap;
8781092 tot->mem.freeswap = new->mem.freeswap;
8791093
8861100 case 'n': /* accumulate network-related counters */
8871101 /*
8881102 ** 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;
8901104 ** values that do not represent a frequency are corrected
8911105 ** afterwards
8921106 */
10201234 break;
10211235
10221236 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;
10371281 break;
10381282 }
10391283 }
44 ** the system on system-level as well as process-level.
55 **
66 ** ==========================================================================
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
99 ** Date: January 2007
1010 ** --------------------------------------------------------------------------
11 ** Copyright (C) 2007 Gerlof Langeveld
11 ** Copyright (C) 2007-2010 Gerlof Langeveld
1212 **
1313 ** This program is free software; you can redistribute it and/or modify it
1414 ** under the terms of the GNU General Public License as published by the
2525 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2626 ** --------------------------------------------------------------------------
2727 **
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 $
2929 ** $Log: ifprop.c,v $
30 ** Revision 1.5 2010/04/23 12:19:35 gerlof
31 ** Modified mail-address in header.
32 **
3033 ** Revision 1.4 2007/02/13 10:34:06 gerlof
3134 ** Removal of external declarations.
3235 **
0 .TH ATOP 1 "March 2008" "AT Computing"
0 .TH ATOP 1 "April 2010" "AT Computing"
11 .SH NAME
22 .B atop
33 - AT Computing's System & Process Monitor
55 Interactive usage:
66 .P
77 .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]...]
99 [
1010 .I interval
1111 [
3131 .I hh:mm
3232 ] [-e
3333 .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]...]
3535 .SH DESCRIPTION
3636 The program
3737 .I atop
4141 and network.
4242 .br
4343 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'
4648 has been installed.
4749 .PP
4850 Every
6466 .I atop
6567 is started, it checks whether the standard output channel is connected to a
6668 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
6870 it produces flat ASCII-output.
6971 .PP
7072 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
7185 .I atop
7286 can be controlled by pressing particular keys.
7387 However it is also possible to specify such key as
111125 accounting file can be specified (accounting should have been activated
112126 on beforehand). When this environment variable is present but its
113127 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.
114137 .SH COLORS
115138 For the resource consumption on system level,
116139 .I atop
159182 it is not critical from a performance point-of-view.
160183 .PP
161184 These default values can be modified in the configuration file
162 (see section CONFIGURATION FILE).
185 (see separate man-page of atoprc).
163186 .PP
164187 When a resource exceeded its critical occupation percentage, the entire
165188 screen line is colored red.
168191 (so it is almost critical), the entire screen line
169192 is colored cyan. This `almost critical percentage' (one value
170193 for all resources) can be modified in the configuration file
171 (see section CONFIGURATION FILE).
194 (see separate man-page of atoprc).
172195 .PP
173196 With the key 'x' (or flag -x), line coloring can be suppressed.
174197 .SH INTERACTIVE COMMANDS
183206 .B g
184207 Show generic output (default).
185208
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
187212 the last interval in system- and user mode, the virtual and resident
188213 memory growth of the process.
189214 .br
192217 number of read- and write transfers on disk, and the number of received and
193218 transmitted network packets are shown for each process.
194219 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
196221 on disk, the status and exit code are shown for each process.
197222 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
199224 thread group, the status and exit code are shown.
200225 .br
201226 The last columns contain the state, the occupation percentage for the
202227 choosen resource (default: cpu) and the process name.
228
229 When more than 80 positions are available, other information is added.
203230 .PP
204231 .TP 5
205232 .B m
206233 Show memory related output.
207234
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
209238 memory faults, size of virtual shared text, total virtual
210239 process size, total resident process size, virtual and resident growth during
211240 last interval, memory occupation percentage and process name.
241
242 When more than 80 positions are available, other information is added.
212243 .PP
213244 .TP 5
214245 .B d
215246 Show disk-related output.
216247
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
218257 physical disk reads, average size per read (bytes), total size for
219258 read transfers,
220259 physical disk writes, average size per write (bytes), total size for
221260 write transfers, disk occupation percentage and process name.
222 .br
223 This information can only be shown when kernel patch `cnt' is installed.
224261 .PP
225262 .TP 5
226263 .B n
227264 Show network related output.
228265
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,
230269 number of received TCP packets with the average size per packet (in bytes),
231270 number of sent TCP packets with the average size per packet (in bytes),
232271 number of received UDP packets with the average size per packet (in bytes),
233272 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,
235274 the network occupation percentage and process name.
236275 .br
237276 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.
238279 .PP
239280 .TP 5
240281 .B s
241282 Show scheduling characteristics.
242283
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:
244286 process-id,
245287 number of threads in state 'running' (R),
246288 number of threads in state 'interruptible sleeping' (S),
249291 nice value, priority, realtime priority, current processor,
250292 status, exit code, state, the occupation percentage for the choosen
251293 resource and the process name.
294
295 When more than 80 positions are available, other information is added.
252296 .PP
253297 .TP 5
254298 .B v
255299 Show various process characteristics.
256300
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,
258304 start date and time, status (e.g. exit code if the process has finished),
259305 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.
260308 .PP
261309 .TP 5
262310 .B c
265313 Per process the following fields are shown: process-id,
266314 the occupation percentage for the choosen resource and the
267315 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.
268328 .PP
269329 .TP 5
270330 .B u
276336 the current virtual and resident memory space consumed by active processes
277337 (or all processes of the user if combined with command `a').
278338 .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.
283343 .br
284344 The last columns contain the accumulated occupation percentage for the
285345 choosen resource (default: cpu) and the user name.
294354 the current virtual and resident memory space consumed by active processes
295355 (or all processes of the user if combined with command `a').
296356 .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.
301361 .br
302362 The last columns contain the accumulated occupation percentage for the
303363 choosen resource (default: cpu) and the program name.
335395 This option remains valid until
336396 another sorting-order is explicitly selected again.
337397 .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'
339401 is installed.
340402 .PP
341403 Miscellaneous interactive commands:
350412 .PP
351413 .TP 5
352414 .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.
354418 .PP
355419 .TP 5
356420 .B z
385449 .B T
386450 When viewing the contents of a raw file, this key can be used to show the
387451 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).
388457 .PP
389458 .TP 5
390459 .B r
402471 The system statistics are still system wide.
403472 If the Enter-key is pressed without specifying a name, active
404473 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.
405476 .PP
406477 .TP 5
407478 .B P
411482 The system statistics are still system wide.
412483 If the Enter-key is pressed without specifying a name, all active
413484 processes will be shown again.
485 .br
486 Whether this key is active or not can be seen in the header line.
414487 .PP
415488 .TP 5
416489 .B a
417490 The `all/active' key can be used to toggle between only showing/accumulating
418491 the processes that were active during the last interval (default) or
419492 showing/accumulating all processes.
493 .br
494 Whether this key is active or not can be seen in the header line.
420495 .PP
421496 .TP 5
422497 .B f
426501 With this key you can force
427502 .I atop
428503 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.
429506 .PP
430507 .TP 5
431508 .B 1
432509 Show relevant counters as an average per second (in the format `..../s')
433510 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.
434513 .PP
435514 .TP 5
436515 .B l
453532 .PP
454533 .TP 5
455534 .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).
457536 .PP
458537 .TP 5
459538 .B q
460 Quit the monitor program.
539 Quit the program.
461540 .PP
462541 .TP 5
463542 .B ^F
466545 .TP 5
467546 .B ^B
468547 Show the previous page of the process list (backward).
548 .PP
549 .TP 5
550 .B ^L
551 Redraw the screen.
469552 .SH RAW DATA STORAGE
470553 In order to store system- and process level statistics for long-term
471554 analysis (e.g. to check the system load and the active processes running
503586 date), the file
504587 .BI /var/log/atop/atop_ YYYYMMDD
505588 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).
506593 .br
507594 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
509599 When output is redirected to a file or pipe,
510600 .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.
512605 .br
513606 With the flag
514607 .B -b
557650 have no effect.
558651 .SH OUTPUT DESCRIPTION
559652 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).
561654 Note that particular counters could have reached their maximum
562655 value (several times) and started by zero again,
563656 so do not rely on these figures.
583676 (Mb instead of Kb, Gb instead of Mb).
584677 For other values, a kind of exponent notation is used (value 123456789
585678 shown in a column of 5 positions gives 123e6).
586 .PP
679 .SH OUTPUT DESCRIPTION - SYSTEM LEVEL
587680 The system level information consists of the following output lines:
588681 .PP
589682 .TP 5
593686 This line contains the total cpu time consumed
594687 in system mode (`sys') and in user mode (`user'),
595688 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
597693 the number of processes that ended during the interval
598694 (`#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.
599698 .PP
600699 .TP 5
601700 .B CPU
608707 sorted on activity. Inactive cpu's will not be shown by default.
609708 The lines showing the per-cpu occupation contain the cpu number in
610709 the last field.
611 .br
710
612711 Every line contains the percentage of cpu time spent in
613712 kernel mode by all active processes (`sys'),
614713 the percentage of cpu time consumed in user mode (`user') for all
622721 In case of per-cpu occupation, the last column shows the cpu number and
623722 the wait percentage (`w') for that cpu.
624723 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
631727 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.
635753 .PP
636754 .TP 5
637755 .B CPL
642760 or that are waiting for disk I/O. These figures are averaged over
643761 1 (`avg1'), 5 (`avg5') and 15 (`avg15') minutes.
644762 .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.
647768 .PP
648769 .TP 5
649770 .B MEM
652773 This line contains the total amount of physical memory
653774 (`tot'), the amount of memory which is currently free (`free'),
654775 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'),
655778 the amount of memory used for filesystem meta data (`buff') and the amount of
656779 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.
657783 .PP
658784 .TP 5
659785 .B SWP
683809 are shown.
684810 .PP
685811 .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.
698835 .PP
699836 .TP 5
700837 .B NET
705842 .br
706843 For the transport layer,
707844 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
710847 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
715864 For the IP layer, counters are shown concerning the number of IP datagrams
716865 received from interfaces, including those received in error (`ipi'),
717866 the number of IP datagrams that local higher-layer protocols offered for
718867 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
723878 For every active network interface one line is shown,
724879 sorted on the interface activity.
725880 Such line shows the name of the interface and its busy percentage
731886 When the interface speed can not be determined (e.g. for the loopback
732887 interface), `---' is shown instead of the percentage.
733888 .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
738903 The number of lines showing the network interfaces can be limited.
739 .PP
904 .SH OUTPUT DESCRIPTION - PROCESS LEVEL
740905 Following the system level information, the processes are shown from which the
741906 resource utilization has changed during the last interval. These processes
742907 might have used cpu time or issued disk- or network requests. However a process
745910 .PP
746911 Per process the following fields may be shown (in alphabetical order),
747912 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.
749922 .PP
750923 .TP 9
751924 .B CMD
774947 for this resource on system level.
775948 .PP
776949 .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
777955 .B DSK
778956 The occupation percentage of this process related to the total load that
779957 is produced by all processes (i.e. total disk accesses
780958 by all processes during the last interval).
781959 .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.
783980 .PP
784981 .TP 9
785982 .B EXC
787984 or the fatal signal number (second position of column `ST' is S or C).
788985 .PP
789986 .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.
792993 .PP
793994 .TP 9
794995 .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.
796998 .PP
797999 .TP 9
7981000 .B MEM
8011003 .PP
8021004 .TP 9
8031005 .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.
8051008 .PP
8061009 .TP 9
8071010 .B NET
8101013 by all processes during the last interval).
8111014 .br
8121015 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).
8131021 .PP
8141022 .TP 9
8151023 .B NPROCS
8271035 .PP
8281036 .TP 9
8291037 .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.
8331042 .PP
8341043 .TP 9
8351044 .B PPID
8491058 CPU consumption and the nice value).
8501059 .PP
8511060 .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.
8541063 This information can only be shown when kernel patch `cnt' is installed.
8551064 .br
8561065 If a process has finished during the last interval, no value is shown
8601069 shown.
8611070 .PP
8621071 .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
8631083 .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
8641089 When the kernel patch `cnt' is installed:
1090 .br
8651091 The number of read accesses issued physically on disk (so reading from the
8661092 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.
8721097 .PP
8731098 .TP 9
8741099 .B RGROW
9101135 .TP 9
9111136 .B RTPR
9121137 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.
9161145 .PP
9171146 .TP 9
9181147 .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
9221152 with its parent process), `T' for stopped (suspended or traced), `W' for
9231153 swapping, and `E' (exit) for processes which have finished during the last
9241154 interval.
1155 .PP
1156 .TP 9
1157 .B SGID
1158 The saved group-id of the process.
9251159 .PP
9261160 .TP 9
9271161 .B SNET
9701204 The start time of the process.
9711205 .PP
9721206 .TP 9
1207 .B SUID
1208 The saved user-id of the process.
1209 .PP
1210 .TP 9
9731211 .B SYSCPU
9741212 CPU time consumption of this process in system mode (kernel mode), usually
9751213 due to system call handling.
9761214 .PP
9771215 .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
9781223 .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.
9811225 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.
9881235 .PP
9891236 .TP 9
9901237 .B TCPSND
9911238 The number of send requests issued by this process for TCP sockets,
9921239 and the average size per transfer in bytes.
9931240 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.
10001243 .PP
10011244 .TP 9
10021245 .B THR
10121255 as a separate line.
10131256 .PP
10141257 .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
10151268 .B TRUN
10161269 Number of threads within this process that are in the state 'running' (R).
10171270 .PP
10261279 state 'uninterruptible sleeping' (D).
10271280 .PP
10281281 .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
10291289 .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,
10311305 and the average size per transfer in bytes.
10321306 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.
10551309 .PP
10561310 .TP 9
10571311 .B USRCPU
10891343 .PP
10901344 .TP 9
10911345 .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
10921355 When the kernel patch `cnt' is installed:
1356 .br
10931357 The number of write accesses issued physically on disk (so writing to the
10941358 disk cache is not accounted for). Usually application processes just transfer
10951359 their data to the cache, while the physical write accesses are done later on
11001364 process has finished during the last interval.
11011365 However when the kernel patch `acct' is installed, these values will be
11021366 shown separately.
1103 .br
1367 .PP
1368 .TP 9
1369 .B WCANCL
11041370 When the kernel patch `cnt' is not installed, but the kernel maintains
11051371 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
11171373 The write data transfer previously accounted for this process
11181374 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
11201376 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
11221378 the process that removes/truncates the file shows
1123 the unflushed removed data as WRDSK_CANCEL.
1379 the unflushed removed data as WCANCL.
11241380 .SH PARSEABLE OUTPUT
11251381 With the flag
11261382 .B -P
11291385 The labels that can be specified for system-level statistics
11301386 correspond to the labels (first verb of each line)
11311387 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".
11331389 .br
11341390 For process-level statistics special labels are introduced:
11351391 "PRG" (general), "PRC" (cpu), "PRM" (memory), "PRD" (disk, only if
11421398 .B atop
11431399 shows a line just containing the label "SEP" as a separator before the
11441400 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.
11451406 .PP
11461407 The first part of each output-line consists of the following six fields:
11471408 .B label
11701431 consumption for all CPU's in idle mode (clock-ticks),
11711432 consumption for all CPU's in wait mode (clock-ticks),
11721433 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).
11751437 .TP 9
11761438 .B cpu
11771439 Subsequent fields:
11831445 consumption for this CPU in idle mode (clock-ticks),
11841446 consumption for this CPU in wait mode (clock-ticks),
11851447 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).
11881451 .TP 9
11891452 .B CPL
11901453 Subsequent fields:
12011464 size of physical memory (pages),
12021465 size of free memory (pages),
12031466 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.
12061470 .TP 9
12071471 .B SWP
12081472 Subsequent fields:
12221486 number of swapins, and
12231487 number of swapouts.
12241488 .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.
12271491 .br
12281492 Subsequent fields:
1229 name of disk,
1493 name,
12301494 number of milliseconds spent for I/O,
12311495 number of reads issued,
12321496 number of sectors transferred for reads,
12681532 exit code, start time (epoch),
12691533 full command line (between brackets), PPID,
12701534 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).
12731540 .TP 9
12741541 .B PRC
12751542 For every process one line is shown.
13621629 .PP
13631630 .B \ atop -PCPU,DSK -r /tmp/atop.raw
13641631 .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
15001645 .PP
15011646 .SH FILES
15021647 .PP
15101655 is not used.
15111656 .PP
15121657 .TP 5
1658 .B /etc/atoprc
1659 Configuration file containing system-wide default values.
1660 See related man-page.
1661 .PP
1662 .TP 5
15131663 .B ~/.atoprc
15141664 Configuration file containing personal default values.
1665 See related man-page.
15151666 .PP
15161667 .TP 5
15171668 .BI /var/log/atop/atop_ YYYYMMDD
15301681 in compressed format.
15311682 .SH SEE ALSO
15321683 .B atopsar(1),
1684 .B atoprc(5),
15331685 .B logrotate(8)
15341686 .br
1535 .B http://www.ATComputing.nl/Tools/atop
1687 .B http://www.atoptool.nl
15361688 .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"
11 .SH NAME
22 .B atopsar
33 - AT Computing's System Activity Report (atop related)
5050 (where YYYYMMDD reflects the date),
5151 the required date of the form YYYYMMDD can be specified with the
5252 .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).
5456 If the
5557 .B -r
5658 option is not specified at all, today's daily logfile is used by default.
182184 Report about paging- and swapping-activity, and overcommitment.
183185 .PP
184186 .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
185195 .B -d
186 Report about utilization of disks and disk-partitions.
196 Report about utilization of disks.
187197 .PP
188198 .TP 5
189199 .B -i
292302 Percentage of cpu time stolen by other virtual machines
293303 running on the same hardware.
294304 .TP 12
305 .B guest%
306 Percentage of cpu time used by other virtual machines
307 running on the same hardware.
308 .TP 12
295309 .B wait%
296310 Percentage of unused cpu time while
297311 at least one of the processes in wait-state awaits completion of disk I/O.
373387 .B cached
374388 Main memory used at this moment to cache data-blocks (snapshot).
375389 .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
376394 .B slabmem
377395 Main memory used at this moment for dynamically allocated memory
378396 by the kernel (snapshot).
408426 The kernel only verifies whether the committed space exceeds the limit
409427 if strict overcommit handling is configured (vm.overcommit_memory is 2).
410428 .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:
414436 .TP 12
415437 .B disk
416 Disk name.
438 Name.
417439 .TP 12
418440 .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
420442 device was busy handling requests).
421443 .TP 12
422444 .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.
424446 .TP 12
425447 .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.
430452 .TP 12
431453 .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.
433455 .TP 12
434456 .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.
437459 .TP 12
438460 .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
440462 (seek, latency and data-transfer).
441463 .PP
442464 The output for the flag
973995 .TP 12
974996 .B \ atopsar
975997 .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
977999 (supposed that
9781000 .B atop
9791001 has been logging daily in the background):
9801002 .PP
9811003 .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 \
9831007 .br
9841008 or
9851009 .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
9871017 .PP
9881018 Write a logfile with
9891019 .B atop
10091039 .TP 12
10101040 .B \ atopsar -AM | grep '[_*+]$'
10111041 .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
10421042 .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.
10431048 .PP
10441049 .TP 5
10451050 .B ~/.atoprc
10461051 Configuration file containing personal default values (mainly flags).
1052 See related man-page.
10471053 .PP
10481054 .TP 5
10491055 .BI /var/log/atop/atop_ YYYYMMDD
10511057 .I YYYYMMDD
10521058 are digits representing the date.
10531059 .SH SEE ALSO
1054 .B atop(1)
1060 .B atop(1),
1061 .B atoprc(5),
10551062 .br
1056 .B http://www.ATComputing.nl/Tools/atop
1063 .B http://www.atoptool.nl
10571064 .SH AUTHOR
1058 Gerlof Langeveld, AT Computing (gerlof@ATComputing.nl)
1065 Gerlof Langeveld (gerlof.langeveld@atoptool.nl)
44 ** the system on system-level as well as process-level.
55 **
66 ** ==========================================================================
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
99 ** Date: February 2007
1010 ** --------------------------------------------------------------------------
11 ** Copyright (C) 2007 Gerlof Langeveld
11 ** Copyright (C) 2007-2010 Gerlof Langeveld
1212 **
1313 ** This program is free software; you can redistribute it and/or modify it
1414 ** under the terms of the GNU General Public License as published by the
2525 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2626 ** --------------------------------------------------------------------------
2727 **
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 $
2929 ** $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 **
3048 ** Revision 1.7 2008/03/06 09:08:29 gerlof
3149 ** Bug-solution regarding parseable output of PPID.
3250 **
6987 void print_MEM();
7088 void print_SWP();
7189 void print_PAG();
90 void print_LVM();
91 void print_MDD();
7292 void print_DSK();
7393 void print_NET();
7494
95115 { "MEM", 0, print_MEM },
96116 { "SWP", 0, print_SWP },
97117 { "PAG", 0, print_PAG },
118 { "LVM", 0, print_LVM },
119 { "MDD", 0, print_MDD },
98120 { "DSK", 0, print_DSK },
99121 { "NET", 0, print_NET },
100122
186208 char
187209 parseout(time_t curtime, int numsecs,
188210 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,
190212 int nexit, char flag)
191213 {
192214 register int i;
193215 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");
194222
195223 /*
196224 ** search all labels which are selected before
229257 /*
230258 ** print functions for system-level statistics
231259 */
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
232288 void
233289 print_CPU(char *hp, struct sstat *ss, struct pstat *ps, int nact)
234290 {
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",
236308 hp,
237309 hertz,
238310 ss->cpu.nrcpu,
243315 ss->cpu.all.wtime,
244316 ss->cpu.all.Itime,
245317 ss->cpu.all.Stime,
246 ss->cpu.all.steal);
318 ss->cpu.all.steal,
319 ss->cpu.all.guest,
320 freq,
321 freqperc
322 );
247323 }
248324
249325 void
250326 print_cpu(char *hp, struct sstat *ss, struct pstat *ps, int nact)
251327 {
252328 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;
253334
254335 for (i=0; i < ss->cpu.nrcpu; i++)
255336 {
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",
257345 hp, hertz, i,
258346 ss->cpu.cpu[i].stime,
259347 ss->cpu.cpu[i].utime,
262350 ss->cpu.cpu[i].wtime,
263351 ss->cpu.cpu[i].Itime,
264352 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);
266357 }
267358 }
268359
282373 void
283374 print_MEM(char *hp, struct sstat *ss, struct pstat *ps, int nact)
284375 {
285 printf( "%s %u %lld %lld %lld %lld %lld\n",
376 printf( "%s %u %lld %lld %lld %lld %lld %lld\n",
286377 hp,
287378 pagesize,
288379 ss->mem.physmem,
289380 ss->mem.freemem,
290381 ss->mem.cachemem,
291382 ss->mem.buffermem,
292 ss->mem.slabmem);
383 ss->mem.slabmem,
384 ss->mem.cachedrt);
293385 }
294386
295387 void
319411 }
320412
321413 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
322450 print_DSK(char *hp, struct sstat *ss, struct pstat *ps, int nact)
323451 {
324452 register int i;
325453
326 for (i=0; ss->xdsk.xdsk[i].name[0]; i++)
454 for (i=0; ss->dsk.dsk[i].name[0]; i++)
327455 {
328456 printf( "%s %s %lld %lld %lld %lld %lld\n",
329457 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);
336464 }
337465 }
338466
383511
384512 for (i=0; i < nact; i++, ps++)
385513 {
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",
387516 hp,
388517 ps->gen.pid,
389518 ps->gen.name,
398527 ps->gen.ppid,
399528 ps->gen.nthrrun,
400529 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);
402538 }
403539 }
404540
00 int parsedef(char *);
11 char parseout(time_t, int, struct sstat *, struct pstat *,
2 int, int, int, int, char);
2 int, int, int, int, int, int, int, char);
77 ** of every running process from kernel-space and extract the required
88 ** activity-counters.
99 ** ==========================================================================
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
1212 ** Date: November 1996
1313 ** LINUX-port: June 2000
1414 ** --------------------------------------------------------------------------
15 ** Copyright (C) 2000-2005 Gerlof Langeveld
15 ** Copyright (C) 2000-2010 Gerlof Langeveld
1616 **
1717 ** This program is free software; you can redistribute it and/or modify it
1818 ** under the terms of the GNU General Public License as published by the
3030 ** --------------------------------------------------------------------------
3131 **
3232 ** $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 **
3339 ** Revision 1.31 2008/03/06 08:38:14 gerlof
3440 ** Register/show ppid of a process.
3541 **
129135 **
130136 */
131137
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 $";
133139
134140 #include <sys/types.h>
135141 #include <sys/param.h>
294300 int nr;
295301 char line[4096], *cmdhead, *cmdtail;
296302 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,
298305 curcpu, nthreads, sleepavg;
299306 count_t utime, stime, starttime;
300307 count_t minflt, majflt, size, rss, nswap,
369376
370377 if (memcmp(line, "Uid:", 4)==0)
371378 {
372 sscanf(line, "Uid: %d", &ruid);
379 sscanf(line, "Uid: %d %d %d %d",
380 &ruid, &euid, &suid, &fsuid);
373381 continue;
374382 }
375383
376384 if (memcmp(line, "Gid:", 4)==0)
377385 {
378 sscanf(line, "Gid: %d", &rgid);
386 sscanf(line, "Gid: %d %d %d %d",
387 &rgid, &egid, &sgid, &fsgid);
379388 continue;
380389 }
381390
430439 ** store required info in process-structure
431440 */
432441 curproc->gen.pid = pid;
442 curproc->gen.ppid = ppid;
433443 curproc->gen.ruid = ruid;
444 curproc->gen.euid = euid;
445 curproc->gen.suid = suid;
446 curproc->gen.fsuid = fsuid;
434447 curproc->gen.rgid = rgid;
435 curproc->gen.ppid = ppid;
448 curproc->gen.egid = egid;
449 curproc->gen.sgid = sgid;
450 curproc->gen.fsgid = fsgid;
436451 curproc->gen.nthr = nthreads;
437452 curproc->gen.state = state;
438453
66 ** Include-file describing process-level counters maintained and functions
77 ** to access the process-database.
88 ** ================================================================
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
1111 ** Date: November 1996
1212 ** LINUX-port: June 2000
1313 **
2323 */
2424
2525 #define PNAMLEN 15
26 #define CMDLEN 68
26 #define CMDLEN 150
2727
2828 /*
2929 ** structure containing only relevant process-info extracted
3333 /* GENERAL PROCESS INFO */
3434 struct gen {
3535 int pid; /* process identification */
36 int ruid; /* real user identification */
37 int rgid; /* real group identification */
3836 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 */
3945 int nthr; /* number of threads in tgroup */
4046 char name[PNAMLEN+1];/* process name string */
4147 char state; /* process state ('E' = exited) */
4248 int excode; /* process exit status */
4349 time_t btime; /* process start time (epoch) */
50 time_t elaps; /* process elaps time (hertz) */
4451 char cmdline[CMDLEN+1];/* command-line string */
4552 int nthrslpi; /* # threads in state 'S' */
4653 int nthrslpu; /* # threads in state 'D' */
124131 ** prototypes for raw process-statistics functions
125132 */
126133 int deviatproc(struct pstat *, int, struct pstat *, int, int,
127 struct pstat *, int *);
134 struct pstat *, struct sstat *,
135 int *, int *, int *, int *);
128136 int photoproc(struct pstat *, int);
129137 unsigned int countprocs(void);
66 ** This source-file contains functions to read all relevant system-level
77 ** figures.
88 ** ==========================================================================
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
1111 ** Date: November 1996
1212 ** LINUX-port: June 2000
1313 ** --------------------------------------------------------------------------
14 ** Copyright (C) 2000-2005 Gerlof Langeveld
14 ** Copyright (C) 2000-2010 Gerlof Langeveld
1515 **
1616 ** This program is free software; you can redistribute it and/or modify it
1717 ** under the terms of the GNU General Public License as published by the
2929 ** --------------------------------------------------------------------------
3030 **
3131 ** $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 **
3254 ** Revision 1.30 2008/02/25 13:47:00 gerlof
3355 ** Experimental code for HTTP statistics.
3456 **
123145 **
124146 */
125147
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 $";
127149
128150 #include <sys/types.h>
129151 #include <stdio.h>
131153 #include <unistd.h>
132154 #include <stdlib.h>
133155 #include <regex.h>
156 #include <sys/stat.h>
134157 #include <sys/times.h>
135158 #include <sys/wait.h>
136159 #include <time.h>
137160 #include <signal.h>
138161 #include <string.h>
162 #include <dirent.h>
139163
140164 #include <sys/socket.h>
141165 #include <netinet/in.h>
146170
147171 #define MAXCNT 64
148172
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);
150181
151182 static struct ipv6_stats ipv6_tmp;
152183 static struct icmpv6_stats icmpv6_tmp;
234265 FILE *fp;
235266 char linebuf[1024], nam[64], origdir[1024];
236267 static char part_stats = 1; /* per-partition statistics ? */
268 unsigned int major, minor;
237269 #if HTTPSTATS
238270 static int wwwvalid = 1;
239271 #endif
278310
279311 if (nr > 8) /* steal support */
280312 si->cpu.all.steal = cnts[7];
313
314 if (nr > 9) /* guest support */
315 si->cpu.all.guest = cnts[8];
281316 }
282317 continue;
283318 }
300335
301336 if (nr > 8) /* steal support */
302337 si->cpu.cpu[i].steal = cnts[7];
338
339 if (nr > 9) /* guest support */
340 si->cpu.cpu[i].guest = cnts[8];
303341 }
304342
305343 si->cpu.nrcpu++;
357395
358396 fclose(fp);
359397 }
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 }
360523
361524 /*
362525 ** gather virtual memory statistics from the file /proc/vmstat and
428591
429592 if ( (fp = fopen("meminfo", "r")) != NULL)
430593 {
431 int nrfields = 9; /* number of fields to be filled */
594 int nrfields = 10; /* number of fields to be filled */
432595
433596 while ( fgets(linebuf, sizeof(linebuf), fp) != NULL &&
434597 nrfields > 0)
465628 cnts[0]*1024/pagesize;
466629 nrfields--;
467630 }
631 }
632 else if (strcmp("Dirty:", nam) == EQ)
633 {
634 si->mem.cachedrt =
635 cnts[0]*1024/pagesize;
636 nrfields--;
468637 }
469638 else if (strcmp("MemTotal:", nam) == EQ)
470639 {
711880 "%*d %*d %*d %255s %lld %*d %lld %*d "
712881 "%lld %*d %lld %*d %*d %lld %lld",
713882 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) );
720889
721890 /*
722891 ** check if this line concerns the entire disk
725894 */
726895 if (nr == 7) /* full stats-line ? */
727896 {
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)
731900 continue;
732901
733902 if (++i >= MAXDSK-1)
735904 }
736905 }
737906
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;
740909
741910 fclose(fp);
742911
750919 */
751920 if ( (fp = fopen("diskstats", "r")) != NULL)
752921 {
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;
755928
756929 while ( fgets(linebuf, sizeof(linebuf), fp) )
757930 {
758931 nr = sscanf(linebuf,
759 "%*d %*d %255s %lld %*d %lld %*d "
932 "%d %d %255s %lld %*d %lld %*d "
760933 "%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 );
768938
769939 /*
770940 ** check if this line concerns the entire disk
771941 ** or just one of the partitions of a disk (to be
772942 ** skipped)
773943 */
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:
779950 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;
782955 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';
788976
789977 fclose(fp);
790978 }
802990
803991 /*
804992 ** 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
806994 */
807995 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)
809998 {
810 strncpy(newname, curname, maxlen-1);
811 *(newname+maxlen-1) = 0;
999 strncpy(px->name, curname, maxlen-1);
1000 *(px->name+maxlen-1) = 0;
8121001 }
8131002
8141003 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)
8161006 {
8171007 char cutype[128];
8181008 int hostnum, busnum, targetnum, lunnum;
8201010 sscanf(curname, "%[^/]/host%d/bus%d/target%d/lun%d",
8211011 cutype, &hostnum, &busnum, &targetnum, &lunnum);
8221012
823 snprintf(newname, maxlen, "%c-h%db%dt%d",
1013 snprintf(px->name, maxlen, "%c-h%db%dt%d",
8241014 cutype[0], hostnum, busnum, targetnum);
8251015 }
8261016
8271017 /*
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
8321129 */
8331130 static struct {
8341131 char *regexp;
8351132 regex_t compreg;
836 void (*modname)(char *, char *, int);
1133 void (*modname)(unsigned int, unsigned int,
1134 char *, struct perdsk *, int);
1135 int retval;
8371136 } 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, },
8471150 };
8481151
8491152 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)
8511155 {
8521156 static int firstcall = 1;
8531157 register int i;
8701174 /*
8711175 ** name-string recognized; modify name-string
8721176 */
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;
8801186 }
8811187
8821188 /*
55 **
66 ** Include-file describing system-level counters maintained.
77 ** ================================================================
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
1010 ** Date: November 1996
1111 ** LINUX-port: June 2000
1212 **
2323 #include "netstats.h"
2424
2525 #define MAXCPU 64
26 #define MAXDSK 128
26 #define MAXDSK 256
27 #define MAXLVM 256
28 #define MAXMDD 128
2729 #define MAXDKNAM 32
2830 #define MAXINTF 32
2931
3537 count_t buffermem; /* number of buffer pages */
3638 count_t slabmem; /* number of slab pages */
3739 count_t cachemem; /* number of cache pages */
38 count_t committed; /* number of reserved pages */
40 count_t cachedrt; /* number of cache pages (dirty) */
3941
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 */
4047 count_t swouts; /* number of pages swapped out */
4148 count_t swins; /* number of pages swapped in */
4249
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 */
4650 count_t commitlim; /* commit limit in pages */
47 count_t allocstall; /* try to free pages forced */
51 count_t committed; /* number of reserved pages */
4852 count_t cfuture[4]; /* reserved for future use */
4953 };
5054
6468
6569 /************************************************************************/
6670
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
6778 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 */
7891 };
7992
8093 struct cpustat {
93106
94107 /************************************************************************/
95108
96 struct perxdsk {
109 struct perdsk {
97110 char name[MAXDKNAM]; /* empty string for last */
98111 count_t nread; /* number of read transfers */
99112 count_t nrsect; /* number of sectors read */
104117 count_t cfuture[4]; /* reserved for future use */
105118 };
106119
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];
110127 };
111128
112129 /************************************************************************/
168185 struct memstat mem;
169186 struct netstat net;
170187 struct intfstat intf;
171 struct xdskstat xdsk;
188 struct dskstat dsk;
172189
173190 struct wwwstat www;
174191 };
88 ** all running processes, needed to remember the process-counters from
99 ** the previous sample.
1010 ** ==========================================================================
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
1313 ** Date: November 1996
1414 ** LINUX-port: June 2000
1515 ** --------------------------------------------------------------------------
16 ** Copyright (C) 2000-2005 Gerlof Langeveld
16 ** Copyright (C) 2000-2010 Gerlof Langeveld
1717 **
1818 ** This program is free software; you can redistribute it and/or modify it
1919 ** under the terms of the GNU General Public License as published by the
3131 ** --------------------------------------------------------------------------
3232 **
3333 ** $Log: procdbase.c,v $
34 ** Revision 1.8 2010/04/23 12:19:35 gerlof
35 ** Modified mail-address in header.
36 **
3437 ** Revision 1.7 2007/11/05 12:12:31 gerlof
3538 ** Match processes not only on pid, but also on start time.
3639 **
5457 **
5558 */
5659
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 $";
5861
5962 #include <sys/types.h>
6063 #include <sys/param.h>
33 ** The program 'atop' offers the possibility to view the activity of
44 ** the system on system-level as well as process-level.
55 ** ==========================================================================
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
88 ** Date: September 2002
99 ** --------------------------------------------------------------------------
10 ** Copyright (C) 2000-2005 Gerlof Langeveld
10 ** Copyright (C) 2000-2010 Gerlof Langeveld
1111 **
1212 ** This program is free software; you can redistribute it and/or modify it
1313 ** under the terms of the GNU General Public License as published by the
2525 ** --------------------------------------------------------------------------
2626 **
2727 ** $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 **
2860 ** Revision 1.22 2008/01/07 10:18:05 gerlof
2961 ** Implement possibility to make summaries.
3062 **
99131 **
100132 */
101133
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 $";
103135
104136 #include <sys/types.h>
105137 #include <sys/param.h>
109141 #include <stdio.h>
110142 #include <errno.h>
111143 #include <fcntl.h>
112 #include <unistd.h>
113144 #include <stdlib.h>
114145 #include <signal.h>
115146 #include <ctype.h>
116147 #include <sys/utsname.h>
117148 #include <string.h>
149 #include <regex.h>
118150 #include <zlib.h>
151 #include <sys/time.h>
152 #include <sys/resource.h>
153 #include <unistd.h>
119154
120155 #include "atop.h"
156 #include "showgeneric.h"
121157 #include "photoproc.h"
122158 #include "photosyst.h"
123159
144180 unsigned int magic;
145181
146182 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 */
149185 unsigned short rawheadlen; /* length of struct rawheader */
150186 unsigned short rawreclen; /* length of struct rawrecord */
151187 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 */
153191 struct utsname utsname; /* info about this system */
154192 char cfuture[8]; /* future use */
155193
173211 unsigned int nlist; /* number of processes in list */
174212 unsigned int npresent; /* total number of processes */
175213 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)*/
176217 unsigned int nzombie; /* number of zombie processes */
177218 unsigned int ifuture[6]; /* future use */
178219 };
183224 static int rawwopen(void);
184225 static int lookslikedatetome(char *);
185226 static void testcompval(int, char *);
227 static void try_other_version(int, int);
186228
187229 /*
188230 ** write a raw record to file
191233 char
192234 rawwrite(time_t curtime, int numsecs,
193235 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)
196238 {
197239 static int rawfd = -1;
198240 struct rawrecord rr;
199241 int rv;
242 struct stat filestat;
200243
201244 Byte scompbuf[sizeof(struct sstat)], *pcompbuf;
202245 unsigned long scomplen = sizeof scompbuf;
208251 */
209252 if (rawfd == -1)
210253 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);
211261
212262 /*
213263 ** compress system- and process-level statistics
237287 rr.flags = 0;
238288 rr.nlist = nlist;
239289 rr.npresent = npresent;
290 rr.ntrun = ntrun;
291 rr.ntslpi = ntslpi;
292 rr.ntslpu = ntslpu;
240293 rr.nzombie = nzombie;
241294 rr.nexit = nexit;
242295 rr.scomplen = scomplen;
249302 {
250303 fprintf(stderr, "%s - ", rawname);
251304 perror("write raw record");
305 (void) ftruncate(rawfd, filestat.st_size);
252306 cleanstop(7);
253307 }
254308
259313 {
260314 fprintf(stderr, "%s - ", rawname);
261315 perror("write raw status record");
316 (void) ftruncate(rawfd, filestat.st_size);
262317 cleanstop(7);
263318 }
264319
269324 {
270325 fprintf(stderr, "%s - ", rawname);
271326 perror("write raw process record");
327 (void) ftruncate(rawfd, filestat.st_size);
272328 cleanstop(7);
273329 }
274330
392448 #define OFFCHUNK 256
393449
394450 void
395 rawread(unsigned int begintime, unsigned int endtime)
451 rawread(void)
396452 {
397 int rawfd;
453 int rawfd, len;
454 char *py;
398455 struct rawheader rh;
399456 struct rawrecord rr;
400457 struct sstat devsstat;
414471 time_t timenow;
415472 struct tm *tp;
416473
417 switch ( strlen(rawname) )
474 switch ( len = strlen(rawname) )
418475 {
419476 /*
420477 ** if no filename is specified, assemble the name of the raw file
448505 snprintf(rawname, RAWNAMESZ, "%s/atop_%s",
449506 BASEPATH,
450507 savedname);
508 break;
451509 }
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);
453542 }
454543
455544 /*
524613 "(created by version %d.%d - "
525614 "current version %d.%d)\n",
526615 (rh.aversion >> 8) & 0x7f,
527 rh.aversion & 0xff,
616 rh.aversion & 0xff,
528617 getnumvers() >> 8,
529618 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);
530628 }
531629
532630 cleanstop(7);
593691 ** check if this sample is within the time-range
594692 ** specified with the -b and -e flags (if any)
595693 */
596 if ( (begintime && begintime > secsinday) ||
597 (endtime && endtime < secsinday) )
694 if ( (begintime && begintime > secsinday) )
598695 {
599 lastcmd = '\0';
696 lastcmd = 1;
600697 lseek(rawfd, rr.scomplen+rr.pcomplen, SEEK_CUR);
601698 continue;
602699 }
603
700
701 begintime = 0;
702
703 if ( (endtime && endtime < secsinday) )
704 {
705 free(offlist);
706 close(rawfd);
707 return;
708 }
709
604710 /*
605711 ** allocate space, read compressed system-level
606712 ** statistics and decompress
640746 lastcmd = (vis.show_samp)(rr.curtime, rr.interval,
641747 &devsstat, devpstat,
642748 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);
645752 free(devpstat);
646753
647754 switch (lastcmd)
648755 {
649 case 'T':
756 case MSAMPPREV:
650757 if (offcur >= 2)
651758 offcur-= 2;
652759 else
655762 lseek(rawfd, *(offlist+offcur), SEEK_SET);
656763 break;
657764
658 case 'r':
765 case MRESET:
659766 lseek(rawfd, *offlist, SEEK_SET);
660767 offcur = 1;
768 break;
769
770 case MSAMPBRANCH:
771 if (begintime && begintime < secsinday)
772 {
773 lseek(rawfd, *offlist, SEEK_SET);
774 offcur = 1;
775 }
661776 }
662777 }
778
779 begintime = 0;
663780
664781 if (offcur >= 1)
665782 offcur--;
792909 cleanstop(7);
793910 }
794911 }
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 }
66 ** This source-file contains the print-functions to visualize the calculated
77 ** figures.
88 ** ==========================================================================
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
1111 ** Date: November 1996
1212 ** LINUX-port: June 2000
1313 ** --------------------------------------------------------------------------
14 ** Copyright (C) 2000-2005 Gerlof Langeveld
14 ** Copyright (C) 2000-2010 Gerlof Langeveld
1515 **
1616 ** This program is free software; you can redistribute it and/or modify it
1717 ** under the terms of the GNU General Public License as published by the
2929 ** --------------------------------------------------------------------------
3030 **
3131 ** $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 **
3294 ** Revision 1.52 2008/03/06 10:14:01 gerlof
3395 ** Modified help-messages.
3496 **
192254 **
193255 */
194256
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 $";
196258
197259 #include <sys/types.h>
198260 #include <sys/param.h>
217279 #include "photoproc.h"
218280 #include "photosyst.h"
219281 #include "showgeneric.h"
282 #include "showlinux.h"
220283
221284 struct selection procsel = {"", {USERSTUB, }, "", 0, { 0, }};
222285
231294
232295 static int maxcpulines = 999; /* maximum cpu lines */
233296 static int maxdsklines = 999; /* maximum disk lines */
297 static int maxmddlines = 999; /* maximum MDD lines */
298 static int maxlvmlines = 999; /* maximum LVM lines */
234299 static int maxintlines = 999; /* maximum interface lines */
235
236 static char *genhdr = "ATOP - %-18.18s "
237 "%s %s %12ld seconds elapsed\n";
238300
239301 static int cumusers(struct pstat *, struct pstat *, int);
240302 static int cumprocs(struct pstat *, struct pstat *, int);
303 static void limitedlines(void);
241304 static long getnumval(char *, long, int);
242305
243306
244307 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,
249312 };
313
314 extern proc_printpair ownprocs[];
250315
251316
252317 /*
255320 char
256321 generic_samp(time_t curtime, int nsecs,
257322 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)
259325 {
260326 static int callnr = 0;
261327
262328 register int i, curline, statline;
263329 int firstproc = 0, plistsz, alistsz, killpid, killsig;
264330 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];
267334 struct passwd *pwd;
268335 struct syscap syscap;
336
337 struct selection *cursel = &procsel;
338 static struct selection emptysel = {"", {USERSTUB, }, "", 0, { 0, }};
269339
270340 struct pstat *save_pstat = NULL;
271341 int save_nact = 0;
351421 showtype = MPROCARG;
352422 break;
353423
424 case MPROCOWN:
425 showtype = MPROCOWN;
426 break;
427
354428 case MAVGVAL:
355429 if (avgval)
356430 avgval=0;
381455 break;
382456
383457 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;
392460
393461 default:
394462 prusage("atop");
422490 cbreak();
423491 noecho();
424492
425 if (COLS < 80)
493 if (COLS < 30)
426494 {
427495 printw("Not enough columns "
428 "(need at least %d columns)\n", 80);
496 "(need at least %d columns)\n", 30);
429497 refresh();
430498 sleep(3);
431499 cleanstop(1);
457525 */
458526 totalcap(&syscap, sstat, pstat, nact);
459527
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
460556 /*
461557 ** loop in which the system resources and the list of active
462558 ** processes is shown; the loop will be preempted by receiving
483579 if (screen)
484580 attron(A_REVERSE);
485581
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);
487598
488599 if (screen)
600 {
489601 attroff(A_REVERSE);
602 attroff(A_REVERSE);
603 }
604 else
605 {
606 printg("\n");
607 }
490608
491609 /*
492610 ** print cumulative system- and user-time for all processes
493611 */
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;
514615
515616 /*
516617 ** print other lines of system-wide statistics
522623
523624 curline = prisyst(sstat, curline, nsecs, avgval,
524625 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 */
527634 if (screen && curline+2 > LINES)
528635 {
529 move(0, 0);
636 curline = 2;
637
638 move(curline, 0);
530639 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 }
541672 }
542673
543674 statline = curline;
675
676 if (screen)
677 move(curline, 0);
544678
545679 if (statmsg)
546680 {
547681 clrtoeol();
682 if (usecolors)
683 attron(COLOR_PAIR(COLORLOW));
684
548685 printg(statmsg);
686
687 if (usecolors)
688 attroff(COLOR_PAIR(COLORLOW));
689
549690 statmsg = NULL;
550691 }
551692 else
553694 if (flag&RRBOOT)
554695 {
555696 if (screen)
697 {
698 if (usecolors)
699 attron(COLOR_PAIR(COLORLOW));
556700 attron(A_BLINK);
557701
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 ***");
560711
561712 if (screen)
713 {
714 if (usecolors)
715 attroff(COLOR_PAIR(COLORLOW));
562716 attroff(A_BLINK);
717 }
563718 }
564719 }
565720
580735 */
581736 save_pstat = pstat;
582737 save_nact = nact;
738 cursel = &emptysel;
583739
584740 /*
585741 ** allocate space for new (temporary) list with
596752 case MCUMUSER:
597753 nact = cumusers(save_pstat, pstat, save_nact);
598754 break;
755
599756 case MCUMPROC:
600757 nact = cumprocs(save_pstat, pstat, save_nact);
601758 break;
602759 }
760
761 lastorder = 0; /* force new sort */
603762
604763 if (screen)
605764 plistsz = LINES-curline-2;
618777
619778 if (nact > 0 && plistsz > 0)
620779 {
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) {
625789 attron(A_REVERSE);
790 move(curline+1, 0);
791 }
626792
627793 /*
628794 ** print the header
644810 */
645811 priproc(pstat, firstproc, nact, curline+2,
646812 firstproc/plistsz+1, (nact-1)/plistsz+1,
647 showtype, curorder, &syscap, &procsel,
813 showtype, curorder, &syscap, cursel,
648814 nsecs, avgval);
649815 }
650816
658824 {
659825 free(pstat);
660826
661 pstat = save_pstat;
662 nact = save_nact;
827 pstat = save_pstat;
828 nact = save_nact;
829 cursel = &procsel;
663830 }
664831
665832 /*
673840 */
674841 if (paused)
675842 {
676 move(statline, 73);
843 move(statline, COLS-6);
677844 attron(A_BLINK);
678845 attron(A_REVERSE);
679846 printw("PAUSED");
729896
730897 return lastchar;
731898
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
732935 /*
733936 ** sort order automatically depending on
734937 ** most busy resource
786989 ** general figures per process
787990 */
788991 case MPROCGEN:
992 if (showtype ==MCUMUSER || showtype ==MCUMPROC)
993 lastorder = 0; /* force new sort */
994
789995 showtype = MPROCGEN;
790996
791997 if (showorder != MSORTAUTO)
7981004 ** memory-specific figures per process
7991005 */
8001006 case MPROCMEM:
1007 if (showtype ==MCUMUSER || showtype ==MCUMPROC)
1008 lastorder = 0; /* force new sort */
1009
8011010 showtype = MPROCMEM;
8021011
8031012 if (showorder != MSORTAUTO)
8161025 "available; request ignored!";
8171026 break;
8181027 }
1028
1029 if (showtype ==MCUMUSER || showtype ==MCUMPROC)
1030 lastorder = 0; /* force new sort */
1031
8191032 showtype = MPROCDSK;
8201033
8211034 if (showorder != MSORTAUTO)
8341047 "request ignored!";
8351048 break;
8361049 }
1050
1051 if (showtype ==MCUMUSER || showtype ==MCUMPROC)
1052 lastorder = 0; /* force new sort */
1053
8371054 showtype = MPROCNET;
8381055
8391056 if (showorder != MSORTAUTO)
8461063 ** various info per process
8471064 */
8481065 case MPROCVAR:
1066 if (showtype ==MCUMUSER || showtype ==MCUMPROC)
1067 lastorder = 0; /* force new sort */
1068
8491069 showtype = MPROCVAR;
8501070 firstproc = 0;
8511071 break;
8541074 ** command-line per process
8551075 */
8561076 case MPROCARG:
1077 if (showtype ==MCUMUSER || showtype ==MCUMPROC)
1078 lastorder = 0; /* force new sort */
1079
8571080 showtype = MPROCARG;
8581081 firstproc = 0;
8591082 break;
8601083
8611084 /*
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 /*
8621104 ** scheduling-values per process
8631105 */
8641106 case MPROCSCH:
1107 if (showtype ==MCUMUSER || showtype ==MCUMPROC)
1108 lastorder = 0; /* force new sort */
1109
8651110 showtype = MPROCSCH;
8661111
8671112 if (showorder != MSORTAUTO)
8771122 statmsg = "Consumption per user; use 'a' to "
8781123 "toggle between all/active processes";
8791124
1125 if (showtype != MCUMUSER)
1126 lastorder = 0; /* force new sort */
1127
8801128 showtype = MCUMUSER;
8811129 firstproc = 0;
8821130 break;
8871135 case MCUMPROC:
8881136 statmsg = "Consumption per program; use 'a' to "
8891137 "toggle between all/active processes";
1138
1139 if (showtype != MCUMPROC)
1140 lastorder = 0; /* force new sort */
8901141
8911142 showtype = MCUMPROC;
8921143 firstproc = 0;
12451496 "statistics (now %d): ",
12461497 maxcpulines, statline);
12471498
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
12481515 maxdsklines =
12491516 getnumval("Maximum lines for disk "
12501517 "statistics (now %d): ",
12771544 break;
12781545
12791546 /*
1280 ** handle forward
1547 ** handle redraw request
1548 */
1549 case MREDRAW:
1550 wclear(stdscr);
1551 break;
1552
1553 /*
1554 ** handle backward
12811555 */
12821556 case MLISTFW:
12831557 if (alistsz-firstproc > plistsz)
13311605 */
13321606 for (numusers=i=0; i < numprocs; i++, curprocs++)
13331607 {
1608 if (procsuppress(curprocs, &procsel))
1609 continue;
1610
13341611 if ( curusers->gen.ruid != curprocs->gen.ruid )
13351612 {
13361613 if (curusers->gen.pid)
13471624 curusers->cpu.utime += curprocs->cpu.utime;
13481625 curusers->cpu.stime += curprocs->cpu.stime;
13491626
1627 curusers->dsk.rsz += curprocs->dsk.rsz;
1628 curusers->dsk.wsz += curprocs->dsk.wsz;
1629
13501630 curusers->dsk.rio += curprocs->dsk.rio;
13511631 curusers->dsk.wio += curprocs->dsk.wio;
13521632
13911671 */
13921672 for (numprogs=i=0; i < numprocs; i++, curprocs++)
13931673 {
1674 if (procsuppress(curprocs, &procsel))
1675 continue;
1676
13941677 if ( strcmp(curprogs->gen.name, curprocs->gen.name) != 0)
13951678 {
13961679 if (curprogs->gen.pid)
14101693 curprogs->dsk.rio += curprocs->dsk.rio;
14111694 curprogs->dsk.wio += curprocs->dsk.wio;
14121695
1696 curprogs->dsk.rsz += curprocs->dsk.rsz;
1697 curprogs->dsk.wsz += curprocs->dsk.wsz;
1698
14131699 curprogs->net.tcpsnd += curprocs->net.tcpsnd;
14141700 curprogs->net.tcprcv += curprocs->net.tcprcv;
14151701 curprogs->net.udpsnd += curprocs->net.udpsnd;
14301716 numprogs++;
14311717
14321718 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;
14331729 }
14341730
14351731 /*
15111807 {"\t'%c' - various info (ppid, user/group, date/time, status, "
15121808 "exitcode)\n", MPROCVAR},
15131809 {"\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},
15141818 {"\n", ' '},
15151819 {"Accumulated figures:\n", ' '},
15161820 {"\t'%c' - total resource consumption per user\n", MCUMUSER},
15171821 {"\t'%c' - total resource consumption per program (i.e. same "
15181822 "process name)\n", MCUMPROC},
15191823 {"\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", ' '},
15401825 {"\t'%c' - focus on specific user name (regular expression)\n",
15411826 MSELUSER},
15421827 {"\t'%c' - focus on specific process name (regular expression)\n",
15431828 MSELPROC},
15441829 {"\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",
15461837 MALLPROC},
1547 {"\t'%c' - pause-button to freeze current sample (toggle)\n",
1548 MPAUSE},
15491838 {"\t'%c' - fixate on static range of header-lines (toggle)\n",
15501839 MSYSFIXED},
1551 {"\t'%c' - use colors to indicate high occupation (toggle)\n",
1840 {"\t'%c' - no colors to indicate high occupation (toggle)\n",
15521841 MCOLORS},
15531842 {"\t'%c' - show average-per-second i.s.o. total values (toggle)\n",
15541843 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", ' '},
15551859 {"\t'%c' - limited lines for per-cpu, disk and interface resources\n",
15561860 MSYSLIMIT},
15571861 {"\t'%c' - kill a process (i.e. send a signal)\n", MKILLPROC},
16611965 "date/time)\n", MPROCVAR);
16621966 printf("\t -%c show command-line per process\n",
16631967 MPROCARG);
1968 printf("\t -%c show own defined process-info\n",
1969 MPROCOWN);
16641970 printf("\t -%c show cumulated process-info per user\n",
16651971 MCUMUSER);
16661972 printf("\t -%c show cumulated process-info per program "
16811987 }
16821988
16831989 /*
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
16851991 */
16861992 void
1687 do_username(char *val)
1993 do_username(char *name, char *val)
16881994 {
16891995 struct passwd *pwd;
16901996
16992005 if (regcomp(&userregex, procsel.username, REG_NOSUB))
17002006 {
17012007 fprintf(stderr,
1702 ".atoprc: invalid regular expression %s\n",
1703 val);
2008 "atoprc - %s: invalid regular expression %s\n",
2009 name, val);
17042010 exit(1);
17052011 }
17062012
17322038 else
17332039 {
17342040 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);
17372043 exit(1);
17382044 }
17392045 }
17452051 }
17462052
17472053 void
1748 do_procname(char *val)
2054 do_procname(char *name, char *val)
17492055 {
17502056 strncpy(procsel.procname, val, sizeof procsel.procname -1);
17512057 procsel.procnamesz = strlen(procsel.procname);
17552061 if (regcomp(&procsel.procregex, procsel.procname, REG_NOSUB))
17562062 {
17572063 fprintf(stderr,
1758 ".atoprc: invalid regular expression %s\n",
1759 val);
2064 "atoprc - %s: invalid regular expression %s\n",
2065 name, val);
17602066 exit(1);
17612067 }
17622068 }
17632069 }
17642070
2071 extern int get_posval(char *name, char *val);
2072
2073
17652074 void
1766 do_maxcpu(char *val)
2075 do_maxcpu(char *name, char *val)
17672076 {
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);
17772078 }
17782079
17792080 void
1780 do_maxdisk(char *val)
2081 do_maxdisk(char *name, char *val)
17812082 {
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);
17912084 }
17922085
17932086 void
1794 do_maxintf(char *val)
2087 do_maxmdd(char *name, char *val)
17952088 {
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);
18052090 }
18062091
18072092 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)
18092106 {
18102107 int i;
18112108
18692166 showtype = MPROCARG;
18702167 break;
18712168
2169 case MPROCOWN:
2170 showtype = MPROCOWN;
2171 break;
2172
18722173 case MCUMUSER:
18732174 showtype = MCUMUSER;
18742175 break;
66 ** Include-file describing prototypes and structures for visualization
77 ** of counters.
88 ** ================================================================
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
1111 ** Date: July 2002
1212 **
1313 ** This program is free software; you can redistribute it and/or modify it
5757 #define MPROCSCH 's'
5858 #define MPROCVAR 'v'
5959 #define MPROCARG 'c'
60 #define MPROCOWN 'o'
6061
6162 #define MCUMUSER 'u'
6263 #define MCUMPROC 'p'
7879 #define MKILLPROC 'k'
7980 #define MLISTFW 0x06
8081 #define MLISTBW 0x02
82 #define MREDRAW 0x0c
8183 #define MINTERVAL 'i'
8284 #define MPAUSE 'z'
8385 #define MQUIT 'q'
8486 #define MRESET 'r'
8587 #define MSAMPNEXT 't'
8688 #define MSAMPPREV 'T'
89 #define MSAMPBRANCH 'b'
8790 #define MVERSION 'V'
8891 #define MAVGVAL '1'
8992 #define MHELP1 '?'
9396 ** general function prototypes
9497 */
9598 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);
97101
98102 void showgenproc(struct pstat *, double, int, int);
99103 void showmemproc(struct pstat *, double, int, int);
106110
107111 void printg (const char *, ...);
108112 int prisyst(struct sstat *, int, int, int, int, int, char *,
109 int, int, int);
113 int, int, int, int, int);
110114 int priproc(struct pstat *, int, int, int, int, int, char, char,
111115 struct syscap *, struct selection *, int, int);
112116 void priphead(int, int, char, char, char);
+1856
-2030
showlinux.c less more
66 ** This source-file contains the Linux-specific functions to calculate
77 ** figures to be visualized.
88 ** ==========================================================================
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
1112 ** 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
1218 ** --------------------------------------------------------------------------
13 ** Copyright (C) 2000-2007 Gerlof Langeveld
19 ** Copyright (C) 2009-2010 JC van Winkel
1420 **
1521 ** This program is free software; you can redistribute it and/or modify it
1622 ** under the terms of the GNU General Public License as published by the
2834 ** --------------------------------------------------------------------------
2935 **
3036 ** $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 **
31100 ** Revision 1.49 2008/03/06 08:38:28 gerlof
32101 ** Register/show ppid of a process.
33102 **
192261 **
193262 */
194263
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 $";
196265
197266 #include <sys/types.h>
198267 #include <sys/param.h>
216285 #include "photoproc.h"
217286 #include "photosyst.h"
218287 #include "showgeneric.h"
288 #include "showlinux.h"
219289
220290 /*
221291 ** critical percentages for occupation-percentage;
222292 ** these defaults can be overruled via the config-file
223293 */
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 */
232302
233303 /*
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 } }
235551 */
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
240622
241623 /*
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
246665
247666 /*
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 }
334707
335708 /*
336709 ** calculate the total consumption on system-level for the
339712 void
340713 totalcap(struct syscap *psc, struct sstat *sstat, struct pstat *pstat, int nact)
341714 {
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 }
383757 }
384758
385759 /*
386760 ** calculate cumulative system- and user-time for all active processes
387761 */
388762 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);
11881002 }
11891003
11901004 /*
11931007 void
11941008 priphead(int curlist, int totlist, char showtype, char showorder, char autosort)
11951009 {
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 }
12791267 }
12801268
12811269
12841272 */
12851273 int
12861274 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 }
13031379
13041380 /*
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))
14171385 continue;
14181386
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;
14651441 }
14661442
14671443
14681444 /*
14691445 ** print the system-wide statistics
14701446 */
1447 static void pridisklike(extraparam *, struct perdsk *, char *,
1448 char *, int, unsigned int *, int *, int, int);
14711449 int
14721450 prisyst(struct sstat *sstat, int curline, int nsecs, int avgval,
14731451 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 {
14841832 /*
1485 ** CPU statistics
1833 ** check if only processes of a particular user
1834 ** should be shown
14861835 */
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)
15011837 {
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;
15041849 }
15051850
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
16101851 /*
1611 ** other CPU-related statistics
1852 ** check if only processes with a particular name
1853 ** should be shown
16121854 */
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
19991862
20001863 /*
20011864 ** sort-functions
20031866 int
20041867 compcpu(const void *a, const void *b)
20051868 {
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);
20141877 }
20151878
20161879 int
20171880 compdsk(const void *a, const void *b)
20181881 {
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);
20271890 }
20281891
20291892 int
20301893 compmem(const void *a, const void *b)
20311894 {
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;
20381901 }
20391902
20401903 int
20411904 compnet(const void *a, const void *b)
20421905 {
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);
20591922 }
20601923
20611924 int
20621925 cpucompar(const void *a, const void *b)
20631926 {
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;
20721935 }
20731936
20741937 int
20751938 diskcompar(const void *a, const void *b)
20761939 {
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;
20831946 }
20841947
20851948 int
20861949 intfcompar(const void *a, const void *b)
20871950 {
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;
21452008 }
21462009
21472010 int
21482011 compusr(const void *a, const void *b)
21492012 {
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;
21562019 }
21572020
21582021 int
21592022 compnam(const void *a, const void *b)
21602023 {
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);
21652028 }
21662029
21672030 /*
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
21702032 */
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 };
66 ** This source-file contains various functions to a.o. format the
77 ** time-of-day, the cpu-time consumption and the memory-occupation.
88 ** ==========================================================================
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
1111 ** Date: November 1996
1212 ** LINUX-port: June 2000
1313 ** --------------------------------------------------------------------------
14 ** Copyright (C) 2000-2005 Gerlof Langeveld
14 ** Copyright (C) 2000-2010 Gerlof Langeveld
1515 **
1616 ** This program is free software; you can redistribute it and/or modify it
1717 ** under the terms of the GNU General Public License as published by the
2929 ** --------------------------------------------------------------------------
3030 **
3131 ** $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 **
3254 ** Revision 1.14 2007/02/13 10:32:47 gerlof
3355 ** Removal of external declarations.
3456 ** Removal of function getpagesz().
7597 **
7698 */
7799
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 $";
79101
80102 #include <sys/types.h>
81103 #include <sys/param.h>
240262 return strvalue;
241263 }
242264
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
243311 /*
244312 ** Function val2cpustr() converts a value (number of milliseconds)
245313 ** to an ascii-string of 7 positions in milliseconds or minute-seconds or
247315 */
248316 #define MAXMSEC (count_t)100000
249317 #define MAXSEC (count_t)60000
318 #define MAXMIN (count_t)60000
250319
251320 char *
252321 val2cpustr(count_t value, char *strvalue)
257326 }
258327 else
259328 {
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);
268337 }
269338 else
270339 {
273342 */
274343 value = (value + 30) / 60;
275344
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 }
277360 }
278361 }
279362
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 }
280391 return strvalue;
281392 }
282393
290401 #define ONEKBYTE 1024
291402 #define ONEMBYTE 1048576
292403 #define ONEGBYTE 1073741824L
404 #define ONETBYTE 1099511627776LL
293405
294406 #define MAXBYTE 1024
295407 #define MAXKBYTE ONEKBYTE*99999L
296408 #define MAXMBYTE ONEMBYTE*999L
409 #define MAXGBYTE ONEGBYTE*999LL
297410
298411 char *
299412 val2memstr(count_t value, char *strvalue, int pformat, int avgval, int nsecs)
337450 if (verifyval <= MAXMBYTE) /* mbytes ? */
338451 aformat = MBFORMAT;
339452 else
340 aformat = GBFORMAT;
453 if (verifyval <= MAXGBYTE) /* mbytes ? */
454 aformat = GBFORMAT;
455 else
456 aformat = TBFORMAT;
341457
342458 /*
343459 ** check if this is also the preferred format
365481 case GBFORMAT:
366482 sprintf(strvalue, "%*.1lfG%s",
367483 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);
368489 break;
369490
370491 default:
11 #include <stdio.h>
22 #include <string.h>
33
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 $";
55
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 $";
88
99 char *
1010 getstrvers(void)
1515 atopdate [sizeof atopdate - 3] = '\0';
1616
1717 snprintf(vers, sizeof vers,
18 "Version:%s -%s < gerlof@ATComputing.nl >",
18 "Version:%s -%s < gerlof.langeveld@atoptool.nl >",
1919 strchr(atoprevision, ' '),
2020 strchr(atopdate , ' '));
2121