diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2015-12-20 00:50:52 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2015-12-20 00:59:25 +0200 |
commit | d479bd2f63445524253e16d8575a0592c266908d (patch) | |
tree | aae2188767328ee7dac100e14ad58ec75eeb35e5 | |
parent | 84e4b3d5274c599ed30482bfe2ca8af080d936af (diff) | |
download | pies-d479bd2f63445524253e16d8575a0592c266908d.tar.gz pies-d479bd2f63445524253e16d8575a0592c266908d.tar.bz2 |
Bugfixes in init mode
* src/ctl.c (ctl_open): Add missing return.
* src/pies.c (config_parse): Return if tree is null.
(main) [INIT_EMU]: Print more info. Override default init_fifo.
Don't use syslog and control socket if running as init process.
* src/pies.h (init_fifo): New extern.
* src/progman.c (open_redirector): Return -1 if running as init process.
(prog_start): Always initialize redir[].
* src/sysvinit.c (init_fifo): New variable. Use it instead if the
INIT_FIFO macro.
(inittrans): Call create_fifo once, when transiting from boot to
normal state.
-rw-r--r-- | src/ctl.c | 4 | ||||
-rw-r--r-- | src/pies.c | 44 | ||||
-rw-r--r-- | src/pies.h | 1 | ||||
-rw-r--r-- | src/progman.c | 18 | ||||
-rw-r--r-- | src/sysvinit.c | 34 |
5 files changed, 67 insertions, 34 deletions
@@ -1187,20 +1187,22 @@ ctl_open () { char *str = xasprintf (DEFAULT_CONTROL_URL, instance); if (pies_url_create (&control.url, str)) { logmsg (LOG_CRIT, _("%s: cannot create URL: %s"), str, strerror (errno)); + return; } free (str); } fd = create_socket (control.url, SOCK_STREAM, NULL, 077); if (fd == -1) { - logmsg (LOG_CRIT, _("can't create control socket %s"), control.url->string); + logmsg (LOG_CRIT, _("can't create control socket %s"), + control.url->string); exit (EX_UNAVAILABLE); } if (listen (fd, 8)) { logmsg (LOG_CRIT, "can't listen on control socket %s: %s", @@ -19,13 +19,13 @@ #include <configmake.h> #include "meta1lex.h" #include "identity.h" int preprocess_only; /* Preprocess config, do nothing more */ int lint_mode; /* Test configuration syntax and exit */ -int log_to_stderr_only; /* Use only stderr for logging */ +int log_to_stderr_only; /* Use only stderr for logging */ int log_facility = LOG_USER; char *log_tag; struct pies_privs pies_privs; int foreground; int init_process; @@ -1813,15 +1813,19 @@ config_error () void config_parse (char const *name) { struct grecs_node *node; struct grecs_node *tree = grecs_parse (name); - if (!tree) - config_error (); + if (!tree) + { + config_error (); + return; + } + for (node = tree; node; node = node->next) { node = grecs_find_node (node, "identity-provider"); if (!node) break; pies_config_provider (node); @@ -2302,13 +2306,14 @@ int main (int argc, char **argv) { int index; pid_t pid; extern char **environ; struct grecs_list_entry *ep; - + int diag_flags; + set_program_name (argv[0]); #ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); bindtextdomain ("pies", LOCALEDIR); textdomain (PACKAGE); @@ -2319,32 +2324,51 @@ main (int argc, char **argv) init_process = getpid () == 1; #ifdef INIT_EMU # warning "pies compiled with init emulation code" if (!init_process) { - fprintf (stderr, "%s: to enable init emulation code,\n", program_name); - fprintf (stderr, "%s: define environment variable INIT_EMU=<inittab>[:<pies_init_file>]\n", program_name); init_process = getenv ("INIT_EMU") != NULL; + if (init_process) + fprintf (stderr, "%s: running in init emulation mode\n", program_name); + else + { + fprintf (stderr, + "%s: to enable init emulation code,\n", program_name); + fprintf (stderr, + "%s: define environment variable INIT_EMU=<inittab>[:<pies_init_file>]\n", program_name); + fprintf (stderr, + "%s: define variable INIT_FIFO=<pathname> to override the default FIFO name\n", + program_name); + } } #endif /* Set default logging */ - diag_setup (DIAG_TO_SYSLOG | (stderr_closed_p () ? 0 : DIAG_TO_STDERR)); + if (init_process) + diag_flags = DIAG_TO_STDERR; + else + diag_flags = DIAG_TO_SYSLOG | (stderr_closed_p () ? 0 : DIAG_TO_STDERR); + + diag_setup (diag_flags); config_init (); if (init_process) { #ifdef INIT_EMU char *emu = getenv ("INIT_EMU"); if (emu) { char *inittab = strtok (emu, ":"); char *piesinit = strtok (NULL, ":"); add_config (CONF_INITTAB, inittab); add_config (CONF_PIES, piesinit ? piesinit : "/etc/pies.init"); + + init_fifo = getenv ("INIT_FIFO"); + if (!init_fifo) + init_fifo = "/tmp/initctl"; } else { add_config (CONF_INITTAB, "/etc/inittab"); add_config (CONF_PIES, "/etc/pies.init"); } @@ -2514,15 +2538,17 @@ main (int argc, char **argv) logmsg (LOG_ERR, _("cannot become a daemon: %s"), strerror (errno)); exit (EX_SOFTWARE); } diag_setup (DIAG_TO_SYSLOG); } - ctl_open (); if (!init_process) - create_pidfile (pidfile); + { + ctl_open (); + create_pidfile (pidfile); + } if (argv[0][0] != '/') logmsg (LOG_NOTICE, _("not started as an absolute pathname; " "SIGHUP will not work")); @@ -522,12 +522,13 @@ int telinit (const char *arg); int inittab_parse (const char *file); int sysvinit_sigtrans (int sig, int *pact); void sysvinit_runlevel_setup (int mask, int *wait); void sysvinit_sysdep_begin (void); extern char *sysvinit_environ_hint[]; +extern char *init_fifo; #ifndef INIT_FIFO # define INIT_FIFO "/dev/initctl" #endif #define INIT_MAGIC 0x03091969 diff --git a/src/progman.c b/src/progman.c index 4864531..8c33db8 100644 --- a/src/progman.c +++ b/src/progman.c @@ -429,13 +429,16 @@ open_redirector (struct prog *master, int stream) char *buf = NULL; size_t size = 0; pid_t pid; int prio; char *tag; fd_set fdset; - + + if (init_process) + return -1; + switch (master->v.p.comp->redir[stream].type) { case redir_null: return -1; case redir_file: @@ -1157,17 +1160,14 @@ prog_start (struct prog *prog) if (prog->v.p.comp->builtin && prog->v.p.comp->builtin->single_process) { prog->v.p.comp->builtin->fun (prog->v.p.socket, prog->v.p.comp); return; } - if (!init_process) - { - redir[RETR_OUT] = open_redirector (prog, RETR_OUT); - redir[RETR_ERR] = open_redirector (prog, RETR_ERR); - } + redir[RETR_OUT] = open_redirector (prog, RETR_OUT); + redir[RETR_ERR] = open_redirector (prog, RETR_ERR); switch (pid = fork ()) { /* The child branch. */ case 0: signal_setup (SIG_DFL); @@ -1278,14 +1278,16 @@ prog_start (struct prog *prog) prog->v.p.comp->mode == pies_comp_inetd || prog->v.p.comp->mode == pies_comp_pass_fd) close (prog->v.p.socket); else if (is_sysvinit (prog->v.p.comp)) sysvinit_acct (SYSV_ACCT_PROC_START, "", prog->tag, pid, ""); - close (redir[RETR_OUT]); - close (redir[RETR_ERR]); + if (redir[RETR_OUT] != -1) + close (redir[RETR_OUT]); + if (redir[RETR_ERR]) + close (redir[RETR_ERR]); prog->pid = pid; prog->v.p.status = status_enabled; debug (1, (_("%s started, pid=%lu"), prog->tag, (unsigned long) pid)); } } diff --git a/src/sysvinit.c b/src/sysvinit.c index 4fd4559..faa504a 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -396,12 +396,13 @@ sysvinit_setenv (char const *data, int size) sysvinit_environ_hint[j]; break; } } } +char *init_fifo = INIT_FIFO; static void create_fifo (void); static int sysvinit_fifo_handler (int fd, void *data) { static size_t size; @@ -412,20 +413,20 @@ sysvinit_fifo_handler (int fd, void *data) } buf; int rc; rc = read (fd, buf.data + size, sizeof (struct sysvinit_request) - size); if (rc == -1) { - logmsg (LOG_ERR, _("error reading from %s: %s"), INIT_FIFO, + logmsg (LOG_ERR, _("error reading from %s: %s"), init_fifo, strerror (errno)); size = 0; return 0; } if (rc == 0) { - logmsg (LOG_ERR, _("end of file on %s: reopening"), INIT_FIFO); + logmsg (LOG_ERR, _("end of file on %s: reopening"), init_fifo); size = 0; close (fd); deregister_socket (fd); create_fifo (); return 0; } @@ -467,57 +468,57 @@ sysvinit_fifo_handler (int fd, void *data) static void create_fifo () { static int fd = -1; struct stat st, fst; - if (stat (INIT_FIFO, &st) < 0) + if (stat (init_fifo, &st) < 0) { if (errno != ENOENT) { - logmsg (LOG_ERR, "cannot stat fifo %s: %s", INIT_FIFO, + logmsg (LOG_ERR, "cannot stat fifo %s: %s", init_fifo, strerror (errno)); return; } - else if (mkfifo (INIT_FIFO, 0600)) + else if (mkfifo (init_fifo, 0600)) { - logmsg (LOG_ERR, "cannot create fifo %s: %s", INIT_FIFO, + logmsg (LOG_ERR, "cannot create fifo %s: %s", init_fifo, strerror (errno)); return; } } else { if (!S_ISFIFO (st.st_mode)) { - logmsg (LOG_ERR, "not a fifo: %s", INIT_FIFO); + logmsg (LOG_ERR, "not a fifo: %s", init_fifo); return; } - chmod (INIT_FIFO, 0600); + chmod (init_fifo, 0600); } if (fd != -1) { fstat (fd, &fst); if (fst.st_dev != st.st_dev || fst.st_ino != st.st_ino) { deregister_socket (fd); close (fd); } - debug (1, ("reopening %s", INIT_FIFO)); + debug (1, ("reopening %s", init_fifo)); } /* Opening the socket in read-write mode ensures we won't get EOF on it when the caller party closes connection (at least on Linux). Nevertheless, the svinit_fifo_handler is prepared for that eventuality, too. */ - fd = open (INIT_FIFO, O_RDWR|O_NONBLOCK); + fd = open (init_fifo, O_RDWR|O_NONBLOCK); if (fd == -1) { - logmsg (LOG_ERR, "cannot open %s: %s", INIT_FIFO, + logmsg (LOG_ERR, "cannot open %s: %s", init_fifo, strerror (errno)); return; } register_socket (fd, sysvinit_fifo_handler, NULL, NULL, NULL); } @@ -628,15 +629,16 @@ inittrans () sysvinit_acct (SYSV_ACCT_BOOT, "reboot", "~~", 0, "~"); break; case single: newlevel = 'S'; break; case normal: - /* boot -> normal */ newlevel = dfl_level ? dfl_level : getinitdefault (); - create_fifo (); + if (trans) + /* boot -> normal */ + create_fifo (); } if (newlevel && newlevel != runlevel) { prevlevel = runlevel ? runlevel : 'N'; debug (1, ("RL TRANS: %c -> %c", prevlevel, newlevel)); sysvinit_acct (SYSV_ACCT_RUNLEVEL, "runlevel", "~~", @@ -700,22 +702,22 @@ telinit (const char *arg) #if 0 req.sleeptime = sltime; #endif signal (SIGALRM, SIG_DFL); alarm (5); - fd = open (INIT_FIFO, O_WRONLY); + fd = open (init_fifo, O_WRONLY); if (fd < 0) { - logmsg (LOG_ERR, _("can't open %s: %s"), INIT_FIFO, strerror (errno)); + logmsg (LOG_ERR, _("can't open %s: %s"), init_fifo, strerror (errno)); exit (EX_UNAVAILABLE); } if (write (fd, &req, sizeof (req)) != sizeof (req)) { logmsg (LOG_ERR, _("error writing to %s: %s"), - INIT_FIFO, strerror (errno)); + init_fifo, strerror (errno)); exit (EX_UNAVAILABLE); } alarm (0); close (fd); exit (0); } |