1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-11 13:53:37 +00:00

1. Fixed edge case that caused child KVM process to turn into a zombie

2. Fixed user-sessions.change event to delay emitting until a session activates (or a few seconds if a session doesn't activate)
This commit is contained in:
Bryan Roe
2021-09-16 16:46:28 -07:00
parent b3f2fa7aea
commit 618ba307cf
3 changed files with 90 additions and 7 deletions

View File

@@ -1348,7 +1348,15 @@ void kvm_relay_brokenPipeSink_2(void *sender)
void kvm_relay_brokenPipeSink(ILibProcessPipe_Pipe sender) void kvm_relay_brokenPipeSink(ILibProcessPipe_Pipe sender)
{ {
void *chain = ((void**)ILibMemory_Extra(sender))[2]; void *chain = ((void**)ILibMemory_Extra(sender))[2];
ILibLifeTime_AddEx(ILibGetBaseTimer(chain), sender, 1000, kvm_relay_brokenPipeSink_2, NULL);
if (g_slavekvm != 0)
{
int r;
waitpid(g_slavekvm, &r, WNOHANG);
g_slavekvm = 0;
}
ILibLifeTime_AddEx(ILibGetBaseTimer(chain), sender, 4000, kvm_relay_brokenPipeSink_2, NULL);
} }
void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid, char* authToken, char *dispid) void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid, char* authToken, char *dispid)

File diff suppressed because one or more lines are too long

View File

@@ -423,12 +423,14 @@ function UserSessions()
{ {
get: function () get: function ()
{ {
if (this._hasLoginCtl != null) { return (this._hasLoginCtl); }
var child = require('child_process').execFile('/bin/sh', ['sh']); var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("whereis loginctl | awk '{ print $2 }'\nexit\n"); child.stdin.write("whereis loginctl | awk '{ print $2 }'\nexit\n");
child.waitExit(); child.waitExit();
return (child.stdout.str.trim()!=""); this._hasLoginCtl = child.stdout.str.trim() != "";
return (this._hasLoginCtl);
} }
}); });
Object.defineProperty(this, "gdmUid", { Object.defineProperty(this, "gdmUid", {
@@ -473,6 +475,71 @@ function UserSessions()
throw ('username: ' + username + ' NOT FOUND'); throw ('username: ' + username + ' NOT FOUND');
}; };
function linux_Onchange_checkLoginCtl()
{
if (linux_Onchange_checkLoginCtl.counter > 10)
{
console.info1("emitting 'changed' because giving up");
require('user-sessions').emit('changed');
return;
}
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stderr.str = ''; child.stderr.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("loginctl list-sessions | tr '\\n' '`' | awk '{");
child.stdin.write('printf "[";');
child.stdin.write('del="";');
child.stdin.write('n=split($0, lines, "`");');
child.stdin.write('for(i=2;i<n;++i)');
child.stdin.write('{');
child.stdin.write(' split(lines[i], tok, " ");');
child.stdin.write(' if(tok[4]=="") { continue; }');
child.stdin.write(' printf "%s{\\"Username\\": \\"%s\\", \\"SessionId\\": \\"%s\\", \\"State\\": \\"Online\\", \\"uid\\": \\"%s\\"}", del, tok[3], tok[1], tok[2];');
child.stdin.write(' del=",";');
child.stdin.write('}');
child.stdin.write('printf "]";');
child.stdin.write("}'\nexit\n");
child.waitExit();
var info1 = JSON.parse(child.stdout.str);
var sids = [];
var i;
for (i = 0; i < info1.length; ++i) { sids.push(info1[i].SessionId); }
console.info1('SIDs => ' + JSON.stringify(sids));
child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stderr.str = ''; child.stderr.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("loginctl show-session -p State " + sids.join(' ') + " | grep State= | tr '\\n' '`' | awk -F'`' '{");
child.stdin.write(' for(n=1;n<NF;++n)');
child.stdin.write(' {');
child.stdin.write(' if($n=="State=active") { print n; break; }');
child.stdin.write(' }');
child.stdin.write("}'\nexit\n");
child.waitExit();
if(child.stdout.str.trim() != '')
{
// There was an active session
console.info1('Active Sessions found');
linux_Onchange_checkLoginCtl.counter = 0;
linux_Onchange_checkLoginCtl.timer = null;
require('user-sessions').emit('changed');
}
else
{
// No sessions were active, so we need to try again
console.info1('No Active Sessions found, try again');
linux_Onchange_checkLoginCtl.counter++;
linux_Onchange_checkLoginCtl.timer = setTimeout(linux_Onchange_checkLoginCtl, 500);
}
}
this.Current = function Current(cb) this.Current = function Current(cb)
{ {
var ret = null; var ret = null;
@@ -556,13 +623,21 @@ function UserSessions()
if (process.platform == 'linux') if (process.platform == 'linux')
{ {
var dbus = require('linux-dbus'); if (require('fs').watch)
if (require('fs').watch) { {
this._linuxWatcher = require('fs').watch('/var/run/utmp'); this._linuxWatcher = require('fs').watch('/var/run/utmp');
this._linuxWatcher.user_session = this;
this._linuxWatcher.on('change', function (a, b) this._linuxWatcher.on('change', function (a, b)
{ {
this.user_session.emit('changed'); if (require('user-sessions').hasLoginCtl)
{
linux_Onchange_checkLoginCtl.counter = 0;
linux_Onchange_checkLoginCtl.timer = null;
linux_Onchange_checkLoginCtl();
}
else
{
require('user-sessions').emit('changed');
}
}); });
} }