Skip to content

Commit

Permalink
fixup! [LibOS] Allow forceful termination of IPC leader when SIGTERM …
Browse files Browse the repository at this point in the history
…was received

Signed-off-by: Stefan Berger <[email protected]>
  • Loading branch information
stefanberger committed Jan 19, 2024
1 parent dae768a commit 2070a5c
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 15 deletions.
2 changes: 1 addition & 1 deletion libos/include/libos_ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ int init_ipc_worker(void);
/*!
* \brief Terminate the IPC worker thread.
*
* \param force Whether to force the termination even if the IPC thread is the leader
* \param force Whether to force the termination of the IPC thread
*/
void terminate_ipc_worker(bool force);

Expand Down
17 changes: 10 additions & 7 deletions libos/src/ipc/libos_ipc_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,10 +397,12 @@ static int create_ipc_worker(void) {
}

/* IPC leader gets a notifier used in terminate_ipc_leader */
if (is_ipc_leader() &&
(ret = PalEventCreate(&g_leader_notifier, /*init_signaled=*/false, /*auto_clear=*/false)) < 0) {
log_error("IPC leader: PalEventCreate() failed");
return pal_to_unix_errno(ret);;
if (is_ipc_leader()) {
ret = PalEventCreate(&g_leader_notifier, /*init_signaled=*/false, /*auto_clear=*/false);
if (ret < 0) {
log_error("IPC leader: PalEventCreate() failed");
return pal_to_unix_errno(ret);
}
}

g_worker_thread = get_new_internal_thread();
Expand All @@ -425,9 +427,10 @@ int init_ipc_worker(void) {
return create_ipc_worker();
}

/* Terminate the IPC worker. If 'force' is set, the IPC leader will not wait
* until it has 0 connections but terminate immediatel, otherwise it will
* wait until all child processes have died and there are 0 connections.
/* Terminate the IPC worker. If 'force' is set, the IPC leader will not wait until it has 0
* connections but terminate immediately, otherwise it will wait until all child processes have
* died and there are 0 connections. 'force' will for example be set when the user sends a SIGTERM
* signal to the Gramine process.
*/
void terminate_ipc_worker(bool force) {
if (is_ipc_leader() && !force) {
Expand Down
13 changes: 6 additions & 7 deletions libos/src/sys/libos_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@
#include "pal.h"

static noreturn void libos_clean_and_exit(int exit_code, int term_signal) {
/*
* TODO: if we are the IPC leader, we need to either:
* 1) kill all other Gramine processes
* 2) wait for them to exit here, before we terminate the IPC helper
*/

shutdown_sync_client();

struct libos_thread* async_thread = terminate_async_worker();
Expand Down Expand Up @@ -53,6 +47,10 @@ static noreturn void libos_clean_and_exit(int exit_code, int term_signal) {
*/
release_id(get_cur_thread()->tid);

/* Terminate the IPC worker and wait until all child processes have also terminated. However,
* if we received a SIGTERM then the IPC worker will be forcefully terminated without waiting
* for child processes. Once we exit, all child proceses will the also exit.
*/
terminate_ipc_worker(term_signal == SIGTERM);

log_debug("process %u exited with status %d", g_process_ipc_ids.self_vmid, exit_code);
Expand Down Expand Up @@ -147,7 +145,8 @@ noreturn void thread_exit(int error_code, int term_signal) {

/* At this point other threads might be still in the middle of an exit routine, but we don't
* care since the below will call `exit_group` eventually. */
libos_clean_and_exit(term_signal ? 128 + (term_signal & ~__WCOREDUMP_BIT) : error_code, term_signal);
libos_clean_and_exit(term_signal ? 128 + (term_signal & ~__WCOREDUMP_BIT) : error_code,
term_signal);
}

static int mark_thread_to_die(struct libos_thread* thread, void* arg) {
Expand Down

0 comments on commit 2070a5c

Please sign in to comment.