This package provides a full system-management, service-management, terminal-management, and logging toolset for BSDs and for Linux.
The basic design elements of the package are these:
The filesystem is the database. The service management system is arranged around service bundles. Everything about a service bundle, including its interrelationships with other bundles, is stored in the filesystem. Bootstrap milestones/targets are just more service bundles, in the filesystem.
The filesystem is the API. The control/status API of the service manager is a suite of FIFOs and ordinary files in the filesystem. Similarly, the I/O interfaces between components of the user-space virtual terminal system are FIFOs and ordinary files in the filesystem.
As little parsing should be done at run-time as possible.
Parsers are common security vulnerabilities, time sinks, or just plain old sources of bugs.
Parsing of things such as human-readable configuration files is done at configuration, or reconfiguration, time; not at run-time.
A special simplified "non-shell" scripting language — that has no overheads relating to "rc" files, interactive modes, complex grammars, or shell variables — is supplied for writing dæmon run
programs.
dæmons are run, not spawned. The program that is configured in a service bundle is expected to be the dæmon, not to spawn it.
dæmons are insulated from one another using ordinary multi-user operating system facilities. dæmon processes run under the aegises of different user accounts, They thus cannot signal, debug, or otherwise directly affect one another. Compromised main dæmons cannot rewrite, and may not even be able to access, their own logs. Compromised log dæmon accounts don't lead to all logs being compromised, or to compromise of main dæmons.
Ownership of files and directories is a permission, and it isn't always granted. It is the permission to grant other permissions. Logging dæmons run under dedicated user accounts that only own the log files, but don't own the log directories. Compromised log dæmon accounts cannot grant direct access to confidential log files by altering (normally restricted) log directory access permissions. Some dæmon user accounts own no files nor directories at all, and so have no ability to grant permissions.
Process state is constructed with small chain-loading tools.
The toolset for doing things like dropping superuser privileges to running as an ordinary user comprises a suite of small, simple to audit, tools that use the operating system's execve()
function to execute the next program in the chain.
As an optimization, eliminating the startup and teardown cost of the runtime libraries in programs whose actual function is often a mere handful of system calls, several chain loading tools can execute directly from one to the next, using a simple-to-audit "built in commands" mechanism.
Bootstrap time is not build again and again time. There is no repeated building of things, over and over again at bootstrap time, that can be built once and then stored in the filesystem to be re-used without further ado.
Service run time is not the place for package management tasks. If, for example, a package needs a dedicated user account for a service, the right way to do this is to allocate once it at package installation and deallocate it at package deinstallation. The wrong way is making the service allocate the ID and recursively update the ownerships and ACLs of files and directories, over and over again with every run of the service.
The primary foreign configuration formats are systemd units and BSD databases.
The world is already, independently, doing the work of replacing Linux "System 5" rc
scripts, and has been since 2011.
Nowadays, "other people's stuff" comes with systemd units.
Likewise, replacing the Mewburn rc
scripts has been a large part of the nosh project and the majority is now replaced with service bundles and a mechanism for generating service bundles from the BSD databases such as /etc/fstab
and /etc/rc.conf
.
Those are therefore the primary foreign configuration file formats that are addressed by conversion/import tools.
Here are some of the distinctive major features where the system is different by design from existing systems.
System bootstrap only runs the enabled services.
The Mewburn rc
mechanism always runs every shell script, relying upon shell scripts to disable themselves when they see a foo_enable=NO
shell variable.
nosh simply doesn't run disabled services at all at boot time.
No in-memory service database. The filesystem is the database. systemd operates in some cases by generating services on the fly, in memory in the service manager process itself. It maintains all services in memory, the source of the infamous "file changed on disk" message where what the service manager knows is out of synch with what's in the filesystem. In the nosh service manager, all service bundles exist in, and are accessible via, the filesystem. If something is generated on the fly, it is generated on the fly in the filesystem. Fewer things are generated on the fly, however, as bootstrap time is not build again and again time.
System management and service management are properly distinct. They are not done by a single program, and system state is not conflated with service state.
No daemontools-style thundering herds. daemontools, daemontools-encore, s6, perp, and runit all share the problems of having no (or almost no) system manager and having little to no dæmon startup/shutdown ordering mechanisms. The traditional mechanism for addressing this is the "thundering herd solution": keep bringing a service up, once per second, until its dependences are up and it finally stays up. This is suboptimal, to say the least; and it ignores the problem of proper shutdown ordering entirely. nosh provides the same daemontools mechanisms, but builds a full service and system management mechanism on top of them.
There are no XML parsers or .INI file parsers running in either the service manager or the system manager processes.
For other differences, see the section on new interfaces.
Here are some of the ways ways where the advances in design are the same as those of other systems.
No /etc/inittab
.
It comes as a surprise to some, but System 5 init
was never the only game in town.
Over the 1990s and 2000s, many alternative process #1 programs were published.
Of those only one, Nikola Vladov's ninit
, maintained compatibility with System 5 /etc/inittab
.
No other replacements for System 5 init
did — not finit
, not minit
, not runit-init
, not upstart, not systemd, not any of the others.
Nor does the nosh package.
Terminal login is an ordinary service like any other and there is no getty
.
It comes as a surprise to even more people that process #1 stopped being responsible for runnning terminal login services and getty
stopped being used in Unix in 1988, years before Linux even existed.
As the Service Access Facility did, nosh puts terminal login services in the charge of the service manager, as ordinary services like any others.
With the SAF, this meant that terminal login could be manipulated with ordinary SAF commands, and terminal login services could be enabled and disabled, and (more importantly, since the old /etc/inittab
system provided no mechanism for this) started and stopped on the fly.
Terminal login services are individually controllable in the ordinary manner with the nosh package, too.
And as the SAF did, nosh terminal login services replace the functionality of getty
is with native login management tools, for all terminals apart from real physical terminals connected to serial ports.
No run levels. This not only reflects the roots of the package in BSDs, which never had run levels in the first place, but also reflects the fact that run-levels are an outdated and passé hodge-podge (Multi-user bootstrap with an X server can be run-level 2, 4, or 5, depending from which system one uses.) that are best avoided. You are strongly encouraged to un-learn the idea of run-levels.
Proper, safe, reliable dæmon tracking.
PID files are tantamount to a loaded gun left lying around for a system administrator to shoot random processes with.
Parsing the output of ps
with shell script is even worse.
The service manager tracks services properly, without stale information lying around and without race conditions.
Parallel and ordered service startup.
If you've ever waited impatiently for the old /etc/rc.delay
to stop sleep
ing you'll appreciate this.
nosh service management starts (and stops) dæmons in parallel, calculating a grouping, and a start/stop order, based upon inter-service ordering dependencies.
For other similarities, see the section on familiar interfaces.