forked from dan/liminix
move the u-boot/serial stuff here from development, as the reality of Liminix development in 2024 is that serial connection is still the smoothest installation method
176 lines
6.7 KiB
ReStructuredText
176 lines
6.7 KiB
ReStructuredText
System Administration
|
|
#####################
|
|
|
|
Services on a running system
|
|
****************************
|
|
|
|
Liminix services are built on s6-rc, which is itself layered on s6.
|
|
See configuration / services node for how to specify them.
|
|
|
|
|
|
|
|
.. list-table:: Service management quick reference
|
|
:widths: 55 45
|
|
:header-rows: 1
|
|
|
|
* - What
|
|
- How
|
|
* - List all running services
|
|
- ``s6-rc -a list``
|
|
* - List all services that are **not** running
|
|
- ``s6-rc -da list``
|
|
* - List services that ``wombat`` depends on
|
|
- ``s6-rc-db dependencies wombat``
|
|
* - ... transitively
|
|
- ``s6-rc-db all-dependencies wombat``
|
|
* - List services that depend on service ``wombat``
|
|
- ``s6-rc-db -d dependencies wombat``
|
|
* - ... transitively
|
|
- ``s6-rc-db -d all-dependencies wombat``
|
|
* - Stop service ``wombat`` and everything depending on it
|
|
- ``s6-rc -d change wombat``
|
|
* - Start service ``wombat`` (but not any services depending on it)
|
|
- ``s6-rc -u change wombat``
|
|
* - Start service ``wombat`` and all* services depending on it
|
|
- ``s6-rc-up-tree wombat``
|
|
|
|
:command:`s6-rc-up-tree` brings up a service and all services that
|
|
depend on it, except for any services that depend on a "controlled"
|
|
service that is not currently running. Controlled services are not
|
|
started at boot time but in response to external events (e.g. plugging
|
|
in a particular piece of hardware) so you probably don't want to be
|
|
starting them by hand if the conditions aren't there.
|
|
|
|
A service may be **up** or **down** (there are no intermediate states
|
|
like "started" or "stopping" or "dying" or "cogitating"). Some (but
|
|
not all) services have "readiness" notifications: the dependents of a
|
|
service with a readiness notification won't be started until the
|
|
service signals (by writing to a nominated file descriptor) that it's
|
|
prepared to start work. Most services defined by Liminix also have a
|
|
``timeout-up`` parameter, which means that if a service has readiness
|
|
notifications and doesn't become ready in the allotted time (defaults
|
|
20 seconds) it will be terminated and its state set to **down**.
|
|
|
|
If the process providing a service dies, it will be restarted
|
|
automatically. Liminix does not automatically set it to **down**.
|
|
|
|
(If the process providing a service dies without ever notifying
|
|
readiness, Liminix will restart it as many times as it has to until the
|
|
timeout period elapses, and then stop it and mark it down.)
|
|
|
|
Controlled services
|
|
===================
|
|
|
|
**Controlled** services are those which are started/stopped on demand
|
|
by a **controller** (another service) instead of being started at boot
|
|
time. For example:
|
|
|
|
* ``svc.uevent-rule.build`` creates a controlled service which is
|
|
active when a particular hardware device (identified by uevent/sysfs
|
|
directory) is present.
|
|
|
|
* :command:`s6-rc-round-robin` can be used in a service controller to
|
|
invoke two or more services in turn, running the next one when the
|
|
process providing the previous one exits. We use this for failover
|
|
from one network connection to a backup connection, for example.
|
|
|
|
The Configuration section of the manual describes this in more detail.
|
|
|
|
Logs
|
|
====
|
|
|
|
Logs for all services are collated into :file:`/run/uncaught-logs/current`.
|
|
The log file is rotated when it reaches a threshold size, into another
|
|
file in the same directory whose name contains a TAI64 timestamp.
|
|
|
|
Each log line is prefixed with a TAI64 timestamp and the name of the
|
|
service, if it is a longrun. If it is a oneshot, a timestamp and the
|
|
name of some other service. To convert the timestamp into a
|
|
human-readable format, use :command:`s6-tai64nlocal`.
|
|
|
|
.. code-block:: console
|
|
|
|
# ls -l /run/uncaught-logs/
|
|
-rw-r--r-- 1 0 lock
|
|
-rw-r--r-- 1 0 state
|
|
-rwxr--r-- 1 98059 @4000000000025cb629c311ac.s
|
|
-rwxr--r-- 1 98061 @40000000000260f7309c7fb4.s
|
|
-rwxr--r-- 1 98041 @40000000000265233a6cc0b6.s
|
|
-rwxr--r-- 1 98019 @400000000002695d10c06929.s
|
|
-rwxr--r-- 1 98064 @4000000000026d84189559e0.s
|
|
-rwxr--r-- 1 98055 @40000000000271ce1e031d91.s
|
|
-rwxr--r-- 1 98054 @400000000002760229733626.s
|
|
-rwxr--r-- 1 98104 @4000000000027a2e3b6f4e12.s
|
|
-rwxr--r-- 1 98023 @4000000000027e6f0ed24a6c.s
|
|
-rw-r--r-- 1 42374 current
|
|
|
|
# tail -2 /run/uncaught-logs/current
|
|
@40000000000284f130747343 wan.link.pppoe Connect: ppp0 <--> /dev/pts/0
|
|
@40000000000284f230acc669 wan.link.pppoe sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x667a9594> <pcomp> <accomp>]
|
|
# tail -2 /run/uncaught-logs/current | s6-tai64nlocal
|
|
1970-01-02 21:51:45.828598156 wan.link.pppoe sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x667a9594> <pcomp> <accom
|
|
p>]
|
|
1970-01-02 21:51:48.832588765 wan.link.pppoe sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x667a9594> <pcomp> <accom
|
|
p>]
|
|
|
|
|
|
|
|
|
|
|
|
Updating an installed system (JFFS2)
|
|
************************************
|
|
|
|
|
|
Adding packages
|
|
===============
|
|
|
|
If your device is running a JFFS2 root filesystem, you can build
|
|
extra packages for it on your build system and copy them to the
|
|
device: any package in Nixpkgs or in the Liminix overlay is available
|
|
with the ``pkgs`` prefix:
|
|
|
|
.. code-block:: console
|
|
|
|
nix-build -I liminix-config=./my-configuration.nix \
|
|
--arg device "import ./devices/mydevice" -A pkgs.tcpdump
|
|
|
|
nix-shell -p min-copy-closure root@the-device result/
|
|
|
|
Note that this only copies the package to the device: it doesn't update
|
|
any profile to add it to ``$PATH``
|
|
|
|
|
|
.. _rebuilding the system:
|
|
|
|
Rebuilding the system
|
|
=====================
|
|
|
|
:command:`liminix-rebuild` is the Liminix analogue of :command:`nixos-rebuild`, although its operation is a bit different because it expects to run on a build machine and then copy to the host device. Run it with the same ``liminix-config`` and ``device`` parameters as you would run :command:`nix-build`, and it will build any new/changed packages and then copy them to the device using SSH. For example:
|
|
|
|
.. code-block:: console
|
|
|
|
liminix-rebuild root@the-device -I liminix-config=./examples/rotuer.nix --arg device "import ./devices/gl-ar750"
|
|
|
|
This will
|
|
|
|
* build anything that needs building
|
|
* copy new or changed packages to the device
|
|
* reboot the device
|
|
|
|
It doesn't delete old packages automatically: to do that run
|
|
:command:`min-collect-garbage`, which will delete any packages not in
|
|
the current system closure. Note that Liminix does not have the NixOS
|
|
concept of environments or generations, and there is no way back from
|
|
this except for building the previous configuration again.
|
|
|
|
|
|
Caveats
|
|
-------
|
|
|
|
* it needs there to be enough free space on the device for all the new
|
|
packages in addition to all the packages already on it - which may be
|
|
a problem if a lot of things have changed (e.g. a new version of
|
|
nixpkgs).
|
|
|
|
* it cannot upgrade the kernel, only userland
|