aboutsummaryrefslogtreecommitdiffstats
path: root/src/deal.go
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2024-08-09 13:56:37 +0800
committerWe-unite <3205135446@qq.com>2024-08-12 14:16:51 +0800
commit3e49a044d22635157916651f0acb5a062397b34b (patch)
tree254cd9a2605fa003f4579e7c5510e6e2aea19375 /src/deal.go
parentea32e017e579f168d87732893335c38d539ac2f1 (diff)
downloadgodo-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.go265
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 @@
1package main
2
3import (
4 "fmt"
5 "os"
6 "syscall"
7
8 "go.mongodb.org/mongo-driver/bson"
9)
10
11const (
12 dbName string = "test"
13 pidColName string = "pids"
14 fdColName string = "fds"
15 fileColName string = "files"
16)
17
18// var mongoMutex sync.Mutex
19var pidCol, fdCol, fileCol mongoClient
20
21var docRes []bson.M
22var err error
23
24func 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
83func 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
105func 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
151func 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
190func 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
210func 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
221func 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
240func 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}