Update upstream source from tag 'upstream/2.6.0'
Update to upstream version '2.6.0'
with Debian dir 655cc59884bc938fcf91ed098865544735b9eb17
Marc Haber
3 years ago
0 | commit 462cc2ba23dfb0e36d41c6ff2e04f4c67f8aa0bc | |
1 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
2 | Date: Mon Dec 21 20:38:17 2020 +0100 | |
3 | ||
4 | Set new process-related fields to zero during conversion | |
5 | ||
6 | M atopconvert.c | |
7 | ||
8 | commit 2b674f9d7c58f5e58d52b3416e3504f4c97741e2 | |
9 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
10 | Date: Mon Dec 21 19:58:56 2020 +0100 | |
11 | ||
12 | Added -Wno-stringop-truncation to CFLAGS. | |
13 | Avoid warnings about truncating command strings with gcc version 8. | |
14 | ||
15 | M Makefile | |
16 | ||
17 | commit 008f86b758514ac747b506a12a2196e4ba5e7ef1 | |
18 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
19 | Date: Sat Dec 19 16:38:18 2020 +0100 | |
20 | ||
21 | Avoid warnings with gcc 8 | |
22 | ||
23 | M atopacctd.c | |
24 | M rawlog.c | |
25 | M showsys.c | |
26 | ||
27 | commit 1bc1a03e5f88b5a11899876a752c3a83fbb671c4 | |
28 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
29 | Date: Sat Dec 19 15:06:35 2020 +0100 | |
30 | ||
31 | Typo corrected. | |
32 | ||
33 | M rpmspec/atop.specsystemd | |
34 | ||
35 | commit 6ca80e13b074523f46516c5fef6414968f06db9f | |
36 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
37 | Date: Sat Dec 19 14:58:56 2020 +0100 | |
38 | ||
39 | Update date in man pages. | |
40 | ||
41 | M man/atop.1 | |
42 | M man/atopacctd.8 | |
43 | M man/atopcat.1 | |
44 | M man/atopconvert.1 | |
45 | M man/atopgpud.8 | |
46 | M man/atoprc.5 | |
47 | M man/atopsar.1 | |
48 | ||
49 | commit 5f8e318def6882c866d3820cf608b6157afba767 | |
50 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
51 | Date: Sat Dec 19 14:48:45 2020 +0100 | |
52 | ||
53 | Prepare atop version 2.6 | |
54 | ||
55 | M version.h | |
56 | ||
57 | commit e22eefa8b1e8a2064787a8ac9a4e7647fc2ff247 | |
58 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
59 | Date: Sat Dec 19 14:45:24 2020 +0100 | |
60 | ||
61 | Support file format of atop 2.6 | |
62 | ||
63 | M atopconvert.c | |
64 | A prev/photoproc_26.h | |
65 | A prev/photosyst_26.h | |
66 | ||
67 | commit 8e2b5fbe5f853cabfe01f2be3860c84a1715d543 | |
68 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
69 | Date: Sat Dec 5 11:12:12 2020 +0100 | |
70 | ||
71 | Avoid error when stopping a stopped daemon (issue #139) | |
72 | The -f flag has been added to the rm command to avoid an error | |
73 | message when trying to stop a daemon that is not active. | |
74 | ||
75 | M atop.init | |
76 | M atopacct.init | |
77 | ||
78 | commit 23642fcdac1fca9bddcb8cbcc2a443a18b2416d3 | |
79 | Merge: af71985 ebc2fe4 | |
80 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
81 | Date: Sat Nov 21 13:00:25 2020 +0100 | |
82 | ||
83 | Merge branch 'threadsort' | |
84 | ||
85 | commit ebc2fe442aa5de14974a2ccd78ead83719196c1f | |
86 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
87 | Date: Sat Nov 21 12:56:58 2020 +0100 | |
88 | ||
89 | Sort threads per process in threadview (option 'Y') | |
90 | Threads per process (threadview) will be sorted according | |
91 | to the current sort criterium when the 'Y' option is active. | |
92 | ||
93 | M man/atop.1 | |
94 | M man/atoprc.5 | |
95 | M showgeneric.c | |
96 | M showgeneric.h | |
97 | ||
98 | commit af7198583b27800f541464617902fcb7cc637f8e | |
99 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
100 | Date: Sat Nov 7 11:16:43 2020 +0100 | |
101 | ||
102 | Explicitly refer to python3 instead of python | |
103 | Specifically needed for CentOS8 that only knows about python2 and python3. | |
104 | ||
105 | M atopgpud | |
106 | M rpmspec/atop.specsystemd | |
107 | ||
108 | commit 16aaba85e16b5e564362c9c6f109480632fd8313 | |
109 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
110 | Date: Sat Oct 24 12:27:43 2020 +0200 | |
111 | ||
112 | Additional fields for parseable output with label NET | |
113 | The most important (error) counters related to TCP and UDP | |
114 | have been added to the parseable output with label NET. | |
115 | Solves issue #98 | |
116 | ||
117 | M man/atop.1 | |
118 | M parseable.c | |
119 | ||
120 | commit 14c0e5c751f1cd00b7191a5a355199daf11e0ef7 | |
121 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
122 | Date: Sat Oct 24 11:27:35 2020 +0200 | |
123 | ||
124 | Correct man page of atop: parseable output for label PRD | |
125 | The obsoleted value 'n' (one but last value) was not described | |
126 | in the man page. This has been added now. Solves issue #136 | |
127 | ||
128 | M man/atop.1 | |
129 | ||
130 | commit 7760d5902451abbb52e45222b07af7667a806163 | |
131 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
132 | Date: Sat Oct 24 11:06:35 2020 +0200 | |
133 | ||
134 | Issue garbage collection, even when system clock modified | |
135 | Even when the system clock (epoch) is decreased, garbare collection | |
136 | should continue to avoid that too many shadow files will occupy | |
137 | disk space. Solves issue #132 | |
138 | ||
139 | M atopacctd.c | |
140 | ||
141 | commit 25c6d641e3b6c4f424003d70b40b0239c0c2b10b | |
142 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
143 | Date: Sat Oct 3 12:32:17 2020 +0200 | |
144 | ||
145 | Size of swap cache added to SWP row (issue #117) | |
146 | ||
147 | M deviate.c | |
148 | M man/atop.1 | |
149 | M parseable.c | |
150 | M photosyst.c | |
151 | M photosyst.h | |
152 | M showlinux.c | |
153 | M showlinux.h | |
154 | M showsys.c | |
155 | ||
156 | commit 90fdd81607461095d7b42525d4924c18b513cd06 | |
157 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
158 | Date: Sat Oct 3 11:25:29 2020 +0200 | |
159 | ||
160 | Show PPID for terminated processes (solves issue #120). | |
161 | When the format of the process accounting record provides the PPID, | |
162 | it should also be shown in the various info (key 'v'). | |
163 | ||
164 | M showprocs.c | |
165 | ||
166 | commit 27dbe4e17634e58fdca5930e8cf2c2e06cd40821 | |
167 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
168 | Date: Sat Aug 29 11:50:17 2020 +0200 | |
169 | ||
170 | When atopacctd restarts, it recreates the shadow directory | |
171 | When atopacctd is killed and restarted afterwards, the shadow directory | |
172 | /var/run/pacct_shadow.d still exists. The old directory will be renamed | |
173 | to a unique name (containing the PID of the running atopacctd) because | |
174 | files from this directory might still be opened by running atop processes. | |
175 | After that, a new directory will be created without intervention. | |
176 | Solved issue #121 | |
177 | ||
178 | M atopacctd.c | |
179 | ||
180 | commit 8c6b556a60048beafa40547dee1eff90ed728e79 | |
181 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
182 | Date: Tue Aug 11 07:58:45 2020 +0200 | |
183 | ||
184 | Skip empty lines in atoprc file | |
185 | ||
186 | M atop.c | |
187 | M atopsar.c | |
188 | M various.c | |
189 | ||
190 | commit 4a215076767b4198a87dace45bdfd976d1da9c9f | |
191 | Merge: 678431f 93877ad | |
192 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
193 | Date: Tue Aug 11 07:37:35 2020 +0200 | |
194 | ||
195 | Merge pull request #125 from bytedance/oom_score_fixed_adj | |
196 | ||
197 | Try to set the highest OOM priority for atop | |
198 | ||
199 | commit 93877ad6dc5c80b97fc91fc1f8df20c064390895 | |
200 | Author: zhenwei pi <pizhenwei@bytedance.com> | |
201 | Date: Tue Aug 11 10:08:37 2020 +0800 | |
202 | ||
203 | Try to set the highest OOM priority for atop | |
204 | ||
205 | We usually expect that atop has highest OOM priority. when the system | |
206 | runs out of memory, atop still could record necessary infomation. | |
207 | Then we are able to analyze the OOM situation afterwards. | |
208 | ||
209 | The orignal verion of this feature: read config from atoprc, then | |
210 | apply to atop process. But Gerlof considers that just trying to set | |
211 | the highest priority is better. So rewrite this as Gerlof's advise. | |
212 | ||
213 | Signed-off-by: zhenwei pi <pizhenwei@bytedance.com> | |
214 | ||
215 | M atop.c | |
216 | M atop.h | |
217 | M various.c | |
218 | ||
219 | commit 678431f34ad49ef6ade6652eb0bb39f07dc42e6d | |
220 | Merge: dd0fb8a 67ab9e3 | |
221 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
222 | Date: Mon Aug 10 20:49:35 2020 +0200 | |
223 | ||
224 | Merge pull request #124 from bytedance/fix-prusage | |
225 | ||
226 | Fix prusage segmentation fault when vis.show_usage is null | |
227 | ||
228 | commit 67ab9e3d6db1c39f5e5816690995e4503d99ec29 | |
229 | Author: Fei Li <lifei.shirley@bytedance.com> | |
230 | Date: Wed Aug 14 20:15:30 2019 +0800 | |
231 | ||
232 | Fix prusage segmentation fault when vis.show_usage is null | |
233 | ||
234 | Signed-off-by: Fei Li <lifei.shirley@bytedance.com> | |
235 | ||
236 | M atop.c | |
237 | ||
238 | commit dd0fb8a41afcd9cc03323df33340a40cc6dba3ea | |
239 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
240 | Date: Fri Jul 3 21:16:17 2020 +0200 | |
241 | ||
242 | Add WCHAN to parseable output (PRC). | |
243 | ||
244 | M man/atop.1 | |
245 | M parseable.c | |
246 | ||
247 | commit 4739704df2449766ac1ac3f2b74f3dc5f1904709 | |
248 | Merge: 9997130 f5742ac | |
249 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
250 | Date: Fri Jul 3 20:34:40 2020 +0200 | |
251 | ||
252 | Merge branch 'wchan' | |
253 | ||
254 | commit f5742ac88ef2e554890bd9a418a403f1bc6b3912 | |
255 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
256 | Date: Fri Jul 3 20:26:52 2020 +0200 | |
257 | ||
258 | Maintain WCHAN per thread | |
259 | When the 'W' key or the -W flag is used, the wait channel will be | |
260 | determined for every sleeping thread. Gathering of this value is optinal | |
261 | because the determination of the WCHAN string is relatively CPU-intensive | |
262 | for atop. | |
263 | The WCHAN is shown when selecting the scheduling statistics (key 's'). | |
264 | ||
265 | M atop.c | |
266 | M atop.h | |
267 | M deviate.c | |
268 | M man/atop.1 | |
269 | M photoproc.c | |
270 | M photoproc.h | |
271 | M showgeneric.c | |
272 | M showgeneric.h | |
273 | M showlinux.c | |
274 | M showlinux.h | |
275 | M showprocs.c | |
276 | ||
277 | commit 99971301394dce410976de972b9536e6db03760e | |
278 | Merge: ef62300 ed1f6d3 | |
279 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
280 | Date: Thu Jul 2 16:22:41 2020 +0200 | |
281 | ||
282 | Merge branch 'bytedance-schedstat' | |
283 | ||
284 | commit ed1f6d30bd359f4d264edfde4e65bcafb16ad32b | |
285 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
286 | Date: Thu Jul 2 16:17:30 2020 +0200 | |
287 | ||
288 | Show runqueue delay for process and threads | |
289 | For every process (cumulated) and thread the time spent waiting on | |
290 | a runqueue is shown (RDELAY). | |
291 | ||
292 | M deviate.c | |
293 | M man/atop.1 | |
294 | M parseable.c | |
295 | M photoproc.c | |
296 | M photoproc.h | |
297 | M showlinux.c | |
298 | M showprocs.c | |
299 | ||
300 | commit 2119fe754f6a75e444c1c48d7303a6754210efbe | |
301 | Merge: ef62300 0ffbcd9 | |
302 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
303 | Date: Thu Jul 2 14:08:37 2020 +0200 | |
304 | ||
305 | Merge branch 'schedstat' of git://github.com/bytedance/atop into bytedance-schedstat | |
306 | ||
307 | commit ef62300ffa08ca978ed6d1bfe7eb65fb242aa873 | |
308 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
309 | Date: Mon Jun 15 14:03:49 2020 +0200 | |
310 | ||
311 | Occasional segmentation fault when atop is combined with netatop | |
312 | Even when the number of exited processes via netatop was zero, still | |
313 | a malloc was issued. In certain circumstances a structure could have | |
314 | been stored at the address that was returned by malloc, resulting in | |
315 | a segmentation fault on a subsequent malloc. | |
316 | ||
317 | M netatopif.c | |
318 | ||
319 | commit 7838d54e81070eedfe5c7362fcca9875fa8d81c5 | |
320 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
321 | Date: Mon Jun 15 13:58:47 2020 +0200 | |
322 | ||
323 | Prevent race condition when last atop stops and new one is started | |
324 | When the last atop incarnation terminates, the atopacctd issues a | |
325 | cleanup of all accounting files and writes a new'current' file. | |
326 | When a new atop is started meanwhile, a race condition might be | |
327 | introduced, which is prevented by a semaphore. | |
328 | ||
329 | M acctproc.c | |
330 | M atopacctd.c | |
331 | ||
332 | commit 19b0d7c12d708d788768c14b45a9ec1114334814 | |
333 | Merge: ebf956c eba520e | |
334 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
335 | Date: Sat Jun 6 11:54:48 2020 +0200 | |
336 | ||
337 | Merge pull request #110 from xixiliguo/atop-rotate | |
338 | ||
339 | disable atop-rotate.timer when uninstall | |
340 | ||
341 | commit 0ffbcd91a346f6e3ac7a22af1b49dd956f00f0c9 | |
342 | Author: zhenwei pi <pizhenwei@bytedance.com> | |
343 | Date: Fri May 22 19:54:09 2020 +0800 | |
344 | ||
345 | Support time spent waiting on a runqueue collection | |
346 | ||
347 | Collect run delay information from /proc/<pid>/schedstat, and show | |
348 | in schedproc page. | |
349 | ||
350 | It's helpful for latency spike trouble shooting case. | |
351 | ||
352 | Signed-off-by: zhenwei pi <pizhenwei@bytedance.com> | |
353 | ||
354 | M deviate.c | |
355 | M photoproc.c | |
356 | M photoproc.h | |
357 | M showlinux.c | |
358 | M showlinux.h | |
359 | M showprocs.c | |
360 | ||
361 | commit ebf956cc28aef6e818e32b920e8e2e73577777f8 | |
362 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
363 | Date: Sat May 16 13:00:03 2020 +0200 | |
364 | ||
365 | Show ARC size for ZFSonlinux | |
366 | The new counter `zfarc` is introduced for memory analysis on system level | |
367 | showing the current size of the ARC (cache) for ZFSonlinux. | |
368 | ||
369 | M deviate.c | |
370 | M man/atop.1 | |
371 | M parseable.c | |
372 | M photosyst.c | |
373 | M photosyst.h | |
374 | M showlinux.c | |
375 | M showlinux.h | |
376 | M showsys.c | |
377 | ||
378 | commit 62961a0190e8844f936ae52162127c58a87d6392 | |
379 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
380 | Date: Tue Apr 28 16:02:13 2020 +0200 | |
381 | ||
382 | Add 'New Process' indicator to parseable output. | |
383 | A new field is added to the output line of -PPRG indicating if the | |
384 | process is newly started during the interval. | |
385 | ||
386 | M man/atop.1 | |
387 | M parseable.c | |
388 | ||
389 | commit 3ddaaa3324a1e2ee67b6c4d85f38c13ce6139d90 | |
390 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
391 | Date: Tue Apr 28 14:59:41 2020 +0200 | |
392 | ||
393 | Correct handling of locale. | |
394 | ||
395 | M README | |
396 | M showgeneric.c | |
397 | ||
398 | commit eba520edfdcc4ddf6bd912447bba57ce13f099db | |
399 | Author: root <root@localhost.localdomain> | |
400 | Date: Wed Apr 22 19:35:40 2020 +0800 | |
401 | ||
402 | disable atop-rotate.timer when uninstall | |
403 | ||
404 | M rpmspec/atop.specsystemd | |
405 | ||
406 | commit 62dc8de0b9a5001268a75950d7d2594d56c4db4a | |
407 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
408 | Date: Sat Mar 7 14:51:00 2020 +0100 | |
409 | ||
410 | Modified locale to "C" to avoid failing sscanf for floats | |
411 | ||
412 | M showgeneric.c | |
413 | ||
414 | commit d87e22b6815d4036dae5f14bab6dca54f9c34e59 | |
415 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
416 | Date: Sat Mar 7 14:50:21 2020 +0100 | |
417 | ||
418 | Modified /usr/lib/systemd/system to /lib/systemd/system | |
419 | ||
420 | M Makefile | |
421 | ||
422 | commit ff551421bff21c272de43e02b8179144f17b7fc9 | |
423 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
424 | Date: Fri Mar 6 07:51:00 2020 +0100 | |
425 | ||
426 | Atopcat: add flags -d (dryrun) and -v (verbose) | |
427 | ||
428 | M atopcat.c | |
429 | M man/atopcat.1 | |
430 | ||
431 | commit 2990fd589f5764fafe3abef2fb2e43002070562f | |
432 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
433 | Date: Mon Feb 24 19:10:09 2020 +0100 | |
434 | ||
435 | Allow forward branches when reading raw data from a pipe. | |
436 | ||
437 | M man/atop.1 | |
438 | M rawlog.c | |
439 | ||
440 | commit e86f32d200fa02dcaaf8bac066160768b48d7d68 | |
441 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
442 | Date: Mon Feb 24 18:19:46 2020 +0100 | |
443 | ||
444 | Introduction of command 'atopcat' to concatenate rawlog files | |
445 | With the command 'atopcat' the contents of rawlog files can be | |
446 | concatenated and written to stdout. The output of this command | |
447 | can be redirected to a file or transferred via a pipe to atop or | |
448 | atopsar. In this way weekly, monthly, ... reports or extractions | |
449 | can be created in an easy way. | |
450 | ||
451 | M .gitignore | |
452 | M Makefile | |
453 | A atopcat.c | |
454 | M atopconvert.c | |
455 | A man/atopcat.1 | |
456 | M man/atopconvert.1 | |
457 | A rawlog.h | |
458 | M rpmspec/atop.specsystemd | |
459 | M rpmspec/atop.specsysv | |
460 | ||
461 | commit 186ab18f0cf66252db7dbd7187c9efb55f4f4188 | |
462 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
463 | Date: Mon Feb 24 18:10:40 2020 +0100 | |
464 | ||
465 | Support reading raw log from pipe with option '-r -' | |
466 | Atop and atopsar can read raw log data from a pipe via stdin | |
467 | when the option '-r -' is used. Since a seek is not possible on a | |
468 | pipe, no rewind is possible nor viewing of previous samples. | |
469 | ||
470 | M atop.c | |
471 | M atopsar.c | |
472 | M man/atop.1 | |
473 | M man/atopsar.1 | |
474 | M rawlog.c | |
475 | M showgeneric.c | |
476 | ||
477 | commit c43dc50eee1c9265340c8531db80a83ec1a06b84 | |
478 | Merge: bc2e412 115feba | |
479 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
480 | Date: Sat Feb 22 17:01:46 2020 +0100 | |
481 | ||
482 | Merge branch 'multiday' | |
483 | ||
484 | commit 115febabe00a562bb40d11da697ff1e452281fce | |
485 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
486 | Date: Sat Feb 22 16:57:47 2020 +0100 | |
487 | ||
488 | Support of logfiles that span multiple days | |
489 | The time specification to define the begin time (-b flag) and | |
490 | end time (-e flag) of both atop and atopsar is [YYYYMMDD]hhmm now. | |
491 | This also applies to the branch key ('b') when using atop interactively. | |
492 | ||
493 | M atop.c | |
494 | M atop.h | |
495 | M atopsar.c | |
496 | M man/atop.1 | |
497 | M man/atopsar.1 | |
498 | M netatopif.c | |
499 | M rawlog.c | |
500 | M showgeneric.c | |
501 | M various.c | |
502 | ||
503 | commit bc2e412791bf5b1d206a362ec1f9ce9f23beac42 | |
504 | Merge: 8b9cd3f f202a31 | |
505 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
506 | Date: Sat Feb 22 13:24:20 2020 +0100 | |
507 | ||
508 | Merge pull request #100 from zlandau/loadavg_crash | |
509 | ||
510 | Fix crash when system reports huge load averages | |
511 | ||
512 | commit f202a317994f563a25a8c64a38ba4445a1d4606b | |
513 | Author: Zachary P. Landau <zlandau@jellofund.net> | |
514 | Date: Sun Feb 16 12:33:30 2020 -0800 | |
515 | ||
516 | Fix crash when system reports huge load averages | |
517 | ||
518 | The load average reporting functions in showsys.c use static buffer | |
519 | sizes. When the load averages on a machine are very large, this causes | |
520 | the writes to extend past the buffer. With this commit, if a number is | |
521 | too large then we just show '>NNNNNN'. I'm not sure if this is the best | |
522 | choice, so I'm open to other ideas. | |
523 | ||
524 | This is what the output looks like when we exceed the maximums: | |
525 | ||
526 | CPL | avg1 >999999 | avg5 >999999 | avg15 >99999 | csw 103117e3 | intr 88296e3 | | |
527 | ||
528 | Note that this was triggered from a kernel that is reporting clearly | |
529 | inaccurate numbers: | |
530 | ||
531 | $ cat /proc/loadavg | |
532 | 1.25 2.40 368567045.47 1/589 53576 | |
533 | ||
534 | But regardless, crashing is no fun. | |
535 | ||
536 | For future reference, I narrowed down the issue by building with | |
537 | -fsanitize=address. For example: | |
538 | ||
539 | ==55396==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55c527d6f14f at pc 0x7f4729942df9 bp 0x7ffe1fd30710 sp 0x7ffe1fd2fea0 | |
540 | WRITE of size 10 at 0x55c527d6f14f thread T0 | |
541 | #0 0x7f4729942df8 in __interceptor_vsprintf /build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1627 | |
542 | #1 0x7f47299432cf in __interceptor_sprintf /build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1670 | |
543 | #2 0x55c527d1c167 in sysprt_CPLAVG15 (/home/kapheine/projects/atop/atop+0x74167) | |
544 | #3 0x55c527d2087a in showsysline (/home/kapheine/projects/atop/atop+0x7887a) | |
545 | #4 0x55c527d1471f in prisyst (/home/kapheine/projects/atop/atop+0x6c71f) | |
546 | #5 0x55c527d090ff in generic_samp (/home/kapheine/projects/atop/atop+0x610ff) | |
547 | #6 0x55c527ce17c9 in main (/home/kapheine/projects/atop/atop+0x397c9) | |
548 | #7 0x7f472952a022 in __libc_start_main (/usr/lib/libc.so.6+0x27022) | |
549 | #8 0x55c527ce266d in _start (/home/kapheine/projects/atop/atop+0x3a66d) | |
550 | ||
551 | 0x55c527d6f14f is located 49 bytes to the left of global variable 'buf' defined in 'showsys.c:981:54' (0x55c527d6f180) of size 15 | |
552 | 0x55c527d6f14f is located 0 bytes to the right of global variable 'buf' defined in 'showsys.c:1000:54' (0x55c527d6f140) of size 15 | |
553 | ||
554 | M showsys.c | |
555 | ||
556 | commit 8b9cd3f8225d7d17828e42dd73f1e8b47176f11a | |
557 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
558 | Date: Sat Feb 15 12:00:45 2020 +0100 | |
559 | ||
560 | Wrong checks on return values of write and pread syscalls | |
561 | ||
562 | M atop.c | |
563 | M atop.h | |
564 | M atopacctd.c | |
565 | M atopsar.c | |
566 | M rawlog.c | |
567 | M showgeneric.c | |
568 | M various.c | |
569 | ||
570 | commit 7bbfd140d2511cb9046905a51096376d7d9b0669 | |
571 | Merge: d4769ab ffc8ba8 | |
572 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
573 | Date: Sat Feb 15 10:20:54 2020 +0100 | |
574 | ||
575 | Merge pull request #50 from Saur2000/master | |
576 | ||
577 | atop.daily, atop.init, atop-pm.sh, mkdate: Avoid using bash | |
578 | ||
579 | commit d4769ab3882d1d74219564f415823e8d29877358 | |
580 | Merge: dfa87a6 788c388 | |
581 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
582 | Date: Sat Feb 15 10:13:55 2020 +0100 | |
583 | ||
584 | Merge pull request #99 from bytedance/logopts-man | |
585 | ||
586 | Update man about default LOGOPT '-R' | |
587 | ||
588 | commit 788c3883f5e1567bba572da92c17facd6332e898 | |
589 | Author: zhenwei pi <pizhenwei@bytedance.com> | |
590 | Date: Tue Feb 11 09:55:13 2020 +0800 | |
591 | ||
592 | Update man about default LOGOPT '-R' | |
593 | ||
594 | Since 604b563a223130d9bcce3d3358537a6c5ce05e7a, atop has removed | |
595 | default LOGOPT '-R', so update man page here. | |
596 | ||
597 | Signed-off-by: zhenwei pi <pizhenwei@bytedance.com> | |
598 | ||
599 | M man/atop.1 | |
600 | ||
601 | commit dfa87a64a68acea86a470063c02be044fbfa518c | |
602 | Merge: 14900df ad4b3c8 | |
603 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
604 | Date: Sat Feb 8 10:25:31 2020 +0100 | |
605 | ||
606 | Merge branch 'rpungartnik-StringManipulation' | |
607 | ||
608 | commit ad4b3c8cd40b01a68f7e6bdc6bacfcf1117db1ae | |
609 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
610 | Date: Sat Feb 8 10:22:40 2020 +0100 | |
611 | ||
612 | Avoid negative values to cause memory overflow, but do not set to 0. | |
613 | ||
614 | M photosyst.c | |
615 | M showsys.c | |
616 | ||
617 | commit 2292e0b5b9327eeae2c1078f0e266d1febef7645 | |
618 | Merge: 14900df e889c66 | |
619 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
620 | Date: Sat Feb 8 10:00:09 2020 +0100 | |
621 | ||
622 | Merge branch 'StringManipulation' of git://github.com/rpungartnik/atop into rpungartnik-StringManipulation | |
623 | ||
624 | commit 14900df5b75bf4d97e0c47caa8ea08f9386230e1 | |
625 | Merge: b3356e5 b2f804c | |
626 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
627 | Date: Sat Jan 18 12:07:42 2020 +0100 | |
628 | ||
629 | Merge branch 'rpungartnik-ResultCheck' | |
630 | ||
631 | commit b2f804c8b49501dc2d8e941bbdfe47e4ec2203e3 | |
632 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
633 | Date: Sat Jan 18 12:05:06 2020 +0100 | |
634 | ||
635 | Avoid compiler warnings due to unused results | |
636 | Compiler warnings are given for return values of system calls | |
637 | that are not verified, even if these system calls are allowed | |
638 | to fail. | |
639 | ||
640 | M atopacctd.c | |
641 | M photosyst.c | |
642 | M rawlog.c | |
643 | M various.c | |
644 | ||
645 | commit 5a39c743c6094c3c4e141dfc7a109cecb46c0944 | |
646 | Merge: b3356e5 2fd755b | |
647 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
648 | Date: Sat Jan 18 11:49:13 2020 +0100 | |
649 | ||
650 | Merge branch 'ResultCheck' of git://github.com/rpungartnik/atop into rpungartnik-ResultCheck | |
651 | ||
652 | commit b3356e5c46d52f23d299b885de8095add0008ac2 | |
653 | Merge: 95e2525 68b2a90 | |
654 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
655 | Date: Sat Jan 18 11:41:14 2020 +0100 | |
656 | ||
657 | Merge branch 'master' of github.com:Atoptool/atop | |
658 | ||
659 | commit 95e252560e435f13fe4d8055de7cbdb1b6a164b5 | |
660 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
661 | Date: Sat Jan 18 11:39:31 2020 +0100 | |
662 | ||
663 | Datatype double changed to long for percentage PSI percentage. | |
664 | ||
665 | M showsys.c | |
666 | ||
667 | commit 68b2a9008ef2aa72e4badd1eb2a0107555f404aa | |
668 | Merge: 461ebee 604b563 | |
669 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
670 | Date: Tue Jan 14 10:32:37 2020 +0100 | |
671 | ||
672 | Merge pull request #97 from bytedance/logopts | |
673 | ||
674 | Drop '-R' in default log option | |
675 | ||
676 | commit 604b563a223130d9bcce3d3358537a6c5ce05e7a | |
677 | Author: zhenwei pi <pizhenwei@bytedance.com> | |
678 | Date: Mon Jan 13 10:14:08 2020 +0800 | |
679 | ||
680 | Drop '-R' in default log option | |
681 | ||
682 | '-R' option is implemented by reading '/proc/PID/smaps' or | |
683 | '/proc/PID/smaps_rollup'. During atop reading smaps/smaps_rollup, | |
684 | atop needs hold the task->mm->mmap_sem, reference linux source code, | |
685 | ||
686 | file linux/fs/proc/task_mmu.c | |
687 | static void *m_start(struct seq_file *m, loff_t *ppos) | |
688 | { | |
689 | ... | |
690 | down_read(&mm->mmap_sem); | |
691 | ... | |
692 | } | |
693 | ||
694 | then atop walks the page table of target process and release lock. | |
695 | ||
696 | The target also needs hold the lock when mmap/mumamp/page fault | |
697 | handling. The lock race will hurt the performence of the target | |
698 | process. A typical case is the latency spike of large size memory | |
699 | of redis. | |
700 | ||
701 | Signed-off-by: zhenwei pi <pizhenwei@bytedance.com> | |
702 | ||
703 | M atop.daily | |
704 | M atop.default | |
705 | M atop.service | |
706 | ||
707 | commit 461ebeecd1e5018d9b23ab6bef466232107f6833 | |
708 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
709 | Date: Sat Jan 11 10:38:04 2020 +0100 | |
710 | ||
711 | Correct handling of atopsarflags from atoprc file | |
712 | The default setting for the options of atopsar was not correct | |
713 | (wrong calling parameter was used). Issue solved. | |
714 | ||
715 | M atopsar.c | |
716 | ||
717 | commit e889c66fbe1d0b7ae38fbcbaa46cea749257f486 | |
718 | Author: Roberto <rpungartnik@gmail.com> | |
719 | Date: Thu Jan 9 08:54:28 2020 -0300 | |
720 | ||
721 | Compilation warnings - String Manipulation | |
722 | ||
723 | Changed the size of path variable using system constant | |
724 | Implemented data size check during message creation to avoid buffer overflow and problems when displaying messages. | |
725 | ||
726 | Now negative numbers are presented as 0(zero) and to big numbers are presented as maximum value(ex.9999). This will avoid problems in case of invalid or unexpected data. | |
727 | ||
728 | This was tested compiling in 32 and 64 bits. | |
729 | ||
730 | M photosyst.c | |
731 | M showsys.c | |
732 | ||
733 | commit cd2c98dfc8f73b3c44c1df0743cf2f43f6ef7ef8 | |
734 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
735 | Date: Thu Jan 9 11:41:17 2020 +0100 | |
736 | ||
737 | Show virtually locked memory per process | |
738 | Per process the value LOCKSZ is maintained to show the amount of memory | |
739 | being locked by the process (virtually). This value is shown for individual | |
740 | processes (key 'm') but also as accumulated value for keys 'p', 'u' and 'j'. | |
741 | ||
742 | M deviate.c | |
743 | M man/atop.1 | |
744 | M parseable.c | |
745 | M photoproc.c | |
746 | M photoproc.h | |
747 | M showgeneric.c | |
748 | M showlinux.c | |
749 | M showlinux.h | |
750 | M showprocs.c | |
751 | ||
752 | commit e0a96a343e1b476cccd32a025d70421bdc754c2f | |
753 | Merge: 0878ae4 4b0cc91 | |
754 | Author: Roberto <rpungartnik@users.noreply.github.com> | |
755 | Date: Mon Jan 6 10:13:58 2020 -0300 | |
756 | ||
757 | Merge pull request #1 from Atoptool/master | |
758 | ||
759 | update | |
760 | ||
761 | commit 4b0cc9133d9e8772a29f8a910ee48615577efd66 | |
762 | Merge: bcbe687 91e0340 | |
763 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
764 | Date: Sat Jan 4 10:53:37 2020 +0100 | |
765 | ||
766 | Merge branch 'master' of github.com:Atoptool/atop | |
767 | ||
768 | commit bcbe68712009663f3fe54214c0fe25dc07e668b5 | |
769 | Merge: 7f4fa0f 5e14308 | |
770 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
771 | Date: Sat Jan 4 10:52:50 2020 +0100 | |
772 | ||
773 | Merge branch 'rpungartnik-CompilationFlags' | |
774 | ||
775 | commit 5e14308568bf90d538fe9a0235df8341fe068d7b | |
776 | Merge: 7f4fa0f 1d22fd8 | |
777 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
778 | Date: Sat Jan 4 10:51:15 2020 +0100 | |
779 | ||
780 | Remove explicit compolations from Makefile (issue #91) | |
781 | ||
782 | commit 91e0340e704b4334df4c9d1e9dda9b0adb7399e8 | |
783 | Merge: 7f4fa0f 95e5d72 | |
784 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
785 | Date: Sat Jan 4 10:34:30 2020 +0100 | |
786 | ||
787 | Merge pull request #90 from rpungartnik/CompilationWarnings | |
788 | ||
789 | Solved some compilation warnings | |
790 | ||
791 | commit 7f4fa0f7fe3a20e0ba0e348529e1f94613d36d99 | |
792 | Merge: 0878ae4 fa101b4 | |
793 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
794 | Date: Sat Jan 4 10:26:09 2020 +0100 | |
795 | ||
796 | Merge branch 'db48x-avio-time-scaling' | |
797 | ||
798 | commit fa101b4dc5d3729d84466f708c29959570bd0919 | |
799 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
800 | Date: Sat Jan 4 10:20:50 2020 +0100 | |
801 | ||
802 | Report disk average I/O in microseconds/nanoseconds (issue #89) | |
803 | Very fast drives might show 0.0 ms as the average I/O time. Therefore, | |
804 | average I/O unit will be adapted to the smallest possible unit. | |
805 | Due to the use of microseconds (abbreviates to a multibyte character), | |
806 | the ncursesw library is used instead of ncurses library (the latter | |
807 | calculates the number of characters in a wrong way). | |
808 | ||
809 | M Makefile | |
810 | M atopsar.c | |
811 | M showgeneric.c | |
812 | M showsys.c | |
813 | ||
814 | commit e47d9f7dbf0ffcd12ce2540097fa2fa87d8ab718 | |
815 | Merge: 0878ae4 c20cbce | |
816 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
817 | Date: Sat Jan 4 09:30:20 2020 +0100 | |
818 | ||
819 | Merge branch 'avio-time-scaling' of git://github.com/db48x/atop into db48x-avio-time-scaling | |
820 | ||
821 | commit 2fd755b83103a2cdda8c4bdd1765e2ac3a75a418 | |
822 | Author: Roberto <rpungartnik@gmail.com> | |
823 | Date: Fri Jan 3 22:31:07 2020 -0300 | |
824 | ||
825 | Compilation Warning - Unused Result on system calls | |
826 | ||
827 | Newer versions of gcc enforce to check the result of system calls | |
828 | ||
829 | M atopacctd.c | |
830 | M photosyst.c | |
831 | M rawlog.c | |
832 | M various.c | |
833 | ||
834 | commit 95e5d72c5a311c356994ec0f4743095bbf8548cc | |
835 | Author: Roberto <rpungartnik@gmail.com> | |
836 | Date: Thu Jan 2 21:53:15 2020 -0300 | |
837 | ||
838 | Solved some compilation warnings | |
839 | ||
840 | Resolved warning from unused rcsid variable | |
841 | Resolved "misleading indentation" warnings | |
842 | ||
843 | No changes in behaviour | |
844 | ||
845 | No changes in behaviour | |
846 | ||
847 | M atop.c | |
848 | M atopsar.c | |
849 | M deviate.c | |
850 | M photoproc.c | |
851 | M photosyst.c | |
852 | M showgeneric.c | |
853 | M showlinux.c | |
854 | M showprocs.c | |
855 | M showsys.c | |
856 | ||
857 | commit 1d22fd8f161e8db198f0f44fb3ce498d04f2f21b | |
858 | Author: Roberto <rpungartnik@gmail.com> | |
859 | Date: Thu Jan 2 20:56:32 2020 -0300 | |
860 | ||
861 | Use CFLAGS and LDFLAGS to all files | |
862 | ||
863 | M Makefile | |
864 | ||
865 | commit 0878ae435d65d2fdcf73a96bd8502fe754ea9af7 | |
866 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
867 | Date: Tue Dec 31 12:44:26 2019 +0100 | |
868 | ||
869 | Show PSI pressure percentage during interval (issue #72) | |
870 | Atop and atopsar show the pressure percentage during the interval | |
871 | as most important percentage now. Atop still shows the average | |
872 | percentages for the last 10, 60 and 300 seconds by widening the window. | |
873 | ||
874 | M atopsar.c | |
875 | M man/atop.1 | |
876 | M man/atopsar.1 | |
877 | M showlinux.c | |
878 | M showlinux.h | |
879 | M showsys.c | |
880 | ||
881 | commit 08c622ecaa5bb0bb260984ceaddc4730d1b312a7 | |
882 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
883 | Date: Tue Dec 24 12:20:02 2019 +0100 | |
884 | ||
885 | Suppress busy percentage for virtual network interface (issue #83) | |
886 | Determine whether or not a network interface is virtual (for which | |
887 | the interface driver usually returns 10 Mbit as speed) by checking | |
888 | the physical address. | |
889 | ||
890 | M ifprop.c | |
891 | ||
892 | commit c20cbce6a3885ce9cba604de829c311909909e97 | |
893 | Author: Daniel Brooks <db48x@db48x.net> | |
894 | Date: Wed Dec 11 12:45:09 2019 -0800 | |
895 | ||
896 | show disk avio values in microseconds or nanoseconds as appropriate | |
897 | ||
898 | M showsys.c | |
899 | ||
900 | commit 802fb3a235c5fd9aa4e6cdc0fb3c31e2dca8ea4a | |
901 | Merge: e4343d3 1c45948 | |
902 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
903 | Date: Sat Nov 23 12:45:08 2019 +0100 | |
904 | ||
905 | Merge branch 'bytedance-readahead-rawlog' | |
906 | ||
907 | commit 1c459481bbef630f335a7e6e1ec7e60daa94ebee | |
908 | Merge: e4343d3 a34e347 | |
909 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
910 | Date: Sat Nov 23 12:36:53 2019 +0100 | |
911 | ||
912 | Merge branch 'readahead-rawlog' of git://github.com/bytedance/atop into bytedance-readahead-rawlog | |
913 | ||
914 | commit e4343d34b0840212266838267e5370fb559354f4 | |
915 | Merge: 1f21007 20443a3 | |
916 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
917 | Date: Sat Nov 23 12:12:45 2019 +0100 | |
918 | ||
919 | Merge pull request #59 from arielnh56/patch-1 | |
920 | ||
921 | Make LOGPATH overrulable | |
922 | ||
923 | commit 1f210074196daaebd8ac3ceca5e74d9f353d67a7 | |
924 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
925 | Date: Sat Nov 23 11:54:10 2019 +0100 | |
926 | ||
927 | Avoid overriding /etc/default/atop during RPM upgrade | |
928 | The file /etc/default/atop should not be overwritten during | |
929 | an RPM upgrade, so it is marked by %config(noreplace) in the | |
930 | RPM spec (solved issue #86). | |
931 | ||
932 | M rpmspec/atop.specsystemd | |
933 | M rpmspec/atop.specsysv | |
934 | ||
935 | commit 737ae433646fe789cc6f26f18f622e0ee799fe2c | |
936 | Merge: d292f1b dfb9cb9 | |
937 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
938 | Date: Sat Nov 23 11:02:00 2019 +0100 | |
939 | ||
940 | Merge pull request #81 from jubnzv/fix-infiniband | |
941 | ||
942 | photosyst.c: fix possible error in reading InfiniBand states | |
943 | ||
944 | commit d292f1b4f4dcc582f72d8e04d511897c543c6bca | |
945 | Merge: 224ab67 485a453 | |
946 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
947 | Date: Sat Nov 23 10:49:54 2019 +0100 | |
948 | ||
949 | Merge pull request #82 from BlackIkeEagle/defpath-not-created | |
950 | ||
951 | DEFPATH not created so touch fails | |
952 | ||
953 | commit 485a453d2ae5700874a57dffc297030254b5ae7c | |
954 | Author: BlackEagle <ike.devolder@gmail.com> | |
955 | Date: Mon Nov 4 09:00:54 2019 +0100 | |
956 | ||
957 | DEFPATH not created so touch fails | |
958 | ||
959 | ``` | |
960 | touch /build/atop/pkg/atop/etc/default/atop | |
961 | touch: cannot touch '/build/atop/pkg/atop/etc/default/atop': No such file or directory | |
962 | ``` | |
963 | ||
964 | Add DEFPATH mkdir in genericinstall to make sure the folder | |
965 | `$(DESTDIR)/etc/default` exits | |
966 | ||
967 | Signed-off-by: BlackEagle <ike.devolder@gmail.com> | |
968 | ||
969 | M Makefile | |
970 | ||
971 | commit 224ab67066810dcb3f80ab40c34bd4ab8d6a2ad7 | |
972 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
973 | Date: Sat Nov 2 12:27:18 2019 +0100 | |
974 | ||
975 | Prepare for release 2.5 | |
976 | ||
977 | M .gitignore | |
978 | M version.h | |
979 | ||
980 | commit e34478820e033a9e581ed601245fef2ae60878b2 | |
981 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
982 | Date: Sat Nov 2 12:26:16 2019 +0100 | |
983 | ||
984 | Add default values for /etc/default/atop file | |
985 | ||
986 | A atop.default | |
987 | M rpmspec/atop.specsystemd | |
988 | ||
989 | commit baf1458e07d37565f7aad469974c87ef0cabc547 | |
990 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
991 | Date: Sat Nov 2 12:25:09 2019 +0100 | |
992 | ||
993 | Add new structs for version 2.5 to atopconvert | |
994 | ||
995 | M atopconvert.c | |
996 | A prev/photoproc_25.h | |
997 | A prev/photosyst_25.h | |
998 | ||
999 | commit 5089600aed667e01846c89fe0bf2c2b4d9b58f02 | |
1000 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | |
1001 | Date: Sat Nov 2 12:23:45 2019 +0100 | |
1002 | ||
1003 | Modify manual dates | |
1004 | ||
1005 | M man/atop.1 | |
1006 | M man/atopacctd.8 | |
1007 | M man/atopconvert.1 | |
1008 | M man/atopgpud.8 | |
1009 | M man/atoprc.5 | |
1010 | M man/atopsar.1 | |
1011 | ||
0 | 1012 | commit 6fa0306b8966ac0210bb013de4289951f8499ab8 |
1 | 1013 | Merge: a802f1a 43b50d0 |
2 | 1014 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> |
22 | 1034 | M rpmspec/atop.specsystemd |
23 | 1035 | M rpmspec/atop.specsysv |
24 | 1036 | |
1037 | commit dfb9cb957eb3464a435908e70d74533558d3aa09 | |
1038 | Merge: c1f68ba 0ee181b | |
1039 | Author: Georgy Komarov <jubnzv@gmail.com> | |
1040 | Date: Fri Oct 25 07:41:20 2019 +0300 | |
1041 | ||
1042 | Merge pull request #1 from codebling/fix-infiniband-cleanup | |
1043 | ||
1044 | Move `ibc` property init to original location, revert whitespace changes | |
1045 | ||
1046 | commit 0ee181b084bca95cb98420737bd98a0f8779a6e4 | |
1047 | Author: Code Bling <codeblingx@gmail.com> | |
1048 | Date: Thu Oct 24 16:01:15 2019 -0400 | |
1049 | ||
1050 | Move `ibc` property init to original location, revert whitespace changes | |
1051 | ||
1052 | M photosyst.c | |
1053 | ||
1054 | commit c1f68ba78275ebbc0da113acc97fc56c8f0cfd7f | |
1055 | Author: Georgy Komarov <jubnzv@gmail.com> | |
1056 | Date: Thu Oct 24 14:52:59 2019 +0300 | |
1057 | ||
1058 | fixup uninitialized memory usage in ibstat | |
1059 | ||
1060 | M photosyst.c | |
1061 | ||
25 | 1062 | commit f8024a674203cec60ab311879b34292a10abff5d |
26 | 1063 | Merge: a802f1a 97d7b82 |
27 | 1064 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> |
28 | 1065 | Date: Wed Oct 23 21:31:33 2019 +0200 |
29 | 1066 | |
30 | 1067 | Merge branch 'master' of git://github.com/SjonHortensius/atop into timers |
1068 | ||
1069 | commit 791e4f8a9eeb1c1d5617f4696135ed0694366b43 | |
1070 | Author: Georgy Komarov <jubnzv@gmail.com> | |
1071 | Date: Fri Oct 18 23:46:21 2019 +0300 | |
1072 | ||
1073 | photosyst: fix possible error in reading InfiniBand states | |
1074 | ||
1075 | Make sure that we read rate file successfully to avoid usage of | |
1076 | uninitialized local variables. | |
1077 | ||
1078 | M photosyst.c | |
31 | 1079 | |
32 | 1080 | commit 97d7b8225d486211a0a02521a406f83780262253 |
33 | 1081 | Author: Justin Kromlinger <mail@hashworks.net> |
38 | 1086 | Read environment file in systemd service, use atop defaults instead of hardcoded |
39 | 1087 | |
40 | 1088 | M atop.service |
1089 | ||
1090 | commit a34e3478e1dabe06877881abd9d808180f4c8058 | |
1091 | Author: zhenwei pi <pizhenwei@bytedance.com> | |
1092 | Date: Fri Sep 27 17:27:54 2019 +0800 | |
1093 | ||
1094 | Readahead rawlog to make -b operation faster | |
1095 | ||
1096 | 1, use posix_fadvise POSIX_FADV_SEQUENTIAL to double kernel readahead buffer. | |
1097 | 2, HDD typically has a 100~200 IOPS, atop needs to read raw records more fastly | |
1098 | under low IOPS. So use pread syscall to load a large area(default every 4M) in | |
1099 | page-cache. | |
1100 | ||
1101 | Test env: | |
1102 | set disk iops as 200 for a virtual machine(KVM). | |
1103 | virsh blkdeviotune stretch sdb --write-iops-sec 200 --read-iops-sec 200 --live | |
1104 | ||
1105 | Test cases: | |
1106 | 1, test upstream atop without any page cache | |
1107 | ~# vmtouch -e /var/log/atop/atop_20190916 | |
1108 | ~# time /root/atop-upstream -r /var/log/atop/atop_20190916 -b 18:00 | |
1109 | real 0m54.639s | |
1110 | user 0m0.094s | |
1111 | sys 0m0.321s | |
1112 | ||
1113 | 2, test upstream atop with full page cache | |
1114 | ~# vmtouch -t /var/log/atop/atop_20190916 | |
1115 | ~# time /root/atop-upstream -r /var/log/atop/atop_20190916 -b 18:00 | |
1116 | real 0m1.266s | |
1117 | user 0m0.004s | |
1118 | sys 0m0.021s | |
1119 | ||
1120 | 3, test new atop without any page cache | |
1121 | ~# vmtouch -e /var/log/atop/atop_20190916 | |
1122 | ~# time /root/atop-new -r /var/log/atop/atop_20190916 -b 18:00 | |
1123 | real 0m3.818s | |
1124 | user 0m0.023s | |
1125 | sys 0m0.170s | |
1126 | ||
1127 | case 1 & case 2: speed of reading rawlog effects atop performance a lot. | |
1128 | case 1 & case 3: readahead makes performance better. | |
1129 | ||
1130 | Signed-off-by: zhenwei pi <pizhenwei@bytedance.com> | |
1131 | ||
1132 | M rawlog.c | |
41 | 1133 | |
42 | 1134 | commit a802f1a68ff0f3f06e6a4c609a87c0679bd07fce |
43 | 1135 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> |
278 | 1370 | |
279 | 1371 | Fix unchecked opendir to prevent dereferencing a NULL pointer |
280 | 1372 | |
1373 | commit 20443a367d225a466aeee77cdf549fb4bd615d87 | |
1374 | Author: Alastair Young <alastair@redhunter.com> | |
1375 | Date: Fri May 24 16:53:15 2019 -0700 | |
1376 | ||
1377 | Make LOGPATH overrulable | |
1378 | ||
1379 | Moved LOGPATH declaration to before DEFAULTSFILE source, so it can be overruled | |
1380 | ||
1381 | M atop.daily | |
1382 | ||
281 | 1383 | commit e7000f778465cf4e73a60604b799a4b1c0e80b15 |
282 | 1384 | Author: gregg leventhal <gregglev@yahoo.com> |
283 | 1385 | Date: Thu May 2 15:03:02 2019 -0400 |
318 | 1420 | Signed-off-by: zhenwei pi <pizhenwei@bytedance.com> |
319 | 1421 | |
320 | 1422 | M photoproc.c |
1423 | ||
1424 | commit ffc8ba8d324243a923abe48e9758adecb03d24a4 | |
1425 | Author: Peter Kjellerstedt <pkj@axis.com> | |
1426 | Date: Tue Feb 12 21:25:23 2019 +0100 | |
1427 | ||
1428 | atop.daily, atop.init, atop-pm.sh, mkdate: Avoid using bash | |
1429 | ||
1430 | Avoid using bash and bashisms when not necesary. On some systems, | |
1431 | e.g., embedded products, bash may not be available by default. | |
1432 | ||
1433 | Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com> | |
1434 | ||
1435 | M atop-pm.sh | |
1436 | M atop.daily | |
1437 | M atop.init | |
1438 | M mkdate | |
321 | 1439 | |
322 | 1440 | commit fa4db436865887f3e451692b9439d2943b4b2936 |
323 | 1441 | Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> |
12 | 12 | MAN8PATH = /usr/share/man/man8 |
13 | 13 | INIPATH = /etc/init.d |
14 | 14 | DEFPATH = /etc/default |
15 | SYSDPATH = /usr/lib/systemd/system | |
15 | SYSDPATH = /lib/systemd/system | |
16 | 16 | CRNPATH = /etc/cron.d |
17 | 17 | ROTPATH = /etc/logrotate.d |
18 | 18 | PMPATH1 = /usr/lib/pm-utils/sleep.d |
19 | 19 | PMPATH2 = /usr/lib64/pm-utils/sleep.d |
20 | 20 | PMPATHD = /usr/lib/systemd/system-sleep |
21 | 21 | |
22 | CFLAGS += -O2 -I. -Wall # -DNOPERFEVENT # -DHTTPSTATS | |
22 | CFLAGS += -O2 -I. -Wall -Wno-stringop-truncation # -DNOPERFEVENT # -DHTTPSTATS | |
23 | 23 | OBJMOD0 = version.o |
24 | 24 | OBJMOD1 = various.o deviate.o procdbase.o |
25 | 25 | OBJMOD2 = acctproc.o photoproc.o photosyst.o rawlog.o ifprop.o parseable.o |
29 | 29 | |
30 | 30 | VERS = $(shell ./atop -V 2>/dev/null| sed -e 's/^[^ ]* //' -e 's/ .*//') |
31 | 31 | |
32 | all: atop atopsar atopacctd atopconvert | |
32 | all: atop atopsar atopacctd atopconvert atopcat | |
33 | 33 | |
34 | 34 | atop: atop.o $(ALLMODS) Makefile |
35 | $(CC) -c version.c | |
36 | $(CC) atop.o $(ALLMODS) -o atop -lncurses -lz -lm -lrt $(LDFLAGS) | |
35 | $(CC) atop.o $(ALLMODS) -o atop -lncursesw -lz -lm -lrt $(LDFLAGS) | |
37 | 36 | |
38 | 37 | atopsar: atop |
39 | 38 | ln -sf atop atopsar |
44 | 43 | atopconvert: atopconvert.o |
45 | 44 | $(CC) atopconvert.o -o atopconvert -lz $(LDFLAGS) |
46 | 45 | |
47 | netlink.o: netlink.c | |
48 | $(CC) -I. -Wall -c netlink.c | |
46 | atopcat: atopcat.o | |
47 | $(CC) atopcat.o -o atopcat $(LDFLAGS) | |
49 | 48 | |
50 | 49 | clean: |
51 | rm -f *.o atop atopacctd atopconvert | |
50 | rm -f *.o atop atopacctd atopconvert atopcat | |
52 | 51 | |
53 | 52 | distr: |
54 | 53 | rm -f *.o atop |
136 | 135 | /sbin/service atop start; \ |
137 | 136 | fi |
138 | 137 | |
139 | genericinstall: atop atopacctd atopconvert | |
138 | genericinstall: atop atopacctd atopconvert atopcat | |
140 | 139 | if [ ! -d $(DESTDIR)$(LOGPATH) ]; \ |
141 | 140 | then mkdir -p $(DESTDIR)$(LOGPATH); fi |
141 | if [ ! -d $(DESTDIR)$(DEFPATH) ]; \ | |
142 | then mkdir -p $(DESTDIR)$(DEFPATH); fi | |
142 | 143 | if [ ! -d $(DESTDIR)$(BINPATH) ]; \ |
143 | 144 | then mkdir -p $(DESTDIR)$(BINPATH); fi |
144 | 145 | if [ ! -d $(DESTDIR)$(SBINPATH) ]; \ |
168 | 169 | cp atopconvert $(DESTDIR)$(BINPATH)/atopconvert |
169 | 170 | chown root $(DESTDIR)$(BINPATH)/atopconvert |
170 | 171 | chmod 0711 $(DESTDIR)$(BINPATH)/atopconvert |
172 | cp atopcat $(DESTDIR)$(BINPATH)/atopcat | |
173 | chown root $(DESTDIR)$(BINPATH)/atopcat | |
174 | chmod 0711 $(DESTDIR)$(BINPATH)/atopcat | |
171 | 175 | cp man/atop.1 $(DESTDIR)$(MAN1PATH) |
172 | 176 | cp man/atopsar.1 $(DESTDIR)$(MAN1PATH) |
173 | 177 | cp man/atopconvert.1 $(DESTDIR)$(MAN1PATH) |
178 | cp man/atopcat.1 $(DESTDIR)$(MAN1PATH) | |
174 | 179 | cp man/atoprc.5 $(DESTDIR)$(MAN5PATH) |
175 | 180 | cp man/atopacctd.8 $(DESTDIR)$(MAN8PATH) |
176 | 181 | cp man/atopgpud.8 $(DESTDIR)$(MAN8PATH) |
182 | 187 | |
183 | 188 | atop.o: atop.h photoproc.h photosyst.h acctproc.h showgeneric.h |
184 | 189 | atopsar.o: atop.h photoproc.h photosyst.h |
185 | rawlog.o: atop.h photoproc.h photosyst.h showgeneric.h | |
190 | rawlog.o: atop.h photoproc.h photosyst.h rawlog.h showgeneric.h | |
186 | 191 | various.o: atop.h acctproc.h |
187 | 192 | ifprop.o: atop.h photosyst.h ifprop.h |
188 | 193 | parseable.o: atop.h photoproc.h photosyst.h parseable.h |
201 | 206 | |
202 | 207 | atopacctd.o: atop.h photoproc.h acctproc.h atopacctd.h version.h versdate.h |
203 | 208 | |
204 | atopconvert.o: atop.h photoproc.h photosyst.h | |
209 | atopconvert.o: atop.h photoproc.h photosyst.h rawlog.h | |
210 | atopcat.o: atop.h rawlog.h |
0 | 0 | DEPENDENCIES |
1 | 1 | |
2 | Install the following packages to be able to build atop: | |
2 | Install the following packages to be able to build atop (package name | |
3 | can be different depending on the Linux distro): | |
3 | 4 | |
4 | * zlib-devel or libz-dev (depending on the distribution) | |
5 | * ncurses-devel or libncurses5-dev (depending on the distribution) | |
5 | * zlib-devel or libz-dev or zlib1g-dev | |
6 | * ncurses-devel or libncurses5-dev/libncursesw5-dev | |
6 | 7 | |
7 | Install the following packages to be able to run atop: | |
8 | 8 | |
9 | * zlib | |
10 | * ncurses | |
9 | Install the following packages to be able to execute atop (package name | |
10 | can be different depending on the Linux distro): | |
11 | ||
12 | * zlib or zlib1g | |
13 | * ncurses or libncurses5/libncursesw5 | |
11 | 14 | |
12 | 15 | |
13 | 16 | INSTALLING AND USING ATOP |
33 | 36 | KERNEL ISSUES WITH PROCESS ACCOUNTING |
34 | 37 | ------------------------------------- |
35 | 38 | |
36 | Newer upstream kernels (e.g. 4.8 and 4.9)have two issuess | |
39 | Newer upstream kernels (e.g. 4.8 and 4.9) have two issuess | |
37 | 40 | with process accounting: |
38 | 41 | |
39 | 42 | 1) Sometimes process accounting does not work at all¹. Atopacctd tries to |
179 | 179 | #define ATOPACCTKEY 3121959 |
180 | 180 | #define ATOPACCTTOT 100 |
181 | 181 | |
182 | struct sembuf semclaim = {0, -1, SEM_UNDO}, | |
183 | semrelse = {0, +1, SEM_UNDO}, | |
184 | semdecre = {1, -1, SEM_UNDO}, | |
185 | semincre = {1, +1, SEM_UNDO}; | |
182 | struct sembuf semclaim = {0, -1, SEM_UNDO}, | |
183 | semrelse = {0, +1, SEM_UNDO}, | |
184 | semdecre = {1, -1, SEM_UNDO}, | |
185 | semincre = {1, +1, SEM_UNDO}; | |
186 | ||
187 | struct sembuf semreglock[] = {{0, -1, SEM_UNDO}, {1, -1, SEM_UNDO}}, | |
188 | semunlock = {1, +1, SEM_UNDO}; | |
186 | 189 | |
187 | 190 | /* |
188 | 191 | ** switch on the process-accounting mechanism |
249 | 252 | ** when the atopacctd daemon is active on this system, |
250 | 253 | ** it should be the preferred way to read the accounting records |
251 | 254 | */ |
252 | if ( (sempacctpubid = semget(PACCTPUBKEY, 0, 0)) != -1) | |
255 | if ( (sempacctpubid = semget(PACCTPUBKEY, 2, 0)) != -1) | |
253 | 256 | { |
254 | 257 | FILE *cfp; |
255 | 258 | char shadowpath[128]; |
258 | 261 | if (! droprootprivs() ) |
259 | 262 | mcleanstop(42, "failed to drop root privs\n"); |
260 | 263 | |
261 | (void) semop(sempacctpubid, &semclaim, 1); | |
264 | (void) semop(sempacctpubid, semreglock, 2); | |
262 | 265 | |
263 | 266 | snprintf(shadowpath, sizeof shadowpath, "%s/%s/%s", |
264 | 267 | pacctdir, PACCTSHADOWD, PACCTSHADOWC); |
265 | 268 | |
266 | 269 | if ( (cfp = fopen(shadowpath, "r")) ) |
267 | 270 | { |
268 | if (fscanf(cfp, "%ld/%lu", | |
271 | if (fscanf(cfp, "%ld/%ld", | |
269 | 272 | &curshadowseq, &maxshadowrec) == 2) |
270 | 273 | { |
271 | 274 | fclose(cfp); |
296 | 299 | |
297 | 300 | semop(sempacctpubid, |
298 | 301 | &semrelse, 1); |
302 | semop(sempacctpubid, | |
303 | &semunlock, 1); | |
299 | 304 | |
300 | 305 | regainrootprivs(); |
301 | 306 | return 1; |
315 | 320 | { |
316 | 321 | supportflags |= ACCTACTIVE; |
317 | 322 | regainrootprivs(); |
323 | semop(sempacctpubid, | |
324 | &semunlock, 1); | |
318 | 325 | return 0; |
319 | 326 | } |
320 | 327 | |
321 | 328 | (void) close(acctfd); |
329 | } | |
330 | else | |
331 | { | |
332 | perror("open shadowpath"); | |
333 | abort(); | |
322 | 334 | } |
323 | 335 | } |
324 | 336 | else |
325 | 337 | { |
338 | fprintf(stderr, | |
339 | "fscanf failed on shadow currency\n"); | |
326 | 340 | fclose(cfp); |
327 | 341 | maxshadowrec = 0; |
328 | 342 | } |
329 | 343 | } |
330 | 344 | |
331 | 345 | (void) semop(sempacctpubid, &semrelse, 1); |
346 | (void) semop(sempacctpubid, &semunlock, 1); | |
332 | 347 | } |
333 | 348 | |
334 | 349 | /* |
867 | 882 | api->mem.majflt = acctexp(acctrec.ac_majflt); |
868 | 883 | api->dsk.rio = acctexp(acctrec.ac_rw); |
869 | 884 | |
870 | strcpy(api->gen.name, acctrec.ac_comm); | |
885 | strncpy(api->gen.name, acctrec.ac_comm, PNAMLEN); | |
886 | api->gen.name[PNAMLEN] = '\0'; | |
871 | 887 | break; |
872 | 888 | |
873 | 889 | case 3: |
894 | 910 | api->mem.majflt = acctexp(acctrec_v3.ac_majflt); |
895 | 911 | api->dsk.rio = acctexp(acctrec_v3.ac_rw); |
896 | 912 | |
897 | strcpy(api->gen.name, acctrec_v3.ac_comm); | |
913 | strncpy(api->gen.name, acctrec_v3.ac_comm, PNAMLEN); | |
914 | api->gen.name[PNAMLEN] = '\0'; | |
898 | 915 | break; |
899 | 916 | } |
900 | 917 | } |
164 | 164 | ** *** empty log message *** |
165 | 165 | ** |
166 | 166 | ** Revision 1.34 2009/11/27 15:07:25 gerlof |
167 | ** Give up root-priviliges at a earlier stage. | |
167 | ** Give up root-privileges at a earlier stage. | |
168 | 168 | ** |
169 | 169 | ** Revision 1.33 2009/11/27 14:01:01 gerlof |
170 | 170 | ** Introduce system-wide configuration file /etc/atoprc |
269 | 269 | ** Initial revision |
270 | 270 | ** |
271 | 271 | */ |
272 | ||
273 | static const char rcsid[] = "$Id: atop.c,v 1.49 2010/10/23 14:01:00 gerlof Exp $"; | |
274 | 272 | |
275 | 273 | #include <sys/types.h> |
276 | 274 | #include <sys/param.h> |
315 | 313 | char acctreason; /* accounting not active (return val) */ |
316 | 314 | char rawname[RAWNAMESZ]; |
317 | 315 | char rawreadflag; |
318 | unsigned int begintime, endtime; | |
316 | time_t begintime, endtime, cursortime; // epoch or time in day | |
319 | 317 | char flaglist[MAXFL]; |
320 | 318 | char deviatonly = 1; |
321 | 319 | char usecolors = 1; /* boolean: colors for high occupation */ |
322 | 320 | char threadview = 0; /* boolean: show individual threads */ |
323 | 321 | char calcpss = 0; /* boolean: read/calculate process PSS */ |
322 | char getwchan = 0; /* boolean: obtain wchan string */ | |
324 | 323 | |
325 | 324 | unsigned short hertz; |
326 | 325 | unsigned int pagesize; |
456 | 455 | struct rlimit rlim; |
457 | 456 | |
458 | 457 | /* |
459 | ** since priviliged actions will be done later on, at this stage | |
460 | ** the root-priviliges are dropped by switching effective user-id | |
458 | ** since privileged actions will be done later on, at this stage | |
459 | ** the root-privileges are dropped by switching effective user-id | |
461 | 460 | ** to real user-id (security reasons) |
462 | 461 | */ |
463 | 462 | if (! droprootprivs() ) |
532 | 531 | break; |
533 | 532 | |
534 | 533 | case 'r': /* reading of raw data ? */ |
535 | if (optind < argc && *(argv[optind]) != '-') | |
536 | strncpy(rawname, argv[optind++], | |
537 | RAWNAMESZ-1); | |
534 | if (optind < argc) | |
535 | { | |
536 | if (*(argv[optind]) == '-') | |
537 | { | |
538 | if (strlen(argv[optind]) == 1) | |
539 | { | |
540 | strcpy(rawname, | |
541 | "/dev/stdin"); | |
542 | optind++; | |
543 | } | |
544 | } | |
545 | else | |
546 | { | |
547 | strncpy(rawname, argv[optind], | |
548 | RAWNAMESZ-1); | |
549 | optind++; | |
550 | } | |
551 | } | |
538 | 552 | |
539 | 553 | rawreadflag++; |
540 | 554 | break; |
543 | 557 | midnightflag++; |
544 | 558 | break; |
545 | 559 | |
546 | case 'a': /* all processes per sample ? */ | |
547 | deviatonly = 0; | |
548 | break; | |
549 | ||
550 | case 'R': /* all processes per sample ? */ | |
551 | calcpss = 1; | |
552 | break; | |
553 | ||
554 | 560 | case 'b': /* begin time ? */ |
555 | if ( !hhmm2secs(optarg, &begintime) ) | |
561 | if ( !getbranchtime(optarg, &begintime) ) | |
556 | 562 | prusage(argv[0]); |
557 | 563 | break; |
558 | 564 | |
559 | 565 | case 'e': /* end time ? */ |
560 | if ( !hhmm2secs(optarg, &endtime) ) | |
566 | if ( !getbranchtime(optarg, &endtime) ) | |
561 | 567 | prusage(argv[0]); |
562 | 568 | break; |
563 | 569 | |
573 | 579 | prusage(argv[0]); |
574 | 580 | |
575 | 581 | linelen = atoi(optarg); |
582 | break; | |
583 | ||
584 | case MALLPROC: /* all processes per sample ? */ | |
585 | deviatonly = 0; | |
586 | break; | |
587 | ||
588 | case MCALCPSS: /* calculate PSS per sample ? */ | |
589 | calcpss = 1; | |
590 | break; | |
591 | ||
592 | case MGETWCHAN: /* obtain wchan string? */ | |
593 | getwchan = 1; | |
576 | 594 | break; |
577 | 595 | |
578 | 596 | default: /* gather other flags */ |
651 | 669 | signal(SIGTERM, cleanstop); |
652 | 670 | |
653 | 671 | /* |
654 | ** regain the root-priviliges that we dropped at the beginning | |
655 | ** to do some priviliged work | |
672 | ** regain the root-privileges that we dropped at the beginning | |
673 | ** to do some privileged work | |
656 | 674 | */ |
657 | 675 | regainrootprivs(); |
658 | 676 | |
659 | 677 | /* |
660 | 678 | ** lock ATOP in memory to get reliable samples (also when |
661 | 679 | ** memory is low and swapping is going on); |
662 | ** ignored if not running under superuser priviliges! | |
680 | ** ignored if not running under superuser privileges! | |
663 | 681 | */ |
664 | 682 | rlim.rlim_cur = RLIM_INFINITY; |
665 | 683 | rlim.rlim_max = RLIM_INFINITY; |
670 | 688 | /* |
671 | 689 | ** increment CPU scheduling-priority to get reliable samples (also |
672 | 690 | ** during heavy CPU load); |
673 | ** ignored if not running under superuser priviliges! | |
691 | ** ignored if not running under superuser privileges! | |
674 | 692 | */ |
675 | 693 | if ( nice(-20) == -1) |
676 | 694 | ; |
677 | 695 | |
696 | set_oom_score_adj(); | |
697 | ||
678 | 698 | /* |
679 | 699 | ** switch-on the process-accounting mechanism to register the |
680 | 700 | ** (remaining) resource-usage by processes which have finished |
693 | 713 | |
694 | 714 | /* |
695 | 715 | ** since privileged activities are finished now, there is no |
696 | ** need to keep running under root-priviliges, so switch | |
716 | ** need to keep running under root-privileges, so switch | |
697 | 717 | ** effective user-id to real user-id |
698 | 718 | */ |
699 | 719 | if (! droprootprivs() ) |
1039 | 1059 | printf("\t\tor\n"); |
1040 | 1060 | printf("Usage: %s -w file [-S] [-%c] [interval [samples]]\n", |
1041 | 1061 | myname, MALLPROC); |
1042 | printf(" %s -r [file] [-b hh:mm] [-e hh:mm] [-flags]\n", | |
1062 | printf(" %s -r [file] [-b [YYYYMMDD]hhmm] [-e [YYYYMMDD]hhmm] [-flags]\n", | |
1043 | 1063 | myname); |
1044 | 1064 | printf("\n"); |
1045 | 1065 | printf("\tgeneric flags:\n"); |
1048 | 1068 | "only)\n", MALLPROC); |
1049 | 1069 | printf("\t -%c calculate proportional set size (PSS) per process\n", |
1050 | 1070 | MCALCPSS); |
1071 | printf("\t -%c determine WCHAN (string) per thread\n", MGETWCHAN); | |
1051 | 1072 | printf("\t -P generate parseable output for specified label(s)\n"); |
1052 | 1073 | printf("\t -L alternate line length (default 80) in case of " |
1053 | 1074 | "non-screen output\n"); |
1054 | 1075 | |
1055 | (*vis.show_usage)(); | |
1076 | if (vis.show_usage) | |
1077 | (*vis.show_usage)(); | |
1056 | 1078 | |
1057 | 1079 | printf("\n"); |
1058 | 1080 | printf("\tspecific flags for raw logfiles:\n"); |
1059 | 1081 | printf("\t -w write raw data to file (compressed)\n"); |
1060 | 1082 | printf("\t -r read raw data from file (compressed)\n"); |
1061 | printf("\t special file: y[y...] for yesterday (repeated)\n"); | |
1083 | printf("\t symbolic file: y[y...] for yesterday (repeated)\n"); | |
1084 | printf("\t file name '-': read raw data from stdin\n"); | |
1062 | 1085 | printf("\t -S finish atop automatically before midnight " |
1063 | 1086 | "(i.s.o. #samples)\n"); |
1064 | printf("\t -b begin showing data from specified time\n"); | |
1065 | printf("\t -e finish showing data after specified time\n"); | |
1087 | printf("\t -b begin showing data from specified date/time\n"); | |
1088 | printf("\t -e finish showing data after specified date/time\n"); | |
1066 | 1089 | printf("\n"); |
1067 | 1090 | printf("\tinterval: number of seconds (minimum 0)\n"); |
1068 | 1091 | printf("\tsamples: number of intervals (minimum 1)\n"); |
1150 | 1173 | |
1151 | 1174 | i = strlen(linebuf); |
1152 | 1175 | |
1153 | if (i > 0 && linebuf[i-1] == '\n') | |
1176 | if (i <= 1) // empty line? | |
1177 | continue; | |
1178 | ||
1179 | if (linebuf[i-1] == '\n') | |
1154 | 1180 | linebuf[i-1] = 0; |
1155 | 1181 | |
1156 | 1182 | nr = sscanf(linebuf, "%19s %255[^#]", |
0 | #!/bin/bash | |
0 | #!/bin/sh | |
1 | 1 | |
2 | LOGOPTS="-R" # default options | |
2 | LOGOPTS="" # default options | |
3 | 3 | LOGINTERVAL=600 # default interval in seconds |
4 | 4 | LOGGENERATIONS=28 # default number of days |
5 | LOGPATH=/var/log/atop # default log location | |
5 | 6 | |
6 | 7 | # allow administrator to overrule the variables |
7 | 8 | # defined above |
23 | 24 | fi |
24 | 25 | |
25 | 26 | CURDAY=`date +%Y%m%d` |
26 | LOGPATH=/var/log/atop | |
27 | 27 | BINPATH=/usr/bin |
28 | 28 | PIDFILE=/var/run/atop.pid |
29 | 29 | |
37 | 37 | |
38 | 38 | while ps -p `cat "$PIDFILE"` > /dev/null |
39 | 39 | do |
40 | let CNT+=1 | |
40 | CNT=$((CNT + 1)) | |
41 | 41 | |
42 | 42 | if [ $CNT -gt 5 ] |
43 | 43 | then |
21 | 21 | ** See the GNU General Public License for more details. |
22 | 22 | */ |
23 | 23 | #define EQ 0 |
24 | #define SECSDAY 86400 | |
24 | #define SECONDSINDAY 86400 | |
25 | 25 | #define RAWNAMESZ 256 |
26 | 26 | |
27 | 27 | /* |
79 | 79 | extern char usecolors; |
80 | 80 | extern char threadview; |
81 | 81 | extern char calcpss; |
82 | extern char getwchan; | |
82 | 83 | extern char rawname[]; |
83 | 84 | extern char rawreadflag; |
84 | extern unsigned int begintime, endtime; | |
85 | extern time_t begintime, endtime, cursortime; // epoch or time in day | |
85 | 86 | extern char flaglist[]; |
86 | 87 | extern struct visualize vis; |
87 | 88 | |
136 | 137 | int atopsar(int, char *[]); |
137 | 138 | char *convtime(time_t, char *); |
138 | 139 | char *convdate(time_t, char *); |
139 | int hhmm2secs(char *, unsigned int *); | |
140 | int daysecs(time_t); | |
140 | int getbranchtime(char *, time_t *); | |
141 | time_t normalize_epoch(time_t, long); | |
142 | ||
141 | 143 | |
142 | 144 | char *val2valstr(count_t, char *, int, int, int); |
143 | 145 | char *val2memstr(count_t, char *, int, int, int); |
190 | 192 | void netatop_exiterase(void); |
191 | 193 | void netatop_exithash(char); |
192 | 194 | void netatop_exitfind(unsigned long, struct tstat *, struct tstat *); |
195 | void set_oom_score_adj(void); |
0 | #!/bin/bash | |
0 | #!/bin/sh | |
1 | 1 | # |
2 | 2 | # atop Startup script for the Atop process logging in background |
3 | 3 | # |
46 | 46 | |
47 | 47 | while ps -p `cat $PIDFILE` > /dev/null |
48 | 48 | do |
49 | let CNT+=1 | |
49 | CNT=$((CNT + 1)) | |
50 | 50 | |
51 | 51 | if [ $CNT -gt 5 ] |
52 | 52 | then |
58 | 58 | |
59 | 59 | rm $PIDFILE |
60 | 60 | fi |
61 | rm /var/lock/subsys/atop | |
61 | rm -f /var/lock/subsys/atop | |
62 | 62 | ;; |
63 | 63 | |
64 | 64 | status) |
2 | 2 | Documentation=man:atop(1) |
3 | 3 | |
4 | 4 | [Service] |
5 | Environment=LOGOPTS="-R" | |
5 | Environment=LOGOPTS="" | |
6 | 6 | Environment=LOGINTERVAL=600 |
7 | 7 | Environment=LOGGENERATIONS=28 |
8 | 8 | Environment=LOGPATH=/var/log/atop |
65 | 65 | then |
66 | 66 | kill $(ps -e | grep atopacctd$ | sed 's/^ *//' | cut -d' ' -f1) |
67 | 67 | fi |
68 | rm /var/lock/subsys/atopacctd | |
68 | rm -f /var/lock/subsys/atopacctd | |
69 | 69 | ;; |
70 | 70 | |
71 | 71 | status) |
73 | 73 | /* |
74 | 74 | ** Semaphore-handling |
75 | 75 | ** |
76 | ** Two semaphore groups are created with one semaphore each. | |
76 | ** Two semaphore groups are created: | |
77 | 77 | ** |
78 | 78 | ** The private semaphore (group) specifies the number of atopacctd processes |
79 | 79 | ** running (to be sure that only one daemon is active at the time). |
80 | 80 | ** |
81 | ** The public semaphore (group) reflects the number of processes using | |
82 | ** the process accounting shadow files, i.e. the number of clients. This | |
83 | ** semaphore starts at a high value and should be decremented whenever a | |
84 | ** client starts using the shadow files and incremented again whenever that | |
85 | ** client terminates. | |
81 | ** The public semaphore group contains two semaphores: | |
82 | ** | |
83 | ** 0: the number of processes using the process accounting shadow files, | |
84 | ** i.e. the number of (atop) clients. This semaphore starts at a high | |
85 | ** value and should be decremented by every (atop) client that starts | |
86 | ** using the shadow files and incremented again whenever that (atop) | |
87 | ** client terminates. | |
88 | ** | |
89 | ** 1: binary semphore that has to be claimed before using/modifying | |
90 | ** semaphore 0 in this group. | |
86 | 91 | */ |
87 | 92 | static int semprv; |
93 | ||
94 | ||
88 | 95 | static int sempub; |
89 | 96 | #define SEMTOTAL 100 |
90 | 97 | #define NUMCLIENTS (SEMTOTAL - semctl(sempub, 0, GETVAL, 0)) |
98 | ||
99 | struct sembuf semlocknowait = {1, -1, SEM_UNDO|IPC_NOWAIT}, | |
100 | semunlock = {1, +1, SEM_UNDO}; | |
101 | ||
91 | 102 | |
92 | 103 | static char atopacctdversion[] = ATOPVERS; |
93 | 104 | static char atopacctddate[] = ATOPDATE; |
133 | 144 | time_t gclast = time(0); |
134 | 145 | |
135 | 146 | struct sigaction sigcleanup; |
147 | int liResult; | |
136 | 148 | |
137 | 149 | /* |
138 | 150 | ** argument passed? |
246 | 258 | } |
247 | 259 | } |
248 | 260 | |
249 | if ( (sempub = semget(PACCTPUBKEY, 0, 0)) == -1) // not existing? | |
250 | { | |
251 | if ( (sempub = semget(PACCTPUBKEY, 1, | |
252 | 0666|IPC_CREAT|IPC_EXCL)) >= 0) | |
253 | { | |
254 | (void) semctl(sempub, 0, SETVAL, SEMTOTAL); | |
255 | } | |
256 | else | |
257 | { | |
258 | perror("cannot create public semaphore"); | |
259 | exit(3); | |
260 | } | |
261 | // create new semaphore group | |
262 | // | |
263 | if ( (sempub = semget(PACCTPUBKEY, 0, 0)) != -1) // existing? | |
264 | (void) semctl(sempub, 0, IPC_RMID, 0); | |
265 | ||
266 | if ( (sempub = semget(PACCTPUBKEY, 2, 0666|IPC_CREAT|IPC_EXCL)) >= 0) | |
267 | { | |
268 | (void) semctl(sempub, 0, SETVAL, SEMTOTAL); | |
269 | (void) semctl(sempub, 1, SETVAL, 1); | |
270 | } | |
271 | else | |
272 | { | |
273 | perror("cannot create public semaphore"); | |
274 | exit(3); | |
261 | 275 | } |
262 | 276 | |
263 | 277 | /* |
303 | 317 | |
304 | 318 | umask(022); |
305 | 319 | |
306 | (void) chdir("/tmp"); // go to a safe place | |
320 | liResult = chdir("/tmp"); // go to a safe place | |
321 | ||
322 | if(liResult != 0) | |
323 | { | |
324 | char lcMessage[64]; | |
325 | ||
326 | snprintf(lcMessage, sizeof(lcMessage) - 1, | |
327 | "%s:%d - Error %d changing to tmp dir\n", | |
328 | __FILE__, __LINE__, errno ); | |
329 | fprintf(stderr, "%s", lcMessage); | |
330 | } | |
307 | 331 | |
308 | 332 | /* |
309 | 333 | ** increase semaphore to define that atopacctd is running |
321 | 345 | */ |
322 | 346 | snprintf(accountpath, sizeof accountpath, "%s/%s", pacctdir, PACCTORIG); |
323 | 347 | |
324 | (void) unlink(accountpath); | |
348 | (void) unlink(accountpath); // in case atopacctd previously killed | |
325 | 349 | |
326 | 350 | if ( (afd = creat(accountpath, 0600)) == -1) |
327 | 351 | { |
344 | 368 | |
345 | 369 | /* |
346 | 370 | ** create directory to store the shadow files |
371 | ** when atopacctd was previously killed, rename the | |
372 | ** old directory to a unique name | |
347 | 373 | */ |
348 | 374 | snprintf(shadowdir, sizeof shadowdir, "%s/%s", pacctdir, PACCTSHADOWD); |
375 | ||
376 | if ( stat(shadowdir, &dirstat) == 0 ) // already exists? | |
377 | { | |
378 | if (S_ISDIR(dirstat.st_mode)) // and is directory? | |
379 | { | |
380 | // define new name to save directory | |
381 | char newshadow[256]; | |
382 | ||
383 | snprintf(newshadow, sizeof newshadow, "%s-old-%d", | |
384 | shadowdir, getpid()); | |
385 | ||
386 | if ( rename(shadowdir, newshadow) == -1) | |
387 | { | |
388 | perror("could not rename old shadow directory"); | |
389 | exit(5); | |
390 | } | |
391 | } | |
392 | } | |
349 | 393 | |
350 | 394 | if ( mkdir(shadowdir, 0755) == -1) |
351 | 395 | { |
366 | 410 | /* |
367 | 411 | ** raise priority (be sure the nice value becomes -20, |
368 | 412 | ** independent of the current nice value) |
369 | */ | |
370 | (void) nice(-39); | |
413 | ** this may fail without notice for non-privileged processes | |
414 | */ | |
415 | liResult = nice(-39); | |
371 | 416 | |
372 | 417 | /* |
373 | 418 | ** connect to NETLINK socket of kernel to be triggered |
421 | 466 | while (! cleanup_and_go) |
422 | 467 | { |
423 | 468 | int state; |
469 | time_t curtime; | |
424 | 470 | |
425 | 471 | /* |
426 | 472 | ** await termination of (at least) one process and |
433 | 479 | break; |
434 | 480 | |
435 | 481 | /* |
436 | ** verify if garbage collection is needed | |
437 | ** i.e. removal of shadow files that are not in use any more | |
438 | */ | |
439 | if ( shadowbusy && time(0) > gclast + GCINTERVAL ) | |
482 | ** garbage collection (i.e. removal of shadow files that | |
483 | ** are not in use any more) is needed in case: | |
484 | ** | |
485 | ** - shadow files are currently maintained because | |
486 | ** at least one atop is running, and | |
487 | ** - shadow files have not been removed for GCINTERVAL | |
488 | ** seconds, or | |
489 | ** - the system clock has been modified (lowered) | |
490 | */ | |
491 | if ( shadowbusy && | |
492 | (time(&curtime) > gclast + GCINTERVAL || | |
493 | curtime < gclast ) ) | |
440 | 494 | { |
441 | 495 | gcshadows(&oldshadow, curshadow); |
442 | 496 | gclast = time(0); |
663 | 717 | ** have been using the shadow files till now and |
664 | 718 | ** cleanup has to be performed |
665 | 719 | */ |
666 | if (NUMCLIENTS == 0) | |
667 | { | |
668 | /* | |
669 | ** did last client just disappeared? | |
670 | */ | |
671 | if (*shadowbusyp) | |
720 | if (semop(sempub, &semlocknowait, 1) == 0) // lock succeeded? | |
721 | { | |
722 | if (NUMCLIENTS == 0) | |
672 | 723 | { |
673 | 724 | /* |
674 | ** remove all shadow files | |
725 | ** did last client just disappear? | |
675 | 726 | */ |
676 | gcshadows(oldshadowp, (*curshadowp)+1); | |
677 | *oldshadowp = 0; | |
678 | *curshadowp = 0; | |
679 | stotsize = 0; | |
680 | ||
681 | /* | |
682 | ** create new file with sequence 0 | |
683 | */ | |
684 | (void) close(sfd); | |
685 | ||
686 | sfd = createshadow(*curshadowp); | |
687 | setcurrent(*curshadowp); | |
688 | ||
689 | *shadowbusyp = 0; | |
690 | } | |
691 | ||
692 | return 1; | |
727 | if (*shadowbusyp) | |
728 | { | |
729 | /* | |
730 | ** remove all shadow files | |
731 | */ | |
732 | gcshadows(oldshadowp, (*curshadowp)+1); | |
733 | *oldshadowp = 0; | |
734 | *curshadowp = 0; | |
735 | stotsize = 0; | |
736 | ||
737 | /* | |
738 | ** create new file with sequence 0 | |
739 | */ | |
740 | (void) close(sfd); | |
741 | ||
742 | sfd = createshadow(*curshadowp); | |
743 | setcurrent(*curshadowp); | |
744 | ||
745 | *shadowbusyp = 0; | |
746 | } | |
747 | ||
748 | (void) semop(sempub, &semunlock, 1); | |
749 | return 1; | |
750 | } | |
751 | ||
752 | (void) semop(sempub, &semunlock, 1); | |
693 | 753 | } |
694 | 754 | |
695 | 755 | *shadowbusyp = 1; |
965 | 1025 | static int cfd = -1; |
966 | 1026 | char currentpath[128], currentdata[128]; |
967 | 1027 | int len; |
1028 | int liResult; | |
968 | 1029 | |
969 | 1030 | /* |
970 | 1031 | ** assemble file name of currency file and open (only once) |
991 | 1052 | /* |
992 | 1053 | ** wipe currency file and write new assembled string |
993 | 1054 | */ |
994 | (void) ftruncate(cfd, 0); | |
1055 | liResult = ftruncate(cfd, 0); | |
1056 | ||
1057 | if(liResult != 0) | |
1058 | { | |
1059 | char lcMessage[64]; | |
1060 | ||
1061 | snprintf(lcMessage, sizeof(lcMessage) - 1, | |
1062 | "%s:%d - Error %d ftruncate\n\n", __FILE__, __LINE__, | |
1063 | errno ); | |
1064 | fprintf(stderr, "%s", lcMessage); | |
1065 | } | |
1066 | ||
995 | 1067 | (void) lseek(cfd, 0, SEEK_SET); |
996 | (void) write(cfd, currentdata, len); | |
1068 | ||
1069 | liResult = write(cfd, currentdata, len); | |
1070 | ||
1071 | if(liResult == -1) | |
1072 | { | |
1073 | char lcMessage[64]; | |
1074 | ||
1075 | snprintf(lcMessage, sizeof(lcMessage) - 1, | |
1076 | "%s:%d - Error %d writing\n\n", __FILE__, __LINE__, | |
1077 | errno ); | |
1078 | fprintf(stderr, "%s", lcMessage); | |
1079 | } | |
997 | 1080 | } |
998 | 1081 | |
999 | 1082 | /* |
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 program concatenates several raw logfiles into one output stream, | |
7 | ** to be stored as new file or to be passed via a pipe to atop/atopsar directly. | |
8 | ** ========================================================================== | |
9 | ** Author: Gerlof Langeveld | |
10 | ** E-mail: gerlof.langeveld@atoptool.nl | |
11 | ** Initial: March 2020 | |
12 | ** -------------------------------------------------------------------------- | |
13 | ** Copyright (C) 2020 Gerlof Langeveld | |
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 | #include <sys/types.h> | |
31 | #include <sys/param.h> | |
32 | #include <sys/stat.h> | |
33 | #include <fcntl.h> | |
34 | #include <time.h> | |
35 | #include <stdio.h> | |
36 | #include <errno.h> | |
37 | #include <stdlib.h> | |
38 | #include <sys/utsname.h> | |
39 | #include <unistd.h> | |
40 | ||
41 | #include "atop.h" | |
42 | #include "rawlog.h" | |
43 | ||
44 | char *convepoch(time_t); | |
45 | void prusage(char *); | |
46 | ||
47 | int | |
48 | main(int argc, char *argv[]) | |
49 | { | |
50 | int i, fd, n, c; | |
51 | int firstfile, beverbose=0, dryrun=0; | |
52 | struct rawheader rh; | |
53 | struct rawrecord rr; | |
54 | char *infile, *sstat, *pstat; | |
55 | unsigned short aversion; | |
56 | ||
57 | // verify the command line arguments: input filename(s) | |
58 | // | |
59 | if (argc < 2) | |
60 | prusage(argv[0]); | |
61 | ||
62 | while ((c = getopt(argc, argv, "?hvd")) != EOF) | |
63 | { | |
64 | switch (c) | |
65 | { | |
66 | case '?': // usage wanted? | |
67 | case 'h': // usage wanted? | |
68 | prusage(argv[0]); | |
69 | break; | |
70 | ||
71 | case 'v': // verbosity wanted? | |
72 | beverbose = 1; | |
73 | break; | |
74 | ||
75 | case 'd': // dry run wanted? | |
76 | dryrun = 1; | |
77 | break; | |
78 | ||
79 | default: | |
80 | prusage(argv[0]); | |
81 | } | |
82 | } | |
83 | ||
84 | if ( isatty(1) && !dryrun) | |
85 | { | |
86 | fprintf(stderr, | |
87 | "this program produces binary output on stdout " | |
88 | "that should be redirected\nto a file or pipe!\n"); | |
89 | exit(1); | |
90 | } | |
91 | ||
92 | // open all input files one-by-one | |
93 | // | |
94 | for (i=optind, firstfile=1; i < argc; i++, firstfile=0) | |
95 | { | |
96 | infile = argv[i]; | |
97 | ||
98 | // open raw file for reading | |
99 | // | |
100 | if ( (fd = open(infile, O_RDONLY)) == -1) | |
101 | { | |
102 | fprintf(stderr, "%s - ", infile); | |
103 | perror("open for reading"); | |
104 | exit(2); | |
105 | } | |
106 | ||
107 | // read the raw header | |
108 | // | |
109 | if ( read(fd, &rh, sizeof rh) < sizeof rh) | |
110 | { | |
111 | fprintf(stderr, "%s: cannot read raw header\n", infile); | |
112 | close(fd); | |
113 | exit(3); | |
114 | } | |
115 | ||
116 | // verify if this is a correct rawlog file | |
117 | // | |
118 | if (rh.magic != MYMAGIC) | |
119 | { | |
120 | fprintf(stderr, "%s: not a valid rawlog file " | |
121 | "(wrong magic number)\n", infile); | |
122 | close(fd); | |
123 | exit(4); | |
124 | } | |
125 | ||
126 | // only for the first file, store the version number and write | |
127 | // the raw header for the entire stream | |
128 | // | |
129 | // for the next files, be sure that the version is the same | |
130 | // as the first file | |
131 | // | |
132 | if (firstfile) | |
133 | { | |
134 | aversion = rh.aversion; | |
135 | ||
136 | if (!dryrun) | |
137 | { | |
138 | if ( write(1, &rh, sizeof rh) < sizeof rh) | |
139 | { | |
140 | fprintf(stderr, | |
141 | "can not write raw header\n"); | |
142 | exit(10); | |
143 | } | |
144 | } | |
145 | ||
146 | if (beverbose) | |
147 | { | |
148 | fprintf(stderr, | |
149 | "Logs created by atop version %d.%d\n\n", | |
150 | (rh.aversion >> 8) & 0x7f, | |
151 | rh.aversion & 0xff); | |
152 | ||
153 | fprintf(stderr, "%-10s %-8s %12s %8s %9s\n", | |
154 | "date", "time", "interval", | |
155 | "comprsys", "comprproc"); | |
156 | } | |
157 | ||
158 | } | |
159 | else // subsequent file | |
160 | { | |
161 | if (aversion != rh.aversion) | |
162 | { | |
163 | fprintf(stderr, | |
164 | "Version of file %s is unequal to " | |
165 | "version of first file\n", infile); | |
166 | close(fd); | |
167 | exit(5); | |
168 | } | |
169 | } | |
170 | ||
171 | // read every raw record followed by the compressed | |
172 | // system-level and process-level stats | |
173 | // | |
174 | while ( read(fd, &rr, sizeof rr) == sizeof rr ) | |
175 | { | |
176 | if (beverbose) | |
177 | { | |
178 | fprintf(stderr, "%19s %12u %8u %9u %s\n", | |
179 | convepoch(rr.curtime), | |
180 | rr.interval, rr.scomplen, rr.pcomplen, | |
181 | rr.flags&RRBOOT ? "boot" : ""); | |
182 | } | |
183 | ||
184 | // dynamically allocate space to read stats | |
185 | // | |
186 | if ( (sstat = malloc(rr.scomplen)) == NULL) | |
187 | { | |
188 | fprintf(stderr, "malloc failed for sstat\n"); | |
189 | exit(7); | |
190 | } | |
191 | ||
192 | if ( (pstat = malloc(rr.pcomplen)) == NULL) | |
193 | { | |
194 | fprintf(stderr, "malloc failed for pstat\n"); | |
195 | exit(7); | |
196 | } | |
197 | ||
198 | // read system-level and process-level stats | |
199 | // | |
200 | if ((n = read(fd, sstat, rr.scomplen)) != rr.scomplen) | |
201 | { | |
202 | if (n == -1) | |
203 | { | |
204 | fprintf(stderr, "read file %s", infile); | |
205 | perror(""); | |
206 | exit(8); | |
207 | } | |
208 | else | |
209 | { | |
210 | fprintf(stderr, | |
211 | "file %s incomplete!\n", infile); | |
212 | ||
213 | free(sstat); | |
214 | free(pstat); | |
215 | break; | |
216 | } | |
217 | } | |
218 | ||
219 | if ((n = read(fd, pstat, rr.pcomplen)) != rr.pcomplen) | |
220 | { | |
221 | if (n == -1) | |
222 | { | |
223 | fprintf(stderr, "read file %s", infile); | |
224 | perror(""); | |
225 | exit(8); | |
226 | } | |
227 | else | |
228 | { | |
229 | fprintf(stderr, | |
230 | "file %s incomplete!\n", infile); | |
231 | ||
232 | free(sstat); | |
233 | free(pstat); | |
234 | break; | |
235 | } | |
236 | } | |
237 | ||
238 | if (!dryrun) | |
239 | { | |
240 | // write raw record followed by the compressed | |
241 | // system-level and process-level stats | |
242 | // | |
243 | if ( write(1, &rr, sizeof rr) < sizeof rr) | |
244 | { | |
245 | fprintf(stderr, | |
246 | "can not write raw record\n"); | |
247 | exit(11); | |
248 | } | |
249 | ||
250 | if ( write(1, sstat, rr.scomplen) < rr.scomplen) | |
251 | { | |
252 | fprintf(stderr, | |
253 | "can not write sstat\n"); | |
254 | exit(11); | |
255 | } | |
256 | ||
257 | if ( write(1, pstat, rr.pcomplen) < rr.pcomplen) | |
258 | { | |
259 | fprintf(stderr, | |
260 | "can not write pstat\n"); | |
261 | exit(11); | |
262 | } | |
263 | } | |
264 | ||
265 | // free dynamically allocated buffers | |
266 | // | |
267 | free(sstat); | |
268 | free(pstat); | |
269 | } | |
270 | ||
271 | close(fd); | |
272 | } | |
273 | ||
274 | return 0; | |
275 | } | |
276 | ||
277 | // Function to convert an epoch time to date-time format | |
278 | // | |
279 | char * | |
280 | convepoch(time_t utime) | |
281 | { | |
282 | struct tm *tt; | |
283 | static char datetime[64]; | |
284 | ||
285 | ||
286 | tt = localtime(&utime); | |
287 | ||
288 | sprintf(datetime, "%04d/%02d/%02d %02d:%02d:%02d", | |
289 | tt->tm_year+1900, tt->tm_mon+1, tt->tm_mday, | |
290 | tt->tm_hour, tt->tm_min, tt->tm_sec); | |
291 | ||
292 | return datetime; | |
293 | } | |
294 | ||
295 | // Function that shows the usage message | |
296 | // | |
297 | void | |
298 | prusage(char *name) | |
299 | { | |
300 | fprintf(stderr, "Usage: %s [-dv] rawfile [rawfile]...\n", name); | |
301 | fprintf(stderr, "\t-d\tdry run (no raw output generated)\n"); | |
302 | fprintf(stderr, "\t-v\tbe verbose\n"); | |
303 | exit(1); | |
304 | } |
10 | 10 | ** E-mail: gerlof.langeveld@atoptool.nl |
11 | 11 | ** Initial: July/August 2018 |
12 | 12 | ** -------------------------------------------------------------------------- |
13 | ** Copyright (C) 2018-2019 Gerlof Langeveld | |
13 | ** Copyright (C) 2018-2020 Gerlof Langeveld | |
14 | 14 | ** |
15 | 15 | ** This program is free software; you can redistribute it and/or modify it |
16 | 16 | ** under the terms of the GNU General Public License as published by the |
50 | 50 | #include "atop.h" |
51 | 51 | #include "photosyst.h" |
52 | 52 | #include "photoproc.h" |
53 | #include "rawlog.h" | |
53 | 54 | |
54 | 55 | #include "prev/photosyst_20.h" |
55 | 56 | #include "prev/photoproc_20.h" |
68 | 69 | |
69 | 70 | #include "prev/photosyst_25.h" |
70 | 71 | #include "prev/photoproc_25.h" |
72 | ||
73 | #include "prev/photosyst_26.h" | |
74 | #include "prev/photoproc_26.h" | |
71 | 75 | |
72 | 76 | |
73 | 77 | /////////////////////////////////////////////////////////////// |
213 | 217 | g22->vpid = 0; |
214 | 218 | } |
215 | 219 | |
220 | void | |
221 | tcpu_to_26(void *old, void *new, count_t oldsize, count_t newsize) | |
222 | { | |
223 | // unused values appear not to be zeroed in version 2.5 | |
224 | // | |
225 | struct cpu_25 *c25 = old; | |
226 | struct cpu_26 *c26 = new; | |
227 | ||
228 | memcpy(c26, c25, sizeof *c26); // copy entire struct | |
229 | ||
230 | memset(&(c26->wchan), 0, sizeof c26->wchan); | |
231 | c26->rundelay = 0; | |
232 | } | |
233 | ||
234 | void | |
235 | tmem_to_26(void *old, void *new, count_t oldsize, count_t newsize) | |
236 | { | |
237 | // unused values appear not to be zeroed in version 2.5 | |
238 | // | |
239 | struct mem_25 *m25 = old; | |
240 | struct mem_26 *m26 = new; | |
241 | ||
242 | memcpy(m26, m25, sizeof *m26); // copy entire struct | |
243 | ||
244 | m26->vlock = 0; | |
245 | } | |
246 | ||
216 | 247 | /////////////////////////////////////////////////////////////// |
217 | 248 | // conversion definition for various structs in sstat and tstat |
218 | 249 | // |
237 | 268 | struct sstat_23 sstat_23; |
238 | 269 | struct sstat_24 sstat_24; |
239 | 270 | struct sstat_25 sstat_25; |
271 | struct sstat_26 sstat_26; | |
240 | 272 | struct sstat sstat; |
241 | 273 | |
242 | 274 | struct tstat_20 tstat_20; |
245 | 277 | struct tstat_23 tstat_23; |
246 | 278 | struct tstat_24 tstat_24; |
247 | 279 | struct tstat_25 tstat_25; |
280 | struct tstat_26 tstat_26; | |
248 | 281 | struct tstat tstat; |
249 | 282 | |
250 | 283 | struct convertall { |
453 | 486 | {sizeof(struct gpu_25), |
454 | 487 | STROFFSET(&tstat_25.gpu, &tstat_25), justcopy}, |
455 | 488 | }, |
489 | ||
490 | {SETVERSION(2,6), // 2.5 --> 2.6 | |
491 | sizeof(struct sstat_26), &sstat_26, | |
492 | sizeof(struct tstat_26), NULL, | |
493 | ||
494 | {sizeof(struct cpustat_26), &sstat_26.cpu, justcopy}, | |
495 | {sizeof(struct memstat_26), &sstat_26.mem, justcopy}, | |
496 | {sizeof(struct netstat_26), &sstat_26.net, justcopy}, | |
497 | {sizeof(struct intfstat_26), &sstat_26.intf, justcopy}, | |
498 | {sizeof(struct dskstat_26), &sstat_26.dsk, justcopy}, | |
499 | {sizeof(struct nfsstat_26), &sstat_26.nfs, justcopy}, | |
500 | {sizeof(struct contstat_26), &sstat_26.cfs, justcopy}, | |
501 | {sizeof(struct wwwstat_26), &sstat_26.www, justcopy}, | |
502 | {sizeof(struct pressure_26), &sstat_26.psi, justcopy}, | |
503 | {sizeof(struct gpustat_26), &sstat_26.gpu, justcopy}, | |
504 | {sizeof(struct ifbstat_26), &sstat_26.ifb, justcopy}, | |
505 | ||
506 | {sizeof(struct gen_26), | |
507 | STROFFSET(&tstat_26.gen, &tstat_26), justcopy}, | |
508 | {sizeof(struct cpu_26), | |
509 | STROFFSET(&tstat_26.cpu, &tstat_26), tcpu_to_26}, | |
510 | {sizeof(struct dsk_26), | |
511 | STROFFSET(&tstat_26.dsk, &tstat_26), justcopy}, | |
512 | {sizeof(struct mem_26), | |
513 | STROFFSET(&tstat_26.mem, &tstat_26), tmem_to_26}, | |
514 | {sizeof(struct net_26), | |
515 | STROFFSET(&tstat_26.net, &tstat_26), justcopy}, | |
516 | {sizeof(struct gpu_26), | |
517 | STROFFSET(&tstat_26.gpu, &tstat_26), justcopy}, | |
518 | }, | |
456 | 519 | }; |
457 | 520 | |
458 | 521 | int numconvs = sizeof convs / sizeof(struct convertall); |
460 | 523 | /////////////////////////////////////////////////////////////// |
461 | 524 | // End of conversion functions |
462 | 525 | /////////////////////////////////////////////////////////////// |
463 | ||
464 | ||
465 | /* | |
466 | ** structure which describes the raw file contents | |
467 | ** | |
468 | ** layout raw file: rawheader | |
469 | ** | |
470 | ** rawrecord \ | |
471 | ** compressed system-level statistics | sample 1 | |
472 | ** compressed process-level statistics / | |
473 | ** | |
474 | ** rawrecord \ | |
475 | ** compressed system-level statistics | sample 2 | |
476 | ** compressed process-level statistics / | |
477 | ** | |
478 | ** etcetera ..... | |
479 | */ | |
480 | #define MYMAGIC (unsigned int) 0xfeedbeef | |
481 | ||
482 | struct rawheader { | |
483 | unsigned int magic; | |
484 | ||
485 | unsigned short aversion; /* creator atop version with MSB */ | |
486 | unsigned short future1; /* can be reused */ | |
487 | unsigned short future2; /* can be reused */ | |
488 | unsigned short rawheadlen; /* length of struct rawheader */ | |
489 | unsigned short rawreclen; /* length of struct rawrecord */ | |
490 | unsigned short hertz; /* clock interrupts per second */ | |
491 | unsigned short sfuture[6]; /* future use */ | |
492 | unsigned int sstatlen; /* length of struct sstat */ | |
493 | unsigned int tstatlen; /* length of struct tstat */ | |
494 | struct utsname utsname; /* info about this system */ | |
495 | char cfuture[8]; /* future use */ | |
496 | ||
497 | unsigned int pagesize; /* size of memory page (bytes) */ | |
498 | int supportflags; /* used features */ | |
499 | int osrel; /* OS release number */ | |
500 | int osvers; /* OS version number */ | |
501 | int ossub; /* OS version subnumber */ | |
502 | int ifuture[6]; /* future use */ | |
503 | }; | |
504 | ||
505 | struct rawrecord { | |
506 | time_t curtime; /* current time (epoch) */ | |
507 | ||
508 | unsigned short flags; /* various flags */ | |
509 | unsigned short sfuture[3]; /* future use */ | |
510 | ||
511 | unsigned int scomplen; /* length of compressed sstat */ | |
512 | unsigned int pcomplen; /* length of compressed tstat's */ | |
513 | unsigned int interval; /* interval (number of seconds) */ | |
514 | unsigned int ndeviat; /* number of tasks in list */ | |
515 | unsigned int nactproc; /* number of processes in list */ | |
516 | unsigned int ntask; /* total number of tasks */ | |
517 | unsigned int totproc; /* total number of processes */ | |
518 | unsigned int totrun; /* number of running threads */ | |
519 | unsigned int totslpi; /* number of sleeping threads(S)*/ | |
520 | unsigned int totslpu; /* number of sleeping threads(D)*/ | |
521 | unsigned int totzomb; /* number of zombie processes */ | |
522 | unsigned int nexit; /* number of exited processes */ | |
523 | unsigned int noverflow; /* number of overflow processes */ | |
524 | unsigned int ifuture[6]; /* future use */ | |
525 | }; | |
526 | 526 | |
527 | 527 | // function prototypes |
528 | 528 | // |
0 | #!/usr/bin/python -Es | |
0 | #!/usr/bin/python3 -Es | |
1 | 1 | |
2 | 2 | # ============================================================== |
3 | 3 | # Daemon that gathers statistical information from all |
28 | 28 | ** -------------------------------------------------------------------------- |
29 | 29 | */ |
30 | 30 | |
31 | static const char rcsid[] = "$Id: atopsar.c,v 1.28 2010/11/26 06:19:43 gerlof Exp $"; | |
32 | ||
33 | 31 | #include <sys/types.h> |
34 | 32 | #include <sys/param.h> |
35 | 33 | #include <sys/mman.h> |
155 | 153 | break; |
156 | 154 | |
157 | 155 | case 'b': /* begin time ? */ |
158 | if ( !hhmm2secs(optarg, &begintime) ) | |
156 | if ( !getbranchtime(optarg, &begintime) ) | |
159 | 157 | pratopsaruse(argv[0]); |
160 | 158 | |
161 | 159 | saved_begintime = begintime; |
162 | 160 | break; |
163 | 161 | |
164 | 162 | case 'e': /* end time ? */ |
165 | if ( !hhmm2secs(optarg, &endtime) ) | |
163 | if ( !getbranchtime(optarg, &endtime) ) | |
166 | 164 | pratopsaruse(argv[0]); |
167 | 165 | break; |
168 | 166 | |
169 | 167 | case 'r': /* reading of file data ? */ |
170 | 168 | strncpy(rawname, optarg, RAWNAMESZ-1); |
169 | ||
170 | if (strcmp(rawname, "-") == 0) | |
171 | strcpy(rawname, "/dev/stdin"); | |
172 | ||
171 | 173 | rawreadflag++; |
172 | 174 | break; |
173 | 175 | |
353 | 355 | curtime = time(0); |
354 | 356 | |
355 | 357 | /* |
356 | ** regain the root-priviliges that we dropped at the beginning | |
357 | ** to do some priviliged work now | |
358 | ** regain the root-privileges that we dropped at the beginning | |
359 | ** to do some privileged work now | |
358 | 360 | */ |
359 | 361 | regainrootprivs(); |
360 | 362 | |
1003 | 1005 | int i; |
1004 | 1006 | |
1005 | 1007 | fprintf(stderr, |
1006 | "Usage: %s [-flags] [-r file|date|y...] [-R cnt] [-b hh:mm] [-e hh:mm]\n", | |
1008 | "Usage: %s [-flags] [-r file|-|date|y...] [-R cnt] [-b time] [-e time]\n", | |
1007 | 1009 | myname); |
1008 | 1010 | fprintf(stderr, "\t\tor\n"); |
1009 | 1011 | fprintf(stderr, |
1017 | 1019 | fprintf(stderr, |
1018 | 1020 | "\t -r read statistical data from specific atop logfile\n"); |
1019 | 1021 | fprintf(stderr, |
1020 | "\t (pathname, or date in format YYYYMMDD, or y[y..])\n"); | |
1022 | "\t (pathname, - for stdin, date in format YYYYMMDD, or y[y..])\n"); | |
1021 | 1023 | fprintf(stderr, |
1022 | 1024 | "\t -R summarize <cnt> samples into one sample\n"); |
1023 | 1025 | fprintf(stderr, |
1024 | "\t -b begin showing data from specified time\n"); | |
1026 | "\t -b begin showing data from specified time as [YYYYMMDD]hhmm\n"); | |
1025 | 1027 | fprintf(stderr, |
1026 | "\t -e finish showing data after specified time\n"); | |
1028 | "\t -e finish showing data after specified time as [YYYYMMDD]hhmm\n"); | |
1027 | 1029 | fprintf(stderr, |
1028 | 1030 | "\t -S print timestamp on every line in case of more " |
1029 | 1031 | "resources\n"); |
1131 | 1133 | } |
1132 | 1134 | |
1133 | 1135 | /* |
1134 | ** function the handle the default flags for atopsar as | |
1135 | ** read from the file ~/.atoprc | |
1136 | ** function to handle the default flags for atopsar as | |
1137 | ** read from the files ~/.atoprc and /etc/atoprc | |
1136 | 1138 | */ |
1137 | 1139 | void |
1138 | do_atopsarflags(char *val) | |
1140 | do_atopsarflags(char *name, char *val) | |
1139 | 1141 | { |
1140 | 1142 | int i, j; |
1141 | 1143 | |
1562 | 1564 | } |
1563 | 1565 | |
1564 | 1566 | /* |
1565 | ** swapping statistics | |
1567 | ** PSI statistics | |
1566 | 1568 | */ |
1567 | 1569 | static void |
1568 | 1570 | psihead(int osvers, int osrel, int ossub) |
1569 | 1571 | { |
1570 | printf("cs_10_60_300 ms_10_60_300 mf_10_60_300 " | |
1571 | "is_10_60_300 if_10_60_300"); | |
1572 | printf("cpusome memsome memfull iosome iofull"); | |
1572 | 1573 | } |
1573 | 1574 | |
1574 | 1575 | static int |
1577 | 1578 | int osvers, int osrel, int ossub, char *tstamp, |
1578 | 1579 | int ppres, int ntrun, int ntslpi, int ntslpu, int pexit, int pzombie) |
1579 | 1580 | { |
1581 | // calculate pressure percentages for entire interval | |
1582 | unsigned int csperc = ss->psi.cpusome.total/(deltatic*10000/hz); | |
1583 | unsigned int msperc = ss->psi.memsome.total/(deltatic*10000/hz); | |
1584 | unsigned int mfperc = ss->psi.memfull.total/(deltatic*10000/hz); | |
1585 | unsigned int isperc = ss->psi.iosome.total /(deltatic*10000/hz); | |
1586 | unsigned int ifperc = ss->psi.iofull.total /(deltatic*10000/hz); | |
1587 | unsigned int badness = 0; | |
1588 | ||
1580 | 1589 | if (!ss->psi.present) |
1581 | 1590 | { |
1582 | printf("no PSI stats available for this system .....\n"); | |
1583 | return 0; | |
1584 | } | |
1585 | ||
1586 | printf("%3.0f%%%3.0f%%%3.0f%% %3.0f%%%3.0f%%%3.0f%% " | |
1587 | "%3.0f%%%3.0f%%%3.0f%% %3.0f%%%3.0f%%%3.0f%% " | |
1588 | "%3.0f%%%3.0f%%%3.0f%%\n", | |
1589 | ss->psi.cpusome.avg10, ss->psi.cpusome.avg60, | |
1590 | ss->psi.cpusome.avg300, | |
1591 | ss->psi.memsome.avg10, ss->psi.memsome.avg60, | |
1592 | ss->psi.memsome.avg300, | |
1593 | ss->psi.memfull.avg10, ss->psi.memfull.avg60, | |
1594 | ss->psi.memfull.avg300, | |
1595 | ss->psi.iosome.avg10, ss->psi.iosome.avg60, | |
1596 | ss->psi.iosome.avg300, | |
1597 | ss->psi.iofull.avg10, ss->psi.iofull.avg60, | |
1598 | ss->psi.iofull.avg300); | |
1591 | printf("no PSI stats available for this interval...\n"); | |
1592 | return 1; | |
1593 | } | |
1594 | ||
1595 | // correct percentages if needed | |
1596 | if (csperc > 100) | |
1597 | csperc = 100; | |
1598 | ||
1599 | if (msperc > 100) | |
1600 | msperc = 100; | |
1601 | ||
1602 | if (mfperc > 100) | |
1603 | mfperc = 100; | |
1604 | ||
1605 | if (isperc > 100) | |
1606 | isperc = 100; | |
1607 | ||
1608 | if (ifperc > 100) | |
1609 | ifperc = 100; | |
1610 | ||
1611 | // consider a 'some' percentage > 0 as almost critical | |
1612 | // (I/O full tends to increase rapidly as well) | |
1613 | if (csperc || msperc || isperc || ifperc) | |
1614 | badness = 80; | |
1615 | ||
1616 | // consider a memory 'full' percentage > 0 as critical | |
1617 | if (mfperc) | |
1618 | badness = 100; | |
1619 | ||
1620 | // show results | |
1621 | preprint(badness); | |
1622 | ||
1623 | printf(" %3u%% %3u%% %3u%% %3u%% %3u%%", | |
1624 | csperc, msperc, mfperc, isperc, ifperc); | |
1625 | ||
1626 | postprint(badness); | |
1599 | 1627 | |
1600 | 1628 | return 1; |
1601 | 1629 | } |
1689 | 1717 | pn = dp->name; |
1690 | 1718 | |
1691 | 1719 | printf("%-14s %3.0lf%% %6.1lf %7.1lf %7.1lf %7.1lf " |
1692 | "%5.1lf %6.2lf ms", | |
1720 | "%5.1lf %9.5lf ms", | |
1693 | 1721 | pn, |
1694 | 1722 | mstot ? (double)dp->io_ms * 100.0 / mstot : 0.0, |
1695 | 1723 | mstot ? (double)dp->nread * 1000.0 / mstot : 0.0, |
166 | 166 | ** Initial revision |
167 | 167 | ** |
168 | 168 | */ |
169 | ||
170 | static const char rcsid[] = "$Id: deviate.c,v 1.45 2010/10/23 14:02:03 gerlof Exp $"; | |
171 | 169 | |
172 | 170 | #include <sys/types.h> |
173 | 171 | #include <sys/param.h> |
583 | 581 | devstat->cpu.curcpu = curstat->cpu.curcpu; |
584 | 582 | devstat->cpu.sleepavg = curstat->cpu.sleepavg; |
585 | 583 | |
584 | if (curstat->cpu.wchan[0]) | |
585 | strcpy(devstat->cpu.wchan, curstat->cpu.wchan); | |
586 | else | |
587 | devstat->cpu.wchan[0] = 0; | |
588 | ||
586 | 589 | devstat->mem.vexec = curstat->mem.vexec; |
587 | 590 | devstat->mem.vmem = curstat->mem.vmem; |
588 | 591 | devstat->mem.rmem = curstat->mem.rmem; |
591 | 594 | devstat->mem.vstack = curstat->mem.vstack; |
592 | 595 | devstat->mem.vlibs = curstat->mem.vlibs; |
593 | 596 | devstat->mem.vswap = curstat->mem.vswap; |
597 | devstat->mem.vlock = curstat->mem.vlock; | |
594 | 598 | |
595 | 599 | if (curstat->gpu.state || prestat->gpu.state) // GPU use? |
596 | 600 | { |
635 | 639 | if (devstat->cpu.utime > totusedcpu) |
636 | 640 | devstat->cpu.utime = 1; |
637 | 641 | |
642 | devstat->cpu.rundelay = | |
643 | subcount(curstat->cpu.rundelay, prestat->cpu.rundelay); | |
638 | 644 | /* |
639 | 645 | ** do further calculations |
640 | 646 | */ |
807 | 813 | dev->mem.cachedrt = cur->mem.cachedrt; |
808 | 814 | dev->mem.totswap = cur->mem.totswap; |
809 | 815 | dev->mem.freeswap = cur->mem.freeswap; |
816 | dev->mem.swapcached = cur->mem.swapcached; | |
810 | 817 | |
811 | 818 | dev->mem.shmem = cur->mem.shmem; |
812 | 819 | dev->mem.shmrss = cur->mem.shmrss; |
817 | 824 | dev->mem.hugepagesz = cur->mem.hugepagesz; |
818 | 825 | |
819 | 826 | dev->mem.vmwballoon = cur->mem.vmwballoon; |
827 | dev->mem.zfsarcsize = cur->mem.zfsarcsize; | |
820 | 828 | |
821 | 829 | dev->mem.swouts = subcount(cur->mem.swouts, pre->mem.swouts); |
822 | 830 | dev->mem.swins = subcount(cur->mem.swins, pre->mem.swins); |
1527 | 1535 | tot->mem.cachedrt = new->mem.cachedrt; |
1528 | 1536 | tot->mem.totswap = new->mem.totswap; |
1529 | 1537 | tot->mem.freeswap = new->mem.freeswap; |
1538 | tot->mem.swapcached = new->mem.swapcached; | |
1530 | 1539 | |
1531 | 1540 | tot->mem.shmem = new->mem.shmem; |
1532 | 1541 | tot->mem.shmrss = new->mem.shmrss; |
99 | 99 | void |
100 | 100 | initifprop(void) |
101 | 101 | { |
102 | FILE *fp; | |
103 | char *cp, linebuf[2048]; | |
104 | int i=0, sockfd; | |
105 | struct ethtool_cmd ethcmd; | |
106 | struct ifreq ifreq; | |
107 | struct iwreq iwreq; | |
102 | FILE *fp; | |
103 | char *cp, linebuf[2048]; | |
104 | int i=0, sockfd; | |
105 | ||
106 | struct ethtool_link_settings ethlink; // preferred! | |
107 | struct ethtool_cmd ethcmd; // deprecated | |
108 | ||
109 | struct ifreq ifreq; | |
110 | struct iwreq iwreq; | |
111 | ||
112 | unsigned long speed; | |
113 | unsigned char duplex, phy_addr, ethernet; | |
108 | 114 | |
109 | 115 | /* |
110 | 116 | ** open /proc/net/dev to obtain all interface names and open |
137 | 143 | |
138 | 144 | /* |
139 | 145 | ** determine properties of ethernet interface |
146 | ** preferably with actual struct ethtool_link_settings, | |
147 | ** otherwise with deprecated struct ethtool_cmd | |
140 | 148 | */ |
141 | 149 | memset(&ifreq, 0, sizeof ifreq); |
142 | 150 | memset(ðcmd, 0, sizeof ethcmd); |
144 | 152 | strncpy((void *)&ifreq.ifr_ifrn.ifrn_name, ifprops[i].name, |
145 | 153 | sizeof ifreq.ifr_ifrn.ifrn_name-1); |
146 | 154 | |
147 | ifreq.ifr_ifru.ifru_data = (void *)ðcmd; | |
148 | ||
149 | ethcmd.cmd = ETHTOOL_GSET; | |
150 | ||
151 | if ( ioctl(sockfd, SIOCETHTOOL, &ifreq) == 0) | |
155 | ethlink.cmd = ETHTOOL_GLINKSETTINGS; | |
156 | ifreq.ifr_ifru.ifru_data = (void *)ðlink; | |
157 | ||
158 | if ( ioctl(sockfd, SIOCETHTOOL, &ifreq) == 0) | |
159 | { | |
160 | ethernet = 1; | |
161 | speed = ethlink.speed; | |
162 | duplex = ethlink.duplex; | |
163 | phy_addr = ethlink.phy_address; | |
164 | } | |
165 | else | |
166 | { | |
167 | ethcmd.cmd = ETHTOOL_GSET; | |
168 | ifreq.ifr_ifru.ifru_data = (void *)ðcmd; | |
169 | ||
170 | if ( ioctl(sockfd, SIOCETHTOOL, &ifreq) == 0) | |
171 | { | |
172 | ethernet = 1; | |
173 | speed = ethcmd.speed; | |
174 | duplex = ethcmd.duplex; | |
175 | phy_addr = ethcmd.phy_address; | |
176 | } | |
177 | else | |
178 | { | |
179 | ethernet = 0; | |
180 | } | |
181 | } | |
182 | ||
183 | if (ethernet) | |
152 | 184 | { |
153 | 185 | ifprops[i].type = 'e'; // type ethernet |
154 | ifprops[i].speed = ethtool_cmd_speed(ðcmd); | |
155 | ||
156 | if (ifprops[i].speed == (u32)SPEED_UNKNOWN) | |
186 | ||
187 | if (speed == (u32)SPEED_UNKNOWN) | |
157 | 188 | ifprops[i].speed = 0; |
158 | ||
159 | switch (ethcmd.duplex) | |
189 | else | |
190 | ifprops[i].speed = speed; | |
191 | ||
192 | switch (duplex) | |
160 | 193 | { |
161 | 194 | case DUPLEX_FULL: |
162 | 195 | ifprops[i].fullduplex = 1; |
165 | 198 | ifprops[i].fullduplex = 0; |
166 | 199 | } |
167 | 200 | |
201 | if (!phy_addr) // virtual interface? | |
202 | { | |
203 | ifprops[i].type = '?'; // set type unknown | |
204 | ifprops[i].speed = 0; | |
205 | ifprops[i].fullduplex = 0; | |
206 | } | |
207 | ||
168 | 208 | if (++i >= MAXINTF-1) |
169 | 209 | break; |
170 | 210 | else |
194 | 234 | } |
195 | 235 | |
196 | 236 | ifprops[i].type = '?'; // type unknown |
237 | ifprops[i].speed = 0; | |
197 | 238 | ifprops[i].fullduplex = 0; |
198 | ifprops[i].speed = 0; | |
199 | 239 | |
200 | 240 | if (++i >= MAXINTF-1) |
201 | 241 | break; |
0 | .TH ATOP 1 "November 2019" "Linux" | |
0 | .TH ATOP 1 "December 2020" "Linux" | |
1 | 1 | .SH NAME |
2 | 2 | .B atop |
3 | 3 | - Advanced System & Process Monitor |
5 | 5 | Interactive Usage: |
6 | 6 | .P |
7 | 7 | .B atop |
8 | [\-g|\-m|\-d|\-n|\-u|\-p|\-s|\-c|\-v|\-o|\-y] [\-C|\-M|\-D|\-N|\-A] [\-afFG1xR] [\-L linelen] [\-Plabel[,label]...] | |
8 | [\-g|\-m|\-d|\-n|\-u|\-p|\-s|\-c|\-v|\-o|\-y|\-Y] [\-C|\-M|\-D|\-N|\-A] [\-afFG1xR] [\-L linelen] [\-Plabel[,label]...] | |
9 | 9 | [ |
10 | 10 | .I interval |
11 | 11 | [ |
28 | 28 | \-r [ |
29 | 29 | .I rawfile |
30 | 30 | ] [\-b |
31 | .I hh:mm | |
31 | .I [YYYYMMDD]hhmm | |
32 | 32 | ] [\-e |
33 | .I hh:mm | |
34 | ] [\-g|\-m|\-d|\-n|\-u|\-p|\-s|\-c|\-v|\-o|\-y] [\-C|\-M|\-D|\-N|\-A] [\-fFG1xR] [\-L linelen] [\-Plabel[,label]...] | |
33 | .I [YYYYMMDD]hhmm | |
34 | ] [\-g|\-m|\-d|\-n|\-u|\-p|\-s|\-c|\-v|\-o|\-y|\-Y] [\-C|\-M|\-D|\-N|\-A] [\-fFG1xR] [\-L linelen] [\-Plabel[,label]...] | |
35 | 35 | .SH DESCRIPTION |
36 | 36 | The program |
37 | 37 | .I atop |
524 | 524 | per individual thread (in a different color). Depending on |
525 | 525 | the option 'a' (all or active toggle), all threads are shown |
526 | 526 | or only the threads that were active during the last interval. |
527 | Depending on the option 'Y' (sort threads), the threads per | |
528 | process will be sorted on the chosen sort criterium or not. | |
527 | 529 | .br |
528 | 530 | Whether this key is active or not can be seen in the header line. |
531 | .PP | |
532 | .TP 5 | |
533 | .B Y | |
534 | Sort the threads per process when combined with option 'y' (toggle). | |
529 | 535 | .PP |
530 | 536 | .TP 5 |
531 | 537 | .B u |
644 | 650 | .B R |
645 | 651 | Gather and calculate the proportional set size of processes (toggle). |
646 | 652 | Gathering of all values that are needed to calculate the PSIZE of a process |
647 | is a relatively time-consuming task, so this key should only be active when | |
653 | is a very time-consuming task, so this key should only be active when | |
648 | 654 | analyzing the resident memory consumption of processes. |
655 | .PP | |
656 | .TP 5 | |
657 | .B W | |
658 | Get the WCHAN per thread (toggle). | |
659 | Gathering of the WCHAN string per thread | |
660 | is a relatively time-consuming task, so this key should only be made | |
661 | active when analyzing the reason for threads to be in sleep state. | |
649 | 662 | .PP |
650 | 663 | .TP 5 |
651 | 664 | .B x |
679 | 692 | particular application transaction, without knowing on beforehand how many |
680 | 693 | seconds this transaction will last. |
681 | 694 | |
682 | When viewing the contents of a raw file, this key can be used to show the | |
683 | next sample from the file. | |
695 | When viewing the contents of a raw file this key can be used to show the | |
696 | next sample from the file. This key can also be used when viewing raw data | |
697 | via a pipe. | |
684 | 698 | .PP |
685 | 699 | .TP 5 |
686 | 700 | .B T |
687 | When viewing the contents of a raw file, this key can be used to show the | |
688 | previous sample from the file (except when reading raw data from a named pipe). | |
701 | When viewing the contents of a raw file this key can be used to show the | |
702 | previous sample from the file, however not when reading raw data from a pipe. | |
689 | 703 | .PP |
690 | 704 | .TP 5 |
691 | 705 | .B b |
692 | 706 | When viewing the contents of a raw file, this key can be used to branch |
693 | to a certain timestamp within the file either forward or backward | |
694 | (except when reading raw data from a named pipe). | |
707 | to a certain timestamp within the file either forward or backward. | |
708 | When viewing raw data from a pipe only forward branches are possible. | |
695 | 709 | .PP |
696 | 710 | .TP 5 |
697 | 711 | .B r |
699 | 713 | boot again. |
700 | 714 | |
701 | 715 | When viewing the contents of a raw file, this key can be used to rewind |
702 | to the beginning of the file again | |
703 | (except when reading raw data from a named pipe). | |
716 | to the beginning of the file again (except when reading raw data from a pipe). | |
704 | 717 | .PP |
705 | 718 | .TP 5 |
706 | 719 | .B U |
906 | 919 | .BI y |
907 | 920 | is specified, yesterday's daily logfile is opened |
908 | 921 | (this can be repeated so 'yyyy' indicates the logfile of four days ago). |
922 | If the filename | |
923 | .BI - | |
924 | is used, stdin will be read. | |
909 | 925 | .br |
910 | 926 | The samples from the file can be viewed interactively by using the key 't' |
911 | 927 | to show the next sample, the key 'T' to show the previous sample, the |
923 | 939 | .B -b |
924 | 940 | (begin time) and/or |
925 | 941 | .B -e |
926 | (end time) followed by a time argument of the form HH:MM, | |
942 | (end time) followed by a time argument of the form [YYYYMMDD]hhmm, | |
927 | 943 | a certain time period within the raw file can be selected. |
928 | 944 | .PP |
929 | 945 | Every day at midnight |
930 | 946 | .B atop |
931 | 947 | is restarted to write compressed binary data to the file |
932 | 948 | .BI /var/log/atop/atop_ YYYYMMDD |
933 | with an interval of 10 minutes by default. The | |
934 | .B -R | |
935 | flag is passed by default to gather information about the proportional | |
936 | set size of every process. | |
949 | with an interval of 10 minutes by default. | |
937 | 950 | .br |
938 | 951 | Furthermore all raw files are removed that are older than 28 days |
939 | 952 | (by default). |
942 | 955 | .B /etc/default/atop |
943 | 956 | that might contain other values for |
944 | 957 | .B LOGOPTS |
945 | (by default the | |
946 | .B -R | |
947 | flag), | |
958 | (by default without any flag), | |
948 | 959 | .B LOGINTERVAL |
949 | 960 | (in seconds, by default 600), |
950 | 961 | .B LOGGENERATIONS |
1177 | 1188 | the amount of shared memory that is currently swapped (`shswp`), |
1178 | 1189 | the amount of memory that is currently claimed by vmware's |
1179 | 1190 | balloon driver (`vmbal`), |
1191 | the amount of memory that is currently claimed by the ARC (cache) | |
1192 | of ZFSonlinux (`zfarc`), | |
1180 | 1193 | the amount of memory that is claimed for huge pages (`hptot`), |
1181 | 1194 | and the amount of huge page memory that is really in use (`hpuse`). |
1182 | 1195 | |
1187 | 1200 | .B SWP |
1188 | 1201 | Swap occupation and overcommit info. |
1189 | 1202 | .br |
1190 | This line contains the total amount of swap space on disk (`tot') and | |
1191 | the amount of free swap space (`free'). | |
1203 | This line contains the total amount of swap space on disk (`tot'), | |
1204 | the amount of free swap space (`free') and the size of the swap cache | |
1205 | (`swcac'). | |
1192 | 1206 | .br |
1193 | 1207 | Furthermore the committed virtual memory space (`vmcom') and the maximum |
1194 | 1208 | limit of the committed space (`vmlim', which is by default swap size |
1214 | 1228 | .B PSI |
1215 | 1229 | Pressure Stall Information. |
1216 | 1230 | .br |
1217 | This line contains three percentages per category: | |
1218 | average pressure percentage over the last 10, 60 and 300 seconds | |
1219 | (separated by slashes). | |
1220 | .br | |
1221 | The categories are: CPU for 'some' (`cs'), | |
1222 | memory for 'some' (`ms'), memory for 'full' (`mf'), | |
1223 | I/O for 'some' (`is'), and I/O for 'full' (`if'). | |
1231 | This line contains percentages about resource pressure related to CPU, | |
1232 | memory and I/O. Certain percentages refer to 'some' meaning that some | |
1233 | processes/threads were delayed due to resource overload. Other | |
1234 | percentages refer to 'full' meaning a loss of overall throughput | |
1235 | due to resource overload. | |
1236 | .br | |
1237 | The values `cpusome', `memsome', `memfull', `iosome' and `iofull' | |
1238 | show the pressure percentage during the entire interval. | |
1239 | .br | |
1240 | The values `cs' (cpu some), `ms' (memory some), `mf' (memory full), | |
1241 | `is' (I/O some) and `if' (I/O full) each show | |
1242 | three percentages separated by slashes: | |
1243 | pressure percentage over the last 10, 60 and 300 seconds. | |
1224 | 1244 | .PP |
1225 | 1245 | .TP 5 |
1226 | 1246 | .B LVM/MDD/DSK |
1540 | 1560 | the width of the column, a hexadecimal value is shown. |
1541 | 1561 | .PP |
1542 | 1562 | .TP 9 |
1563 | .B LOCKSZ | |
1564 | The virtual amount of memory being locked (i.e. non-swappable) by this process (or user). | |
1565 | .PP | |
1566 | .TP 9 | |
1543 | 1567 | .B MAJFLT |
1544 | 1568 | The number of page faults issued by this process that have been solved |
1545 | 1569 | by creating/loading the requested memory page. |
1635 | 1659 | by all processes. |
1636 | 1660 | .br |
1637 | 1661 | Since gathering of all values that are needed to calculate the PSIZE is a |
1638 | relatively time-consuming task, the 'R' key (or '-R' flag) should | |
1662 | very time-consuming task, the 'R' key (or '-R' flag) should | |
1639 | 1663 | be active. Gathering these values also requires superuser privileges |
1640 | 1664 | (otherwise '?K' is shown in the output). |
1641 | 1665 | .br |
1654 | 1678 | data tranfer of a process to the data transfer of its parent process when |
1655 | 1679 | terminating, so you might see transfers for (parent) processes like |
1656 | 1680 | cron, bash or init, that are not really issued by them. |
1681 | .PP | |
1682 | .TP 9 | |
1683 | .B RDELAY | |
1684 | Runqueue delay, i.e. time spent waiting on a runqueue. | |
1657 | 1685 | .PP |
1658 | 1686 | .TP 9 |
1659 | 1687 | .B RGID |
1905 | 1933 | .TP 9 |
1906 | 1934 | .B VSTEXT |
1907 | 1935 | The virtual memory size of the (shared) text of the executable program. |
1936 | .PP | |
1937 | .TP 9 | |
1938 | .B WCHAN | |
1939 | Wait channel of thread in sleep state, i.e. the name of the kernel function | |
1940 | in which the thread has been put asleep. | |
1941 | .br | |
1942 | Since determining the name string of the kernel function is a | |
1943 | relatively time-consuming task, the 'W' key (or '-W' flag) should | |
1944 | be active. | |
1908 | 1945 | .PP |
1909 | 1946 | .TP 9 |
1910 | 1947 | .B WRDSK |
2050 | 2087 | size of resident shared memory (pages), |
2051 | 2088 | size of swapped shared memory (pages), |
2052 | 2089 | huge page size (in bytes), |
2053 | total size of huge pages (huge pages), and | |
2054 | size of free huge pages (huge pages). | |
2090 | total size of huge pages (huge pages), | |
2091 | size of free huge pages (huge pages), and | |
2092 | size of ARC (cache) of ZFSonlinux (pages). | |
2055 | 2093 | .TP 9 |
2056 | 2094 | .B SWP |
2057 | 2095 | Subsequent fields: |
2058 | 2096 | page size for this machine (in bytes), |
2059 | 2097 | size of swap (pages), |
2060 | 2098 | size of free swap (pages), |
2061 | 0 (future use), | |
2099 | size of swap cache (pages), | |
2062 | 2100 | size of committed space (pages), and |
2063 | 2101 | limit for committed space (pages). |
2064 | 2102 | .TP 9 |
2135 | 2173 | number of uncached requests. |
2136 | 2174 | .TP 9 |
2137 | 2175 | .B NET |
2138 | First one line is produced for the upper layers of the TCP/IP stack. | |
2176 | First, one line is produced for the upper layers of the TCP/IP stack. | |
2139 | 2177 | .br |
2140 | 2178 | Subsequent fields: |
2141 | 2179 | the verb "upper", |
2145 | 2183 | number of packets transmitted by UDP, |
2146 | 2184 | number of packets received by IP, |
2147 | 2185 | number of packets transmitted by IP, |
2148 | number of packets delivered to higher layers by IP, and | |
2149 | number of packets forwarded by IP. | |
2150 | ||
2151 | Next one line is shown for every interface. | |
2186 | number of packets delivered to higher layers by IP, | |
2187 | number of packets forwarded by IP, | |
2188 | number of input errors (UDP), | |
2189 | number of noport errors (UDP), | |
2190 | number of active opens (TCP), | |
2191 | number of passive opens (TCP), | |
2192 | number of passive opens (TCP), | |
2193 | number of established connections at this moment (TCP), | |
2194 | number of retransmitted segments (TCP), | |
2195 | number of input errors (TCP), and | |
2196 | number of output resets (TCP). | |
2197 | ||
2198 | Next, one line is shown for every interface. | |
2152 | 2199 | .br |
2153 | 2200 | Subsequent fields: |
2154 | 2201 | name of the interface, |
2183 | 2230 | effective uid, effective gid, |
2184 | 2231 | saved uid, saved gid, |
2185 | 2232 | filesystem uid, filesystem gid, elapsed time (hertz), |
2186 | is_process (y/n), OpenVZ virtual pid (VPID), OpenVZ container id (CTID) | |
2187 | and Docker container id (CID). | |
2233 | is_process (y/n), OpenVZ virtual pid (VPID), OpenVZ container id (CTID), | |
2234 | Docker container id (CID), and indication if the task is newly started | |
2235 | during this interval ('N'). | |
2188 | 2236 | .TP 9 |
2189 | 2237 | .B PRC |
2190 | 2238 | For every process one line is shown. |
2196 | 2244 | CPU-consumption in system mode (clockticks), |
2197 | 2245 | nice value, priority, realtime priority, |
2198 | 2246 | scheduling policy, current CPU, sleep average, |
2199 | TGID (group number of related tasks/threads) and is_process (y/n). | |
2247 | TGID (group number of related tasks/threads), is_process (y/n), | |
2248 | runqueue delay in nanoseconds for this thread or for all threads (in case of | |
2249 | process), and wait channel of this thread (between brackets). | |
2200 | 2250 | .TP 9 |
2201 | 2251 | .B PRE |
2202 | 2252 | For every process one line is shown. |
2229 | 2279 | virtual data size (Kbytes), |
2230 | 2280 | virtual stack size (Kbytes), |
2231 | 2281 | swap space used (Kbytes), |
2232 | TGID (group number of related tasks/threads), is_process (y/n) and | |
2233 | proportional set size (Kbytes) if in 'R' option is specified. | |
2282 | TGID (group number of related tasks/threads), is_process (y/n), | |
2283 | proportional set size (Kbytes) if in 'R' option is specified and | |
2284 | virtually locked memory space (Kbytes). | |
2234 | 2285 | .TP 9 |
2235 | 2286 | .B PRD |
2236 | 2287 | For every process one line is shown. |
2244 | 2295 | number of writes on disk, |
2245 | 2296 | cumulative number of sectors written, |
2246 | 2297 | cancelled number of written sectors, |
2247 | TGID (group number of related tasks/threads) and is_process (y/n). | |
2298 | TGID (group number of related tasks/threads), | |
2299 | obsoleted value ('n'), and is_process (y/n). | |
2248 | 2300 | .br |
2249 | 2301 | If the standard I/O statistics (>= 2.6.20) are not used, |
2250 | 2302 | the disk I/O counters per process are not relevant. |
2322 | 2374 | View the contents of the standard logfile of 2014, June 7 from |
2323 | 2375 | 02:00 PM onwards interactively: |
2324 | 2376 | .PP |
2325 | .B \ atop -r 20140607 -b 14:00 | |
2377 | .B \ atop -r 20140607 -b 1400 | |
2378 | .PP | |
2379 | Concatenate all raw log files of January 2020 and generate parsable | |
2380 | output about the CPU utilization: | |
2381 | .PP | |
2382 | .TP 12 | |
2383 | .B \ atopcat /var/log/atop/atop_202001?? | atop -r - -PCPU | |
2326 | 2384 | .PP |
2327 | 2385 | .SH FILES |
2328 | 2386 | .PP |
2363 | 2421 | .TP 8 |
2364 | 2422 | \ |
2365 | 2423 | .br |
2366 | LOGOPTS="-R" | |
2424 | LOGOPTS="" | |
2367 | 2425 | .br |
2368 | 2426 | LOGINTERVAL=600 |
2369 | 2427 | .br |
2396 | 2454 | .SH SEE ALSO |
2397 | 2455 | .B atopsar(1), |
2398 | 2456 | .B atopconvert(1), |
2457 | .B atopcat(1), | |
2399 | 2458 | .B atoprc(5), |
2400 | 2459 | .B atopacctd(8), |
2401 | 2460 | .B netatop(4), |
0 | .TH ATOPACCTD 8 "November 2019" "Linux" | |
0 | .TH ATOPACCTD 8 "December 2020" "Linux" | |
1 | 1 | .SH NAME |
2 | 2 | .B atopacctd |
3 | 3 | - process accounting daemon |
0 | .TH ATOPCAT 1 "December 2020" "Linux" | |
1 | .SH NAME | |
2 | .B atopcat | |
3 | - concatenate raw log files to stdout | |
4 | .SH SYNOPSIS | |
5 | .P | |
6 | .B atopcat [-dv] rawfile [rawfile]... | |
7 | .P | |
8 | .SH DESCRIPTION | |
9 | The program | |
10 | .I atopcat | |
11 | can be used to concatenate several raw log files into one stream (stdout). | |
12 | In this way, raw log files can be merged into one larger file by redirecting | |
13 | stdout to a file. Alternatively, merged data from several raw log files | |
14 | can be transferred directly into | |
15 | .I atop | |
16 | or | |
17 | .I atopsar | |
18 | via a pipe. | |
19 | ||
20 | Options: | |
21 | .PP | |
22 | .TP 5 | |
23 | .B -d | |
24 | dry-run: read logfile(s) but do not generate output on stdout | |
25 | .PP | |
26 | .TP 5 | |
27 | .B -v | |
28 | verbose: print one line per sample containing date/time, interval length | |
29 | in seconds, compressed length of the system-level information and | |
30 | compressed length of the process-level information. | |
31 | .SH EXAMPLES | |
32 | Concatenate the raw log files of five contiguous working days, | |
33 | write it into a new raw log file for that week and | |
34 | view that week interactively: | |
35 | .PP | |
36 | .TP 12 | |
37 | .B \ atopcat /var/log/atop/atop_2020021[0-4] > week_2020_7 | |
38 | .TP 12 | |
39 | .B \ atop -r week_2020_7 | |
40 | .PP | |
41 | Concatenate the raw log files of a week and view that week interactively | |
42 | (since | |
43 | .I atop | |
44 | reads from a pipe, previous intervals can not be retrieved while viewing): | |
45 | .PP | |
46 | .TP 12 | |
47 | .B \ atopcat /var/log/atop/atop_2020021[0-6] | atop -r - | |
48 | .PP | |
49 | Concatenate all raw log files of January 2020 and generate parsable | |
50 | output about the CPU utilization: | |
51 | .PP | |
52 | .TP 12 | |
53 | .B \ atopcat /var/log/atop/atop_202001?? | atop -r - -PCPU | |
54 | .PP | |
55 | Concatenate the daily raw log files of February 3 and 4, | |
56 | and generate a report about memory utilization from 14:00h on the first day | |
57 | till 11:00h on the second day: | |
58 | .PP | |
59 | .TP 12 | |
60 | .B \ atopcat /var/log/atop/atop_2020020[34] | | |
61 | .B \ atopsar -m -r - -b 202002031400 -e 202002041100 | |
62 | .PP | |
63 | Repair a raw log file from which the last interval has not been | |
64 | completely written (e.g. if you intend to expand the file with new samples): | |
65 | .PP | |
66 | .TP 12 | |
67 | .B \ atopcat /var/log/atop/atop_20200303 > /tmp/repaired | |
68 | .PP | |
69 | In the latter case, | |
70 | .B atopcat | |
71 | reports that the input file is incomplete and stops after the last consistent | |
72 | sample. | |
73 | .SH SEE ALSO | |
74 | .B atop(1), | |
75 | .B atopsar(1), | |
76 | .B atopconvert(1) | |
77 | .br | |
78 | .B https://www.atoptool.nl | |
79 | .SH AUTHOR | |
80 | Gerlof Langeveld (gerlof.langeveld@atoptool.nl) |
0 | .TH ATOPCONVERT 1 "November 2019" "Linux" | |
0 | .TH ATOPCONVERT 1 "December 2020" "Linux" | |
1 | 1 | .SH NAME |
2 | 2 | .B atopconvert |
3 | 3 | - convert raw log file to newer version |
44 | 44 | Files can only be upgraded to higher version, but not downgraded. |
45 | 45 | .SH SEE ALSO |
46 | 46 | .B atop(1), |
47 | .B atopsar(1) | |
47 | .B atopsar(1), | |
48 | .B atopcat(1) | |
48 | 49 | .br |
49 | 50 | .B https://www.atoptool.nl |
50 | 51 | .SH AUTHOR |
0 | .TH ATOPGPUD 8 "November 2019" "Linux" | |
0 | .TH ATOPGPUD 8 "December 2020" "Linux" | |
1 | 1 | .SH NAME |
2 | 2 | .B atopgpud |
3 | 3 | - GPU statistics daemon |
0 | .TH ATOPRC 5 "November 2019" "Linux" | |
0 | .TH ATOPRC 5 "December 2020" "Linux" | |
1 | 1 | .SH NAME |
2 | 2 | .B atoprc |
3 | 3 | - atop/atopsar related rcfile |
31 | 31 | .B atop |
32 | 32 | can be defined here. The flags which are allowed |
33 | 33 | are 'g', 'm', 'd', 'n', 'u', 'p', 's', 'c', 'v', 'C', 'M', 'D', 'N', 'A', |
34 | \&'a', 'y', 'f', 'F', 'G', 'R', '1', 'e', 'E' and 'x'. | |
34 | \&'a', 'y', 'Y', 'f', 'F', 'G', 'R', '1', 'e', 'E' and 'x'. | |
35 | 35 | .PP |
36 | 36 | .TP 4 |
37 | 37 | .B interval |
0 | .TH ATOPSAR 1 "November 2019" "Linux" | |
0 | .TH ATOPSAR 1 "December 2020" "Linux" | |
1 | 1 | .SH NAME |
2 | 2 | .B atopsar |
3 | 3 | - Advanced System Activity Report (atop related) |
6 | 6 | .B atopsar |
7 | 7 | [\-flags...] |
8 | 8 | [\-r |
9 | .I file|date | |
9 | .I file|date|- | |
10 | 10 | ] [\-R |
11 | 11 | .I cnt |
12 | 12 | ] [\-b |
13 | .I hh:mm | |
13 | .I [YYYYMMDD]hhmm | |
14 | 14 | ] [\-e |
15 | .I hh:mm | |
15 | .I [YYYYMMDD]hhmm | |
16 | 16 | ] |
17 | 17 | .br |
18 | 18 | .B atopsar |
52 | 52 | .B -r |
53 | 53 | option instead of the filename, or |
54 | 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). | |
55 | (this can be repeated so 'yyyy' indicates the logfile of four days ago), or | |
56 | the filename '-' can be used to read raw data from stdin. | |
56 | 57 | If the |
57 | 58 | .B -r |
58 | 59 | option is not specified at all, today's daily logfile is used by default. |
62 | 63 | .B -b |
63 | 64 | and |
64 | 65 | .B -e |
65 | followed by a time argument of the form hh:mm. | |
66 | followed by a time argument of the form [YYYYMMDD]hhmm. | |
66 | 67 | .PP |
67 | 68 | In the second synopsis line, |
68 | 69 | .B atopsar |
488 | 489 | .B -B |
489 | 490 | contains the Pressure Stall Information (PSI): |
490 | 491 | .TP 12 |
491 | .B cs_10_60_300 | |
492 | Average pressure percentage over the last 10, 60 and 300 seconds for the | |
492 | .B cpusome | |
493 | Average pressure percentage during the interval for the | |
493 | 494 | category 'CPU some'. |
494 | 495 | .TP 12 |
495 | .B ms_10_60_300 | |
496 | Average pressure percentage over the last 10, 60 and 300 seconds for the | |
496 | .B memsome | |
497 | Average pressure percentage during the interval for the | |
497 | 498 | category 'memory some'. |
498 | 499 | .TP 12 |
499 | .B mf_10_60_300 | |
500 | Average pressure percentage over the last 10, 60 and 300 seconds for the | |
500 | .B memfull | |
501 | Average pressure percentage during the interval for the | |
501 | 502 | category 'memory full'. |
502 | 503 | .TP 12 |
503 | .B is_10_60_300 | |
504 | Average pressure percentage over the last 10, 60 and 300 seconds for the | |
504 | .B iosome | |
505 | Average pressure percentage during the interval for the | |
505 | 506 | category 'I/O some'. |
506 | 507 | .TP 12 |
507 | .B if_10_60_300 | |
508 | Average pressure percentage over the last 10, 60 and 300 seconds for the | |
508 | .B iofull | |
509 | Average pressure percentage during the interval for the | |
509 | 510 | category 'I/O full'. |
510 | 511 | .PP |
511 | 512 | The output for the flags |
1234 | 1235 | .SH SEE ALSO |
1235 | 1236 | .B atop(1), |
1236 | 1237 | .B atopconvert(1), |
1238 | .B atopcat(1), | |
1237 | 1239 | .B atoprc(5), |
1238 | 1240 | .B atopacctd(8), |
1239 | 1241 | .B netatop(4), |
54 | 54 | /* |
55 | 55 | ** storage of last exited tasks read from exitfile |
56 | 56 | ** every exitstore struct is registered in hash buckets, |
57 | ** by its pid or by its begintime | |
57 | ** by its pid or by its begin time | |
58 | 58 | */ |
59 | 59 | struct exitstore { |
60 | 60 | struct exitstore *next; |
343 | 343 | nexitnet = nahp->curseq - lastseq; |
344 | 344 | lastseq = nahp->curseq; |
345 | 345 | |
346 | if (nexitnet == 0) | |
347 | return 0; | |
348 | ||
346 | 349 | /* |
347 | 350 | ** allocate storage for all exited processes |
348 | 351 | */ |
429 | 432 | |
430 | 433 | /* |
431 | 434 | ** add all stored tasks to a hash bucket, either |
432 | ** by pid (argument 'p') or by begintime (argument 'b') | |
435 | ** by pid (argument 'p') or by begin time (argument 'b') | |
433 | 436 | */ |
434 | 437 | void |
435 | 438 | netatop_exithash(char hashtype) |
484 | 487 | fill_networkcnt(dev, pre, esp); |
485 | 488 | break; |
486 | 489 | |
487 | case 'b': // search by begintime | |
490 | case 'b': // search by begin time | |
488 | 491 | if (esp->isused) |
489 | 492 | continue; |
490 | 493 |
74 | 74 | #include <unistd.h> |
75 | 75 | #include <stdlib.h> |
76 | 76 | #include <string.h> |
77 | #include <limits.h> | |
77 | 78 | #include <sys/utsname.h> |
78 | 79 | |
79 | 80 | #include "atop.h" |
420 | 421 | void |
421 | 422 | print_MEM(char *hp, struct sstat *ss, struct tstat *ps, int nact) |
422 | 423 | { |
423 | printf( "%s %u %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", | |
424 | printf( "%s %u %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", | |
424 | 425 | hp, |
425 | 426 | pagesize, |
426 | 427 | ss->mem.physmem, |
436 | 437 | ss->mem.shmswp, |
437 | 438 | ss->mem.hugepagesz, |
438 | 439 | ss->mem.tothugepage, |
439 | ss->mem.freehugepage); | |
440 | ss->mem.freehugepage, | |
441 | ss->mem.zfsarcsize); | |
440 | 442 | } |
441 | 443 | |
442 | 444 | void |
447 | 449 | pagesize, |
448 | 450 | ss->mem.totswap, |
449 | 451 | ss->mem.freeswap, |
450 | (long long)0, | |
452 | ss->mem.swapcached, | |
451 | 453 | ss->mem.committed, |
452 | 454 | ss->mem.commitlim); |
453 | 455 | } |
598 | 600 | { |
599 | 601 | register int i; |
600 | 602 | |
601 | printf( "%s %s %lld %lld %lld %lld %lld %lld %lld %lld\n", | |
603 | printf( "%s %s %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", | |
602 | 604 | hp, |
603 | 605 | "upper", |
604 | 606 | ss->net.tcp.InSegs, |
614 | 616 | ss->net.ipv4.InDelivers + |
615 | 617 | ss->net.ipv6.Ip6InDelivers, |
616 | 618 | ss->net.ipv4.ForwDatagrams + |
617 | ss->net.ipv6.Ip6OutForwDatagrams); | |
619 | ss->net.ipv6.Ip6OutForwDatagrams, | |
620 | ss->net.udpv4.InErrors + | |
621 | ss->net.udpv6.Udp6InErrors, | |
622 | ss->net.udpv4.NoPorts + | |
623 | ss->net.udpv6.Udp6NoPorts, | |
624 | ss->net.tcp.ActiveOpens, | |
625 | ss->net.tcp.PassiveOpens, | |
626 | ss->net.tcp.CurrEstab, | |
627 | ss->net.tcp.RetransSegs, | |
628 | ss->net.tcp.InErrs, | |
629 | ss->net.tcp.OutRsts); | |
618 | 630 | |
619 | 631 | for (i=0; ss->intf.intf[i].name[0]; i++) |
620 | 632 | { |
667 | 679 | exitcode = (ps->gen.excode >> 8) & 0xff; |
668 | 680 | |
669 | 681 | printf("%s %d (%s) %c %d %d %d %d %d %ld (%s) %d %d %d %d " |
670 | "%d %d %d %d %d %d %ld %c %d %d %s\n", | |
682 | "%d %d %d %d %d %d %ld %c %d %d %s %c\n", | |
671 | 683 | hp, |
672 | 684 | ps->gen.pid, |
673 | 685 | ps->gen.name, |
693 | 705 | ps->gen.isproc ? 'y':'n', |
694 | 706 | ps->gen.vpid, |
695 | 707 | ps->gen.ctid, |
696 | ps->gen.container[0] ? ps->gen.container:"-"); | |
708 | ps->gen.container[0] ? ps->gen.container:"-", | |
709 | ps->gen.excode & ~(INT_MAX) ? 'N' : '-'); | |
697 | 710 | } |
698 | 711 | } |
699 | 712 | |
704 | 717 | |
705 | 718 | for (i=0; i < nact; i++, ps++) |
706 | 719 | { |
707 | printf("%s %d (%s) %c %u %lld %lld %d %d %d %d %d %d %d %c\n", | |
720 | printf("%s %d (%s) %c %u %lld %lld %d %d %d %d %d %d %d %c " | |
721 | "%llu (%s)\n", | |
708 | 722 | hp, |
709 | 723 | ps->gen.pid, |
710 | 724 | ps->gen.name, |
719 | 733 | ps->cpu.curcpu, |
720 | 734 | ps->cpu.sleepavg, |
721 | 735 | ps->gen.tgid, |
722 | ps->gen.isproc ? 'y':'n'); | |
736 | ps->gen.isproc ? 'y':'n', | |
737 | ps->cpu.rundelay, | |
738 | ps->cpu.wchan); | |
723 | 739 | } |
724 | 740 | } |
725 | 741 | |
731 | 747 | for (i=0; i < nact; i++, ps++) |
732 | 748 | { |
733 | 749 | printf("%s %d (%s) %c %u %lld %lld %lld %lld %lld %lld " |
734 | "%lld %lld %lld %lld %lld %d %c %lld\n", | |
750 | "%lld %lld %lld %lld %lld %d %c %lld %lld\n", | |
735 | 751 | hp, |
736 | 752 | ps->gen.pid, |
737 | 753 | ps->gen.name, |
751 | 767 | ps->gen.tgid, |
752 | 768 | ps->gen.isproc ? 'y':'n', |
753 | 769 | ps->mem.pmem == (unsigned long long)-1LL ? |
754 | 0:ps->mem.pmem); | |
770 | 0:ps->mem.pmem, | |
771 | ps->mem.vlock); | |
755 | 772 | } |
756 | 773 | } |
757 | 774 |
135 | 135 | ** |
136 | 136 | */ |
137 | 137 | |
138 | static const char rcsid[] = "$Id: photoproc.c,v 1.33 2010/04/23 12:19:35 gerlof Exp $"; | |
139 | ||
140 | 138 | #include <sys/types.h> |
141 | 139 | #include <sys/param.h> |
142 | 140 | #include <dirent.h> |
167 | 165 | static int proccont(struct tstat *); |
168 | 166 | static void proccmd(struct tstat *); |
169 | 167 | static void procsmaps(struct tstat *); |
168 | static void procwchan(struct tstat *); | |
169 | static count_t procschedstat(struct tstat *); | |
170 | 170 | |
171 | 171 | unsigned long |
172 | 172 | photoproc(struct tstat *tasklist, int maxtask) |
268 | 268 | continue; |
269 | 269 | } |
270 | 270 | |
271 | procschedstat(curtask); /* from /proc/pid/schedstat */ | |
271 | 272 | proccmd(curtask); /* from /proc/pid/cmdline */ |
272 | 273 | dockstat += proccont(curtask); /* from /proc/pid/cpuset */ |
273 | 274 | |
279 | 280 | if (calcpss) |
280 | 281 | procsmaps(curtask); /* from /proc/pid/smaps */ |
281 | 282 | |
283 | /* | |
284 | ** determine thread's wchan, if wanted ('expensive' from | |
285 | ** a CPU consumption point-of-view) | |
286 | */ | |
287 | if (getwchan) | |
288 | procwchan(curtask); | |
289 | ||
282 | 290 | // read network stats from netatop |
283 | 291 | netatop_gettask(curtask->gen.tgid, 'g', curtask); |
284 | 292 | |
296 | 304 | curtask->gen.nthrrun = 0; |
297 | 305 | curtask->gen.nthrslpi = 0; |
298 | 306 | curtask->gen.nthrslpu = 0; |
307 | ||
308 | /* | |
309 | ** rundelay on process level is equal to the rundelay | |
310 | ** of the main thread; totalize the rundelays of all | |
311 | ** threads | |
312 | */ | |
313 | curtask->cpu.rundelay = 0; | |
299 | 314 | |
300 | 315 | /* |
301 | 316 | ** open underlying task directory |
344 | 359 | continue; |
345 | 360 | } |
346 | 361 | |
362 | /* | |
363 | ** determine thread's wchan, if wanted | |
364 | ** ('expensive' from a CPU consumption | |
365 | ** point-of-view) | |
366 | */ | |
367 | if (getwchan) | |
368 | procwchan(curthr); | |
369 | ||
370 | /* totalize rundelays of all threads */ | |
371 | curtask->cpu.rundelay += | |
372 | procschedstat(curthr); | |
373 | ||
347 | 374 | strcpy(curthr->gen.container, |
348 | 375 | curtask->gen.container); |
349 | 376 | |
654 | 681 | continue; |
655 | 682 | } |
656 | 683 | |
684 | if (memcmp(line, "VmLck:", 6)==0) | |
685 | { | |
686 | sscanf(line, "VmLck: %lld", &(curtask->mem.vlock)); | |
687 | continue; | |
688 | } | |
689 | ||
657 | 690 | if (memcmp(line, "SigQ:", 5)==0) |
658 | 691 | break; |
659 | 692 | } |
760 | 793 | } |
761 | 794 | } |
762 | 795 | } |
796 | } | |
797 | ||
798 | ||
799 | /* | |
800 | ** determine the wait channel of a sleeping thread | |
801 | ** i.e. the name of the kernel function in which the thread | |
802 | ** has been put in sleep state) | |
803 | */ | |
804 | static void | |
805 | procwchan(struct tstat *curtask) | |
806 | { | |
807 | FILE *fp; | |
808 | register int nr = 0; | |
809 | ||
810 | if ( (fp = fopen("wchan", "r")) != NULL) | |
811 | { | |
812 | ||
813 | nr = fread(curtask->cpu.wchan, 1, | |
814 | sizeof(curtask->cpu.wchan)-1, fp); | |
815 | if (nr < 0) | |
816 | nr = 0; | |
817 | fclose(fp); | |
818 | } | |
819 | ||
820 | curtask->cpu.wchan[nr] = 0; | |
763 | 821 | } |
764 | 822 | |
765 | 823 | |
855 | 913 | |
856 | 914 | procsmaps_firstcall = 0; |
857 | 915 | } |
916 | ||
858 | 917 | /* |
859 | 918 | ** open the file (always succeeds, even if no root privs) |
860 | 919 | */ |
890 | 949 | if (! droprootprivs()) |
891 | 950 | mcleanstop(42, "failed to drop root privs\n"); |
892 | 951 | } |
952 | ||
953 | /* | |
954 | ** get run_delay from /proc/<pid>/schedstat | |
955 | ** ref: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/scheduler/sched-stats.rst?h=v5.7-rc6 | |
956 | */ | |
957 | static count_t | |
958 | procschedstat(struct tstat *curtask) | |
959 | { | |
960 | FILE *fp; | |
961 | char line[4096]; | |
962 | count_t runtime, rundelay = 0; | |
963 | unsigned long pcount; | |
964 | static char *schedstatfile = "schedstat"; | |
965 | ||
966 | /* | |
967 | ** open the schedstat file | |
968 | */ | |
969 | if ( (fp = fopen(schedstatfile, "r")) ) | |
970 | { | |
971 | curtask->cpu.rundelay = 0; | |
972 | ||
973 | if (fgets(line, sizeof line, fp)) | |
974 | { | |
975 | sscanf(line, "%llu %llu %lu\n", | |
976 | &runtime, &rundelay, &pcount); | |
977 | ||
978 | curtask->cpu.rundelay = rundelay; | |
979 | } | |
980 | ||
981 | /* | |
982 | ** verify if fgets returned NULL due to error i.s.o. EOF | |
983 | */ | |
984 | if (ferror(fp)) | |
985 | curtask->cpu.rundelay = 0; | |
986 | ||
987 | fclose(fp); | |
988 | } | |
989 | else | |
990 | { | |
991 | curtask->cpu.rundelay = 0; | |
992 | } | |
993 | ||
994 | return curtask->cpu.rundelay; | |
995 | } |
74 | 74 | int curcpu; /* current processor */ |
75 | 75 | int sleepavg; /* sleep average percentage */ |
76 | 76 | int ifuture[4]; /* reserved for future use */ |
77 | count_t cfuture[4]; /* reserved for future use */ | |
77 | char wchan[16]; /* wait channel string */ | |
78 | count_t rundelay; /* schedstat rundelay (nanosec) */ | |
79 | count_t cfuture[1]; /* reserved for future use */ | |
78 | 80 | } cpu; |
79 | 81 | |
80 | 82 | /* DISK STATISTICS */ |
102 | 104 | count_t vstack; /* virtmem stack (Kb) */ |
103 | 105 | count_t vlibs; /* virtmem libexec (Kb) */ |
104 | 106 | count_t vswap; /* swap space used (Kb) */ |
105 | count_t cfuture[4]; /* reserved for future use */ | |
107 | count_t vlock; /* virtual locked (Kb) */ | |
108 | count_t cfuture[3]; /* reserved for future use */ | |
106 | 109 | } mem; |
107 | 110 | |
108 | 111 | /* NETWORK STATISTICS */ |
148 | 148 | ** |
149 | 149 | */ |
150 | 150 | |
151 | static const char rcsid[] = "$Id: photosyst.c,v 1.38 2010/11/19 07:40:40 gerlof Exp $"; | |
152 | ||
153 | 151 | #include <sys/types.h> |
154 | 152 | #include <stdio.h> |
155 | 153 | #include <string.h> |
156 | 154 | #include <unistd.h> |
157 | 155 | #include <stdlib.h> |
156 | #include <errno.h> | |
158 | 157 | #include <regex.h> |
159 | 158 | #include <sys/stat.h> |
160 | 159 | #include <sys/times.h> |
654 | 653 | si->mem.shmem = (count_t) 0; |
655 | 654 | si->mem.totswap = (count_t)-1; |
656 | 655 | si->mem.freeswap = (count_t)-1; |
656 | si->mem.swapcached = (count_t) 0; | |
657 | 657 | si->mem.committed = (count_t) 0; |
658 | 658 | |
659 | 659 | if ( (fp = fopen("meminfo", "r")) != NULL) |
739 | 739 | cnts[0]*1024/pagesize; |
740 | 740 | } |
741 | 741 | } |
742 | else if (strcmp("SwapCached:", nam) == EQ) | |
743 | { | |
744 | si->mem.swapcached = | |
745 | cnts[0]*1024/pagesize; | |
746 | } | |
742 | 747 | else if (strcmp("Slab:", nam) == EQ) |
743 | 748 | { |
744 | 749 | si->mem.slabmem = cnts[0]*1024/pagesize; |
790 | 795 | if ( strcmp("current:", nam) == EQ) |
791 | 796 | { |
792 | 797 | si->mem.vmwballoon = cnts[0]; |
798 | break; | |
799 | } | |
800 | } | |
801 | ||
802 | fclose(fp); | |
803 | } | |
804 | ||
805 | /* | |
806 | ** ZFSonlinux: gather size of ARC cache in memory | |
807 | ** searching for: | |
808 | ** size 4 519101312 | |
809 | */ | |
810 | si->mem.zfsarcsize = (count_t) 0; | |
811 | ||
812 | if ( (fp = fopen("spl/kstat/zfs/arcstats", "r")) != NULL) | |
813 | { | |
814 | while ( fgets(linebuf, sizeof(linebuf), fp) != NULL) | |
815 | { | |
816 | nr = sscanf(linebuf, | |
817 | "%s %lld %lld", nam, &cnts[0], &cnts[1]); | |
818 | ||
819 | if (nr < 3) | |
820 | continue; | |
821 | ||
822 | if ( strcmp("size", nam) == EQ) | |
823 | { | |
824 | si->mem.zfsarcsize = cnts[1] / pagesize; | |
793 | 825 | break; |
794 | 826 | } |
795 | 827 | } |
1588 | 1620 | DIR *dirp; |
1589 | 1621 | struct dirent *dentry; |
1590 | 1622 | struct stat statbuf; |
1591 | char path[64]; | |
1623 | char path[PATH_MAX]; | |
1592 | 1624 | |
1593 | 1625 | if ( (dirp = opendir(MAPDIR)) ) |
1594 | 1626 | { |
1827 | 1859 | |
1828 | 1860 | if (firstcall) |
1829 | 1861 | { |
1830 | char path[128], *p; | |
1862 | char path[PATH_MAX], *p; | |
1831 | 1863 | struct stat statbuf; |
1832 | 1864 | struct dirent *contdent, *portdent; |
1833 | 1865 | DIR *contp, *portp; |
1943 | 1975 | ibprep(struct ibcachent *ibc) |
1944 | 1976 | { |
1945 | 1977 | FILE *fp; |
1946 | char path[128], linebuf[64], speedunit; | |
1978 | char path[PATH_MAX], linebuf[64], speedunit; | |
1947 | 1979 | |
1948 | 1980 | // determine port rate and number of lanes |
1949 | 1981 | snprintf(path, sizeof path, "%s/ports/%d/rate", ibc->ibha, ibc->port); |
1954 | 1986 | { |
1955 | 1987 | (void) sscanf(linebuf, "%lld %c%*s (%hdX", |
1956 | 1988 | &(ibc->rate), &speedunit, &(ibc->lanes)); |
1989 | ||
1990 | // calculate megabits/second | |
1991 | switch (speedunit) | |
1992 | { | |
1993 | case 'M': | |
1994 | case 'm': | |
1995 | break; | |
1996 | case 'G': | |
1997 | case 'g': | |
1998 | ibc->rate *= 1000; | |
1999 | break; | |
2000 | case 'T': | |
2001 | case 't': | |
2002 | ibc->rate *= 1000000; | |
2003 | break; | |
2004 | } | |
2005 | ||
2006 | } | |
2007 | else | |
2008 | { | |
2009 | ibc->lanes = 0; | |
2010 | ibc->rate = 0; | |
1957 | 2011 | } |
1958 | 2012 | |
1959 | 2013 | fclose(fp); |
1960 | } | |
1961 | ||
1962 | // calculate megabits/second | |
1963 | switch (speedunit) | |
1964 | { | |
1965 | case 'M': | |
1966 | case 'm': | |
1967 | break; | |
1968 | case 'G': | |
1969 | case 'g': | |
1970 | ibc->rate *= 1000; | |
1971 | break; | |
1972 | case 'T': | |
1973 | case 't': | |
1974 | ibc->rate *= 1000000; | |
1975 | break; | |
1976 | 2014 | } |
1977 | 2015 | |
1978 | 2016 | // build all pathnames to obtain the counters |
2109 | 2147 | { |
2110 | 2148 | static int firstcall = 1, cpualloced, *fdi, *fdc; |
2111 | 2149 | int i; |
2150 | int liResult; | |
2112 | 2151 | |
2113 | 2152 | if (!enable_perfevents()) |
2114 | 2153 | return; |
2195 | 2234 | { |
2196 | 2235 | if (*(fdi+i) != -1) |
2197 | 2236 | { |
2198 | read(*(fdi+i), &(cs->cpu[i].instr), sizeof(count_t)); | |
2237 | liResult = read(*(fdi+i), &(cs->cpu[i].instr), sizeof(count_t)); | |
2199 | 2238 | cs->all.instr += cs->cpu[i].instr; |
2200 | ||
2201 | read(*(fdc+i), &(cs->cpu[i].cycle), sizeof(count_t)); | |
2239 | if(liResult < 0) | |
2240 | { | |
2241 | char lcMessage[64]; | |
2242 | ||
2243 | snprintf(lcMessage, sizeof(lcMessage) - 1, | |
2244 | "%s:%d - Error %d reading instr counters\n", | |
2245 | __FILE__, __LINE__, errno); | |
2246 | fprintf(stderr, "%s", lcMessage); | |
2247 | } | |
2248 | ||
2249 | liResult = read(*(fdc+i), &(cs->cpu[i].cycle), sizeof(count_t)); | |
2202 | 2250 | cs->all.cycle += cs->cpu[i].cycle; |
2251 | if(liResult < 0) | |
2252 | { | |
2253 | char lcMessage[64]; | |
2254 | ||
2255 | snprintf(lcMessage, sizeof(lcMessage) - 1, | |
2256 | "%s:%d - Error %d reading cycle counters\n", | |
2257 | __FILE__, __LINE__, errno ); | |
2258 | fprintf(stderr, "%s", lcMessage); | |
2259 | } | |
2203 | 2260 | } |
2204 | 2261 | } |
2205 | 2262 | } |
72 | 72 | count_t hugepagesz; // huge page size (bytes) |
73 | 73 | |
74 | 74 | count_t vmwballoon; // vmware claimed balloon pages |
75 | count_t cfuture[8]; // reserved for future use | |
75 | count_t zfsarcsize; // zfsonlinux ARC size (pages) | |
76 | count_t swapcached; // swap cache (pages) | |
77 | count_t cfuture[6]; // reserved for future use | |
76 | 78 | }; |
77 | 79 | |
78 | 80 | /************************************************************************/ |
0 | /* | |
1 | ** structure containing only relevant process-info extracted | |
2 | ** from kernel's process-administration | |
3 | */ | |
4 | struct tstat_26 { | |
5 | /* GENERAL TASK INFO */ | |
6 | struct gen_26 { | |
7 | int tgid; /* threadgroup identification */ | |
8 | int pid; /* process identification */ | |
9 | int ppid; /* parent process identification*/ | |
10 | int ruid; /* real user identification */ | |
11 | int euid; /* eff. user identification */ | |
12 | int suid; /* saved user identification */ | |
13 | int fsuid; /* fs user identification */ | |
14 | int rgid; /* real group identification */ | |
15 | int egid; /* eff. group identification */ | |
16 | int sgid; /* saved group identification */ | |
17 | int fsgid; /* fs group identification */ | |
18 | int nthr; /* number of threads in tgroup */ | |
19 | char name[PNAMLEN+1];/* process name string */ | |
20 | char isproc; /* boolean: process level? */ | |
21 | char state; /* process state ('E' = exited) */ | |
22 | int excode; /* process exit status */ | |
23 | time_t btime; /* process start time (epoch) */ | |
24 | time_t elaps; /* process elaps time (hertz) */ | |
25 | char cmdline[CMDLEN+1];/* command-line string */ | |
26 | int nthrslpi; /* # threads in state 'S' */ | |
27 | int nthrslpu; /* # threads in state 'D' */ | |
28 | int nthrrun; /* # threads in state 'R' */ | |
29 | ||
30 | int ctid; /* OpenVZ container ID */ | |
31 | int vpid; /* OpenVZ virtual PID */ | |
32 | ||
33 | int wasinactive; /* boolean: task inactive */ | |
34 | ||
35 | char container[16]; /* Docker container id (12 pos) */ | |
36 | } gen; | |
37 | ||
38 | /* CPU STATISTICS */ | |
39 | struct cpu_26 { | |
40 | count_t utime; /* time user text (ticks) */ | |
41 | count_t stime; /* time system text (ticks) */ | |
42 | int nice; /* nice value */ | |
43 | int prio; /* priority */ | |
44 | int rtprio; /* realtime priority */ | |
45 | int policy; /* scheduling policy */ | |
46 | int curcpu; /* current processor */ | |
47 | int sleepavg; /* sleep average percentage */ | |
48 | int ifuture[4]; /* reserved for future use */ | |
49 | char wchan[16]; /* wait channel string */ | |
50 | count_t rundelay; /* schedstat rundelay (nanosec) */ | |
51 | count_t cfuture[1]; /* reserved for future use */ | |
52 | } cpu; | |
53 | ||
54 | /* DISK STATISTICS */ | |
55 | struct dsk_26 { | |
56 | count_t rio; /* number of read requests */ | |
57 | count_t rsz; /* cumulative # sectors read */ | |
58 | count_t wio; /* number of write requests */ | |
59 | count_t wsz; /* cumulative # sectors written */ | |
60 | count_t cwsz; /* cumulative # written sectors */ | |
61 | /* being cancelled */ | |
62 | count_t cfuture[4]; /* reserved for future use */ | |
63 | } dsk; | |
64 | ||
65 | /* MEMORY STATISTICS */ | |
66 | struct mem_26 { | |
67 | count_t minflt; /* number of page-reclaims */ | |
68 | count_t majflt; /* number of page-faults */ | |
69 | count_t vexec; /* virtmem execfile (Kb) */ | |
70 | count_t vmem; /* virtual memory (Kb) */ | |
71 | count_t rmem; /* resident memory (Kb) */ | |
72 | count_t pmem; /* resident memory (Kb) */ | |
73 | count_t vgrow; /* virtual growth (Kb) */ | |
74 | count_t rgrow; /* resident growth (Kb) */ | |
75 | count_t vdata; /* virtmem data (Kb) */ | |
76 | count_t vstack; /* virtmem stack (Kb) */ | |
77 | count_t vlibs; /* virtmem libexec (Kb) */ | |
78 | count_t vswap; /* swap space used (Kb) */ | |
79 | count_t vlock; /* virtual locked (Kb) */ | |
80 | count_t cfuture[3]; /* reserved for future use */ | |
81 | } mem; | |
82 | ||
83 | /* NETWORK STATISTICS */ | |
84 | struct net_26 { | |
85 | count_t tcpsnd; /* number of TCP-packets sent */ | |
86 | count_t tcpssz; /* cumulative size packets sent */ | |
87 | count_t tcprcv; /* number of TCP-packets recved */ | |
88 | count_t tcprsz; /* cumulative size packets rcvd */ | |
89 | count_t udpsnd; /* number of UDP-packets sent */ | |
90 | count_t udpssz; /* cumulative size packets sent */ | |
91 | count_t udprcv; /* number of UDP-packets recved */ | |
92 | count_t udprsz; /* cumulative size packets sent */ | |
93 | count_t avail1; /* */ | |
94 | count_t avail2; /* */ | |
95 | count_t cfuture[4]; /* reserved for future use */ | |
96 | } net; | |
97 | ||
98 | struct gpu_26 { | |
99 | char state; // A - active, E - Exit, '\0' - no use | |
100 | char cfuture[3]; // | |
101 | short nrgpus; // number of GPUs for this process | |
102 | int32_t gpulist; // bitlist with GPU numbers | |
103 | ||
104 | int gpubusy; // gpu busy perc process lifetime -1 = n/a | |
105 | int membusy; // memory busy perc process lifetime -1 = n/a | |
106 | count_t timems; // milliseconds accounting -1 = n/a | |
107 | // value 0 for active process, | |
108 | // value > 0 after termination | |
109 | ||
110 | count_t memnow; // current memory consumption in KiB | |
111 | count_t memcum; // cumulative memory consumption in KiB | |
112 | count_t sample; // number of samples | |
113 | } gpu; | |
114 | }; |
0 | #define MAXCPU_26 2048 | |
1 | #define MAXDSK_26 1024 | |
2 | #define MAXLVM_26 2048 | |
3 | #define MAXMDD_26 256 | |
4 | #define MAXINTF_26 128 | |
5 | #define MAXCONTAINER_26 128 | |
6 | #define MAXNFSMOUNT_26 64 | |
7 | #define MAXIBPORT_26 32 | |
8 | #define MAXGPU_26 32 | |
9 | ||
10 | /************************************************************************/ | |
11 | struct memstat_26 { | |
12 | count_t physmem; // number of physical pages | |
13 | count_t freemem; // number of free pages | |
14 | count_t buffermem; // number of buffer pages | |
15 | count_t slabmem; // number of slab pages | |
16 | count_t cachemem; // number of cache pages | |
17 | count_t cachedrt; // number of cache pages (dirty) | |
18 | ||
19 | count_t totswap; // number of pages in swap | |
20 | count_t freeswap; // number of free swap pages | |
21 | ||
22 | count_t pgscans; // number of page scans | |
23 | count_t pgsteal; // number of page steals | |
24 | count_t allocstall; // try to free pages forced | |
25 | count_t swouts; // number of pages swapped out | |
26 | count_t swins; // number of pages swapped in | |
27 | ||
28 | count_t commitlim; // commit limit in pages | |
29 | count_t committed; // number of reserved pages | |
30 | ||
31 | count_t shmem; // tot shmem incl. tmpfs (pages) | |
32 | count_t shmrss; // resident shared memory (pages) | |
33 | count_t shmswp; // swapped shared memory (pages) | |
34 | ||
35 | count_t slabreclaim; // reclaimable slab (pages) | |
36 | ||
37 | count_t tothugepage; // total huge pages (huge pages) | |
38 | count_t freehugepage; // free huge pages (huge pages) | |
39 | count_t hugepagesz; // huge page size (bytes) | |
40 | ||
41 | count_t vmwballoon; // vmware claimed balloon pages | |
42 | count_t zfsarcsize; // zfsonlinux ARC size (pages) | |
43 | count_t swapcached; // swap cache (pages) | |
44 | count_t cfuture[6]; // reserved for future use | |
45 | }; | |
46 | ||
47 | /************************************************************************/ | |
48 | ||
49 | struct netstat_26 { | |
50 | struct ipv4_stats ipv4; | |
51 | struct icmpv4_stats icmpv4; | |
52 | struct udpv4_stats udpv4; | |
53 | ||
54 | struct ipv6_stats ipv6; | |
55 | struct icmpv6_stats icmpv6; | |
56 | struct udpv6_stats udpv6; | |
57 | ||
58 | struct tcp_stats tcp; | |
59 | }; | |
60 | ||
61 | /************************************************************************/ | |
62 | ||
63 | struct freqcnt_26 { | |
64 | count_t maxfreq;/* frequency in MHz */ | |
65 | count_t cnt; /* number of clock ticks times state */ | |
66 | count_t ticks; /* number of total clock ticks */ | |
67 | /* if zero, cnt is actul freq */ | |
68 | }; | |
69 | ||
70 | struct percpu_26 { | |
71 | int cpunr; | |
72 | count_t stime; /* system time in clock ticks */ | |
73 | count_t utime; /* user time in clock ticks */ | |
74 | count_t ntime; /* nice time in clock ticks */ | |
75 | count_t itime; /* idle time in clock ticks */ | |
76 | count_t wtime; /* iowait time in clock ticks */ | |
77 | count_t Itime; /* irq time in clock ticks */ | |
78 | count_t Stime; /* softirq time in clock ticks */ | |
79 | count_t steal; /* steal time in clock ticks */ | |
80 | count_t guest; /* guest time in clock ticks */ | |
81 | struct freqcnt_26 freqcnt;/* frequency scaling info */ | |
82 | count_t instr; /* CPU instructions */ | |
83 | count_t cycle; /* CPU cycles */ | |
84 | count_t cfuture[2]; /* reserved for future use */ | |
85 | }; | |
86 | ||
87 | struct cpustat_26 { | |
88 | count_t nrcpu; /* number of cpu's */ | |
89 | count_t devint; /* number of device interrupts */ | |
90 | count_t csw; /* number of context switches */ | |
91 | count_t nprocs; /* number of processes started */ | |
92 | float lavg1; /* load average last minute */ | |
93 | float lavg5; /* load average last 5 minutes */ | |
94 | float lavg15; /* load average last 15 minutes */ | |
95 | count_t cfuture[4]; /* reserved for future use */ | |
96 | ||
97 | struct percpu_26 all; | |
98 | struct percpu_26 cpu[MAXCPU_26]; | |
99 | }; | |
100 | ||
101 | /************************************************************************/ | |
102 | ||
103 | struct perdsk_26 { | |
104 | char name[MAXDKNAM]; /* empty string for last */ | |
105 | count_t nread; /* number of read transfers */ | |
106 | count_t nrsect; /* number of sectors read */ | |
107 | count_t nwrite; /* number of write transfers */ | |
108 | count_t nwsect; /* number of sectors written */ | |
109 | count_t io_ms; /* number of millisecs spent for I/O */ | |
110 | count_t avque; /* average queue length */ | |
111 | count_t cfuture[4]; /* reserved for future use */ | |
112 | }; | |
113 | ||
114 | struct dskstat_26 { | |
115 | int ndsk; /* number of physical disks */ | |
116 | int nmdd; /* number of md volumes */ | |
117 | int nlvm; /* number of logical volumes */ | |
118 | struct perdsk_26 dsk[MAXDSK_26]; | |
119 | struct perdsk_26 mdd[MAXMDD_26]; | |
120 | struct perdsk_26 lvm[MAXLVM_26]; | |
121 | }; | |
122 | ||
123 | /************************************************************************/ | |
124 | ||
125 | struct perintf_26 { | |
126 | char name[16]; /* empty string for last */ | |
127 | ||
128 | count_t rbyte; /* number of read bytes */ | |
129 | count_t rpack; /* number of read packets */ | |
130 | count_t rerrs; /* receive errors */ | |
131 | count_t rdrop; /* receive drops */ | |
132 | count_t rfifo; /* receive fifo */ | |
133 | count_t rframe; /* receive framing errors */ | |
134 | count_t rcompr; /* receive compressed */ | |
135 | count_t rmultic;/* receive multicast */ | |
136 | count_t rfuture[4]; /* reserved for future use */ | |
137 | ||
138 | count_t sbyte; /* number of written bytes */ | |
139 | count_t spack; /* number of written packets */ | |
140 | count_t serrs; /* transmit errors */ | |
141 | count_t sdrop; /* transmit drops */ | |
142 | count_t sfifo; /* transmit fifo */ | |
143 | count_t scollis;/* collisions */ | |
144 | count_t scarrier;/* transmit carrier */ | |
145 | count_t scompr; /* transmit compressed */ | |
146 | count_t sfuture[4]; /* reserved for future use */ | |
147 | ||
148 | char type; /* interface type ('e'/'w'/'?') */ | |
149 | long speed; /* interface speed in megabits/second */ | |
150 | long speedp; /* previous interface speed */ | |
151 | char duplex; /* full duplex (boolean) */ | |
152 | count_t cfuture[4]; /* reserved for future use */ | |
153 | }; | |
154 | ||
155 | struct intfstat_26 { | |
156 | int nrintf; | |
157 | struct perintf_26 intf[MAXINTF_26]; | |
158 | }; | |
159 | ||
160 | /************************************************************************/ | |
161 | ||
162 | struct pernfsmount_26 { | |
163 | char mountdev[128]; /* mountdevice */ | |
164 | count_t age; /* number of seconds mounted */ | |
165 | ||
166 | count_t bytesread; /* via normal reads */ | |
167 | count_t byteswrite; /* via normal writes */ | |
168 | count_t bytesdread; /* via direct reads */ | |
169 | count_t bytesdwrite; /* via direct writes */ | |
170 | count_t bytestotread; /* via reads */ | |
171 | count_t bytestotwrite; /* via writes */ | |
172 | count_t pagesmread; /* via mmap reads */ | |
173 | count_t pagesmwrite; /* via mmap writes */ | |
174 | ||
175 | count_t future[8]; | |
176 | }; | |
177 | ||
178 | struct nfsstat_26 { | |
179 | struct { | |
180 | count_t netcnt; | |
181 | count_t netudpcnt; | |
182 | count_t nettcpcnt; | |
183 | count_t nettcpcon; | |
184 | ||
185 | count_t rpccnt; | |
186 | count_t rpcbadfmt; | |
187 | count_t rpcbadaut; | |
188 | count_t rpcbadcln; | |
189 | ||
190 | count_t rpcread; | |
191 | count_t rpcwrite; | |
192 | ||
193 | count_t rchits; /* repcache hits */ | |
194 | count_t rcmiss; /* repcache misses */ | |
195 | count_t rcnoca; /* uncached requests */ | |
196 | ||
197 | count_t nrbytes; /* read bytes */ | |
198 | count_t nwbytes; /* written bytes */ | |
199 | ||
200 | count_t future[8]; | |
201 | } server; | |
202 | ||
203 | struct { | |
204 | count_t rpccnt; | |
205 | count_t rpcretrans; | |
206 | count_t rpcautrefresh; | |
207 | ||
208 | count_t rpcread; | |
209 | count_t rpcwrite; | |
210 | ||
211 | count_t future[8]; | |
212 | } client; | |
213 | ||
214 | struct { | |
215 | int nrmounts; | |
216 | struct pernfsmount_26 nfsmnt[MAXNFSMOUNT_26]; | |
217 | } nfsmounts; | |
218 | }; | |
219 | ||
220 | /************************************************************************/ | |
221 | struct psi_26 { | |
222 | float avg10; // average pressure last 10 seconds | |
223 | float avg60; // average pressure last 60 seconds | |
224 | float avg300; // average pressure last 300 seconds | |
225 | count_t total; // total number of milliseconds | |
226 | }; | |
227 | ||
228 | struct pressure_26 { | |
229 | char present; /* pressure stats supported? */ | |
230 | char future[3]; | |
231 | struct psi_26 cpusome; /* pressure stall info 'some' */ | |
232 | struct psi_26 memsome; /* pressure stall info 'some' */ | |
233 | struct psi_26 memfull; /* pressure stall info 'full' */ | |
234 | struct psi_26 iosome; /* pressure stall info 'some' */ | |
235 | struct psi_26 iofull; /* pressure stall info 'full' */ | |
236 | }; | |
237 | ||
238 | /************************************************************************/ | |
239 | ||
240 | struct percontainer_26 { | |
241 | unsigned long ctid; /* container id */ | |
242 | unsigned long numproc; /* number of processes */ | |
243 | ||
244 | count_t system; /* */ | |
245 | count_t user; /* */ | |
246 | count_t nice; /* */ | |
247 | count_t uptime; /* */ | |
248 | ||
249 | count_t physpages; /* */ | |
250 | }; | |
251 | ||
252 | struct contstat_26 { | |
253 | int nrcontainer; | |
254 | struct percontainer_26 cont[MAXCONTAINER_26]; | |
255 | }; | |
256 | ||
257 | /************************************************************************/ | |
258 | /* | |
259 | ** experimental stuff for access to local HTTP daemons | |
260 | */ | |
261 | #define HTTPREQ "GET /server-status?auto HTTP/1.1\nHost: localhost\n\n" | |
262 | ||
263 | struct wwwstat_26 { | |
264 | count_t accesses; /* total number of HTTP-requests */ | |
265 | count_t totkbytes; /* total kbytes transfer for HTTP-req */ | |
266 | count_t uptime; /* number of seconds since startup */ | |
267 | int bworkers; /* number of busy httpd-daemons */ | |
268 | int iworkers; /* number of idle httpd-daemons */ | |
269 | }; | |
270 | ||
271 | /************************************************************************/ | |
272 | struct pergpu_26 { | |
273 | char taskstats; // GPU task statistics supported? | |
274 | unsigned char nrprocs; // number of processes using GPU | |
275 | char type[MAXGPUTYPE+1]; // GPU type | |
276 | char busid[MAXGPUBUS+1]; // GPU bus identification | |
277 | int gpunr; // GPU number | |
278 | int gpupercnow; // processor percentage last second | |
279 | // -1 if not supported | |
280 | int mempercnow; // memory percentage last second | |
281 | // -1 if not supported | |
282 | count_t memtotnow; // total memory in KiB | |
283 | count_t memusenow; // used memory in KiB | |
284 | count_t samples; // number of samples | |
285 | count_t gpuperccum; // cumulative processor busy percentage | |
286 | // -1 if not supported | |
287 | count_t memperccum; // cumulative memory percentage | |
288 | // -1 if not supported | |
289 | count_t memusecum; // cumulative used memory in KiB | |
290 | }; | |
291 | ||
292 | struct gpustat_26 { | |
293 | int nrgpus; // total number of GPUs | |
294 | struct pergpu_26 gpu[MAXGPU_26]; | |
295 | }; | |
296 | ||
297 | /************************************************************************/ | |
298 | struct perifb_26 { | |
299 | char ibname[MAXIBNAME]; // InfiniBand controller | |
300 | short portnr; // InfiniBand controller port | |
301 | ||
302 | short lanes; // number of lanes (traffic factor) | |
303 | count_t rate; // transfer rate in megabits/sec | |
304 | count_t rcvb; // bytes received | |
305 | count_t sndb; // bytes transmitted | |
306 | count_t rcvp; // packets received | |
307 | count_t sndp; // packets transmitted | |
308 | }; | |
309 | ||
310 | struct ifbstat_26 { | |
311 | int nrports; // total number of IB ports | |
312 | struct perifb_26 ifb[MAXIBPORT_26]; | |
313 | }; | |
314 | /************************************************************************/ | |
315 | ||
316 | struct sstat_26 { | |
317 | struct cpustat_26 cpu; | |
318 | struct memstat_26 mem; | |
319 | struct netstat_26 net; | |
320 | struct intfstat_26 intf; | |
321 | struct dskstat_26 dsk; | |
322 | struct nfsstat_26 nfs; | |
323 | struct contstat_26 cfs; | |
324 | struct pressure_26 psi; | |
325 | struct gpustat_26 gpu; | |
326 | struct ifbstat_26 ifb; | |
327 | ||
328 | struct wwwstat_26 www; | |
329 | }; |
36 | 36 | #include <stdlib.h> |
37 | 37 | #include <signal.h> |
38 | 38 | #include <ctype.h> |
39 | #include <string.h> | |
39 | 40 | #include <sys/utsname.h> |
40 | 41 | #include <string.h> |
41 | 42 | #include <regex.h> |
49 | 50 | #include "showgeneric.h" |
50 | 51 | #include "photoproc.h" |
51 | 52 | #include "photosyst.h" |
53 | #include "rawlog.h" | |
52 | 54 | |
53 | 55 | #define BASEPATH "/var/log/atop" |
54 | ||
55 | /* | |
56 | ** structure which describes the raw file contents | |
57 | ** | |
58 | ** layout raw file: rawheader | |
59 | ** | |
60 | ** rawrecord \ | |
61 | ** compressed system-level statistics | sample 1 | |
62 | ** compressed process-level statistics / | |
63 | ** | |
64 | ** rawrecord \ | |
65 | ** compressed system-level statistics | sample 2 | |
66 | ** compressed process-level statistics / | |
67 | ** | |
68 | ** etcetera ..... | |
69 | */ | |
70 | #define MYMAGIC (unsigned int) 0xfeedbeef | |
71 | ||
72 | struct rawheader { | |
73 | unsigned int magic; | |
74 | ||
75 | unsigned short aversion; /* creator atop version with MSB */ | |
76 | unsigned short future1; /* can be reused */ | |
77 | unsigned short future2; /* can be reused */ | |
78 | unsigned short rawheadlen; /* length of struct rawheader */ | |
79 | unsigned short rawreclen; /* length of struct rawrecord */ | |
80 | unsigned short hertz; /* clock interrupts per second */ | |
81 | unsigned short sfuture[6]; /* future use */ | |
82 | unsigned int sstatlen; /* length of struct sstat */ | |
83 | unsigned int tstatlen; /* length of struct tstat */ | |
84 | struct utsname utsname; /* info about this system */ | |
85 | char cfuture[8]; /* future use */ | |
86 | ||
87 | unsigned int pagesize; /* size of memory page (bytes) */ | |
88 | int supportflags; /* used features */ | |
89 | int osrel; /* OS release number */ | |
90 | int osvers; /* OS version number */ | |
91 | int ossub; /* OS version subnumber */ | |
92 | int ifuture[6]; /* future use */ | |
93 | }; | |
94 | ||
95 | struct rawrecord { | |
96 | time_t curtime; /* current time (epoch) */ | |
97 | ||
98 | unsigned short flags; /* various flags */ | |
99 | unsigned short sfuture[3]; /* future use */ | |
100 | ||
101 | unsigned int scomplen; /* length of compressed sstat */ | |
102 | unsigned int pcomplen; /* length of compressed tstat's */ | |
103 | unsigned int interval; /* interval (number of seconds) */ | |
104 | unsigned int ndeviat; /* number of tasks in list */ | |
105 | unsigned int nactproc; /* number of processes in list */ | |
106 | unsigned int ntask; /* total number of tasks */ | |
107 | unsigned int totproc; /* total number of processes */ | |
108 | unsigned int totrun; /* number of running threads */ | |
109 | unsigned int totslpi; /* number of sleeping threads(S)*/ | |
110 | unsigned int totslpu; /* number of sleeping threads(D)*/ | |
111 | unsigned int totzomb; /* number of zombie processes */ | |
112 | unsigned int nexit; /* number of exited processes */ | |
113 | unsigned int noverflow; /* number of overflow processes */ | |
114 | unsigned int ifuture[6]; /* future use */ | |
115 | }; | |
116 | 56 | |
117 | 57 | static int getrawrec (int, struct rawrecord *, int); |
118 | 58 | static int getrawsstat(int, struct sstat *, int); |
404 | 344 | |
405 | 345 | if (lookslikedatetome(rawname)) |
406 | 346 | { |
407 | char savedname[RAWNAMESZ]; | |
408 | ||
409 | strncpy(savedname, rawname, RAWNAMESZ-1); | |
347 | char savedname[16]; | |
348 | ||
349 | strcpy(savedname, rawname); // no overflow (len=8) | |
410 | 350 | |
411 | 351 | snprintf(rawname, RAWNAMESZ, "%s/atop_%s", |
412 | 352 | BASEPATH, |
474 | 414 | */ |
475 | 415 | if ( (rawfd = open(rawname, O_RDONLY)) == -1) |
476 | 416 | { |
477 | char command[512], tmpname1[RAWNAMESZ], tmpname2[RAWNAMESZ]; | |
417 | char command[512], tmpname1[200], tmpname2[200]; | |
478 | 418 | |
479 | 419 | /* |
480 | 420 | ** check if a compressed raw file is present |
513 | 453 | } |
514 | 454 | } |
515 | 455 | |
456 | /* make the kernel readahead more effective, */ | |
457 | if (isregular) | |
458 | posix_fadvise(rawfd, 0, 0, POSIX_FADV_SEQUENTIAL); | |
459 | ||
516 | 460 | /* |
517 | 461 | ** read the raw header and verify the magic |
518 | 462 | */ |
609 | 553 | { |
610 | 554 | while ( getrawrec(rawfd, &rr, rh.rawreclen) == rh.rawreclen) |
611 | 555 | { |
612 | unsigned int secsinday = daysecs(rr.curtime); | |
613 | 556 | unsigned int k, l; |
557 | ||
558 | cursortime = rr.curtime; // maintain current | |
559 | ||
560 | /* | |
561 | ** normalize the begintime and endtime if the | |
562 | ** format hh:mm has been used instead of an | |
563 | ** absolute date-time string | |
564 | ** (only happens for the first record) | |
565 | */ | |
566 | if (begintime <= SECONDSINDAY) | |
567 | begintime = normalize_epoch(cursortime, | |
568 | begintime); | |
569 | ||
570 | if (endtime && endtime <= SECONDSINDAY) | |
571 | endtime = normalize_epoch(cursortime, endtime); | |
614 | 572 | |
615 | 573 | /* |
616 | 574 | ** store the offset of the raw record in the offset list |
637 | 595 | ** check if this sample is within the time-range |
638 | 596 | ** specified with the -b and -e flags (if any) |
639 | 597 | */ |
640 | if ( (begintime && begintime > secsinday) ) | |
598 | if ( (begintime > cursortime) ) | |
641 | 599 | { |
642 | 600 | lastcmd = 1; |
643 | 601 | |
644 | 602 | if (isregular) |
645 | 603 | { |
646 | lseek(rawfd, rr.scomplen+rr.pcomplen, | |
647 | SEEK_CUR); | |
604 | static off_t curr_pos = -1; | |
605 | off_t next_pos; | |
606 | ||
607 | lastcmd = 1; | |
608 | next_pos = lseek(rawfd, rr.scomplen+rr.pcomplen, SEEK_CUR); | |
609 | if ((curr_pos >> READAHEADOFF) != (next_pos >> READAHEADOFF)) | |
610 | { | |
611 | int liResult; | |
612 | /* just read READAHEADSIZE bytes into page cache */ | |
613 | char *buf = malloc(READAHEADSIZE); | |
614 | ptrverify(buf, "Malloc failed for readahead"); | |
615 | liResult = pread(rawfd, buf, READAHEADSIZE, next_pos & ~(READAHEADSIZE - 1)); | |
616 | if(liResult == -1) | |
617 | { | |
618 | char lcMessage[64]; | |
619 | ||
620 | snprintf(lcMessage, sizeof(lcMessage) - 1, | |
621 | "%s:%d - Error %d in readahead\n", | |
622 | __FILE__, __LINE__, errno); | |
623 | fprintf(stderr, "%s", lcMessage); | |
624 | } | |
625 | free(buf); | |
626 | } | |
627 | curr_pos = next_pos; | |
628 | continue; | |
648 | 629 | } |
649 | 630 | else // named pipe not seekable |
650 | 631 | { |
665 | 646 | |
666 | 647 | begintime = 0; // allow earlier times from now on |
667 | 648 | |
668 | if ( (endtime && endtime < secsinday) ) | |
649 | if ( (endtime && endtime < cursortime) ) | |
669 | 650 | { |
670 | 651 | if (isregular) |
671 | 652 | free(offlist); |
695 | 676 | devtstat.procall = malloc(sizeof(struct tstat *) |
696 | 677 | * rr.totproc); |
697 | 678 | |
698 | devtstat.procactive = malloc(sizeof(struct tstat *) * rr.nactproc); | |
679 | devtstat.procactive = malloc(sizeof(struct tstat *) * | |
680 | rr.nactproc); | |
699 | 681 | |
700 | 682 | ptrverify(devtstat.taskall, |
701 | 683 | "Malloc failed for %d stored tasks\n", |
799 | 781 | rr.nexit, rr.noverflow, flags); |
800 | 782 | } |
801 | 783 | while (!isregular && |
802 | (lastcmd == MSAMPPREV || | |
803 | lastcmd == MSAMPBRANCH || | |
804 | lastcmd == MRESET )); | |
784 | ( lastcmd == MSAMPPREV || | |
785 | lastcmd == MRESET || | |
786 | (lastcmd == MSAMPBRANCH && | |
787 | begintime < cursortime) )); | |
805 | 788 | |
806 | 789 | free(devtstat.taskall); |
807 | 790 | free(devtstat.procall); |
824 | 807 | break; |
825 | 808 | |
826 | 809 | case MSAMPBRANCH: |
827 | if (begintime && begintime < secsinday) | |
810 | if (begintime < cursortime && isregular) | |
828 | 811 | { |
829 | lseek(rawfd, *offlist, | |
830 | SEEK_SET); | |
812 | lseek(rawfd, *offlist, SEEK_SET); | |
831 | 813 | offcur = 1; |
832 | 814 | } |
833 | 815 | } |
0 | /* | |
1 | ** structure describing the raw file contents | |
2 | ** | |
3 | ** layout raw file: rawheader | |
4 | ** | |
5 | ** rawrecord \ | |
6 | ** compressed system-level statistics | sample 1 | |
7 | ** compressed process-level statistics / | |
8 | ** | |
9 | ** rawrecord \ | |
10 | ** compressed system-level statistics | sample 2 | |
11 | ** compressed process-level statistics / | |
12 | ** | |
13 | ** etcetera ..... | |
14 | */ | |
15 | #define MYMAGIC (unsigned int) 0xfeedbeef | |
16 | #define READAHEADOFF 22 | |
17 | #define READAHEADSIZE (1 << READAHEADOFF) | |
18 | ||
19 | struct rawheader { | |
20 | unsigned int magic; | |
21 | ||
22 | unsigned short aversion; /* creator atop version with MSB */ | |
23 | unsigned short future1; /* can be reused */ | |
24 | unsigned short future2; /* can be reused */ | |
25 | unsigned short rawheadlen; /* length of struct rawheader */ | |
26 | unsigned short rawreclen; /* length of struct rawrecord */ | |
27 | unsigned short hertz; /* clock interrupts per second */ | |
28 | unsigned short sfuture[6]; /* future use */ | |
29 | unsigned int sstatlen; /* length of struct sstat */ | |
30 | unsigned int tstatlen; /* length of struct tstat */ | |
31 | struct utsname utsname; /* info about this system */ | |
32 | char cfuture[8]; /* future use */ | |
33 | ||
34 | unsigned int pagesize; /* size of memory page (bytes) */ | |
35 | int supportflags; /* used features */ | |
36 | int osrel; /* OS release number */ | |
37 | int osvers; /* OS version number */ | |
38 | int ossub; /* OS version subnumber */ | |
39 | int ifuture[6]; /* future use */ | |
40 | }; | |
41 | ||
42 | struct rawrecord { | |
43 | time_t curtime; /* current time (epoch) */ | |
44 | ||
45 | unsigned short flags; /* various flags */ | |
46 | unsigned short sfuture[3]; /* future use */ | |
47 | ||
48 | unsigned int scomplen; /* length of compressed sstat */ | |
49 | unsigned int pcomplen; /* length of compressed tstat's */ | |
50 | unsigned int interval; /* interval (number of seconds) */ | |
51 | unsigned int ndeviat; /* number of tasks in list */ | |
52 | unsigned int nactproc; /* number of processes in list */ | |
53 | unsigned int ntask; /* total number of tasks */ | |
54 | unsigned int totproc; /* total number of processes */ | |
55 | unsigned int totrun; /* number of running threads */ | |
56 | unsigned int totslpi; /* number of sleeping threads(S)*/ | |
57 | unsigned int totslpu; /* number of sleeping threads(D)*/ | |
58 | unsigned int totzomb; /* number of zombie processes */ | |
59 | unsigned int nexit; /* number of exited processes */ | |
60 | unsigned int noverflow; /* number of overflow processes */ | |
61 | unsigned int ifuture[6]; /* future use */ | |
62 | }; |
253 | 253 | ** Initial revision |
254 | 254 | ** |
255 | 255 | */ |
256 | ||
257 | static const char rcsid[] = "$Id: showgeneric.c,v 1.71 2010/10/25 19:08:32 gerlof Exp $"; | |
258 | 256 | |
259 | 257 | #include <sys/types.h> |
260 | 258 | #include <sys/param.h> |
273 | 271 | #include <pwd.h> |
274 | 272 | #include <grp.h> |
275 | 273 | #include <regex.h> |
274 | #include <locale.h> | |
276 | 275 | |
277 | 276 | #include "atop.h" |
278 | 277 | #include "photoproc.h" |
288 | 287 | static int paused; /* boolean: currently in pause-mode */ |
289 | 288 | static int fixedhead; /* boolean: fixate header-lines */ |
290 | 289 | static int sysnosort; /* boolean: suppress sort of resources */ |
290 | static int threadsort; /* boolean: sort threads per process */ | |
291 | 291 | static int avgval; /* boolean: average values i.s.o. total */ |
292 | 292 | static int suppressexit; /* boolean: suppress exited processes */ |
293 | 293 | |
350 | 350 | register int i, curline, statline, nproc; |
351 | 351 | int firstproc = 0, plistsz, alistsz, killpid, killsig; |
352 | 352 | int lastchar; |
353 | char format1[16], format2[16], hhmm[16]; | |
353 | char format1[16], format2[16], branchtime[32]; | |
354 | 354 | char *statmsg = NULL, statbuf[80], genline[80]; |
355 | 355 | char *lastsortp, curorder, autoorder; |
356 | 356 | char buf[33]; |
506 | 506 | |
507 | 507 | int seclen = val2elapstr(nsecs, buf); |
508 | 508 | int lenavail = (screen ? COLS : linelen) - |
509 | 49 - seclen - utsnodenamelen; | |
509 | 51 - seclen - utsnodenamelen; | |
510 | 510 | int len1 = lenavail / 3; |
511 | 511 | int len2 = lenavail - len1 - len1; |
512 | 512 | |
513 | printg("ATOP - %s%*s%s %s%*s%c%c%c%c%c%c%c%c%c%c%c%c%c%c%*s%s" | |
514 | " elapsed", | |
513 | printg("ATOP - %s%*s%s %s%*s%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%" | |
514 | "*s%s elapsed", | |
515 | 515 | utsname.nodename, len1, "", |
516 | 516 | format1, format2, len1, "", |
517 | 517 | threadview ? MTHREAD : '-', |
518 | threadsort ? MTHRSORT : '-', | |
518 | 519 | fixedhead ? MSYSFIXED : '-', |
519 | 520 | sysnosort ? MSYSNOSORT : '-', |
520 | 521 | deviatonly ? '-' : MALLPROC, |
521 | 522 | usecolors ? '-' : MCOLORS, |
522 | 523 | avgval ? MAVGVAL : '-', |
523 | 524 | calcpss ? MCALCPSS : '-', |
525 | getwchan ? MGETWCHAN : '-', | |
524 | 526 | suppressexit ? MSUPEXITS : '-', |
525 | 527 | procsel.userid[0] != USERSTUB ? MSELUSER : '-', |
526 | 528 | procsel.prognamesz ? MSELPROC : '-', |
934 | 936 | else |
935 | 937 | j = ntotal; |
936 | 938 | |
939 | /* | |
940 | ** zip process list with thread list | |
941 | */ | |
937 | 942 | if (zipagain) |
938 | 943 | { |
939 | 944 | struct tstat *tall = devtstat->taskall; |
940 | 945 | struct tstat *pcur; |
946 | long int n; | |
941 | 947 | |
942 | 948 | for (i=j=0; i < ncurlist; i++) |
943 | 949 | { |
944 | 950 | pcur = curlist[i]; |
945 | 951 | |
946 | tsklist[j++] = pcur; | |
952 | tsklist[j++] = pcur; // take process | |
953 | ||
954 | n = j; // start index of threads | |
947 | 955 | |
948 | 956 | for (t = pcur - tall + 1; |
949 | 957 | t < devtstat->ntaskall && |
964 | 972 | else |
965 | 973 | tsklist[j++] = tall+t; |
966 | 974 | } |
975 | ||
976 | if (threadsort && j-n > 0 && | |
977 | curorder != MSORTMEM) | |
978 | { | |
979 | qsort(&tsklist[n], j-n, | |
980 | sizeof(struct tstat *), | |
981 | procsort[(int)curorder&0x1f]); | |
982 | } | |
967 | 983 | } |
968 | 984 | |
969 | 985 | zipagain = 0; |
1120 | 1136 | echo(); |
1121 | 1137 | move(statline, 0); |
1122 | 1138 | clrtoeol(); |
1123 | printw("Enter new time (format hh:mm): "); | |
1124 | ||
1125 | hhmm[0] = '\0'; | |
1126 | scanw("%15s\n", hhmm); | |
1139 | printw("Enter new time " | |
1140 | "(format [YYYYMMDD]hhmm): "); | |
1141 | ||
1142 | branchtime[0] = '\0'; | |
1143 | scanw("%31s\n", branchtime); | |
1127 | 1144 | noecho(); |
1128 | 1145 | |
1129 | if ( !hhmm2secs(hhmm, &begintime) ) | |
1146 | begintime = cursortime; | |
1147 | ||
1148 | if ( !getbranchtime(branchtime, &begintime) ) | |
1130 | 1149 | { |
1131 | 1150 | move(statline, 0); |
1132 | 1151 | clrtoeol(); |
1133 | 1152 | statmsg = "Wrong time format!"; |
1134 | 1153 | beep(); |
1135 | begintime = 0; | |
1154 | begintime = 0; | |
1136 | 1155 | break; |
1137 | 1156 | } |
1138 | 1157 | |
1961 | 1980 | |
1962 | 1981 | /* |
1963 | 1982 | ** per-thread view wanted with sorting on |
1964 | ** process level or thread level | |
1983 | ** process level | |
1965 | 1984 | */ |
1966 | 1985 | case MTHREAD: |
1967 | 1986 | if (threadview) |
1979 | 1998 | break; |
1980 | 1999 | |
1981 | 2000 | /* |
2001 | ** sorting on thread level as well (threadview) | |
2002 | */ | |
2003 | case MTHRSORT: | |
2004 | if (threadsort) | |
2005 | { | |
2006 | threadsort = 0; | |
2007 | statmsg = "Thread sorting disabled for thread view"; | |
2008 | firstproc = 0; | |
2009 | } | |
2010 | else | |
2011 | { | |
2012 | threadsort = 1; | |
2013 | statmsg = "Thread sorting enabled for thread view"; | |
2014 | firstproc = 0; | |
2015 | } | |
2016 | break; | |
2017 | ||
2018 | /* | |
1982 | 2019 | ** per-process PSS calculation wanted |
1983 | 2020 | */ |
1984 | 2021 | case MCALCPSS: |
1991 | 2028 | { |
1992 | 2029 | calcpss = 1; |
1993 | 2030 | statmsg = "PSIZE gathering enabled"; |
2031 | } | |
2032 | break; | |
2033 | ||
2034 | /* | |
2035 | ** per-thread WCHAN definition | |
2036 | */ | |
2037 | case MGETWCHAN: | |
2038 | if (getwchan) | |
2039 | { | |
2040 | getwchan = 0; | |
2041 | statmsg = "WCHAN gathering disabled"; | |
2042 | } | |
2043 | else | |
2044 | { | |
2045 | getwchan = 1; | |
2046 | statmsg = "WCHAN gathering enabled"; | |
1994 | 2047 | } |
1995 | 2048 | break; |
1996 | 2049 | |
2412 | 2465 | curstat->mem.vdata += curproc->mem.vdata; |
2413 | 2466 | curstat->mem.vstack += curproc->mem.vstack; |
2414 | 2467 | curstat->mem.vswap += curproc->mem.vswap; |
2468 | curstat->mem.vlock += curproc->mem.vlock; | |
2415 | 2469 | curstat->mem.rgrow += curproc->mem.rgrow; |
2416 | 2470 | curstat->mem.vgrow += curproc->mem.vgrow; |
2417 | 2471 | |
2773 | 2827 | threadview = 1; |
2774 | 2828 | break; |
2775 | 2829 | |
2830 | case MTHRSORT: | |
2831 | if (threadsort) | |
2832 | threadsort = 0; | |
2833 | else | |
2834 | threadsort = 1; | |
2835 | break; | |
2836 | ||
2776 | 2837 | case MCALCPSS: |
2777 | 2838 | if (calcpss) |
2778 | 2839 | calcpss = 0; |
2779 | 2840 | else |
2780 | 2841 | calcpss = 1; |
2842 | break; | |
2843 | ||
2844 | case MGETWCHAN: | |
2845 | if (getwchan) | |
2846 | getwchan = 0; | |
2847 | else | |
2848 | getwchan = 1; | |
2781 | 2849 | break; |
2782 | 2850 | |
2783 | 2851 | case MSUPEXITS: |
2824 | 2892 | if (screen) |
2825 | 2893 | { |
2826 | 2894 | /* |
2895 | ** if stdin is not connected to a tty (might be redirected | |
2896 | ** to pipe or file), close it and duplicate stdout (tty) | |
2897 | ** to stdin | |
2898 | */ | |
2899 | if ( !isatty(0) ) | |
2900 | { | |
2901 | (void) close(0); | |
2902 | (void) dup(1); | |
2903 | } | |
2904 | ||
2905 | /* | |
2827 | 2906 | ** initialize screen-handling via curses |
2828 | 2907 | */ |
2908 | setlocale(LC_ALL, ""); | |
2909 | setlocale(LC_NUMERIC, "C"); | |
2910 | ||
2829 | 2911 | initscr(); |
2830 | 2912 | cbreak(); |
2831 | 2913 | noecho(); |
2921 | 3003 | ' '}, |
2922 | 3004 | {"\n", ' '}, |
2923 | 3005 | {"Presentation (keys shown in header line):\n", ' '}, |
2924 | {"\t'%c' - show individual threads (toggle)\n", | |
3006 | {"\t'%c' - show threads within process (thread view) (toggle)\n", | |
2925 | 3007 | MTHREAD}, |
3008 | {"\t'%c' - sort threads (when combined with thread view) (toggle)\n", | |
3009 | MTHRSORT}, | |
2926 | 3010 | {"\t'%c' - show all processes (default: active processes) (toggle)\n", |
2927 | 3011 | MALLPROC}, |
2928 | 3012 | {"\t'%c' - show fixed number of header lines (toggle)\n", |
2937 | 3021 | MAVGVAL}, |
2938 | 3022 | {"\t'%c' - calculate proportional set size (PSIZE) (toggle)\n", |
2939 | 3023 | MCALCPSS}, |
3024 | {"\t'%c' - determine WCHAN per thread (toggle)\n", | |
3025 | MGETWCHAN}, | |
2940 | 3026 | {"\n", ' '}, |
2941 | 3027 | {"Raw file viewing:\n", ' '}, |
2942 | 3028 | {"\t'%c' - show next sample in raw file\n", MSAMPNEXT}, |
3056 | 3142 | MSUPEXITS); |
3057 | 3143 | printf("\t -%c show limited number of lines for certain resources\n", |
3058 | 3144 | MSYSLIMIT); |
3059 | printf("\t -%c show individual threads\n", MTHREAD); | |
3145 | printf("\t -%c show threads within process\n", MTHREAD); | |
3146 | printf("\t -%c sort threads (when combined with '%c')\n", MTHRSORT, MTHREAD); | |
3060 | 3147 | printf("\t -%c show average-per-second i.s.o. total values\n\n", |
3061 | 3148 | MAVGVAL); |
3062 | 3149 | printf("\t -%c no colors in case of high occupation\n", |
3409 | 3496 | threadview = 1; |
3410 | 3497 | break; |
3411 | 3498 | |
3499 | case MTHRSORT: | |
3500 | threadsort = 1; | |
3501 | break; | |
3502 | ||
3412 | 3503 | case MCOLORS: |
3413 | 3504 | usecolors = 0; |
3414 | 3505 | break; |
3415 | 3506 | |
3416 | 3507 | case MCALCPSS: |
3417 | 3508 | calcpss = 1; |
3509 | break; | |
3510 | ||
3511 | case MGETWCHAN: | |
3512 | getwchan = 1; | |
3418 | 3513 | break; |
3419 | 3514 | |
3420 | 3515 | case MSUPEXITS: |
98 | 98 | #define MSORTAUTO 'A' |
99 | 99 | |
100 | 100 | #define MTHREAD 'y' |
101 | #define MTHRSORT 'Y' | |
101 | 102 | #define MCALCPSS 'R' |
103 | #define MGETWCHAN 'W' | |
102 | 104 | #define MSUPEXITS 'G' |
103 | 105 | #define MCOLORS 'x' |
104 | 106 | #define MSYSFIXED 'f' |
259 | 259 | ** Initial |
260 | 260 | ** |
261 | 261 | */ |
262 | ||
263 | static const char rcsid[] = "$Id: showlinux.c,v 1.70 2010/10/23 14:04:12 gerlof Exp $"; | |
264 | 262 | |
265 | 263 | #include <sys/types.h> |
266 | 264 | #include <sys/param.h> |
387 | 385 | &syspdef_BLANKBOX, |
388 | 386 | &syspdef_VMWBAL, |
389 | 387 | &syspdef_BLANKBOX, |
388 | &syspdef_ZFSARC, | |
389 | &syspdef_BLANKBOX, | |
390 | 390 | &syspdef_HUPTOT, |
391 | 391 | &syspdef_HUPUSE, |
392 | 392 | 0 |
394 | 394 | sys_printdef *swpsyspdefs[] = { |
395 | 395 | &syspdef_SWPTOT, |
396 | 396 | &syspdef_SWPFREE, |
397 | &syspdef_BLANKBOX, | |
398 | &syspdef_SWPCACHE, | |
399 | &syspdef_BLANKBOX, | |
397 | 400 | &syspdef_SWPCOMMITTED, |
398 | 401 | &syspdef_SWPCOMMITLIM, |
399 | 402 | &syspdef_BLANKBOX, |
409 | 412 | 0 |
410 | 413 | }; |
411 | 414 | sys_printdef *psisyspdefs[] = { |
415 | &syspdef_PSICPUSTOT, | |
416 | &syspdef_PSIMEMSTOT, | |
417 | &syspdef_PSIMEMFTOT, | |
418 | &syspdef_PSIIOSTOT, | |
419 | &syspdef_PSIIOFTOT, | |
412 | 420 | &syspdef_PSICPUS, |
413 | 421 | &syspdef_PSIMEMS, |
414 | 422 | &syspdef_PSIMEMF, |
545 | 553 | &procprt_PPID, |
546 | 554 | &procprt_SYSCPU, |
547 | 555 | &procprt_USRCPU, |
556 | &procprt_RUNDELAY, | |
557 | &procprt_WCHAN, | |
548 | 558 | &procprt_VGROW, |
549 | 559 | &procprt_RGROW, |
550 | 560 | &procprt_MINFLT, |
557 | 567 | &procprt_VDATA, |
558 | 568 | &procprt_VSTACK, |
559 | 569 | &procprt_SWAPSZ, |
570 | &procprt_LOCKSZ, | |
560 | 571 | &procprt_CMD, |
561 | 572 | &procprt_RUID, |
562 | 573 | &procprt_EUID, |
1017 | 1028 | if (memline[0].f == 0) |
1018 | 1029 | { |
1019 | 1030 | make_sys_prints(memline, MAXITEMS, |
1020 | "MEMTOT:6 " | |
1021 | "MEMFREE:7 " | |
1022 | "MEMCACHE:5 " | |
1023 | "MEMDIRTY:3 " | |
1024 | "MEMBUFFER:5 " | |
1025 | "MEMSLAB:5 " | |
1026 | "RECSLAB:2 " | |
1031 | "MEMTOT:8 " | |
1032 | "MEMFREE:9 " | |
1033 | "MEMCACHE:7 " | |
1034 | "MEMDIRTY:5 " | |
1035 | "MEMBUFFER:7 " | |
1036 | "MEMSLAB:7 " | |
1037 | "RECSLAB:4 " | |
1027 | 1038 | "BLANKBOX:0 " |
1028 | 1039 | "SHMEM:4 " |
1029 | "SHMRSS:3 " | |
1030 | "SHMSWP:1 " | |
1031 | "BLANKBOX:0 " | |
1032 | "VMWBAL:4 " | |
1033 | "BLANKBOX:0 " | |
1034 | "HUPTOT:4 " | |
1040 | "SHMRSS:4 " | |
1041 | "SHMSWP:3 " | |
1042 | "BLANKBOX:0 " | |
1043 | "VMWBAL:5 " | |
1044 | "BLANKBOX:0 " | |
1045 | "ZFSARC:6 " | |
1046 | "BLANKBOX:0 " | |
1047 | "HUPTOT:6 " | |
1035 | 1048 | "HUPUSE:3 ", memsyspdefs, "builtin memline"); |
1036 | 1049 | } |
1037 | 1050 | if (swpline[0].f == 0) |
1041 | 1054 | "SWPFREE:4 " |
1042 | 1055 | "BLANKBOX:0 " |
1043 | 1056 | "BLANKBOX:0 " |
1044 | "BLANKBOX:0 " | |
1045 | "BLANKBOX:0 " | |
1057 | "SWPCACHE:2 " | |
1046 | 1058 | "BLANKBOX:0 " |
1047 | 1059 | "BLANKBOX:0 " |
1048 | 1060 | "SWPCOMMITTED:5 " |
1065 | 1077 | if (psiline[0].f == 0) |
1066 | 1078 | { |
1067 | 1079 | make_sys_prints(psiline, MAXITEMS, |
1068 | "PSICPUS:3 " | |
1069 | "PSIMEMS:3 " | |
1080 | "PSICPUSTOT:7 " | |
1081 | "PSIMEMSTOT:7 " | |
1082 | "PSIMEMFTOT:8 " | |
1083 | "PSIIOSTOT:7 " | |
1084 | "PSIIOFTOT:8 " | |
1085 | "PSICPUS:6 " | |
1086 | "PSIMEMS:5 " | |
1070 | 1087 | "PSIMEMF:3 " |
1071 | "PSIIOS:3 " | |
1072 | "PSIIOF:3 " | |
1073 | "BLANKBOX:0 " | |
1074 | "BLANKBOX:0 " | |
1088 | "PSIIOS:4 " | |
1089 | "PSIIOF:2 " | |
1075 | 1090 | "BLANKBOX:0 ", psisyspdefs, "builtin psiline"); |
1076 | 1091 | } |
1077 | 1092 | if (contline[0].f == 0) |
1269 | 1284 | |
1270 | 1285 | make_proc_prints(memprocs, MAXITEMS, |
1271 | 1286 | "PID:10 TID:3 MINFLT:2 MAJFLT:2 VSTEXT:4 VSLIBS:4 " |
1272 | "VDATA:4 VSTACK:4 VSIZE:6 RSIZE:7 PSIZE:5 " | |
1287 | "VDATA:4 VSTACK:4 LOCKSZ:3 VSIZE:6 RSIZE:7 PSIZE:5 " | |
1273 | 1288 | "VGROW:7 RGROW:8 SWAPSZ:5 RUID:1 EUID:0 " |
1274 | 1289 | "SORTITEM:9 CMD:10", |
1275 | 1290 | "built-in memprocs"); |
1276 | 1291 | |
1277 | 1292 | make_proc_prints(schedprocs, MAXITEMS, |
1278 | "PID:10 TID:6 CID:5 VPID:4 CTID:4 TRUN:7 TSLPI:7 " | |
1279 | "TSLPU:7 POLI:8 NICE:9 PRI:9 RTPR:9 CPUNR:8 ST:8 " | |
1280 | "EXC:8 S:8 SORTITEM:10 CMD:10", | |
1293 | "PID:10 TID:6 CID:4 VPID:3 CTID:3 TRUN:7 TSLPI:7 " | |
1294 | "TSLPU:7 POLI:8 NICE:9 PRI:5 RTPR:9 CPUNR:8 ST:8 " | |
1295 | "EXC:8 S:8 RDELAY:8 WCHAN:5 SORTITEM:10 CMD:10", | |
1281 | 1296 | "built-in schedprocs"); |
1282 | 1297 | |
1283 | 1298 | make_proc_prints(dskprocs, MAXITEMS, |
1313 | 1328 | |
1314 | 1329 | make_proc_prints(totusers, MAXITEMS, |
1315 | 1330 | "NPROCS:10 SYSCPU:9 USRCPU:9 VSIZE:6 " |
1316 | "RSIZE:8 PSIZE:8 SWAPSZ:5 RDDSK:7 CWRDSK:7 " | |
1331 | "RSIZE:8 PSIZE:8 LOCKSZ:3 SWAPSZ:5 RDDSK:7 CWRDSK:7 " | |
1317 | 1332 | "RNET:6 SNET:6 SORTITEM:10 RUID:10", |
1318 | 1333 | "built-in totusers"); |
1319 | 1334 | |
1320 | 1335 | make_proc_prints(totprocs, MAXITEMS, |
1321 | 1336 | "NPROCS:10 SYSCPU:9 USRCPU:9 VSIZE:6 " |
1322 | "RSIZE:8 PSIZE:8 SWAPSZ:5 RDDSK:7 CWRDSK:7 " | |
1337 | "RSIZE:8 PSIZE:8 LOCKSZ:3 SWAPSZ:5 RDDSK:7 CWRDSK:7 " | |
1323 | 1338 | "RNET:6 SNET:6 SORTITEM:10 CMD:10", |
1324 | 1339 | "built-in totprocs"); |
1325 | 1340 | |
1326 | 1341 | make_proc_prints(totconts, MAXITEMS, |
1327 | 1342 | "NPROCS:10 SYSCPU:9 USRCPU:9 VSIZE:6 " |
1328 | "RSIZE:8 PSIZE:8 SWAPSZ:5 RDDSK:7 CWRDSK:7 " | |
1343 | "RSIZE:8 PSIZE:8 LOCKSZ:3 SWAPSZ:5 RDDSK:7 CWRDSK:7 " | |
1329 | 1344 | "RNET:6 SNET:6 SORTITEM:10 CID:10", |
1330 | 1345 | "built-in totconts"); |
1331 | 1346 | } |
1411 | 1426 | #define FORMTID "TID:6 " |
1412 | 1427 | #define FORMCID "CID:5 " |
1413 | 1428 | #define FORMCPU "SYSCPU:9 USRCPU:9 " |
1429 | #define FORMDEL "RDELAY:4 " | |
1414 | 1430 | #define FORMMEM "VGROW:8 RGROW:8 " |
1415 | 1431 | #define FORMDSK "RDDSK:7 CWRDSK:7 " |
1416 | 1432 | #define FORMNET "RNET:6 SNET:6 " |
1417 | #define FORMMSC "RUID:3 EUID:2 ST:4 EXC:4 THR:4 S:4 CPUNR:4 " | |
1433 | #define FORMMSC "RUID:2 EUID:1 ST:3 EXC:3 THR:3 S:3 CPUNR:3 " | |
1418 | 1434 | #define FORMEND "SORTITEM:10 CMD:10" |
1419 | 1435 | |
1420 | 1436 | static void |
1439 | 1455 | |
1440 | 1456 | memcpy(p, FORMCPU, sizeof FORMCPU -1); |
1441 | 1457 | p += sizeof FORMCPU -1; |
1458 | ||
1459 | memcpy(p, FORMDEL, sizeof FORMDEL -1); | |
1460 | p += sizeof FORMDEL -1; | |
1442 | 1461 | |
1443 | 1462 | memcpy(p, FORMMEM, sizeof FORMMEM -1); |
1444 | 1463 | p += sizeof FORMMEM -1; |
2279 | 2298 | register count_t bcpu = (*(struct tstat **)b)->cpu.stime + |
2280 | 2299 | (*(struct tstat **)b)->cpu.utime; |
2281 | 2300 | |
2282 | if (acpu < bcpu) return 1; | |
2283 | if (acpu > bcpu) return -1; | |
2284 | return compmem(a, b); | |
2301 | if (acpu < bcpu) | |
2302 | return 1; | |
2303 | ||
2304 | if (acpu > bcpu) | |
2305 | return -1; | |
2306 | ||
2307 | return compmem(a, b); | |
2285 | 2308 | } |
2286 | 2309 | |
2287 | 2310 | int |
2303 | 2326 | else |
2304 | 2327 | bdsk = tb->dsk.rio; |
2305 | 2328 | |
2306 | if (adsk < bdsk) return 1; | |
2307 | if (adsk > bdsk) return -1; | |
2308 | return compcpu(a, b); | |
2329 | if (adsk < bdsk) | |
2330 | return 1; | |
2331 | ||
2332 | if (adsk > bdsk) | |
2333 | return -1; | |
2334 | ||
2335 | return compcpu(a, b); | |
2309 | 2336 | } |
2310 | 2337 | |
2311 | 2338 | int |
2314 | 2341 | register count_t amem = (*(struct tstat **)a)->mem.rmem; |
2315 | 2342 | register count_t bmem = (*(struct tstat **)b)->mem.rmem; |
2316 | 2343 | |
2317 | if (amem < bmem) return 1; | |
2318 | if (amem > bmem) return -1; | |
2319 | return 0; | |
2344 | if (amem < bmem) | |
2345 | return 1; | |
2346 | ||
2347 | if (amem > bmem) | |
2348 | return -1; | |
2349 | ||
2350 | return 0; | |
2320 | 2351 | } |
2321 | 2352 | |
2322 | 2353 | int |
2337 | 2368 | |
2338 | 2369 | if (abusy == -1 || bbusy == -1) |
2339 | 2370 | { |
2340 | if (amem < bmem) return 1; | |
2341 | if (amem > bmem) return -1; | |
2342 | return 0; | |
2371 | if (amem < bmem) | |
2372 | return 1; | |
2373 | ||
2374 | if (amem > bmem) | |
2375 | return -1; | |
2376 | ||
2377 | return 0; | |
2343 | 2378 | } |
2344 | 2379 | else |
2345 | 2380 | { |
2346 | if (abusy < bbusy) return 1; | |
2347 | if (abusy > bbusy) return -1; | |
2348 | return 0; | |
2381 | if (abusy < bbusy) | |
2382 | return 1; | |
2383 | ||
2384 | if (abusy > bbusy) | |
2385 | return -1; | |
2386 | ||
2387 | return 0; | |
2349 | 2388 | } |
2350 | 2389 | } |
2351 | 2390 | |
2361 | 2400 | (*(struct tstat **)b)->net.udpssz + |
2362 | 2401 | (*(struct tstat **)b)->net.udprsz ; |
2363 | 2402 | |
2364 | if (anet < bnet) return 1; | |
2365 | if (anet > bnet) return -1; | |
2366 | return compcpu(a, b); | |
2403 | if (anet < bnet) | |
2404 | return 1; | |
2405 | ||
2406 | if (anet > bnet) | |
2407 | return -1; | |
2408 | ||
2409 | return compcpu(a, b); | |
2367 | 2410 | } |
2368 | 2411 | |
2369 | 2412 | int |
2372 | 2415 | register int uida = (*(struct tstat **)a)->gen.ruid; |
2373 | 2416 | register int uidb = (*(struct tstat **)b)->gen.ruid; |
2374 | 2417 | |
2375 | if (uida > uidb) return 1; | |
2376 | if (uida < uidb) return -1; | |
2377 | return 0; | |
2418 | if (uida > uidb) | |
2419 | return 1; | |
2420 | ||
2421 | if (uida < uidb) | |
2422 | return -1; | |
2423 | ||
2424 | return 0; | |
2378 | 2425 | } |
2379 | 2426 | |
2380 | 2427 | int |
2406 | 2453 | register count_t bidle = ((struct percpu *)b)->itime + |
2407 | 2454 | ((struct percpu *)b)->wtime; |
2408 | 2455 | |
2409 | if (aidle < bidle) return -1; | |
2410 | if (aidle > bidle) return 1; | |
2411 | return 0; | |
2456 | if (aidle < bidle) | |
2457 | return -1; | |
2458 | ||
2459 | if (aidle > bidle) | |
2460 | return 1; | |
2461 | ||
2462 | return 0; | |
2412 | 2463 | } |
2413 | 2464 | |
2414 | 2465 | int |
2421 | 2472 | |
2422 | 2473 | if (agpuperc == -1 || bgpuperc == -1) |
2423 | 2474 | { |
2424 | if (amemuse < bmemuse) return 1; | |
2425 | if (amemuse > bmemuse) return -1; | |
2426 | return 0; | |
2475 | if (amemuse < bmemuse) | |
2476 | return 1; | |
2477 | ||
2478 | if (amemuse > bmemuse) | |
2479 | return -1; | |
2480 | ||
2481 | return 0; | |
2427 | 2482 | } |
2428 | 2483 | else |
2429 | 2484 | { |
2430 | if (agpuperc < bgpuperc) return 1; | |
2431 | if (agpuperc > bgpuperc) return -1; | |
2432 | return 0; | |
2485 | if (agpuperc < bgpuperc) | |
2486 | return 1; | |
2487 | ||
2488 | if (agpuperc > bgpuperc) | |
2489 | return -1; | |
2490 | ||
2491 | return 0; | |
2433 | 2492 | } |
2434 | 2493 | } |
2435 | 2494 | |
2439 | 2498 | register count_t amsio = ((struct perdsk *)a)->io_ms; |
2440 | 2499 | register count_t bmsio = ((struct perdsk *)b)->io_ms; |
2441 | 2500 | |
2442 | if (amsio < bmsio) return 1; | |
2443 | if (amsio > bmsio) return -1; | |
2444 | return 0; | |
2501 | if (amsio < bmsio) | |
2502 | return 1; | |
2503 | ||
2504 | if (amsio > bmsio) | |
2505 | return -1; | |
2506 | ||
2507 | return 0; | |
2445 | 2508 | } |
2446 | 2509 | |
2447 | 2510 | int |
2487 | 2550 | */ |
2488 | 2551 | if (aspeed && bspeed) |
2489 | 2552 | { |
2490 | if (afactor < bfactor) return 1; | |
2491 | if (afactor > bfactor) return -1; | |
2492 | return 0; | |
2553 | if (afactor < bfactor) | |
2554 | return 1; | |
2555 | ||
2556 | if (afactor > bfactor) | |
2557 | return -1; | |
2558 | ||
2559 | return 0; | |
2493 | 2560 | } |
2494 | 2561 | |
2495 | 2562 | if (!aspeed && !bspeed) |
2496 | 2563 | { |
2497 | if ((arbyte + asbyte) < (brbyte + bsbyte)) return 1; | |
2498 | if ((arbyte + asbyte) > (brbyte + bsbyte)) return -1; | |
2499 | return 0; | |
2564 | if ((arbyte + asbyte) < (brbyte + bsbyte)) | |
2565 | return 1; | |
2566 | ||
2567 | if ((arbyte + asbyte) > (brbyte + bsbyte)) | |
2568 | return -1; | |
2569 | ||
2570 | return 0; | |
2500 | 2571 | } |
2501 | 2572 | |
2502 | 2573 | if (aspeed) |
2514 | 2585 | count_t btransfer = ((struct perifb *)b)->rcvb + |
2515 | 2586 | ((struct perifb *)b)->sndb; |
2516 | 2587 | |
2517 | if (atransfer < btransfer) return 1; | |
2518 | if (atransfer > btransfer) return -1; | |
2519 | return 0; | |
2588 | if (atransfer < btransfer) | |
2589 | return 1; | |
2590 | ||
2591 | if (atransfer > btransfer) | |
2592 | return -1; | |
2593 | ||
2594 | return 0; | |
2520 | 2595 | } |
2521 | 2596 | |
2522 | 2597 | |
2535 | 2610 | nb->bytestotread + nb->bytestotwrite + |
2536 | 2611 | nb->pagesmread + nb->pagesmwrite; |
2537 | 2612 | |
2538 | if (aused < bused) return 1; | |
2539 | if (aused > bused) return -1; | |
2540 | return 0; | |
2613 | if (aused < bused) | |
2614 | return 1; | |
2615 | ||
2616 | if (aused > bused) | |
2617 | return -1; | |
2618 | ||
2619 | return 0; | |
2541 | 2620 | } |
2542 | 2621 | |
2543 | 2622 | int |
2549 | 2628 | register count_t aused = ca->system + ca->user + ca->nice; |
2550 | 2629 | register count_t bused = cb->system + cb->user + cb->nice; |
2551 | 2630 | |
2552 | if (aused < bused) return 1; | |
2553 | if (aused > bused) return -1; | |
2554 | return 0; | |
2631 | if (aused < bused) | |
2632 | return 1; | |
2633 | ||
2634 | if (aused > bused) | |
2635 | return -1; | |
2636 | ||
2637 | return 0; | |
2555 | 2638 | } |
2556 | 2639 | |
2557 | 2640 | /* |
188 | 188 | extern sys_printdef syspdef_SHMRSS; |
189 | 189 | extern sys_printdef syspdef_SHMSWP; |
190 | 190 | extern sys_printdef syspdef_VMWBAL; |
191 | extern sys_printdef syspdef_ZFSARC; | |
191 | 192 | extern sys_printdef syspdef_HUPTOT; |
192 | 193 | extern sys_printdef syspdef_HUPUSE; |
193 | 194 | extern sys_printdef syspdef_SWPTOT; |
194 | 195 | extern sys_printdef syspdef_SWPFREE; |
196 | extern sys_printdef syspdef_SWPCACHE; | |
195 | 197 | extern sys_printdef syspdef_SWPCOMMITTED; |
196 | 198 | extern sys_printdef syspdef_SWPCOMMITLIM; |
197 | 199 | extern sys_printdef syspdef_PAGSCAN; |
199 | 201 | extern sys_printdef syspdef_PAGSTALL; |
200 | 202 | extern sys_printdef syspdef_PAGSWIN; |
201 | 203 | extern sys_printdef syspdef_PAGSWOUT; |
204 | extern sys_printdef syspdef_PSICPUSTOT; | |
205 | extern sys_printdef syspdef_PSIMEMSTOT; | |
206 | extern sys_printdef syspdef_PSIMEMFTOT; | |
207 | extern sys_printdef syspdef_PSIIOSTOT; | |
208 | extern sys_printdef syspdef_PSIIOFTOT; | |
202 | 209 | extern sys_printdef syspdef_PSICPUS; |
203 | 210 | extern sys_printdef syspdef_PSIMEMS; |
204 | 211 | extern sys_printdef syspdef_PSIMEMF; |
313 | 320 | extern proc_printdef procprt_VDATA; |
314 | 321 | extern proc_printdef procprt_VSTACK; |
315 | 322 | extern proc_printdef procprt_SWAPSZ; |
323 | extern proc_printdef procprt_LOCKSZ; | |
316 | 324 | extern proc_printdef procprt_CMD; |
317 | 325 | extern proc_printdef procprt_RUID; |
318 | 326 | extern proc_printdef procprt_EUID; |
365 | 373 | extern proc_printdef procprt_GPUGPUBUSY; |
366 | 374 | extern proc_printdef procprt_GPUMEMBUSY; |
367 | 375 | extern proc_printdef procprt_SORTITEM; |
376 | extern proc_printdef procprt_RUNDELAY; | |
377 | extern proc_printdef procprt_WCHAN; | |
368 | 378 | |
369 | 379 | |
370 | 380 |
80 | 80 | ** Initial |
81 | 81 | ** |
82 | 82 | */ |
83 | ||
84 | static const char rcsid[] = "$Id: showprocs.c,v 1.15 2011/09/05 11:44:16 gerlof Exp $"; | |
85 | 83 | |
86 | 84 | #include <sys/types.h> |
87 | 85 | #include <sys/param.h> |
511 | 509 | { |
512 | 510 | static char buf[64]; |
513 | 511 | |
514 | sprintf(buf, "%*s", procprt_PPID.width, "-"); | |
512 | if (curstat->gen.ppid) | |
513 | sprintf(buf, "%*d", procprt_PPID.width, curstat->gen.ppid); | |
514 | else | |
515 | sprintf(buf, "%*s", procprt_PPID.width, "-"); | |
515 | 516 | return buf; |
516 | 517 | } |
517 | 518 | |
816 | 817 | |
817 | 818 | proc_printdef procprt_SWAPSZ = |
818 | 819 | { "SWAPSZ", "SWAPSZ", procprt_SWAPSZ_a, procprt_SWAPSZ_e, 6 }; |
820 | /***************************************************************/ | |
821 | char * | |
822 | procprt_LOCKSZ_a(struct tstat *curstat, int avgval, int nsecs) | |
823 | { | |
824 | static char buf[10]; | |
825 | ||
826 | val2memstr(curstat->mem.vlock*1024, buf, KBFORMAT, 0, 0); | |
827 | return buf; | |
828 | } | |
829 | ||
830 | char * | |
831 | procprt_LOCKSZ_e(struct tstat *curstat, int avgval, int nsecs) | |
832 | { | |
833 | return " 0K"; | |
834 | } | |
835 | ||
836 | proc_printdef procprt_LOCKSZ = | |
837 | { "LOCKSZ", "LOCKSZ", procprt_LOCKSZ_a, procprt_LOCKSZ_e, 6 }; | |
819 | 838 | /***************************************************************/ |
820 | 839 | char * |
821 | 840 | procprt_CMD_a(struct tstat *curstat, int avgval, int nsecs) |
2017 | 2036 | { "MEMBUSY", "GPUMEMBUSY", procprt_GPUMEMBUSY_ae, procprt_GPUMEMBUSY_ae, 7}; |
2018 | 2037 | /***************************************************************/ |
2019 | 2038 | char * |
2039 | procprt_WCHAN_a(struct tstat *curstat, int avgval, int nsecs) | |
2040 | { | |
2041 | static char buf[32]; | |
2042 | ||
2043 | if (curstat->gen.state != 'R') | |
2044 | snprintf(buf, sizeof buf, "%-15.15s", curstat->cpu.wchan); | |
2045 | else | |
2046 | snprintf(buf, sizeof buf, "%-15.15s", " "); | |
2047 | ||
2048 | return buf; | |
2049 | } | |
2050 | ||
2051 | char * | |
2052 | procprt_WCHAN_e(struct tstat *curstat, int avgval, int nsecs) | |
2053 | { | |
2054 | static char buf[32]; | |
2055 | ||
2056 | snprintf(buf, sizeof buf, "%-15.15s", " "); | |
2057 | return buf; | |
2058 | } | |
2059 | ||
2060 | proc_printdef procprt_WCHAN = | |
2061 | { "WCHAN ", "WCHAN", procprt_WCHAN_a, procprt_WCHAN_e, 15 }; | |
2062 | /***************************************************************/ | |
2063 | char * | |
2064 | procprt_RUNDELAY_a(struct tstat *curstat, int avgval, int nsecs) | |
2065 | { | |
2066 | static char buf[10]; | |
2067 | ||
2068 | val2cpustr(curstat->cpu.rundelay/1000000, buf); | |
2069 | return buf; | |
2070 | } | |
2071 | ||
2072 | char * | |
2073 | procprt_RUNDELAY_e(struct tstat *curstat, int avgval, int nsecs) | |
2074 | { | |
2075 | static char buf[10]; | |
2076 | ||
2077 | snprintf(buf, sizeof buf, " -"); | |
2078 | return buf; | |
2079 | } | |
2080 | ||
2081 | proc_printdef procprt_RUNDELAY = | |
2082 | { "RDELAY", "RDELAY", procprt_RUNDELAY_a, procprt_RUNDELAY_e, 6 }; | |
2083 | /***************************************************************/ | |
2084 | char * | |
2020 | 2085 | procprt_SORTITEM_ae(struct tstat *curstat, int avgval, int nsecs) |
2021 | 2086 | { |
2022 | 2087 | return ""; // dummy function |
67 | 67 | ** |
68 | 68 | */ |
69 | 69 | |
70 | static const char rcsid[] = "XXXXXX"; | |
71 | ||
72 | 70 | #include <sys/types.h> |
73 | 71 | #include <sys/param.h> |
74 | 72 | #include <sys/stat.h> |
960 | 958 | sysprt_CPLAVG1(void *p, void *notused, int badness, int *color) |
961 | 959 | { |
962 | 960 | struct sstat *sstat=p; |
963 | static char buf[15]="avg1 "; | |
964 | ||
965 | if (sstat->cpu.lavg1 > 999.0) | |
961 | static char buf[17]="avg1 "; | |
962 | ||
963 | if (sstat->cpu.lavg1 > 999999.0) | |
964 | { | |
965 | sprintf(buf+5, ">999999"); | |
966 | } | |
967 | else if (sstat->cpu.lavg1 > 999.0) | |
966 | 968 | { |
967 | 969 | sprintf(buf+5, "%7.0f", sstat->cpu.lavg1); |
968 | 970 | } |
981 | 983 | struct sstat *sstat=p; |
982 | 984 | static char buf[15]="avg5 "; |
983 | 985 | |
984 | if (sstat->cpu.lavg5 > 999.0) | |
986 | if (sstat->cpu.lavg5 > 999999.0) | |
987 | { | |
988 | sprintf(buf+5, ">999999"); | |
989 | } | |
990 | else if (sstat->cpu.lavg5 > 999.0) | |
985 | 991 | { |
986 | 992 | sprintf(buf+5, "%7.0f", sstat->cpu.lavg5); |
987 | 993 | } |
1003 | 1009 | if (sstat->cpu.lavg15 > (2 * sstat->cpu.nrcpu) ) |
1004 | 1010 | *color = COLORALMOST; |
1005 | 1011 | |
1006 | if (sstat->cpu.lavg15 > 999.0) | |
1012 | if (sstat->cpu.lavg15 > 99999.0) | |
1013 | { | |
1014 | sprintf(buf+6, ">99999"); | |
1015 | } | |
1016 | else if (sstat->cpu.lavg15 > 999.0) | |
1007 | 1017 | { |
1008 | 1018 | sprintf(buf+6, "%6.0f", sstat->cpu.lavg15); |
1009 | 1019 | } |
1406 | 1416 | sys_printdef syspdef_VMWBAL = {"VMWBAL", sysprt_VMWBAL}; |
1407 | 1417 | /*******************************************************************/ |
1408 | 1418 | char * |
1419 | sysprt_ZFSARC(void *p, void *notused, int badness, int *color) | |
1420 | { | |
1421 | struct sstat *sstat=p; | |
1422 | static char buf[16]="zfarc "; | |
1423 | *color = -1; | |
1424 | val2memstr(sstat->mem.zfsarcsize * pagesize, buf+6, MBFORMAT, 0, 0); | |
1425 | return buf; | |
1426 | } | |
1427 | ||
1428 | sys_printdef syspdef_ZFSARC = {"ZFSARC", sysprt_ZFSARC}; | |
1429 | /*******************************************************************/ | |
1430 | char * | |
1409 | 1431 | sysprt_SWPTOT(void *p, void *notused, int badness, int *color) |
1410 | 1432 | { |
1411 | 1433 | struct sstat *sstat=p; |
1428 | 1450 | } |
1429 | 1451 | |
1430 | 1452 | sys_printdef syspdef_SWPFREE = {"SWPFREE", sysprt_SWPFREE}; |
1453 | /*******************************************************************/ | |
1454 | char * | |
1455 | sysprt_SWPCACHE(void *p, void *notused, int badness, int *color) | |
1456 | { | |
1457 | struct sstat *sstat=p; | |
1458 | static char buf[16]="swcac "; | |
1459 | *color = -1; | |
1460 | val2memstr(sstat->mem.swapcached * pagesize, buf+6, MBFORMAT, 0, 0); | |
1461 | return buf; | |
1462 | } | |
1463 | ||
1464 | sys_printdef syspdef_SWPCACHE = {"SWPCACHE", sysprt_SWPCACHE}; | |
1431 | 1465 | /*******************************************************************/ |
1432 | 1466 | char * |
1433 | 1467 | sysprt_SWPCOMMITTED(void *p, void *notused, int badness, int *color) |
1520 | 1554 | |
1521 | 1555 | sys_printdef syspdef_PAGSWOUT = {"PAGSWOUT", sysprt_PAGSWOUT}; |
1522 | 1556 | /*******************************************************************/ |
1523 | // general formatting of PSI field | |
1557 | // general formatting of PSI field in avg10/avg60/avg300 | |
1524 | 1558 | void |
1525 | psiformat(struct psi *p, char *head, char *buf, int bufsize) | |
1559 | psiformatavg(struct psi *p, char *head, char *buf, int bufsize) | |
1526 | 1560 | { |
1527 | 1561 | static char formats[] = "%.0f/%.0f/%.0f"; |
1528 | 1562 | char tmpbuf[32]; |
1553 | 1587 | { |
1554 | 1588 | struct sstat *sstat=p; |
1555 | 1589 | static char buf[16]; |
1556 | psiformat(&(sstat->psi.cpusome), "cs", buf, sizeof buf); | |
1590 | psiformatavg(&(sstat->psi.cpusome), "cs", buf, sizeof buf); | |
1557 | 1591 | return buf; |
1558 | 1592 | } |
1559 | 1593 | sys_printdef syspdef_PSICPUS = {"PSICPUS", sysprt_PSICPUS}; |
1563 | 1597 | { |
1564 | 1598 | struct sstat *sstat=p; |
1565 | 1599 | static char buf[16]; |
1566 | psiformat(&(sstat->psi.memsome), "ms", buf, sizeof buf); | |
1600 | psiformatavg(&(sstat->psi.memsome), "ms", buf, sizeof buf); | |
1567 | 1601 | return buf; |
1568 | 1602 | } |
1569 | 1603 | sys_printdef syspdef_PSIMEMS = {"PSIMEMS", sysprt_PSIMEMS}; |
1573 | 1607 | { |
1574 | 1608 | struct sstat *sstat=p; |
1575 | 1609 | static char buf[16]; |
1576 | psiformat(&(sstat->psi.memfull), "mf", buf, sizeof buf); | |
1610 | psiformatavg(&(sstat->psi.memfull), "mf", buf, sizeof buf); | |
1577 | 1611 | return buf; |
1578 | 1612 | } |
1579 | 1613 | sys_printdef syspdef_PSIMEMF = {"PSIMEMF", sysprt_PSIMEMF}; |
1583 | 1617 | { |
1584 | 1618 | struct sstat *sstat=p; |
1585 | 1619 | static char buf[16]; |
1586 | psiformat(&(sstat->psi.iosome), "is", buf, sizeof buf); | |
1620 | psiformatavg(&(sstat->psi.iosome), "is", buf, sizeof buf); | |
1587 | 1621 | return buf; |
1588 | 1622 | } |
1589 | 1623 | sys_printdef syspdef_PSIIOS = {"PSIIOS", sysprt_PSIIOS}; |
1593 | 1627 | { |
1594 | 1628 | struct sstat *sstat=p; |
1595 | 1629 | static char buf[16]; |
1596 | psiformat(&(sstat->psi.iofull), "if", buf, sizeof buf); | |
1630 | psiformatavg(&(sstat->psi.iofull), "if", buf, sizeof buf); | |
1597 | 1631 | return buf; |
1598 | 1632 | } |
1599 | 1633 | sys_printdef syspdef_PSIIOF = {"PSIIOF", sysprt_PSIIOF}; |
1634 | ||
1635 | /*******************************************************************/ | |
1636 | // general formatting of PSI field in total percentage | |
1637 | void | |
1638 | psiformattot(struct psi *p, char *head, void *q, int *color, char *buf, int bufsize) | |
1639 | { | |
1640 | static char formats[] = "%-7.7s %3lu%%"; | |
1641 | extraparam *as=q; | |
1642 | unsigned long perc = p->total/(as->nsecs*10000); | |
1643 | ||
1644 | if (perc > 100) | |
1645 | perc = 100; | |
1646 | ||
1647 | if (perc >= 1) | |
1648 | *color = COLORALMOST; | |
1649 | ||
1650 | snprintf(buf, bufsize, formats, head, perc); | |
1651 | } | |
1652 | ||
1653 | char * | |
1654 | sysprt_PSICPUSTOT(void *p, void *q, int badness, int *color) | |
1655 | { | |
1656 | struct sstat *sstat=p; | |
1657 | static char buf[32]; | |
1658 | ||
1659 | psiformattot(&(sstat->psi.cpusome), "cpusome", q, color, buf, sizeof buf); | |
1660 | return buf; | |
1661 | } | |
1662 | sys_printdef syspdef_PSICPUSTOT = {"PSICPUSTOT", sysprt_PSICPUSTOT}; | |
1663 | ||
1664 | char * | |
1665 | sysprt_PSIMEMSTOT(void *p, void *q, int badness, int *color) | |
1666 | { | |
1667 | struct sstat *sstat=p; | |
1668 | static char buf[32]; | |
1669 | ||
1670 | psiformattot(&(sstat->psi.memsome), "memsome", q, color, buf, sizeof buf); | |
1671 | return buf; | |
1672 | } | |
1673 | sys_printdef syspdef_PSIMEMSTOT = {"PSIMEMSTOT", sysprt_PSIMEMSTOT}; | |
1674 | ||
1675 | char * | |
1676 | sysprt_PSIMEMFTOT(void *p, void *q, int badness, int *color) | |
1677 | { | |
1678 | struct sstat *sstat=p; | |
1679 | static char buf[32]; | |
1680 | ||
1681 | psiformattot(&(sstat->psi.memfull), "memfull", q, color, buf, sizeof buf); | |
1682 | return buf; | |
1683 | } | |
1684 | sys_printdef syspdef_PSIMEMFTOT = {"PSIMEMFTOT", sysprt_PSIMEMFTOT}; | |
1685 | ||
1686 | char * | |
1687 | sysprt_PSIIOSTOT(void *p, void *q, int badness, int *color) | |
1688 | { | |
1689 | struct sstat *sstat=p; | |
1690 | static char buf[32]; | |
1691 | ||
1692 | psiformattot(&(sstat->psi.iosome), "iosome", q, color, buf, sizeof buf); | |
1693 | return buf; | |
1694 | } | |
1695 | sys_printdef syspdef_PSIIOSTOT = {"PSIIOSTOT", sysprt_PSIIOSTOT}; | |
1696 | ||
1697 | ||
1698 | char * | |
1699 | sysprt_PSIIOFTOT(void *p, void *q, int badness, int *color) | |
1700 | { | |
1701 | struct sstat *sstat=p; | |
1702 | static char buf[32]; | |
1703 | ||
1704 | psiformattot(&(sstat->psi.iofull), "iofull", q, color, buf, sizeof buf); | |
1705 | return buf; | |
1706 | } | |
1707 | sys_printdef syspdef_PSIIOFTOT = {"PSIIOFTOT", sysprt_PSIIOFTOT}; | |
1600 | 1708 | |
1601 | 1709 | /*******************************************************************/ |
1602 | 1710 | char * |
1828 | 1936 | |
1829 | 1937 | *color = -1; |
1830 | 1938 | |
1831 | if (tim > 100.0) | |
1939 | if (tim >= 100.0) | |
1832 | 1940 | { |
1833 | 1941 | sprintf(buf+5, "%4.0lf ms", tim); |
1834 | } | |
1835 | else if (tim > 10.0) | |
1942 | } | |
1943 | else if (tim >= 10.0) | |
1836 | 1944 | { |
1837 | 1945 | sprintf(buf+5, "%4.1lf ms", tim); |
1838 | 1946 | } |
1839 | else | |
1947 | else if (tim >= 0.1) | |
1840 | 1948 | { |
1841 | 1949 | sprintf(buf+5, "%4.2lf ms", tim); |
1950 | } | |
1951 | else if (tim >= 0.01) | |
1952 | { | |
1953 | sprintf(buf+5, "%4.1lf µs", tim * 1000.0); | |
1954 | } | |
1955 | else if (tim >= 0.0001) | |
1956 | { | |
1957 | sprintf(buf+5, "%4.2lf µs", tim * 1000.0); | |
1958 | } | |
1959 | else | |
1960 | { | |
1961 | sprintf(buf+5, "%4.1lf ns", tim * 1000000.0); | |
1842 | 1962 | } |
1843 | 1963 | |
1844 | 1964 | return buf; |
2123 | 2243 | (sstat->intf.intf[as->index].speed *10); |
2124 | 2244 | } |
2125 | 2245 | |
2246 | if( busy < -99 ) | |
2247 | { | |
2248 | // when we get wrong values, show wrong values | |
2249 | busy = -99; | |
2250 | } | |
2251 | else if( busy > 999 ) | |
2252 | { | |
2253 | busy = 999; | |
2254 | } | |
2126 | 2255 | snprintf(buf, sizeof(buf)-1, "%-7.7s %3lld%%", |
2127 | 2256 | sstat->intf.intf[as->index].name, busy); |
2128 | 2257 | |
2203 | 2332 | c = 'T'; |
2204 | 2333 | } |
2205 | 2334 | |
2206 | sprintf(buf+3, "%4lld %cbps", val, c); | |
2335 | if(val < -999) | |
2336 | { | |
2337 | // when we get wrong values, show wrong values | |
2338 | val = -999; | |
2339 | } | |
2340 | else if(val > 9999) | |
2341 | { | |
2342 | val = 9999; | |
2343 | } | |
2344 | ||
2345 | snprintf(buf+3, sizeof(buf)-3, "%4lld %cbps", val, c); | |
2207 | 2346 | |
2208 | 2347 | return buf; |
2209 | 2348 | } |
2217 | 2356 | count_t speed = sstat->intf.intf[as->index].speed; |
2218 | 2357 | |
2219 | 2358 | *color = -1; |
2359 | ||
2360 | if (speed < 0 ) | |
2361 | speed = 0; | |
2220 | 2362 | |
2221 | 2363 | if (speed < 10000) |
2222 | 2364 | { |
2225 | 2367 | else |
2226 | 2368 | { |
2227 | 2369 | speed /= 1000; |
2370 | ||
2371 | if (speed > 9999) | |
2372 | { | |
2373 | speed = 9999; | |
2374 | } | |
2228 | 2375 | snprintf(buf, sizeof buf, "sp %4lld Gbps", speed); |
2229 | 2376 | } |
2230 | 2377 | |
2411 | 2558 | { |
2412 | 2559 | struct sstat *sstat = p; |
2413 | 2560 | extraparam *as = q; |
2414 | static char buf[16]; | |
2561 | static char buf[64]; | |
2415 | 2562 | count_t rate = sstat->ifb.ifb[as->index].rate; |
2416 | 2563 | |
2417 | 2564 | *color = -1; |
2423 | 2570 | else |
2424 | 2571 | { |
2425 | 2572 | rate /= 1000; |
2573 | ||
2574 | if (rate > 9999) | |
2575 | { | |
2576 | rate = 9999; | |
2577 | } | |
2426 | 2578 | snprintf(buf, sizeof buf, "sp %4lld Gbps", rate); |
2427 | 2579 | } |
2428 | 2580 |
110 | 110 | #include <stdlib.h> |
111 | 111 | #include <errno.h> |
112 | 112 | #include <stdarg.h> |
113 | #include <string.h> | |
114 | #include <fcntl.h> | |
113 | 115 | |
114 | 116 | #include "atop.h" |
115 | 117 | #include "acctproc.h" |
151 | 153 | |
152 | 154 | |
153 | 155 | /* |
154 | ** Convert a hh:mm string into a number of seconds since 00:00 | |
156 | ** Convert a string in format [YYYYMMDD]hh[:]mm into an epoch time value or | |
157 | ** when only the value hh[:]mm was given, take this time from midnight. | |
158 | ** | |
159 | ** Arguments: String with date-time in format [YYYYMMDD]hh[:]mm | |
160 | ** or hh[:]mm. | |
161 | ** | |
162 | ** Pointer to time_t containing 0 or current epoch time. | |
155 | 163 | ** |
156 | 164 | ** Return-value: 0 - Wrong input-format |
157 | 165 | ** 1 - Success |
158 | 166 | */ |
159 | 167 | int |
160 | hhmm2secs(char *itim, unsigned int *otim) | |
161 | { | |
162 | register int i; | |
168 | getbranchtime(char *itim, time_t *newtime) | |
169 | { | |
170 | register int ilen = strlen(itim); | |
163 | 171 | int hours, minutes; |
172 | time_t epoch; | |
173 | struct tm tm; | |
174 | ||
175 | memset(&tm, 0, sizeof tm); | |
164 | 176 | |
165 | 177 | /* |
166 | ** check string syntax | |
178 | ** verify length of input string | |
167 | 179 | */ |
168 | for (i=0; *(itim+i); i++) | |
169 | if ( !isdigit(*(itim+i)) && *(itim+i) != ':' ) | |
170 | return(0); | |
171 | ||
172 | sscanf(itim, "%d:%d", &hours, &minutes); | |
173 | ||
174 | if ( hours < 0 || hours > 23 || minutes < 0 || minutes > 59 ) | |
175 | return(0); | |
176 | ||
177 | *otim = (hours * 3600) + (minutes * 60); | |
178 | ||
179 | if (*otim >= SECSDAY) | |
180 | *otim = SECSDAY-1; | |
181 | ||
182 | return(1); | |
183 | } | |
184 | ||
185 | ||
186 | /* | |
187 | ** Return number of seconds since midnight according local clock time | |
188 | ** | |
189 | ** Return-value: Number of seconds | |
190 | */ | |
191 | int | |
192 | daysecs(time_t itime) | |
193 | { | |
194 | struct tm *tt; | |
195 | ||
196 | tt = localtime(&itime); | |
197 | ||
198 | return( (tt->tm_hour*3600) + (tt->tm_min*60) ); | |
180 | if (ilen != 4 && ilen != 5 && ilen != 12 && ilen != 13) | |
181 | return 0; // wrong date-time format | |
182 | ||
183 | /* | |
184 | ** check string syntax for absolute time specified as | |
185 | ** YYYYMMDDhh:mm or YYYYMMDDhhmm | |
186 | */ | |
187 | if ( sscanf(itim, "%4d%2d%2d%2d:%2d", &tm.tm_year, &tm.tm_mon, | |
188 | &tm.tm_mday, &tm.tm_hour, &tm.tm_min) == 5 || | |
189 | sscanf(itim, "%4d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, | |
190 | &tm.tm_mday, &tm.tm_hour, &tm.tm_min) == 5 ) | |
191 | { | |
192 | tm.tm_year -= 1900; | |
193 | tm.tm_mon -= 1; | |
194 | ||
195 | if (tm.tm_year < 100 || tm.tm_mon < 0 || tm.tm_mon > 11 || | |
196 | tm.tm_mday < 1 || tm.tm_mday > 31 || | |
197 | tm.tm_hour < 0 || tm.tm_hour > 23 || | |
198 | tm.tm_min < 0 || tm.tm_min > 59 ) | |
199 | { | |
200 | return 0; // wrong date-time format | |
201 | } | |
202 | ||
203 | tm.tm_isdst = -1; | |
204 | ||
205 | if ((epoch = mktime(&tm)) == -1) | |
206 | return 0; // wrong date-time format | |
207 | ||
208 | // correct date-time format | |
209 | *newtime = epoch; | |
210 | return 1; | |
211 | } | |
212 | ||
213 | /* | |
214 | ** check string syntax for relative time specified as | |
215 | ** hh:mm or hhmm | |
216 | */ | |
217 | if ( sscanf(itim, "%2d:%2d", &hours, &minutes) == 2 || | |
218 | sscanf(itim, "%2d%2d", &hours, &minutes) == 2 ) | |
219 | { | |
220 | if ( hours < 0 || hours > 23 || minutes < 0 || minutes > 59 ) | |
221 | return 0; // wrong date-time format | |
222 | ||
223 | /* | |
224 | ** when the new time is already filled with an epoch time, | |
225 | ** the relative time will be on the same day as indicated by | |
226 | ** that epoch time | |
227 | ** when the new time is the time within a day or 0, the new | |
228 | ** time will be stored again as the time within a day. | |
229 | */ | |
230 | if (*newtime <= SECONDSINDAY) // time within the day? | |
231 | { | |
232 | *newtime = (hours * 3600) + (minutes * 60); | |
233 | ||
234 | if (*newtime >= SECONDSINDAY) | |
235 | *newtime = SECONDSINDAY-1; | |
236 | ||
237 | return 1; | |
238 | } | |
239 | else | |
240 | { | |
241 | *newtime = normalize_epoch(*newtime, | |
242 | (hours*3600) + (minutes*60)); | |
243 | return 1; | |
244 | } | |
245 | } | |
246 | ||
247 | return 0; // wrong date-time format | |
248 | } | |
249 | ||
250 | ||
251 | /* | |
252 | ** Normalize an epoch time with the number of seconds within a day | |
253 | ** Return-value: Normalized epoch | |
254 | */ | |
255 | time_t | |
256 | normalize_epoch(time_t epoch, long secondsinday) | |
257 | { | |
258 | struct tm tm; | |
259 | ||
260 | localtime_r(&epoch, &tm); // convert epoch to tm | |
261 | ||
262 | tm.tm_hour = 0; | |
263 | tm.tm_min = 0; | |
264 | tm.tm_sec = secondsinday; | |
265 | tm.tm_isdst = -1; | |
266 | ||
267 | return mktime(&tm); // convert tm to epoch | |
199 | 268 | } |
200 | 269 | |
201 | 270 | |
632 | 701 | void |
633 | 702 | regainrootprivs(void) |
634 | 703 | { |
635 | seteuid(0); | |
636 | } | |
704 | int liResult; | |
705 | ||
706 | // this will fail for non-privileged processes | |
707 | liResult = seteuid(0); | |
708 | ||
709 | if (liResult != 0) | |
710 | { | |
711 | } | |
712 | } | |
713 | ||
714 | /* | |
715 | ** try to set the highest OOM priority | |
716 | */ | |
717 | void | |
718 | set_oom_score_adj(void) | |
719 | { | |
720 | int fd; | |
721 | char val[] = "-1000"; /* suggested by Gerlof, always set -1000 */ | |
722 | ||
723 | /* | |
724 | ** set OOM score adj to avoid to lost necessary log of system. | |
725 | ** ignored if not running under superuser privileges! | |
726 | */ | |
727 | fd = open("/proc/self/oom_score_adj", O_RDWR); | |
728 | if ( fd < 0 ) { | |
729 | return; | |
730 | } | |
731 | ||
732 | if ( write(fd, val, strlen(val)) < 0 ) | |
733 | ; | |
734 | ||
735 | close(fd); | |
736 | } |