Re: rcd(8) - new service manager daemon

hackee <[email protected]> Wed, 17 Jun 2026 11:23:00 +0000
Newsgroups gmane.os.freebsd.devel.hackers
Message-ID <4ql1C4GIt0xEItg5UNq6B3LGgVlvsZUE6ckiHU95v0SKxb6RtF2_RlaYKzb0xDhALOF3j1PBiW0fgfOUlJWwMJRAHB1CV9fTJyseMYlJfzY=@proton.me>
Hi.
As for me, I don't care, I wrote my own init scripts (mksh based) and use them. Boot time is about 7.5 seconds.
BR. 

> Hi,
> 
> This is honestly great! I must admit the long bootup times - while
> *fine* - have always been kind of annoying, and having something
> backwards-compatible that improves on that (and, I assume, is generally
> more modern) is very appealing to me. I will be testing it ASAP.
> 
> Do you have an estimate as to how much time is saved from specifically
> the parallelisation?
> 
> Warm regards,
> Céleste
> 
> Baptiste Daroussin <[email protected]> writes:
> 
> > Hello everyone
> >
> > I have been working for the past years on rcd(8), a new service manager
> > daemon for FreeBSD, some of you might recall a presentation in french 15
> > years ago or some discussion in BSDcam also that old!
> > I would like to start a discussion about its integration into the tree.
> >
> > What is rcd?
> >
> > rcd(8) is a service manager daemon called by init(8) (in place of
> > /etc/rc).  It reads service definitions from UCL unit files
> > (/etc/rcd.d/*.ucl), builds a dependency DAG, and starts services in
> > parallel.  After boot completes, it forks to background and stays
> > running as a supervision daemon (automatically restarting failed
> > services and accepting control commands via a UNIX socket).
> >
> > Key features:
> >
> >   - Parallel boot via dependency DAG (no more serial rc.d execution)
> >   - Process tracking via pdfork(2) descriptors (no PID file races)
> >   - Subreaper via procctl(2) (no orphaned process escape)
> >   - Socket activation (pre-bound sockets passed via fd inheritance)
> >   - Resource control per service via rctl(2)
> >   - Service isolation via native jail(2) integration
> >   - OOM protection via procctl(2) PROC_SPROTECT
> >   - UCL-based unit files (JSON Schema validated)
> >   - Embedded Lua interpreter for inline service hooks
> >   - Template units for per-instance services (e.g., dhclient@em0)
> >   - Safe in-place binary upgrade (SIGUSR1: save state, re-exec)
> >   - Per-service access control on the control socket
> >   - Suspend/resume support
> >
> > User interface: rcctl(8)
> >
> > Service management is done via rcctl(8):
> >
> >     rcctl start sshd
> >     rcctl enable sshd
> >     rcctl restart dhclient@em0 netif@em1
> >     rcctl status
> >     rcctl show nginx
> >
> > 100% backward compatibility
> >
> > This is a hard requirement: rcd must work on existing FreeBSD systems
> > without modifying any rc.d scripts or configuration files.  Here is how
> > this is achieved:
> >
> >   1) rcd scans /etc/rc.d/ and /usr/local/etc/rc.d/ for existing
> >      rc.d scripts, parses their PROVIDE/REQUIRE/BEFORE/KEYWORD headers
> >      (same format as rcorder(8)), reads rc.conf(5) to determine the
> >      enabled state, and wraps each script as a virtual "legacy" unit
> >      in the dependency graph.
> >
> >   2) Legacy scripts are auto-classified during loading:
> >      - Scripts with pidfile= or command= -> "legacy-forking" units,
> >        tracked by rcd-exec(8) sub-reaper without pidfiles.
> >      - Scripts with only comments/blank lines -> barrier units.
> >      - Scripts without rcvar= are always enabled.
> >
> >   3) All rcctl(8) commands are passed through to the script directly:
> >          rcctl reload sshd -> /bin/sh /etc/rc.d/sshd reload
> >
> >   4) Template instances preserve the traditional calling convention:
> >          rcctl restart netif@em0 netif@em1
> >          -> /bin/sh /etc/rc.d/netif restart em0 em1
> >
> >   5) rcd reads /etc/defaults/rc.conf, /etc/rc.conf and
> >      /etc/rc.conf.local to determine legacy service enablement.
> >
> > The result: you can install rcd on a running system, reboot, and
> > everything works exactly as before -- except boot is faster because
> > services start in parallel where the dependency graph allows.
> >
> > Current status and what I need
> >
> > I would like to commit this to main soon so that people can start
> > testing it on their machines.  The initial commit will include:
> >
> >   - sbin/rcd/   -- the daemon, rcd-exec helper, unit tests
> >   - sbin/rcctl/ -- the control utility
> >   - Man pages: rcd.8, rcctl.8, rcd.conf.5, rcd.d.5, rcd-lua.3,
> >     rcd-exec.8
> >
> > It will NOT change init(8) or /etc/rc yet.  rcd will be built and
> > installed but not activated by default.  To test, you will be able to
> > run it manually or configure via kenv(8) to replace /etc/rc.
> >
> > Migration path
> >
> > The plan for a smooth transition:
> >
> > - 1 (now): Commit rcd(8) and rcctl(8) to the tree.  Build by
> >   default, but not activated.  Early adopters can test.
> >
> > - 2 (later): Commit init(8) changes to call rcd when present (falling
> >   back to /etc/rc otherwise).  Provide a /etc/rc wrapper that invokes
> >   rcd for systems that want to switch.
> >
> > - In the meantime: convert base system rc.d scripts to native
> >   UCL unit files adding the norcd keywords to the rc.d so that they
> >   are not read anymore by rcd(8).
> >
> > - Ultimately: rc.d -> unit files, at the pace each maintainer sees fit.
> >   There is no deadline; rc.d scripts are supported as long as needed.
> >
> > The code lives there:
> > https://reviews.freebsd.org/D56835
> >
> > Baptiste
> 
>