summaryrefslogtreecommitdiffstats
path: root/src/deal.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/deal.go')
-rw-r--r--src/deal.go173
1 files changed, 102 insertions, 71 deletions
diff --git a/src/deal.go b/src/deal.go
index 118d914..783dab8 100644
--- a/src/deal.go
+++ b/src/deal.go
@@ -1,51 +1,48 @@
1package main 1package main
2 2
3import ( 3import (
4 "context"
5 "fmt" 4 "fmt"
5 "sync"
6 "time" 6 "time"
7 7
8 "go.mongodb.org/mongo-driver/bson" 8 "go.mongodb.org/mongo-driver/bson"
9 "go.mongodb.org/mongo-driver/mongo"
10 "go.mongodb.org/mongo-driver/mongo/options"
11) 9)
12 10
13const ( 11const (
14 dbName string = "test" 12 dbName string = "test"
15 colName string = "pids" 13 pidColName string = "pids"
16) 14)
17 15
16var mongoMutex sync.Mutex
17var pidCol mongoClient
18
18func deal() { 19func deal() {
19 defer wg.Done() 20 defer wg.Done()
20 var cooked Event 21 var cooked Event
21 var ok bool 22 var ok bool
22 23
23 var err error 24 var err error
24 var mongo *mongo.Client
25 var res []bson.M 25 var res []bson.M
26 26
27 mongo, err = connect() 27 if err = pidCol.Connect(dbName, pidColName); err != nil {
28 if err != nil { 28 fmt.Printf("Error connecting the mongodb: %v\n", err)
29 fmt.Printf("Err connecting the mongodb: %v\n", err)
30 } 29 }
31 pidCol := mongo.Database(dbName).Collection(colName) 30 if err = pidCol.Drop(); err != nil {
32 31 fmt.Printf("Error drop the mongodb: %v\n", err)
33 err = pidCol.Drop(context.Background())
34 if err != nil {
35 fmt.Printf("Err drop: %v\n", err)
36 } 32 }
37 33
38 _, err = pidCol.InsertOne(context.Background(), bson.M{ 34 err = pidCol.InsertOne(bson.M{
39 "ppid": 1, 35 "ppid": 1,
40 "pid": containerdPid, 36 "pid": containerdPid,
41 "cwd": "/", 37 "cwd": "/",
38 "children": bson.M{},
42 }) 39 })
43 if err != nil { 40 if err != nil {
44 fmt.Printf("Err containerd: %v", err) 41 fmt.Printf("Err containerd: %v", err)
45 return 42 return
46 } 43 }
47
48 fmt.Printf("Containerd: %d\n", containerdPid) 44 fmt.Printf("Containerd: %d\n", containerdPid)
45 defer pidCol.Disconnect()
49 46
50 for { 47 for {
51 cooked, ok = <-cookedChan 48 cooked, ok = <-cookedChan
@@ -54,81 +51,115 @@ func deal() {
54 } 51 }
55 52
56 switch syscallTable[cooked.syscall] { 53 switch syscallTable[cooked.syscall] {
57 case "fork", "vfork", "clone": 54 case "clone":
58 // 有无父进程在观察中 55 // 有无父进程在观察中
59 res, err = findDocuments(mongo, "test", "pids", bson.M{"pid": cooked.ppid}) 56 res, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
60 if err != nil || len(res) != 1 { 57 if err != nil || len(res) != 1 {
61 break 58 break
62 } 59 }
63 60
64 // 自身是否已经记录 61 // 自身是否已经记录
65 res, err = findDocuments(mongo, "test", "pids", bson.M{"pid": cooked.pid}) 62 res, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
66 if err != nil { 63 if err != nil {
67 fmt.Printf("Err finding: %v\n", err) 64 fmt.Printf("Err finding: %v\n", err)
68 break 65 break
69 } else if len(res) != 0 {
70 fmt.Printf("Err inserting pid %v: already in db: %v\n", cooked.pid, res)
71 break
72 }
73
74 doc := []bson.A{}
75 for _, str := range cooked.argv {
76 doc = append(doc, bson.A{str})
77 } 66 }
78 _, err := pidCol.InsertOne(context.Background(), bson.M{ 67 mongoMutex.Lock()
79 "timestamp": cooked.timestamp, 68 if len(res) != 0 {
80 "ppid": cooked.ppid, 69 // 进程原本就存在,换言之别的消息先到了
81 "pid": cooked.pid, 70 // 所有先行抵达的消息必须保留execve/children字段
82 "cwd": cooked.cwd, 71 // 此处不再更新
83 "args": doc, 72 // 以防把原有信息更没了
84 "children": []bson.M{}, 73 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
85 }) 74 "start_timestamp": cooked.timestamp,
86 if err != nil { 75 "ppid": cooked.ppid,
87 fmt.Printf("Err insert: %v\n", err) 76 "pid": cooked.pid,
77 "cwd": cooked.cwd,
78 // "execve": []bson.M{},
79 "args": cooked.argv,
80 // "children": []bson.M{},
81 })
82 } else {
83 // 这进程本是新修的
84 pidCol.InsertOne(bson.M{
85 "start_timestamp": cooked.timestamp,
86 "ppid": cooked.ppid,
87 "pid": cooked.pid,
88 "cwd": cooked.cwd,
89 "execve": []bson.M{},
90 "args": cooked.argv,
91 "children": []bson.M{},
92 })
88 } 93 }
89 94
90 _, err = pidCol.UpdateOne(context.Background(), bson.M{"pid": cooked.pid}, bson.M{ 95 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
91 "$push": bson.M{ 96 "$push": bson.M{
92 "children": cooked.pid, 97 "children": cooked.pid,
93 }, 98 },
94 }) 99 })
100 mongoMutex.Unlock()
101 case "execve":
102 // 父进程在不在?不在扔
103 res, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
104 if err != nil || len(res) != 1 {
105 break
106 }
107
108 // 首先检查进程是否存在,如不存在则为之创建
109 res, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
95 if err != nil { 110 if err != nil {
96 fmt.Printf("Err insert: %v\n", err) 111 break
112 }
113 mongoMutex.Lock()
114 if len(res) == 1 {
115 // 自身已在,直接记录
116 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
117 "$push": bson.M{
118 "execve": bson.M{
119 "timestamp": cooked.timestamp,
120 "args": cooked.argv,
121 },
122 },
123 })
124 } else {
125 // 先fork抵达,插入
126 pidCol.InsertOne(bson.M{
127 "children": []bson.M{},
128 "execve": []bson.M{
129 {
130 "timestamp": cooked.timestamp,
131 "execve": cooked.argv,
132 },
133 },
134 })
97 } 135 }
136 mongoMutex.Unlock()
98 case "exit", "exit_group": 137 case "exit", "exit_group":
99 // TODO: 记得补全退出逻辑 138 go deletePid(cooked)
100 // 上哪找exit code呢?
101 } 139 }
102 } 140 }
103} 141}
104 142
105func connect() (*mongo.Client, error) { 143func deletePid(cooked Event) {
106 client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) 144 time.Sleep(1 * time.Second)
107 145 mongoMutex.Lock()
108 if err != nil { 146 // 先从老爹那里销户
109 return nil, err 147 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
110 } 148 "$pull": bson.M{
111 149 "children": cooked.pid,
112 ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) 150 },
113 err = client.Connect(ctx) 151 })
114
115 if err != nil {
116 return nil, err
117 }
118
119 return client, nil
120}
121
122func findDocuments(client *mongo.Client, dbName, colName string, filter bson.M) ([]bson.M, error) {
123 collection := client.Database(dbName).Collection(colName)
124
125 cur, err := collection.Find(context.Background(), filter)
126 if err != nil {
127 return nil, err
128 }
129 152
130 var results []bson.M 153 // 孩子们需要收容
131 err = cur.All(context.Background(), &results) 154 // 不必到children里一个个找,直接看ppid即可
155 pidCol.UpdateMany(bson.M{"ppid": cooked.pid}, bson.M{"ppid": 1})
132 156
133 return results, err 157 // 可以去死了
158 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
159 "$set": bson.M{
160 "exit_timestamp": cooked.timestamp,
161 "exit_code": cooked.exit_code,
162 },
163 })
164 mongoMutex.Unlock()
134} 165}