mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Fixed child process signal behaviours. (#128)
* Restored signal handlers upon fork(). * Improved error handling of hpfs process kill scenario. * Set pgid for forked processes for graceful sending of SIGINT.
This commit is contained in:
@@ -62,7 +62,7 @@ namespace comm
|
||||
else if (pid == 0)
|
||||
{
|
||||
// Websocat process.
|
||||
util::unmask_signal();
|
||||
util::fork_detach();
|
||||
|
||||
close(write_pipe[1]); //parent write
|
||||
close(read_pipe[0]); //parent read
|
||||
|
||||
@@ -295,7 +295,7 @@ namespace comm
|
||||
else if (pid == 0)
|
||||
{
|
||||
// Websocketd process.
|
||||
util::unmask_signal();
|
||||
util::fork_detach();
|
||||
|
||||
// We are using websocketd forked repo: https://github.com/codetsunami/websocketd
|
||||
|
||||
|
||||
@@ -519,7 +519,7 @@ namespace cons
|
||||
if (pid == 0)
|
||||
{
|
||||
// appbill process.
|
||||
util::unmask_signal();
|
||||
util::fork_detach();
|
||||
|
||||
// before execution chdir into a valid the latest state data directory that contains an appbill.table
|
||||
chdir(conf::ctx.state_rw_dir.c_str());
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace hpfs
|
||||
else if (pid == 0)
|
||||
{
|
||||
// hpfs process.
|
||||
util::unmask_signal();
|
||||
util::fork_detach();
|
||||
|
||||
// Fill process args.
|
||||
char *execv_args[] = {
|
||||
@@ -145,7 +145,7 @@ namespace hpfs
|
||||
else if (pid == 0)
|
||||
{
|
||||
// hpfs process.
|
||||
util::unmask_signal();
|
||||
util::fork_detach();
|
||||
|
||||
// If the mount dir is not specified, assign a mount dir based on hpfs process id.
|
||||
const pid_t self_pid = getpid();
|
||||
|
||||
11
src/main.cpp
11
src/main.cpp
@@ -67,12 +67,12 @@ int parse_cmd(int argc, char **argv)
|
||||
*/
|
||||
void deinit()
|
||||
{
|
||||
usr::deinit();
|
||||
p2p::deinit();
|
||||
cons::deinit();
|
||||
state_sync::deinit();
|
||||
state_serve::deinit();
|
||||
read_req::deinit();
|
||||
usr::deinit();
|
||||
p2p::deinit();
|
||||
hpfs::deinit();
|
||||
}
|
||||
|
||||
@@ -190,8 +190,9 @@ int main(int argc, char **argv)
|
||||
<< (conf::cfg.startup_mode == conf::OPERATING_MODE::OBSERVER ? "Observer" : "Proposer");
|
||||
LOG_INFO << "Public key: " << conf::cfg.pubkeyhex.substr(2); // Public key without 'ed' prefix.
|
||||
|
||||
if (hpfs::init() != 0 || p2p::init() != 0 || usr::init() != 0 || read_req::init() != 0 ||
|
||||
state_serve::init() != 0 || state_sync::init() != 0 || cons::init() != 0)
|
||||
if (hpfs::init() != 0 || read_req::init() != 0 ||
|
||||
state_serve::init() != 0 || state_sync::init() != 0 || cons::init() != 0 ||
|
||||
p2p::init() != 0 || usr::init() != 0)
|
||||
{
|
||||
deinit();
|
||||
return -1;
|
||||
@@ -203,7 +204,7 @@ int main(int argc, char **argv)
|
||||
// Wait until consensus thread finishes.
|
||||
cons::wait();
|
||||
|
||||
// deinit() here only gets called when there is an error in consensus.
|
||||
// deinit() here only gets called when there is an error in consensus.
|
||||
// If not deinit in the sigint handler is called when a SIGINT is received.
|
||||
deinit();
|
||||
}
|
||||
|
||||
18
src/sc.cpp
18
src/sc.cpp
@@ -67,7 +67,7 @@ namespace sc
|
||||
else if (pid == 0)
|
||||
{
|
||||
// Contract process.
|
||||
util::unmask_signal();
|
||||
util::fork_detach();
|
||||
|
||||
// Set up the process environment and overlay the contract binary program with execv().
|
||||
|
||||
@@ -112,7 +112,9 @@ namespace sc
|
||||
ret = -1;
|
||||
|
||||
success:
|
||||
stop_hpfs_rw_session(ctx);
|
||||
if (stop_hpfs_rw_session(ctx) == -1)
|
||||
ret = -1;
|
||||
|
||||
cleanup_fdmap(ctx.userfds);
|
||||
if (!ctx.args.readonly)
|
||||
{
|
||||
@@ -131,7 +133,7 @@ namespace sc
|
||||
{
|
||||
if (pid > 0)
|
||||
{
|
||||
int scstatus;
|
||||
int scstatus = 0;
|
||||
waitpid(pid, &scstatus, 0);
|
||||
if (!WIFEXITED(scstatus))
|
||||
return WEXITSTATUS(scstatus);
|
||||
@@ -156,17 +158,18 @@ namespace sc
|
||||
*/
|
||||
int stop_hpfs_rw_session(execution_context &ctx)
|
||||
{
|
||||
int result = 0;
|
||||
// Read the root hash if not in readonly mode.
|
||||
if (!ctx.args.readonly && hpfs::get_hash(ctx.args.post_execution_state_hash, ctx.args.state_dir, "/") < 1)
|
||||
return -1;
|
||||
result = -1;
|
||||
|
||||
LOG_DEBUG << "Stopping hpfs session... pid:" << ctx.hpfs_pid << (ctx.args.readonly ? " (rdonly)" : "");
|
||||
|
||||
if (util::kill_process(ctx.hpfs_pid, true) == -1)
|
||||
return -1;
|
||||
result = -1;
|
||||
|
||||
ctx.hpfs_pid = 0;
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -711,9 +714,6 @@ namespace sc
|
||||
if (ctx.contract_pid > 0)
|
||||
util::kill_process(ctx.contract_pid, true);
|
||||
|
||||
if (ctx.hpfs_pid > 0)
|
||||
util::kill_process(ctx.hpfs_pid, true);
|
||||
|
||||
if (ctx.output_fetcher_thread.joinable())
|
||||
ctx.output_fetcher_thread.join();
|
||||
}
|
||||
|
||||
18
src/util.cpp
18
src/util.cpp
@@ -206,13 +206,25 @@ namespace util
|
||||
pthread_sigmask(SIG_BLOCK, &mask, NULL);
|
||||
}
|
||||
|
||||
// Clears signal mask from the calling thread.
|
||||
// Used for other processes forked from hpcore threads.
|
||||
void unmask_signal()
|
||||
/**
|
||||
* Clears signal mask and signal handlers from the caller.
|
||||
* Called by other processes forked from hpcore threads so they get detatched from
|
||||
* the hpcore signal setup.
|
||||
*/
|
||||
void fork_detach()
|
||||
{
|
||||
// Restore signal handlers to defaults.
|
||||
signal(SIGINT, SIG_DFL);
|
||||
signal(SIGSEGV, SIG_DFL);
|
||||
signal(SIGABRT, SIG_DFL);
|
||||
|
||||
// Remove any signal masks applied by hpcore.
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
pthread_sigmask(SIG_SETMASK, &mask, NULL);
|
||||
|
||||
// Set process group id (so the terminal doesn't send kill signals to forked children).
|
||||
setpgrp();
|
||||
}
|
||||
|
||||
// Kill a process with a signal and if specified, wait until it stops running.
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace util
|
||||
|
||||
void mask_signal();
|
||||
|
||||
void unmask_signal();
|
||||
void fork_detach();
|
||||
|
||||
int kill_process(const pid_t pid, const bool wait, const int signal = SIGINT);
|
||||
|
||||
|
||||
BIN
test/bin/hpfs
BIN
test/bin/hpfs
Binary file not shown.
Reference in New Issue
Block a user