311 lines
11 KiB
Diff
311 lines
11 KiB
Diff
From bfc5d283ad9558d169bdb70e6b43876f5aa0062c Mon Sep 17 00:00:00 2001
|
|
From: yinbin <yinbin8@huawei.com>
|
|
Date: Tue, 31 Dec 2024 14:45:58 +0800
|
|
Subject: [PATCH] SIGNAL: Adjust sigaction function to keep lstack signal
|
|
function executed successfully.
|
|
|
|
---
|
|
src/lstack/api/lstack_unistd.c | 91 ++++++++++++++++++----
|
|
src/lstack/core/lstack_dump.c | 4 +-
|
|
src/lstack/core/lstack_protocol_stack.c | 23 +++++-
|
|
src/lstack/core/lstack_stack_stat.c | 24 +++---
|
|
src/lstack/core/lstack_thread_rpc.c | 1 +
|
|
src/lstack/include/lstack_protocol_stack.h | 3 +
|
|
6 files changed, 117 insertions(+), 29 deletions(-)
|
|
|
|
diff --git a/src/lstack/api/lstack_unistd.c b/src/lstack/api/lstack_unistd.c
|
|
index 47d80ec..90e603e 100644
|
|
--- a/src/lstack/api/lstack_unistd.c
|
|
+++ b/src/lstack/api/lstack_unistd.c
|
|
@@ -26,23 +26,54 @@
|
|
static int g_hijack_signal[] = { SIGTERM, SIGINT, SIGSEGV, SIGBUS, SIGFPE, SIGILL, SIGKILL};
|
|
#define HIJACK_SIGNAL_COUNT (sizeof(g_hijack_signal) / sizeof(g_hijack_signal[0]))
|
|
|
|
+static struct sigaction g_register_sigactions[NSIG]; // NSIG is the signal counts of system, normally equal 65 in Linux.
|
|
+static void lstack_sig_default_handler(int sig);
|
|
+
|
|
+static bool sig_is_registered(int sig)
|
|
+{
|
|
+ if (g_register_sigactions[sig].sa_handler != NULL &&
|
|
+ g_register_sigactions[sig].sa_handler != (void *) lstack_sig_default_handler) {
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
static inline bool match_hijack_signal(int sig)
|
|
{
|
|
unsigned int i;
|
|
for (i = 0; i < HIJACK_SIGNAL_COUNT; i++) {
|
|
if (sig == g_hijack_signal[i]) {
|
|
- return 1;
|
|
+ return true;
|
|
}
|
|
}
|
|
- return 0;
|
|
+ return false;
|
|
}
|
|
|
|
-static void lstack_sig_default_handler(int sig)
|
|
+/* When operations such as pressing Ctrl+C or Kill are executed, we don't need to dump the stack. */
|
|
+bool sig_need_dump(int sig)
|
|
{
|
|
+ if (sig == SIGINT || sig == SIGTERM || sig == SIGKILL) {
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static void lstack_sigaction_default_handler(int sig, siginfo_t *info, void *context)
|
|
+{
|
|
+ static bool skip_process_exit = false;
|
|
+
|
|
+ /* avoiding sig function being executed twice. */
|
|
+ if (!skip_process_exit) {
|
|
+ skip_process_exit = true;
|
|
+ } else {
|
|
+ return;
|
|
+ }
|
|
+
|
|
LSTACK_LOG(ERR, LSTACK, "lstack dumped, caught signal: %d\n", sig);
|
|
|
|
- /* When operations such as pressing Ctrl+C or Kill, the call stack exit is not displayed. */
|
|
- if (sig != SIGINT && sig != SIGTERM && sig != SIGKILL) {
|
|
+ stack_stop();
|
|
+
|
|
+ if (sig_need_dump(sig)) {
|
|
/* dump stack info */
|
|
dump_stack();
|
|
|
|
@@ -50,17 +81,31 @@ static void lstack_sig_default_handler(int sig)
|
|
dump_lstack();
|
|
}
|
|
|
|
+ if (sig_is_registered(sig)) {
|
|
+ if (g_register_sigactions[sig].sa_flags & SA_SIGINFO) {
|
|
+ g_register_sigactions[sig].sa_sigaction(sig, info, context);
|
|
+ } else {
|
|
+ g_register_sigactions[sig].sa_handler(sig);
|
|
+ }
|
|
+ }
|
|
+
|
|
if (get_global_cfg_params() && get_global_cfg_params()->is_primary) {
|
|
delete_primary_path();
|
|
}
|
|
|
|
control_fd_close();
|
|
|
|
+ stack_exit();
|
|
lwip_exit();
|
|
gazelle_exit();
|
|
(void)kill(getpid(), sig);
|
|
}
|
|
|
|
+static void lstack_sig_default_handler(int sig)
|
|
+{
|
|
+ lstack_sigaction_default_handler(sig, NULL, NULL);
|
|
+}
|
|
+
|
|
static void pthread_block_sig(int sig)
|
|
{
|
|
sigset_t mask;
|
|
@@ -105,18 +150,34 @@ int lstack_sigaction(int sig_num, const struct sigaction *action, struct sigacti
|
|
{
|
|
struct sigaction new_action;
|
|
|
|
- if ((match_hijack_signal(sig_num) != 0) && (action && action->sa_handler == SIG_DFL)) {
|
|
+ if (match_hijack_signal(sig_num) && action != NULL) {
|
|
new_action = *action;
|
|
- new_action.sa_flags |= SA_RESETHAND;
|
|
- new_action.sa_handler = lstack_sig_default_handler;
|
|
- return posix_api->sigaction_fn(sig_num, &new_action, old_action);
|
|
- }
|
|
|
|
- /* SA_INTERRUPT is deprecated, use SA_RESETHAND instead. */
|
|
- if ((match_hijack_signal(sig_num) != 0) && (action && action->sa_flags == SA_INTERRUPT)) {
|
|
- new_action = *action;
|
|
- new_action.sa_flags |= SA_RESETHAND;
|
|
- return posix_api->sigaction_fn(sig_num, &new_action, old_action);
|
|
+ if (action->sa_handler == SIG_DFL) {
|
|
+ new_action = *action;
|
|
+ new_action.sa_flags |= SA_RESETHAND;
|
|
+ new_action.sa_handler = lstack_sig_default_handler;
|
|
+ return posix_api->sigaction_fn(sig_num, &new_action, old_action);
|
|
+ }
|
|
+
|
|
+ /* SA_INTERRUPT is deprecated, use SA_RESETHAND instead. */
|
|
+ if (action->sa_flags == SA_INTERRUPT) {
|
|
+ new_action = *action;
|
|
+ new_action.sa_flags |= SA_RESETHAND;
|
|
+ return posix_api->sigaction_fn(sig_num, &new_action, old_action);
|
|
+ }
|
|
+
|
|
+ if (sig_need_dump(sig_num)) {
|
|
+ g_register_sigactions[sig_num] = new_action;
|
|
+
|
|
+ /* If SA_SIGINFO is setted, we use sa_sigaction. */
|
|
+ if (action->sa_flags & SA_SIGINFO) {
|
|
+ new_action.sa_sigaction = lstack_sigaction_default_handler;
|
|
+ } else {
|
|
+ new_action.sa_handler = lstack_sig_default_handler;
|
|
+ }
|
|
+ return posix_api->sigaction_fn(sig_num, &new_action, old_action);
|
|
+ }
|
|
}
|
|
|
|
return posix_api->sigaction_fn(sig_num, action, old_action);
|
|
diff --git a/src/lstack/core/lstack_dump.c b/src/lstack/core/lstack_dump.c
|
|
index d415ddc..2a4477d 100644
|
|
--- a/src/lstack/core/lstack_dump.c
|
|
+++ b/src/lstack/core/lstack_dump.c
|
|
@@ -23,14 +23,16 @@
|
|
#define DUMP_BACKTRACE_SIZE 64
|
|
|
|
static const char *dump_command[] = {
|
|
- "gazellectl lstack show 1",
|
|
"gazellectl lstack show 1 -s",
|
|
"gazellectl lstack show 1 -x",
|
|
+ "gazellectl lstack show 1 -v",
|
|
+ "gazellectl lstack show 1 -I",
|
|
"gazellectl lstack show 1 -p UDP",
|
|
"gazellectl lstack show 1 -p TCP",
|
|
"gazellectl lstack show 1 -p ICMP",
|
|
"gazellectl lstack show 1 -p IP",
|
|
"gazellectl lstack show 1 -p ETHARP",
|
|
+ "gazellectl lstack show 1",
|
|
"gazellectl lstack show 1 -c"
|
|
};
|
|
|
|
diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c
|
|
index 2c60a49..1eebac4 100644
|
|
--- a/src/lstack/core/lstack_protocol_stack.c
|
|
+++ b/src/lstack/core/lstack_protocol_stack.c
|
|
@@ -51,7 +51,7 @@ static void stack_set_state(struct protocol_stack *stack, enum rte_lcore_state_t
|
|
__atomic_store_n(&stack->state, state, __ATOMIC_RELEASE);
|
|
}
|
|
|
|
-static enum rte_lcore_state_t stack_get_state(struct protocol_stack *stack)
|
|
+enum rte_lcore_state_t stack_get_state(struct protocol_stack *stack)
|
|
{
|
|
return __atomic_load_n(&stack->state, __ATOMIC_ACQUIRE);
|
|
}
|
|
@@ -777,17 +777,32 @@ OUT2:
|
|
return -1;
|
|
}
|
|
|
|
-void stack_exit(void)
|
|
+static void stack_all_fds_close(struct protocol_stack *stack)
|
|
{
|
|
- /* close all fd */
|
|
for (int i = 3; i < GAZELLE_MAX_CLIENTS + GAZELLE_RESERVED_CLIENTS; i++) {
|
|
struct lwip_sock *sock = lwip_get_socket(i);
|
|
- if (!POSIX_IS_CLOSED(sock) && sock->stack == get_protocol_stack()) {
|
|
+ if (!POSIX_IS_CLOSED(sock) && sock->stack == stack) {
|
|
lwip_close(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
+void stack_exit(void)
|
|
+{
|
|
+ struct protocol_stack *stack = get_protocol_stack();
|
|
+ if (stack != NULL) {
|
|
+ stack_all_fds_close(stack);
|
|
+ }
|
|
+}
|
|
+
|
|
+void stack_stop(void)
|
|
+{
|
|
+ struct protocol_stack *stack = get_protocol_stack();
|
|
+ if (stack != NULL) {
|
|
+ stack_set_state(stack, WAIT);
|
|
+ }
|
|
+}
|
|
+
|
|
void stack_group_exit(void)
|
|
{
|
|
int i;
|
|
diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c
|
|
index c88da8f..b1eb60e 100644
|
|
--- a/src/lstack/core/lstack_stack_stat.c
|
|
+++ b/src/lstack/core/lstack_stack_stat.c
|
|
@@ -30,6 +30,7 @@
|
|
#include "lstack_dpdk.h"
|
|
#include "lstack_stack_stat.h"
|
|
#include "lstack_virtio.h"
|
|
+#include "lstack_dump.h"
|
|
|
|
void time_stamp_transfer_pbuf(struct pbuf *pbuf_old, struct pbuf *pbuf_new)
|
|
{
|
|
@@ -263,11 +264,13 @@ static void get_stack_stats(struct gazelle_stack_dfx_data *dfx, struct protocol_
|
|
int32_t rpc_call_result = rpc_msgcnt(&stack->rpc_queue);
|
|
dfx->data.pkts.call_msg_cnt = (rpc_call_result < 0) ? 0 : rpc_call_result;
|
|
|
|
- rpc_call_result = rpc_call_mbufpoolsize(&stack->dfx_rpc_queue);
|
|
- dfx->data.pkts.mbufpool_avail_cnt = (rpc_call_result < 0) ? 0 : rpc_call_result;
|
|
+ if (stack_get_state(stack) == RUNNING) {
|
|
+ rpc_call_result = rpc_call_mbufpoolsize(&stack->dfx_rpc_queue);
|
|
+ dfx->data.pkts.mbufpool_avail_cnt = (rpc_call_result < 0) ? 0 : rpc_call_result;
|
|
|
|
- rpc_call_result = rpc_call_recvlistcnt(&stack->dfx_rpc_queue);
|
|
- dfx->data.pkts.recv_list_cnt = (rpc_call_result < 0) ? 0 : rpc_call_result;
|
|
+ rpc_call_result = rpc_call_recvlistcnt(&stack->dfx_rpc_queue);
|
|
+ dfx->data.pkts.recv_list_cnt = (rpc_call_result < 0) ? 0 : rpc_call_result;
|
|
+ }
|
|
|
|
dfx->data.pkts.conn_num = stack->conn_num;
|
|
}
|
|
@@ -343,11 +346,14 @@ static void get_stack_dfx_data(struct gazelle_stack_dfx_data *dfx, struct protoc
|
|
}
|
|
break;
|
|
case GAZELLE_STAT_LSTACK_SHOW_CONN:
|
|
- rpc_call_result = rpc_call_conntable(&stack->dfx_rpc_queue, dfx->data.conn.conn_list,
|
|
- GAZELLE_LSTACK_MAX_CONN);
|
|
- dfx->data.conn.conn_num = (rpc_call_result < 0) ? 0 : rpc_call_result;
|
|
- rpc_call_result = rpc_call_connnum(&stack->dfx_rpc_queue);
|
|
- dfx->data.conn.total_conn_num = (rpc_call_result < 0) ? 0 : rpc_call_result;
|
|
+ if (stack_get_state(stack) == RUNNING) {
|
|
+ rpc_call_result = rpc_call_conntable(&stack->dfx_rpc_queue, dfx->data.conn.conn_list,
|
|
+ GAZELLE_LSTACK_MAX_CONN);
|
|
+ dfx->data.conn.conn_num = (rpc_call_result < 0) ? 0 : rpc_call_result;
|
|
+ rpc_call_result = rpc_call_connnum(&stack->dfx_rpc_queue);
|
|
+ dfx->data.conn.total_conn_num = (rpc_call_result < 0) ? 0 : rpc_call_result;
|
|
+ }
|
|
+
|
|
break;
|
|
case GAZELLE_STAT_LSTACK_SHOW_LATENCY:
|
|
ret = memcpy_s(&dfx->data.latency, sizeof(dfx->data.latency), &stack->latency, sizeof(stack->latency));
|
|
diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c
|
|
index 26bd16a..9f871af 100644
|
|
--- a/src/lstack/core/lstack_thread_rpc.c
|
|
+++ b/src/lstack/core/lstack_thread_rpc.c
|
|
@@ -146,6 +146,7 @@ static struct rpc_msg *rpc_msg_alloc_except(rpc_func_t func)
|
|
|
|
static void stack_exit_by_rpc(struct rpc_msg *msg)
|
|
{
|
|
+ stack_stop();
|
|
stack_exit();
|
|
}
|
|
|
|
diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h
|
|
index 068e9d2..c7c7efe 100644
|
|
--- a/src/lstack/include/lstack_protocol_stack.h
|
|
+++ b/src/lstack/include/lstack_protocol_stack.h
|
|
@@ -120,10 +120,13 @@ void thread_bind_stack(struct protocol_stack *stack);
|
|
int stack_group_init(void);
|
|
void stack_group_exit(void);
|
|
void stack_exit(void);
|
|
+void stack_stop(void);
|
|
|
|
int stack_setup_thread(void);
|
|
int stack_setup_app_thread(void);
|
|
|
|
int stack_polling(unsigned wakeup_tick);
|
|
|
|
+enum rte_lcore_state_t stack_get_state(struct protocol_stack *stack);
|
|
+
|
|
#endif
|
|
--
|
|
2.33.0
|
|
|