Commit | Line | Data |
---|---|---|
4ed24f86 JD |
1 | #!/usr/bin/env python3 |
2 | # | |
3 | # The MIT License (MIT) | |
4 | # | |
a3fa57c0 | 5 | # Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com> |
d87a5b68 | 6 | # 2015 - Antoine Busque <abusque@efficios.com> |
4ed24f86 JD |
7 | # |
8 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |
9 | # of this software and associated documentation files (the "Software"), to deal | |
10 | # in the Software without restriction, including without limitation the rights | |
11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
12 | # copies of the Software, and to permit persons to whom the Software is | |
13 | # furnished to do so, subject to the following conditions: | |
14 | # | |
15 | # The above copyright notice and this permission notice shall be included in | |
16 | # all copies or substantial portions of the Software. | |
17 | # | |
18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
24 | # SOFTWARE. | |
25 | ||
c16e0164 JD |
26 | from linuxautomaton import sp, sv, common |
27 | ||
28 | ||
29 | class StatedumpStateProvider(sp.StateProvider): | |
30 | def __init__(self, state): | |
3b1dda96 | 31 | self._state = state |
c16e0164 JD |
32 | cbs = { |
33 | 'lttng_statedump_process_state': | |
34 | self._process_lttng_statedump_process_state, | |
35 | 'lttng_statedump_file_descriptor': | |
3b1dda96 | 36 | self._process_lttng_statedump_file_descriptor |
c16e0164 JD |
37 | } |
38 | self._register_cbs(cbs) | |
39 | ||
40 | def process_event(self, ev): | |
41 | self._process_event_cb(ev) | |
42 | ||
c16e0164 | 43 | def _process_lttng_statedump_process_state(self, event): |
3f52a605 AB |
44 | tid = event['tid'] |
45 | pid = event['pid'] | |
46 | name = event['name'] | |
3b1dda96 | 47 | if tid not in self._state.tids: |
586ee389 AB |
48 | proc = sv.Process() |
49 | proc.tid = tid | |
50 | self._state.tids[tid] = proc | |
c16e0164 | 51 | else: |
586ee389 | 52 | proc = self._state.tids[tid] |
c16e0164 JD |
53 | # Even if the process got created earlier, some info might be |
54 | # missing, add it now. | |
586ee389 AB |
55 | proc.pid = pid |
56 | proc.comm = name | |
c16e0164 JD |
57 | |
58 | if pid != tid: | |
59 | # create the parent | |
3b1dda96 | 60 | if pid not in self._state.tids: |
c16e0164 JD |
61 | parent = sv.Process() |
62 | parent.tid = pid | |
63 | parent.pid = pid | |
64 | parent.comm = name | |
3b1dda96 | 65 | self._state.tids[pid] = parent |
c16e0164 | 66 | else: |
3b1dda96 | 67 | parent = self._state.tids[pid] |
586ee389 | 68 | # If the thread had opened FDs, they need to be assigned |
c16e0164 | 69 | # to the parent. |
586ee389 | 70 | StatedumpStateProvider._assign_fds_to_parent(proc, parent) |
067ef19f AB |
71 | self._state.send_notification_cb('create_parent_proc', |
72 | proc=proc, | |
73 | parent_proc=parent) | |
c16e0164 JD |
74 | |
75 | def _process_lttng_statedump_file_descriptor(self, event): | |
3f52a605 AB |
76 | pid = event['pid'] |
77 | fd = event['fd'] | |
78 | filename = event['filename'] | |
d87a5b68 | 79 | cloexec = event['flags'] & common.O_CLOEXEC == common.O_CLOEXEC |
c16e0164 | 80 | |
3b1dda96 | 81 | if pid not in self._state.tids: |
d87a5b68 AB |
82 | proc = sv.Process() |
83 | proc.pid = pid | |
84 | proc.tid = pid | |
3b1dda96 | 85 | self._state.tids[pid] = proc |
c16e0164 | 86 | else: |
3b1dda96 | 87 | proc = self._state.tids[pid] |
c16e0164 | 88 | |
d87a5b68 | 89 | if fd not in proc.fds: |
586ee389 | 90 | proc.fds[fd] = sv.FD(fd, filename, sv.FDType.unknown, cloexec) |
067ef19f AB |
91 | self._state.send_notification_cb('create_fd', |
92 | fd=fd, | |
64376e90 AB |
93 | parent_proc=proc, |
94 | timestamp=event.timestamp) | |
c16e0164 JD |
95 | else: |
96 | # just fix the filename | |
d87a5b68 | 97 | proc.fds[fd].filename = filename |
44823c31 | 98 | |
586ee389 AB |
99 | @staticmethod |
100 | def _assign_fds_to_parent(proc, parent): | |
101 | if proc.fds: | |
102 | toremove = [] | |
103 | for fd in proc.fds: | |
104 | if fd not in parent.fds: | |
105 | parent.fds[fd] = proc.fds[fd] | |
106 | else: | |
107 | # best effort to fix the filename | |
108 | if not parent.fds[fd].filename: | |
109 | parent.fds[fd].filename = proc.fds[fd].filename | |
110 | toremove.append(fd) | |
111 | for fd in toremove: | |
112 | del proc.fds[fd] |