aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-02-15 22:24:04 +0200
committerSergey Poznyakoff <gray@gnu.org>2016-02-15 22:24:04 +0200
commit27366c475aa4955f296f169cf9acd33e36b9d7b3 (patch)
tree3e09f2ae80c423ccd2a0a2929852be3560cb1d2b
parent0a5eb4f65a20d37f2051dce8816485dd219fb735 (diff)
downloadpies-27366c475aa4955f296f169cf9acd33e36b9d7b3.tar.gz
pies-27366c475aa4955f296f169cf9acd33e36b9d7b3.tar.bz2
Implement emergency shell.
* src/pies.c (main): Move init-specific command line handling to sysvinit_parse_argv. * src/pies.h (dfl_level): Remove extern. (sysvinit_parse_argv): New proto. * src/sysvinit.c (sysvinit_parse_argv): New function. (sysvinit_begin): Start emergency shell, if requested.
-rw-r--r--src/pies.c40
-rw-r--r--src/pies.h2
-rw-r--r--src/progman.c6
-rw-r--r--src/sysvinit.c72
4 files changed, 95 insertions, 25 deletions
diff --git a/src/pies.c b/src/pies.c
index 3734b47..653a865 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -1927,7 +1927,6 @@ char **pies_master_argv;
1927int 1927int
1928main (int argc, char **argv) 1928main (int argc, char **argv)
1929{ 1929{
1930 int index;
1931 pid_t pid; 1930 pid_t pid;
1932 extern char **environ; 1931 extern char **environ;
1933 struct grecs_list_entry *ep; 1932 struct grecs_list_entry *ep;
@@ -2001,18 +2000,24 @@ main (int argc, char **argv)
2001 config_file_add_type (CONF_INITTAB, "/etc/inittab"); 2000 config_file_add_type (CONF_INITTAB, "/etc/inittab");
2002 config_file_add_type (CONF_PIES, "/etc/pies.init"); 2001 config_file_add_type (CONF_PIES, "/etc/pies.init");
2003#endif 2002#endif
2004 for (index = 1; index < argc; index++) 2003 sysvinit_parse_argv (argc, argv);
2004 }
2005 else
2006 {
2007 int index;
2008
2009 parse_options (argc, argv, &index);
2010 argc -= index;
2011 argv += index;
2012
2013 if (argc && !(command == COM_RESTART_COMPONENT
2014 || command == COM_TRACE_DEPEND
2015 || command == COM_TRACE_PREREQ))
2005 { 2016 {
2006 if (!strcmp (argv[index], "single") || !strcmp (argv[index], "-s")) 2017 logmsg (LOG_ERR, "extra command line arguments");
2007 dfl_level = 'S'; 2018 exit (EX_USAGE);
2008 else if (strchr("0123456789sS", argv[index][0]) && !argv[index][1])
2009 {
2010 dfl_level = toupper (argv[index][0]);
2011 }
2012 } 2019 }
2013 } 2020 }
2014 else
2015 parse_options (argc, argv, &index);
2016 2021
2017 if (!instance) 2022 if (!instance)
2018 { 2023 {
@@ -2059,15 +2064,6 @@ main (int argc, char **argv)
2059 /* Re-setup logging: it might have been reset in the config file */ 2064 /* Re-setup logging: it might have been reset in the config file */
2060 diag_setup (log_to_stderr_only ? DIAG_TO_STDERR : 0); 2065 diag_setup (log_to_stderr_only ? DIAG_TO_STDERR : 0);
2061 2066
2062 if (argc != index
2063 && !(command == COM_RESTART_COMPONENT
2064 || command == COM_TRACE_DEPEND
2065 || command == COM_TRACE_PREREQ))
2066 {
2067 logmsg (LOG_ERR, "extra command line arguments");
2068 exit (EX_CONFIG);
2069 }
2070
2071 if (!control.url) 2067 if (!control.url)
2072 { 2068 {
2073 char const *str = default_control_url[init_process]; 2069 char const *str = default_control_url[init_process];
@@ -2086,7 +2082,7 @@ main (int argc, char **argv)
2086 pies_priv_setup (&pies_privs); 2082 pies_priv_setup (&pies_privs);
2087 if (pies_umask) 2083 if (pies_umask)
2088 umask (pies_umask); 2084 umask (pies_umask);
2089 exit (request_restart_components (argc - index, argv + index)); 2085 exit (request_restart_components (argc, argv));
2090 2086
2091 case COM_RELOAD: 2087 case COM_RELOAD:
2092 exit (request_reload ()); 2088 exit (request_reload ());
@@ -2102,11 +2098,11 @@ main (int argc, char **argv)
2102 exit (0); 2098 exit (0);
2103 2099
2104 case COM_TRACE_DEPEND: 2100 case COM_TRACE_DEPEND:
2105 components_trace (argv + index, depmap_row); 2101 components_trace (argv, depmap_row);
2106 exit (0); 2102 exit (0);
2107 2103
2108 case COM_TRACE_PREREQ: 2104 case COM_TRACE_PREREQ:
2109 components_trace (argv + index, depmap_col); 2105 components_trace (argv, depmap_col);
2110 exit (0); 2106 exit (0);
2111 2107
2112 default: 2108 default:
diff --git a/src/pies.h b/src/pies.h
index bcce32a..4a6160f 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -291,7 +291,6 @@ extern char *qotdfile;
291extern int init_process; 291extern int init_process;
292extern char *console_device; 292extern char *console_device;
293extern int initdefault; 293extern int initdefault;
294extern int dfl_level;
295 294
296extern size_t pies_master_argc; 295extern size_t pies_master_argc;
297extern char **pies_master_argv; 296extern char **pies_master_argv;
@@ -523,6 +522,7 @@ void sysvinit_power (void);
523 522
524void sysvinit_report (struct json_value *obj); 523void sysvinit_report (struct json_value *obj);
525int sysvinit_set_runlevel (int newlevel); 524int sysvinit_set_runlevel (int newlevel);
525void sysvinit_parse_argv (int argc, char **argv);
526 526
527extern char *sysvinit_environ_hint[]; 527extern char *sysvinit_environ_hint[];
528extern char *init_fifo; 528extern char *init_fifo;
diff --git a/src/progman.c b/src/progman.c
index 8a5187c..1be7d27 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -1205,7 +1205,7 @@ prog_start (struct prog *prog)
1205 close_fds (&fdset); 1205 close_fds (&fdset);
1206 1206
1207 prog_execute (prog); 1207 prog_execute (prog);
1208 1208
1209 1209
1210 case -1: 1210 case -1:
1211 logmsg (LOG_CRIT, 1211 logmsg (LOG_CRIT,
@@ -1546,6 +1546,9 @@ progman_wake_sleeping (int onalrm)
1546 { 1546 {
1547 if (IS_ACTIVE_COMPONENT (prog) && prog->v.p.wait) 1547 if (IS_ACTIVE_COMPONENT (prog) && prog->v.p.wait)
1548 { 1548 {
1549 /* The following works on the assumption that prog->v.p.wait is
1550 set when enabling the component and gets cleared right after
1551 it has finished. */
1549 if (prog->v.p.status != status_running) 1552 if (prog->v.p.status != status_running)
1550 prog_start (prog); 1553 prog_start (prog);
1551 return; 1554 return;
@@ -2411,4 +2414,5 @@ progman_stop_tag (const char *name)
2411 struct prog *prog = progman_locate (name); 2414 struct prog *prog = progman_locate (name);
2412 progman_stop_component (&prog); 2415 progman_stop_component (&prog);
2413} 2416}
2417
2414/* EOF */ 2418/* EOF */
diff --git a/src/sysvinit.c b/src/sysvinit.c
index 2d0671c..0370fcc 100644
--- a/src/sysvinit.c
+++ b/src/sysvinit.c
@@ -16,6 +16,7 @@
16 16
17#include "pies.h" 17#include "pies.h"
18#include "prog.h" 18#include "prog.h"
19#include <sys/ioctl.h>
19#include <termios.h> 20#include <termios.h>
20 21
21enum boot_state 22enum boot_state
@@ -59,12 +60,13 @@ int prevlevel = 'N';
59 60
60int initdefault; /* Default runlevel */ 61int initdefault; /* Default runlevel */
61int dfl_level; 62int dfl_level;
63int emergency_shell;
62 64
63int 65int
64console_open (int mode) 66console_open (int mode)
65{ 67{
66 int i, fd; 68 int i, fd;
67 69
68 for (i = 0; i < 5; i++) 70 for (i = 0; i < 5; i++)
69 { 71 {
70 fd = open (console_device, mode | O_NONBLOCK); 72 fd = open (console_device, mode | O_NONBLOCK);
@@ -646,6 +648,56 @@ unintr_sleep (unsigned n)
646 ; 648 ;
647} 649}
648 650
651static void
652start_shell (const char *shell)
653{
654 pid_t pid, rc;
655 int st;
656 struct sigaction act, old;
657
658 act.sa_flags = SA_RESTART;
659 act.sa_handler = SIG_DFL;
660 sigemptyset (&act.sa_mask);
661 sigaction (SIGCHLD, &act, &old);
662
663 pid = fork ();
664 if (pid == -1)
665 {
666 logmsg (LOG_CRIT, "cannot run `%s': fork failed: %s",
667 shell, strerror (errno));
668 exit (1);
669 }
670
671 if (pid == 0)
672 {
673 int fd;
674
675 signal_setup (SIG_DFL);
676 setsid ();
677
678 fd = console_open (O_RDWR|O_NOCTTY);
679 if (fd < 0)
680 {
681 logmsg (LOG_CRIT, "open(%s): %s",
682 console_device, strerror (errno));
683 exit (1);
684 }
685 ioctl (fd, TIOCSCTTY, 1);
686 dup (fd);
687 dup (fd);
688
689 execl (shell, shell, NULL);
690 _exit (127);
691 }
692
693 while ((rc = wait (&st)) != pid)
694 if (rc == (pid_t) -1 && errno == ECHILD)
695 break;
696
697 logmsg (LOG_CRIT, "shell finished");
698 sigaction (SIGCHLD, &old, NULL);
699}
700
649/* Memory allocation functions for INIT. They may not fail, therefore 701/* Memory allocation functions for INIT. They may not fail, therefore
650 they just retry allocation until it eventually succeeds. 702 they just retry allocation until it eventually succeeds.
651*/ 703*/
@@ -698,6 +750,8 @@ sysvinit_begin ()
698 sysvinit_runlevel_setup (PIES_COMP_DEFAULT); 750 sysvinit_runlevel_setup (PIES_COMP_DEFAULT);
699 add_extra_sigv (sigv, ARRAY_SIZE (sigv)); 751 add_extra_sigv (sigv, AR