~ubuntu-branches/ubuntu/quantal/lxc/quantal-201208301614

« back to all changes in this revision

Viewing changes to src/lxc/start.c

  • Committer: Bazaar Package Importer
  • Author(s): Guido Trotter
  • Date: 2010-06-28 10:15:48 UTC
  • mto: (1.1.4 upstream) (3.1.5 sid)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20100628101548-vexhggdo6x9cpwtk
ImportĀ upstreamĀ versionĀ 0.7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
#include <sys/param.h>
37
37
#include <sys/file.h>
38
38
#include <sys/mount.h>
 
39
#include <sys/stat.h>
39
40
#include <sys/types.h>
40
41
#include <sys/prctl.h>
41
42
#include <sys/types.h>
44
45
#include <sys/un.h>
45
46
#include <sys/poll.h>
46
47
 
47
 
#ifdef HAVE_SYS_SIGNALFD_H 
 
48
#ifdef HAVE_SYS_SIGNALFD_H
48
49
#  include <sys/signalfd.h>
49
50
#else
 
51
/* assume kernel headers are too old */
 
52
#include <stdint.h>
 
53
struct signalfd_siginfo
 
54
{
 
55
        uint32_t ssi_signo;
 
56
        int32_t ssi_errno;
 
57
        int32_t ssi_code;
 
58
        uint32_t ssi_pid;
 
59
        uint32_t ssi_uid;
 
60
        int32_t ssi_fd;
 
61
        uint32_t ssi_tid;
 
62
        uint32_t ssi_band;
 
63
        uint32_t ssi_overrun;
 
64
        uint32_t ssi_trapno;
 
65
        int32_t ssi_status;
 
66
        int32_t ssi_int;
 
67
        uint64_t ssi_ptr;
 
68
        uint64_t ssi_utime;
 
69
        uint64_t ssi_stime;
 
70
        uint64_t ssi_addr;
 
71
        uint8_t __pad[48];
 
72
};
 
73
 
50
74
#  ifndef __NR_signalfd4
51
75
/* assume kernel headers are too old */
52
76
#    if __i386__
88
112
#define PR_CAPBSET_DROP 24
89
113
#endif
90
114
 
91
 
#include <lxc/log.h>
92
 
#include <lxc/conf.h>
93
 
#include <lxc/confile.h>
94
 
#include <lxc/start.h>
95
 
#include <lxc/utils.h>
96
 
#include <lxc/cgroup.h>
97
 
#include <lxc/monitor.h>
98
 
 
 
115
#include "start.h"
 
116
#include "conf.h"
 
117
#include "cgroup.h"
 
118
#include "log.h"
 
119
#include "cgroup.h"
99
120
#include "error.h"
100
121
#include "af_unix.h"
101
122
#include "mainloop.h"
 
123
#include "utils.h"
 
124
#include "utmp.h"
 
125
#include "monitor.h"
102
126
#include "commands.h"
103
 
 
 
127
#include "console.h"
 
128
#include "sync.h"
104
129
 
105
130
lxc_log_define(lxc_start, lxc);
106
131
 
107
132
LXC_TTY_HANDLER(SIGINT);
108
133
LXC_TTY_HANDLER(SIGQUIT);
109
134
 
 
135
static int match_fd(int fd)
 
136
{
 
137
        return (fd == 0 || fd == 1 || fd == 2);
 
138
}
 
139
 
 
140
int lxc_check_inherited(int fd_to_ignore)
 
141
{
 
142
        struct dirent dirent, *direntp;
 
143
        int fd, fddir;
 
144
        DIR *dir;
 
145
        int ret = 0;
 
146
 
 
147
        dir = opendir("/proc/self/fd");
 
148
        if (!dir) {
 
149
                WARN("failed to open directory: %m");
 
150
                return -1;
 
151
        }
 
152
 
 
153
        fddir = dirfd(dir);
 
154
 
 
155
        while (!readdir_r(dir, &dirent, &direntp)) {
 
156
                char procpath[64];
 
157
                char path[PATH_MAX];
 
158
 
 
159
                if (!direntp)
 
160
                        break;
 
161
 
 
162
                if (!strcmp(direntp->d_name, "."))
 
163
                        continue;
 
164
 
 
165
                if (!strcmp(direntp->d_name, ".."))
 
166
                        continue;
 
167
 
 
168
                fd = atoi(direntp->d_name);
 
169
 
 
170
                if (fd == fddir || fd == lxc_log_fd || fd == fd_to_ignore)
 
171
                        continue;
 
172
 
 
173
                if (match_fd(fd))
 
174
                        continue;
 
175
                /*
 
176
                 * found inherited fd
 
177
                 */
 
178
                ret = -1;
 
179
 
 
180
                snprintf(procpath, sizeof(procpath), "/proc/self/fd/%d", fd);
 
181
 
 
182
                if (readlink(procpath, path, sizeof(path)) == -1)
 
183
                        ERROR("readlink(%s) failed : %m", procpath);
 
184
                else
 
185
                        ERROR("inherited fd %d on %s", fd, path);
 
186
        }
 
187
 
 
188
        if (closedir(dir))
 
189
                ERROR("failed to close directory");
 
190
        return ret;
 
191
}
 
192
 
110
193
static int setup_sigchld_fd(sigset_t *oldmask)
111
194
{
112
195
        sigset_t mask;
139
222
        return fd;
140
223
}
141
224
 
142
 
static int sigchld_handler(int fd, void *data, 
 
225
static int sigchld_handler(int fd, void *data,
143
226
                           struct lxc_epoll_descr *descr)
144
227
{
145
 
        DEBUG("child exited");
146
 
 
 
228
        struct signalfd_siginfo siginfo;
 
229
        int ret;
 
230
        pid_t *pid = data;
 
231
 
 
232
        ret = read(fd, &siginfo, sizeof(siginfo));
 
233
        if (ret < 0) {
 
234
                ERROR("failed to read sigchld info");
 
235
                return -1;
 
236
        }
 
237
 
 
238
        if (ret != sizeof(siginfo)) {
 
239
                ERROR("unexpected siginfo size");
 
240
                return -1;
 
241
        }
 
242
 
 
243
        if (siginfo.ssi_code == CLD_STOPPED ||
 
244
            siginfo.ssi_code == CLD_CONTINUED) {
 
245
                INFO("container init process was stopped/continued");
 
246
                return 0;
 
247
        }
 
248
 
 
249
        /* more robustness, protect ourself from a SIGCHLD sent
 
250
         * by a process different from the container init
 
251
         */
 
252
        if (siginfo.ssi_pid != *pid) {
 
253
                WARN("invalid pid for SIGCHLD");
 
254
                return 0;
 
255
        }
 
256
 
 
257
        DEBUG("container init process exited");
147
258
        return 1;
148
259
}
149
260
 
 
261
int lxc_pid_callback(int fd, struct lxc_request *request,
 
262
                     struct lxc_handler *handler)
 
263
{
 
264
        struct lxc_answer answer;
 
265
        int ret;
 
266
 
 
267
        answer.pid = handler->pid;
 
268
        answer.ret = 0;
 
269
 
 
270
        ret = send(fd, &answer, sizeof(answer), 0);
 
271
        if (ret < 0) {
 
272
                WARN("failed to send answer to the peer");
 
273
                return -1;
 
274
        }
 
275
 
 
276
        if (ret != sizeof(answer)) {
 
277
                ERROR("partial answer sent");
 
278
                return -1;
 
279
        }
 
280
 
 
281
        return 0;
 
282
}
 
283
 
150
284
int lxc_set_state(const char *name, struct lxc_handler *handler, lxc_state_t state)
151
285
{
152
286
        handler->state = state;
170
304
                goto out_mainloop_open;
171
305
        }
172
306
 
173
 
        if (lxc_command_mainloop_add(name, &descr, handler))
174
 
                goto out_mainloop_open;
 
307
        if (lxc_console_mainloop_add(&descr, handler)) {
 
308
                ERROR("failed to add console handler to mainloop");
 
309
                goto out_mainloop_open;
 
310
        }
 
311
 
 
312
        if (lxc_command_mainloop_add(name, &descr, handler)) {
 
313
                ERROR("failed to add command handler to mainloop");
 
314
                goto out_mainloop_open;
 
315
        }
 
316
 
 
317
        if (lxc_utmp_mainloop_add(&descr, handler)) {
 
318
                ERROR("failed to add utmp handler to mainloop");
 
319
                goto out_mainloop_open;
 
320
        }
175
321
 
176
322
        return lxc_mainloop(&descr);
177
323
 
182
328
        return -1;
183
329
}
184
330
 
185
 
static int fdname(int fd, char *name, size_t size)
186
 
{
187
 
        char path[MAXPATHLEN];
188
 
        ssize_t len;
189
 
 
190
 
        snprintf(path, MAXPATHLEN, "/proc/self/fd/%d", fd);
191
 
 
192
 
        len = readlink(path, name, size);
193
 
        if (len >  0)
194
 
                path[len] = '\0';
195
 
 
196
 
        return (len <= 0) ? -1 : 0;
197
 
}
198
 
 
199
 
static int console_init(char *console, size_t size)
200
 
{
201
 
        struct stat stat;
202
 
        int i;
203
 
 
204
 
        for (i = 0; i < 3; i++) {
205
 
                if (!isatty(i))
206
 
                        continue;
207
 
 
208
 
                if (ttyname_r(i, console, size)) {
209
 
                        SYSERROR("failed to retrieve tty name");
210
 
                        return -1;
211
 
                }
212
 
 
213
 
                return 0;
214
 
        }
215
 
 
216
 
        if (!fstat(0, &stat)) {
217
 
                if (S_ISREG(stat.st_mode) || S_ISCHR(stat.st_mode) ||
218
 
                    S_ISFIFO(stat.st_mode) || S_ISLNK(stat.st_mode))
219
 
                        return fdname(0, console, size);
220
 
        }
221
 
 
222
 
        console[0] = '\0';
223
 
 
224
 
        DEBUG("console initialized");
225
 
 
226
 
        return 0;
227
 
}
228
 
 
229
331
struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf)
230
332
{
231
333
        struct lxc_handler *handler;
238
340
 
239
341
        handler->conf = conf;
240
342
 
 
343
        handler->name = strdup(name);
 
344
        if (!handler->name) {
 
345
                ERROR("failed to allocate memory");
 
346
                goto out_free;
 
347
        }
 
348
 
241
349
        /* Begin the set the state to STARTING*/
242
350
        if (lxc_set_state(name, handler, STARTING)) {
243
351
                ERROR("failed to set state '%s'", lxc_state2str(STARTING));
244
 
                goto out_free;
245
 
        }
246
 
 
247
 
        if (console_init(conf->console, sizeof(conf->console))) {
248
 
                ERROR("failed to initialize the console");
249
 
                goto out_aborting;
 
352
                goto out_free_name;
250
353
        }
251
354
 
252
355
        if (lxc_create_tty(name, conf)) {
254
357
                goto out_aborting;
255
358
        }
256
359
 
 
360
        if (lxc_create_console(conf)) {
 
361
                ERROR("failed to create console");
 
362
                goto out_delete_tty;
 
363
        }
 
364
 
257
365
        /* the signal fd has to be created before forking otherwise
258
366
         * if the child process exits before we setup the signal fd,
259
367
         * the event will be lost and the command will be stuck */
260
368
        handler->sigfd = setup_sigchld_fd(&handler->oldmask);
261
369
        if (handler->sigfd < 0) {
262
370
                ERROR("failed to set sigchild fd handler");
263
 
                goto out_delete_tty;
 
371
                goto out_delete_console;
264
372
        }
265
373
 
266
 
        /* Avoid signals from terminal */
267
 
        LXC_TTY_ADD_HANDLER(SIGINT);
268
 
        LXC_TTY_ADD_HANDLER(SIGQUIT);
269
 
 
270
374
        INFO("'%s' is initialized", name);
271
375
        return handler;
272
376
 
 
377
out_delete_console:
 
378
        lxc_delete_console(&conf->console);
273
379
out_delete_tty:
274
380
        lxc_delete_tty(&conf->tty_info);
275
381
out_aborting:
276
382
        lxc_set_state(name, handler, ABORTING);
 
383
out_free_name:
 
384
        free(handler->name);
 
385
        handler->name = NULL;
277
386
out_free:
278
387
        free(handler);
279
388
        return NULL;
286
395
         */
287
396
        lxc_set_state(name, handler, STOPPING);
288
397
        lxc_set_state(name, handler, STOPPED);
289
 
        lxc_unlink_nsgroup(name);
290
 
 
 
398
 
 
399
        /* reset mask set by setup_sigchld_fd */
 
400
        if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL))
 
401
                WARN("failed to restore sigprocmask");
 
402
 
 
403
        lxc_delete_console(&handler->conf->console);
291
404
        lxc_delete_tty(&handler->conf->tty_info);
 
405
        free(handler->name);
292
406
        free(handler);
293
 
 
294
 
        LXC_TTY_DEL_HANDLER(SIGQUIT);
295
 
        LXC_TTY_DEL_HANDLER(SIGINT);
296
407
}
297
408
 
298
409
void lxc_abort(const char *name, struct lxc_handler *handler)
299
410
{
300
411
        lxc_set_state(name, handler, ABORTING);
301
 
        kill(handler->pid, SIGKILL);
 
412
        if (handler->pid > 0)
 
413
                kill(handler->pid, SIGKILL);
302
414
}
303
415
 
304
 
struct start_arg {
305
 
        const char *name;
306
 
        char *const *argv;
307
 
        struct lxc_handler *handler;
308
 
        int *sv;
309
 
};
310
 
 
311
 
static int do_start(void *arg)
 
416
static int do_start(void *data)
312
417
{
313
 
        struct start_arg *start_arg = arg;
314
 
        struct lxc_handler *handler = start_arg->handler;
315
 
        const char *name = start_arg->name;
316
 
        char *const *argv = start_arg->argv;
317
 
        int *sv = start_arg->sv;
318
 
        int err = -1, sync;
 
418
        struct lxc_handler *handler = data;
319
419
 
320
420
        if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) {
321
421
                SYSERROR("failed to set sigprocmask");
322
422
                return -1;
323
423
        }
324
424
 
325
 
        close(sv[1]);
326
 
 
327
 
        /* Be sure we don't inherit this after the exec */
328
 
        fcntl(sv[0], F_SETFD, FD_CLOEXEC);
329
 
 
330
 
        /* Tell our father he can begin to configure the container */
331
 
        if (write(sv[0], &sync, sizeof(sync)) < 0) {
332
 
                SYSERROR("failed to write socket");
333
 
                return -1;
334
 
        }
335
 
 
336
 
        /* Wait for the father to finish the configuration */
337
 
        if (read(sv[0], &sync, sizeof(sync)) < 0) {
338
 
                SYSERROR("failed to read socket");
339
 
                return -1;
340
 
        }
 
425
        lxc_sync_fini_parent(handler);
 
426
 
 
427
        /* Tell the parent task it can begin to configure the
 
428
         * container and wait for it to finish
 
429
         */
 
430
        if (lxc_sync_barrier_parent(handler, LXC_SYNC_CONFIGURE))
 
431
                return -1;
341
432
 
342
433
        /* Setup the container, ip, names, utsname, ... */
343
 
        if (lxc_setup(name, handler->conf)) {
 
434
        if (lxc_setup(handler->name, handler->conf)) {
344
435
                ERROR("failed to setup the container");
345
436
                goto out_warn_father;
346
437
        }
355
446
                return -1;
356
447
        }
357
448
 
358
 
        NOTICE("exec'ing '%s'", argv[0]);
 
449
        close(handler->sigfd);
359
450
 
360
 
        execvp(argv[0], argv);
361
 
        SYSERROR("failed to exec %s", argv[0]);
 
451
        /* after this call, we are in error because this
 
452
         * ops should not return as it execs */
 
453
        if (handler->ops->start(handler, handler->data))
 
454
                return -1;
362
455
 
363
456
out_warn_father:
364
 
        /* If the exec fails, tell that to our father */
365
 
        if (write(sv[0], &err, sizeof(err)) < 0)
366
 
                SYSERROR("failed to write the socket");
 
457
        lxc_sync_wake_parent(handler, LXC_SYNC_POST_CONFIGURE);
367
458
        return -1;
368
459
}
369
460
 
370
 
int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[])
 
461
int lxc_spawn(struct lxc_handler *handler)
371
462
{
372
 
        int sv[2];
373
463
        int clone_flags;
374
 
        int err = -1, sync;
375
 
 
376
 
        struct start_arg start_arg = {
377
 
                .name = name,
378
 
                .argv = argv,
379
 
                .handler = handler,
380
 
                .sv = sv,
381
 
        };
382
 
 
383
 
        /* Synchro socketpair */
384
 
        if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
385
 
                SYSERROR("failed to create communication socketpair");
 
464
        int failed_before_rename = 0;
 
465
        const char *name = handler->name;
 
466
 
 
467
        if (lxc_sync_init(handler))
386
468
                return -1;
387
 
        }
388
469
 
389
470
        clone_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
390
471
        if (!lxc_list_empty(&handler->conf->network)) {
396
477
                 */
397
478
                if (lxc_create_network(&handler->conf->network)) {
398
479
                        ERROR("failed to create the network");
399
 
                        goto out_close;
 
480
                        lxc_sync_fini(handler);
 
481
                        return -1;
400
482
                }
401
483
        }
402
484
 
 
485
 
403
486
        /* Create a process in a new set of namespaces */
404
 
        handler->pid = lxc_clone(do_start, &start_arg, clone_flags);
 
487
        handler->pid = lxc_clone(do_start, handler, clone_flags);
405
488
        if (handler->pid < 0) {
406
489
                SYSERROR("failed to fork into a new namespace");
407
 
                goto out_close;
408
 
        }
409
 
 
410
 
        close(sv[0]);
411
 
        
412
 
        /* Wait for the child to be ready */
413
 
        if (read(sv[1], &sync, sizeof(sync)) < 0) {
414
 
                SYSERROR("failed to read the socket");
415
 
                goto out_abort;
416
 
        }
 
490
                goto out_delete_net;
 
491
        }
 
492
 
 
493
        lxc_sync_fini_child(handler);
 
494
 
 
495
        if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE))
 
496
                failed_before_rename = 1;
417
497
 
418
498
        if (lxc_rename_nsgroup(name, handler))
419
 
                goto out_abort;
 
499
                goto out_delete_net;
 
500
 
 
501
        if (failed_before_rename)
 
502
                goto out_delete_net;
420
503
 
421
504
        /* Create the network configuration */
422
505
        if (clone_flags & CLONE_NEWNET) {
423
506
                if (lxc_assign_network(&handler->conf->network, handler->pid)) {
424
507
                        ERROR("failed to create the configured network");
425
 
                        goto out_abort;
 
508
                        goto out_delete_net;
426
509
                }
427
510
        }
428
511
 
429
 
        /* Tell the child to continue its initialization */
430
 
        if (write(sv[1], &sync, sizeof(sync)) < 0) {
431
 
                SYSERROR("failed to write the socket");
432
 
                goto out_abort;
433
 
        }
 
512
        /* Tell the child to continue its initialization and wait for
 
513
         * it to exec or return an error
 
514
         */
 
515
        if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CONFIGURE))
 
516
                return -1;
434
517
 
435
 
        /* Wait for the child to exec or returning an error */
436
 
        if (read(sv[1], &sync, sizeof(sync)) < 0) {
437
 
                ERROR("failed to read the socket");
 
518
        if (handler->ops->post_start(handler, handler->data))
438
519
                goto out_abort;
439
 
        }
440
520
 
441
521
        if (lxc_set_state(name, handler, RUNNING)) {
442
522
                ERROR("failed to set state to %s",
444
524
                goto out_abort;
445
525
        }
446
526
 
447
 
        err = 0;
448
 
 
449
 
        NOTICE("'%s' started with pid '%d'", argv[0], handler->pid);
450
 
 
451
 
out_close:
452
 
        close(sv[0]);
453
 
        close(sv[1]);
454
 
        return err;
455
 
 
 
527
        lxc_sync_fini(handler);
 
528
        return 0;
 
529
 
 
530
out_delete_net:
 
531
        if (clone_flags & CLONE_NEWNET)
 
532
                lxc_delete_network(&handler->conf->network);
456
533
out_abort:
457
534
        lxc_abort(name, handler);
458
 
        close(sv[1]);
 
535
        lxc_sync_fini(handler);
459
536
        return -1;
460
537
}
461
538
 
462
 
int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf)
 
539
int __lxc_start(const char *name, struct lxc_conf *conf,
 
540
                struct lxc_operations* ops, void *data)
463
541
{
464
542
        struct lxc_handler *handler;
465
543
        int err = -1;
470
548
                ERROR("failed to initialize the container");
471
549
                return -1;
472
550
        }
 
551
        handler->ops = ops;
 
552
        handler->data = data;
473
553
 
474
 
        err = lxc_spawn(name, handler, argv);
 
554
        err = lxc_spawn(handler);
475
555
        if (err) {
476
 
                ERROR("failed to spawn '%s'", argv[0]);
 
556
                ERROR("failed to spawn '%s'", name);
477
557
                goto out_fini;
478
558
        }
479
559
 
480
 
        err = lxc_close_all_inherited_fd();
481
 
        if (err) {
482
 
                ERROR("unable to close inherited fds");
483
 
                goto out_abort;
484
 
        }
 
560
        /* Avoid signals from terminal */
 
561
        LXC_TTY_ADD_HANDLER(SIGINT);
 
562
        LXC_TTY_ADD_HANDLER(SIGQUIT);
485
563
 
486
564
        err = lxc_poll(name, handler);
487
565
        if (err) {
494
572
 
495
573
        err =  lxc_error_set_and_log(handler->pid, status);
496
574
out_fini:
 
575
        LXC_TTY_DEL_HANDLER(SIGQUIT);
 
576
        LXC_TTY_DEL_HANDLER(SIGINT);
 
577
        lxc_unlink_nsgroup(name);
497
578
        lxc_fini(name, handler);
498
579
        return err;
499
580
 
501
582
        lxc_abort(name, handler);
502
583
        goto out_fini;
503
584
}
 
585
 
 
586
struct start_args {
 
587
        char *const *argv;
 
588
};
 
589
 
 
590
static int start(struct lxc_handler *handler, void* data)
 
591
{
 
592
        struct start_args *arg = data;
 
593
 
 
594
        NOTICE("exec'ing '%s'", arg->argv[0]);
 
595
 
 
596
        execvp(arg->argv[0], arg->argv);
 
597
        SYSERROR("failed to exec %s", arg->argv[0]);
 
598
        return 0;
 
599
}
 
600
 
 
601
static int post_start(struct lxc_handler *handler, void* data)
 
602
{
 
603
        struct start_args *arg = data;
 
604
 
 
605
        NOTICE("'%s' started with pid '%d'", arg->argv[0], handler->pid);
 
606
        return 0;
 
607
}
 
608
 
 
609
static struct lxc_operations start_ops = {
 
610
        .start = start,
 
611
        .post_start = post_start
 
612
};
 
613
 
 
614
int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf)
 
615
{
 
616
        struct start_args start_arg = {
 
617
                .argv = argv,
 
618
        };
 
619
 
 
620
        if (lxc_check_inherited(-1))
 
621
                return -1;
 
622
 
 
623
        return __lxc_start(name, conf, &start_ops, &start_arg);
 
624
}