@ai-ecoverse/slicc-kernel 1.179.0 → 1.180.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -2
- package/dist/driver-worker.js +53 -1
- package/dist/driver-worker.js.map +2 -2
- package/dist/index.js +53 -1
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +217 -20
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js +53 -1
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.cjs +1 -1
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +267 -18
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +1 -1
- package/dist/types/client/attach.d.ts +15 -3
- package/dist/types/client/protocol.d.ts +20 -4
- package/dist/types/index.d.ts +1 -1
- package/dist/types/kernel/jobs.d.ts +2 -1
- package/dist/types/kernel/trace.d.ts +59 -0
- package/dist/types/launcher.d.ts +9 -0
- package/dist/types/node.d.ts +1 -1
- package/package.json +2 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -7451,6 +7451,82 @@ var KERNEL_SIGINFO = Object.freeze({
|
|
|
7451
7451
|
status: 0
|
|
7452
7452
|
});
|
|
7453
7453
|
|
|
7454
|
+
// src/kernel/trace.ts
|
|
7455
|
+
var TRACE_LIMIT = 4096;
|
|
7456
|
+
var TRACE_LIMIT_MAX = 65536;
|
|
7457
|
+
function traceLimit(value2) {
|
|
7458
|
+
if (value2 === void 0) return TRACE_LIMIT;
|
|
7459
|
+
if (!Number.isInteger(value2) || value2 < 1 || value2 > TRACE_LIMIT_MAX) {
|
|
7460
|
+
throw Object.assign(new Error(`a trace limit is an integer from 1 to ${TRACE_LIMIT_MAX}`), {
|
|
7461
|
+
code: "EINVAL"
|
|
7462
|
+
});
|
|
7463
|
+
}
|
|
7464
|
+
return value2;
|
|
7465
|
+
}
|
|
7466
|
+
var TraceHub = class {
|
|
7467
|
+
subs = /* @__PURE__ */ new Set();
|
|
7468
|
+
seq = 0;
|
|
7469
|
+
get idle() {
|
|
7470
|
+
return this.subs.size === 0;
|
|
7471
|
+
}
|
|
7472
|
+
subscribe(tag, viewer, deliver, limit = TRACE_LIMIT) {
|
|
7473
|
+
const sub = {
|
|
7474
|
+
tag,
|
|
7475
|
+
viewer: copyCred(viewer),
|
|
7476
|
+
limit,
|
|
7477
|
+
queue: [],
|
|
7478
|
+
dropped: 0,
|
|
7479
|
+
waiting: false,
|
|
7480
|
+
scheduled: false,
|
|
7481
|
+
deliver
|
|
7482
|
+
};
|
|
7483
|
+
this.subs.add(sub);
|
|
7484
|
+
return {
|
|
7485
|
+
ack: () => {
|
|
7486
|
+
sub.waiting = false;
|
|
7487
|
+
this.schedule(sub);
|
|
7488
|
+
},
|
|
7489
|
+
close: () => {
|
|
7490
|
+
this.subs.delete(sub);
|
|
7491
|
+
sub.queue = [];
|
|
7492
|
+
}
|
|
7493
|
+
};
|
|
7494
|
+
}
|
|
7495
|
+
wants(tags, cred) {
|
|
7496
|
+
if (!tags?.length || this.subs.size === 0) return false;
|
|
7497
|
+
for (const sub of this.subs) if (this.matches(sub, tags, cred)) return true;
|
|
7498
|
+
return false;
|
|
7499
|
+
}
|
|
7500
|
+
publish(tags, cred, draft) {
|
|
7501
|
+
if (!tags?.length) return;
|
|
7502
|
+
let event;
|
|
7503
|
+
for (const sub of this.subs) {
|
|
7504
|
+
if (!this.matches(sub, tags, cred)) continue;
|
|
7505
|
+
event ??= { ...draft, seq: ++this.seq };
|
|
7506
|
+
if (sub.queue.length >= sub.limit) sub.dropped++;
|
|
7507
|
+
else sub.queue.push(event);
|
|
7508
|
+
this.schedule(sub);
|
|
7509
|
+
}
|
|
7510
|
+
}
|
|
7511
|
+
matches(sub, tags, cred) {
|
|
7512
|
+
return tags.includes(sub.tag) && maySee(sub.viewer, cred);
|
|
7513
|
+
}
|
|
7514
|
+
schedule(sub) {
|
|
7515
|
+
if (sub.scheduled || sub.waiting) return;
|
|
7516
|
+
if (sub.queue.length === 0 && sub.dropped === 0) return;
|
|
7517
|
+
sub.scheduled = true;
|
|
7518
|
+
queueMicrotask(() => {
|
|
7519
|
+
sub.scheduled = false;
|
|
7520
|
+
if (!this.subs.has(sub)) return;
|
|
7521
|
+
const batch = { events: sub.queue, dropped: sub.dropped };
|
|
7522
|
+
sub.queue = [];
|
|
7523
|
+
sub.dropped = 0;
|
|
7524
|
+
sub.waiting = true;
|
|
7525
|
+
sub.deliver(batch);
|
|
7526
|
+
});
|
|
7527
|
+
}
|
|
7528
|
+
};
|
|
7529
|
+
|
|
7454
7530
|
// src/body-idle.ts
|
|
7455
7531
|
var BODY_IDLE_MS = 5 * 60 * 1e3;
|
|
7456
7532
|
|
|
@@ -8130,7 +8206,7 @@ var UserDb = class {
|
|
|
8130
8206
|
};
|
|
8131
8207
|
|
|
8132
8208
|
// src/client/protocol.ts
|
|
8133
|
-
var PROTOCOL = [1,
|
|
8209
|
+
var PROTOCOL = [1, 15];
|
|
8134
8210
|
var FS_METHODS = [
|
|
8135
8211
|
"readFile",
|
|
8136
8212
|
"writeFile",
|
|
@@ -8297,9 +8373,21 @@ async function runAs(l, self, requested) {
|
|
|
8297
8373
|
function clientCred(self) {
|
|
8298
8374
|
return self ? credOf(self) : copyCred(ROOT);
|
|
8299
8375
|
}
|
|
8376
|
+
var MAX_SPAWN_TAGS = 8;
|
|
8377
|
+
function spawnTags(value2) {
|
|
8378
|
+
if (!Array.isArray(value2)) {
|
|
8379
|
+
tagOption(value2);
|
|
8380
|
+
return value2 === void 0 ? [] : [value2];
|
|
8381
|
+
}
|
|
8382
|
+
if (value2.length > MAX_SPAWN_TAGS) {
|
|
8383
|
+
throw new TypeError(`a spawn adds at most ${MAX_SPAWN_TAGS} tags`);
|
|
8384
|
+
}
|
|
8385
|
+
for (const each of value2) tagOption(each ?? 0);
|
|
8386
|
+
return value2;
|
|
8387
|
+
}
|
|
8300
8388
|
async function runTagged(l, self, options, tag, session = -1) {
|
|
8301
|
-
|
|
8302
|
-
const tags = withTag(
|
|
8389
|
+
let tags = withTag(void 0, tag);
|
|
8390
|
+
for (const added of spawnTags(options.tag)) tags = withTag(tags, added);
|
|
8303
8391
|
return {
|
|
8304
8392
|
user: await runAs(l, self, options.user),
|
|
8305
8393
|
tag,
|
|
@@ -8430,6 +8518,34 @@ async function watchOp(l, req, watches, send2, g) {
|
|
|
8430
8518
|
watches.set(req.id, unwatch);
|
|
8431
8519
|
return { result: req.id };
|
|
8432
8520
|
}
|
|
8521
|
+
function traceRegistry(send2) {
|
|
8522
|
+
const traces = /* @__PURE__ */ new Map();
|
|
8523
|
+
return {
|
|
8524
|
+
answer(l, self, req) {
|
|
8525
|
+
if (req.op === "untrace") {
|
|
8526
|
+
traces.get(req.trace)?.close();
|
|
8527
|
+
return { result: traces.delete(req.trace) };
|
|
8528
|
+
}
|
|
8529
|
+
if (typeof req.tag !== "string" || req.tag === "") {
|
|
8530
|
+
throw fsError("EINVAL", "trace: a tag is a non-empty string");
|
|
8531
|
+
}
|
|
8532
|
+
const limit = traceLimit(req.limit);
|
|
8533
|
+
const id2 = req.id;
|
|
8534
|
+
const deliver = ({ events, dropped: dropped2 }) => send2({ trace: id2, events, ...dropped2 > 0 ? { dropped: dropped2 } : {} });
|
|
8535
|
+
traces.set(id2, l.traces.subscribe(req.tag, credOf(self), deliver, limit));
|
|
8536
|
+
return { result: id2 };
|
|
8537
|
+
},
|
|
8538
|
+
ack(data) {
|
|
8539
|
+
if (typeof data.traceAck !== "number") return false;
|
|
8540
|
+
traces.get(data.traceAck)?.ack();
|
|
8541
|
+
return true;
|
|
8542
|
+
},
|
|
8543
|
+
close() {
|
|
8544
|
+
for (const trace of traces.values()) trace.close();
|
|
8545
|
+
traces.clear();
|
|
8546
|
+
}
|
|
8547
|
+
};
|
|
8548
|
+
}
|
|
8433
8549
|
var TRAITS_WATCH = -1;
|
|
8434
8550
|
function traitsWatch(launcher, transport, send2) {
|
|
8435
8551
|
return launcher.onTraits(() => send2({ traits: transport.traits }));
|
|
@@ -8456,6 +8572,21 @@ function requestBinding(send2, port) {
|
|
|
8456
8572
|
close: () => unbind?.()
|
|
8457
8573
|
};
|
|
8458
8574
|
}
|
|
8575
|
+
function answered(pending, req, reply, detach) {
|
|
8576
|
+
pending.then(
|
|
8577
|
+
({ result, signal, transfer }) => {
|
|
8578
|
+
reply(req.id, { result, ...signal ? { signal } : {} }, transfer);
|
|
8579
|
+
if (req.op === "detach") detach(req.kill === true);
|
|
8580
|
+
},
|
|
8581
|
+
(err) => {
|
|
8582
|
+
const code = err?.code;
|
|
8583
|
+
reply(req.id, {
|
|
8584
|
+
error: err instanceof Error ? err.message : String(err),
|
|
8585
|
+
...typeof code === "string" ? { code } : {}
|
|
8586
|
+
});
|
|
8587
|
+
}
|
|
8588
|
+
);
|
|
8589
|
+
}
|
|
8459
8590
|
function serveClient(port, host) {
|
|
8460
8591
|
let state = "new";
|
|
8461
8592
|
let self;
|
|
@@ -8471,6 +8602,7 @@ function serveClient(port, host) {
|
|
|
8471
8602
|
};
|
|
8472
8603
|
const reply = (id2, body, transfer) => send2({ id: id2, ...body }, transfer);
|
|
8473
8604
|
const hosts = hostRegistries(send2, ended.promise, port);
|
|
8605
|
+
const traces = traceRegistry(send2);
|
|
8474
8606
|
function detach(kill = false, bye = "the slicc-kernel detached this client") {
|
|
8475
8607
|
if (state === "closed") return;
|
|
8476
8608
|
send2({ bye });
|
|
@@ -8478,6 +8610,7 @@ function serveClient(port, host) {
|
|
|
8478
8610
|
net?.close();
|
|
8479
8611
|
for (const unwatch of watches.values()) unwatch();
|
|
8480
8612
|
watches.clear();
|
|
8613
|
+
traces.close();
|
|
8481
8614
|
hosts.close();
|
|
8482
8615
|
for (const session of terminals.values()) session.close();
|
|
8483
8616
|
terminals.clear();
|
|
@@ -8585,6 +8718,9 @@ function serveClient(port, host) {
|
|
|
8585
8718
|
case "serve-facade":
|
|
8586
8719
|
case "unserve-facade":
|
|
8587
8720
|
return { result: hosts.answer(l, req) };
|
|
8721
|
+
case "trace":
|
|
8722
|
+
case "untrace":
|
|
8723
|
+
return traces.answer(l, self, req);
|
|
8588
8724
|
case "detach":
|
|
8589
8725
|
return { result: true };
|
|
8590
8726
|
default:
|
|
@@ -8608,20 +8744,9 @@ function serveClient(port, host) {
|
|
|
8608
8744
|
net?.answer(data);
|
|
8609
8745
|
return;
|
|
8610
8746
|
}
|
|
8747
|
+
if (traces.ack(data)) return;
|
|
8611
8748
|
const req = data;
|
|
8612
|
-
handle(req)
|
|
8613
|
-
({ result, signal, transfer }) => {
|
|
8614
|
-
reply(req.id, { result, ...signal ? { signal } : {} }, transfer);
|
|
8615
|
-
if (req.op === "detach") detach(req.kill === true);
|
|
8616
|
-
},
|
|
8617
|
-
(err) => {
|
|
8618
|
-
const code = err?.code;
|
|
8619
|
-
reply(req.id, {
|
|
8620
|
-
error: err instanceof Error ? err.message : String(err),
|
|
8621
|
-
...typeof code === "string" ? { code } : {}
|
|
8622
|
-
});
|
|
8623
|
-
}
|
|
8624
|
-
);
|
|
8749
|
+
answered(handle(req), req, reply, detach);
|
|
8625
8750
|
});
|
|
8626
8751
|
port.addEventListener("close", () => detach());
|
|
8627
8752
|
port.start?.();
|
|
@@ -8779,7 +8904,7 @@ function satisfies(version, range2) {
|
|
|
8779
8904
|
}
|
|
8780
8905
|
|
|
8781
8906
|
// src/version.ts
|
|
8782
|
-
var KERNEL_VERSION = true ? "1.
|
|
8907
|
+
var KERNEL_VERSION = true ? "1.180.0" : "0.0.0-dev";
|
|
8783
8908
|
var OS_RELEASE = "6.0.0-slicc";
|
|
8784
8909
|
function procVersion() {
|
|
8785
8910
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -30069,6 +30194,9 @@ var JobTable = class {
|
|
|
30069
30194
|
idOf(pid) {
|
|
30070
30195
|
return this.members.get(pid)?.shownAs ?? pid;
|
|
30071
30196
|
}
|
|
30197
|
+
execParentOf(pid) {
|
|
30198
|
+
return this.members.get(pid)?.execParent;
|
|
30199
|
+
}
|
|
30072
30200
|
byId(id2) {
|
|
30073
30201
|
for (const member of this.members.values()) if (member.shownAs === id2) return member;
|
|
30074
30202
|
return this.member(id2);
|
|
@@ -35283,10 +35411,12 @@ var Launcher = class {
|
|
|
35283
35411
|
});
|
|
35284
35412
|
const fit = await (handle.ready ?? true);
|
|
35285
35413
|
if (fit) {
|
|
35414
|
+
this.traceAdmitted(handle.pid, true);
|
|
35286
35415
|
await fds.closeAll();
|
|
35287
35416
|
return handle;
|
|
35288
35417
|
}
|
|
35289
35418
|
await handle.exited;
|
|
35419
|
+
this.traceAdmitted(handle.pid, false);
|
|
35290
35420
|
await this.memories.refused().catch(async (err) => {
|
|
35291
35421
|
await fds.closeAll();
|
|
35292
35422
|
throw err;
|
|
@@ -35417,10 +35547,12 @@ var Launcher = class {
|
|
|
35417
35547
|
if (req.group === "lead") this.jobs.lead(pid);
|
|
35418
35548
|
if (req.group === "session") this.jobs.setsid(pid);
|
|
35419
35549
|
this.described.set(pid, describe(req, terminal?.name ?? null));
|
|
35550
|
+
this.traceStarted(pid, req);
|
|
35420
35551
|
handle.onState(
|
|
35421
35552
|
(state) => state === "stopped" ? this.stopped.add(pid) : this.stopped.delete(pid)
|
|
35422
35553
|
);
|
|
35423
|
-
void handle.exited.then(() => {
|
|
35554
|
+
void handle.exited.then((status) => {
|
|
35555
|
+
this.traceEnded(pid, handle, status);
|
|
35424
35556
|
this.cwds.release(this.cwdSlots.get(pid));
|
|
35425
35557
|
this.cwdSlots.delete(pid);
|
|
35426
35558
|
this.cwdPaths.delete(pid);
|
|
@@ -35535,6 +35667,71 @@ var Launcher = class {
|
|
|
35535
35667
|
imageTimes = /* @__PURE__ */ new Map();
|
|
35536
35668
|
childTimes = /* @__PURE__ */ new Map();
|
|
35537
35669
|
stopped = /* @__PURE__ */ new Set();
|
|
35670
|
+
traces = new TraceHub();
|
|
35671
|
+
traceHeld = /* @__PURE__ */ new Map();
|
|
35672
|
+
replacedImages = /* @__PURE__ */ new Set();
|
|
35673
|
+
traceStarted(pid, req) {
|
|
35674
|
+
const replaces = req.exec ? req.ppid : void 0;
|
|
35675
|
+
if (req.quietOom) this.traceHeld.set(pid, { replaces, events: [] });
|
|
35676
|
+
else if (replaces !== void 0) this.replacedImages.add(replaces);
|
|
35677
|
+
this.traceEmit(pid, () => {
|
|
35678
|
+
const { pid: shown2, ppid } = this.identityOf(pid);
|
|
35679
|
+
const described2 = this.described.get(pid);
|
|
35680
|
+
const { argv, started, tty: _tty, exeId: _exeId, ...exe } = described2;
|
|
35681
|
+
return {
|
|
35682
|
+
type: req.fork ? "fork" : "exec",
|
|
35683
|
+
pid: shown2,
|
|
35684
|
+
ppid,
|
|
35685
|
+
pgid: this.jobs.pgidOf(pid),
|
|
35686
|
+
argv: [...argv],
|
|
35687
|
+
...exe,
|
|
35688
|
+
uid: this.credOf(pid).euid,
|
|
35689
|
+
at: started,
|
|
35690
|
+
...req.exec ? { replaced: true } : {}
|
|
35691
|
+
};
|
|
35692
|
+
});
|
|
35693
|
+
}
|
|
35694
|
+
traceEnded(pid, handle, status) {
|
|
35695
|
+
if (this.replacedImages.delete(pid)) return;
|
|
35696
|
+
this.traceEmit(pid, () => ({
|
|
35697
|
+
type: "exit",
|
|
35698
|
+
pid: this.jobs.idOf(pid),
|
|
35699
|
+
status,
|
|
35700
|
+
...signalField(handle.termsig()),
|
|
35701
|
+
...this.chainTimes(pid),
|
|
35702
|
+
at: Date.now()
|
|
35703
|
+
}));
|
|
35704
|
+
}
|
|
35705
|
+
traceEmit(pid, build) {
|
|
35706
|
+
if (this.traces.idle) return;
|
|
35707
|
+
const tags = this.tagsOf(pid);
|
|
35708
|
+
const cred = this.credOf(pid);
|
|
35709
|
+
if (!this.traces.wants(tags, cred)) return;
|
|
35710
|
+
const held = this.traceHeld.get(pid);
|
|
35711
|
+
if (held) held.events.push({ tags, cred: copyCred(cred), draft: build() });
|
|
35712
|
+
else this.traces.publish(tags, cred, build());
|
|
35713
|
+
}
|
|
35714
|
+
traceAdmitted(pid, fit) {
|
|
35715
|
+
const held = this.traceHeld.get(pid);
|
|
35716
|
+
if (!held) return;
|
|
35717
|
+
this.traceHeld.delete(pid);
|
|
35718
|
+
if (!fit) return;
|
|
35719
|
+
if (held.replaces !== void 0) this.replacedImages.add(held.replaces);
|
|
35720
|
+
for (const { tags, cred, draft } of held.events) this.traces.publish(tags, cred, draft);
|
|
35721
|
+
}
|
|
35722
|
+
chainTimes(pid) {
|
|
35723
|
+
let utime = 0;
|
|
35724
|
+
let stime = 0;
|
|
35725
|
+
let timed2 = false;
|
|
35726
|
+
for (let at = pid; at !== void 0; at = this.jobs.execParentOf(at)) {
|
|
35727
|
+
const t = this.timesAt(at);
|
|
35728
|
+
if (!t) continue;
|
|
35729
|
+
timed2 = true;
|
|
35730
|
+
utime += t.utime;
|
|
35731
|
+
stime += t.stime;
|
|
35732
|
+
}
|
|
35733
|
+
return timed2 ? { utime, stime } : {};
|
|
35734
|
+
}
|
|
35538
35735
|
stateOf(pid) {
|
|
35539
35736
|
if (!this.processes.has(pid)) return "Z";
|
|
35540
35737
|
return this.stopped.has(pid) ? "T" : "S";
|
|
@@ -37061,7 +37258,7 @@ function sudoApprovals(port) {
|
|
|
37061
37258
|
}
|
|
37062
37259
|
};
|
|
37063
37260
|
}
|
|
37064
|
-
function
|
|
37261
|
+
function answered2(data, remote, uplink, approvals) {
|
|
37065
37262
|
if (data.sudoAnswer) approvals.answer(data.sudoAnswer);
|
|
37066
37263
|
else if (data.net !== void 0) remote?.receive(data);
|
|
37067
37264
|
else if (typeof data.uplink === "string") uplink?.receive(data);
|
|
@@ -37346,7 +37543,7 @@ function serveKernel(port, deps) {
|
|
|
37346
37543
|
const grant = event.data.hostfsGrant;
|
|
37347
37544
|
if (grant) return granted2(grant);
|
|
37348
37545
|
if (allowed(event.data)) return;
|
|
37349
|
-
if (
|
|
37546
|
+
if (answered2(event.data, remote, uplink, approvals)) return;
|
|
37350
37547
|
const req = event.data;
|
|
37351
37548
|
handle(req).then(
|
|
37352
37549
|
(result) => reply(req.id, { result }, transferOf2(req, result)),
|