aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-11-05 10:26:17 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2015-11-05 10:26:17 +0200
commite7e3df9a6c4599f982a62bb8d7cd973ccd8cee72 (patch)
treee897c5d7e85bdaa5503aab6a25c174cf06d1c5d2
parent6cc676f7f8d86849607b7f707c8682e7efdb65c3 (diff)
downloadpies-e7e3df9a6c4599f982a62bb8d7cd973ccd8cee72.tar.gz
pies-e7e3df9a6c4599f982a62bb8d7cd973ccd8cee72.tar.bz2
New ctl commands: start, stop, restart, reboot, shutdown.
* src/ctl.c (CTL_ACTION_STATE): New state. (cmdtab): Add new commands: start, stop, restart, reboot, shutdown. (ctlio)<action>: New member. (ctlio_create): Initialize action. (list_prog): List scheduled wakeup time for sleeping components. (cmd_start,cmd_stop) (cmd_restart,cmd_reboot,cmd_shutdown): New functions. (ctlwr): Handle CTL_ACTION_STATE. * src/pies.c (pies_schedule_action): New function. (stop_components): Use progman_stop_tag(). * src/pies.h (pies_schedule_action, progman_stop_tag): New protos. (progman_stop_component): Remove. * src/prog.h (progman_locate, progman_stop_component): New protos. * src/progman.c (progman_locate): New function. (progman_cleanup): Set status depending on the CF_DISABLED bit. (progman_stop_component): Take struct prog* as argument. (progman_stop_tag): New function.
-rw-r--r--src/ctl.c109
-rw-r--r--src/pies.c9
-rw-r--r--src/pies.h4
-rw-r--r--src/prog.h2
-rw-r--r--src/progman.c77
5 files changed, 163 insertions, 38 deletions
diff --git a/src/ctl.c b/src/ctl.c
index 002a764..eef1aae 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -102,6 +102,7 @@ ctlbuf_chomp (struct ctlbuf *buf)
#define CTL_END_STATE 0
#define CTL_INITIAL_STATE 0x01
#define CTL_AUTHENTICATED_STATE 0x02
+#define CTL_ACTION_STATE 0x04
#define CTL_ALL_STATES (CTL_INITIAL_STATE|CTL_AUTHENTICATED_STATE)
struct ctlio;
@@ -111,6 +112,11 @@ static void cmd_noop (struct ctlio *, size_t, char **);
static void cmd_help (struct ctlio *, size_t, char **);
static void cmd_id (struct ctlio *, size_t, char **);
static void cmd_list (struct ctlio *, size_t, char **);
+static void cmd_start (struct ctlio *, size_t, char **);
+static void cmd_stop (struct ctlio *, size_t, char **);
+static void cmd_restart (struct ctlio *, size_t, char **);
+static void cmd_reboot (struct ctlio *, size_t, char **);
+static void cmd_shutdown (struct ctlio *, size_t, char **);
struct ctlio_command
{
@@ -133,6 +139,16 @@ static struct ctlio_command cmdtab[] = {
CTL_ALL_STATES, 1, 1, cmd_help },
{ "list", "list components",
CTL_AUTHENTICATED_STATE, 1, 0, cmd_list },
+ { "stop", "stop component",
+ CTL_AUTHENTICATED_STATE, 2, 2, cmd_stop },
+ { "start", "start component",
+ CTL_AUTHENTICATED_STATE, 2, 2, cmd_start },
+ { "restart", "restart component",
+ CTL_AUTHENTICATED_STATE, 2, 2, cmd_restart },
+ { "reboot", "restart pies",
+ CTL_AUTHENTICATED_STATE, 1, 1, cmd_reboot },
+ { "shutdown", "stop pies",
+ CTL_AUTHENTICATED_STATE, 1, 1, cmd_shutdown },
{ NULL }
};
@@ -152,6 +168,7 @@ ctlio_command_find (char const *verb)
struct ctlio
{
int state;
+ int action;
struct ctlbuf ibuf;
struct ctlbuf obuf;
struct wordsplit ws;
@@ -165,6 +182,7 @@ ctlio_create (void)
io = xmalloc (sizeof (*io));
io->state = CTL_AUTHENTICATED_STATE; //FIXME CTL_INITIAL_STATE;
+ io->action = ACTION_CONT;
ctlbuf_init (&io->ibuf);
ctlbuf_init (&io->obuf);
io->ws.ws_delim = " \t()";
@@ -678,7 +696,8 @@ pcond_parse_binary (struct pcond_parser_state *state, struct pcond_node **ret)
else
{
pcond_free (pleft);
- ctlio_reply (state->io, "551", "expected 'and' or 'or', but found %s", term);
+ ctlio_reply (state->io, "551", "expected 'and' or 'or', but found %s",
+ term);
return -1;
}
@@ -754,16 +773,16 @@ list_prog (struct prog *prog, void *data)
ctlio_printf (io, "PID: %lu%s", (unsigned long) prog->pid, CRLF);
else if (prog->v.p.status == status_listener
&& prog->v.p.comp->socket_url)
- ctlio_printf (io, "URL: %10s%s", prog->v.p.comp->socket_url->string, CRLF);
+ ctlio_printf (io, "URL: %10s%s", prog->v.p.comp->socket_url->string,
+ CRLF);
-#if 0
- //FIXME
if (prog->v.p.status == status_sleeping)
{
- time_t t = prog->v.p.timestamp + SLEEPTIME;
- fprintftime (fp, "%H:%M:%S", localtime (&t), 0, 0);
+ ctlio_printf (io, "Wakeup-Time: %lu%s",
+ (unsigned long) (prog->v.p.timestamp + SLEEPTIME),
+ CRLF);
}
-#endif
+
ctlio_printf (io, "Command:");
for (i = 0; i < prog->v.p.comp->argc; i++)
ctlio_printf (io, " %s", quotearg (prog->v.p.comp->argv[i]));
@@ -813,6 +832,77 @@ cmd_list (struct ctlio *io, size_t argc, char **argv)
pcond_free (env.cond);
}
+
+static void
+cmd_start (struct ctlio *io, size_t argc, char **argv)
+{
+ char const *tag = argv[1];
+ struct prog *prog = progman_locate (tag);
+ if (!prog)
+ ctlio_reply (io, "552", "Component not found");
+ else if (!IS_COMPONENT (prog))
+ ctlio_reply (io, "553", "Not a component");
+ else if (prog->v.p.status != status_disabled)
+ ctlio_reply (io, "554", "Not stopped");
+ else
+ {
+ prog->v.p.comp->flags &= CF_DISABLED;
+ prog->v.p.status = status_enabled;
+ kill (getpid (), SIGALRM);
+ ctlio_reply (io, "250", "Complete");
+ }
+}
+
+static void
+cmd_stop (struct ctlio *io, size_t argc, char **argv)
+{
+ char const *tag = argv[1];
+ struct prog *prog = progman_locate (tag);
+ if (!prog)
+ ctlio_reply (io, "552", "Component not found");
+ else if (!IS_COMPONENT (prog))
+ ctlio_reply (io, "553", "Not a component");
+ else
+ {
+ progman_stop_component (prog);
+ prog->v.p.comp->flags |= CF_DISABLED;
+ ctlio_reply (io, "250", "Complete");
+ }
+}
+
+static void
+cmd_restart (struct ctlio *io, size_t argc, char **argv)
+{
+ char const *tag = argv[1];
+ struct prog *prog = progman_locate (tag);
+ if (!prog)
+ ctlio_reply (io, "552", "Component not found");
+ else if (!(IS_COMPONENT (prog)
+ && !(prog->v.p.comp->mode == pies_comp_inetd
+ && prog->v.p.listener)))
+ ctlio_reply (io, "553", "Not a component");
+ else
+ {
+ progman_stop_component (prog);
+ ctlio_reply (io, "250", "Complete");
+ }
+}
+
+static void
+cmd_reboot (struct ctlio *io, size_t argc, char **argv)
+{
+ io->action = ACTION_RESTART;
+ io->state = CTL_ACTION_STATE;
+ ctlio_reply (io, "250", "Rebooting, closing connection");
+}
+
+static void
+cmd_shutdown (struct ctlio *io, size_t argc, char **argv)
+{
+ io->action = ACTION_STOP;
+ io->state = CTL_ACTION_STATE;
+ ctlio_reply (io, "250", "Shuttign down, connection will be closed");
+}
static int ctlrd (int fd, void *data);
static int ctlwr (int fd, void *data);
@@ -864,6 +954,11 @@ ctlwr (int fd, void *data)
write (fd, &c, 1);
else if (io->state == CTL_END_STATE)
return ctlio_end (fd, io);
+ else if (io->state == CTL_ACTION_STATE)
+ {
+ pies_schedule_action (io->action);
+ return ctlio_end (fd, io);
+ }
else
{
update_socket (fd, PIES_EVT_WR, NULL);
diff --git a/src/pies.c b/src/pies.c
index 60663a5..9aa1a37 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -1797,6 +1797,13 @@ int action = ACTION_CONT;
int children_cleanup = 0;
int got_alarm = 0;
+void
+pies_schedule_action (int act)
+{
+ action = act;
+ /*FIXME: got_alarm?*/
+}
+
RETSIGTYPE
sig_handler (int sig)
{
@@ -1995,7 +2002,7 @@ stop_components ()
continue;
if (buf[len - 1] == '\n')
buf[len - 1] = 0;
- progman_stop_component (buf);
+ progman_stop_tag (buf);
}
free (buf);
diff --git a/src/pies.h b/src/pies.h
index f882f63..82ffddb 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -308,6 +308,8 @@ void add_config (enum config_syntax syntax, const char *name);
void free_redirector (struct redirector *rp);
+void pies_schedule_action (int act);
+
void register_prog (struct component *comp);
int progman_running_p (void);
size_t progman_running_count (void);
@@ -317,7 +319,7 @@ void progman_stop (void);
void progman_cleanup (int expect_term);
void progman_filter (int (*filter) (struct component *, void *data),
void *data);
-void progman_stop_component (const char *name);
+void progman_stop_tag (const char *name);
void progman_dump_stats (const char *filename);
void progman_dump_prereq (void);
void progman_dump_depmap (void);
diff --git a/src/prog.h b/src/prog.h
index 9e55e56..6590d4e 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -84,5 +84,7 @@ struct prog
#define IS_COMPONENT(p) ((p)->type == TYPE_COMPONENT)
+struct prog *progman_locate (const char *name);
void progman_foreach (int (*filter) (struct prog *, void *data), void *data);
void prog_stop (struct prog *prog, int sig);
+void progman_stop_component (struct prog *prog);
diff --git a/src/progman.c b/src/progman.c
index d045efa..90d54b5 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -23,6 +23,17 @@ static pies_depmap_t depmap;
static int recompute_alarm;
static struct grecs_symtab *conn_tab;
+struct prog *
+progman_locate (const char *name)
+{
+ struct prog *prog;
+
+ for (prog = proghead; prog; prog = prog->next)
+ if (strcmp (prog->tag, name) == 0)
+ break;
+ return prog;
+}
+
void
progman_foreach (int (*filter) (struct prog *, void *data), void *data)
{
@@ -624,7 +635,6 @@ static size_t envsize; /* Size of environ. If it is not 0, then we
#define ENV_REMOTEIP "REMOTEIP"
#define ENV_REMOTEPORT "REMOTEPORT"
#define ENV_REMOTEHOST "REMOTEHOST"
-
static char *sockenv_hint[] = {
"-" ENV_PROTO,
"-" ENV_SOCKTYPE,
@@ -2395,7 +2405,8 @@ progman_cleanup (int expect_term)
if (is_sysvinit (prog->v.p.comp))
sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog->tag, pid, "");
- prog->v.p.status = status_enabled;
+ prog->v.p.status = (prog->v.p.comp->flags & CF_DISABLED)
+ ? status_disabled : status_enabled;
prog_stop_dependents (prog);
if (!expect_term)
react (prog, status, pid);
@@ -2426,36 +2437,44 @@ progman_cleanup (int expect_term)
}
void
-progman_stop_component (const char *name)
+progman_stop_component (struct prog *prog)
{
- struct prog *prog;
-
- for (prog = proghead; prog; prog = prog->next)
- if (IS_COMPONENT (prog) && strcmp (prog->tag, name) == 0)
- {
- logmsg (LOG_INFO, _("stopping component `%s'"), prog->tag);
- switch (prog->v.p.status)
- {
- case status_enabled:
- case status_listener:
- prog_stop (prog, SIGTERM);
- break;
-
- case status_disabled:
- if (!(prog->v.p.comp->flags & CF_DISABLED))
+ if (prog && IS_COMPONENT (prog))
+ {
+ switch (prog->v.p.status)
+ {
+ case status_enabled:
+ case status_listener:
+ logmsg (LOG_INFO, _("stopping component `%s'"), prog->tag);
+ prog_stop (prog, SIGTERM);
+ break;
+
+ case status_disabled:
+ if (!(prog->v.p.comp->flags & CF_DISABLED))
+ {
+ logmsg (LOG_INFO, _("enabling component `%s'"), prog->tag);
prog->v.p.status = status_enabled;
- break;
+ }
+ break;
- case status_sleeping:
- prog->v.p.failcount = 0;
- break;
-
- default:
- logmsg (LOG_INFO,
- _("stopping component `%s': component not started"),
- prog->tag);
- }
- }
+ case status_sleeping:
+ logmsg (LOG_INFO, _("waking up component `%s'"), prog->tag);
+ prog->v.p.failcount = 0;
+ break;
+
+ default:
+ logmsg (LOG_INFO,
+ _("stopping component `%s': component not started"),
+ prog->tag);
+ }
+ }
+}
+
+void
+progman_stop_tag (const char *name)
+{
+ struct prog *prog = progman_locate (name);
+ progman_stop_component (prog);
}
void

Return to:

Send suggestions and report system problems to the System administrator.