diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-11-05 10:26:17 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-11-05 10:26:17 +0200 |
commit | e7e3df9a6c4599f982a62bb8d7cd973ccd8cee72 (patch) | |
tree | e897c5d7e85bdaa5503aab6a25c174cf06d1c5d2 /src | |
parent | 6cc676f7f8d86849607b7f707c8682e7efdb65c3 (diff) | |
download | pies-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/ctl.c | 109 | ||||
-rw-r--r-- | src/pies.c | 9 | ||||
-rw-r--r-- | src/pies.h | 4 | ||||
-rw-r--r-- | src/prog.h | 2 | ||||
-rw-r--r-- | src/progman.c | 77 |
5 files changed, 163 insertions, 38 deletions
@@ -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); @@ -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); @@ -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); @@ -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 |