diff options
author | We-unite <3205135446@qq.com> | 2024-08-09 13:56:37 +0800 |
---|---|---|
committer | We-unite <3205135446@qq.com> | 2024-08-12 14:16:51 +0800 |
commit | 3e49a044d22635157916651f0acb5a062397b34b (patch) | |
tree | 254cd9a2605fa003f4579e7c5510e6e2aea19375 /src/deal.go | |
parent | ea32e017e579f168d87732893335c38d539ac2f1 (diff) | |
download | godo-3e49a044d22635157916651f0acb5a062397b34b.tar.gz godo-3e49a044d22635157916651f0acb5a062397b34b.zip |
Add db structure, fix filePath, start filtering
This commit I made several changes:
- Use structure instead of simple bson.M(interface{}). bson.M has
some shortcomings: 1) It makes the database in chaos and hard to
read, but this's not important; 2) Some entrys may has more or
less content than others, which makes it hard to decode and filt.
So I design new data structure to encode and decode. Hopes that
there's no bugs.
- Fix the way to calculate file path. The original method is to add
all the PATH entries together, that's totally wrong! PATH entry
has several types, as it shows in "objtype". I can't find it in
the kernel src code, so what i know is just "PARENT" means the dir
the file is in, while the filename itself has the path, so we
whould ignore all "PARENT"s. When the src code is found, we should
check it again.
- Fix bugs in updating. The update function of mongodb is set to
required to has a '$' such as 'set'/'push', so when we update a
whole doc, we should use replace but not update function. And,
we should never ignore the error infomation it gives us.
Hope that there's no more bugs for this Big Change.
Now its' time to write filter as well as viewer. Best wishes with
NO BUGS!
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 | } | ||