aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-01-06 17:04:28 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2013-01-06 17:04:28 +0200
commit1bfa33ac7c167cd863b88a5cac7690d511851e6e (patch)
treea892e281cba3ea127af5faf5da81ff2cc0c3aae9
parent4f7c28158308563dcad912d87a0031d095d4690a (diff)
downloadpies-1bfa33ac7c167cd863b88a5cac7690d511851e6e.tar.gz
pies-1bfa33ac7c167cd863b88a5cac7690d511851e6e.tar.bz2
Fix runlevel transition algorithm, implement SysV-style fifo interface.
* src/prog.h: New file. * src/Makefile.am: Add new file. * src/cmdline.opt: New option --telinit (-T). * src/diag.c (vlogmsg): In sysvin it mode, write directly to the console. Close it when finished. * src/pies.c (_cb_initdefault, _cb_runlevels): Use is_valid_runlevel to check if the specified runlevels are ok. (main): In sysvinit mode, reset action to ACTION_CONT. * src/pies.h (progman_filter): New proto. (progman_accept,register_socket): Change signature. (deregister_socket): New proto. (register_program_socket): New proto. * src/progman.c: Move constant and adatatype definitions to prog.h (prog_stop): Remove static qualifier. (console_open): Likewise. (progman_accept): Use new socket API. (progman_stop): Correctly handle timeouts. (progman_foreach): New function. * src/socket.c: Register all sockets along with their handlers in a doubly-linked list. (sockinst): New struct. (register_socket,deregister_socket): New functions. (register_program_socket): New function. (pies_pause): Traverse the list to find which fd has changed. Use its registered handler to handle the event. * src/sysvinit.c: Include prog.h (is_valid_runlevel): New function. (sysvinit_fifo_handler,check_fifo): New static functions. (inittrans): Fix transition algorithm. (telinit): New function.
-rw-r--r--src/Makefile.am3
-rw-r--r--src/cmdline.opt9
-rw-r--r--src/diag.c31
-rw-r--r--src/pies.c16
-rw-r--r--src/pies.h36
-rw-r--r--src/prog.h85
-rw-r--r--src/progman.c125
-rw-r--r--src/socket.c106
-rw-r--r--src/sysvinit.c192
9 files changed, 488 insertions, 115 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 3752eae..9e9bf80 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -40,7 +40,8 @@ noinst_HEADERS = \
40 cmdline.h\ 40 cmdline.h\
41 meta1gram.h\ 41 meta1gram.h\
42 meta1lex.h\ 42 meta1lex.h\
43 pies.h 43 pies.h\
44 prog.h
44 45
45meta1lex.c: meta1gram.h 46meta1lex.c: meta1gram.h
46 47
diff --git a/src/cmdline.opt b/src/cmdline.opt
index 31fcf20..76fc4da 100644
--- a/src/cmdline.opt
+++ b/src/cmdline.opt
@@ -110,7 +110,14 @@ BEGIN
110 log_to_stderr_only = 1; 110 log_to_stderr_only = 1;
111 lint_mode = 1; 111 lint_mode = 1;
112END 112END
113 113
114OPTION(telinit,T,RUNLEVEL,
115 [<emulate telinit command>])
116BEGIN
117 log_to_stderr_only = 1;
118 exit (telinit (optarg));
119END
120
114GROUP(Preprocessor) 121GROUP(Preprocessor)
115 122
116OPTION(define,D,[<NAME[=VALUE]>], 123OPTION(define,D,[<NAME[=VALUE]>],
diff --git a/src/diag.c b/src/diag.c
index fe057d0..bb64ab9 100644
--- a/src/diag.c
+++ b/src/diag.c
@@ -42,17 +42,42 @@ syslog_printer (int prio, const char *fmt, va_list ap)
42#endif 42#endif
43} 43}
44 44
45static FILE *
46stderr_open ()
47{
48 if (!init_process)
49 return stderr;
50 else
51 {
52 int fd = console_open (O_WRONLY|O_NOCTTY|O_NDELAY);
53 if (fd == -1)
54 return NULL;
55 return fdopen (fd, "w");
56 }
57}
58
59static void
60stderr_close (FILE *fp)
61{
62 if (init_process)
63 fclose (fp);
64}
65
45void 66void
46vlogmsg (int prio, const char *fmt, va_list ap) 67vlogmsg (int prio, const char *fmt, va_list ap)
47{ 68{
48 if (DIAG_OUTPUT (DIAG_TO_STDERR)) 69 if (DIAG_OUTPUT (DIAG_TO_STDERR))
49 { 70 {
50 va_list aq; 71 va_list aq;
51 fprintf (stderr, "%s: ", program_name); 72 FILE *fp = stderr_open ();
73 if (!fp)
74 return;
75 fprintf (fp, "%s: ", program_name);
52 va_copy (aq, ap); 76 va_copy (aq, ap);
53 vfprintf (stderr, fmt, aq); 77 vfprintf (fp, fmt, aq);
54 va_end (aq); 78 va_end (aq);
55 fprintf (stderr, "\n"); 79 fprintf (fp, "\n");
80 stderr_close (fp);
56 } 81 }
57 82
58 if (DIAG_OUTPUT (DIAG_TO_SYSLOG)) 83 if (DIAG_OUTPUT (DIAG_TO_SYSLOG))
diff --git a/src/pies.c b/src/pies.c
index a2dc5e0..41ca486 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -959,8 +959,6 @@ _cb_flags (enum grecs_callback_command cmd,
959 return 0; 959 return 0;
960} 960}
961 961
962static const char valid_runlevels[] = "0123456789Ss";
963
964static int 962static int
965_cb_initdefault (enum grecs_callback_command cmd, 963_cb_initdefault (enum grecs_callback_command cmd,
966 grecs_locus_t *locus, 964 grecs_locus_t *locus,
@@ -975,7 +973,7 @@ _cb_initdefault (enum grecs_callback_command cmd,
975 grecs_error (locus, 0, _("argument must be a single character")); 973 grecs_error (locus, 0, _("argument must be a single character"));
976 return 1; 974 return 1;
977 } 975 }
978 if (!strchr (valid_runlevels, value->v.string[0])) 976 if (!is_valid_runlevel (value->v.string[0]))
979 { 977 {
980 grecs_error (locus, 0, _("not a valid runlevel")); 978 grecs_error (locus, 0, _("not a valid runlevel"));
981 return 1; 979 return 1;
@@ -995,7 +993,7 @@ _cb_runlevels (enum grecs_callback_command cmd,
995 return 1; 993 return 1;
996 for (p = value->v.string; *p; p++) 994 for (p = value->v.string; *p; p++)
997 { 995 {
998 if (!strchr (valid_runlevels, *p)) 996 if (!is_valid_runlevel (*p))
999 { 997 {
1000 grecs_error (locus, 0, _("not a valid runlevel: %c")); 998 grecs_error (locus, 0, _("not a valid runlevel: %c"));
1001 return 1; 999 return 1;
@@ -2332,7 +2330,7 @@ main (int argc, char **argv)
2332 (unsigned long) pid); 2330 (unsigned long) pid);
2333 exit (EX_USAGE); 2331 exit (EX_USAGE);
2334 } 2332 }
2335 2333
2336 logmsg (LOG_INFO, _("%s %s starting"), proginfo.package, proginfo.version); 2334 logmsg (LOG_INFO, _("%s %s starting"), proginfo.package, proginfo.version);
2337 2335
2338 if (!foreground) 2336 if (!foreground)
@@ -2381,6 +2379,14 @@ main (int argc, char **argv)
2381 progman_dump_stats (statfile); 2379 progman_dump_stats (statfile);
2382 action = ACTION_CONT; 2380 action = ACTION_CONT;
2383 break; 2381 break;
2382
2383 case ACTION_STOP:
2384 case ACTION_RESTART:
2385 if (init_process)
2386 {
2387 debug (1, ("ignoring stop/restart"));
2388 action = ACTION_CONT;
2389 }
2384 } 2390 }
2385 if (action == ACTION_CONT) 2391 if (action == ACTION_CONT)
2386 { 2392 {
diff --git a/src/pies.h b/src/pies.h
index e7ad1c6..2203d87 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -285,11 +285,13 @@ void progman_start (void);
285void progman_wake_sleeping (int); 285void progman_wake_sleeping (int);
286void progman_stop (void); 286void progman_stop (void);
287void progman_cleanup (int expect_term); 287void progman_cleanup (int expect_term);
288void progman_filter (int (*filter) (struct component *, void *data),
289 void *data);
288void progman_stop_component (const char *name); 290void progman_stop_component (const char *name);
289void progman_dump_stats (const char *filename); 291void progman_dump_stats (const char *filename);
290void progman_dump_prereq (void); 292void progman_dump_prereq (void);
291void progman_dump_depmap (void); 293void progman_dump_depmap (void);
292int progman_accept (int socket); 294int progman_accept (int socket, void *data);
293int progman_build_depmap (void); 295int progman_build_depmap (void);
294void progman_create_sockets (void); 296void progman_create_sockets (void);
295struct component *progman_lookup_component (const char *tag); 297struct component *progman_lookup_component (const char *tag);
@@ -362,7 +364,10 @@ void pies_url_destroy (struct pies_url **purl);
362const char * pies_url_get_arg (struct pies_url *url, const char *argname); 364const char * pies_url_get_arg (struct pies_url *url, const char *argname);
363 365
364void pies_pause (void); 366void pies_pause (void);
365int register_socket (int socktype, int fd); 367void *register_socket (int fd, int (*handler) (int, void *), void *data);
368void deregister_socket (int fd);
369
370int register_program_socket (int socktype, int fd, void *data);
366int pass_fd (const char *socket, int fd, unsigned time_out); 371int pass_fd (const char *socket, int fd, unsigned time_out);
367int create_socket (struct pies_url *url, int socket_type, 372int create_socket (struct pies_url *url, int socket_type,
368 const char *user, mode_t umask); 373 const char *user, mode_t umask);
@@ -456,6 +461,33 @@ struct inetd_builtin *inetd_builtin_lookup (const char *service, int socktype);
456void sysvinit_begin (void); 461void sysvinit_begin (void);
457int inittrans (void); 462int inittrans (void);
458int is_comp_wait (struct component *comp); 463int is_comp_wait (struct component *comp);
464int is_valid_runlevel (int c);
465
466#ifndef INIT_FIFO
467# define INIT_FIFO "/dev/initctl"
468#endif
469
470#define INIT_MAGIC 0x03091969
471#define INIT_CMD_START 0
472#define INIT_CMD_RUNLVL 1
473#define INIT_CMD_POWERFAIL 2
474#define INIT_CMD_POWERFAILNOW 3
475#define INIT_CMD_POWEROK 4
476#define INIT_CMD_BSD 5
477#define INIT_CMD_SETENV 6
478#define INIT_CMD_UNSETENV 7
479
480#define INIT_CMD_CHANGECONS 12345
481
482struct sysvinit_request {
483 int magic; /* Magic number */
484 int cmd; /* What kind of request */
485 int runlevel; /* Runlevel to change to */
486 int sleeptime; /* Time between TERM and KILL */
487 char pad[368];
488};
489
490
459 491
460/* utmp.c */ 492/* utmp.c */
461#define SYSV_ACCT_BOOT 0 493#define SYSV_ACCT_BOOT 0
diff --git a/src/prog.h b/src/prog.h
new file mode 100644
index 0000000..2fd4c47
--- /dev/null
+++ b/src/prog.h
@@ -0,0 +1,85 @@
1/* This file is part of GNU Pies.
2 Copyright (C) 2008, 2009, 2010, 2011 Sergey Poznyakoff
3
4 GNU Pies is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Pies is di