~jamesodhunt/upstart/test-quiesce-cleanup

« back to all changes in this revision

Viewing changes to init/system.c

  • Committer: Scott James Remnant
  • Date: 2009-07-08 19:43:16 UTC
  • Revision ID: scott@netsplit.com-20090708194316-t6rw4e8auuza6qju
* conf/control-alt-delete.conf: Default job for Control-Alt-Delete
* conf/rc-sysinit.conf: Default job for system initialisation
* conf/rc.conf: A fully wacky instance job that runs the rc script
for runlevel changes
* conf/rcS.conf: And a job for single-user-mode, which calls back
to rc-sysinit
* conf/Makefile.am (dist_init_DATA): Install the default files
into the /etc/init directory
* configure.ac (AC_CONFIG_FILES): Create conf/Makefile
* Makefile.am (SUBDIRS): Recurse into the conf directory.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *
3
3
 * system.c - core system functions
4
4
 *
5
 
 * Copyright © 2010 Canonical Ltd.
 
5
 * Copyright © 2009 Canonical Ltd.
6
6
 * Author: Scott James Remnant <scott@netsplit.com>.
7
7
 *
8
8
 * This program is free software; you can redistribute it and/or modify
26
26
#include <sys/types.h>
27
27
#include <sys/ioctl.h>
28
28
#include <sys/stat.h>
29
 
#include <sys/mount.h>
30
29
 
31
30
#include <fcntl.h>
32
31
#include <signal.h>
33
 
#include <string.h>
34
32
#include <unistd.h>
35
33
#include <termios.h>
36
34
 
37
35
#include <nih/macros.h>
38
 
#include <nih/alloc.h>
39
 
#include <nih/string.h>
40
36
#include <nih/error.h>
41
37
#include <nih/logging.h>
42
38
 
48
44
/**
49
45
 * system_kill:
50
46
 * @pid: process id of process,
51
 
 * @signal: signal to send.
52
 
 *
53
 
 * Send all processes in the same process group as @pid, which may not
54
 
 * necessarily be the group leader the @signal.
 
47
 * @force: force the death.
 
48
 *
 
49
 * Kill all processes in the same process group as @pid, which may not
 
50
 * necessarily be the group leader.
 
51
 *
 
52
 * When @force is FALSE, the TERM signal is sent; when it is TRUE, KILL
 
53
 * is sent instead.
55
54
 *
56
55
 * Returns: zero on success, negative value on raised error.
57
56
 **/
58
57
int
59
58
system_kill (pid_t pid,
60
 
             int   signal)
 
59
             int   force)
61
60
{
 
61
        int   signal;
62
62
        pid_t pgid;
63
63
 
64
64
        nih_assert (pid > 0);
65
65
 
 
66
        signal = (force ? SIGKILL : SIGTERM);
 
67
 
66
68
        pgid = getpgid (pid);
67
69
 
68
70
        if (kill (pgid > 0 ? -pgid : pid, signal) < 0)
110
112
                if (type == CONSOLE_OWNER)
111
113
                        ioctl (fd, TIOCSCTTY, 1);
112
114
                break;
113
 
                /* FALLTHROUGH */
114
 
        case CONSOLE_LOG:
115
115
        case CONSOLE_NONE:
116
116
                /* No console really means /dev/null */
117
117
                fd = open (DEV_NULL, O_RDWR | O_NOCTTY);
159
159
 
160
160
        return 0;
161
161
}
162
 
 
163
 
 
164
 
/**
165
 
 * system_mount:
166
 
 * @type: filesystem type,
167
 
 * @dir: mountpoint,
168
 
 * @flags: mount flags.
169
 
 *
170
 
 * Mount the kernel filesystem @type at @dir with @flags, if not already mounted.  This
171
 
 * is used to ensure that the proc and sysfs filesystems are always
172
 
 * available.
173
 
 *
174
 
 * Filesystems are always mounted with the MS_NODEV, MS_NOEXEC and MS_NOSUID
175
 
 * mount options, which are sensible for /proc and /sys.
176
 
 *
177
 
 * Returns: zero on success, negative value on raised error.
178
 
 **/
179
 
int
180
 
system_mount (const char *type,
181
 
              const char *dir,
182
 
              unsigned long flags)
183
 
{
184
 
        nih_local char *parent = NULL;
185
 
        char *          ptr;
186
 
        struct stat     parent_stat;
187
 
        struct stat     dir_stat;
188
 
 
189
 
        nih_assert (type != NULL);
190
 
        nih_assert (dir != NULL);
191
 
 
192
 
        /* Stat the parent directory of the mountpoint to obtain the dev_t */
193
 
        ptr = strrchr (dir, '/');
194
 
        nih_assert (ptr != NULL);
195
 
 
196
 
        parent = NIH_MUST (nih_strndup (NULL, dir, ptr == dir ? 1 : ptr - dir));
197
 
        if (stat (parent, &parent_stat) < 0)
198
 
                nih_return_system_error (-1);
199
 
 
200
 
        /* Also stat the mountpoint to obtain the dev_t */
201
 
        if (stat (dir, &dir_stat) < 0)
202
 
                nih_return_system_error (-1);
203
 
 
204
 
        /* If the two dev_ts do not match, then there is already a filesystem
205
 
         * mounted and we needn't do anything.
206
 
         */
207
 
        if (parent_stat.st_dev != dir_stat.st_dev)
208
 
                return 0;
209
 
 
210
 
        /* Mount the filesystem */
211
 
        if (mount ("none", dir, type, flags, NULL) < 0)
212
 
                nih_return_system_error (-1);
213
 
 
214
 
        return 0;
215
 
}
216
 
 
217
 
/**
218
 
 * system_mknod:
219
 
 *
220
 
 * @path: full path,
221
 
 * @mode: mode to create device with,
222
 
 * @dev: device major and minor numbers.
223
 
 *
224
 
 * Create specified device.
225
 
 *
226
 
 * Note that depending on the device, if an error occurs
227
 
 * it may not be reportable, hence no return value,
228
 
 * but an attempt to display an error.
229
 
 **/
230
 
void
231
 
system_mknod (const char *path, mode_t mode, dev_t dev)
232
 
{
233
 
        nih_assert (path);
234
 
 
235
 
        if (mknod (path, mode, dev) < 0 && errno != EEXIST)
236
 
                nih_error ("%s: %s", _("Unable to create device"), path);
237
 
}
238
 
 
239
 
/**
240
 
 * system_check_file:
241
 
 *
242
 
 * @path: full path,
243
 
 * @type: file type,
244
 
 * @dev: device major and minor numbers (only checked for character and
245
 
 * block devices).
246
 
 *
247
 
 * Perform checks on specified file.
248
 
 *
249
 
 * Returns: 0 if device exists and has the specified @path,
250
 
 * @type and @dev attributes, else -1.
251
 
 **/
252
 
int
253
 
system_check_file (const char *path, mode_t type, dev_t dev)
254
 
{
255
 
        struct stat  statbuf;
256
 
        int          ret;
257
 
 
258
 
        nih_assert (path);
259
 
 
260
 
        ret = stat (path, &statbuf);
261
 
 
262
 
        if (ret < 0 || ! ((statbuf.st_mode & S_IFMT) == type))
263
 
                return -1;
264
 
 
265
 
        if (type == S_IFCHR || type == S_IFBLK) {
266
 
                if (major (statbuf.st_rdev) != major (dev)
267
 
                        || minor (statbuf.st_rdev) != minor (dev))
268
 
                return -1;
269
 
        }
270
 
 
271
 
        return 0;
272
 
}