mirror of
https://github.com/troglobit/finit.git
synced 2026-10-18 10:59:34 +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
@@ -36,6 +36,67 @@
|
||||
#include "pid.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 unique NAME:ID tuple that identify each process in Finit. Here
|
||||
@@ -366,6 +427,7 @@ void cond_init(void)
|
||||
}
|
||||
|
||||
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);
|
||||
int cond_affects (const char *name, const char *names);
|
||||
|
||||
void cond_boot_parse (char *arg);
|
||||
int cond_update (const char *name);
|
||||
int cond_set_path (const char *path, enum cond_state new);
|
||||
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_reload (void);
|
||||
|
||||
int cond_set_noupdate (const char *name);
|
||||
int cond_set_oneshot_noupdate(const char *name);
|
||||
int cond_clear_noupdate(const char *name);
|
||||
int cond_set_noupdate(const char *name);
|
||||
int cond_set_oneshot_noupdate(const char *name);
|
||||
int cond_clear_noupdate(const char *name);
|
||||
|
||||
void cond_reassert (const char *pat);
|
||||
void cond_deassert (const char *pat);
|
||||
|
||||
@@ -113,6 +113,11 @@ static void parse_finit_opts(char *opt)
|
||||
return;
|
||||
}
|
||||
|
||||
if (string_compare(opt, "cond")) {
|
||||
cond_boot_parse(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string_compare(opt, "status_style")) {
|
||||
if (!arg) {
|
||||
_e("status_style option requires an argument, skipping.");
|
||||
|
||||
Reference in new issue
Block a user