vsock communication
The channelβ
The channel between host and guest is a vsock (the job VM does not even have a network):
- the guest listens on vsock port 5000;
- on the host,
krun_add_vsock_port2withlisten=truebinds that port to a Unix socket in a working directory inside the cache; - the host connects to that Unix socket like any local socket.
There is no text handshake: the connection on the Unix socket already reaches the guest.
Message formatβ
Every message, in both directions, is:
+------------------------+----------------------+
| length (4 bytes, BE) | JSON payload (UTF-8) |
+------------------------+----------------------+
- The length is a 4-byte unsigned integer, big-endian, and counts only the payload.
- The maximum frame is 64 MiB; the host refuses to read a frame above that.
The same frame serves every operation: the ephemeral job and the machine operations (exec, file copy, terminal,
workload, published port, secrets, SSH agent, S3), selected by the job's op field.
Sequenceβ
host guest
β connect(Unix socket) ββββββββββββββΆ accept (vsock 5000)
β [length][Job JSON] ββββββββββββββββΆ runs
β ββββββββββββββββ [length][Result JSON]
β closes; the job VM is destroyed
Readinessβ
libkrun creates the Unix socket before the guest starts listening, so a successful connection does not prove the guest is ready. The readiness wait sends an sh true job every 1 ms until it gets a response. Only after that does the VM receive real jobs.
Payloadsβ
- Job:
{trace_id, lang, code, files[{name, content}], stdin, timeout}β see Job request. - Result:
{trace_id, status, stdout, stderr, exception, executionTime, exit_code, error}β see Job response.
Byte-by-byte details in vsock protocol.