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
| Phase | Service | Socket | Status |
|---|---|---|---|
| 0 | kernel IPC infrastructure | blocking AF_UNIX, socketpair, SCM_RIGHTS, SO_PEERCRED, /dev/shm0, AF_INET fd path | implemented |
| 1 | windowd | /run/leonos/windowd.sock | implemented |
| 2 | imd | /run/leonos/input-method.sock | implemented |
| 3 | sessiond | /run/leonos/session.sock | implemented |
| 4 | devmand (device-agent) | /run/leonos/devman.sock | implemented |
| 5 | procfs | /proc | implemented |
| 6 | fd-3 removal and cleanup | n/a | implemented |
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
| Message | Direction | Fields | Permission |
|---|---|---|---|
HELLO | client -> server | u32 client_pid | SO_PEERCRED match |
ERROR | server -> client | s32 code | any |
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.
| Message | Direction | Fields | Permission |
|---|---|---|---|
HELLO | app -> windowd | u32 pid, u32 role | SO_PEERCRED pid match |
HELLO_ACK | windowd -> client | u32 version | any |
POLICY_HELLO | desktop -> windowd | u32 pid, token[32] | uid==0 + token |
CREATE | app -> windowd | u32 width,height,flags, title[48], text[1024] | app connection |
CREATE_ACK | windowd -> app | u32 win_id,width,height,stride + SCM_RIGHTS shm fd | any |
DESTROY | app -> windowd | u32 window_id | owner |
PRESENT | app -> windowd | u32 win_id,width,height,stride | owner |
UPDATE | app -> windowd | u32 win_id,mask,flags, title[48] | owner |
FETCH | desktop -> windowd | u32 win_id,cap_w,cap_h,stride | policy |
FETCH_ACK | windowd -> desktop | u32 win_id,width,height,stride + SCM_RIGHTS shm fd | policy |
EVENT | desktop -> windowd -> app | struct leonos_gui_app_event | policy sender, target by win_id |
INPUT | windowd -> desktop | struct leonos_input_event | policy |
WINDOW_NOTIFY | windowd -> desktop | struct leonos_gui_window_msg types 1..7 | policy |
MOUSE_VISIBLE | app/desktop <-> windowd | u32 win_id,visible | query uses win_id=0xffffffff |
CURSOR_REQUEST/CURSOR_REGION | app -> windowd -> desktop | gui cursor structs | any app |
DISPLAY_STATE/APPEARANCE_STATE | publisher/query | gui state structs | policy publishes; app queries |
DISPLAY_REQUEST/APPEARANCE_REQUEST | app -> windowd -> desktop | gui request structs | policy 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)
| Message | Direction | Fields | Permission |
|---|---|---|---|
HELLO | client -> sessiond | u32 pid,uid | SO_PEERCRED match |
ACK | sessiond -> client | s32 code,u32 request_id | any |
REQUEST | client -> sessiond | struct leonos_startup_command | uid!=0 |
REQUEST_STATUS | client -> sessiond | request_id | any |
DIALOG_GET/RESOLVE | client -> sessiond | request_id/decision | any |
LIST/SET_ENABLED/REMOVE | client -> sessiond | startup entry records | uid owner |
LAUNCH_CURRENT | client -> sessiond | none | current session; child is setuid |
devmand (/run/leonos/devman.sock, the device-agent.elf service)
| Message | Direction | Fields | Permission |
|---|---|---|---|
HELLO | client -> devmand | u32 pid,uid | SO_PEERCRED match |
ACK | devmand -> client | s32 code,u32 count | any |
DEVICE_LIST | client -> devmand | capacity -> count + struct leonos_device_info[] | any |
DRIVER_LIST | client -> devmand | capacity -> count + struct leonos_driver_info[] | any |
DRIVER_CONTROL | client -> devmand | action/file | SO_PEERCRED uid==0 |
Phase 6 cleanup
- The fd 3 control-descriptor mechanism and every private service-request ioctl family are deleted from kernel and libc source.
- Remaining ioctls are device-UAPI only: TTY termios/winsize, evdev, OSS, block BLK, fbdev FBIO, and
/dev/gpuGPU commands. - ACL compatibility is expressed through
chmod/chown; kernel-debug state uses/var/lib/leonos/kernel-debug.
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)
| Message | Direction | Fields | Permission |
|---|---|---|---|
HELLO | client -> imd | u32 pid, u32 role(app/provider) | SO_PEERCRED pid match |
ACK | imd -> client | s32 code | any |
REGISTER | provider -> imd | struct leonos_inputm_provider | uid!=0 |
UNREGISTER | provider -> imd | none | provider connection |
KEY_EVENT | imd -> provider | struct leonos_inputm_key_event | active provider |
SUBMIT_KEY | app -> imd | struct leonos_inputm_key_event (window_id/keycode/pressed) | focused context |
RESULT | provider -> imd; imd -> app | struct leonos_inputm_result | provider / target app |
SET_CONTEXT | app -> imd | struct leonos_inputm_context | owning pid |
SET_ACTIVE/GET_STATE/LIST/NOTIFY_CONFIG | app -> imd | uid + id / provider array / state | uid 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
| Phase | New service | New protocol files | Removed kernel files | Removed macro families |
|---|---|---|---|---|
| 0 | kernel IPC | unix_ipc.h/c, syscall_socket.c blocking, shm.c | none | none (added syscalls) |
| 1 | windowd | windowd.h, wind.c, apps/windowd/ | gui_ipc.c, gui_ipc.h | LEONOS_GUI_IOCTL_* |
| 2 | imd | inputmd.h, apps/imd/ | inputm.c ioctls, /dev/input-method node | LEONOS_INPUTM_IOCTL_* |
| 3 | (no daemon) | netsock.c | none; net ioctls replaced by LEONOS_NET_CONTROL_IOCTL on AF_INET fds + OpenRC services | LEONOS_IOCTL_NET_* |
| 4 | sessiond | sessiond.h, apps/sessiond/, sessiond_client.c | none (syscall branches removed); authd never shipped — accounts moved to PAM | LEONOS_AUTH_IOCTL_, LEONOS_STARTUP_IOCTL_ |
| 5 | devmand (device-agent) | devmand.h, apps/device-agent/, devmand_client.c, procfs.c, procsys.c | none (/dev/hwinfo removed; /dev/driverctl retained as kernel-internal admin ioctl) | device/driver/system/time/machine/perf/affinity ioctls |
| 6 | n/a | security/ABI/path tools | legacy ACL/signal/text/audio/PTY/kernel-debug branches | remaining 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).