~jamesodhunt/upstart/async-spawn.20140310

3 by Scott James Remnant
* init/main.c: Add the simplest template main.c
1
/* upstart
2
 *
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
3
 * Copyright © 2009-2011 Canonical Ltd.
1103 by Scott James Remnant
Restore author field
4
 * Author: Scott James Remnant <scott@netsplit.com>.
3 by Scott James Remnant
* init/main.c: Add the simplest template main.c
5
 *
1124 by Scott James Remnant
* COPYING: Change licence to version 2 of the GNU GPL.
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License version 2, as
1101 by Scott James Remnant
* COPYING: Change licence from GPL-2+ to GPL-3 only.
8
 * published by the Free Software Foundation.
3 by Scott James Remnant
* init/main.c: Add the simplest template main.c
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
1124 by Scott James Remnant
* COPYING: Change licence to version 2 of the GNU GPL.
15
 * You should have received a copy of the GNU General Public License along
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3 by Scott James Remnant
* init/main.c: Add the simplest template main.c
18
 */
19
20
#ifdef HAVE_CONFIG_H
21
# include <config.h>
22
#endif /* HAVE_CONFIG_H */
23
24
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
25
#include <sys/types.h>
274 by Scott James Remnant
* init/main.c: Include sys/time.h
26
#include <sys/time.h>
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
27
#include <sys/wait.h>
28
#include <sys/ioctl.h>
29
#include <sys/reboot.h>
30
#include <sys/resource.h>
1373.2.1 by James Hunt
* init/main.c:main(): Create /dev/ptmx and mount /dev and /dev/pts to
31
#include <sys/mount.h>
1405.2.5 by Stéphane Graber
Skip prctl on systems that don't have it. Also do an explicit define of PR_SET_CHILD_SUBREAPER for systems with older headers. In the case where the kernel doesn't support it, child-subreaper-failed will simply be emitted.
32
33
#ifdef HAVE_SYS_PRCTL_H
1405.2.1 by Stéphane Graber
Early implementation of the prctl subreaper call
34
#include <sys/prctl.h>
1405.2.5 by Stéphane Graber
Skip prctl on systems that don't have it. Also do an explicit define of PR_SET_CHILD_SUBREAPER for systems with older headers. In the case where the kernel doesn't support it, child-subreaper-failed will simply be emitted.
35
#ifndef PR_SET_CHILD_SUBREAPER
36
#define PR_SET_CHILD_SUBREAPER 35
37
#endif
38
#endif
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
39
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
40
#include <errno.h>
41
#include <stdio.h>
1327 by Scott James Remnant
* init/job_class.c, init/job_class.h: Move constants into the
42
#include <limits.h>
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
43
#include <signal.h>
132 by Scott James Remnant
* init/process.c (process_setup_environment): Inherit the PATH
44
#include <stdlib.h>
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
45
#include <string.h>
125 by Scott James Remnant
* init/main.c (main): Open the syslog connection and set the logger.
46
#include <syslog.h>
111 by Scott James Remnant
* init/main.c: Add missing include for unistd.h
47
#include <unistd.h>
48
188 by Scott James Remnant
* init/main.c: Move the kernel headers include beneath the C
49
#include <linux/kd.h>
50
110 by Scott James Remnant
* init/main.c (main): Write the main function
51
#include <nih/macros.h>
52
#include <nih/alloc.h>
53
#include <nih/list.h>
54
#include <nih/timer.h>
55
#include <nih/signal.h>
56
#include <nih/child.h>
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
57
#include <nih/option.h>
110 by Scott James Remnant
* init/main.c (main): Write the main function
58
#include <nih/main.h>
187 by Scott James Remnant
* init/main.c (term_handler): Close the control connection if we
59
#include <nih/error.h>
110 by Scott James Remnant
* init/main.c (main): Write the main function
60
#include <nih/logging.h>
61
926 by Scott James Remnant
* init/job_class.c, init/main.c: Correct includes and some function
62
#include "paths.h"
931 by Scott James Remnant
* init/main.c: Include events.h to get the ones we need.
63
#include "events.h"
926 by Scott James Remnant
* init/job_class.c, init/main.c: Correct includes and some function
64
#include "system.h"
1327 by Scott James Remnant
* init/job_class.c, init/job_class.h: Move constants into the
65
#include "job_class.h"
934 by Scott James Remnant
* init/job.c (job_change_state): Change calls to job_process_run
66
#include "job_process.h"
110 by Scott James Remnant
* init/main.c (main): Write the main function
67
#include "event.h"
718 by Scott James Remnant
* init/main.c (main): Read the configuration again.
68
#include "conf.h"
897 by Scott James Remnant
* init/main.c: Attempt to connect to the system bus on startup,
69
#include "control.h"
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
70
#include "state.h"
1405.7.5 by Dmitrijs Ledkovs
User sessions are born
71
#include "xdg.h"
3 by Scott James Remnant
* init/main.c: Add the simplest template main.c
72
73
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
74
/* Prototypes for static functions */
814 by Scott James Remnant
* init/main.c: Selectively compile out certain pieces when make is
75
#ifndef DEBUG
1260 by Scott James Remnant
* init/tests/test_conf.c (test_source_reload_job_dir): Add tests for
76
static int  logger_kmsg     (NihLogLevel priority, const char *message);
370 by Scott James Remnant
* init/main.c (segv_handler): Rename to crash_handler and handle
77
static void crash_handler   (int signum);
1371.1.1 by James Hunt
* init/main.c: Add in "bare" re-exec handling from Ubuntu
78
#endif /* DEBUG */
79
static void term_handler    (void *data, NihSignal *signal);
80
#ifndef DEBUG
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
81
static void cad_handler     (void *data, NihSignal *signal);
82
static void kbd_handler     (void *data, NihSignal *signal);
584 by Scott James Remnant
* init/event.h (PWRSTATUS_EVENT): Add new power-status-changed event.
83
static void pwr_handler     (void *data, NihSignal *signal);
720 by Scott James Remnant
* init/main.c (main): Add a handler for the SIGHUP signal
84
static void hup_handler     (void *data, NihSignal *signal);
1213 by Scott James Remnant
* init/main.c (hup_handler): Move call to reconnect to D-Bus system
85
static void usr1_handler    (void *data, NihSignal *signal);
977 by Scott James Remnant
* init/main.c: Also remove SIGTERM handling, we don't re-exec
86
#endif /* DEBUG */
645 by Scott James Remnant
* init/main.c: Improve restarting and rescuing a little; store the
87
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
88
static void handle_confdir      (void);
89
static void handle_logdir       (void);
90
static int  console_type_setter (NihOption *option, const char *arg);
1471.1.1 by James Hunt
* init/main.c:
91
static int  conf_dir_setter     (NihOption *option, const char *arg);
1371.9.1 by Colin Watson
Test that ptrace handling works across stateful re-exec.
92
645 by Scott James Remnant
* init/main.c: Improve restarting and rescuing a little; store the
93
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
94
/**
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
95
 * state_fd:
96
 *
97
 * File descriptor to read serialised state from when performing
1371.1.32 by James Hunt
Updates to re-exec logic and D-Bus handling.
98
 * stateful re-exec. If value is not -1, attempt stateful re-exec.
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
99
 **/
100
static int state_fd = -1;
101
102
/**
1471.1.1 by James Hunt
* init/main.c:
103
 * conf_dirs:
104
 *
105
 * Array of full paths to job configuration file directories.
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
106
 **/
1471.1.1 by James Hunt
* init/main.c:
107
static char **conf_dirs = NULL;
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
108
1286.1.1 by James Hunt
Add ability to suppress initial event and/or change its name.
109
/**
110
 * initial_event:
111
 *
112
 * Alternate event to emit at startup (rather than STARTUP_EVENT).
113
 **/
114
static char *initial_event = NULL;
115
116
/**
117
 * disable_startup_event:
118
 *
119
 * If TRUE, do not emit a startup event.
120
 **/
121
static int disable_startup_event = FALSE;
122
1533.2.1 by James Hunt
* init/control.c: Typo.
123
/**
124
 * disable_dbus:
125
 *
126
 * If TRUE, do not connect to a D-Bus bus
127
 * (only connect to the private socket).
128
 **/
129
static int disable_dbus = FALSE;
130
1432.2.1 by James Hunt
* init/job_process.c: job_process_run(): Invert meaning.
131
extern int          no_inherit_env;
1405.16.13 by Stéphane Graber
Update upstart code to behave the same way as initctl. That's, don't bind the session bus unless passed --session.
132
extern int          user_mode;
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
133
extern int          disable_sessions;
134
extern int          disable_job_logging;
135
extern int          use_session_bus;
136
extern int          default_console;
1472.2.3 by James Hunt
* init/job.c: job_serialise_all(): Really serialise all JobClasses,
137
extern int          write_state_file;
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
138
extern char        *log_dir;
1546.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'NotifyDBusAddress' method.
139
extern DBusBusType  dbus_bus_type;
1543.1.1 by James Hunt
* init/job_class.c:
140
extern mode_t       initial_umask;
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
141
142
/**
143
 * options:
144
 *
145
 * Command-line options we accept.
146
 **/
147
static NihOption options[] = {
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
148
	{ 0, "confdir", N_("specify alternative directory to load configuration files from"),
1471.1.1 by James Hunt
* init/main.c:
149
		NULL, "DIR", NULL, conf_dir_setter },
1245.2.8 by James Hunt
* init/Makefile.am: Added session object to all test apps that need it.
150
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
151
	{ 0, "default-console", N_("default value for console stanza"),
152
		NULL, "VALUE", NULL, console_type_setter },
153
1533.2.1 by James Hunt
* init/control.c: Typo.
154
	{ 0, "no-dbus", N_("do not connect to a D-Bus bus"),
155
		NULL, NULL, &disable_dbus, NULL },
156
1432.2.1 by James Hunt
* init/job_process.c: job_process_run(): Invert meaning.
157
	{ 0, "no-inherit-env", N_("jobs will not inherit environment of init"),
1543.1.1 by James Hunt
* init/job_class.c:
158
		NULL, NULL, &no_inherit_env , NULL },
1427.1.1 by James Hunt
* init/job_process.c: job_process_run(): Copy parent environment if
159
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
160
	{ 0, "logdir", N_("specify alternative directory to store job output logs in"),
161
		NULL, "DIR", &log_dir, NULL },
162
163
	{ 0, "no-log", N_("disable job logging"),
164
		NULL, NULL, &disable_job_logging, NULL },
165
1442 by James Hunt
* init/main.c: Correct description for '--no-sessions'.
166
	{ 0, "no-sessions", N_("disable chroot sessions"),
1245.2.8 by James Hunt
* init/Makefile.am: Added session object to all test apps that need it.
167
		NULL, NULL, &disable_sessions, NULL },
1245.2.11 by James Hunt
Merge from upstream.
168
1286.1.1 by James Hunt
Add ability to suppress initial event and/or change its name.
169
	{ 0, "no-startup-event", N_("do not emit any startup event (for testing)"),
170
		NULL, NULL, &disable_startup_event, NULL },
171
1371.1.36 by James Hunt
* init/control.c:
172
	/* Must be specified for both stateful and stateless re-exec */
1371.1.32 by James Hunt
Updates to re-exec logic and D-Bus handling.
173
	{ 0, "restart", N_("flag a re-exec has occurred"),
1371.1.2 by James Hunt
* init/main.c: Unhide "restart" option.
174
		NULL, NULL, &restart, NULL },
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
175
1371.1.32 by James Hunt
Updates to re-exec logic and D-Bus handling.
176
	/* Required for stateful re-exec */
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
177
	{ 0, "state-fd", N_("specify file descriptor to read serialisation data from"),
178
		NULL, "FD", &state_fd, nih_option_int },
179
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
180
	{ 0, "session", N_("use D-Bus session bus rather than system bus (for testing)"),
181
		NULL, NULL, &use_session_bus, NULL },
182
1286.1.1 by James Hunt
Add ability to suppress initial event and/or change its name.
183
	{ 0, "startup-event", N_("specify an alternative initial event (for testing)"),
184
		NULL, "NAME", &initial_event, NULL },
185
1405.8.1 by Stéphane Graber
Add a new --user parameter setting user_mode to 1
186
	{ 0, "user", N_("start in user mode (as used for user sessions)"),
187
		NULL, NULL, &user_mode, NULL },
188
1472.2.3 by James Hunt
* init/job.c: job_serialise_all(): Really serialise all JobClasses,
189
	{ 0, "write-state-file", N_("attempt to write state file on every re-exec"),
190
		NULL, NULL, &write_state_file, NULL },
191
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
192
	/* Ignore invalid options */
193
	{ '-', "--", NULL, NULL, NULL, NULL, NULL },
194
195
	NIH_OPTION_LAST
196
};
176 by Scott James Remnant
* init/process.c (process_setup_console): Remove the console reset
197
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
198
3 by Scott James Remnant
* init/main.c: Add the simplest template main.c
199
int
200
main (int   argc,
201
      char *argv[])
202
{
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
203
	char **args = NULL;
401 by Scott James Remnant
* init/main.c (main): Being unable tp open the control socket, or
204
	int    ret;
110 by Scott James Remnant
* init/main.c (main): Write the main function
205
1471.1.1 by James Hunt
* init/main.c:
206
	conf_dirs = NIH_MUST (nih_str_array_new (NULL));
207
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
208
	args_copy = NIH_MUST (nih_str_array_copy (NULL, NULL, argv));
209
210
	nih_main_init (args_copy[0]);
110 by Scott James Remnant
* init/main.c (main): Write the main function
211
259 by Scott James Remnant
* configure.ac (AC_INIT): Change bug reporting address to the
212
	nih_option_set_synopsis (_("Process management daemon."));
263 by Scott James Remnant
* init/main.c (main): Formatting.
213
	nih_option_set_help (
214
		_("This daemon is normally executed by the kernel and given "
215
		  "process id 1 to denote its special status.  When executed "
216
		  "by a user process, it will actually run /sbin/telinit."));
258 by Scott James Remnant
* init/main.c (main): Set the synopsis, and direct people to look
217
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
218
	args = nih_option_parser (NULL, argc, argv, options, FALSE);
219
	if (! args)
220
		exit (1);
221
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
222
	handle_confdir ();
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
223
	handle_logdir ();
224
225
	if (disable_job_logging)
226
		nih_debug ("Job logging disabled");
227
1546.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'NotifyDBusAddress' method.
228
	if (getenv (USE_SESSION_BUS_ENV))
229
		use_session_bus = TRUE;
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
230
1436.1.1 by Stéphane Graber
Only inherit the environment in user mode. Fix test to avoid inheriting environment.
231
	if (! user_mode)
232
		no_inherit_env = TRUE;
233
814 by Scott James Remnant
* init/main.c: Selectively compile out certain pieces when make is
234
#ifndef DEBUG
1405.16.13 by Stéphane Graber
Update upstart code to behave the same way as initctl. That's, don't bind the session bus unless passed --session.
235
	if (use_session_bus == FALSE && user_mode == FALSE) {
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
236
1373.2.2 by Steve Langasek
Don't overmount /dev if /dev/pts and /dev/ptmx are already present.
237
		int needs_devtmpfs = 0;
238
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
239
		/* Check we're root */
240
		if (getuid ()) {
241
			nih_fatal (_("Need to be root"));
242
			exit (1);
243
		}
244
245
		/* Check we're process #1 */
246
		if (getpid () > 1) {
247
			execv (TELINIT, argv);
248
			/* Ignore failure, probably just that telinit doesn't exist */
249
250
			nih_fatal (_("Not being executed as init"));
251
			exit (1);
252
		}
253
254
		/* Clear our arguments from the command-line, so that we show up in
255
		 * ps or top output as /sbin/init, with no extra flags.
256
		 *
257
		 * This is a very Linux-specific trick; by deleting the NULL
258
		 * terminator at the end of the last argument, we fool the kernel
259
		 * into believing we used a setproctitle()-a-like to extend the
260
		 * argument space into the environment space, and thus make it use
261
		 * strlen() instead of its own assumed length.  In fact, we've done
262
		 * the exact opposite, and shrunk the command line length to just that
263
		 * of whatever is in argv[0].
264
		 *
265
		 * If we don't do this, and just write \0 over the rest of argv, for
266
		 * example; the command-line length still includes those \0s, and ps
267
		 * will show whitespace in their place.
268
		 */
269
		if (argc > 1) {
270
			char *arg_end;
271
272
			arg_end = argv[argc-1] + strlen (argv[argc-1]);
273
			*arg_end = ' ';
274
		}
275
276
277
		/* Become the leader of a new session and process group, shedding
278
		 * any controlling tty (which we shouldn't have had anyway - but
279
		 * you never know what initramfs did).
280
		 */
281
		setsid ();
282
1373.2.3 by James Hunt
* init/main.c:main(): Handle hostile initramfs-less environments by
283
		/* Allow devices to be created with the actual perms
284
		 * specified.
285
		 */
1543.1.1 by James Hunt
* init/job_class.c:
286
		initial_umask = umask (0);
1373.2.3 by James Hunt
* init/main.c:main(): Handle hostile initramfs-less environments by
287
1376.1.1 by James Hunt
* init/main.c: main(): Remove checks for /dev/kmsg, /dev/null,
288
		/* Check if key /dev entries already exist; if they do,
1373.2.3 by James Hunt
* init/main.c:main(): Handle hostile initramfs-less environments by
289
		 * we should assume we don't need to mount /dev.
290
		 */
1376 by James Hunt
Merge of lp:~vorlon/upstart/lp.980917-redux.
291
		if (system_check_file ("/dev/ptmx", S_IFCHR, makedev (5, 2)) < 0
1376.1.1 by James Hunt
* init/main.c: main(): Remove checks for /dev/kmsg, /dev/null,
292
			|| system_check_file ("/dev/pts", S_IFDIR, 0) < 0)
1373.2.3 by James Hunt
* init/main.c:main(): Handle hostile initramfs-less environments by
293
			needs_devtmpfs = 1;
294
295
		if (needs_devtmpfs) {
1546.2.1 by Steve Langasek
allow mount options to be passed to system_mount().
296
			if (system_mount ("devtmpfs", "/dev",
297
					  MS_NOEXEC | MS_NOSUID, NULL) < 0) {
1373.2.3 by James Hunt
* init/main.c:main(): Handle hostile initramfs-less environments by
298
				NihError *err;
299
300
				err = nih_error_get ();
301
				nih_error ("%s: %s", _("Unable to mount /dev filesystem"),
302
						err->message);
303
				nih_free (err);
304
			}
305
306
			/* Required to exist before /dev/pts accessed */
307
			system_mknod ("/dev/ptmx", (S_IFCHR | 0666), makedev (5, 2));
308
309
			if (mkdir ("/dev/pts", 0755) < 0 && errno != EEXIST)
310
				nih_error ("%s: %s", _("Cannot create directory"), "/dev/pts");
311
		}
312
1546.2.1 by Steve Langasek
allow mount options to be passed to system_mount().
313
		if (system_mount ("devpts", "/dev/pts", MS_NOEXEC | MS_NOSUID,
1546.2.2 by Steve Langasek
Set mount options when mounting /dev/pts to match the permissions set by either initramfs-tools or mountall.
314
				  "gid=5,mode=0620") < 0) {
1373.2.3 by James Hunt
* init/main.c:main(): Handle hostile initramfs-less environments by
315
			NihError *err;
316
317
			err = nih_error_get ();
318
			nih_error ("%s: %s", _("Unable to mount /dev/pts filesystem"),
319
					err->message);
320
			nih_free (err);
321
		}
322
323
		/* These devices must exist, but we have to have handled the /dev
324
		 * check (and possible mount) prior to considering
325
		 * creating them. And yet, if /dev is not available from
326
		 * the outset and an error occurs, we are unable to report it,
327
		 * hence these checks are performed as early as is
328
		 * feasible.
329
		 */
330
		system_mknod ("/dev/null", (S_IFCHR | 0666), makedev (1, 3));
331
		system_mknod ("/dev/tty", (S_IFCHR | 0666), makedev (5, 0));
1377 by Steve Langasek
Merge lp:~jamesodhunt/upstart/bug-980917-the-bug-that-would-not-die, fixing
332
		system_mknod ("/dev/console", (S_IFCHR | 0600), makedev (5, 1));
1373.2.3 by James Hunt
* init/main.c:main(): Handle hostile initramfs-less environments by
333
		system_mknod ("/dev/kmsg", (S_IFCHR | 0600), makedev (1, 11));
334
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
335
		/* Set the standard file descriptors to the ordinary console device,
336
		 * resetting it to sane defaults unless we're inheriting from another
337
		 * init process which we know left it in a sane state.
338
		 */
1326 by Scott James Remnant
* init/main.c: Deal with failure to setup the system console by
339
		if (system_setup_console (CONSOLE_OUTPUT, (! restart)) < 0) {
340
			NihError *err;
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
341
1326 by Scott James Remnant
* init/main.c: Deal with failure to setup the system console by
342
			err = nih_error_get ();
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
343
1326 by Scott James Remnant
* init/main.c: Deal with failure to setup the system console by
344
			nih_warn ("%s: %s", _("Unable to initialize console, will try /dev/null"),
345
				  err->message);
346
			nih_free (err);
347
	
348
			if (system_setup_console (CONSOLE_NONE, FALSE) < 0) {
349
				err = nih_error_get ();
350
				nih_fatal ("%s: %s", _("Unable to initialize console as /dev/null"),
351
					   err->message);
352
				nih_free (err);
353
	
354
				exit (1);
355
			}
356
		}
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
357
358
		/* Set the PATH environment variable */
359
		setenv ("PATH", PATH, TRUE);
360
361
		/* Switch to the root directory in case we were started from some
362
		 * strange place, or worse, some directory in the initramfs that's
363
		 * going to go away soon.
364
		 */
365
		if (chdir ("/"))
366
			nih_warn ("%s: %s", _("Unable to set root directory"),
367
				strerror (errno));
368
369
		/* Mount the /proc and /sys filesystems, which are pretty much
370
		 * essential for any Linux system; not to mention used by
1373.2.1 by James Hunt
* init/main.c:main(): Create /dev/ptmx and mount /dev and /dev/pts to
371
		 * ourselves. Also mount /dev/pts to allow CONSOLE_LOG
372
		 * to function if booted in an initramfs-less environment.
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
373
		 */
1546.2.1 by Steve Langasek
allow mount options to be passed to system_mount().
374
		if (system_mount ("proc", "/proc",
375
				  MS_NODEV | MS_NOEXEC | MS_NOSUID, NULL) < 0) {
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
376
			NihError *err;
377
378
			err = nih_error_get ();
379
			nih_warn ("%s: %s", _("Unable to mount /proc filesystem"),
380
				err->message);
381
			nih_free (err);
382
		}
383
1546.2.1 by Steve Langasek
allow mount options to be passed to system_mount().
384
		if (system_mount ("sysfs", "/sys",
385
				  MS_NODEV | MS_NOEXEC | MS_NOSUID, NULL) < 0) {
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
386
			NihError *err;
387
388
			err = nih_error_get ();
389
			nih_warn ("%s: %s", _("Unable to mount /sys filesystem"),
390
				err->message);
391
			nih_free (err);
392
		}
1373.2.3 by James Hunt
* init/main.c:main(): Handle hostile initramfs-less environments by
393
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
394
	} else {
395
		nih_debug ("Running with UID %d as PID %d (PPID %d)",
396
				(int)getuid (), (int)getpid (), (int)getppid ());
397
	}
398
814 by Scott James Remnant
* init/main.c: Selectively compile out certain pieces when make is
399
#else /* DEBUG */
400
	nih_log_set_priority (NIH_LOG_DEBUG);
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
401
	nih_debug ("Running with UID %d as PID %d (PPID %d)",
402
		(int)getuid (), (int)getpid (), (int)getppid ());
814 by Scott James Remnant
* init/main.c: Selectively compile out certain pieces when make is
403
#endif /* DEBUG */
806 by Scott James Remnant
* init/process.c (process_setup_limits): Integrate this function back
404
1543.1.1 by James Hunt
* init/job_class.c:
405
	if (user_mode) {
406
		/* Save initial value */
407
		initial_umask = umask (0);
408
		(void)umask (initial_umask);
409
	}
401 by Scott James Remnant
* init/main.c (main): Being unable tp open the control socket, or
410
110 by Scott James Remnant
* init/main.c (main): Write the main function
411
	/* Reset the signal state and install the signal handler for those
412
	 * signals we actually want to catch; this also sets those that
413
	 * can be sent to us, because we're special
414
	 */
892 by Scott James Remnant
* init/main.c: Drop the attempt to rescue a crashed system by
415
	if (! restart)
401 by Scott James Remnant
* init/main.c (main): Being unable tp open the control socket, or
416
		nih_signal_reset ();
417
893 by Scott James Remnant
* init/main.c: Use a better name for kbdrequest
418
#ifndef DEBUG
1405.16.13 by Stéphane Graber
Update upstart code to behave the same way as initctl. That's, don't bind the session bus unless passed --session.
419
	if (use_session_bus == FALSE && user_mode == FALSE) {
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
420
		/* Catch fatal errors immediately rather than waiting for a new
421
		 * iteration through the main loop.
422
		 */
423
		nih_signal_set_handler (SIGSEGV, crash_handler);
424
		nih_signal_set_handler (SIGABRT, crash_handler);
425
	}
814 by Scott James Remnant
* init/main.c: Selectively compile out certain pieces when make is
426
#endif /* DEBUG */
806 by Scott James Remnant
* init/process.c (process_setup_limits): Integrate this function back
427
785 by Scott James Remnant
* init/main.c (main): Tidy up.
428
	/* Don't ignore SIGCHLD or SIGALRM, but don't respond to them
429
	 * directly; it's enough that they interrupt the main loop and
430
	 * get dealt with during it.
431
	 */
432
	nih_signal_set_handler (SIGCHLD, nih_signal_handler);
433
	nih_signal_set_handler (SIGALRM, nih_signal_handler);
434
814 by Scott James Remnant
* init/main.c: Selectively compile out certain pieces when make is
435
#ifndef DEBUG
1405.16.13 by Stéphane Graber
Update upstart code to behave the same way as initctl. That's, don't bind the session bus unless passed --session.
436
	if (use_session_bus == FALSE && user_mode == FALSE) {
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
437
		/* Ask the kernel to send us SIGINT when control-alt-delete is
438
		 * pressed; generate an event with the same name.
439
		 */
440
		reboot (RB_DISABLE_CAD);
441
		nih_signal_set_handler (SIGINT, nih_signal_handler);
442
		NIH_MUST (nih_signal_add_handler (NULL, SIGINT, cad_handler, NULL));
443
444
		/* Ask the kernel to send us SIGWINCH when alt-uparrow is pressed;
445
		 * generate a keyboard-request event.
446
		 */
447
		if (ioctl (0, KDSIGACCEPT, SIGWINCH) == 0) {
448
			nih_signal_set_handler (SIGWINCH, nih_signal_handler);
449
			NIH_MUST (nih_signal_add_handler (NULL, SIGWINCH,
450
						kbd_handler, NULL));
451
		}
452
453
		/* powstatd sends us SIGPWR when it changes /etc/powerstatus */
454
		nih_signal_set_handler (SIGPWR, nih_signal_handler);
455
		NIH_MUST (nih_signal_add_handler (NULL, SIGPWR, pwr_handler, NULL));
456
785 by Scott James Remnant
* init/main.c (main): Tidy up.
457
	}
1371.1.33 by James Hunt
* init/control.c: liberal scattering of control_init() for protection.
458
1427.3.2 by James Hunt
* init/Makefile.am: Added quiesce.o, now required by control.o.
459
	/* SIGHUP instructs us to re-load our configuration */
460
	nih_signal_set_handler (SIGHUP, nih_signal_handler);
461
	NIH_MUST (nih_signal_add_handler (NULL, SIGHUP, hup_handler, NULL));
462
1546.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'NotifyDBusAddress' method.
463
	/* Session Inits only reconnect to D-Bus when notified
464
	 * via their private socket.
465
	 */
466
	if (! user_mode) {
467
		/* SIGUSR1 instructs us to reconnect to D-Bus */
468
		nih_signal_set_handler (SIGUSR1, nih_signal_handler);
469
		NIH_MUST (nih_signal_add_handler (NULL, SIGUSR1, usr1_handler, NULL));
470
	}
1427.3.2 by James Hunt
* init/Makefile.am: Added quiesce.o, now required by control.o.
471
1427.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'EndSession' method.
472
	/* SIGTERM instructs us to re-exec ourselves when running as PID
473
	 * 1, or to exit when running as a Session Init; this signal should
474
	 * be the last in the list to ensure that all other signals are
475
	 * handled before a SIGTERM.
1371.1.33 by James Hunt
* init/control.c: liberal scattering of control_init() for protection.
476
	 */
477
	nih_signal_set_handler (SIGTERM, nih_signal_handler);
478
	NIH_MUST (nih_signal_add_handler (NULL, SIGTERM, term_handler, NULL));
479
977 by Scott James Remnant
* init/main.c: Also remove SIGTERM handling, we don't re-exec
480
#endif /* DEBUG */
185 by Scott James Remnant
* init/main.c: Use the TERM signal instead of USR1, as old init
481
806 by Scott James Remnant
* init/process.c (process_setup_limits): Integrate this function back
482
787 by Scott James Remnant
* init/job.c (job_child_reaper): Update argument names and types
483
	/* Watch children for events */
792 by Scott James Remnant
* init/job.c (job_child_handler): Implement a combined child event
484
	NIH_MUST (nih_child_add_watch (NULL, -1, NIH_CHILD_ALL,
934 by Scott James Remnant
* init/job.c (job_change_state): Change calls to job_process_run
485
				       job_process_handler, NULL));
110 by Scott James Remnant
* init/main.c (main): Write the main function
486
785 by Scott James Remnant
* init/main.c (main): Tidy up.
487
	/* Process the event queue each time through the main loop */
470 by Scott James Remnant
* init/main.c (main): Call event_poll instead of event_queue_run.
488
	NIH_MUST (nih_main_loop_add_func (NULL, (NihMainLoopCb)event_poll,
336 by Scott James Remnant
* init/main.c (main): Guard against various things returning an error
489
					  NULL));
110 by Scott James Remnant
* init/main.c (main): Write the main function
490
491
1327 by Scott James Remnant
* init/job_class.c, init/job_class.h: Move constants into the
492
	/* Adjust our OOM priority to the default, which will be inherited
493
	 * by all jobs.
494
	 */
495
	if (JOB_DEFAULT_OOM_SCORE_ADJ) {
496
		char  filename[PATH_MAX];
497
		int   oom_value;
498
		FILE *fd;
499
500
		snprintf (filename, sizeof (filename),
501
			  "/proc/%d/oom_score_adj", getpid ());
502
		oom_value = JOB_DEFAULT_OOM_SCORE_ADJ;
503
		fd = fopen (filename, "w");
1328 by Scott James Remnant
* init/job_process.c (job_process_spawn), init/main.c: error
504
		if ((! fd) && (errno == ENOENT)) {
1327 by Scott James Remnant
* init/job_class.c, init/job_class.h: Move constants into the
505
			snprintf (filename, sizeof (filename),
506
				  "/proc/%d/oom_adj", getpid ());
507
			oom_value = (JOB_DEFAULT_OOM_SCORE_ADJ
508
				     * ((JOB_DEFAULT_OOM_SCORE_ADJ < 0) ? 17 : 15)) / 1000;
509
			fd = fopen (filename, "w");
510
		}
511
		if (! fd) {
512
			nih_warn ("%s: %s", _("Unable to set default oom score"),
513
				  strerror (errno));
514
		} else {
515
			fprintf (fd, "%d\n", oom_value);
516
517
			if (fclose (fd))
518
				nih_warn ("%s: %s", _("Unable to set default oom score"),
519
					  strerror (errno));
520
		}
521
	}
522
523
1371.1.33 by James Hunt
* init/control.c: liberal scattering of control_init() for protection.
524
	if (restart) {
525
		if (state_fd == -1) {
526
			nih_warn ("%s",
527
				_("Stateful re-exec supported but stateless re-exec requested"));
1371.1.73 by James Hunt
Tidy-up.
528
		} else if (state_read (state_fd) < 0) {
1371.1.33 by James Hunt
* init/control.c: liberal scattering of control_init() for protection.
529
1371.1.36 by James Hunt
* init/control.c:
530
			/* Stateful re-exec has failed so try once more by
531
			 * degrading to stateless re-exec, which even in
532
			 * the case of low-memory scenarios will work.
1371.1.33 by James Hunt
* init/control.c: liberal scattering of control_init() for protection.
533
			 */
534
535
			/* Inform the child we've given up on stateful
536
			 * re-exec.
537
			 */
538
			close (state_fd);
539
540
			nih_error ("%s - %s",
541
				_("Failed to read serialisation data"),
542
				_("reverting to stateless re-exec"));
543
1371.1.68 by James Hunt
* init/main.c:
544
			/* Remove any existing (but now stale) state fd
545
			 * args which will effectively disable stateful
546
			 * re-exec.
1371.1.33 by James Hunt
* init/control.c: liberal scattering of control_init() for protection.
547
			 */
1371.1.89 by James Hunt
* init/main.c: main(): Updated call to clean_args().
548
			clean_args (&args_copy);
1371.1.36 by James Hunt
* init/control.c:
549
550
			/* Attempt stateless re-exec */
1371.1.33 by James Hunt
* init/control.c: liberal scattering of control_init() for protection.
551
			perform_reexec ();
552
553
			nih_error ("%s",
554
				_("Both stateful and stateless re-execs failed"));
555
556
			/* Out of options */
557
			nih_assert_not_reached ();
1371.1.42 by James Hunt
* init/conf.c: Temporarily enable debug_show_*() functions for non-debug
558
		} else {
1371.1.43 by James Hunt
* init/control.c:
559
			close (state_fd);
560
1371.1.42 by James Hunt
* init/conf.c: Temporarily enable debug_show_*() functions for non-debug
561
			nih_info ("Stateful re-exec completed");
1371.1.33 by James Hunt
* init/control.c: liberal scattering of control_init() for protection.
562
		}
563
	}
564
718 by Scott James Remnant
* init/main.c (main): Read the configuration again.
565
	/* Read configuration */
1471.1.1 by James Hunt
* init/main.c:
566
	if (! user_mode) {
567
		char   *conf_dir;
568
		int     len = 0;
569
570
		nih_assert (conf_dirs[0]);
571
572
		/* Count entries */
573
		for (char **d = conf_dirs; d && *d; d++, len++)
574
			;
575
576
		nih_assert (len);
577
578
		/* Use last value specified */
579
		conf_dir = conf_dirs[len-1];
580
1405.7.5 by Dmitrijs Ledkovs
User sessions are born
581
		NIH_MUST (conf_source_new (NULL, CONFFILE, CONF_FILE));
582
1471.1.1 by James Hunt
* init/main.c:
583
		nih_debug ("Using configuration directory %s", conf_dir);
1405.7.5 by Dmitrijs Ledkovs
User sessions are born
584
		NIH_MUST (conf_source_new (NULL, conf_dir, CONF_JOB_DIR));
1471.1.1 by James Hunt
* init/main.c:
585
	} else {
586
		nih_local char **dirs = NULL;
1405.7.5 by Dmitrijs Ledkovs
User sessions are born
587
1405.7.8 by Dmitrijs Ledkovs
wrap api call with NIH_MUST, we must get conf-source dirs
588
		dirs = NIH_MUST (get_user_upstart_dirs ());
1471.1.1 by James Hunt
* init/main.c:
589
590
		for (char **d = conf_dirs[0] ? conf_dirs : dirs; d && *d; d++) {
591
			nih_debug ("Using configuration directory %s", *d);
1405.7.5 by Dmitrijs Ledkovs
User sessions are born
592
			NIH_MUST (conf_source_new (NULL, *d, CONF_JOB_DIR));
1471.1.1 by James Hunt
* init/main.c:
593
		}
1405.7.5 by Dmitrijs Ledkovs
User sessions are born
594
	}
718 by Scott James Remnant
* init/main.c (main): Read the configuration again.
595
1471.1.1 by James Hunt
* init/main.c:
596
	nih_free (conf_dirs);
597
1426 by James Hunt
* init/control.c:
598
	job_class_environment_init ();
599
1371.5.1 by Steve Langasek
Drop unnecessary divergence when handling conf sources on re-exec
600
	conf_reload ();
677 by Scott James Remnant
* init/main.c: Wait until we've closed inherited standard file
601
943 by Scott James Remnant
* init/control.c (control_server_open, control_server_close)
602
	/* Create a listening server for private connections. */
1405.16.15 by Stéphane Graber
Revert main.c hunk that was making upstart always listen for private connections. It's no longer required now that user_mode is separate from use_session_bus.
603
	if (use_session_bus == FALSE) {
604
		while (control_server_open () < 0) {
605
			NihError *err;
943 by Scott James Remnant
* init/control.c (control_server_open, control_server_close)
606
1405.16.15 by Stéphane Graber
Revert main.c hunk that was making upstart always listen for private connections. It's no longer required now that user_mode is separate from use_session_bus.
607
			err = nih_error_get ();
608
			if (err->number != ENOMEM) {
609
				nih_warn ("%s: %s", _("Unable to listen for private connections"),
610
					err->message);
611
				nih_free (err);
612
				break;
613
			}
943 by Scott James Remnant
* init/control.c (control_server_open, control_server_close)
614
			nih_free (err);
615
		}
616
	}
617
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
618
	/* Open connection to the appropriate D-Bus bus; we normally expect this to
1371.1.42 by James Hunt
* init/conf.c: Temporarily enable debug_show_*() functions for non-debug
619
	 * fail (since dbus-daemon probably isn't running yet) and will try again
620
	 * later - don't let ENOMEM stop us though.
897 by Scott James Remnant
* init/main.c: Attempt to connect to the system bus on startup,
621
	 */
1533.2.1 by James Hunt
* init/control.c: Typo.
622
	if (disable_dbus) {
623
		nih_info (_("Not connecting to %s bus"),
624
				use_session_bus ? "session" : "system");
625
	} else {
626
		while (control_bus_open () < 0) {
627
			NihError *err;
628
			int       number;
629
630
			err = nih_error_get ();
631
			number = err->number;
632
			nih_free (err);
633
634
			if (number != ENOMEM)
635
				break;
636
		}
897 by Scott James Remnant
* init/main.c: Attempt to connect to the system bus on startup,
637
	}
638
893 by Scott James Remnant
* init/main.c: Use a better name for kbdrequest
639
#ifndef DEBUG
1405.16.13 by Stéphane Graber
Update upstart code to behave the same way as initctl. That's, don't bind the session bus unless passed --session.
640
	if (use_session_bus == FALSE && user_mode == FALSE) {
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
641
		/* Now that the startup is complete, send all further logging output
642
		 * to kmsg instead of to the console.
643
		 */
1326 by Scott James Remnant
* init/main.c: Deal with failure to setup the system console by
644
		if (system_setup_console (CONSOLE_NONE, FALSE) < 0) {
645
			NihError *err;
646
			
647
			err = nih_error_get ();
648
			nih_fatal ("%s: %s", _("Unable to setup standard file descriptors"),
649
				   err->message);
650
			nih_free (err);
651
	
652
			exit (1);
653
		}
1274 by Scott James Remnant
* init/main.c: Don't close the console until initialization is
654
1282.1.1 by James Hunt
Add command-line option to use D-Bus session bus (for testing).
655
		nih_log_set_logger (logger_kmsg);
656
	}
814 by Scott James Remnant
* init/main.c: Selectively compile out certain pieces when make is
657
#endif /* DEBUG */
806 by Scott James Remnant
* init/process.c (process_setup_limits): Integrate this function back
658
659
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
660
	/* Generate and run the startup event or read the state from the
661
	 * init daemon that exec'd us
662
	 */
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
663
	if (! restart) {
1286.1.1 by James Hunt
Add ability to suppress initial event and/or change its name.
664
		if (disable_startup_event) {
665
			nih_debug ("Startup event disabled");
666
		} else {
667
			NIH_MUST (event_new (NULL,
668
				initial_event
669
				? initial_event
670
				: STARTUP_EVENT,
671
				NULL));
672
		}
673
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
674
	} else {
1371.1.32 by James Hunt
Updates to re-exec logic and D-Bus handling.
675
		sigset_t        mask;
185 by Scott James Remnant
* init/main.c: Use the TERM signal instead of USR1, as old init
676
1371.1.32 by James Hunt
Updates to re-exec logic and D-Bus handling.
677
		/* We have been re-exec'd. Don't emit an initial event
678
		 * as only Upstart is restarting - we don't want to restart
679
		 * the system (another reason being that we don't yet support
680
		 * upstart-in-initramfs to upstart-in-root-filesystem
681
		 * state-passing transitions).
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
682
		 */
683
1371.1.32 by James Hunt
Updates to re-exec logic and D-Bus handling.
684
		/* We're ok to receive signals again so restore signals
685
		 * disabled by the term_handler */
185 by Scott James Remnant
* init/main.c: Use the TERM signal instead of USR1, as old init
686
		sigemptyset (&mask);
687
		sigprocmask (SIG_SETMASK, &mask, NULL);
1405.4.4 by Stéphane Graber
Move the code a bit later to ensure we're done reconnecting to all the DBUS buses. This mean that the Restart event will now be emitted whenever upstart restarts and not be restricted to succesful sateful re-execs.
688
1473 by James Hunt
* Typo and doc changes.
689
		/* Emit the Restarted signal so that any listening Instance Init
1405.4.4 by Stéphane Graber
Move the code a bit later to ensure we're done reconnecting to all the DBUS buses. This mean that the Restart event will now be emitted whenever upstart restarts and not be restricted to succesful sateful re-execs.
690
		 * knows that it needs to restart too.
691
		 */
1405.4.8 by Stéphane Graber
Move event code to control.c
692
		control_notify_restarted();
180 by Scott James Remnant
* init/main.c (main): Parse command-line arguments, specifically
693
	}
694
1317 by James Hunt
* init/main.c: main(): Display a message to say sessions are disabled if
695
	if (disable_sessions)
1427.3.2 by James Hunt
* init/Makefile.am: Added quiesce.o, now required by control.o.
696
		nih_debug ("Chroot Sessions disabled");
1317 by James Hunt
* init/main.c: main(): Display a message to say sessions are disabled if
697
1405.2.1 by Stéphane Graber
Early implementation of the prctl subreaper call
698
	/* Set us as the child subreaper.
699
	 * This ensures that even when init doesn't run as PID 1, it'll always be
700
	 * the ultimate parent of everything it spawns. */
701
1405.2.5 by Stéphane Graber
Skip prctl on systems that don't have it. Also do an explicit define of PR_SET_CHILD_SUBREAPER for systems with older headers. In the case where the kernel doesn't support it, child-subreaper-failed will simply be emitted.
702
#ifdef HAVE_SYS_PRCTL_H
1405.2.2 by Stéphane Graber
Only set as subreaper when pid > 1. Emit a prctl-subreaper-failed event when the prctl call fails.
703
	if (getpid () > 1 && prctl (PR_SET_CHILD_SUBREAPER, 1) < 0) {
1405.2.3 by Stéphane Graber
Drop extra comment, change event from prctl-subreaper-failed to child-subreaper-failed and change wording of the warning.
704
		nih_warn ("%s: %s", _("Unable to register as subreaper"),
1405.2.1 by Stéphane Graber
Early implementation of the prctl subreaper call
705
				  strerror (errno));
1405.2.2 by Stéphane Graber
Only set as subreaper when pid > 1. Emit a prctl-subreaper-failed event when the prctl call fails.
706
1405.2.3 by Stéphane Graber
Drop extra comment, change event from prctl-subreaper-failed to child-subreaper-failed and change wording of the warning.
707
		NIH_MUST (event_new (NULL, "child-subreaper-failed", NULL));
1405.2.1 by Stéphane Graber
Early implementation of the prctl subreaper call
708
	}
1405.2.5 by Stéphane Graber
Skip prctl on systems that don't have it. Also do an explicit define of PR_SET_CHILD_SUBREAPER for systems with older headers. In the case where the kernel doesn't support it, child-subreaper-failed will simply be emitted.
709
#endif
1406 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added "GetEnv" and "SetEnv" methods.
710
806 by Scott James Remnant
* init/process.c (process_setup_limits): Integrate this function back
711
	/* Run through the loop at least once to deal with signals that were
712
	 * delivered to the previous process while the mask was set or to
713
	 * process the startup event we emitted.
714
	 */
470 by Scott James Remnant
* init/main.c (main): Call event_poll instead of event_queue_run.
715
	nih_main_loop_interrupt ();
110 by Scott James Remnant
* init/main.c (main): Write the main function
716
	ret = nih_main_loop ();
717
1515.1.1 by James Hunt
* init/quiesce.c: quiesce_finalise(): Move cleanup to main()
718
	/* Cleanup */
719
	conf_destroy ();
720
	session_destroy ();
721
	control_cleanup ();
722
110 by Scott James Remnant
* init/main.c (main): Write the main function
723
	return ret;
3 by Scott James Remnant
* init/main.c: Add the simplest template main.c
724
}
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
725
726
814 by Scott James Remnant
* init/main.c: Selectively compile out certain pieces when make is
727
#ifndef DEBUG
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
728
/**
1260 by Scott James Remnant
* init/tests/test_conf.c (test_source_reload_job_dir): Add tests for
729
 * logger_kmsg:
730
 * @priority: priority of message being logged,
731
 * @message: message to log.
732
 *
733
 * Outputs the @message to the kernel log message socket prefixed with an
734
 * appropriate tag based on @priority, the program name and terminated with
735
 * a new line.
736
 *
737
 * Returns: zero on success, negative value on error.
738
 **/
739
static int
740
logger_kmsg (NihLogLevel priority,
741
	     const char *message)
742
{
743
	int   tag;
744
	FILE *kmsg;
745
746
	nih_assert (message != NULL);
747
748
	switch (priority) {
749
	case NIH_LOG_DEBUG:
750
		tag = '7';
751
		break;
752
	case NIH_LOG_INFO:
753
		tag = '6';
754
		break;
755
	case NIH_LOG_MESSAGE:
756
		tag = '5';
757
		break;
758
	case NIH_LOG_WARN:
759
		tag = '4';
760
		break;
761
	case NIH_LOG_ERROR:
762
		tag = '3';
763
		break;
764
	case NIH_LOG_FATAL:
765
		tag = '2';
766
		break;
767
	default:
768
		tag = 'd';
769
	}
770
771
	kmsg = fopen ("/dev/kmsg", "w");
772
	if (! kmsg)
773
		return -1;
774
775
	if (fprintf (kmsg, "<%c>%s: %s\n", tag, program_name, message) < 0) {
776
		int saved_errno = errno;
777
		fclose (kmsg);
778
		errno = saved_errno;
779
		return -1;
780
	}
781
782
	if (fclose (kmsg) < 0)
783
		return -1;
784
785
	return 0;
786
}
787
788
789
/**
370 by Scott James Remnant
* init/main.c (segv_handler): Rename to crash_handler and handle
790
 * crash_handler:
253 by Scott James Remnant
* init/cfgfile.c, init/cfgfile.h, init/control.c, init/control.h,
791
 * @signum: signal number received.
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
792
 *
370 by Scott James Remnant
* init/main.c (segv_handler): Rename to crash_handler and handle
793
 * Handle receiving the SEGV or ABRT signal, usually caused by one of
794
 * our own mistakes.  We deal with it by dumping core in a child process
892 by Scott James Remnant
* init/main.c: Drop the attempt to rescue a crashed system by
795
 * and then killing the parent.
370 by Scott James Remnant
* init/main.c (segv_handler): Rename to crash_handler and handle
796
 *
892 by Scott James Remnant
* init/main.c: Drop the attempt to rescue a crashed system by
797
 * Sadly there's no real alternative to the ensuing kernel panic.  Our
798
 * state is likely in tatters, so we can't sigjmp() anywhere "safe" or
799
 * re-exec since the system will be suddenly lobotomised.  We definitely
800
 * don't want to start a root shell or anything like that.  Best thing is
801
 * to just stop the whole thing and hope that bug report comes quickly.
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
802
 **/
803
static void
370 by Scott James Remnant
* init/main.c (segv_handler): Rename to crash_handler and handle
804
crash_handler (int signum)
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
805
{
892 by Scott James Remnant
* init/main.c: Drop the attempt to rescue a crashed system by
806
	pid_t pid;
645 by Scott James Remnant
* init/main.c: Improve restarting and rescuing a little; store the
807
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
808
	nih_assert (args_copy[0] != NULL);
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
809
810
	pid = fork ();
811
	if (pid == 0) {
812
		struct sigaction act;
813
		struct rlimit    limit;
814
		sigset_t         mask;
815
816
		/* Mask out all signals */
817
		sigfillset (&mask);
818
		sigprocmask (SIG_SETMASK, &mask, NULL);
819
370 by Scott James Remnant
* init/main.c (segv_handler): Rename to crash_handler and handle
820
		/* Set the handler to the default so core is dumped */
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
821
		act.sa_handler = SIG_DFL;
822
		act.sa_flags = 0;
823
		sigemptyset (&act.sa_mask);
370 by Scott James Remnant
* init/main.c (segv_handler): Rename to crash_handler and handle
824
		sigaction (signum, &act, NULL);
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
825
826
		/* Don't limit the core dump size */
827
		limit.rlim_cur = RLIM_INFINITY;
828
		limit.rlim_max = RLIM_INFINITY;
829
		setrlimit (RLIMIT_CORE, &limit);
830
806 by Scott James Remnant
* init/process.c (process_setup_limits): Integrate this function back
831
		/* Dump in the root directory */
1197 by Scott James Remnant
* init/main.c (crash_handler): Restore missing chdir ("/") call.
832
		if (chdir ("/"))
833
			nih_warn ("%s: %s", _("Unable to set root directory"),
834
				  strerror (errno));
806 by Scott James Remnant
* init/process.c (process_setup_limits): Integrate this function back
835
370 by Scott James Remnant
* init/main.c (segv_handler): Rename to crash_handler and handle
836
		/* Raise the signal again */
837
		raise (signum);
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
838
839
		/* Unmask so that we receive it */
370 by Scott James Remnant
* init/main.c (segv_handler): Rename to crash_handler and handle
840
		sigdelset (&mask, signum);
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
841
		sigprocmask (SIG_SETMASK, &mask, NULL);
842
843
		/* Wait for death */
844
		pause ();
845
		exit (0);
846
	} else if (pid > 0) {
847
		/* Wait for the core to be generated */
848
		waitpid (pid, NULL, 0);
849
643 by Scott James Remnant
* init/main.c (main, crash_handler): Promote deadly errors to nih_fatal
850
		nih_fatal (_("Caught %s, core dumped"),
374 by Scott James Remnant
* init/main.c (crash_handler): s/SEGV/SIGSEGV/
851
			   (signum == SIGSEGV
852
			    ? "segmentation fault" : "abort"));
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
853
	} else {
643 by Scott James Remnant
* init/main.c (main, crash_handler): Promote deadly errors to nih_fatal
854
		nih_fatal (_("Caught %s, unable to dump core"),
374 by Scott James Remnant
* init/main.c (crash_handler): s/SEGV/SIGSEGV/
855
			   (signum == SIGSEGV
856
			    ? "segmentation fault" : "abort"));
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
857
	}
633 by Scott James Remnant
* init/main.c (crash_handler): Simply trying to leave a SEGV handler
858
892 by Scott James Remnant
* init/main.c: Drop the attempt to rescue a crashed system by
859
	/* Goodbye, cruel world. */
860
	exit (signum);
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
861
}
1371.1.1 by James Hunt
* init/main.c: Add in "bare" re-exec handling from Ubuntu
862
#endif
863
864
/**
865
 * term_handler:
866
 * @data: unused,
867
 * @signal: signal caught.
868
 *
869
 * This is called when we receive the TERM signal, which instructs us
1427.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'EndSession' method.
870
 * to reexec ourselves when running as PID 1, or to perform a controlled
871
 * exit when running as a Session Init.
1371.1.1 by James Hunt
* init/main.c: Add in "bare" re-exec handling from Ubuntu
872
 **/
873
static void
874
term_handler (void      *data,
875
	      NihSignal *signal)
876
{
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
877
	nih_assert (args_copy[0] != NULL);
1371.1.1 by James Hunt
* init/main.c: Add in "bare" re-exec handling from Ubuntu
878
	nih_assert (signal != NULL);
879
1427.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'EndSession' method.
880
	if (user_mode) {
881
		quiesce (QUIESCE_REQUESTER_SYSTEM);
882
		return;
883
	}
884
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
885
	nih_warn (_("Re-executing %s"), args_copy[0]);
1371.1.32 by James Hunt
Updates to re-exec logic and D-Bus handling.
886
	stateful_reexec ();
1371.1.1 by James Hunt
* init/main.c: Add in "bare" re-exec handling from Ubuntu
887
}
888
889
890
#ifndef DEBUG
806 by Scott James Remnant
* init/process.c (process_setup_limits): Integrate this function back
891
/**
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
892
 * cad_handler:
893
 * @data: unused,
894
 * @signal: signal that called this handler.
895
 *
1427.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'EndSession' method.
896
 * Handle having received the SIGINT signal, sent to us when somebody
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
897
 * presses Ctrl-Alt-Delete on the console.  We just generate a
202 by Scott James Remnant
* init/main.c (cad_handler, kbd_handler): Generate the new event
898
 * ctrlaltdel event.
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
899
 **/
900
static void
901
cad_handler (void      *data,
902
	     NihSignal *signal)
903
{
992 by Scott James Remnant
* init/event.c (event_new): There's no reason this shouldn't be
904
	NIH_MUST (event_new (NULL, CTRLALTDEL_EVENT, NULL));
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
905
}
906
907
/**
908
 * kbd_handler:
909
 * @data: unused,
910
 * @signal: signal that called this handler.
911
 *
1427.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'EndSession' method.
912
 * Handle having received the SIGWINCH signal, sent to us when somebody
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
913
 * presses Alt-UpArrow on the console.  We just generate a
914
 * kbdrequest event.
915
 **/
916
static void
917
kbd_handler (void      *data,
918
	     NihSignal *signal)
919
{
992 by Scott James Remnant
* init/event.c (event_new): There's no reason this shouldn't be
920
	NIH_MUST (event_new (NULL, KBDREQUEST_EVENT, NULL));
135 by Scott James Remnant
* init/main.c (main): Stop handling SIGTERM, we never want people
921
}
171 by Scott James Remnant
* init/main.c (stop_handler): Catch STOP/TSTP and CONT.
922
923
/**
584 by Scott James Remnant
* init/event.h (PWRSTATUS_EVENT): Add new power-status-changed event.
924
 * pwr_handler:
925
 * @data: unused,
926
 * @signal: signal that called this handler.
927
 *
1427.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'EndSession' method.
928
 * Handle having received the SIGPWR signal, sent to us when powstatd
584 by Scott James Remnant
* init/event.h (PWRSTATUS_EVENT): Add new power-status-changed event.
929
 * changes the /etc/powerstatus file.  We just generate a
930
 * power-status-changed event and jobs read the file.
931
 **/
932
static void
933
pwr_handler (void      *data,
934
	     NihSignal *signal)
935
{
992 by Scott James Remnant
* init/event.c (event_new): There's no reason this shouldn't be
936
	NIH_MUST (event_new (NULL, PWRSTATUS_EVENT, NULL));
584 by Scott James Remnant
* init/event.h (PWRSTATUS_EVENT): Add new power-status-changed event.
937
}
938
939
/**
720 by Scott James Remnant
* init/main.c (main): Add a handler for the SIGHUP signal
940
 * hup_handler:
941
 * @data: unused,
942
 * @signal: signal that called this handler.
943
 *
1427.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'EndSession' method.
944
 * Handle having received the SIGHUP signal, which we use to instruct us to
720 by Scott James Remnant
* init/main.c (main): Add a handler for the SIGHUP signal
945
 * reload our configuration.
946
 **/
947
static void
948
hup_handler (void      *data,
949
	     NihSignal *signal)
950
{
951
	nih_info (_("Reloading configuration"));
1371.5.1 by Steve Langasek
Drop unnecessary divergence when handling conf sources on re-exec
952
	conf_reload ();
1213 by Scott James Remnant
* init/main.c (hup_handler): Move call to reconnect to D-Bus system
953
}
1157 by Scott James Remnant
* init/main.c (hup_handler): Also try and reconnect to the message
954
1213 by Scott James Remnant
* init/main.c (hup_handler): Move call to reconnect to D-Bus system
955
/**
956
 * usr1_handler:
957
 * @data: unused,
958
 * @signal: signal that called this handler.
959
 *
1427.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'EndSession' method.
960
 * Handle having received the SIGUSR signal, which we use to instruct us to
1213 by Scott James Remnant
* init/main.c (hup_handler): Move call to reconnect to D-Bus system
961
 * reconnect to D-Bus.
962
 **/
963
static void
964
usr1_handler (void      *data,
965
	      NihSignal *signal)
966
{
1546.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'NotifyDBusAddress' method.
967
	nih_assert (! user_mode);
968
1533.2.1 by James Hunt
* init/control.c: Typo.
969
	if (disable_dbus)
970
		return;
971
1157 by Scott James Remnant
* init/main.c (hup_handler): Also try and reconnect to the message
972
	if (! control_bus) {
1546.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'NotifyDBusAddress' method.
973
		char *dbus_bus_name;
974
975
		dbus_bus_name = dbus_bus_type == DBUS_BUS_SESSION
976
			? "session" : "system";
977
978
		nih_info (_("Reconnecting to D-Bus %s bus"),
979
				dbus_bus_name);
1157 by Scott James Remnant
* init/main.c (hup_handler): Also try and reconnect to the message
980
1371.6.7 by Steve Langasek
remove #ifdefed code around control_bus_open; depends on the dbus serialization
981
		if (control_bus_open () < 0) {
1157 by Scott James Remnant
* init/main.c (hup_handler): Also try and reconnect to the message
982
			NihError *err;
983
984
			err = nih_error_get ();
1546.3.1 by James Hunt
* dbus/com.ubuntu.Upstart.xml: Added 'NotifyDBusAddress' method.
985
			nih_warn (_("Unable to connect to the D-Bus %s bus: %s"),
986
					dbus_bus_name, err->message);
1157 by Scott James Remnant
* init/main.c (hup_handler): Also try and reconnect to the message
987
			nih_free (err);
988
		}
989
	}
720 by Scott James Remnant
* init/main.c (main): Add a handler for the SIGHUP signal
990
}
977 by Scott James Remnant
* init/main.c: Also remove SIGTERM handling, we don't re-exec
991
#endif /* DEBUG */
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
992
993
/**
994
 * handle_confdir:
995
 *
1471.1.1 by James Hunt
* init/main.c:
996
 * Determine where system configuration files should be loaded from
997
 * if not specified on the command-line.
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
998
 **/
999
static void
1000
handle_confdir (void)
1001
{
1471.1.1 by James Hunt
* init/main.c:
1002
	char  *dir;
1003
1004
	nih_assert (conf_dirs);
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
1005
1006
	/* user has already specified directory on command-line */
1471.1.1 by James Hunt
* init/main.c:
1007
	if (conf_dirs[0])
1008
		return;
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
1009
1405.7.5 by Dmitrijs Ledkovs
User sessions are born
1010
	if (user_mode)
1011
		return;
1012
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
1013
	dir = getenv (CONFDIR_ENV);
1471.1.1 by James Hunt
* init/main.c:
1014
1015
	NIH_MUST (nih_str_array_add (&conf_dirs, NULL, NULL, dir ? dir : CONFDIR));
1284.1.1 by James Hunt
Add option to allow alternate location for job config files.
1016
}
1017
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
1018
/**
1019
 * handle_logdir:
1020
 *
1021
 * Determine directory where job log files should be written to.
1022
 **/
1023
static void
1024
handle_logdir (void)
1025
{
1026
	char *dir;
1027
1028
	/* user has already specified directory on command-line */
1029
	if (log_dir)
1030
		goto out;
1031
1405.18.1 by Dmitrijs Ledkovs
* init/xdg.[ch]: add xdg_get_cache_home and get_user_log_dir
1032
	if (user_mode) {
1033
		log_dir = get_user_log_dir ();
1034
		return;
1035
	}
1036
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
1037
	log_dir = JOB_LOGDIR;
1038
1039
	dir = getenv (LOGDIR_ENV);
1040
	if (! dir)
1041
		return;
1042
1043
	log_dir = dir;
1044
1045
out:
1046
	nih_debug ("Using alternate log directory %s",
1047
			log_dir);
1048
}
1049
1050
/**  
1051
 * NihOption setter function to handle selection of default console
1052
 * type.
1053
 *
1371.1.3 by James Hunt
Tue Jun 19 17:40:37 BST 2012
1054
 * Returns: 0 on success, -1 on invalid console type.
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
1055
 **/
1056
static int
1057
console_type_setter (NihOption *option, const char *arg)
1058
{
1059
	 nih_assert (option);
1060
1061
	 default_console = (int)job_class_console_type (arg);
1062
1063
	 if (default_console == -1) {
1064
		 nih_fatal ("%s: %s", _("invalid console type specified"), arg);
1065
		 return -1;
1066
	 }
1067
1348 by James Hunt
* init/main.c: console_type_setter(): NihOptionSetter's should
1068
	 return 0;
1330 by James Hunt
Introduction of 'log' argument to 'console' stanza allowing
1069
}
1471.1.1 by James Hunt
* init/main.c:
1070
1071
/**  
1072
 * NihOption setter function to handle selection of configuration file
1073
 * directories.
1074
 *
1075
 * Returns: 0 on success, -1 on invalid console type.
1076
 **/
1077
static int
1078
conf_dir_setter (NihOption *option, const char *arg)
1079
{
1080
	nih_assert (conf_dirs);
1081
	nih_assert (option);
1082
1083
	NIH_MUST (nih_str_array_add (&conf_dirs, NULL, NULL, arg));
1084
1085
	return 0;
1086
}