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:
@@ -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]
|
||||||
|
|||||||
@@ -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');
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user