Codebase list atop / 7a935cd
New upstream version 2.5.0 Marc Haber 3 years ago
31 changed file(s) with 1493 addition(s) and 317 deletion(s). Raw diff Collapse all Expand all
0 commit 6fa0306b8966ac0210bb013de4289951f8499ab8
1 Merge: a802f1a 43b50d0
2 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
3 Date: Sat Oct 26 22:32:32 2019 +0200
4
5 Merge branch 'timers'
6
7 commit 43b50d02d413aba226154d3ce8b4721b27b0a06c
8 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
9 Date: Sat Oct 26 22:28:37 2019 +0200
10
11 Modify man pages and spec files for added unit files
12 The atop.daily script is not used any more for systemd-based systems.
13 The man page of atop has been changed accordingly. Furthermore, the
14 spec files have been modified to install the new unit files.
15
16 M Makefile
17 M atop-rotate.service
18 M atop-rotate.timer
19 D atop.cronsystemd
20 M atop.service
21 M man/atop.1
22 M rpmspec/atop.specsystemd
23 M rpmspec/atop.specsysv
24
25 commit f8024a674203cec60ab311879b34292a10abff5d
26 Merge: a802f1a 97d7b82
27 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
28 Date: Wed Oct 23 21:31:33 2019 +0200
29
30 Merge branch 'master' of git://github.com/SjonHortensius/atop into timers
31
32 commit 97d7b8225d486211a0a02521a406f83780262253
33 Author: Justin Kromlinger <mail@hashworks.net>
34 Date: Fri Oct 11 13:37:27 2019 +0200
35
36 Read environment file in systemd service, use atop defaults (#1)
37
38 Read environment file in systemd service, use atop defaults instead of hardcoded
39
40 M atop.service
41
42 commit a802f1a68ff0f3f06e6a4c609a87c0679bd07fce
43 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
44 Date: Wed Sep 18 21:43:20 2019 +0200
45
46 Allow raw data to be read from a named pipe
47 When reading raw data from a named pipe instead of from
48 a regular file, it is not possible to branch ('b'), reset ('r')
49 or go to a precious sample in an interactive session. With atopsar,
50 only one report can be generated (no combination of various reporting
51 flags).
52
53 M atop.h
54 M atopsar.c
55 M man/atop.1
56 M rawlog.c
57
58 commit db74804d15e98af37ed62bfcad95a93959c9d277
59 Merge: b10ee34 78f99bb
60 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
61 Date: Wed Sep 18 12:02:31 2019 +0200
62
63 Merge pull request #69 from gleventhal/fix-lseek-segfault-on-nonseekable-piped-rawlog
64
65 Check that rawlog is seekable to prevent later segfaults
66
67 commit b10ee3492ee232a600aa934a724c4c687c691e79
68 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
69 Date: Wed Sep 18 11:46:58 2019 +0200
70
71 Improve determination of container ID
72 Many processes might use the cpuset cgroup without being a
73 container. The length of the basename is verified to be at
74 least 64 characters (length of SHA256 identifying a container).
75
76 M photoproc.c
77
78 commit fea96f0690f6694624d85b9cb4f216fafea09b79
79 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
80 Date: Mon Sep 16 21:02:23 2019 +0200
81
82 Correction to avoid loosing first position of CID.
83
84 M photoproc.c
85
86 commit 3fe8f59d71cb8cd70d0fa8d4fd77f232be2922d1
87 Merge: 3e0b68c a3db75e
88 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
89 Date: Mon Sep 16 20:57:26 2019 +0200
90
91 Merge branch 'bytedance-fix-docker-container-k8s'
92
93 commit a3db75e174efbe95518f5a18fe89b9aa8154e177
94 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
95 Date: Mon Sep 16 20:55:04 2019 +0200
96
97 Proposed solution for K8s containers modified.
98 Docker containers on RedHat/CentOS based systems have
99 a prefix 'docker-' behind the last '/' that should
100 be skipped.
101
102 M photoproc.c
103
104 commit 82f2fc889419555a9a1df868e6d1133c0b0169cc
105 Author: zhenwei pi <pizhenwei@bytedance.com>
106 Date: Fri May 24 19:54:42 2019 +0800
107
108 Fix container compatibility for docker created by k8s
109
110 Cpuset of a docker created by k8s looks like this:
111 /kubepods/burstable/pod07dbb922-[SNAP]/223dc5e15b[SNAP]
112
113 Instead of checking prefix "docker", we usually get 12 char from
114 last '/'.
115 Test for docker and k8s, both of them work well. 'CID' row shows
116 the same string as the `docker ps`.
117
118 Test result for k8s:
119 ~# docker ps
120 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
121 e978af4928f6 hub.byted.org/google_containers/pause-amd64:3.0 "/pause" 39 hours ago Up 39 hours k8s_POD_dp-9fe0dd7536-55fd89b474-[SNAP]
122
123 ~# atop -j
124 NPROCS SYSCPU USRCPU VSIZE RSIZE PSIZE SWAPSZ RDDSK WRDSK RNET SNET CPU CID 1/1
125 557 1h42m 2h57m 29.6G 1.3G 1.1G 0K 1.9G 19.0G 0 0 11% host--------
126 1 0.00s 0.00s 1028K 4K 109K 0K 0K 0K 0 0 0% e978af4928f6
127
128 Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
129
130 M photoproc.c
131
132 commit 3e0b68cb9858a16749c98c3d399d2373e239caa6
133 Merge: 1b50456 086366f
134 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
135 Date: Sat Aug 10 12:20:13 2019 +0200
136
137 Merge branch 'bytedance-perfevent'
138 By default, suppress gathering of 'perf' counters on VM guests.
139
140 commit 086366f9e008c711d51e8400ae9d54479224fae0
141 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
142 Date: Sat Aug 10 12:18:46 2019 +0200
143
144 Adapt documentation to new keyword 'perfevents' in atoprc.
145
146 M man/atop.1
147 M man/atoprc.5
148 M photosyst.c
149
150 commit ea9e1814e255922dfedbb428bea48d2800f681f3
151 Merge: 1b50456 16abcac
152 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
153 Date: Sat Aug 10 10:34:48 2019 +0200
154
155 Merge branch 'perfevent' of git://github.com/bytedance/atop into bytedance-perfevent
156 Avoid overhead using perf in VMs.
157
158 commit 1b504568a4562ce6fca93275898e084a8f832d29
159 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
160 Date: Sat Aug 3 12:47:11 2019 +0200
161
162 Error messages no longer wiped by clear screen
163 By introducing function mcleanstop, error messages are
164 shown after ncurses has closed the window (solves issue #67).
165
166 M acctproc.c
167 M atop.c
168 M atop.h
169 M atopsar.c
170 M deviate.c
171 M netatopif.c
172 M photoproc.c
173 M photosyst.c
174 M rawlog.c
175 M showlinux.c
176 M various.c
177
178 commit 1e93ac6a8e486dfda633af049c950040020373c9
179 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
180 Date: Sat Aug 3 09:52:18 2019 +0200
181
182 Exchanged a TAB by spaces in front of statement
183 (TAB was accepted by Python2 but refused by Python3).
184
185 M atopgpud
186 M man/atopgpud.8
187
188 commit 78f99bbfb6d54a420c404fd8c37dc4f48b7f8110
189 Author: gregg leventhal <gregglev@yahoo.com>
190 Date: Mon Jun 24 16:25:58 2019 -0400
191
192 Check if rawlog is a regular, seekable file. If the user does atop -r <(gunzip atop_2019_06_10.gz) for example, a failing lseek will result in a later segfault
193
194 M rawlog.c
195
196 commit 16abcac132eec4755373aa673389e67219488844
197 Author: zhenwei pi <pizhenwei@bytedance.com>
198 Date: Wed Mar 20 14:58:18 2019 +0800
199
200 Auto detect hypervisor and apply to perfevents
201
202 In virtualization case, PMU in guest is emulated by hypervisor, such as
203 vPMU is emulated by KVM.
204 Currently perf in guest has overhead, typically rdpmc/wrmsr cause a lot
205 of vm-exits, and guest will hit a performance drop. atop should be
206 careful while useing perf.
207
208 Support "perfevents" config in atoprc, which supports 3 modes:
209 "enable": force using perf.
210 "disable": force disable perf.
211 "auto": default mode, atop will detect hypervisor. if atop is running in
212 guest, auto disable perf, otherwise enable perf.
213
214 Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
215
216 M atop.c
217 M photosyst.c
218
219 commit 7ebca1362e7158c769770006afd61b7e4ec67211
220 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
221 Date: Fri Jun 7 16:06:30 2019 +0200
222
223 Cosmetic changes.
224
225 M rawlog.c
226
227 commit b55f28a740258e33206443612be2d4fb80464d96
228 Merge: a4e3664 25007e9
229 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
230 Date: Fri Jun 7 15:43:31 2019 +0200
231
232 Merge pull request #60 from bytedance/writev-record
233
234 Use writev to write record data
235
236 commit 25007e9d927f8d37a9f8659d5d2122435409ee7d
237 Author: zhenwei pi <pizhenwei@bytedance.com>
238 Date: Tue Mar 19 16:18:15 2019 +0800
239
240 Use writev to write record data
241
242 Currently atop writes 3 parts of one raw record by 3 write syscall.
243 atop may be killed during writing record, and continue to append records
244 after the original log. uncompleted record data is generated. Ex,
245 good case : ... rr,scompbuf,pcompbuf ... rr,scompbuf,pcompbuf ...
246 bad case : ... rr,scompbuf[missing] ... rr,scompbuf,pcompbuf ...
247
248 1-writev syscall makes writing record as a atomic operation, and make sure
249 each raw record is completed.
250
251 Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
252
253 M rawlog.c
254
255 commit a4e3664f78d8588136696102bb9624b2ec46a54d
256 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
257 Date: Sun May 26 16:55:01 2019 +0200
258
259 Added comment (cosmetic change)
260
261 M photoproc.c
262
263 commit 1338f5f47cc4e11b7afe8f6ce5543126754ae416
264 Merge: b54801c eea28ab
265 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
266 Date: Sun May 26 16:49:16 2019 +0200
267
268 Merge pull request #54 from pacepi/use-smaps-rollup
269
270 Prefer to use smaps_rollup instead of smaps
271
272 commit b54801ca81c06b073126f7f941db1d922a2f1e1c
273 Merge: fa4db43 e7000f7
274 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
275 Date: Sun May 26 16:28:08 2019 +0200
276
277 Merge pull request #57 from gleventhal/master
278
279 Fix unchecked opendir to prevent dereferencing a NULL pointer
280
281 commit e7000f778465cf4e73a60604b799a4b1c0e80b15
282 Author: gregg leventhal <gregglev@yahoo.com>
283 Date: Thu May 2 15:03:02 2019 -0400
284
285 Fix unchecked opendir to prevent dereferrencing a NULL pointer
286
287 M photoproc.c
288
289 commit 65fb301d59208692da4fec1ead38e8efbed66c33
290 Author: Sjon Hortensius <sjon@hortensius.net>
291 Date: Mon Mar 18 13:44:23 2019 +0100
292
293 For systemd - replace 5 files with rotate service and timer
294
295 M Makefile
296 A atop-rotate.service
297 A atop-rotate.timer
298 M atop.service
299
300 commit eea28abb735cbf941045ade56d2c22657bf014b7
301 Author: zhenwei pi <pizhenwei@bytedance.com>
302 Date: Mon Jan 28 20:27:47 2019 +0800
303
304 Prefer to use smaps_rollup instead of smaps
305
306 Since Linux-4.14, kernel supports "/proc/PID/smaps_rollup" to count process
307 Pss.
308 Test case on CPU Intel i7-8700K :
309 1, create a virtual machine with 12G memory.
310 2, count Pss for 3 time with smaps : 7176, 7221, 7182.
311 average 7193(microseconds).
312 3, count Pss for 3 time with smaps_rollup : 1963, 1985, 1972.
313 average 1973(microseconds).
314
315 smaps_rollup has better performence than smaps. We check it in first call,
316 and prefer to use.
317
318 Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
319
320 M photoproc.c
321
322 commit fa4db436865887f3e451692b9439d2943b4b2936
323 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
324 Date: Thu Feb 7 12:03:42 2019 +0100
325
326 Correction of PSI value 'io full'
327 'I/O full' showed the same value as 'I/O some', which has been
328 corrected now.
329
330 M showsys.c
331
332 commit 58a25af78314d432a7591e536fd2d5b23666ecb4
333 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
334 Date: Tue Jan 22 17:32:37 2019 +0100
335
336 Atopconvert shows version of input file and copies if needed.
337 When only the name of the input file is given, then atopconvert
338 shows the version of the input file.
339 When the version of the input file is already up-to-date, still
340 the input file is copied to the output file.
341
342 M atopconvert.c
343 M man/atopconvert.1
344
345 commit c3073ee609509857620c58aa4d050344b63696a2
346 Merge: 41333c6 4b0a957
347 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
348 Date: Sun Jan 13 00:04:29 2019 +0100
349
350 Merge branch 'master' of github.com:Atoptool/atop
351
352 commit 41333c6dab5c16b60d610bfa79f33f1f56793307
353 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
354 Date: Sat Jan 12 23:43:59 2019 +0100
355
356 Various corrections.
357
358 M rpmspec/atop.specsystemd
359
0360 commit 3ca52a7c0c9948eedd6ba25a1a902ebc6488a79f
1361 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
2362 Date: Sat Jan 12 22:31:10 2019 +0100
97457 M showlinux.h
98458 M showprocs.c
99459 M showsys.c
460
461 commit 4b0a957aed6370c4268d592fa6bef78aa141fe82
462 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
463 Date: Tue Jan 8 20:06:15 2019 +0100
464
465 Not enough entries created to register all tasks.
466 Calculation has been adapted.
467
468 M atop.c
469 M photoproc.c
100470
101471 commit 8fe68ff3ed14bd25da93ba0480ec116a7f36b731
102472 Author: Gerlof Langeveld <gerlof.langeveld@atoptool.nl>
1111 MAN5PATH = /usr/share/man/man5
1212 MAN8PATH = /usr/share/man/man8
1313 INIPATH = /etc/init.d
14 DEFPATH = /etc/default
1415 SYSDPATH = /usr/lib/systemd/system
1516 CRNPATH = /etc/cron.d
1617 ROTPATH = /etc/logrotate.d
6364 if [ ! -d $(DESTDIR)$(PMPATHD) ]; \
6465 then mkdir -p $(DESTDIR)$(PMPATHD); fi
6566 #
66 cp atop.service $(DESTDIR)$(SYSDPATH)
67 chmod 0644 $(DESTDIR)$(SYSDPATH)/atop.service
68 cp atopgpu.service $(DESTDIR)$(SYSDPATH)
69 chmod 0644 $(DESTDIR)$(SYSDPATH)/atopgpu.service
70 cp atopacct.service $(DESTDIR)$(SYSDPATH)
71 chmod 0644 $(DESTDIR)$(SYSDPATH)/atopacct.service
72 cp atop.cronsystemd $(DESTDIR)$(CRNPATH)/atop
73 cp atop-pm.sh $(DESTDIR)$(PMPATHD)
74 chmod 0711 $(DESTDIR)$(PMPATHD)/atop-pm.sh
67 cp atop.service $(DESTDIR)$(SYSDPATH)
68 chmod 0644 $(DESTDIR)$(SYSDPATH)/atop.service
69 cp atopgpu.service $(DESTDIR)$(SYSDPATH)
70 chmod 0644 $(DESTDIR)$(SYSDPATH)/atopgpu.service
71 cp atop-rotate.service $(DESTDIR)$(SYSDPATH)
72 chmod 0644 $(DESTDIR)$(SYSDPATH)/atop-rotate.service
73 cp atop-rotate.timer $(DESTDIR)$(SYSDPATH)
74 chmod 0644 $(DESTDIR)$(SYSDPATH)/atop-rotate.timer
75 cp atopacct.service $(DESTDIR)$(SYSDPATH)
76 chmod 0644 $(DESTDIR)$(SYSDPATH)/atopacct.service
77 cp atop-pm.sh $(DESTDIR)$(PMPATHD)
78 chmod 0711 $(DESTDIR)$(PMPATHD)/atop-pm.sh
7579 #
7680 # only when making on target system:
7781 #
7882 if [ -z "$(DESTDIR)" -a -f /bin/systemctl ]; \
79 then /bin/systemctl stop atop 2> /dev/null; \
80 /bin/systemctl disable atop 2> /dev/null; \
81 /bin/systemctl stop atopacct 2> /dev/null; \
82 /bin/systemctl disable atopacct 2> /dev/null; \
83 /bin/systemctl enable atopacct; \
84 /bin/systemctl start atopacct; \
85 /bin/systemctl enable atop; \
86 /bin/systemctl start atop; \
83 then /bin/systemctl disable --now atop 2> /dev/null; \
84 /bin/systemctl disable --now atopacct 2> /dev/null; \
85 /bin/systemctl daemon-reload; \
86 /bin/systemctl enable --now atopacct; \
87 /bin/systemctl enable --now atop; \
88 /bin/systemctl enable --now atop-rotate.timer; \
8789 fi
8890
8991 sysvinstall: genericinstall
9092 if [ ! -d $(DESTDIR)$(INIPATH) ]; \
91 then mkdir -p $(DESTDIR)$(INIPATH); fi
93 then mkdir -p $(DESTDIR)$(INIPATH); fi
94 if [ ! -d $(DESTDIR)$(SCRPATH) ]; \
95 then mkdir -p $(DESTDIR)$(SCRPATH); fi
96 if [ ! -d $(DESTDIR)$(CRNPATH) ]; \
97 then mkdir -p $(DESTDIR)$(CRNPATH); fi
98 if [ ! -d $(DESTDIR)$(ROTPATH) ]; \
99 then mkdir -p $(DESTDIR)$(ROTPATH); fi
92100 #
93101 cp atop.init $(DESTDIR)$(INIPATH)/atop
94102 cp atopacct.init $(DESTDIR)$(INIPATH)/atopacct
95103 cp atop.cronsysv $(DESTDIR)$(CRNPATH)/atop
104 cp atop.daily $(DESTDIR)$(SCRPATH)
105 chmod 0711 $(DESTDIR)$(SCRPATH)/atop.daily
106 cp psaccs_atop $(DESTDIR)$(ROTPATH)/psaccs_atop
107 cp psaccu_atop $(DESTDIR)$(ROTPATH)/psaccu_atop
108 touch $(DESTDIR)$(LOGPATH)/dummy_before
109 touch $(DESTDIR)$(LOGPATH)/dummy_after
96110 #
97111 if [ -d $(DESTDIR)$(PMPATH1) ]; \
98112 then cp 45atoppm $(DESTDIR)$(PMPATH1); \
129143 then mkdir -p $(DESTDIR)$(BINPATH); fi
130144 if [ ! -d $(DESTDIR)$(SBINPATH) ]; \
131145 then mkdir -p $(DESTDIR)$(SBINPATH); fi
132 if [ ! -d $(DESTDIR)$(SCRPATH) ]; \
133 then mkdir -p $(DESTDIR)$(SCRPATH); fi
134146 if [ ! -d $(DESTDIR)$(MAN1PATH) ]; \
135147 then mkdir -p $(DESTDIR)$(MAN1PATH); fi
136148 if [ ! -d $(DESTDIR)$(MAN5PATH) ]; \
137149 then mkdir -p $(DESTDIR)$(MAN5PATH); fi
138150 if [ ! -d $(DESTDIR)$(MAN8PATH) ]; \
139151 then mkdir -p $(DESTDIR)$(MAN8PATH); fi
140 if [ ! -d $(DESTDIR)$(CRNPATH) ]; \
141 then mkdir -p $(DESTDIR)$(CRNPATH); fi
142 if [ ! -d $(DESTDIR)$(ROTPATH) ]; \
143 then mkdir -p $(DESTDIR)$(ROTPATH); fi
152 #
153 touch $(DESTDIR)$(DEFPATH)/atop
154 chmod 644 $(DESTDIR)$(DEFPATH)/atop
144155 #
145156 cp atop $(DESTDIR)$(BINPATH)/atop
146157 chown root $(DESTDIR)$(BINPATH)/atop
157168 cp atopconvert $(DESTDIR)$(BINPATH)/atopconvert
158169 chown root $(DESTDIR)$(BINPATH)/atopconvert
159170 chmod 0711 $(DESTDIR)$(BINPATH)/atopconvert
160 cp atop.daily $(DESTDIR)$(SCRPATH)
161 chmod 0711 $(DESTDIR)$(SCRPATH)/atop.daily
162171 cp man/atop.1 $(DESTDIR)$(MAN1PATH)
163172 cp man/atopsar.1 $(DESTDIR)$(MAN1PATH)
164173 cp man/atopconvert.1 $(DESTDIR)$(MAN1PATH)
165174 cp man/atoprc.5 $(DESTDIR)$(MAN5PATH)
166175 cp man/atopacctd.8 $(DESTDIR)$(MAN8PATH)
167176 cp man/atopgpud.8 $(DESTDIR)$(MAN8PATH)
168 cp psaccs_atop $(DESTDIR)$(ROTPATH)/psaccs_atop
169 cp psaccu_atop $(DESTDIR)$(ROTPATH)/psaccu_atop
170 touch $(DESTDIR)$(LOGPATH)/dummy_before
171 touch $(DESTDIR)$(LOGPATH)/dummy_after
172177
173178 ##########################################################################
174179
221221 ** open active account file with the specified name
222222 */
223223 if (! droprootprivs() )
224 cleanstop(42);
224 mcleanstop(42, "failed to drop root privs\n");
225225
226226 if ( (acctfd = open(ep, O_RDONLY) ) == -1)
227227 return 1;
256256 struct flock flock;
257257
258258 if (! droprootprivs() )
259 cleanstop(42);
259 mcleanstop(42, "failed to drop root privs\n");
260260
261261 (void) semop(sempacctpubid, &semclaim, 1);
262262
549549 break;
550550
551551 default:
552 fprintf(stderr, "Unknown format of process accounting file\n");
553 cleanstop(8);
552 mcleanstop(8, "Unknown format of process accounting file\n");
554553 }
555554
556555 /*
630629 (void) rmdir(ACCTDIR);
631630
632631 if (! droprootprivs() )
633 cleanstop(42);
632 mcleanstop(42,
633 "failed to drop root privs\n");
634634 }
635635 }
636636
970970 (void) acct(ACCTDIR "/" ACCTFILE);
971971
972972 if (! droprootprivs() )
973 cleanstop(42);
973 mcleanstop(42, "failed to drop root privs\n");
974974
975975 acctsize = 0;
976976
0 [Unit]
1 Description=Restart atop daemon to rotate logs
2
3 [Service]
4 Type=oneshot
5 ExecStart=/usr/bin/systemctl try-restart atop.service
0 [Unit]
1 Description=Daily atop restart
2
3 [Timer]
4 OnCalendar=daily
5
6 [Install]
7 WantedBy=timers.target
390390 void do_almostcrit(char *, char *);
391391 void do_atopsarflags(char *, char *);
392392 void do_pacctdir(char *, char *);
393 void do_perfevents(char *, char *);
393394
394395 static struct {
395396 char *tag;
437438 { "swoutcritsec", do_swoutcritsec, 0, },
438439 { "almostcrit", do_almostcrit, 0, },
439440 { "atopsarflags", do_atopsarflags, 0, },
441 { "perfevents", do_perfevents, 0, },
440442 { "pacctdir", do_pacctdir, 1, },
441443 };
442444
695697 ** effective user-id to real user-id
696698 */
697699 if (! droprootprivs() )
698 cleanstop(42);
700 mcleanstop(42, "failed to drop root privs\n");
699701
700702 /*
701703 ** start the engine now .....
907909
908910 do
909911 {
910 curtlen = counttasks();
912 curtlen = counttasks(); // worst-case value
911913 curtpres = realloc(curtpres,
912914 curtlen * sizeof(struct tstat));
913915
914 ptrverify(curtpres, "Malloc failed for %d tstats\n",
916 ptrverify(curtpres, "Malloc failed for %lu tstats\n",
915917 curtlen);
916918
917919 memset(curtpres, 0, curtlen * sizeof(struct tstat));
11631165 if (tagname[0] == '#')
11641166 continue;
11651167
1166 fprintf(stderr,
1168 mcleanstop(1,
11671169 "%s: syntax error line "
11681170 "%d (no value specified)\n",
11691171 path, line);
11701172
1171 cleanstop(1);
11721173 break; /* not reached */
11731174
11741175 default:
11781179 if (tagvalue[0] != '#')
11791180 break;
11801181
1181 fprintf(stderr,
1182 mcleanstop(1,
11821183 "%s: syntax error line "
11831184 "%d (no value specified)\n",
11841185 path, line);
1185
1186 cleanstop(1);
11871186 }
11881187
11891188 /*
+0
-2
atop.cronsystemd less more
0 # daily restart of atop at midnight
1 0 0 * * * root systemctl restart atop
0 LOGOPTS="-R"
1 LOGINTERVAL=600
2 LOGGENERATIONS=28
3 LOGPATH=/var/log/atop
163163 int contcompar(const void *, const void *);
164164
165165 count_t subcount(count_t, count_t);
166 void rawread(void);
166 int rawread(void);
167167 char rawwrite (time_t, int,
168168 struct devtstat *, struct sstat *,
169169 int, unsigned int, char);
174174 char *getstrvers(void);
175175 unsigned short getnumvers(void);
176176 void ptrverify(const void *, const char *, ...);
177 void mcleanstop(int, const char *, ...);
177178 void cleanstop(int);
178179 void prusage(char *);
179180
22 Documentation=man:atop(1)
33
44 [Service]
5 Type=simple
6 ExecStart=/usr/share/atop/atop.daily
5 Environment=LOGOPTS="-R"
6 Environment=LOGINTERVAL=600
7 Environment=LOGGENERATIONS=28
8 Environment=LOGPATH=/var/log/atop
9 EnvironmentFile=/etc/default/atop
10 ExecStartPre=/bin/sh -c 'test -n "$LOGINTERVAL" -a "$LOGINTERVAL" -eq "$LOGINTERVAL"'
11 ExecStartPre=/bin/sh -c 'test -n "$LOGGENERATIONS" -a "$LOGGENERATIONS" -eq "$LOGGENERATIONS"'
12 ExecStart=/bin/sh -c 'exec /usr/bin/atop ${LOGOPTS} -w "${LOGPATH}/atop_$(date +%%Y%%m%%d)" ${LOGINTERVAL}'
13 ExecStartPost=/usr/bin/find "${LOGPATH}" -name "atop_*" -mtime +${LOGGENERATIONS} -exec rm -v {} \;
714 KillSignal=SIGUSR2
8 #ExecStopPost=/usr/bin/sleep 3
915
1016 [Install]
1117 WantedBy=multi-user.target
6666 #include "prev/photosyst_24.h"
6767 #include "prev/photoproc_24.h"
6868
69 #include "prev/photosyst_25.h"
70 #include "prev/photoproc_25.h"
71
6972
7073 ///////////////////////////////////////////////////////////////
7174 // Conversion functions
233236 struct sstat_22 sstat_22;
234237 struct sstat_23 sstat_23;
235238 struct sstat_24 sstat_24;
239 struct sstat_25 sstat_25;
236240 struct sstat sstat;
237241
238242 struct tstat_20 tstat_20;
240244 struct tstat_22 tstat_22;
241245 struct tstat_23 tstat_23;
242246 struct tstat_24 tstat_24;
247 struct tstat_25 tstat_25;
243248 struct tstat tstat;
244249
245250 struct convertall {
417422 STROFFSET(&tstat_24.net, &tstat_24), justcopy},
418423 {sizeof(struct gpu_24),
419424 STROFFSET(&tstat_24.gpu, &tstat_24), justcopy},
425 },
426
427 {SETVERSION(2,5), // 2.4 --> 2.5
428 sizeof(struct sstat_25), &sstat_25,
429 sizeof(struct tstat_25), NULL,
430
431 {sizeof(struct cpustat_25), &sstat_25.cpu, justcopy},
432 {sizeof(struct memstat_25), &sstat_25.mem, justcopy},
433 {sizeof(struct netstat_25), &sstat_25.net, justcopy},
434 {sizeof(struct intfstat_25), &sstat_25.intf, justcopy},
435 {sizeof(struct dskstat_25), &sstat_25.dsk, justcopy},
436 {sizeof(struct nfsstat_25), &sstat_25.nfs, justcopy},
437 {sizeof(struct contstat_25), &sstat_25.cfs, justcopy},
438 {sizeof(struct wwwstat_25), &sstat_25.www, justcopy},
439 {sizeof(struct pressure_25), &sstat_25.psi, justcopy},
440 {sizeof(struct gpustat_25), &sstat_25.gpu, justcopy},
441 {sizeof(struct ifbstat_25), &sstat_25.ifb, justcopy},
442
443 {sizeof(struct gen_25),
444 STROFFSET(&tstat_25.gen, &tstat_25), justcopy},
445 {sizeof(struct cpu_25),
446 STROFFSET(&tstat_25.cpu, &tstat_25), justcopy},
447 {sizeof(struct dsk_25),
448 STROFFSET(&tstat_25.dsk, &tstat_25), justcopy},
449 {sizeof(struct mem_25),
450 STROFFSET(&tstat_25.mem, &tstat_25), justcopy},
451 {sizeof(struct net_25),
452 STROFFSET(&tstat_25.net, &tstat_25), justcopy},
453 {sizeof(struct gpu_25),
454 STROFFSET(&tstat_25.gpu, &tstat_25), justcopy},
420455 },
421456 };
422457
499534 static void writesamp(int, struct rawrecord *, void *, int, void *,
500535 int, int);
501536
537 static void copy_file(int, int);
502538 static void convert_samples(int, int, struct rawheader *, int, int);
503539 static void do_sconvert(struct sconvstruct *, struct sconvstruct *);
504540 static void do_tconvert(void *, void *,
520556 // verify the command line arguments:
521557 // optional flags and mandatory input and output filename
522558 //
523 if (argc < 3)
559 if (argc < 2)
524560 prusage(argv[0]);
525561
526562 while ((c = getopt(argc, argv, "?t:")) != EOF)
566602 }
567603 }
568604
569 if (optind < argc-2)
605 if (optind >= argc)
570606 prusage(argv[0]);
571607
572608 infile = argv[optind++];
573 outfile = argv[optind++];
574
575 if (strcmp(infile, outfile) == 0)
576 {
577 fprintf(stderr,
578 "input file and output file should not be identical!\n");
579 exit(12);
580 }
581609
582610 // determine target version (default: latest version)
583611 //
632660 exit(11);
633661 }
634662
635 if (versionix >= targetix)
636 {
637 fprintf(stderr,
638 "This version is already up-to-date!\n");
639 exit(0);
663 if (versionix > targetix)
664 {
665 fprintf(stderr, "Downgrading of version is not supported!\n");
666 exit(11);
640667 }
641668
642669 if (irh.sstatlen != convs[versionix].sstatlen ||
652679 exit(11);
653680 }
654681
682 // handle the output file
683 //
684 if (optind >= argc)
685 exit(0);
686
687 outfile = argv[optind++];
688
689 if (strcmp(infile, outfile) == 0)
690 {
691 fprintf(stderr,
692 "input file and output file should not be identical!\n");
693 exit(12);
694 }
695
655696 // open the output file
656697 //
657698 if ( (ofd = openout(outfile)) == -1)
673714 printf("Version of %s: %d.%d\n", outfile,
674715 (orh.aversion >> 8) & 0x7f, orh.aversion & 0xff);
675716
676 // copy and convert every sample
677 //
678 convert_samples(ifd, ofd, &irh, versionix, targetix);
717 // copy and convert every sample, unless the version of the
718 // input file is identical to the target version (then just copy)
719 //
720 if (versionix < targetix)
721 convert_samples(ifd, ofd, &irh, versionix, targetix);
722 else
723 copy_file(ifd, ofd);
724
725 close(ifd);
726 close(ofd);
679727
680728 return 0;
681729 }
823871 }
824872 }
825873
874
875 //
876 // Function to copy input file transparently to output file
877 //
878 static void
879 copy_file(int ifd, int ofd)
880 {
881 unsigned char buf[64*1024];
882 int nr, nw;
883
884 (void) lseek(ifd, 0, SEEK_SET);
885 (void) lseek(ofd, 0, SEEK_SET);
886
887 while ( (nr = read(ifd, buf, sizeof buf)) > 0)
888 {
889 if ( (nw = write(ofd, buf, nr)) < nr)
890 {
891 if (nw == -1)
892 {
893 perror("write output file");
894 exit(42);
895 }
896 else
897 {
898 fprintf(stderr,
899 "Output file saturated\n");
900 exit(42);
901 }
902 }
903 }
904
905 if (nr == -1)
906 {
907 perror("read input file");
908 exit(42);
909 }
910 else
911 {
912 printf("Raw file copied (version already up-to-date)\n");
913 }
914 }
915
826916 //
827917 // Function that opens an existing raw file and
828918 // verifies the magic number
9101000 prusage(char *name)
9111001 {
9121002 fprintf(stderr,
913 "Usage: %s [-t version] rawinput rawoutput\n", name);
1003 "Usage: %s [-t version] rawinput [rawoutput]\n", name);
9141004 fprintf(stderr,
915 "\t\t-t version target version (default: %d.%d) for output\n",
1005 "\t-t version target version (default: %d.%d) for output\n",
9161006 (convs[numconvs-1].version >> 8) & 0x7f,
9171007 convs[numconvs-1].version & 0x7f);
9181008
180180 self.stats.procstats[pid].memcum += proc.usedGpuMemory//1024
181181 self.stats.procstats[pid].sample += 1
182182
183 if self.stats.tasksupport & ACCOUNT:
183 if self.stats.tasksupport & ACCOUNT:
184184 try:
185185 stats = pynvml.nvmlDeviceGetAccountingStats(self.gpuhandle, pid)
186186
317317 prinow = i;
318318 daylim = 0;
319319 begintime = saved_begintime;
320 rawread();
320
321 if (!rawread()) // reading from named pipe
322 break; // can only be done once
323
321324 printf("\n");
322325 }
323326 }
383386 ** effective user-id to real user-id
384387 */
385388 if (! droprootprivs() )
386 cleanstop(42);
389 mcleanstop(42, "failed to drop root privs\n");
387390
388391 /*
389392 ** start live reporting
933933 initifprop(); /* refresh interface info */
934934
935935 if (! droprootprivs()) /* drop setuid-root privs */
936 cleanstop(42);
936 mcleanstop(42, "failed to drop root privs\n");
937937
938938 for (i=0; cur->intf.intf[i].name[0]; i++)
939939 {
0 .TH ATOP 1 "January 2019" "Linux"
0 .TH ATOP 1 "November 2019" "Linux"
11 .SH NAME
22 .B atop
33 - Advanced System & Process Monitor
685685 .TP 5
686686 .B T
687687 When viewing the contents of a raw file, this key can be used to show the
688 previous sample from the file.
688 previous sample from the file (except when reading raw data from a named pipe).
689689 .PP
690690 .TP 5
691691 .B b
692692 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).
693 to a certain timestamp within the file either forward or backward
694 (except when reading raw data from a named pipe).
694695 .PP
695696 .TP 5
696697 .B r
698699 boot again.
699700
700701 When viewing the contents of a raw file, this key can be used to rewind
701 to the beginning of the file again.
702 to the beginning of the file again
703 (except when reading raw data from a named pipe).
702704 .PP
703705 .TP 5
704706 .B U
924926 (end time) followed by a time argument of the form HH:MM,
925927 a certain time period within the raw file can be selected.
926928 .PP
927 When
929 Every day at midnight
928930 .B atop
929 is installed, the script
930 .B atop.daily
931 is stored in the
932 .I /usr/share/atop
933 directory.
934 This scripts takes care that
935 .B atop
936 is activated every day at midnight to write compressed binary data to the file
931 is restarted to write compressed binary data to the file
937932 .BI /var/log/atop/atop_ YYYYMMDD
938933 with an interval of 10 minutes by default. The
939934 .B -R
940935 flag is passed by default to gather information about the proportional
941936 set size of every process.
942937 .br
943 Furthermore the script removes all raw files which are by default
944 older than 28 days.
945 .br
946 The mentioned default values can be overruled by creating the file
938 Furthermore all raw files are removed that are older than 28 days
939 (by default).
940 .br
941 The mentioned default values can be overruled in the file
947942 .B /etc/default/atop
948943 that might contain other values for
949944 .B LOGOPTS
951946 .B -R
952947 flag),
953948 .B LOGINTERVAL
954 (in seconds, by default 600), and
949 (in seconds, by default 600),
955950 .B LOGGENERATIONS
956 (in days, by default 28).
957 .PP
958 The
959 .B atop.daily
960 script is activated via the
961 .B cron
962 daemon using the file
963 .I /etc/cron.d/atop
964 with the contents
965 .br
966 .B \ \ \ \ \ \ \ \ 0 0 * * * root /usr/share/atop/atop.daily
967 .PP
968 When the package
969 .B psacct
970 is installed, the process accounting is automatically restarted via the
971 .B logrotate
972 mechanism. The file
973 .B /etc/logrotate.d/psaccs_atop
974 takes care that
975 .B atop
976 is finished just before the rotation of the process accounting file
977 and the file
978 .B /etc/logrotate.d/psaccu_atop
979 takes care that
980 .B atop
981 is restarted again after the rotation.
982 When the package
983 .B psacct
984 is not installed, these logrotate-files have no effect.
951 (in days, by default 28), and
952 .B LOGPATH
953 (directory in which logfiles are stored).
985954 .PP
986955 Unfortunately, it is not always possible to keep the format of the raw files
987956 compatible in newer versions of
11141083 .I average
11151084 instructions per cycle and number of cycles is shown in the CPU line
11161085 for all CPUs.
1086 .br
1087 Beware that reading the cycle counter in virtual machines (guests) might
1088 introduce performance delays. Therefore this metric is by default disabled
1089 in virtual machines. However, with the keyword 'perfevents' in the atoprc file
1090 this metric can be explicitly set to 'enable' or 'disable'
1091 (see separate man-page of atoprc).
11171092 .br
11181093 See also: http://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html
11191094
23812356 Configuration file to overrule the settings of
23822357 .I atop
23832358 that runs in the background to create the daily logfile.
2384 This file is not created or overwritten when
2385 .I atop
2386 is installed, so it has to be created manually to override
2387 the default settings.
2359 This file is created when
2360 .I atop
2361 is installed.
23882362 The default settings are:
23892363 .TP 8
23902364 \
24002374 Raw file, where
24012375 .I YYYYMMDD
24022376 are digits representing the current date.
2403 This name is used by the script
2404 .B atop.daily
2405 as default name for the output file, and by
2377 This name is used by
2378 .B atop
2379 running in the background as default name for the output file, and by
24062380 .B atop
24072381 as default name for the input file when using the
24082382 .B -r
0 .TH ATOPACCTD 8 "June 2018" "Linux"
0 .TH ATOPACCTD 8 "November 2019" "Linux"
11 .SH NAME
22 .B atopacctd
33 - process accounting daemon
0 .TH ATOPCONVERT 1 "January 2019" "Linux"
0 .TH ATOPCONVERT 1 "November 2019" "Linux"
11 .SH NAME
22 .B atopconvert
33 - convert raw log file to newer version
66 .B atopconvert
77 [\-t
88 .I version
9 ] rawinput rawoutput
9 ] rawinput [rawoutput]
1010 .P
1111 .SH DESCRIPTION
1212 The program
1313 .I atopconvert
1414 can be used to convert the layout of a raw log file to a newer version.
15 The only mandatory arguments are the name of the raw input file to be converted
16 and the name of the raw output file. The program
15 The only mandatory argument is the name of the raw input file. When no
16 output file is specified on the command line,
1717 .I atopconvert
18 verifies the version of the input file and converts it (by default) to
19 the format used by the newest version of
18 only shows the version of the input file.
19 When the name of an output file is specified, the input file will
20 be converted to the output file, or just copied when the input file
21 already has the required version.
22
23 The program
24 .I atopconvert
25 converts the input file (by default) to the format used by the
26 newest version of
2027 .I atop
2128 and writes to the output file. With the
2229 .B -t
3138 or can even be extended by that
3239 .I atop
3340 version.
34 .PP
41 .SH NOTES
3542 The raw input file should be at least of version 2.0!
43
44 Files can only be upgraded to higher version, but not downgraded.
3645 .SH SEE ALSO
3746 .B atop(1),
3847 .B atopsar(1)
0 .TH ATOPGPUD 8 "January 2019" "Linux"
0 .TH ATOPGPUD 8 "November 2019" "Linux"
11 .SH NAME
22 .B atopgpud
33 - GPU statistics daemon
117117 while the subsequent three bytes indicate the length (big endian order) of the
118118 response string that follows.
119119 .br
120 In the reponse strings the character '@' introduces system level information
120 In the response strings the character '@' introduces system level information
121121 of one specific GPU and the character '#' introduces process level information
122122 related to that GPU.
123123 .br
0 .TH ATOPRC 5 "January 2019" "Linux"
0 .TH ATOPRC 5 "November 2019" "Linux"
11 .SH NAME
22 .B atoprc
33 - atop/atopsar related rcfile
191191 can be defined here. The flags that are allowed
192192 are 'S', 'x', 'C', 'M', 'H', 'a', 'A' and the flags to select
193193 one or more specific reports.
194 .PP
195 .TP 4
196 .B perfevents
197 Defines whether or not the CPU cycle counter should be retrieved
198 by
199 .B atop
200 via the 'perf' counters. The values 'auto' (default), 'enable'
201 or 'disable' can be specified. In case of 'auto', the CPU cycle
202 counter will not be retrieved on virtual machines due to the
203 overhead of reading this counter in a guest.
194204 .PP
195205 .TP 4
196206 .B pacctdir
0 .TH ATOPSAR 1 "January 2019" "Linux"
0 .TH ATOPSAR 1 "November 2019" "Linux"
11 .SH NAME
22 .B atopsar
33 - Advanced System Activity Report (atop related)
209209 kill(nahp->mypid, SIGHUP);
210210
211211 if (! droprootprivs())
212 cleanstop(42);
212 mcleanstop(42, "failed to drop root privs\n");
213213
214214 (void) munmap(nahp, sizeof *nahp);
215215 (void) close(netexitfd);
247247 memset(&tp->net, 0, sizeof tp->net);
248248
249249 if (! droprootprivs())
250 cleanstop(42);
250 mcleanstop(42, "failed to drop root privs\n");
251251
252252 if (errno == ENOPROTOOPT || errno == EPERM)
253253 {
261261 }
262262
263263 if (! droprootprivs())
264 cleanstop(42);
264 mcleanstop(42, "failed to drop root privs\n");
265265
266266 /*
267267 ** statistics available: fill counters
301301 */
302302 if (getsockopt(netsock, SOL_IP, NETATOP_FORCE_GC, NULL, &socklen)!=0) {
303303 if (! droprootprivs())
304 cleanstop(42);
304 mcleanstop(42, "failed to drop root privs\n");
305305
306306 if (errno == ENOPROTOOPT || errno == EPERM)
307307 {
320320 */
321321 if (getsockopt(netsock, SOL_IP, NETATOP_EMPTY_EXIT, 0, &socklen) !=0) {
322322 if (! droprootprivs())
323 cleanstop(42);
323 mcleanstop(42, "failed to drop root privs\n");
324324
325325 if (errno == ENOPROTOOPT || errno == EPERM)
326326 {
334334 }
335335
336336 if (! droprootprivs())
337 cleanstop(42);
337 mcleanstop(42, "failed to drop root privs\n");
338338
339339 /*
340340 ** verify how many exited processes are available to be read
199199 }
200200
201201 if (! droprootprivs())
202 cleanstop(42);
202 mcleanstop(42, "failed to drop root privs\n");
203203
204204 /*
205205 ** find epoch time of boot moment
218218 netatop_probe();
219219
220220 if (! droprootprivs())
221 cleanstop(42);
221 mcleanstop(42, "failed to drop root privs\n");
222222
223223 /*
224224 ** read all subdirectory-names below the /proc directory
225225 */
226226 if ( getcwd(origdir, sizeof origdir) == NULL)
227 {
228 perror("save current dir");
229 cleanstop(53);
230 }
227 mcleanstop(53, "failed to save current dir\n");
231228
232229 if ( chdir("/proc") == -1)
233 {
234 perror("change to /proc");
235 cleanstop(54);
236 }
230 mcleanstop(54, "failed to change to /proc\n");
237231
238232 dirp = opendir(".");
239233
310304 {
311305 dirtask = opendir(".");
312306
307 /*
308 ** due to race condition, opendir() might
309 ** have failed (leave task and process-level
310 ** directories)
311 */
312 if( dirtask == NULL )
313 {
314 if(chdir("../..") == -1);
315 continue;
316 }
317
313318 while ((tent=readdir(dirtask)) && tval<maxtask)
314319 {
315320 struct tstat *curthr = tasklist+tval;
340345 }
341346
342347 strcpy(curthr->gen.container,
343 curtask->gen.container);
348 curtask->gen.container);
344349
345350 switch (curthr->gen.state)
346351 {
359364
360365 // read network stats from netatop
361366 netatop_gettask(curthr->gen.pid, 't',
362 curthr);
367 curthr);
363368
364369 // all stats read now
365370 tval++; /* increment thread-level */
377382 closedir(dirp);
378383
379384 if ( chdir(origdir) == -1)
380 {
381 perror(origdir);
382 cleanstop(55);
383 }
385 mcleanstop(55, "cannot change to %s\n", origdir);
384386
385387 if (dockstat)
386388 supportflags |= DOCKSTAT;
412414 if ( fgets(linebuf, sizeof(linebuf), fp) != NULL)
413415 {
414416 if ( sscanf(linebuf, "%*f %*f %*f %*d/%lu", &nr) < 1)
415 cleanstop(53);
417 mcleanstop(53, "wrong /proc/loadavg\n");
416418 }
417419 else
418 cleanstop(53);
420 mcleanstop(53, "unreadable /proc/loadavg\n");
419421
420422 fclose(fp);
421423 }
422424 else
423 cleanstop(53);
425 mcleanstop(53, "can not open /proc/loadavg\n");
424426
425427
426428 /*
427429 ** add total number of processes
428430 */
429431 if ( getcwd(origdir, sizeof origdir) == NULL)
430 cleanstop(53);
432 mcleanstop(53, "cannot determine cwd\n");
431433
432434 if ( chdir("/proc") == -1)
433 cleanstop(53);
435 mcleanstop(53, "cannot change to /proc\n");
434436
435437 dirp = opendir(".");
436438
446448 closedir(dirp);
447449
448450 if ( chdir(origdir) == -1)
449 cleanstop(53);
451 mcleanstop(53, "cannot change to %s\n", origdir);
450452
451453 return nr;
452454 }
716718 }
717719
718720 if (! droprootprivs())
719 cleanstop(42);
721 mcleanstop(42, "failed to drop root privs\n");
720722 }
721723
722724 return 1;
762764
763765
764766 /*
765 ** store the Docker container ID, retrieved from the cpuset
766 ** that could look like this:
767 ** store the Docker container ID, retrieved from the 'cpuset'
768 ** that might look like this:
767769 ** /system.slice/docker-af78216c2a230f1aa5dce56cbf[SNAP].scope (e.g. CentOS)
768770 ** /docker/af78216c2a230f1aa5dce56cbf[SNAP] (e.g. openSUSE and Ubuntu))
771 **
772 ** docker created by k8s might look like this:
773 ** /kubepods/burstable/pod07dbb922-[SNAP]/223dc5e15b[SNAP]
774 **
775 ** In general:
776 ** - search for last '/' (basename)
777 ** - check if '/' followed by 'docker-': then skip 'docker-'
778 ** - take 12 positions for the container ID
779 **
780 ** Return value:
781 ** 0 - no container
782 ** 1 - container
769783 */
770 #define CIDPREFIX "docker"
771784 #define CIDSIZE 12
785 #define SHA256SIZE 64
786 #define DOCKPREFIX "docker-"
772787
773788 static int
774789 proccont(struct tstat *curtask)
775790 {
776 FILE *fp;
777 char line[80];
791 FILE *fp;
792 char line[256];
778793
779794 if ( (fp = fopen("cpuset", "r")) != NULL)
780795 {
782797
783798 if ( fgets(line, sizeof line, fp) )
784799 {
785 // default string (so if not used) is "/"
786 if (line[1] && (p = strstr(line, CIDPREFIX)) )
800 fclose(fp);
801
802 // fast check for processes not using cpuset
803 // i.e. anyhow not container
804 if (memcmp(line, "/\n", 3) == 0)
805 return 0;
806
807 // possibly container: find basename in path and
808 // verify that its minimum length is the size of SHA256
809 if ( (p = strrchr(line, '/')) != NULL &&
810 strlen(p) >= SHA256SIZE)
787811 {
788 memcpy(curtask->gen.container,
789 p + sizeof CIDPREFIX, CIDSIZE);
790
791 fclose(fp);
812 p++;
813
814 if (memcmp(p, DOCKPREFIX,
815 sizeof(DOCKPREFIX)-1) == 0)
816 p += sizeof(DOCKPREFIX)-1;
817
818 memcpy(curtask->gen.container, p, CIDSIZE);
792819 return 1;
793820 }
794821 }
795
796 fclose(fp);
822 else
823 {
824 fclose(fp);
825 }
797826 }
798827
799828 return 0;
802831
803832 /*
804833 ** open file "smaps" and obtain required info
834 ** since Linux-4.14, kernel supports "smaps_rollup" which has better
835 ** performence. check "smaps_rollup" in first call
836 ** if kernel supports "smaps_rollup", use "smaps_rollup" instead
805837 */
806838 static void
807839 procsmaps(struct tstat *curtask)
809841 FILE *fp;
810842 char line[4096];
811843 count_t pssval;
812
813
844 static int procsmaps_firstcall = 1;
845 static char *smapsfile = "smaps";
846
847 if (procsmaps_firstcall)
848 {
849 regainrootprivs();
850 if ( (fp = fopen("/proc/1/smaps_rollup", "r")) )
851 {
852 smapsfile = "smaps_rollup";
853 fclose(fp);
854 }
855
856 procsmaps_firstcall = 0;
857 }
814858 /*
815859 ** open the file (always succeeds, even if no root privs)
816860 */
817861 regainrootprivs();
818862
819 if ( (fp = fopen("smaps", "r")) )
863 if ( (fp = fopen(smapsfile, "r")) )
820864 {
821865 curtask->mem.pmem = 0;
822866
844888 }
845889
846890 if (! droprootprivs())
847 cleanstop(42);
891 mcleanstop(42, "failed to drop root privs\n");
848892 }
193193 #define MDDTYPE 2
194194 #define LVMTYPE 3
195195
196 /* hypervisor enum */
197 enum {
198 HYPER_NONE = 0,
199 HYPER_XEN,
200 HYPER_KVM,
201 HYPER_MSHV,
202 HYPER_VMWARE,
203 HYPER_IBM,
204 HYPER_VSERVER,
205 HYPER_UML,
206 HYPER_INNOTEK,
207 HYPER_HITACHI,
208 HYPER_PARALLELS,
209 HYPER_VBOX,
210 HYPER_OS400,
211 HYPER_PHYP,
212 HYPER_SPAR,
213 HYPER_WSL,
214 };
215
196216 #ifndef NOPERFEVENT
217 enum {
218 PERF_EVENTS_AUTO = 0,
219 PERF_EVENTS_ENABLE,
220 PERF_EVENTS_DISABLE,
221 };
222
223 static int perfevents = PERF_EVENTS_AUTO;
197224 static void getperfevents(struct cpustat *);
198225 #endif
199226
201228
202229 static int isdisk(unsigned int, unsigned int,
203230 char *, struct perdsk *, int);
231
232 static int run_in_guest(void);
204233
205234 static struct ipv6_stats ipv6_tmp;
206235 static struct icmpv6_stats icmpv6_tmp;
299328 memset(si, 0, sizeof(struct sstat));
300329
301330 if ( getcwd(origdir, sizeof origdir) == NULL)
302 {
303 perror("save current dir");
304 cleanstop(53);
305 }
331 mcleanstop(54, "failed to save current dir\n");
306332
307333 if ( chdir("/proc") == -1)
308 {
309 perror("change to /proc");
310 cleanstop(54);
311 }
312
334 mcleanstop(54, "failed to change to /proc\n");
313335
314336 /*
315337 ** gather various general statistics from the file /proc/stat and
12911313 }
12921314
12931315 if (! droprootprivs())
1294 cleanstop(42);
1316 mcleanstop(42, "failed to drop root privs\n");
12951317
12961318 /*
12971319 ** pressure statistics in /proc/pressure (>= 4.20)
13781400 }
13791401
13801402 if ( chdir("..") == -1)
1381 {
1382 perror("return to /proc");
1383 cleanstop(54);
1384 }
1403 mcleanstop(54, "failed to return to /proc\n");
13851404 }
13861405 else
13871406 {
14941513 ** return to original directory
14951514 */
14961515 if ( chdir(origdir) == -1)
1497 {
1498 perror(origdir);
1499 cleanstop(55);
1500 }
1516 mcleanstop(55, "failed to change to %s\n", origdir);
15011517
15021518 #ifndef NOPERFEVENT
15031519 /*
20552071 ** instructions and cycles per CPU
20562072 */
20572073 #ifndef NOPERFEVENT
2074
2075 void
2076 do_perfevents(char *tagname, char *tagvalue)
2077 {
2078 if (!strcmp("enable", tagvalue))
2079 perfevents = PERF_EVENTS_ENABLE;
2080 else if (!strcmp("disable", tagvalue))
2081 perfevents = PERF_EVENTS_DISABLE;
2082 else
2083 {
2084 if (run_in_guest())
2085 perfevents = PERF_EVENTS_DISABLE;
2086 else
2087 perfevents = PERF_EVENTS_ENABLE;
2088 }
2089 }
2090
2091 static int
2092 enable_perfevents()
2093 {
2094 if (perfevents == PERF_EVENTS_AUTO)
2095 do_perfevents("perfevents", "auto");
2096
2097 return perfevents == PERF_EVENTS_ENABLE;
2098 }
2099
20582100 long
20592101 perf_event_open(struct perf_event_attr *hwevent, pid_t pid,
20602102 int cpu, int groupfd, unsigned long flags)
20682110 static int firstcall = 1, cpualloced, *fdi, *fdc;
20692111 int i;
20702112
2113 if (!enable_perfevents())
2114 return;
2115
20712116 /*
20722117 ** once initialize perf event counter retrieval
20732118 */
21132158 }
21142159
21152160 if (! droprootprivs())
2116 cleanstop(42);
2161 mcleanstop(42, "failed to drop root privs\n");
2162
21172163
21182164 /*
21192165 ** all failed (probably no kernel support)?
21562202 cs->all.cycle += cs->cpu[i].cycle;
21572203 }
21582204 }
2205 }
2206 #else
2207 void
2208 do_perfevents(char *tagname, char *tagvalue)
2209 {
2210 wcleanstop(1, "atop built with NOPERFEVENT, cannot use perfevents\n");
21592211 }
21602212 #endif
21612213
22742326 return 1;
22752327 }
22762328 #endif
2329
2330
2331 #if defined(__x86_64__) || defined(__i386__)
2332 #define HYPERVISOR_INFO_LEAF 0x40000000
2333
2334 static inline void
2335 x86_cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx,
2336 unsigned int *ecx, unsigned int *edx)
2337 {
2338 __asm__(
2339 #if defined(__PIC__) && defined(__i386__)
2340 "xchg %%ebx, %%esi;"
2341 "cpuid;"
2342 "xchg %%esi, %%ebx;"
2343 : "=S" (*ebx),
2344 #else
2345 "cpuid;"
2346 : "=b" (*ebx),
2347 #endif
2348 "=a" (*eax),
2349 "=c" (*ecx),
2350 "=d" (*edx)
2351 : "1" (op), "c"(0));
2352 }
2353
2354 static int
2355 get_hypervisor(void)
2356 {
2357 unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0, hyper = HYPER_NONE;
2358 char hyper_vendor_id[13];
2359
2360 memset(hyper_vendor_id, 0, sizeof(hyper_vendor_id));
2361
2362 x86_cpuid(HYPERVISOR_INFO_LEAF, &eax, &ebx, &ecx, &edx);
2363 memcpy(hyper_vendor_id + 0, &ebx, 4);
2364 memcpy(hyper_vendor_id + 4, &ecx, 4);
2365 memcpy(hyper_vendor_id + 8, &edx, 4);
2366 hyper_vendor_id[12] = '\0';
2367
2368 if (!hyper_vendor_id[0])
2369 return hyper;
2370
2371 if (!strncmp("XenVMMXenVMM", hyper_vendor_id, 12))
2372 hyper = HYPER_XEN;
2373 else if (!strncmp("KVMKVMKVM", hyper_vendor_id, 9))
2374 hyper = HYPER_KVM;
2375 else if (!strncmp("Microsoft Hv", hyper_vendor_id, 12))
2376 hyper = HYPER_MSHV;
2377 else if (!strncmp("VMwareVMware", hyper_vendor_id, 12))
2378 hyper = HYPER_VMWARE;
2379 else if (!strncmp("UnisysSpar64", hyper_vendor_id, 12))
2380 hyper = HYPER_SPAR;
2381
2382 return hyper;
2383 }
2384 #else /* ! (__x86_64__ || __i386__) */
2385 static int
2386 get_hypervisor(void)
2387 {
2388 return HYPER_NONE;
2389 }
2390 #endif
2391
2392 static int
2393 run_in_guest(void)
2394 {
2395 return get_hypervisor() != HYPER_NONE;
2396 }
0 /*
1 ** structure containing only relevant process-info extracted
2 ** from kernel's process-administration
3 */
4 struct tstat_25 {
5 /* GENERAL TASK INFO */
6 struct gen_25 {
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_25 {
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 count_t cfuture[4]; /* reserved for future use */
50 } cpu;
51
52 /* DISK STATISTICS */
53 struct dsk_25 {
54 count_t rio; /* number of read requests */
55 count_t rsz; /* cumulative # sectors read */
56 count_t wio; /* number of write requests */
57 count_t wsz; /* cumulative # sectors written */
58 count_t cwsz; /* cumulative # written sectors */
59 /* being cancelled */
60 count_t cfuture[4]; /* reserved for future use */
61 } dsk;
62
63 /* MEMORY STATISTICS */
64 struct mem_25 {
65 count_t minflt; /* number of page-reclaims */
66 count_t majflt; /* number of page-faults */
67 count_t vexec; /* virtmem execfile (Kb) */
68 count_t vmem; /* virtual memory (Kb) */
69 count_t rmem; /* resident memory (Kb) */
70 count_t pmem; /* resident memory (Kb) */
71 count_t vgrow; /* virtual growth (Kb) */
72 count_t rgrow; /* resident growth (Kb) */
73 count_t vdata; /* virtmem data (Kb) */
74 count_t vstack; /* virtmem stack (Kb) */
75 count_t vlibs; /* virtmem libexec (Kb) */
76 count_t vswap; /* swap space used (Kb) */
77 count_t cfuture[4]; /* reserved for future use */
78 } mem;
79
80 /* NETWORK STATISTICS */
81 struct net_25 {
82 count_t tcpsnd; /* number of TCP-packets sent */
83 count_t tcpssz; /* cumulative size packets sent */
84 count_t tcprcv; /* number of TCP-packets recved */
85 count_t tcprsz; /* cumulative size packets rcvd */
86 count_t udpsnd; /* number of UDP-packets sent */
87 count_t udpssz; /* cumulative size packets sent */
88 count_t udprcv; /* number of UDP-packets recved */
89 count_t udprsz; /* cumulative size packets sent */
90 count_t avail1; /* */
91 count_t avail2; /* */
92 count_t cfuture[4]; /* reserved for future use */
93 } net;
94
95 struct gpu_25 {
96 char state; // A - active, E - Exit, '\0' - no use
97 char cfuture[3]; //
98 short nrgpus; // number of GPUs for this process
99 int32_t gpulist; // bitlist with GPU numbers
100
101 int gpubusy; // gpu busy perc process lifetime -1 = n/a
102 int membusy; // memory busy perc process lifetime -1 = n/a
103 count_t timems; // milliseconds accounting -1 = n/a
104 // value 0 for active process,
105 // value > 0 after termination
106
107 count_t memnow; // current memory consumption in KiB
108 count_t memcum; // cumulative memory consumption in KiB
109 count_t sample; // number of samples
110 } gpu;
111 };
0 #define MAXCPU_25 2048
1 #define MAXDSK_25 1024
2 #define MAXLVM_25 2048
3 #define MAXMDD_25 256
4 #define MAXINTF_25 128
5 #define MAXCONTAINER_25 128
6 #define MAXNFSMOUNT_25 64
7 #define MAXIBPORT_25 32
8 #define MAXGPU_25 32
9
10 /************************************************************************/
11 struct memstat_25 {
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 cfuture[8]; // reserved for future use
43 };
44
45 /************************************************************************/
46
47 struct netstat_25 {
48 struct ipv4_stats ipv4;
49 struct icmpv4_stats icmpv4;
50 struct udpv4_stats udpv4;
51
52 struct ipv6_stats ipv6;
53 struct icmpv6_stats icmpv6;
54 struct udpv6_stats udpv6;
55
56 struct tcp_stats tcp;
57 };
58
59 /************************************************************************/
60
61 struct freqcnt_25 {
62 count_t maxfreq;/* frequency in MHz */
63 count_t cnt; /* number of clock ticks times state */
64 count_t ticks; /* number of total clock ticks */
65 /* if zero, cnt is actul freq */
66 };
67
68 struct percpu_25 {
69 int cpunr;
70 count_t stime; /* system time in clock ticks */
71 count_t utime; /* user time in clock ticks */
72 count_t ntime; /* nice time in clock ticks */
73 count_t itime; /* idle time in clock ticks */
74 count_t wtime; /* iowait time in clock ticks */
75 count_t Itime; /* irq time in clock ticks */
76 count_t Stime; /* softirq time in clock ticks */
77 count_t steal; /* steal time in clock ticks */
78 count_t guest; /* guest time in clock ticks */
79 struct freqcnt_25 freqcnt;/* frequency scaling info */
80 count_t instr; /* CPU instructions */
81 count_t cycle; /* CPU cycles */
82 count_t cfuture[2]; /* reserved for future use */
83 };
84
85 struct cpustat_25 {
86 count_t nrcpu; /* number of cpu's */
87 count_t devint; /* number of device interrupts */
88 count_t csw; /* number of context switches */
89 count_t nprocs; /* number of processes started */
90 float lavg1; /* load average last minute */
91 float lavg5; /* load average last 5 minutes */
92 float lavg15; /* load average last 15 minutes */
93 count_t cfuture[4]; /* reserved for future use */
94
95 struct percpu_25 all;
96 struct percpu_25 cpu[MAXCPU_25];
97 };
98
99 /************************************************************************/
100
101 struct perdsk_25 {
102 char name[MAXDKNAM]; /* empty string for last */
103 count_t nread; /* number of read transfers */
104 count_t nrsect; /* number of sectors read */
105 count_t nwrite; /* number of write transfers */
106 count_t nwsect; /* number of sectors written */
107 count_t io_ms; /* number of millisecs spent for I/O */
108 count_t avque; /* average queue length */
109 count_t cfuture[4]; /* reserved for future use */
110 };
111
112 struct dskstat_25 {
113 int ndsk; /* number of physical disks */
114 int nmdd; /* number of md volumes */
115 int nlvm; /* number of logical volumes */
116 struct perdsk_25 dsk[MAXDSK_25];
117 struct perdsk_25 mdd[MAXMDD_25];
118 struct perdsk_25 lvm[MAXLVM_25];
119 };
120
121 /************************************************************************/
122
123 struct perintf_25 {
124 char name[16]; /* empty string for last */
125
126 count_t rbyte; /* number of read bytes */
127 count_t rpack; /* number of read packets */
128 count_t rerrs; /* receive errors */
129 count_t rdrop; /* receive drops */
130 count_t rfifo; /* receive fifo */
131 count_t rframe; /* receive framing errors */
132 count_t rcompr; /* receive compressed */
133 count_t rmultic;/* receive multicast */
134 count_t rfuture[4]; /* reserved for future use */
135
136 count_t sbyte; /* number of written bytes */
137 count_t spack; /* number of written packets */
138 count_t serrs; /* transmit errors */
139 count_t sdrop; /* transmit drops */
140 count_t sfifo; /* transmit fifo */
141 count_t scollis;/* collisions */
142 count_t scarrier;/* transmit carrier */
143 count_t scompr; /* transmit compressed */
144 count_t sfuture[4]; /* reserved for future use */
145
146 char type; /* interface type ('e'/'w'/'?') */
147 long speed; /* interface speed in megabits/second */
148 long speedp; /* previous interface speed */
149 char duplex; /* full duplex (boolean) */
150 count_t cfuture[4]; /* reserved for future use */
151 };
152
153 struct intfstat_25 {
154 int nrintf;
155 struct perintf_25 intf[MAXINTF_25];
156 };
157
158 /************************************************************************/
159
160 struct pernfsmount_25 {
161 char mountdev[128]; /* mountdevice */
162 count_t age; /* number of seconds mounted */
163
164 count_t bytesread; /* via normal reads */
165 count_t byteswrite; /* via normal writes */
166 count_t bytesdread; /* via direct reads */
167 count_t bytesdwrite; /* via direct writes */
168 count_t bytestotread; /* via reads */
169 count_t bytestotwrite; /* via writes */
170 count_t pagesmread; /* via mmap reads */
171 count_t pagesmwrite; /* via mmap writes */
172
173 count_t future[8];
174 };
175
176 struct nfsstat_25 {
177 struct {
178 count_t netcnt;
179 count_t netudpcnt;
180 count_t nettcpcnt;
181 count_t nettcpcon;
182
183 count_t rpccnt;
184 count_t rpcbadfmt;
185 count_t rpcbadaut;
186 count_t rpcbadcln;
187
188 count_t rpcread;
189 count_t rpcwrite;
190
191 count_t rchits; /* repcache hits */
192 count_t rcmiss; /* repcache misses */
193 count_t rcnoca; /* uncached requests */
194
195 count_t nrbytes; /* read bytes */
196 count_t nwbytes; /* written bytes */
197
198 count_t future[8];
199 } server;
200
201 struct {
202 count_t rpccnt;
203 count_t rpcretrans;
204 count_t rpcautrefresh;
205
206 count_t rpcread;
207 count_t rpcwrite;
208
209 count_t future[8];
210 } client;
211
212 struct {
213 int nrmounts;
214 struct pernfsmount_25 nfsmnt[MAXNFSMOUNT_25];
215 } nfsmounts;
216 };
217
218 /************************************************************************/
219 struct psi_25 {
220 float avg10; // average pressure last 10 seconds
221 float avg60; // average pressure last 60 seconds
222 float avg300; // average pressure last 300 seconds
223 count_t total; // total number of milliseconds
224 };
225
226 struct pressure_25 {
227 char present; /* pressure stats supported? */
228 char future[3];
229 struct psi_25 cpusome; /* pressure stall info 'some' */
230 struct psi_25 memsome; /* pressure stall info 'some' */
231 struct psi_25 memfull; /* pressure stall info 'full' */
232 struct psi_25 iosome; /* pressure stall info 'some' */
233 struct psi_25 iofull; /* pressure stall info 'full' */
234 };
235
236 /************************************************************************/
237
238 struct percontainer_25 {
239 unsigned long ctid; /* container id */
240 unsigned long numproc; /* number of processes */
241
242 count_t system; /* */
243 count_t user; /* */
244 count_t nice; /* */
245 count_t uptime; /* */
246
247 count_t physpages; /* */
248 };
249
250 struct contstat_25 {
251 int nrcontainer;
252 struct percontainer_25 cont[MAXCONTAINER_25];
253 };
254
255 /************************************************************************/
256 /*
257 ** experimental stuff for access to local HTTP daemons
258 */
259 struct wwwstat_25 {
260 count_t accesses; /* total number of HTTP-requests */
261 count_t totkbytes; /* total kbytes transfer for HTTP-req */
262 count_t uptime; /* number of seconds since startup */
263 int bworkers; /* number of busy httpd-daemons */
264 int iworkers; /* number of idle httpd-daemons */
265 };
266
267 /************************************************************************/
268
269 struct pergpu_25 {
270 char taskstats; // GPU task statistics supported?
271 unsigned char nrprocs; // number of processes using GPU
272 char type[MAXGPUTYPE+1]; // GPU type
273 char busid[MAXGPUBUS+1]; // GPU bus identification
274 int gpunr; // GPU number
275 int gpupercnow; // processor percentage last second
276 // -1 if not supported
277 int mempercnow; // memory percentage last second
278 // -1 if not supported
279 count_t memtotnow; // total memory in KiB
280 count_t memusenow; // used memory in KiB
281 count_t samples; // number of samples
282 count_t gpuperccum; // cumulative processor busy percentage
283 // -1 if not supported
284 count_t memperccum; // cumulative memory percentage
285 // -1 if not supported
286 count_t memusecum; // cumulative used memory in KiB
287 };
288
289 struct gpustat_25 {
290 int nrgpus; // total number of GPUs
291 struct pergpu_25 gpu[MAXGPU_25];
292 };
293
294 /************************************************************************/
295
296 struct perifb_25 {
297 char ibname[MAXIBNAME]; // InfiniBand controller
298 short portnr; // InfiniBand controller port
299
300 short lanes; // number of lanes (traffic factor)
301 count_t rate; // transfer rate in megabits/sec
302 count_t rcvb; // bytes received
303 count_t sndb; // bytes transmitted
304 count_t rcvp; // packets received
305 count_t sndp; // packets transmitted
306 };
307
308 struct ifbstat_25 {
309 int nrports; // total number of IB ports
310 struct perifb_25 ifb[MAXIBPORT_25];
311 };
312 /************************************************************************/
313
314 struct sstat_25 {
315 struct cpustat_25 cpu;
316 struct memstat_25 mem;
317 struct netstat_25 net;
318 struct intfstat_25 intf;
319 struct dskstat_25 dsk;
320 struct nfsstat_25 nfs;
321 struct contstat_25 cfs;
322 struct pressure_25 psi;
323 struct gpustat_25 gpu;
324 struct ifbstat_25 ifb;
325
326 struct wwwstat_25 www;
327 };
4343 #include <sys/time.h>
4444 #include <sys/resource.h>
4545 #include <unistd.h>
46 #include <sys/uio.h>
4647
4748 #include "atop.h"
4849 #include "showgeneric.h"
117118 static int getrawsstat(int, struct sstat *, int);
118119 static int getrawtstat(int, struct tstat *, int, int);
119120 static int rawwopen(void);
121 static int readchunk(int, void *, int);
120122 static int lookslikedatetome(char *);
121123 static void testcompval(int, char *);
122124 static void try_other_version(int, int);
139141 unsigned long scomplen = sizeof scompbuf;
140142 unsigned long pcomplen = sizeof(struct tstat) *
141143 devtstat->ntaskall;
144 struct iovec iov[3];
142145
143146 /*
144147 ** first call:
213216 if (supportflags & GPUSTAT)
214217 rr.flags |= RRGPUSTAT;
215218
216 if ( write(rawfd, &rr, sizeof rr) == -1)
219 /*
220 ** use 1-writev to make record operation atomic
221 ** to avoid write uncompleted record data.
222 */
223 iov[0].iov_base = &rr;
224 iov[0].iov_len = sizeof (rr);
225
226 iov[1].iov_base = scompbuf;
227 iov[1].iov_len = scomplen;
228
229 iov[2].iov_base = pcompbuf;
230 iov[2].iov_len = pcomplen;
231
232 if ( writev(rawfd, iov, 3) == -1)
217233 {
218234 fprintf(stderr, "%s - ", rawname);
219 perror("write raw record");
220235 if ( ftruncate(rawfd, filestat.st_size) == -1)
221 cleanstop(8);
222 cleanstop(7);
223 }
224
225 /*
226 ** write compressed system status structure to file
227 */
228 if ( write(rawfd, scompbuf, scomplen) == -1)
229 {
230 fprintf(stderr, "%s - ", rawname);
231 perror("write raw status record");
232 if ( ftruncate(rawfd, filestat.st_size) == -1)
233 cleanstop(8);
234 cleanstop(7);
235 }
236
237 /*
238 ** write compressed list of process status structures to file
239 */
240 if ( write(rawfd, pcompbuf, pcomplen) == -1)
241 {
242 fprintf(stderr, "%s - ", rawname);
243 perror("write raw process record");
244 if ( ftruncate(rawfd, filestat.st_size) == -1)
245 cleanstop(8);
246 cleanstop(7);
236 mcleanstop(8,
237 "failed to write raw/status/process record to %s\n",
238 rawname);
239
240 mcleanstop(7,
241 "failed to write raw/status/process record to %s\n",
242 rawname);
247243 }
248244
249245 free(pcompbuf);
280276 ** read and verify header record
281277 */
282278 if ( read(fd, &rh, sizeof rh) < sizeof rh)
283 {
284 fprintf(stderr, "%s - cannot read header\n", rawname);
285 cleanstop(7);
286 }
279 mcleanstop(7, "%s - cannot read header\n", rawname);
287280
288281 if (rh.magic != MYMAGIC)
289 {
290 fprintf(stderr,
291 "file %s exists but does not contain raw "
282 mcleanstop(7, "file %s exists but does not contain raw "
292283 "atop output (wrong magic number)\n", rawname);
293
294 cleanstop(7);
295 }
296284
297285 if ( rh.sstatlen != sizeof(struct sstat) ||
298286 rh.tstatlen != sizeof(struct tstat) ||
365353 */
366354 #define OFFCHUNK 256
367355
368 void
356 int
369357 rawread(void)
370358 {
371 int i, j, rawfd, len;
359 int i, j, rawfd, len, isregular = 1;
372360 char *py;
373361 struct rawheader rh;
374362 struct rawrecord rr;
381369 ** variables to maintain the offsets of the raw records
382370 ** to be able to see previous samples again
383371 */
384 off_t *offlist;
372 off_t *offlist = NULL;
385373 unsigned int offsize = 0;
386374 unsigned int offcur = 0;
387375 char lastcmd = 'X', flags;
463451 }
464452
465453 /*
454 ** make sure the file is a regular file (seekable) or
455 ** a pipe (not seekable)
456 */
457 if (stat(rawname, &filestat) == -1)
458 {
459 fprintf(stderr, "%s - ", rawname);
460 perror("stat raw file");
461 cleanstop(7);
462 }
463
464 if (!S_ISREG(filestat.st_mode) && !S_ISFIFO(filestat.st_mode))
465 {
466 fprintf(stderr, "raw file must be a regular file or pipe\n");
467 cleanstop(7);
468 }
469
470 isregular = S_ISREG(filestat.st_mode);
471
472 /*
466473 ** open raw file
467474 */
468475 if ( (rawfd = open(rawname, O_RDONLY)) == -1)
509516 /*
510517 ** read the raw header and verify the magic
511518 */
512 if ( read(rawfd, &rh, sizeof rh) < sizeof rh)
519 if ( readchunk(rawfd, &rh, sizeof rh) < sizeof rh)
513520 {
514521 fprintf(stderr, "can not read raw file header\n");
515522 cleanstop(7);
581588 /*
582589 ** allocate a list for backtracking of rawrecord-offsets
583590 */
584 offlist = malloc(sizeof(off_t) * OFFCHUNK);
585
586 ptrverify(offlist, "Malloc failed for backtrack list\n");
587
588 offsize = OFFCHUNK;
589
590 *offlist = lseek(rawfd, 0, SEEK_CUR);
591 offcur = 1;
591 if (isregular)
592 {
593 offlist = malloc(sizeof(off_t) * OFFCHUNK);
594
595 ptrverify(offlist, "Malloc failed for backtrack list\n");
596
597 offsize = OFFCHUNK;
598
599 *offlist = lseek(rawfd, 0, SEEK_CUR);
600 offcur = 1;
601 }
592602
593603 /*
594604 ** read a raw record header until end-of-file
606616 ** store the offset of the raw record in the offset list
607617 ** in case of offset list overflow, extend the list
608618 */
609 *(offlist+offcur) = lseek(rawfd, 0, SEEK_CUR) -
619 if (isregular)
620 {
621 *(offlist+offcur) = lseek(rawfd, 0, SEEK_CUR) -
610622 rh.rawreclen;
611623
612 if ( ++offcur >= offsize )
613 {
614 offlist = realloc(offlist,
624 if ( ++offcur >= offsize )
625 {
626 offlist = realloc(offlist,
615627 (offsize+OFFCHUNK)*sizeof(off_t));
616628
617 ptrverify(offlist,
629 ptrverify(offlist,
618630 "Realloc failed for backtrack list\n");
619631
620 offsize+= OFFCHUNK;
632 offsize+= OFFCHUNK;
633 }
621634 }
622635
623636 /*
627640 if ( (begintime && begintime > secsinday) )
628641 {
629642 lastcmd = 1;
630 lseek(rawfd, rr.scomplen+rr.pcomplen, SEEK_CUR);
643
644 if (isregular)
645 {
646 lseek(rawfd, rr.scomplen+rr.pcomplen,
647 SEEK_CUR);
648 }
649 else // named pipe not seekable
650 {
651 char *dummybuf =
652 malloc(rr.scomplen+rr.pcomplen);
653
654 ptrverify(dummybuf,
655 "Malloc rawlog pipe buffer failed\n");
656
657 readchunk(rawfd, dummybuf,
658 rr.scomplen+rr.pcomplen);
659
660 free(dummybuf);
661 }
662
631663 continue;
632664 }
633665
635667
636668 if ( (endtime && endtime < secsinday) )
637669 {
638 free(offlist);
670 if (isregular)
671 free(offlist);
672
639673 close(rawfd);
640 return;
674 return isregular;
641675 }
642676
643677 /*
747781
748782 nrgpus = sstat.gpu.nrgpus;
749783
750 (void) fstat(rawfd, &filestat);
751
752 if ( filestat.st_size -
753 lseek(rawfd, (off_t)0, SEEK_CUR) <= rh.rawreclen)
754 flags |= RRLAST;
755
756 lastcmd = (vis.show_samp)(rr.curtime, rr.interval,
784 if (isregular)
785 {
786 (void) fstat(rawfd, &filestat);
787
788 if ( filestat.st_size -
789 lseek(rawfd, (off_t)0, SEEK_CUR)
790 <= rh.rawreclen)
791 flags |= RRLAST;
792 }
793
794 do
795 {
796 lastcmd = (vis.show_samp)(rr.curtime,
797 rr.interval,
757798 &devtstat, &sstat,
758799 rr.nexit, rr.noverflow, flags);
800 }
801 while (!isregular &&
802 (lastcmd == MSAMPPREV ||
803 lastcmd == MSAMPBRANCH ||
804 lastcmd == MRESET ));
759805
760806 free(devtstat.taskall);
761807 free(devtstat.procall);
762808 free(devtstat.procactive);
763
809
764810 switch (lastcmd)
765811 {
766 case MSAMPPREV:
812 case MSAMPPREV:
767813 if (offcur >= 2)
768814 offcur-= 2;
769815 else
770816 offcur = 0;
771
817
772818 lseek(rawfd, *(offlist+offcur), SEEK_SET);
773819 break;
774820
775 case MRESET:
821 case MRESET:
776822 lseek(rawfd, *offlist, SEEK_SET);
777823 offcur = 1;
778824 break;
780826 case MSAMPBRANCH:
781827 if (begintime && begintime < secsinday)
782828 {
783 lseek(rawfd, *offlist, SEEK_SET);
829 lseek(rawfd, *offlist,
830 SEEK_SET);
784831 offcur = 1;
785832 }
786833 }
788835
789836 begintime = 0; // allow earlier times from now on
790837
791 if (offcur >= 1)
792 offcur--;
793
794 lseek(rawfd, *(offlist+offcur), SEEK_SET);
795 }
796
797 free(offlist);
838 if (isregular)
839 {
840 if (offcur >= 1)
841 offcur--;
842
843 lseek(rawfd, *(offlist+offcur), SEEK_SET);
844 }
845 else
846 {
847 lastcmd = 'q';
848 }
849 }
850
851 if (isregular)
852 free(offlist);
798853
799854 close(rawfd);
855
856 return isregular;
800857 }
801858
802859 /*
805862 static int
806863 getrawrec(int rawfd, struct rawrecord *prr, int rrlen)
807864 {
808 return read(rawfd, prr, rrlen);
865 return readchunk(rawfd, prr, rrlen);
809866 }
810867
811868 /*
818875 unsigned long uncomplen = sizeof(struct sstat);
819876 int rv;
820877
821 if ( (compbuf = malloc(complen)) == NULL)
878 compbuf = malloc(complen);
822879
823880 ptrverify(compbuf, "Malloc failed for reading compressed sysstats\n");
824881
825 if ( read(rawfd, compbuf, complen) < complen)
882 if ( readchunk(rawfd, compbuf, complen) < complen)
826883 {
827884 free(compbuf);
828885 return 0;
851908
852909 ptrverify(compbuf, "Malloc failed for reading compressed procstats\n");
853910
854 if ( read(rawfd, compbuf, complen) < complen)
911 if ( readchunk(rawfd, compbuf, complen) < complen)
855912 {
856913 free(compbuf);
857914 return 0;
901958 break;
902959
903960 case Z_MEM_ERROR:
904 fprintf(stderr, "atop/atopsar - "
961 mcleanstop(7, "atop/atopsar - "
905962 "%s: failed due to lack of memory\n", func);
906 cleanstop(7);
907963
908964 case Z_BUF_ERROR:
909 fprintf(stderr, "atop/atopsar - "
965 mcleanstop(7, "atop/atopsar - "
910966 "%s: failed due to lack of room in buffer\n", func);
911 cleanstop(7);
912967
913968 case Z_DATA_ERROR:
914 fprintf(stderr, "atop/atopsar - "
969 mcleanstop(7, "atop/atopsar - "
915970 "%s: failed due to corrupted/incomplete data\n", func);
916 cleanstop(7);
917971
918972 default:
919 fprintf(stderr, "atop/atopsar - "
973 mcleanstop(7, "atop/atopsar - "
920974 "%s: unexpected error %d\n", func, rv);
921 cleanstop(7);
922 }
975 }
976 }
977
978 static int
979 readchunk(int fd, void *buf, int len)
980 {
981 char *p = buf;
982 int n;
983
984 while (len > 0)
985 {
986 switch (n = read(fd, p, len))
987 {
988 case 0:
989 return 0; // EOF
990 case -1:
991 perror("read raw file");
992 cleanstop(9);
993 default:
994 len -= n;
995 p += n;
996 }
997 }
998
999 return (char *)p - (char *)buf;
9231000 }
9241001
9251002 /*
710710 *p=0;
711711 }
712712 else
713 {
714 fprintf(stderr,
715 "atoprc - %s: no name:prio pair for "
716 "`%s'\n", name, linename);
717 cleanstop(1);
718 }
713 mcleanstop(1, "atoprc - %s: no name:prio pair for "
714 "`%s'\n", name, linename);
719715
720716 /* now get number */
721717 p++;
777773 }
778774 }
779775 if (permissables[j]==0)
780 {
781 fprintf(stderr,
782 "atoprc - own system line: item %s invalid in %s line!\n",
783 name, linename);
784 cleanstop(1);
785 }
776 mcleanstop(1,
777 "atoprc - own system line: item %s invalid in %s line\n",
778 name, linename);
786779 }
787780 ar[i].f=0;
788781 ar[i].prio=0;
866859 }
867860 if (allprocpdefs[j]==0)
868861 {
869 fprintf(stderr,
862 mcleanstop(1,
870863 "atoprc - ownprocline: item %s invalid!\n",
871864 name);
872 cleanstop(1);
873865 }
874866 }
875867 ar[i].f=0;
15931593 {
15941594 struct sstat *sstat=p;
15951595 static char buf[16];
1596 psiformat(&(sstat->psi.iosome), "if", buf, sizeof buf);
1596 psiformat(&(sstat->psi.iofull), "if", buf, sizeof buf);
15971597 return buf;
15981598 }
15991599 sys_printdef syspdef_PSIIOF = {"PSIIOF", sysprt_PSIIOF};
571571
572572 va_start(args, errormsg);
573573 vfprintf(stderr, errormsg, args);
574 va_end (args);
574 va_end(args);
575575
576576 exit(13);
577577 }
578578 }
579579
580580 /*
581 ** signal catcher for cleanup before exit
581 ** cleanup, give error message and exit
582582 */
583583 void
584 cleanstop(int exitcode)
585 {
584 mcleanstop(int exitcode, const char *errormsg, ...)
585 {
586 va_list args;
587
586588 acctswoff();
587589 netatop_signoff();
588590 (vis.show_end)();
591
592 va_start(args, errormsg);
593 vfprintf(stderr, errormsg, args);
594 va_end(args);
595
596 exit(exitcode);
597 }
598
599 /*
600 ** cleanup, give error message and exit
601 */
602 void
603 cleanstop(int exitcode)
604 {
605 acctswoff();
606 netatop_signoff();
607 (vis.show_end)();
608
589609 exit(exitcode);
590610 }
591611
0 #define ATOPDATE "2019/01/12 20:37:57"
0 #define ATOPDATE "2019/11/02 11:36:41"
0 #define ATOPVERS "2.4.0"
0 #define ATOPVERS "2.5.0"