78 lines
1.9 KiB
JavaScript
78 lines
1.9 KiB
JavaScript
/**
|
|
* Declarative kernel boot stage graph for `/proc/bare_os/boot_graph.json`.
|
|
* Mirrors the default sequence in kernel/init (trusted boot path).
|
|
*/
|
|
|
|
const DEFAULT_BOOT_STAGES = Object.freeze([
|
|
'boot.policy',
|
|
'os-release',
|
|
'motd',
|
|
'rc.profile',
|
|
'rc',
|
|
'rc.d',
|
|
'rc.local',
|
|
'kernel.d',
|
|
'kernel.ext.d',
|
|
'banner',
|
|
'onboot',
|
|
'selftest'
|
|
])
|
|
|
|
/**
|
|
* @param {{ bootReadyJson?: () => string, stageMsHistogram?: Record<string, number> }} [opts]
|
|
*/
|
|
export function buildBareOsBootGraphProcJson(opts = {}) {
|
|
const nodes = DEFAULT_BOOT_STAGES.map((id, i) => ({
|
|
id,
|
|
order: i,
|
|
bootStage: bootStageForKernelLabel(id)
|
|
}))
|
|
/** @type {{ from: string, to: string, kind: string }[]} */
|
|
const edges = []
|
|
for (let i = 0; i < nodes.length - 1; i++) {
|
|
edges.push({
|
|
from: nodes[i].id,
|
|
to: nodes[i + 1].id,
|
|
kind: 'sequence'
|
|
})
|
|
}
|
|
let ready = {}
|
|
try {
|
|
const t =
|
|
opts.bootReadyJson && typeof opts.bootReadyJson === 'function'
|
|
? opts.bootReadyJson()
|
|
: ''
|
|
ready = t ? JSON.parse(String(t).trim() || '{}') : {}
|
|
} catch {
|
|
ready = {}
|
|
}
|
|
const hist =
|
|
opts.stageMsHistogram && typeof opts.stageMsHistogram === 'object'
|
|
? opts.stageMsHistogram
|
|
: {}
|
|
return {
|
|
schema: 1,
|
|
note: 'Kernel boot stage edges (declarative); latency histogram is populated when journal export is enabled.',
|
|
nodes,
|
|
edges,
|
|
stageMsHistogram: hist,
|
|
bootReady: ready,
|
|
atMs: Date.now()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} label
|
|
*/
|
|
function bootStageForKernelLabel(label) {
|
|
const s = String(label || '').toLowerCase()
|
|
if (s === 'boot.policy') return 'policy'
|
|
if (s === 'os-release' || s === 'motd') return 'preflight'
|
|
if (s.startsWith('rc') || s === 'kernel.d' || s === 'kernel.ext.d')
|
|
return 'rc'
|
|
if (s === 'onboot') return 'onboot'
|
|
if (s.includes('selftest')) return 'selftest'
|
|
if (s.includes('repl') || s.includes('banner')) return 'shell'
|
|
return 'other'
|
|
}
|