Commit | Line | Data |
---|---|---|
bd3cd7c5 JD |
1 | import socket |
2 | ||
3 | ||
4 | class StateVariable: | |
5 | pass | |
6 | ||
7 | ||
8 | class Process(): | |
9 | def __init__(self): | |
10 | self.tid = -1 | |
11 | self.pid = -1 | |
12 | self.comm = "" | |
13 | # indexed by fd | |
14 | self.fds = {} | |
15 | # indexed by filename | |
16 | self.closed_fds = {} | |
17 | self.current_syscall = {} | |
18 | self.init_counts() | |
19 | ||
20 | def init_counts(self): | |
21 | self.cpu_ns = 0 | |
22 | self.migrate_count = 0 | |
23 | # network read/write | |
24 | self.net_read = 0 | |
25 | self.net_write = 0 | |
26 | # disk read/write (might be cached) | |
27 | self.disk_read = 0 | |
28 | self.disk_write = 0 | |
29 | # actual block access read/write | |
30 | self.block_read = 0 | |
31 | self.block_write = 0 | |
32 | # unclassified read/write (FD passing and statedump) | |
33 | self.unk_read = 0 | |
34 | self.unk_write = 0 | |
35 | # total I/O read/write | |
36 | self.read = 0 | |
37 | self.write = 0 | |
38 | # last TS where the process was scheduled in | |
39 | self.last_sched = 0 | |
40 | # the process scheduled before this one | |
41 | self.prev_tid = -1 | |
42 | # indexed by syscall_name | |
43 | self.syscalls = {} | |
44 | self.perf = {} | |
45 | self.dirty = 0 | |
46 | self.allocated_pages = 0 | |
47 | self.freed_pages = 0 | |
48 | self.total_syscalls = 0 | |
49 | # array of IORequest objects for freq analysis later (block and | |
50 | # syscalls with no FD like sys_sync) | |
51 | self.iorequests = [] | |
52 | ||
53 | ||
54 | class CPU(): | |
55 | def __init__(self): | |
56 | self.cpu_id = -1 | |
57 | self.cpu_ns = 0 | |
58 | self.current_tid = -1 | |
59 | self.start_task_ns = 0 | |
60 | self.perf = {} | |
61 | self.wakeup_queue = [] | |
62 | ||
63 | ||
64 | class Syscall(): | |
65 | def __init__(self): | |
66 | self.name = "" | |
67 | self.count = 0 | |
68 | ||
69 | ||
70 | class Disk(): | |
71 | def __init__(self): | |
72 | self.name = "" | |
73 | self.prettyname = "" | |
74 | self.init_counts() | |
75 | ||
76 | def init_counts(self): | |
77 | self.nr_sector = 0 | |
78 | self.nr_requests = 0 | |
79 | self.completed_requests = 0 | |
80 | self.request_time = 0 | |
81 | self.pending_requests = {} | |
82 | self.rq_list = [] | |
83 | self.max = None | |
84 | self.min = None | |
85 | self.total = None | |
86 | self.count = None | |
87 | self.rq_values = None | |
88 | self.stdev = None | |
89 | ||
90 | ||
91 | class Iface(): | |
92 | def __init__(self): | |
93 | self.name = "" | |
94 | self.init_counts() | |
95 | ||
96 | def init_counts(self): | |
97 | self.recv_bytes = 0 | |
98 | self.recv_packets = 0 | |
99 | self.send_bytes = 0 | |
100 | self.send_packets = 0 | |
101 | ||
102 | ||
103 | class FDType(): | |
104 | unknown = 0 | |
105 | disk = 1 | |
106 | net = 2 | |
107 | # not 100% sure they are network FDs (assumed when net_dev_xmit is | |
108 | # called during a write syscall and the type in unknown). | |
109 | maybe_net = 3 | |
110 | ||
111 | ||
112 | class FD(): | |
113 | def __init__(self): | |
114 | self.filename = "" | |
115 | self.fd = -1 | |
116 | # address family | |
117 | self.family = socket.AF_UNSPEC | |
118 | self.fdtype = FDType.unknown | |
119 | # if FD was inherited, parent PID | |
120 | self.parent = -1 | |
121 | self.init_counts() | |
122 | ||
123 | def init_counts(self): | |
124 | # network read/write | |
125 | self.net_read = 0 | |
126 | self.net_write = 0 | |
127 | # disk read/write (might be cached) | |
128 | self.disk_read = 0 | |
129 | self.disk_write = 0 | |
130 | # unclassified read/write (FD passing and statedump) | |
131 | self.unk_read = 0 | |
132 | self.unk_write = 0 | |
133 | # total read/write | |
134 | self.read = 0 | |
135 | self.write = 0 | |
136 | self.open = 0 | |
137 | self.close = 0 | |
138 | self.cloexec = 0 | |
139 | # array of syscall IORequest objects for freq analysis later | |
140 | self.iorequests = [] | |
141 | ||
142 | ||
143 | class IRQ(): | |
144 | HARD_IRQ = 1 | |
145 | SOFT_IRQ = 2 | |
146 | # from include/linux/interrupt.h | |
147 | soft_names = {0: "HI_SOFTIRQ", | |
148 | 1: "TIMER_SOFTIRQ", | |
149 | 2: "NET_TX_SOFTIRQ", | |
150 | 3: "NET_RX_SOFTIRQ", | |
151 | 4: "BLOCK_SOFTIRQ", | |
152 | 5: "BLOCK_IOPOLL_SOFTIRQ", | |
153 | 6: "TASKLET_SOFTIRQ", | |
154 | 7: "SCHED_SOFTIRQ", | |
155 | 8: "HRTIMER_SOFTIRQ", | |
156 | 9: "RCU_SOFTIRQ"} | |
157 | ||
158 | def __init__(self): | |
159 | self.nr = -1 | |
160 | self.irqclass = 0 | |
161 | self.start_ts = -1 | |
162 | self.stop_ts = -1 | |
163 | self.raise_ts = -1 | |
164 | self.cpu_id = -1 | |
165 | ||
166 | ||
167 | class IORequest(): | |
168 | # I/O "type" | |
169 | IO_SYSCALL = 1 | |
170 | IO_BLOCK = 2 | |
171 | IO_NET = 3 | |
172 | # I/O operations | |
173 | OP_OPEN = 1 | |
174 | OP_READ = 2 | |
175 | OP_WRITE = 3 | |
176 | OP_CLOSE = 4 | |
177 | OP_SYNC = 5 | |
178 | ||
179 | def __init__(self): | |
180 | # IORequest.IO_* | |
181 | self.iotype = None | |
182 | # bytes for syscalls and net, sectors for block | |
183 | # FIXME: syscalls handling vectors (vector size missing) | |
184 | self.size = None | |
185 | # for syscalls and block: delay between issue and completion | |
186 | # of the request | |
187 | self.duration = None | |
188 | # IORequest.OP_* | |
189 | self.operation = None | |
190 | # syscall name | |
191 | self.name = None | |
192 | # begin syscall timestamp | |
193 | self.begin = None | |
194 | # end syscall timestamp | |
195 | self.end = None | |
196 | # current process | |
197 | self.proc = None | |
198 | # current FD (for syscalls) | |
199 | self.fd = None | |
200 | # buffers dirtied during the operation | |
201 | self.dirty = 0 | |
202 | # pages allocated during the operation | |
203 | self.page_alloc = 0 | |
204 | # pages freed during the operation | |
205 | self.page_free = 0 | |
206 | # pages written on disk during the operation | |
207 | self.page_written = 0 | |
208 | # kswapd was forced to wakeup during the operation | |
209 | self.woke_kswapd = False | |
210 | # estimated pages flushed during a sync operation | |
211 | self.page_cleared = 0 | |
212 | ||
213 | ||
214 | class Syscalls_stats(): | |
215 | def __init__(self): | |
216 | self.read_max = 0 | |
217 | self.read_min = None | |
218 | self.read_total = 0 | |
219 | self.read_count = 0 | |
220 | self.read_rq = [] | |
221 | self.all_read = [] | |
222 | ||
223 | self.write_max = 0 | |
224 | self.write_min = None | |
225 | self.write_total = 0 | |
226 | self.write_count = 0 | |
227 | self.write_rq = [] | |
228 | self.all_write = [] | |
229 | ||
230 | self.open_max = 0 | |
231 | self.open_min = None | |
232 | self.open_total = 0 | |
233 | self.open_count = 0 | |
234 | self.open_rq = [] | |
235 | self.all_open = [] | |
236 | ||
237 | self.sync_max = 0 | |
238 | self.sync_min = None | |
239 | self.sync_total = 0 | |
240 | self.sync_count = 0 | |
241 | self.sync_rq = [] | |
242 | self.all_sync = [] | |
243 | ||
244 | ||
245 | class SyscallConsts(): | |
246 | # TODO: decouple socket/family logic from this class | |
247 | INET_FAMILIES = [socket.AF_INET, socket.AF_INET6] | |
248 | DISK_FAMILIES = [socket.AF_UNIX] | |
249 | # list nof syscalls that open a FD on disk (in the exit_syscall event) | |
250 | DISK_OPEN_SYSCALLS = ["sys_open", "syscall_entry_open", | |
251 | "sys_openat", "syscall_entry_openat"] | |
252 | # list of syscalls that open a FD on the network | |
253 | # (in the exit_syscall event) | |
254 | NET_OPEN_SYSCALLS = ["sys_accept", "syscall_entry_accept", | |
255 | "sys_socket", "syscall_entry_socket"] | |
256 | # list of syscalls that can duplicate a FD | |
257 | DUP_OPEN_SYSCALLS = ["sys_fcntl", "syscall_entry_fcntl", | |
258 | "sys_dup2", "syscall_entry_dup2"] | |
259 | SYNC_SYSCALLS = ["sys_sync", "syscall_entry_sync", | |
260 | "sys_sync_file_range", "syscall_entry_sync_file_range", | |
261 | "sys_fsync", "syscall_entry_fsync", | |
262 | "sys_fdatasync", "syscall_entry_fdatasync"] | |
263 | # merge the 3 open lists | |
264 | OPEN_SYSCALLS = DISK_OPEN_SYSCALLS + NET_OPEN_SYSCALLS + DUP_OPEN_SYSCALLS | |
265 | # list of syscalls that close a FD (in the "fd =" field) | |
266 | CLOSE_SYSCALLS = ["sys_close", "syscall_entry_close"] | |
267 | # list of syscall that read on a FD, value in the exit_syscall following | |
268 | READ_SYSCALLS = ["sys_read", "syscall_entry_read", | |
269 | "sys_recvmsg", "syscall_entry_recvmsg", | |
270 | "sys_recvfrom", "syscall_entry_recvfrom", | |
271 | "sys_splice", "syscall_entry_splice", | |
272 | "sys_readv", "syscall_entry_readv", | |
273 | "sys_sendfile64", "syscall_entry_sendfile64"] | |
274 | # list of syscall that write on a FD, value in the exit_syscall following | |
275 | WRITE_SYSCALLS = ["sys_write", "syscall_entry_write", | |
276 | "sys_sendmsg", "syscall_entry_sendmsg", | |
277 | "sys_sendto", "syscall_entry_sendto", | |
278 | "sys_writev", "syscall_entry_writev"] | |
279 | # generic names assigned to special FDs, don't try to match these in the | |
280 | # closed_fds dict | |
281 | GENERIC_NAMES = ["unknown", "socket"] | |
282 | ||
283 | def __init__(): | |
284 | pass |