~xnox/ubuntu/vivid/upstart/fix-rotate-logs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
/* upstart
 *
 * Copyright © 2011 Canonical Ltd.
 * Author: Scott James Remnant <scott@netsplit.com>.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef INIT_JOB_CLASS_H
#define INIT_JOB_CLASS_H

#include <dbus/dbus.h>

#include <sys/types.h>
#include <sys/resource.h>

#include <time.h>

#include <nih/macros.h>
#include <nih/list.h>
#include <nih/hash.h>

#include <nih-dbus/dbus_message.h>

#include "process.h"
#include "event_operator.h"
#include "session.h"


/**
 * ExpectType:
 *
 * This is used to determine what to expect to happen before moving the job
 * from the spawned state.  EXPECT_NONE means that we don't expect anything
 * so the job will move directly out of the spawned state without waiting.
 **/
typedef enum expect_type {
	EXPECT_NONE,
	EXPECT_STOP,
	EXPECT_DAEMON,
	EXPECT_FORK
} ExpectType;

/**
 * ConsoleType:
 *
 * This is used to identify how a job would like its standard input, output
 * and error file descriptors arranged.  The options are:
 * - CONSOLE_NONE: to have these all mapped to /dev/null,
 * - CONSOLE_OUTPUT: the console device (non-owning process),
 * - CONSOLE_OWNER: the console device (owning process),
 * - CONSOLE_LOG: stdin is mapped to /dev/null and standard output and error
 *   are redirected to the built-in logger (this is the default).
 **/
typedef enum console_type {
	CONSOLE_NONE,
	CONSOLE_OUTPUT,
	CONSOLE_OWNER,
	CONSOLE_LOG
} ConsoleType;


/**
 * JOB_DEFAULT_KILL_TIMEOUT:
 *
 * The default length of time to wait after sending a process the TERM
 * signal before sending the KILL signal if it hasn't terminated.
 **/
#define JOB_DEFAULT_KILL_TIMEOUT 5

/**
 * JOB_DEFAULT_RESPAWN_LIMIT:
 *
 * The default number of times in JOB_DEFAULT_RESPAWN_INTERVAL seconds that
 * we permit a process to respawn before stoping it
 **/
#define JOB_DEFAULT_RESPAWN_LIMIT 10

/**
 * JOB_DEFAULT_RESPAWN_INTERVAL:
 *
 * The default number of seconds before resetting the respawn timer.
 **/
#define JOB_DEFAULT_RESPAWN_INTERVAL 5

/**
 * JOB_DEFAULT_UMASK:
 *
 * The default file creation mark for processes.
 **/
#define JOB_DEFAULT_UMASK 022

/**
 * JOB_NICE_INVALID:
 *
 * The nice level for processes when no nice level is set.
 **/
#define JOB_NICE_INVALID -21

/**
 * JOB_DEFAULT_OOM_SCORE_ADJ:
 *
 * The default OOM score adjustment for processes.
 **/
#define JOB_DEFAULT_OOM_SCORE_ADJ 0

/**
 * JOB_DEFAULT_ENVIRONMENT:
 *
 * Environment variables to always copy from our own environment, these
 * can be overriden in the job definition or by events since they have the
 * lowest priority.
 **/
#define JOB_DEFAULT_ENVIRONMENT \
	"PATH",			\
	"TERM"


/**
 * JobClass:
 * @entry: list header,
 * @name: unique name,
 * @path: path of D-Bus object,
 * @session: attached session,
 * @instance: pattern to uniquely identify multiple instances,
 * @instances: hash table of active instances,
 * @description: description; intended for humans,
 * @author: author; intended for humans,
 * @version: version; intended for humans,
 * @env: NULL-terminated array of default environment variables,
 * @export: NULL-terminated array of environment exported to events,
 * @start_on: event operator expression that can start an instance,
 * @stop_on: event operator expression that stops instances,
 * @emits: NULL-terminated array of events that may be emitted by instances,
 * @process: processes to be run,
 * @expect: what to expect before entering the next state after spawned,
 * @task: start requests are not unblocked until instances have finished,
 * @kill_timeout: time to wait between sending TERM and KILL signals,
 * @kill_signal: first signal to send (usually SIGTERM),
 * @reload_signal: reload signal to send (usually SIGHUP),
 * @respawn: instances should be restarted if main process fails,
 * @respawn_limit: number of respawns in @respawn_interval that we permit,
 * @respawn_interval: barrier for @respawn_limit,
 * @normalexit: array of exit codes that prevent a respawn,
 * @normalexit_len: length of @normalexit array,
 * @console: how to arrange processes' stdin/out/err file descriptors,
 * @umask: file mode creation mask,
 * @nice: process priority,
 * @oom_score_adj: OOM killer score adjustment,
 * @limits: resource limits indexed by resource,
 * @chroot: root directory of process (implies @chdir if not set),
 * @chdir: working directory of process,
 * @setuid: user name to drop to before starting process,
 * @setgid: group name to drop to before starting process,
 * @deleted: whether job should be deleted when finished,
 * @usage: usage text - how to control job,
 * @apparmor_switch: AppArmor profile to switch to before starting job,
 * @cgroups: list of CGroup objects representing the cgroups the
 *  job is required to run in,
 * @cgmanager_wait: TRUE if job waiting for cgroup manager to be
 * available.
 *
 * This structure holds the configuration of a known task or service that
 * should be tracked by the init daemon; as tasks and services are
 * fundamentally identical except for when they "finish", they are both
 * collated together and only differ in the value of @task.
 **/
typedef struct job_class {
	NihList         entry;

	char           *name;
	char           *path;
	Session *       session;

	char           *instance;
	NihHash        *instances;

	char           *description;
	char           *author;
	char           *version;

	char          **env;
	char          **export;

	EventOperator  *start_on;
	EventOperator  *stop_on;
	char          **emits;

	Process       **process;
	ExpectType      expect;
	int             task;

	time_t          kill_timeout;
	int             kill_signal;

	int             reload_signal;

	int             respawn;
	int             respawn_limit;
	time_t          respawn_interval;

	int            *normalexit;
	size_t          normalexit_len;

	ConsoleType     console;

	mode_t          umask;
	int             nice;
	int             oom_score_adj;
	struct rlimit  *limits[RLIMIT_NLIMITS];
	char           *chroot;
	char           *chdir;
	char           *setuid;
	char           *setgid;

	int             deleted;
	int             debug;

	char           *usage;

	char	       *apparmor_switch;
	NihList         cgroups;
	int             cgmanager_wait;
} JobClass;


NIH_BEGIN_EXTERN

extern NihHash  *job_classes;

void        job_class_init                 (void);

void        job_class_environment_init     (void);

void        job_class_environment_reset    (void);

void        job_class_environment_clear    (void);

int         job_class_environment_set      (const char *var, int replace);
int         job_class_environment_unset    (const char *name);

char **     job_class_environment_get_all  (const void *parent)
	__attribute__ ((warn_unused_result));

const char *job_class_environment_get      (const char *name)
	__attribute__ ((warn_unused_result));

JobClass  * job_class_new                  (const void *parent,
					    const char *name,
					    Session *session)
	__attribute__ ((warn_unused_result));

int         job_class_consider             (JobClass *class);
int         job_class_reconsider           (JobClass *class);

void        job_class_add_safe             (JobClass *class);

void        job_class_register             (JobClass *class,
					    DBusConnection *conn, int signal);
void        job_class_unregister           (JobClass *class,
					    DBusConnection *conn);

char      **job_class_environment          (const void *parent,
					    JobClass *class, size_t *len)
	__attribute__ ((warn_unused_result));


int         job_class_get_instance         (JobClass *class,
					    NihDBusMessage *message,
					    char * const *env,
					    char **instance)
	__attribute__ ((warn_unused_result));
int         job_class_get_instance_by_name (JobClass *class,
					    NihDBusMessage *message,
					    const char *name,
					    char **instance)
	__attribute__ ((warn_unused_result));
int         job_class_get_all_instances    (JobClass *class,
					    NihDBusMessage *message,
					    char ***instances)
	__attribute__ ((warn_unused_result));

int         job_class_start                (JobClass *class,
					    NihDBusMessage *message,
					    char * const *env, int wait)
	__attribute__ ((warn_unused_result));
int         job_class_stop                 (JobClass *class,
					    NihDBusMessage *message,
					    char * const *env, int wait)
	__attribute__ ((warn_unused_result));
int         job_class_restart              (JobClass *class,
					    NihDBusMessage *message,
					    char * const *env, int wait)
	__attribute__ ((warn_unused_result));

int         job_class_get_name             (JobClass *class,
					    NihDBusMessage *message,
					    char **name)
	__attribute__ ((warn_unused_result));
int         job_class_get_description      (JobClass *class,
					    NihDBusMessage *message,
					    char **description)
	__attribute__ ((warn_unused_result));
int         job_class_get_author           (JobClass *class,
					    NihDBusMessage *message,
					    char **author)
	__attribute__ ((warn_unused_result));
int         job_class_get_version          (JobClass *class,
					    NihDBusMessage *message,
					    char **version)
	__attribute__ ((warn_unused_result));

int         job_class_get_start_on         (JobClass *class,
					    NihDBusMessage *message,
					    char ****start_on);
int         job_class_get_stop_on          (JobClass *class,
					    NihDBusMessage *message,
					    char ****stop_on);
int         job_class_get_emits	           (JobClass *class,
					    NihDBusMessage *message,
					    char ***emits);
int         job_class_get_usage	           (JobClass *class,
					    NihDBusMessage *message,
					    char **usage);

const char *
job_class_console_type_enum_to_str (ConsoleType console)
	__attribute__ ((warn_unused_result));

ConsoleType
job_class_console_type_str_to_enum (const char *name)
	__attribute__ ((warn_unused_result));

const char *
job_class_expect_type_enum_to_str (ExpectType expect)
	__attribute__ ((warn_unused_result));

ExpectType
job_class_expect_type_str_to_enum (const char *name)
	__attribute__ ((warn_unused_result));

ConsoleType job_class_console_type         (const char *console)
	__attribute__ ((warn_unused_result));

json_object *job_class_serialise (JobClass *class)
	__attribute__ ((warn_unused_result));

JobClass *job_class_deserialise (json_object *json)
	__attribute__ ((warn_unused_result));

json_object * job_class_serialise_all (void)
	__attribute__ ((warn_unused_result));

int job_class_deserialise_all (json_object *json)
	__attribute__ ((warn_unused_result));

JobClass * job_class_get (const char *name, Session *session)
	__attribute__ ((warn_unused_result));

json_object * job_class_serialise_job_environ (void)
	__attribute__ ((warn_unused_result));

int job_class_deserialise_job_environ (json_object *json)
	__attribute__ ((warn_unused_result));

void job_class_prepare_reexec (void);

time_t     job_class_max_kill_timeout (void)
	__attribute__ ((warn_unused_result));

JobClass  *job_class_get_registered (const char *name, const Session *session)
	__attribute__ ((warn_unused_result));

void       job_class_event_block (void *parent, JobClass *old, JobClass *new);

ssize_t
job_class_get_index (const JobClass *class)
	__attribute__ ((warn_unused_result));

int job_class_induct_job (JobClass *class)
	__attribute__ ((warn_unused_result));

#ifdef ENABLE_CGROUPS

int job_class_induct_jobs (void)
	__attribute__ ((warn_unused_result));

int job_class_cgroups (JobClass *class)
	__attribute__ ((warn_unused_result));

#endif /* ENABLE_CGROUPS */

NIH_END_EXTERN

#endif /* INIT_JOB_CLASS_H */