LeonOS Documentation

LeonOS Unix IPC protocol

This document is the normative wire contract for the LeonOS service sockets. All paths live below /run/leonos/. Every service uses an AF_UNIX SOCK_STREAM connection and the length-prefixed framing described below.

Framing


u32 magic  = 'LNXU' (0x554e4c4c on little-endian x86_64)
u32 version = 1
repeat:
  u32 length
  u8  payload[length]

All integers are little-endian. A client opens one connection and issues a HELLO message first. The server uses SO_PEERCRED to learn the peer {pid, uid, gid}; the pid in HELLO must match the kernel-reported peer pid or the connection is rejected with ERROR{code=EPERM}.

Status

PhaseServiceSocketStatus
0kernel IPC infrastructureblocking AF_UNIX, socketpair, SCM_RIGHTS, SO_PEERCRED, /dev/shm0, AF_INET fd pathimplemented
1windowd/run/leonos/windowd.sockimplemented
2imd/run/leonos/input-method.sockimplemented
3sessiond/run/leonos/session.sockimplemented
4devmand (device-agent)/run/leonos/devman.sockimplemented
5procfs/procimplemented
6fd-3 removal and cleanupn/aimplemented

The four daemons run as independent OpenRC services (system/rootfs/etc/init.d/leonos-{windowd,imd,session,device}). There is no netmand or authd socket service: network control is a kernel ioctl on AF_INET fds (LEONOS_NET_CONTROL_IOCTL) with DHCP/NTP lifecycle owned by the leonos-dhcp/leonos-ntp OpenRC services, and accounts are standard /etc/passwd + /etc/shadow files authenticated through PAM.

Common message set

MessageDirectionFieldsPermission
HELLOclient -> serveru32 client_pidSO_PEERCRED match
ERRORserver -> clients32 codeany

windowd (/run/leonos/windowd.sock)

The userspace windowd daemon owns the window registry. Pixel storage is a /dev/shm0 segment per window and crosses the socket only as an SCM_RIGHTS fd. Desktop connects with the policy handshake token desktop-policy-v1; the kernel SO_PEERCRED uid must be zero.

MessageDirectionFieldsPermission
HELLOapp -> windowdu32 pid, u32 roleSO_PEERCRED pid match
HELLO_ACKwindowd -> clientu32 versionany
POLICY_HELLOdesktop -> windowdu32 pid, token[32]uid==0 + token
CREATEapp -> windowdu32 width,height,flags, title[48], text[1024]app connection
CREATE_ACKwindowd -> appu32 win_id,width,height,stride + SCM_RIGHTS shm fdany
DESTROYapp -> windowdu32 window_idowner
PRESENTapp -> windowdu32 win_id,width,height,strideowner
UPDATEapp -> windowdu32 win_id,mask,flags, title[48]owner
FETCHdesktop -> windowdu32 win_id,cap_w,cap_h,stridepolicy
FETCH_ACKwindowd -> desktopu32 win_id,width,height,stride + SCM_RIGHTS shm fdpolicy
EVENTdesktop -> windowd -> appstruct leonos_gui_app_eventpolicy sender, target by win_id
INPUTwindowd -> desktopstruct leonos_input_eventpolicy
WINDOW_NOTIFYwindowd -> desktopstruct leonos_gui_window_msg types 1..7policy
MOUSE_VISIBLEapp/desktop <-> windowdu32 win_id,visiblequery uses win_id=0xffffffff
CURSOR_REQUEST/CURSOR_REGIONapp -> windowd -> desktopgui cursor structsany app
DISPLAY_STATE/APPEARANCE_STATEpublisher/querygui state structspolicy publishes; app queries
DISPLAY_REQUEST/APPEARANCE_REQUESTapp -> windowd -> desktopgui request structspolicy receives

Accounts and authentication (no socket service)

Authentication has no AF_UNIX protocol. Accounts are standard /etc/passwd//etc/shadow records (Alpine shadow packaging) and login, password change, and elevation run through the PAM stack: login.elf calls leonos_pam_login(), su/sudo use the upstream binaries with sudoers/PAM policy (the sudod.elf askpass helper supports the legacy leonos_sudo_ libc API), and pam_leonos_password is the LeonOS-specific verifier module. The leonos_auth_ libc wrappers in userland/libc/src/auth_accounts.c read the passwd database directly with getpwuid-style calls; mutating operations run the standard tools as root or require the caller's own uid.

sessiond (/run/leonos/session.sock)

MessageDirectionFieldsPermission
HELLOclient -> sessiondu32 pid,uidSO_PEERCRED match
ACKsessiond -> clients32 code,u32 request_idany
REQUESTclient -> sessiondstruct leonos_startup_commanduid!=0
REQUEST_STATUSclient -> sessiondrequest_idany
DIALOG_GET/RESOLVEclient -> sessiondrequest_id/decisionany
LIST/SET_ENABLED/REMOVEclient -> sessiondstartup entry recordsuid owner
LAUNCH_CURRENTclient -> sessiondnonecurrent session; child is setuid

devmand (/run/leonos/devman.sock, the device-agent.elf service)

MessageDirectionFieldsPermission
HELLOclient -> devmandu32 pid,uidSO_PEERCRED match
ACKdevmand -> clients32 code,u32 countany
DEVICE_LISTclient -> devmandcapacity -> count + struct leonos_device_info[]any
DRIVER_LISTclient -> devmandcapacity -> count + struct leonos_driver_info[]any
DRIVER_CONTROLclient -> devmandaction/fileSO_PEERCRED uid==0

Phase 6 cleanup

procfs (kernel, read-only)

/proc/uptime, /proc/meminfo, /proc/version, /proc/machine-id, /proc/<pid>/stat, /proc/<pid>/cmdline, and /proc/self/* are synthetic storage nodes. They are read through ordinary open/read/readdir and are never served through a private ioctl.

Networking (no socket service)

There is no netmand daemon. Read-only network status queries use the kernel's LEONOS_NET_CONTROL_IOCTL (include/uapi/leonos/net_control.h) on an AF_INET socket fd, credential-checked in the kernel. Configuration changes are lifecycle operations of the OpenRC services leonos-dhcp (udhcpc, hook publishes /run/leonos/dhcp-lease) and leonos-ntp (hook publishes /run/leonos/ntp-state); the leonos_net_dhcp_renew()/ leonos_time_ntp_sync() libc helpers restart those services and validate the published files.

imd (/run/leonos/input-method.sock)

MessageDirectionFieldsPermission
HELLOclient -> imdu32 pid, u32 role(app/provider)SO_PEERCRED pid match
ACKimd -> clients32 codeany
REGISTERprovider -> imdstruct leonos_inputm_provideruid!=0
UNREGISTERprovider -> imdnoneprovider connection
KEY_EVENTimd -> providerstruct leonos_inputm_key_eventactive provider
SUBMIT_KEYapp -> imdstruct leonos_inputm_key_event (window_id/keycode/pressed)focused context
RESULTprovider -> imd; imd -> appstruct leonos_inputm_resultprovider / target app
SET_CONTEXTapp -> imdstruct leonos_inputm_contextowning pid
SET_ACTIVE/GET_STATE/LIST/NOTIFY_CONFIGapp -> imduid + id / provider array / stateuid owner or uid==0

Phase 0 verification

Run /usr/lib/leonos/apps/ipctest/ipctest.elf on the target. It covers blocking socketpair reads, SCM_RIGHTS passing of a /dev/shm0 descriptor, shared mmap, credential syscalls, uname, and an AF_INET connect probe.

Migration status

PhaseNew serviceNew protocol filesRemoved kernel filesRemoved macro families
0kernel IPCunix_ipc.h/c, syscall_socket.c blocking, shm.cnonenone (added syscalls)
1windowdwindowd.h, wind.c, apps/windowd/gui_ipc.c, gui_ipc.hLEONOS_GUI_IOCTL_*
2imdinputmd.h, apps/imd/inputm.c ioctls, /dev/input-method nodeLEONOS_INPUTM_IOCTL_*
3(no daemon)netsock.cnone; net ioctls replaced by LEONOS_NET_CONTROL_IOCTL on AF_INET fds + OpenRC servicesLEONOS_IOCTL_NET_*
4sessiondsessiond.h, apps/sessiond/, sessiond_client.cnone (syscall branches removed); authd never shipped — accounts moved to PAMLEONOS_AUTH_IOCTL_, LEONOS_STARTUP_IOCTL_
5devmand (device-agent)devmand.h, apps/device-agent/, devmand_client.c, procfs.c, procsys.cnone (/dev/hwinfo removed; /dev/driverctl retained as kernel-internal admin ioctl)device/driver/system/time/machine/perf/affinity ioctls
6n/asecurity/ABI/path toolslegacy ACL/signal/text/audio/PTY/kernel-debug branchesremaining private ioctl macros

Legacy application exports (leonos_gui_, leonos_auth_, leonos_net_, text_input_, leonos_startup_*, device/driver/system helpers) remain in libleonos with unchanged signatures; only their transport changed (windowd / imd / sessiond / devmand sockets, PAM-backed account reads, or AF_INET sockets plus the net control ioctl).