mirror of
https://github.com/troglobit/finit.git
synced 2026-11-11 16:40:48 +00:00
Fix #250: support finit.cond=foo for cmdline <boot/foo> conditions
As a real life example, this can be useful for a mfgtest mode for the device, wherein the bootloader can be set to finit.cond=test_mode or finit.cond=user_mode and then specific services can start up in test mode which wouldn't normally start. Or even custom firmware update mode such as finit.cond=fw_update_mode which performs some specific firmware update steps and doesn't launch normal processes. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
0d57a507f3
commit
caa398816d
5 files changed
+93
-8
No files matched your search
@@ -12,6 +12,17 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
|
|||||||
* `debug`: Enable kernel debug. Debug messages are printed to the
|
* `debug`: Enable kernel debug. Debug messages are printed to the
|
||||||
console until Finit starts up, unless `loglevel=7` (below) is used.
|
console until Finit starts up, unless `loglevel=7` (below) is used.
|
||||||
|
|
||||||
|
* `finit.cond=foo[,bar[,baz]]`: set `<boot/foo>` condition, optionally
|
||||||
|
multiple conditions can be set using the same option, separated with a
|
||||||
|
comma. Alternatively, multiple `foo.cond=arg` can be given. Each will
|
||||||
|
result in a `<boot/arg>` condition being set to control the rest of the
|
||||||
|
system bootstrap.
|
||||||
|
|
||||||
|
Very useful for selecting different boot modes, e.g. manufacturing test,
|
||||||
|
firmware upgrade, or rescue mode.
|
||||||
|
|
||||||
|
> Note: `<boot/...>` conditions cannot be cleared with `initctl`!
|
||||||
|
|
||||||
* `finit.debug[=bool]`: Enable finit debug. This is operated
|
* `finit.debug[=bool]`: Enable finit debug. This is operated
|
||||||
independently of the kernel `debug` setting. New as of Finit v4.
|
independently of the kernel `debug` setting. New as of Finit v4.
|
||||||
|
|
||||||
|
|||||||
+11
-5
@@ -46,11 +46,16 @@ Triggering
|
|||||||
----------
|
----------
|
||||||
|
|
||||||
Conditions are mainly triggered (asserted) by built-in plugins, e.g.,
|
Conditions are mainly triggered (asserted) by built-in plugins, e.g.,
|
||||||
`netlink.so` and `pidfile.so`, see below for built-in conditions. Finit
|
|
||||||
also supports user-defined conditions, sometimes referred to as static
|
- `netlink.so`: provides `<net/...>`
|
||||||
or one-shot conditions. They live in the `<usr/...` namespace and are
|
- `pidfile.so`: provides `<pid/...>`
|
||||||
constrained to a flat hierarchy without any sub-directories, unlike the
|
- Cmdline `finit.cond=arg`: provides `<boot/arg`
|
||||||
pidfile plugin, for instance.
|
|
||||||
|
See below for built-in conditions. Finit also supports user-defined
|
||||||
|
conditions, sometimes referred to as static or one-shot conditions.
|
||||||
|
They live in the `<usr/...` namespace and are constrained to a flat
|
||||||
|
hierarchy without any sub-directories, unlike the pidfile plugin, for
|
||||||
|
instance.
|
||||||
|
|
||||||
User-defined conditions are controlled using the `initctl cond set` and
|
User-defined conditions are controlled using the `initctl cond set` and
|
||||||
`initctl cond clear` commands:
|
`initctl cond clear` commands:
|
||||||
@@ -118,6 +123,7 @@ Built-in conditions:
|
|||||||
- `sys/pwr/fail`
|
- `sys/pwr/fail`
|
||||||
- `sys/key/ctrlaltdel`
|
- `sys/key/ctrlaltdel`
|
||||||
- `usr/foo`
|
- `usr/foo`
|
||||||
|
- `boot/arg`
|
||||||
|
|
||||||
**Note:** `up` means administratively up, the interface flag `IFF_UP`.
|
**Note:** `up` means administratively up, the interface flag `IFF_UP`.
|
||||||
`running` is the `IFF_RUNNING` flag, meaning operatively up. The
|
`running` is the `IFF_RUNNING` flag, meaning operatively up. The
|
||||||
|
|||||||
@@ -36,6 +36,67 @@
|
|||||||
#include "pid.h"
|
#include "pid.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
|
|
||||||
|
struct cond_boot {
|
||||||
|
TAILQ_ENTRY(cond_boot) link;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
static TAILQ_HEAD(, cond_boot) cond_boot_list = TAILQ_HEAD_INITIALIZER(cond_boot_list);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse finit.cond=cond[,cond[,...]] from command line. It creates a
|
||||||
|
* temporary linked list of conds which are freed when finit reaches
|
||||||
|
* cond_init(), which calls cond_boot_strap() to realize the conditions
|
||||||
|
* in the file system as regular static conditions. Policy, however,
|
||||||
|
* dictates that these are read-only and should not be possible to
|
||||||
|
* manage from initctl.
|
||||||
|
*/
|
||||||
|
void cond_boot_parse(char *arg)
|
||||||
|
{
|
||||||
|
struct cond_boot *node;
|
||||||
|
|
||||||
|
if (!arg)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node = malloc(sizeof(*node));
|
||||||
|
if (!node) {
|
||||||
|
_pe("Out of memory cannot track boot conditions");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->name = strdup(arg);
|
||||||
|
TAILQ_INSERT_HEAD(&cond_boot_list, node, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert all conditions read from the kernel command line (above) into
|
||||||
|
* proper finit conditions.
|
||||||
|
*/
|
||||||
|
static void cond_boot_strap(void)
|
||||||
|
{
|
||||||
|
struct cond_boot *node, *tmp;
|
||||||
|
|
||||||
|
TAILQ_FOREACH_SAFE(node, &cond_boot_list, link, tmp) {
|
||||||
|
TAILQ_REMOVE(&cond_boot_list, node, link);
|
||||||
|
if (node->name) {
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
ptr = strtok(node->name, ",");
|
||||||
|
while (ptr) {
|
||||||
|
char cond[strlen(ptr) + 6];
|
||||||
|
|
||||||
|
snprintf(cond, sizeof(cond), "boot/%s", ptr);
|
||||||
|
cond_set_oneshot_noupdate(cond);
|
||||||
|
|
||||||
|
ptr = strtok(NULL, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
free(node->name);
|
||||||
|
}
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The service condition name is constructed from the 'pid/' prefix and
|
* The service condition name is constructed from the 'pid/' prefix and
|
||||||
* the unique NAME:ID tuple that identify each process in Finit. Here
|
* the unique NAME:ID tuple that identify each process in Finit. Here
|
||||||
@@ -366,6 +427,7 @@ void cond_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cond_bump_reconf();
|
cond_bump_reconf();
|
||||||
|
cond_boot_strap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+4
-3
@@ -31,6 +31,7 @@ enum cond_state cond_get (const char *name);
|
|||||||
enum cond_state cond_get_agg (const char *names);
|
enum cond_state cond_get_agg (const char *names);
|
||||||
int cond_affects (const char *name, const char *names);
|
int cond_affects (const char *name, const char *names);
|
||||||
|
|
||||||
|
void cond_boot_parse (char *arg);
|
||||||
int cond_update (const char *name);
|
int cond_update (const char *name);
|
||||||
int cond_set_path (const char *path, enum cond_state new);
|
int cond_set_path (const char *path, enum cond_state new);
|
||||||
void cond_set (const char *name);
|
void cond_set (const char *name);
|
||||||
@@ -38,9 +39,9 @@ void cond_set_oneshot (const char *name);
|
|||||||
void cond_clear (const char *name);
|
void cond_clear (const char *name);
|
||||||
void cond_reload (void);
|
void cond_reload (void);
|
||||||
|
|
||||||
int cond_set_noupdate (const char *name);
|
int cond_set_noupdate(const char *name);
|
||||||
int cond_set_oneshot_noupdate(const char *name);
|
int cond_set_oneshot_noupdate(const char *name);
|
||||||
int cond_clear_noupdate(const char *name);
|
int cond_clear_noupdate(const char *name);
|
||||||
|
|
||||||
void cond_reassert (const char *pat);
|
void cond_reassert (const char *pat);
|
||||||
void cond_deassert (const char *pat);
|
void cond_deassert (const char *pat);
|
||||||
|
|||||||
@@ -113,6 +113,11 @@ static void parse_finit_opts(char *opt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (string_compare(opt, "cond")) {
|
||||||
|
cond_boot_parse(arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (string_compare(opt, "status_style")) {
|
if (string_compare(opt, "status_style")) {
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
_e("status_style option requires an argument, skipping.");
|
_e("status_style option requires an argument, skipping.");
|
||||||
|
|||||||
Reference in new issue
Block a user