Skip to content

Commit 5ba7c6e

Browse files
lec-bitlec-bit
authored andcommitted
add kernel module log
Signed-off-by: lec-bit <glfhmzmy@126.com>
1 parent b483787 commit 5ba7c6e

File tree

6 files changed

+170
-17
lines changed

6 files changed

+170
-17
lines changed

kernel/ko_src/kmesh/defer_connect.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,13 @@ static int defer_connect(struct sock *sk, struct msghdr *msg, size_t size)
6666
goto connect;
6767

6868
kbuf = (void *)kmalloc(kbuf_size, GFP_KERNEL);
69-
if (!kbuf)
69+
if (!kbuf) {
70+
LOG(KERN_ERR, "kbuf kmalloc failed\n");
7071
return -EFAULT;
72+
}
7173

7274
if (copy_from_user(kbuf, ubase, kbuf_size)) {
75+
LOG(KERN_ERR, "copy_from_user failed\n");
7376
err = -EFAULT;
7477
goto out;
7578
}
@@ -104,6 +107,7 @@ static int defer_connect(struct sock *sk, struct msghdr *msg, size_t size)
104107
connect:
105108
err = sk->sk_prot->connect(sk, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_in));
106109
if (unlikely(err)) {
110+
LOG(KERN_ERR, "connect failed:%d\n", err);
107111
tcp_set_state(sk, TCP_CLOSE);
108112
sk->sk_route_caps = 0;
109113
inet_sk(sk)->inet_dport = 0;
@@ -192,8 +196,10 @@ static struct tcp_ulp_ops kmesh_defer_ulp_ops __read_mostly = {
192196
int __init defer_conn_init(void)
193197
{
194198
kmesh_defer_proto = kmalloc(sizeof(struct proto), GFP_ATOMIC);
195-
if (!kmesh_defer_proto)
199+
if (!kmesh_defer_proto) {
200+
LOG(KERN_ERR, "kmesh_defer_proto kmalloc failed\n");
196201
return -ENOMEM;
202+
}
197203
*kmesh_defer_proto = tcp_prot;
198204
kmesh_defer_proto->connect = defer_tcp_connect;
199205
kmesh_defer_proto->sendmsg = defer_tcp_sendmsg;

kernel/ko_src/kmesh/kmesh_main.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ static int __init kmesh_init(void)
1919
int ret;
2020

2121
ret = defer_conn_init();
22-
if (ret)
22+
if (ret) {
23+
LOG(KERN_ERR, "defer_conn_init failed:%d\n", ret);
2324
return ret;
25+
}
2426

2527
ret = proto_common_init();
26-
if (ret)
28+
if (ret) {
29+
LOG(KERN_ERR, "proto_common_init failed:%d\n", ret);
2730
return ret;
31+
}
2832

2933
ret = kmesh_register_http_1_1_init();
3034
return ret;

kernel/ko_src/kmesh/kmesh_parse_http_1_1.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ static enum state __parse_request_startline(
121121
}
122122

123123
failed:
124+
if (current_state != ST_FIELD_NAME_START)
125+
LOG(KERN_ERR, "__parse_request_startline failed, current_state:%d, char: %c\n", current_state, ch);
124126
return current_state;
125127
}
126128

@@ -131,8 +133,10 @@ static bool parse_request_startline(const struct bpf_mem_ptr *msg, struct bpf_me
131133
struct kmesh_data_node *URI = new_kmesh_data_node(URI_STRING_LENGTH);
132134
struct kmesh_data_node *http_version = new_kmesh_data_node(VERSION_STRING_LENGTH);
133135

134-
if (IS_ERR(method) || IS_ERR(URI) || IS_ERR(http_version))
136+
if (IS_ERR(method) || IS_ERR(URI) || IS_ERR(http_version)) {
137+
LOG(KERN_ERR, "parse_request new kmesh_data_node failed\n");
135138
goto failed;
139+
}
136140

137141
current_state = __parse_request_startline(msg, context, method, URI, http_version);
138142
if (current_state != ST_FIELD_NAME_START)
@@ -232,6 +236,8 @@ static enum state __parse_respose_startline(
232236
}
233237
}
234238
failed:
239+
if (current_state != ST_FIELD_NAME_START)
240+
LOG(KERN_ERR, "__parse_respose_startline failed, current_state:%d, char: %c\n", current_state, ch);
235241
return current_state;
236242
}
237243

@@ -242,8 +248,10 @@ static bool parse_respose_startline(const struct bpf_mem_ptr *msg, struct bpf_me
242248
struct kmesh_data_node *status_code = new_kmesh_data_node(STATUS_STRING_LENGTH);
243249
struct kmesh_data_node *reason = new_kmesh_data_node(REASON_STRING_LENGTH);
244250

245-
if (IS_ERR(http_version) || IS_ERR(status_code) || IS_ERR(reason))
251+
if (IS_ERR(http_version) || IS_ERR(status_code) || IS_ERR(reason)) {
252+
LOG(KERN_ERR, "parse_respose new kmesh_data_node failed\n");
246253
goto failed;
254+
}
247255

248256
current_state = __parse_respose_startline(msg, context, http_version, status_code, reason);
249257
if (current_state != ST_FIELD_NAME_START)
@@ -279,8 +287,10 @@ static bool parse_header(struct bpf_mem_ptr *context)
279287
ch = ((char *)context->ptr)[i];
280288
switch (current_state) {
281289
case ST_FIELD_NAME_START:
282-
if (ch == FIELD_SPLIT)
290+
if (ch == FIELD_SPLIT) {
291+
LOG(KERN_ERR, "Invalid field split detected, char:%c, current_state:%d\n", ch, current_state);
283292
return false;
293+
}
284294
if (ch == CR) {
285295
current_state = ST_HEAD_END;
286296
break;
@@ -315,15 +325,20 @@ static bool parse_header(struct bpf_mem_ptr *context)
315325
current_state = ST_NEW_LINE;
316326
break;
317327
case ST_NEW_LINE:
318-
if (unlikely(ch != LF))
328+
if (unlikely(ch != LF)) {
329+
LOG(KERN_ERR, "Expected LF but got another character:%c, current_state:%d\n", ch, current_state);
319330
return false;
320-
if (field_name_end_position < field_name_begin_position)
321-
return false;
322-
if (field_value_end_position < field_value_begin_position)
331+
}
332+
if (field_name_end_position < field_name_begin_position
333+
|| field_value_end_position < field_value_begin_position) {
334+
LOG(KERN_ERR, "Invalid field name or value positions, char:%c, current_state:%d\n", ch, current_state);
323335
return false;
336+
}
324337
new_field = new_kmesh_data_node(field_name_end_position - field_name_begin_position + 2);
325-
if (IS_ERR(new_field))
338+
if (IS_ERR(new_field)) {
339+
LOG(KERN_ERR, "Failed to create new field node, char:%c, current_state:%d\n", ch, current_state);
326340
return false;
341+
}
327342
(void)strncpy(
328343
new_field->keystring,
329344
((char *)context->ptr) + field_name_begin_position,
@@ -347,18 +362,21 @@ static bool parse_header(struct bpf_mem_ptr *context)
347362
current_state = ST_FIELD_NAME_START;
348363
break;
349364
case ST_HEAD_END:
350-
if (ch != LF)
365+
if (ch != LF) {
366+
LOG(KERN_ERR, "Expected LF but got another character:%c, current_state:%d\n", ch, current_state);
351367
return false;
368+
}
352369
head_end = true;
353370
break;
354371
default:
355372
// It's not going to get here
356373
break;
357374
}
358375
}
359-
if (current_state != ST_HEAD_END)
376+
if (current_state != ST_HEAD_END) {
377+
LOG(KERN_ERR, "parse_header failed, current_state:%d\n", current_state);
360378
return false;
361-
379+
}
362380
return true;
363381
}
364382

kernel/ko_src/kmesh/kmesh_parse_protocol_data.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ struct kmesh_data_node *new_kmesh_data_node(u32 name_field_length)
1515
{
1616
struct kmesh_data_node *new = (struct kmesh_data_node *)kmalloc(sizeof(struct kmesh_data_node), GFP_ATOMIC);
1717
if (unlikely(!new)) {
18-
(void)pr_err("[kmesh data node] alloc data node memory failed! no memory!\n");
18+
LOG(KERN_ERR, "alloc data node memory failed! no memory!\n");
1919
return ERR_PTR(-ENOMEM);
2020
}
2121
(void)memset(new, 0x0, sizeof(struct kmesh_data_node));
2222
new->keystring = (char *)kmalloc(name_field_length * sizeof(char), GFP_ATOMIC);
2323
if (unlikely(!new->keystring)) {
2424
kfree(new);
25-
(void)pr_err("[kmesh data node] alloc data node key memory failed! no memory!\n");
25+
LOG(KERN_ERR, "alloc data node key memory failed! no memory!\n");
2626
return ERR_PTR(-ENOMEM);
2727
}
2828
(void)memset(new->keystring, 0x0, sizeof(char) * name_field_length);

pkg/controller/controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
manage "kmesh.net/kmesh/pkg/controller/manage"
3333
"kmesh.net/kmesh/pkg/controller/security"
3434
"kmesh.net/kmesh/pkg/dns"
35+
"kmesh.net/kmesh/pkg/kolog"
3536
"kmesh.net/kmesh/pkg/kube"
3637
"kmesh.net/kmesh/pkg/logger"
3738
helper "kmesh.net/kmesh/pkg/utils"
@@ -107,6 +108,7 @@ func (c *Controller) Start(stopCh <-chan struct{}) error {
107108
}
108109
kmeshManageController, err = manage.NewKmeshManageController(clientset, secertManager, c.bpfWorkloadObj.XdpAuth.XdpAuthz.FD(), tcFd, c.mode)
109110
} else {
111+
kolog.KmeshModuleLog(stopCh)
110112
kmeshManageController, err = manage.NewKmeshManageController(clientset, nil, -1, tcFd, c.mode)
111113
}
112114
if err != nil {

pkg/kolog/kolog.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright The Kmesh Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at:
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package kolog
18+
19+
import (
20+
"bufio"
21+
"fmt"
22+
"os"
23+
"strconv"
24+
"strings"
25+
"time"
26+
27+
"kmesh.net/kmesh/pkg/logger"
28+
)
29+
30+
var (
31+
log = logger.NewLoggerScope("Kmesh_module")
32+
)
33+
34+
// Used for timestamp conversion
35+
func getBootTime() (time.Time, error) {
36+
data, err := os.ReadFile("/proc/stat")
37+
if err != nil {
38+
return time.Time{}, err
39+
}
40+
41+
for _, line := range strings.Split(string(data), "\n") {
42+
if strings.HasPrefix(line, "btime ") {
43+
parts := strings.Fields(line)
44+
if len(parts) < 2 {
45+
continue
46+
}
47+
btime, err := strconv.ParseInt(parts[1], 10, 64)
48+
if err != nil {
49+
return time.Time{}, err
50+
}
51+
return time.Unix(btime, 0), nil
52+
}
53+
}
54+
return time.Time{}, fmt.Errorf("btime not found")
55+
}
56+
57+
// Convert to a readable time:dataTime
58+
func timeParse(timestamp uint64, bootTime time.Time) time.Time {
59+
totalNano := (timestamp) * uint64(time.Microsecond)
60+
return bootTime.Add(time.Duration(totalNano))
61+
}
62+
63+
func parseKmsgLine(line string, bootTime time.Time, appStartTimestamp uint64) {
64+
parts := strings.Split(line, ",")
65+
if len(parts) < 3 {
66+
return
67+
}
68+
69+
// parse timestamp
70+
timestampStr := strings.TrimSpace(parts[2])
71+
timestamp, err := strconv.ParseUint(timestampStr, 10, 64)
72+
if err != nil {
73+
log.Printf("Parse timestamp error: %v", err)
74+
return
75+
}
76+
77+
if timestamp < appStartTimestamp {
78+
return
79+
}
80+
eventTime := timeParse(timestamp, bootTime)
81+
82+
// parse is Kmesh log
83+
if strings.Contains(line, "Kmesh_module") {
84+
// The log print will add a '\n' at the end again,
85+
// so the original string's '\n' needs to be removed.
86+
line = strings.TrimSuffix(line, "\n")
87+
log.Printf("[%s] %s\n", eventTime.Format(time.DateTime), line)
88+
}
89+
}
90+
91+
func KmeshModuleLog(stopCh <-chan struct{}) {
92+
go func() {
93+
bootTime, err := getBootTime()
94+
if err != nil {
95+
log.Fatalf("getBootTime: %v", err)
96+
}
97+
startTimestamp := uint64(time.Now().UnixMicro() - bootTime.UnixMicro())
98+
99+
file, err := os.Open("/dev/kmsg")
100+
if err != nil {
101+
log.Fatalf("open /dev/kmsg failed: %v", err)
102+
}
103+
defer file.Close()
104+
105+
reader := bufio.NewReader(file)
106+
for {
107+
select {
108+
case <-stopCh:
109+
return
110+
default:
111+
line, err := reader.ReadString('\n')
112+
if err != nil {
113+
if err.Error() == "EOF" {
114+
time.Sleep(100 * time.Millisecond)
115+
continue
116+
}
117+
log.Fatalf("ReadString err: %v", err)
118+
}
119+
parseKmsgLine(line, bootTime, startTimestamp)
120+
}
121+
}
122+
}()
123+
}

0 commit comments

Comments
 (0)