summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org>2016-01-31 14:40:27 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2016-01-31 14:40:27 (GMT)
commitd9d267052215f223897af18310e4adee310308e7 (patch) (side-by-side diff)
tree6b6f9eb636975f5721e00d2d71007185fa5b2fbf
parent6f9f2fd7a6952b544dccbf0bdc7f9c312f602afe (diff)
downloadpies-d9d267052215f223897af18310e4adee310308e7.tar.gz
pies-d9d267052215f223897af18310e4adee310308e7.tar.bz2
Support sysvinit ondemand components.
* src/ctl.c (fun_start): Handle status_finished same as status_sleeping (for restarting ondemand components). * src/progman.c: Respawn ondemand components. * src/sysvinit.c (enablecomp): Handle pies_comp_ondemand. (sysvinit_demand): New function. (sysvinit_fifo_handler): Handle ondemand runlevels. (inittab_parse): Support "off" fields. Convert runlevels to upper case.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--src/ctl.c16
-rw-r--r--src/progman.c9
-rw-r--r--src/sysvinit.c90
3 files changed, 83 insertions, 32 deletions
diff --git a/src/ctl.c b/src/ctl.c
index 0e5ea97..489fc7f 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -1873,27 +1873,29 @@ fun_stop (struct json_value *result, struct prog *prog)
return 0;
}
static int
fun_start (struct json_value *result, struct prog *prog)
{
- if (prog->v.p.status == status_disabled)
+ switch (prog->v.p.status)
{
+ case status_disabled:
prog->v.p.comp->flags &= ~CF_DISABLED;
prog->v.p.status = status_enabled;
json_object_set_string (result, "status", "OK");
- }
- else if (prog->v.p.status == status_sleeping)
- {
+ break;
+
+ case status_sleeping:
+ case status_finished:
prog->v.p.status = status_enabled;
prog->v.p.failcount = 0;
prog->v.p.timestamp = 0;
json_object_set_string (result, "status", "OK");
- }
- else
- {
+ break;
+
+ default:
json_object_set_string (result, "status", "ER");
json_object_set_string (result, "error_message", "already running");
return 1;
}
return 0;
}
diff --git a/src/progman.c b/src/progman.c
index 4ca3824..020dccd 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -300,15 +300,15 @@ progman_waiting_p ()
struct prog *prog;
for (prog = proghead; prog; prog = prog->next)
{
if (IS_COMPONENT (prog) && prog->v.p.wait && prog->pid > 0)
{
- debug(1, ("%s: waiting for %s (%lu)",
- __FUNCTION__, prog_tag (prog),
- (unsigned long) prog->pid));
+ debug (3, ("%s: waiting for %s (%lu)",
+ __FUNCTION__, prog_tag (prog),
+ (unsigned long) prog->pid));
return 1;
}
}
return 0;
}
@@ -2302,13 +2302,14 @@ progman_cleanup (int expect_term)
if (listener->v.p.comp->flags & CF_WAIT)
enable_socket (listener->v.p.socket);
}
}
else
{
- if (prog->v.p.comp->mode >= pies_mark_sysvinit)
+ if (prog->v.p.comp->mode >= pies_mark_sysvinit
+ && prog->v.p.comp->mode != pies_comp_ondemand)
{
sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog_tag (prog),
pid, "");
prog->v.p.status = status_finished;
prog->v.p.wait = 0;
}
diff --git a/src/sysvinit.c b/src/sysvinit.c
index be7aef8..337b922 100644
--- a/src/sysvinit.c
+++ b/src/sysvinit.c
@@ -235,17 +235,20 @@ enablecomp (struct prog *prog, void *data)
switch (comp->mode)
{
case pies_comp_sysinit:
case pies_comp_boot:
case pies_comp_bootwait:
return 0;
+
+ case pies_comp_ondemand:
+ return prog->v.p.status == status_enabled;
+
case pies_comp_powerfail:
case pies_comp_powerwait:
case pies_comp_powerokwait:
case pies_comp_ctrlaltdel:
- case pies_comp_ondemand:
case pies_comp_powerfailnow:
case pies_comp_kbrequest:
return s && (s->mask & PIES_COMP_MASK (comp->mode));
default:
break;
}
@@ -297,13 +300,34 @@ sysvinit_runlevel_setup (int mask, int *wait)
s.wait = *wait;
}
progman_foreach (runlevel_setup_prog, &s);
if (wait)
*wait = s.wait;
}
-
+
+static int
+demand_prog (struct prog *prog, void *data)
+{
+ int *rl = data;
+ struct component *comp = prog->v.p.comp;
+ if (comp->mode == pies_comp_ondemand
+ && comp->runlevels
+ && strchr (comp->runlevels, *rl))
+ {
+ prog->v.p.status = status_enabled;
+ debug (1, ("%s: %s", prog_tag (prog), "enabled"));
+ }
+ return 0;
+}
+
+static void
+sysvinit_demand (int rl)
+{
+ progman_foreach (demand_prog, &rl);
+}
+
static const char valid_runlevel_arg[] = "0123456789SsQqAaBbCcUu";
int
is_valid_runlevel (int c)
{
return !!strchr (valid_runlevel_arg, c);
@@ -455,14 +479,27 @@ sysvinit_fifo_handler (int fd, void *data)
case 'Q':
break;
default:
if (buf.req.runlevel != runlevel)
{
- dfl_level = buf.req.runlevel;
- inittrans ();
+ switch (buf.req.runlevel)
+ {
+ case 'A':
+ case 'B':
+ case 'C':
+ sysvinit_demand (buf.req.runlevel);
+ break;
+
+ default:
+ if (runlevel_index (buf.req.runlevel) != -1)
+ {
+ dfl_level = buf.req.runlevel;
+ inittrans ();
+ }
+ }
}
}
break;
case INIT_CMD_SETENV:
sysvinit_setenv (buf.req.data, sizeof (buf.req.data));
@@ -816,25 +853,25 @@ struct action_parser
const char *action;
enum pies_comp_mode mode;
int (*parser) (struct component *comp, const char *file, unsigned line);
};
static struct action_parser action_tab[] = {
- { "wait", pies_comp_wait },
- { "once", pies_comp_once },
- { "boot", pies_comp_boot },
- { "bootwait", pies_comp_bootwait },
- { "powerfail", pies_comp_powerfail },
- { "powerwait", pies_comp_powerwait },
- { "powerokwait", pies_comp_powerokwait },
- { "ctrlaltdel", pies_comp_ctrlaltdel },
- { "ondemand", pies_comp_ondemand },
- { "sysinit", pies_comp_sysinit },
+ { "wait", pies_comp_wait },
+ { "once", pies_comp_once },
+ { "boot", pies_comp_boot },
+ { "bootwait", pies_comp_bootwait },
+ { "powerfail", pies_comp_powerfail },
+ { "powerwait", pies_comp_powerwait },
+ { "powerokwait", pies_comp_powerokwait },
+ { "ctrlaltdel", pies_comp_ctrlaltdel },
+ { "ondemand", pies_comp_ondemand },
+ { "sysinit", pies_comp_sysinit },
{ "powerfailnow", pies_comp_powerfailnow },
- { "kbrequest", pies_comp_kbrequest },
- { "respawn", pies_comp_respawn },
+ { "kbrequest", pies_comp_kbrequest },
+ { "respawn", pies_comp_respawn },
{ NULL }
};
static struct action_parser *
find_action_parser (const char *action)
{
@@ -843,12 +880,21 @@ find_action_parser (const char *action)
for (ap = action_tab; ap->action; ap++)
if (strcmp (ap->action, action) == 0)
return ap;
return NULL;
}
+static char *
+strupr (char *s)
+{
+ char *p;
+ for (p = s; *p; p++)
+ *p = toupper (*p);
+ return s;
+}
+
int
inittab_parse (const char *file)
{
FILE *fp;
size_t size = 0;
char *buf = NULL;
@@ -928,14 +974,13 @@ inittab_parse (const char *file)
runlevels = getfld (p, &p);
action = getfld (p, &p);
process = p;
if (!id || !runlevels || !action || !process)
{
- logmsg (LOG_ERR, "%s:%u: %s",
- file, line_no, _("not enough fields"));
+ logmsg (LOG_ERR, "%s:%u: %s", file, line_no, _("not enough fields"));
err = 1;
continue;
}
if (strcmp (action, "initdefault") == 0)
{
@@ -947,24 +992,27 @@ inittab_parse (const char *file)
}
else
initdefault = toupper (runlevels[0]);
continue;
}
+ if (strcmp (action, "off") == 0)
+ /* Ignore the entry */
+ continue;
+
ap = find_action_parser (action);
if (!ap)
{
- logmsg (LOG_ERR, "%s:%u: %s",
- file, line_no, _("unknown action"));
+ logmsg (LOG_ERR, "%s:%u: %s", file, line_no, _("unknown action"));
err = 1;
continue;
}
comp = component_create (id);
comp->mode = ap->mode;
- comp->runlevels = grecs_strdup (runlevels);
+ comp->runlevels = grecs_strdup (strupr (runlevels));
if (wordsplit (process, &ws, WRDSF_DEFFLAGS))
{
component_free (comp);
logmsg (LOG_ERR, "%s:%u: wordsplit: %s", file, line_no,
strerror (errno));

Return to:

Send suggestions and report system problems to the System administrator.