mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 13:33:09 +07:00
Replace 'initctl emit <EV>' with 'initctl cond <cmd> <COND>'
This patch replaces the old 'initctl emit <EV>' idea with a more
full blown condition generator:
initctl cond <set|clear|flux> <COND>
This aligns better with terminology used elsewhere in the new Finit
service state machine and dependency handling already documented.
The 'flux' sub-command is mostly intended for simulation/test of
Finit itself and should perhaps not be documented.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
@@ -694,13 +694,12 @@ not return until the given command has fully completed.
|
||||
Commands:
|
||||
debug Toggle Finit (daemon) debug
|
||||
help This help text
|
||||
emit <EV> Emit event; a predefined event: RELOAD, STOP, START
|
||||
or a custom string matching an event in a service
|
||||
stanza, e.g: GW:UP, IFUP:IFNAME, IFDN:IFNAME. Where
|
||||
IFNAME is the interface name, e.g. eth0
|
||||
reload Reload *.conf in /etc/finit.d/ and activate changes
|
||||
runlevel [0-9] Show or set runlevel: 0 halt, 6 reboot
|
||||
status | show Show status of services
|
||||
cond set <COND> Set (assert) condition => +COND
|
||||
cond clear <COND> Clear (deassert) condition => -COND
|
||||
cond flux <COND> Emulate flux condition => ~COND
|
||||
cond show Show condition status
|
||||
start <JOB|NAME>[:ID] Start service by job# or name, with optional ID
|
||||
stop <JOB|NAME>[:ID] Stop/Pause a running service by job# or name
|
||||
@@ -709,55 +708,6 @@ not return until the given command has fully completed.
|
||||
version Show Finit version
|
||||
```
|
||||
|
||||
The `emit <EV>` command can be used to send events to Finit. Built-in
|
||||
events are: RELOAD, STOP, START. These events act on a lower level than
|
||||
their command counterparts. The `reload` command reloads all `*.conf`
|
||||
files in `/etc/finit.d/` *and* activates the changes, with `emit RELOAD`
|
||||
only the `*.conf` files are reloaded.
|
||||
|
||||
**Note:** The `emit STOP` event is more like "prepare" than "stop".
|
||||
Depending on how the service is declared, `<!>` or not, the service
|
||||
may be stopped, or skipped to be be sent `SIGHUP` later when `emit
|
||||
START` is issued.
|
||||
|
||||
To achieve the same result as `initctl reload` emit all three events:
|
||||
|
||||
```shell
|
||||
~ $ initctl emit "RELOAD,STOP,START"
|
||||
```
|
||||
|
||||
On an embedded system this can be used when changing complete system
|
||||
configuration. Between `STOP` and `START` reset/change any hardware
|
||||
or kernel settings required to be in effect before new services are
|
||||
started.
|
||||
|
||||
```shell
|
||||
# 1. Update/Change/Generate all daemon configuration files
|
||||
~ $ …
|
||||
|
||||
# 2. Update /etc/finit.d/*.conf
|
||||
~ $ …
|
||||
|
||||
# 3. Prepare finit, stop all old/previous services
|
||||
~ $ initctl emit "RELOAD,STOP"
|
||||
|
||||
# 4. Reconfigure hardware, interfaces/bridges/VLANs, etc.
|
||||
~ $ brctl …
|
||||
~ $ vconfig …
|
||||
~ $ ifconfig …
|
||||
|
||||
# 5. Complete finit reload by starting all new services and
|
||||
# SIGHUP any changed services
|
||||
~ $ initctl emit "START"
|
||||
```
|
||||
|
||||
The `emit <EV>` command can also be used to emit custom events. In
|
||||
fact, the event is a simple string. Declare a list of events in a
|
||||
service stanza: `service … <GW:UP,IFUP:eth0>` to reload (`SIGHUP`) a
|
||||
service when recieving the `"GW:UP"` or `"IFUP:eth0"` strings. If a
|
||||
service cannot handle reload and must be stopped-started, simply add an
|
||||
exclamation mark first: `service … <!GW:UP,IFUP:eth0>`.
|
||||
|
||||
The `<!>` notation to a service stanza can be used empty, then it will
|
||||
apply to `reload` and `runlevel` commands. I.e., when a service's
|
||||
`.conf` file has been changed Finit will stop and start it instead. If
|
||||
@@ -768,8 +718,7 @@ behaviour, but not all daemons support this, unfortunately.
|
||||
**Note:** even though it is possible to start services not belonging to
|
||||
the current runlevel these services will not be respawned automatically
|
||||
by Finit if they exit (crash). Hence, if the runlevel is 2, the below
|
||||
Dropbear SSH service will not be restarted if it, for some reason,
|
||||
exits.
|
||||
Dropbear SSH service will not be restarted if it is killed or exits.
|
||||
|
||||
```shell
|
||||
~ $ initctl status -v
|
||||
|
||||
+15
-3
@@ -40,14 +40,14 @@ service's pidfile being created.
|
||||
Triggering
|
||||
----------
|
||||
|
||||
Conditions are triggered either by plugins or by using the `emit`
|
||||
Conditions are triggered either by plugins or by using the `cond`
|
||||
command of the `initctl` control tool.
|
||||
|
||||
* `initctl emit +your/cond/here`
|
||||
* `initctl cond set your/cond/here`
|
||||
|
||||
To set a condition
|
||||
|
||||
* `initctl emit -your/cond/here`
|
||||
* `initctl cond clear your/cond/here`
|
||||
|
||||
To clear a condition
|
||||
|
||||
@@ -115,6 +115,18 @@ 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.
|
||||
|
||||
To fake interface `vlan1` suddenly appearing, and test what happens to
|
||||
`udhcpc` we can enable debug mode and assert the condition, like this:
|
||||
|
||||
```shell
|
||||
~ # initctl debug
|
||||
~ # initctl cond set net/vlan1/exist
|
||||
```
|
||||
|
||||
Then watch the console for the debug messages and then check the output
|
||||
from `initctl cond show` again. (The client will likely have failed to
|
||||
start, but at least the condition is now satisfied.)
|
||||
|
||||
|
||||
Internals
|
||||
---------
|
||||
|
||||
@@ -173,9 +173,11 @@ static void show_cond_one(const char *_conds)
|
||||
case COND_ON:
|
||||
printf("+%s", cond);
|
||||
break;
|
||||
|
||||
case COND_FLUX:
|
||||
printf("\e[1m~%s\e[0m", cond);
|
||||
break;
|
||||
|
||||
case COND_OFF:
|
||||
printf("\e[1m-%s\e[0m", cond);
|
||||
break;
|
||||
@@ -185,10 +187,20 @@ static void show_cond_one(const char *_conds)
|
||||
putchar('>');
|
||||
}
|
||||
|
||||
static void show_cond(void)
|
||||
static int do_cond_magic(char op, char *cond)
|
||||
{
|
||||
cond[0] = op;
|
||||
return do_emit(cond);
|
||||
}
|
||||
|
||||
static int do_cond_set (char *cond) { return do_cond_magic('+', cond); }
|
||||
static int do_cond_clear(char *cond) { return do_cond_magic('-', cond); }
|
||||
static int do_cond_flux (char *cond) { return do_cond_magic('~', cond); }
|
||||
|
||||
static int do_cond_show(char *UNUSED(arg))
|
||||
{
|
||||
enum cond_state cond;
|
||||
svc_t *svc;
|
||||
enum cond_state cond;
|
||||
|
||||
printf("PID Service Status Condition (+ on, ~ flux, - off)\n");
|
||||
printf("====================================================================================\n");
|
||||
@@ -209,12 +221,33 @@ static void show_cond(void)
|
||||
show_cond_one(svc->cond);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_cond(char *UNUSED(arg))
|
||||
static int do_cond(char *cmd)
|
||||
{
|
||||
show_cond();
|
||||
return 0;
|
||||
int c;
|
||||
char *arg;
|
||||
command_t command[] = {
|
||||
{ "set", do_cond_set },
|
||||
{ "clear", do_cond_clear },
|
||||
{ "flux", do_cond_flux },
|
||||
{ "show", do_cond_show },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
arg = strpbrk(cmd, " ");
|
||||
if (arg) {
|
||||
*arg = 0;
|
||||
|
||||
for (c = 0; command[c].cmd; c++) {
|
||||
if (!strcmp(command[c].cmd, cmd))
|
||||
return command[c].cb(arg);
|
||||
}
|
||||
}
|
||||
|
||||
return do_cond_show(NULL);
|
||||
}
|
||||
|
||||
static int show_version(char *UNUSED(arg))
|
||||
@@ -345,13 +378,12 @@ static int usage(int rc)
|
||||
"Commands:\n"
|
||||
" debug Toggle Finit (daemon) debug\n"
|
||||
" help This help text\n"
|
||||
" emit <EV> Emit event; a predefined event: RELOAD, STOP, START\n"
|
||||
" or a custom string matching an event in a service\n"
|
||||
" stanza, e.g: GW:UP, IFUP:IFNAME, IFDN:IFNAME. Where\n"
|
||||
" IFNAME is the interface name, e.g. eth0\n"
|
||||
" reload Reload *.conf in /etc/finit.d/ and activate changes\n"
|
||||
" runlevel [0-9] Show or set runlevel: 0 halt, 6 reboot\n"
|
||||
" status | show Show status of services\n"
|
||||
" cond set <COND> Set (assert) condition => +COND\n"
|
||||
" cond clear <COND> Clear (deassert) condition => -COND\n"
|
||||
" cond flux <COND> Emulate flux condition => ~COND\n"
|
||||
" cond show Show condition status\n"
|
||||
" start <JOB|NAME>[:ID] Start service by job# or name, with optional ID\n"
|
||||
" stop <JOB|NAME>[:ID] Stop/Pause a running service by job# or name\n"
|
||||
@@ -366,7 +398,6 @@ int main(int argc, char *argv[])
|
||||
int c;
|
||||
command_t command[] = {
|
||||
{ "debug", toggle_debug },
|
||||
{ "emit", do_emit },
|
||||
{ "reload", do_reload },
|
||||
{ "runlevel", do_runlevel },
|
||||
{ "status", show_status },
|
||||
|
||||
Reference in New Issue
Block a user