Kill child processes

On Unix, child processes are not killed when parent dies.

Each process is part of a process group (pgid). When pgid == pid,
it is the process group leader.

node creates child processes with the parent as the group leader
(detached = false).

You can send a signal to entire group using kill(-pgid), as in,
negative value in argument. Systemd can be made to do this by
setting the KillMode=control-group.

Unrelated: Process groups reside inside session groups. Each session
group has a controlling terminal. Only one process in the session
group has access to the terminal. Process group is basically like
a bash pipeline. A session group is the entire login session with only
one process having terminal access at a time.

Fixes #543
This commit is contained in:
girish@cloudron.io
2016-01-21 17:40:41 -08:00
parent 022ff89836
commit bcb0e61bfc
4 changed files with 6 additions and 2 deletions
+2 -1
View File
@@ -227,7 +227,8 @@ Description=Cloudron Installer
Type=idle Type=idle
ExecStart="${INSTALLER_SOURCE_DIR}/src/server.js" ExecStart="${INSTALLER_SOURCE_DIR}/src/server.js"
Environment="DEBUG=installer*,connect-lastmile" ${provisionEnv} Environment="DEBUG=installer*,connect-lastmile" ${provisionEnv}
KillMode=process ; kill any child (installer.sh, retire.sh) as well
KillMode=control-group
Restart=on-failure Restart=on-failure
[Install] [Install]
+1
View File
@@ -36,6 +36,7 @@ util.inherits(InstallerError, Error);
InstallerError.INTERNAL_ERROR = 1; InstallerError.INTERNAL_ERROR = 1;
InstallerError.ALREADY_PROVISIONED = 2; InstallerError.ALREADY_PROVISIONED = 2;
// system until file has KillMode=control-group to bring down child processes
function spawn(tag, cmd, args, callback) { function spawn(tag, cmd, args, callback) {
assert.strictEqual(typeof tag, 'string'); assert.strictEqual(typeof tag, 'string');
assert.strictEqual(typeof cmd, 'string'); assert.strictEqual(typeof cmd, 'string');
+2 -1
View File
@@ -9,7 +9,8 @@ WorkingDirectory=/home/yellowtent/box
Restart=always Restart=always
ExecStart=/usr/bin/node --max_old_space_size=150 /home/yellowtent/box/box.js ExecStart=/usr/bin/node --max_old_space_size=150 /home/yellowtent/box/box.js
Environment="HOME=/home/yellowtent" "USER=yellowtent" "DEBUG=box*,connect-lastmile" "BOX_ENV=cloudron" "NODE_ENV=production" Environment="HOME=/home/yellowtent" "USER=yellowtent" "DEBUG=box*,connect-lastmile" "BOX_ENV=cloudron" "NODE_ENV=production"
KillMode=process ; kill apptask processes as well
KillMode=control-group
User=yellowtent User=yellowtent
Group=yellowtent Group=yellowtent
MemoryLimit=200M MemoryLimit=200M
+1
View File
@@ -92,6 +92,7 @@ function startAppTask(appId) {
return; return;
} }
// when parent process dies, apptask processes are killed because KillMode=control-group in systemd unit file
gActiveTasks[appId] = child_process.fork(__dirname + '/apptask.js', [ appId ]); gActiveTasks[appId] = child_process.fork(__dirname + '/apptask.js', [ appId ]);
var pid = gActiveTasks[appId].pid; var pid = gActiveTasks[appId].pid;