per-user-manager — manage per-user stuff
per-user-manager
[args
...]
init
[args
...]
per-user-manager can be used by individual users to manage non-system-wide, per-user, stuff. It is not meant to be run as process #1, and the system will not operate correctly if it is mis-used as process #1. To manage a system, use system-manager(1). The purpose of per-user-manager is to run per-user service management providing an overall control API for it that is similar to that of process #1. This permits per-user service manament to be addressed by system-control(1) (when its --user command-line option is employed) control subcommands such as halt.
The operation of per-user-manager falls into three parts: process setup, reaping, and responding to per-user events.
Unlike system-manager(8) it does no system setup. Mounting "API" filesystems, creating device nodes, and requesting the kernel for special system events are not user-local actions.
per-user-manager expects to be started in the state that the user intends services to run as. It does very little to its process state, which is inherited by the service manager and the logger:
(On operating systems that support this) it calls prctl(2) to tell the kernel that it is a "local reaper". Any service processes started (directly or indirectly) by the service-manager(1) that lose their original parents will be re-parented to the per-user-manager process, which will "reap" them when they terminate. This yields a slightly more informative process tree.
If control groups are available and it is in one, it enables the CPU, memory, IO, and tasks control group controllers for its own control group and for the service-manager.slice
control group immediately below it.
It moves itself into a me.slice
control group, so that the controllers can be enabled for sub-groups.
per-user-manager does not duplicate functionality with peculiar special-purpose mechanisms of its own. So:
If you wish it to run in a particular directory, chain to it from chdir(1).
If you wish it to run with a modified environment, chain to it from clearenv(1), setenv(1), unsetenv(1), envdir(1), or read-conf(1).
If you wish it to run with a different umask setting, chain to it from umask(1).
If you wish it to run as a session leader, chain to it from setsid(1).
And so forth.
per-user-manager operates as a "grim reaper", cleaning up after any child processes that exit. The operating system (if this is supported) re-parents any orphaned descendent processes to it. per-user-manager spawns exactly three processes itself:
After creating a local domain socket named /run/user/
it spawns an instance of service-manager(1).
If control groups are available, it is run in its own dedicated $USER
/service-manager/controlservice-manager.slice
subordinate control group below the system-manager's original own.
This is the local service manager for the user, controlled through the socket.
It is not expected to ever terminate (before user-level shutdown).
If it does, per-user-manager re-spawns it.
As events occur, it spawns (ephemeral) instances of service-control(1).
If control groups are available, they are is run in their own dedicated service-control.slice
subordinate control group below the system-manager's original own.
These calculate the details of service and target dependencices for user-wide state changes, and pass instructions to the local service manager for bringing services up and down.
Only one instance is spawned at a time.
It spawns an instance of cyclog(1) with its input connected to the read end of a pipe.
If control groups are available, it is run in its own dedicated per-user-manager-log.slice
subordinate control group below the system-manager's original own.
This process is expected to only terminate when the pipe is closed.
If it terminates otherwise, per-user-manager simply re-spawns it.
The write end of the aforementioned pipe is connected to the the standard outputs and standard errors of the service manager, the (ephemeral) service controllers, and of per-user-manager itself.
(Their standard input is connected to /dev/null
.)
per-user-manager retains open file descriptors to this pipe, so that no unsaved log data are lost should the logger unexpectedly exit.
The logger is intended to be just for the per-user manager, the service manager, and the service controllers.
Actual services should be plumbed to their own logging services.
The logger is told to write its logfiles to /run/user/
, and to cap their maximum total size at 1MiB.
$USER
/per-user-manager/log
$USER
is the result of the getlogin(2) library function (on the BSDs), or (failing that) the value of the $LOGNAME
or $USER
variables.
The only IPC mechanism provided by per-user-manager is signals. (Commands to manipulate services are sent to the spawned service manager, not to the per-user manager.) User-local events are flagged by sending various signals to the per-user manager process. per-user-manager responds to these signals as follows:
SIGRTMIN + 0
, SIGRTMIN + 1
, SIGRTMIN + 2
Spawn system-control start normal .
This will activate the normal
target, which is an alias for the intrat
target.
SIGINT
, SIGTERM
, SIGHUP
, SIGPIPE
, SIGRTMIN + 3
, SIGRTMIN + 4
, SIGRTMIN + 5
Spawn system-control start halt .
This will activate the halt
target an alias for the exit
target.
Implicit in activating the exit
target is activating the shutdown
target, which deactivates everything else.
(This is written into the packaged target definitions, not hardwired into system-control(8).)
SIGRTMIN + 10
Spawn system-control start sysinit .
This will activate the sysinit
target an alias for the intrat
target.
SIGRTMIN + 13
, SIGRTMIN + 14
, SIGRTMIN + 15
Close the pipe, terminate the service manager, and wait a short while for it. Then exit.
When the exit
target is fully active, it is expected to send the SIGRTMIN + 13
signal to the per-user manager process.
In the packaged target definitions, they use the --force option to the halt subcommand of system-control(8) to do this.
Do not send these signals directly, as this does not shut down services in order.
It ignores the SIGTTIN
, SIGTTOU
, SIGTSTP
, and SIGALRM
signals.
per-user-manager startup is also treated as a user-local event. In response this "event" per-user-manager spawns system-control --user init . This calculates what to initialize and sends appropriate signals back to the per-user manager process.