gazelle/0311-SIGNAL-Adjust-sigaction-function-to-keep-lstack-sign.patch
yinbin 3960eb3399 sync DUMP: fix abnomal printing in the dump process.
(cherry picked from commit 8b299f18d5aa647bc82d60712ede06139c6b1bd7)
2025-01-17 19:53:26 +08:00

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