diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-01-06 17:04:28 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-01-06 17:04:28 +0200 |
commit | 1bfa33ac7c167cd863b88a5cac7690d511851e6e (patch) | |
tree | a892e281cba3ea127af5faf5da81ff2cc0c3aae9 | |
parent | 4f7c28158308563dcad912d87a0031d095d4690a (diff) | |
download | pies-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.am | 3 | ||||
-rw-r--r-- | src/cmdline.opt | 9 | ||||
-rw-r--r-- | src/diag.c | 31 | ||||
-rw-r--r-- | src/pies.c | 16 | ||||
-rw-r--r-- | src/pies.h | 36 | ||||
-rw-r--r-- | src/prog.h | 85 | ||||
-rw-r--r-- | src/progman.c | 125 | ||||
-rw-r--r-- | src/socket.c | 106 | ||||
-rw-r--r-- | src/sysvinit.c | 192 |
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 | ||
45 | meta1lex.c: meta1gram.h | 46 | meta1lex.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; |
112 | END | 112 | END |
113 | 113 | ||
114 | OPTION(telinit,T,RUNLEVEL, | ||
115 | [<emulate telinit command>]) | ||
116 | BEGIN | ||
117 | log_to_stderr_only = 1; | ||
118 | exit (telinit (optarg)); | ||
119 | END | ||
120 | |||
114 | GROUP(Preprocessor) | 121 | GROUP(Preprocessor) |
115 | 122 | ||
116 | OPTION(define,D,[<NAME[=VALUE]>], | 123 | OPTION(define,D,[<NAME[=VALUE]>], |
@@ -42,17 +42,42 @@ syslog_printer (int prio, const char *fmt, va_list ap) | |||
42 | #endif | 42 | #endif |
43 | } | 43 | } |
44 | 44 | ||
45 | static FILE * | ||
46 | stderr_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 | |||
59 | static void | ||
60 | stderr_close (FILE *fp) | ||
61 | { | ||
62 | if (init_process) | ||
63 | fclose (fp); | ||
64 | } | ||
65 | |||
45 | void | 66 | void |
46 | vlogmsg (int prio, const char *fmt, va_list ap) | 67 | vlogmsg (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)) |
@@ -959,8 +959,6 @@ _cb_flags (enum grecs_callback_command cmd, | |||
959 | return 0; | 959 | return 0; |
960 | } | 960 | } |
961 | 961 | ||
962 | static const char valid_runlevels[] = "0123456789Ss"; | ||
963 | |||
964 | static int | 962 | static 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 | { |
@@ -285,11 +285,13 @@ void progman_start (void); | |||
285 | void progman_wake_sleeping (int); | 285 | void progman_wake_sleeping (int); |
286 | void progman_stop (void); | 286 | void progman_stop (void); |
287 | void progman_cleanup (int expect_term); | 287 | void progman_cleanup (int expect_term); |
288 | void progman_filter (int (*filter) (struct component *, void *data), | ||
289 | void *data); | ||
288 | void progman_stop_component (const char *name); | 290 | void progman_stop_component (const char *name); |
289 | void progman_dump_stats (const char *filename); | 291 | void progman_dump_stats (const char *filename); |
290 | void progman_dump_prereq (void); | 292 | void progman_dump_prereq (void); |
291 | void progman_dump_depmap (void); | 293 | void progman_dump_depmap (void); |
292 | int progman_accept (int socket); | 294 | int progman_accept (int socket, void *data); |
293 | int progman_build_depmap (void); | 295 | int progman_build_depmap (void); |
294 | void progman_create_sockets (void); | 296 | void progman_create_sockets (void); |
295 | struct component *progman_lookup_component (const char *tag); | 297 | struct component *progman_lookup_component (const char *tag); |
@@ -362,7 +364,10 @@ void pies_url_destroy (struct pies_url **purl); | |||
362 | const char * pies_url_get_arg (struct pies_url *url, const char *argname); | 364 | const char * pies_url_get_arg (struct pies_url *url, const char *argname); |
363 | 365 | ||
364 | void pies_pause (void); | 366 | void pies_pause (void); |
365 | int register_socket (int socktype, int fd); | 367 | void *register_socket (int fd, int (*handler) (int, void *), void *data); |
368 | void deregister_socket (int fd); | ||
369 | |||
370 | int register_program_socket (int socktype, int fd, void *data); | ||
366 | int pass_fd (const char *socket, int fd, unsigned time_out); | 371 | int pass_fd (const char *socket, int fd, unsigned time_out); |
367 | int create_socket (struct pies_url *url, int socket_type, | 372 | int 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); | |||
456 | void sysvinit_begin (void); | 461 | void sysvinit_begin (void); |
457 | int inittrans (void); | 462 | int inittrans (void); |
458 | int is_comp_wait (struct component *comp); | 463 | int is_comp_wait (struct component *comp); |
464 | int 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 | |||
482 | struct 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 |