From 5b28fed32180467da7d27f80c787f09062578176 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Tue, 5 Jan 2016 21:11:27 +0100 Subject: [PATCH] Audit. Signed-off-by: Joachim Nilsson --- doc/conditions.md | 152 +++++++++++++++++++++++++++------------------- 1 file changed, 89 insertions(+), 63 deletions(-) diff --git a/doc/conditions.md b/doc/conditions.md index 2f3d4e35..ec062cc0 100644 --- a/doc/conditions.md +++ b/doc/conditions.md @@ -1,99 +1,125 @@ -# Finit Conditions +Finit Conditions +================ -In addition to runlevels, Finit supports user-defined conditions that -services can declare a dependency on. The conditions are specified in -angle brackets on the service stanza. Multiple conditions may be -specified, separated by commas. Conditions are AND-ed together during -evaluation, i.e. all conditions must be satisfied in order for the -service to be able to run. +![Condition state machine](../images/cond-statem.jpg "Condition state machine") -##### Example: -``` -service [2345] /sbin/netd -- Network monitor +Table of Contents +----------------- + +* [Introduction](#introduction) +* [Triggering](#triggering) +* [Built-in Conditions](#built-in--conditions) +* [Debugging](#debugging) +* [Internals](#internals) + + +Introduction +------------ + +In addition to runlevels, services can declare user-defined conditions +as dependencies. Conditions are specified within angle brackets (<>) in +the service stanza. Multiple conditions may be specified separated by +comma. Conditions are AND'ed during evaluation, i.e. all conditions +must be satisfied in order for a service to run. + + +**Example:** + +```shell + service [2345] /sbin/netd -- Network monitor ``` -In this example the `netd` daemon will not be started until both -`svc/sbin/setupd` and `svc/sbin/zebra` are satisfied. +In this example the Network monitor daemon `netd` is not started until +both the `svc/sbin/setupd` *and* `svc/sbin/zebra` conditions are +satisfied. An `svc` condition is satisfied by the corresponding +service's pidfile being created. -## Triggering +Triggering +---------- -Conditions are triggered by using the `emit` sub-command of the -`initctl` command. +Conditions are triggered by using the `emit` command of the `initctl` +control tool. - * To set a condition, use: `initctl emit +your/cond/here`. - * To clear a condition, use: `initctl emit -your/cond/here`. +* `initctl emit +your/cond/here` -A condition will retain its current state until the next -reconfiguration or runlevel change. At that point, all set conditions -will transition into the `flux` state, meaning that the condition's -state is unknown. The rationale for this can be found in the -[Internals](#internals) section. Thus, after a reconfiguration, it is -up to the "owner" of the condition to convey the new (or possibly -unchanged) state of it. + To set a condition + +* `initctl emit -your/cond/here` + + To clear a condition + +Conditions retain their current state until the next reconfiguration or +runlevel change. At that point all set conditions transition into the +`flux` state, meaning the condition's state is unknown. (See +[Internals](#internals) for the rationale behind this.) Thus, after a +reconfiguration it is up to the "owner" of the condition to convey the +new (or possibly unchanged) state of it. -## Built-in Conditions +Built-in Conditions +------------------- Finit is distributed with the `pidfile`-plugin. If enabled, it will -watch `/var/run/` for pidfiles created by services that is controls +watch `/var/run/` for pidfiles created by services that it controls and set a corresponding condition in the `svc/` namespace. -Thus, if Finit starts the `/sbin/netd` daemon and it creates -`/var/run/netd.pid`, the condition `svc/sbin/netd` will be set. If the -file is removed, the condition will be cleared. +For example, if Finit starts the `/sbin/netd` daemon and it creates the +file `/var/run/netd.pid`, the condition `svc/sbin/netd` is satisfied. +If the file is removed, the condition is cleared. -## Debugging +Debugging +--------- -If a service is not being started when it ought to be, the problem -might be that one of its conditions are not in the expected -state. This is indicated when running `initctl status` by the service -being in the `ready` state. +If a service is not being started as it should, the problem might be +that one of its conditions are not in the expected state. Use the +command `initctl status` to inspect service status. Services in the +`ready` state are pending a condition. -In that situation, running `initctl cond show` will reveal which of -the conditions that are not in the `on` state. +In that situation, running `initctl cond show` reveals which of the +conditions that are not satisfied. Listed as `off` below. -##### Example: +**Example:** -``` -~ # initctl cond show -PID Service Status Condition (+ on, ~ flux, - off) -==================================================================================== -1419 /sbin/netd on <+svc/sbin/setupd,+svc/sbin/zebra> -0 /sbin/udhcpc off <-net/vlan1/exist> +```shell + ~ # initctl cond show + PID Service Status Condition (+ on, ~ flux, - off) + =============================================================================== + 1419 /sbin/netd on <+svc/sbin/setupd,+svc/sbin/zebra> + 0 /sbin/udhcpc off <-net/vlan1/exist> ``` -Here we can see that `netd` is allowed to run since both of its -conditions are in the `on` state, as indicated by the -`+`-prefix. `udhcpc` is not allowed to run since `net/vlan1/exist` is -in the `off` state, indicated by the `-`-prefix. +Here we can see that `netd` is allowed to run since both its conditions +are in the `on` state, as indicated by the `+`-prefix. `udhcpc` however +is not allowed to run since `net/vlan1/exist` condition is not satsifed. +As indicated by the `-`-prefix. -## Internals +Internals +--------- A condition is always in one of three states: - * `on`: The condition is asserted. - * `off`: The condition is deasserted. - * `flux`: The conditions state is unknown. +* `on`: The condition is asserted. +* `off`: The condition is deasserted. +* `flux`: The conditions state is unknown. All conditions that have not explicitly been set are interpreted as being in the `off` state. -When a reconfiguration is requested, Finit will transition all -conditions to the `flux` state. As a result, any service that depends -on the condition will be sent a SIGSTOP. Once the new state of the -condition becomes known the service will receive a SIGCONT. Then if -the condition is no longer satisfied the service will be stopped, -otherwise no action needs to be taken. +When a reconfiguration is requested, Finit transitions all conditions to +the `flux` state. As a result, services that depend on a condition are +sent `SIGSTOP`. Once the new state of the condition is asserted, the +service receives `SIGCONT`. If the condition is no longer satisfied the +service will then be stopped, otherwise no further action is taken. -This minimizes the number of services that have to be restarted -needlessly, just because the depending service was sent a SIGHUP for -example. +This STOP/CONT handling minimizes the number of unnecessary service +restarts that would otherwise occur because a depending service was sent +`SIGHUP` for example. Therefore, any plugin that supplies Finit with conditions must ensure -that their state is updated after each reconfiguration. This can be -done by binding to the `HOOK_SVC_RECONF`-hook. Look at -`plugins/pidfile.c` too see an example of this. +that their state is updated after each reconfiguration. This can be +done by binding to the `HOOK_SVC_RECONF` hook. For an example of how +to do this, see `plugins/pidfile.c`.