diff --git a/src/vm/node_modules/VM.js b/src/vm/node_modules/VM.js index e75f44478..96e680716 100644 --- a/src/vm/node_modules/VM.js +++ b/src/vm/node_modules/VM.js @@ -17641,11 +17641,21 @@ function doShutdownStop(vmobj, options, callback) cb(); }); }, function waitInstalled(cb) { - VM.waitForZoneState(vmobj, 'installed', {timeout: STOP_TIMEOUT}, - function shutdownWaitCb(err) { + var stop_timeout = Date.now(0) + STOP_TIMEOUT * 1000; + var ival = setInterval(function () { + // Every second, tell `systemd-shutdown` to re-check + // its list of remaining processes. + // (By default, `systemd-shutdown` waits 90 seconds + // for a root cgroup SIGCHLD that is never sent.) + fs.readlink('/proc/' + vmobj.pid + '/path/a.out', + function (err, link) { + if (!err && jsprim.endsWith(link, '/systemd-shutdown')) { + killSig(vmobj.pid, 'SIGCHLD'); + } + }); - if (err && err.hasOwnProperty('code') - && err.code === 'ETIMEOUT') { + if (Date.now(0) > stop_timeout) { + clearInterval(ival); log.info('Timeout waiting for shutdown to complete; ' + 'halting.'); @@ -17660,10 +17670,22 @@ function doShutdownStop(vmobj, options, callback) } cb(_err); }); - return; } - cb(err); - }); + + var load_opts = {fields: ['zone_state'], log: log}; + vmload.getVmobj(vmobj.uuid, load_opts, function (_err, vmobj) { + if (_err) { + log.warn({err: _err, stdout: fds.stdout, + stderr: fds.stderr}, 'Error checking status while halting zone'); + return; + } + + if (vmobj.zone_state == 'installed') { + clearInterval(ival); + cb(); + } + }); + }, 1000); }, function zonecfgNoAutoboot(cb) { zonecfg(vmobj.uuid, [unset_autoboot], {log: log}, function (err, fds) { @@ -18213,6 +18235,18 @@ function doReboot(vmobj, options, callback) } ticks = 180 * 10; // (180 * 10) 100ms ticks = 3m ival = setInterval(function () { + if (ticks % 10 == 0) { + // Every second, tell `systemd-shutdown` to re-check + // its list of remaining processes. + // (By default, `systemd-shutdown` waits 90 seconds + // for a root cgroup SIGCHLD that is never sent.) + fs.readlink('/proc/' + vmobj.pid + '/path/a.out', + function (err, link) { + if (!err && jsprim.endsWith(link, '/systemd-shutdown')) { + killSig(vmobj.pid, 'SIGCHLD'); + } + }); + } if (reboot_complete) { log.debug('reboot marked complete, cleaning up'); clearInterval(ival);