diff options
Diffstat (limited to 'src/deal.go')
-rw-r--r-- | src/deal.go | 165 |
1 files changed, 101 insertions, 64 deletions
diff --git a/src/deal.go b/src/deal.go index fd9f788..118d914 100644 --- a/src/deal.go +++ b/src/deal.go | |||
@@ -1,97 +1,134 @@ | |||
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | ||
4 | "fmt" | 5 | "fmt" |
5 | "time" | 6 | "time" |
7 | |||
8 | "go.mongodb.org/mongo-driver/bson" | ||
9 | "go.mongodb.org/mongo-driver/mongo" | ||
10 | "go.mongodb.org/mongo-driver/mongo/options" | ||
11 | ) | ||
12 | |||
13 | const ( | ||
14 | dbName string = "test" | ||
15 | colName string = "pids" | ||
6 | ) | 16 | ) |
7 | 17 | ||
8 | func deal() { | 18 | func deal() { |
9 | defer wg.Done() | 19 | defer wg.Done() |
10 | var cooked Event | 20 | var cooked Event |
11 | var ok bool | 21 | var ok bool |
22 | |||
23 | var err error | ||
24 | var mongo *mongo.Client | ||
25 | var res []bson.M | ||
26 | |||
27 | mongo, err = connect() | ||
28 | if err != nil { | ||
29 | fmt.Printf("Err connecting the mongodb: %v\n", err) | ||
30 | } | ||
31 | pidCol := mongo.Database(dbName).Collection(colName) | ||
32 | |||
33 | err = pidCol.Drop(context.Background()) | ||
34 | if err != nil { | ||
35 | fmt.Printf("Err drop: %v\n", err) | ||
36 | } | ||
37 | |||
38 | _, err = pidCol.InsertOne(context.Background(), bson.M{ | ||
39 | "ppid": 1, | ||
40 | "pid": containerdPid, | ||
41 | "cwd": "/", | ||
42 | }) | ||
43 | if err != nil { | ||
44 | fmt.Printf("Err containerd: %v", err) | ||
45 | return | ||
46 | } | ||
47 | |||
48 | fmt.Printf("Containerd: %d\n", containerdPid) | ||
49 | |||
12 | for { | 50 | for { |
13 | cooked, ok = <-cookedChan | 51 | cooked, ok = <-cookedChan |
14 | if !ok { | 52 | if !ok { |
15 | break | 53 | break |
16 | } | 54 | } |
17 | // type Event struct { | 55 | |
18 | // timestamp time.Time | ||
19 | // pid, ppid int | ||
20 | // syscall int | ||
21 | // argc int | ||
22 | // args []string | ||
23 | // cwd string | ||
24 | // } | ||
25 | // type process struct { | ||
26 | // timestamp time.Time | ||
27 | // pid, ppid int | ||
28 | // argv []string | ||
29 | // cwd string | ||
30 | // rootfs string | ||
31 | // children []int | ||
32 | // } | ||
33 | switch syscallTable[cooked.syscall] { | 56 | switch syscallTable[cooked.syscall] { |
34 | case "fork", "vfork", "clone": | 57 | case "fork", "vfork", "clone": |
35 | ppid := cooked.ppid | 58 | // 有无父进程在观察中 |
36 | pid := cooked.pid | 59 | res, err = findDocuments(mongo, "test", "pids", bson.M{"pid": cooked.ppid}) |
37 | parent, ok := pids.Load(ppid) | 60 | if err != nil || len(res) != 1 { |
38 | if !ok { | ||
39 | break | 61 | break |
40 | } | 62 | } |
41 | parent.(*process).children = append(parent.(*process).children, pid) | 63 | |
42 | pids.Store(pid, &process{ | 64 | // 自身是否已经记录 |
43 | timestamp: cooked.timestamp, | 65 | res, err = findDocuments(mongo, "test", "pids", bson.M{"pid": cooked.pid}) |
44 | pid: cooked.pid, | 66 | if err != nil { |
45 | ppid: cooked.ppid, | 67 | fmt.Printf("Err finding: %v\n", err) |
46 | argv: cooked.argv, | 68 | break |
47 | cwd: cooked.cwd, | 69 | } else if len(res) != 0 { |
48 | children: make([]int, 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 | } | ||
78 | _, err := pidCol.InsertOne(context.Background(), bson.M{ | ||
79 | "timestamp": cooked.timestamp, | ||
80 | "ppid": cooked.ppid, | ||
81 | "pid": cooked.pid, | ||
82 | "cwd": cooked.cwd, | ||
83 | "args": doc, | ||
84 | "children": []bson.M{}, | ||
49 | }) | 85 | }) |
50 | fmt.Printf("%v syscall=%d, ppid=%d, pid=%d, cwd=\"%s\", argc=%d, ", cooked.timestamp, cooked.syscall, cooked.ppid, cooked.pid, cooked.cwd, cooked.argc) | 86 | if err != nil { |
51 | for i := 0; i < cooked.argc; i++ { | 87 | fmt.Printf("Err insert: %v\n", err) |
52 | fmt.Printf("arg[%d]=\"%s\", ", i, cooked.argv[i]) | ||
53 | } | 88 | } |
54 | fmt.Printf("\n") | 89 | |
55 | case "exit", "exit_group": | 90 | _, err = pidCol.UpdateOne(context.Background(), bson.M{"pid": cooked.pid}, bson.M{ |
56 | _, ok := pids.Load(cooked.pid) | 91 | "$push": bson.M{ |
57 | if !ok { | 92 | "children": cooked.pid, |
58 | break | 93 | }, |
94 | }) | ||
95 | if err != nil { | ||
96 | fmt.Printf("Err insert: %v\n", err) | ||
59 | } | 97 | } |
60 | go deletePid(cooked) | 98 | case "exit", "exit_group": |
99 | // TODO: 记得补全退出逻辑 | ||
100 | // 上哪找exit code呢? | ||
61 | } | 101 | } |
62 | } | 102 | } |
63 | } | 103 | } |
64 | 104 | ||
65 | func deletePid(cooked Event) { | 105 | func connect() (*mongo.Client, error) { |
66 | time.Sleep(1 * time.Second) | 106 | client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) |
67 | Process, ok := pids.Load(cooked.pid) | 107 | |
68 | if !ok { | 108 | if err != nil { |
69 | return | 109 | return nil, err |
70 | } | 110 | } |
71 | pProcess := Process.(*process) | 111 | |
72 | 112 | ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) | |
73 | // 先从爹那里注销户籍 | 113 | err = client.Connect(ctx) |
74 | parent, ok := pids.Load(pProcess.ppid) | 114 | |
75 | if ok { | 115 | if err != nil { |
76 | pParent := parent.(*process) | 116 | return nil, err |
77 | for i, child := range pParent.children { | ||
78 | if child == pProcess.pid { | ||
79 | pParent.children = append(pParent.children[:i], pParent.children[i+1:]...) | ||
80 | break | ||
81 | } | ||
82 | } | ||
83 | } | 117 | } |
84 | 118 | ||
85 | // 子进程需要收容 | 119 | return client, nil |
86 | for i := 0; i < len(pProcess.children); i++ { | 120 | } |
87 | child, ok := pids.Load(pProcess.children[i]) | 121 | |
88 | if ok { | 122 | func findDocuments(client *mongo.Client, dbName, colName string, filter bson.M) ([]bson.M, error) { |
89 | child.(*process).ppid = 1 | 123 | collection := client.Database(dbName).Collection(colName) |
90 | } | 124 | |
125 | cur, err := collection.Find(context.Background(), filter) | ||
126 | if err != nil { | ||
127 | return nil, err | ||
91 | } | 128 | } |
92 | 129 | ||
93 | // 可以去死了 | 130 | var results []bson.M |
94 | pids.Delete(cooked.pid) | 131 | err = cur.All(context.Background(), &results) |
95 | _, ok = pids.Load(cooked.pid) | 132 | |
96 | fmt.Printf("%v Goodbye, %d! ok = %v\n", time.Now(), cooked.pid, ok) | 133 | return results, err |
97 | } | 134 | } |