--- lbbs/src/net_server.c 2025/06/25 01:50:14 1.66 +++ lbbs/src/net_server.c 2025/09/22 05:07:22 1.71 @@ -25,6 +25,7 @@ #include "login.h" #include "menu.h" #include "net_server.h" +#include "section_list.h" #include "section_list_loader.h" #include #include @@ -44,6 +45,9 @@ #include #include +#define WAIT_CHILD_PROCESS_EXIT_TIMEOUT 5 // second +#define WAIT_CHILD_PROCESS_KILL_TIMEOUT 1 // second + struct process_sockaddr_t { pid_t pid; @@ -121,6 +125,7 @@ static ssh_channel new_session_channel(s static int fork_server(void) { ssh_event event; + long int ssh_timeout = 0; int pid; int i; int ret; @@ -172,6 +177,13 @@ static int fork_server(void) ssh_callbacks_init(&cb); ssh_set_server_callbacks(SSH_session, &cb); + ssh_timeout = 60; // second + if (ssh_options_set(SSH_session, SSH_OPTIONS_TIMEOUT, &ssh_timeout) < 0) + { + log_error("Error setting SSH options: %s\n", ssh_get_error(SSH_session)); + goto cleanup; + } + if (ssh_handle_key_exchange(SSH_session)) { log_error("ssh_handle_key_exchange() error: %s\n", ssh_get_error(SSH_session)); @@ -197,6 +209,13 @@ static int fork_server(void) log_error("SSH auth error, tried %d times\n", cb_data.tries); goto cleanup; } + + ssh_timeout = 0; + if (ssh_options_set(SSH_session, SSH_OPTIONS_TIMEOUT, &ssh_timeout) < 0) + { + log_error("Error setting SSH options: %s\n", ssh_get_error(SSH_session)); + goto cleanup; + } } // Redirect Input @@ -257,6 +276,8 @@ int net_server(const char *hostaddr, in_ struct epoll_event ev, events[MAX_EVENTS]; int nfds, epollfd; siginfo_t siginfo; + int notify_child_exit = 0; + time_t tm_notify_child_exit = time(NULL); int sd_notify_stopping = 0; MENU_SET bbs_menu_new; int i, j; @@ -399,13 +420,43 @@ int net_server(const char *hostaddr, in_ if (SYS_server_exit && !SYS_child_exit && SYS_child_process_count > 0) { - log_common("Notify %d child process to exit\n", SYS_child_process_count); - if (kill(0, SIGTERM) < 0) + if (notify_child_exit == 0) { - log_error("Send SIGTERM signal failed (%d)\n", errno); + sd_notifyf(0, "STATUS=Notify %d child process to exit", SYS_child_process_count); + log_common("Notify %d child process to exit\n", SYS_child_process_count); + + if (kill(0, SIGTERM) < 0) + { + log_error("Send SIGTERM signal failed (%d)\n", errno); + } + + notify_child_exit = 1; + tm_notify_child_exit = time(NULL); } + else if (notify_child_exit == 1 && time(NULL) - tm_notify_child_exit >= WAIT_CHILD_PROCESS_EXIT_TIMEOUT) + { + sd_notifyf(0, "STATUS=Kill %d child process", SYS_child_process_count); + + for (i = 0; i < BBS_max_client; i++) + { + if (process_sockaddr_pool[i].pid != 0) + { + log_error("Kill child process (pid=%d)\n", process_sockaddr_pool[i].pid); + if (kill(process_sockaddr_pool[i].pid, SIGKILL) < 0) + { + log_error("Send SIGKILL signal failed (%d)\n", errno); + } + } + } - sd_notifyf(0, "STATUS=Waiting for %d child process to exit", SYS_child_process_count); + notify_child_exit = 2; + tm_notify_child_exit = time(NULL); + } + else if (notify_child_exit == 2 && time(NULL) - tm_notify_child_exit >= WAIT_CHILD_PROCESS_KILL_TIMEOUT) + { + log_error("Main process prepare to exit without waiting for %d child process any longer\n", SYS_child_process_count); + SYS_child_process_count = 0; + } } if (SYS_conf_reload && !SYS_server_exit) @@ -426,18 +477,11 @@ int net_server(const char *hostaddr, in_ } else { + unload_menu(&bbs_menu); memcpy(&bbs_menu, &bbs_menu_new, sizeof(bbs_menu_new)); log_common("Reload menu successfully\n"); } - sd_notify(0, "READY=1"); - } - - if (SYS_data_file_reload && !SYS_server_exit) - { - SYS_data_file_reload = 0; - sd_notify(0, "RELOADING=1"); - for (int i = 0; i < data_files_load_startup_count; i++) { if (load_file(data_files_load_startup[i]) < 0) @@ -445,19 +489,19 @@ int net_server(const char *hostaddr, in_ log_error("load_file_mmap(%s) error\n", data_files_load_startup[i]); } } - log_common("Reload data files successfully\n"); - sd_notify(0, "READY=1"); - } - - if (SYS_section_list_reload && !SYS_server_exit) - { - SYS_section_list_reload = 0; - if (section_list_loader_reload() < 0) + // Load section config and gen_ex + if (load_section_config_from_db(1) < 0) { - log_error("section_list_loader_reload() failed\n"); + log_error("load_section_config_from_db(1) error\n"); } + else + { + log_common("Reload section config and gen_ex successfully\n"); + } + + sd_notify(0, "READY=1"); } nfds = epoll_wait(epollfd, events, MAX_EVENTS, 100); // 0.1 second