diff options
Diffstat (limited to 'src/deal.go')
-rw-r--r-- | src/deal.go | 265 |
1 files changed, 0 insertions, 265 deletions
diff --git a/src/deal.go b/src/deal.go deleted file mode 100644 index e553174..0000000 --- a/src/deal.go +++ /dev/null | |||
@@ -1,265 +0,0 @@ | |||
1 | package main | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "os" | ||
6 | "syscall" | ||
7 | |||
8 | "go.mongodb.org/mongo-driver/bson" | ||
9 | ) | ||
10 | |||
11 | const ( | ||
12 | dbName string = "test" | ||
13 | pidColName string = "pids" | ||
14 | fdColName string = "fds" | ||
15 | fileColName string = "files" | ||
16 | ) | ||
17 | |||
18 | // var mongoMutex sync.Mutex | ||
19 | var pidCol, fdCol, fileCol mongoClient | ||
20 | |||
21 | var docRes []bson.M | ||
22 | var err error | ||
23 | |||
24 | func deal() { | ||
25 | defer wg.Done() | ||
26 | var cooked Event | ||
27 | var ok bool | ||
28 | |||
29 | if err = pidCol.init(dbName, pidColName); err != nil { | ||
30 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
31 | return | ||
32 | } | ||
33 | err = pidCol.InsertOne(bson.M{ | ||
34 | "ppid": 1, | ||
35 | "pid": containerdPid, | ||
36 | "cwd": "/", | ||
37 | "children": []bson.M{}, | ||
38 | "daemon": true, | ||
39 | }) | ||
40 | if err != nil { | ||
41 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
42 | return | ||
43 | } | ||
44 | |||
45 | if err = fdCol.init(dbName, fdColName); err != nil { | ||
46 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
47 | return | ||
48 | } | ||
49 | if err = fileCol.init(dbName, fileColName); err != nil { | ||
50 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
51 | } | ||
52 | |||
53 | fmt.Printf("Containerd: %d\n", containerdPid) | ||
54 | defer pidCol.Disconnect() | ||
55 | defer fdCol.Disconnect() | ||
56 | defer fileCol.Disconnect() | ||
57 | |||
58 | for { | ||
59 | cooked, ok = <-cookedChan | ||
60 | if !ok { | ||
61 | break | ||
62 | } | ||
63 | |||
64 | switch cooked.tag { | ||
65 | case NEWPID: | ||
66 | go dealNewPid(cooked) | ||
67 | case EXECVE: | ||
68 | go dealExecve(cooked) | ||
69 | case PIDEXIT: | ||
70 | go deletePid(cooked) | ||
71 | case FILEOPEN: | ||
72 | go fileOpen(cooked) | ||
73 | case FILEWRITE: | ||
74 | go fileWrite(cooked) | ||
75 | case FILECLOSE: | ||
76 | go fileClose(cooked) | ||
77 | case PIVOTROOT: | ||
78 | go pivotRoot(cooked) | ||
79 | } | ||
80 | } | ||
81 | } | ||
82 | |||
83 | func deletePid(cooked Event) { | ||
84 | // 先从老爹那里销户 | ||
85 | pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ | ||
86 | "$pull": bson.M{ | ||
87 | "children": cooked.pid, | ||
88 | }, | ||
89 | }) | ||
90 | |||
91 | // 在这套逻辑里,孩子是不需要收容的,因为我们根本就不看ppid来工作 | ||
92 | |||
93 | // 可以去死了 | ||
94 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ | ||
95 | "$set": bson.M{ | ||
96 | "exit_timestamp": cooked.timestamp, | ||
97 | "exit_code": cooked.exit_code, | ||
98 | "exit_signal": cooked.exit_signal, | ||
99 | }, | ||
100 | }) | ||
101 | |||
102 | // 理论上这里需要关闭所有文件描述符,但为了处理效率,留给后续流程 | ||
103 | } | ||
104 | |||
105 | func dealNewPid(cooked Event) { | ||
106 | // 自身是否已经记录 | ||
107 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid}) | ||
108 | if err != nil { | ||
109 | fmt.Fprintf(os.Stderr, "Err finding: %v\n", err) | ||
110 | return | ||
111 | } | ||
112 | |||
113 | if len(docRes) != 0 { | ||
114 | // 进程原本就存在,换言之别的消息先到了 | ||
115 | // 所有先行抵达的消息必须保留execve/children字段 | ||
116 | // 此处不再更新 | ||
117 | // 以防把原有信息更没了 | ||
118 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ | ||
119 | "start_timestamp": cooked.timestamp, | ||
120 | "ppid": cooked.ppid, | ||
121 | "parentTgid": cooked.parentTgid, | ||
122 | "pid": cooked.pid, | ||
123 | "tgid": cooked.tgid, | ||
124 | "cwd": cooked.cwd, | ||
125 | // "execve": []bson.M{}, | ||
126 | "args": cooked.argv, | ||
127 | // "children": []bson.M{}, | ||
128 | }) | ||
129 | } else { | ||
130 | // 这进程本是新修的 | ||
131 | pidCol.InsertOne(bson.M{ | ||
132 | "start_timestamp": cooked.timestamp, | ||
133 | "ppid": cooked.ppid, | ||
134 | "parentTgid": cooked.parentTgid, | ||
135 | "pid": cooked.pid, | ||
136 | "tgid": cooked.tgid, | ||
137 | "cwd": cooked.cwd, | ||
138 | "execve": []bson.M{}, | ||
139 | "args": cooked.argv, | ||
140 | "children": []bson.M{}, | ||
141 | }) | ||
142 | } | ||
143 | |||
144 | pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ | ||
145 | "$push": bson.M{ | ||
146 | "children": cooked.pid, | ||
147 | }, | ||
148 | }) | ||
149 | } | ||
150 | |||
151 | func dealExecve(cooked Event) { | ||
152 | // 父进程在不在?不在扔 | ||
153 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) | ||
154 | if err != nil || len(docRes) != 1 { | ||
155 | return | ||
156 | } | ||
157 | |||
158 | // 首先检查进程是否存在,如不存在则为之创建 | ||
159 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid}) | ||
160 | if err != nil { | ||
161 | return | ||
162 | } | ||
163 | |||
164 | if len(docRes) == 1 { | ||
165 | // 自身已在,直接记录 | ||
166 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ | ||
167 | "$push": bson.M{ | ||
168 | "execve": bson.M{ | ||
169 | "timestamp": cooked.timestamp, | ||
170 | "execArgs": cooked.argv, | ||
171 | }, | ||
172 | }, | ||
173 | }) | ||
174 | } else { | ||
175 | // 先fork抵达,插入 | ||
176 | pidCol.InsertOne(bson.M{ | ||
177 | "ppid": cooked.ppid, | ||
178 | "pid": cooked.pid, | ||
179 | "children": []bson.M{}, | ||
180 | "execve": []bson.M{ | ||
181 | { | ||
182 | "timestamp": cooked.timestamp, | ||
183 | "execArgs": cooked.argv, | ||
184 | }, | ||
185 | }, | ||
186 | }) | ||
187 | } | ||
188 | } | ||
189 | |||
190 | func fileOpen(cooked Event) { | ||
191 | // 权限检查过了,不必再查 | ||
192 | fdCol.InsertOne(bson.M{ | ||
193 | "timestamp": cooked.timestamp, | ||
194 | "fileName": cooked.srcPath, | ||
195 | "pid": cooked.pid, | ||
196 | "fd": cooked.exit_code, | ||
197 | "flags": cooked.syscallParam, | ||
198 | "written": []bson.M{}, | ||
199 | }) | ||
200 | |||
201 | if cooked.syscallParam[1]&syscall.O_TRUNC != 0 { | ||
202 | fdCol.UpdateOne(bson.M{"pid": cooked.pid, "fd": cooked.exit_code}, bson.M{ | ||
203 | "$push": bson.M{ | ||
204 | "written": cooked.timestamp, | ||
205 | }, | ||
206 | }) | ||
207 | } | ||
208 | } | ||
209 | |||
210 | func fileClose(cooked Event) { | ||
211 | res, err := fdCol.FindOneAndDelete(bson.M{"pid": cooked.pid, "fd": cooked.syscallParam[0]}) | ||
212 | if err != nil { | ||
213 | return | ||
214 | } | ||
215 | res["close_timestamp"] = cooked.timestamp | ||
216 | if err := fileCol.InsertOne(res); err != nil { | ||
217 | fmt.Fprintf(os.Stderr, "Err inserting files: %v\n", err) | ||
218 | } | ||
219 | } | ||
220 | |||
221 | func fileWrite(cooked Event) { | ||
222 | res, err := fdCol.Finddoc(bson.M{ | ||
223 | "pid": cooked.pid, | ||
224 | "fd": cooked.syscallParam[0], | ||
225 | "close_timestamp": bson.M{"$exists": false}, | ||
226 | }) | ||
227 | if err != nil { | ||
228 | fmt.Fprintf(os.Stderr, "Err closing fd %d of pid %d: %v\n", cooked.syscallParam[0], cooked.pid, err) | ||
229 | } | ||
230 | if len(res) == 0 { | ||
231 | return | ||
232 | } | ||
233 | fdCol.UpdateOne(bson.M{ | ||
234 | "pid": cooked.pid, | ||
235 | "fd": cooked.syscallParam[0], | ||
236 | "close_timestamp": bson.M{"$exists": false}, | ||
237 | }, bson.M{"$push": bson.M{"written": cooked.timestamp}}) | ||
238 | } | ||
239 | |||
240 | func pivotRoot(cooked Event) { | ||
241 | // docker的根目录信息,记录 | ||
242 | docRes, err := pidCol.Finddoc(bson.M{"pid": cooked.pid}) | ||
243 | if err != nil { | ||
244 | fmt.Fprintf(os.Stderr, "Err finding: %v\n", err) | ||
245 | return | ||
246 | } | ||
247 | |||
248 | if len(docRes) == 0 { | ||
249 | // fork还没到,等一下 | ||
250 | pidCol.InsertOne(bson.M{ | ||
251 | "start_timestamp": cooked.timestamp, | ||
252 | "ppid": cooked.ppid, | ||
253 | "pid": cooked.pid, | ||
254 | "rootfs": "cwd", | ||
255 | }) | ||
256 | } else { | ||
257 | // 读取已有的工作目录 | ||
258 | cwd := docRes[0]["cwd"] | ||
259 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ | ||
260 | "$set": bson.M{ | ||
261 | "rootfs": cwd, | ||
262 | }, | ||
263 | }) | ||
264 | } | ||
265 | } | ||