]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/start.c
Move the configuration file to the start function
[mirror_lxc.git] / src / lxc / start.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "../config.h"
25 #include <stdio.h>
26 #undef _GNU_SOURCE
27 #include <string.h>
28 #include <stdlib.h>
29 #include <dirent.h>
30 #include <errno.h>
31 #include <unistd.h>
32 #include <signal.h>
33 #include <fcntl.h>
34 #include <termios.h>
35 #include <namespace.h>
36 #include <sys/param.h>
37 #include <sys/file.h>
38 #include <sys/mount.h>
39 #include <sys/types.h>
40 #include <sys/prctl.h>
41 #include <sys/types.h>
42 #include <sys/capability.h>
43 #include <sys/wait.h>
44 #include <sys/un.h>
45 #include <sys/poll.h>
46
47 #include <lxc/lxc.h>
48 #include <lxc/confile.h>
49
50 #ifdef HAVE_SYS_SIGNALFD_H
51 # include <sys/signalfd.h>
52 #else
53 # ifndef __NR_signalfd4
54 /* assume kernel headers are too old */
55 # if __i386__
56 # define __NR_signalfd4 327
57 # elif __x86_64__
58 # define __NR_signalfd4 289
59 # elif __powerpc__
60 # define __NR_signalfd4 313
61 # elif __s390x__
62 # define __NR_signalfd4 322
63 # endif
64 #endif
65
66 # ifndef __NR_signalfd
67 /* assume kernel headers are too old */
68 # if __i386__
69 # define __NR_signalfd 321
70 # elif __x86_64__
71 # define __NR_signalfd 282
72 # elif __powerpc__
73 # define __NR_signalfd 305
74 # elif __s390x__
75 # define __NR_signalfd 316
76 # endif
77 #endif
78
79 int signalfd(int fd, const sigset_t *mask, int flags)
80 {
81 int retval;
82
83 retval = syscall (__NR_signalfd4, fd, mask, _NSIG / 8, flags);
84 if (errno == ENOSYS && flags == 0)
85 retval = syscall (__NR_signalfd, fd, mask, _NSIG / 8);
86 return retval;
87 }
88 #endif
89
90 #if !HAVE_DECL_PR_CAPBSET_DROP
91 #define PR_CAPBSET_DROP 24
92 #endif
93
94 #include "error.h"
95 #include "af_unix.h"
96 #include "mainloop.h"
97 #include "commands.h"
98
99 #include <lxc/lxc.h>
100 #include <lxc/log.h>
101
102 lxc_log_define(lxc_start, lxc);
103
104 LXC_TTY_HANDLER(SIGINT);
105 LXC_TTY_HANDLER(SIGQUIT);
106
107 static int setup_sigchld_fd(sigset_t *oldmask)
108 {
109 sigset_t mask;
110 int fd;
111
112 if (sigprocmask(SIG_BLOCK, NULL, &mask)) {
113 SYSERROR("failed to get mask signal");
114 return -1;
115 }
116
117 if (sigaddset(&mask, SIGCHLD) || sigprocmask(SIG_BLOCK, &mask, oldmask)) {
118 SYSERROR("failed to set mask signal");
119 return -1;
120 }
121
122 fd = signalfd(-1, &mask, 0);
123 if (fd < 0) {
124 SYSERROR("failed to create the signal fd");
125 return -1;
126 }
127
128 if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
129 SYSERROR("failed to set sigfd to close-on-exec");
130 close(fd);
131 return -1;
132 }
133
134 DEBUG("sigchild handler set");
135
136 return fd;
137 }
138
139 static int sigchld_handler(int fd, void *data,
140 struct lxc_epoll_descr *descr)
141 {
142 DEBUG("child exited");
143
144 return 1;
145 }
146
147 static int set_state(const char *name, struct lxc_handler *handler, lxc_state_t state)
148 {
149 handler->state = state;
150 lxc_monitor_send_state(name, state);
151 return 0;
152 }
153
154 int lxc_poll(const char *name, struct lxc_handler *handler)
155 {
156 int sigfd = handler->sigfd;
157 int pid = handler->pid;
158 int ret = -1;
159 struct lxc_epoll_descr descr;
160
161 if (lxc_mainloop_open(&descr)) {
162 ERROR("failed to create mainloop");
163 goto out_sigfd;
164 }
165
166 if (lxc_mainloop_add_handler(&descr, sigfd, sigchld_handler, &pid)) {
167 ERROR("failed to add handler for the signal");
168 goto out_mainloop_open;
169 }
170
171 if (lxc_command_mainloop_add(name, &descr, handler))
172 goto out_mainloop_open;
173
174 ret = lxc_mainloop(&descr);
175
176 out:
177 return ret;
178
179 out_mainloop_open:
180 lxc_mainloop_close(&descr);
181 out_sigfd:
182 close(sigfd);
183 goto out;
184 }
185
186 static void remove_init_pid(const char *name, pid_t pid)
187 {
188 char init[MAXPATHLEN];
189
190 snprintf(init, MAXPATHLEN, LXCPATH "/%s/init", name);
191 unlink(init);
192 }
193
194 static int fdname(int fd, char *name, size_t size)
195 {
196 char path[MAXPATHLEN];
197 ssize_t len;
198
199 snprintf(path, MAXPATHLEN, "/proc/self/fd/%d", fd);
200
201 len = readlink(path, name, size);
202 if (len > 0)
203 path[len] = '\0';
204
205 return (len <= 0) ? -1 : 0;
206 }
207
208 static int console_init(char *console, size_t size)
209 {
210 struct stat stat;
211 int i;
212
213 for (i = 0; i < 3; i++) {
214 if (!isatty(i))
215 continue;
216
217 if (ttyname_r(i, console, size)) {
218 SYSERROR("failed to retrieve tty name");
219 return -1;
220 }
221
222 return 0;
223 }
224
225 if (!fstat(0, &stat)) {
226 if (S_ISREG(stat.st_mode) || S_ISCHR(stat.st_mode) ||
227 S_ISFIFO(stat.st_mode) || S_ISLNK(stat.st_mode))
228 return fdname(0, console, size);
229 }
230
231 console[0] = '\0';
232
233 DEBUG("console initialized");
234
235 return 0;
236 }
237
238 struct lxc_handler *lxc_init(const char *name)
239 {
240 struct lxc_handler *handler;
241 char path[MAXPATHLEN];
242
243 handler = malloc(sizeof(*handler));
244 if (!handler)
245 return NULL;
246
247 memset(handler, 0, sizeof(*handler));
248
249 handler->lock = lxc_get_lock(name);
250 if (handler->lock < 0)
251 goto out_free;
252
253 /* Begin the set the state to STARTING*/
254 if (set_state(name, handler, STARTING)) {
255 ERROR("failed to set state '%s'", lxc_state2str(STARTING));
256 goto out_put_lock;
257 }
258
259 if (lxc_conf_init(&handler->lxc_conf)) {
260 ERROR("failed to initialize the configuration");
261 goto out_aborting;
262 }
263
264 snprintf(path, sizeof(path), LXCPATH "/%s/config", name);
265
266 if (!access(path, F_OK)) {
267
268 if (lxc_config_read(path, &handler->lxc_conf)) {
269 ERROR("failed to read the configuration file");
270 goto out_aborting;
271 }
272 }
273
274 if (console_init(handler->tty, sizeof(handler->tty))) {
275 ERROR("failed to initialize the console");
276 goto out_aborting;
277 }
278
279 if (lxc_create_tty(name, &handler->tty_info)) {
280 ERROR("failed to create the ttys");
281 goto out_aborting;
282 }
283
284 /* the signal fd has to be created before forking otherwise
285 * if the child process exits before we setup the signal fd,
286 * the event will be lost and the command will be stuck */
287 handler->sigfd = setup_sigchld_fd(&handler->oldmask);
288 if (handler->sigfd < 0) {
289 ERROR("failed to set sigchild fd handler");
290 goto out_delete_tty;
291 }
292
293 /* Avoid signals from terminal */
294 LXC_TTY_ADD_HANDLER(SIGINT);
295 LXC_TTY_ADD_HANDLER(SIGQUIT);
296
297 out:
298 if (handler)
299 INFO("'%s' is initialized", name);
300
301 return handler;
302
303 out_delete_tty:
304 lxc_delete_tty(&handler->tty_info);
305 out_aborting:
306 set_state(name, handler, ABORTING);
307 out_put_lock:
308 lxc_put_lock(handler->lock);
309 out_free:
310 free(handler);
311 handler = NULL;
312 goto out;
313 }
314
315 void lxc_fini(const char *name, struct lxc_handler *handler)
316 {
317 /* The STOPPING state is there for future cleanup code
318 * which can take awhile
319 */
320 set_state(name, handler, STOPPING);
321 set_state(name, handler, STOPPED);
322 lxc_unlink_nsgroup(name);
323
324 if (handler) {
325 remove_init_pid(name, handler->pid);
326 lxc_delete_tty(&handler->tty_info);
327 lxc_put_lock(handler->lock);
328 free(handler);
329 }
330
331 LXC_TTY_DEL_HANDLER(SIGQUIT);
332 LXC_TTY_DEL_HANDLER(SIGINT);
333 }
334
335 void lxc_abort(const char *name, struct lxc_handler *handler)
336 {
337 set_state(name, handler, ABORTING);
338 kill(handler->pid, SIGKILL);
339 }
340
341 struct start_arg {
342 const char *name;
343 char *const *argv;
344 struct lxc_handler *handler;
345 int *sv;
346 };
347
348 static int do_start(void *arg)
349 {
350 struct start_arg *start_arg = arg;
351 struct lxc_handler *handler = start_arg->handler;
352 const char *name = start_arg->name;
353 char *const *argv = start_arg->argv;
354 int *sv = start_arg->sv;
355 int err = -1, sync;
356
357 if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) {
358 SYSERROR("failed to set sigprocmask");
359 goto out_child;
360 }
361
362 close(sv[1]);
363
364 /* Be sure we don't inherit this after the exec */
365 fcntl(sv[0], F_SETFD, FD_CLOEXEC);
366
367 /* Tell our father he can begin to configure the container */
368 if (write(sv[0], &sync, sizeof(sync)) < 0) {
369 SYSERROR("failed to write socket");
370 goto out_child;
371 }
372
373 /* Wait for the father to finish the configuration */
374 if (read(sv[0], &sync, sizeof(sync)) < 0) {
375 SYSERROR("failed to read socket");
376 goto out_child;
377 }
378
379 /* Setup the container, ip, names, utsname, ... */
380 if (lxc_setup(name, handler)) {
381 ERROR("failed to setup the container");
382 goto out_warn_father;
383 }
384
385 if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) {
386 SYSERROR("failed to remove CAP_SYS_BOOT capability");
387 goto out_child;
388 }
389
390 if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
391 SYSERROR("failed to set pdeath signal");
392 goto out_child;
393 }
394
395 NOTICE("exec'ing '%s'", argv[0]);
396
397 execvp(argv[0], argv);
398 SYSERROR("failed to exec %s", argv[0]);
399
400 out_warn_father:
401 /* If the exec fails, tell that to our father */
402 if (write(sv[0], &err, sizeof(err)) < 0)
403 SYSERROR("failed to write the socket");
404 out_child:
405 return -1;
406 }
407
408 int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[])
409 {
410 int sv[2];
411 int clone_flags;
412 int err = -1, sync;
413
414 struct start_arg start_arg = {
415 .name = name,
416 .argv = argv,
417 .handler = handler,
418 .sv = sv,
419 };
420
421 /* Synchro socketpair */
422 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
423 SYSERROR("failed to create communication socketpair");
424 goto out;
425 }
426
427 clone_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
428 if (conf_has_network(name))
429 clone_flags |= CLONE_NEWNET;
430
431 /* Create a process in a new set of namespaces */
432 handler->pid = lxc_clone(do_start, &start_arg, clone_flags);
433 if (handler->pid < 0) {
434 SYSERROR("failed to fork into a new namespace");
435 goto out_close;
436 }
437
438 close(sv[0]);
439
440 /* Wait for the child to be ready */
441 if (read(sv[1], &sync, sizeof(sync)) < 0) {
442 SYSERROR("failed to read the socket");
443 goto out_abort;
444 }
445
446 if (lxc_rename_nsgroup(name, handler))
447 goto out_abort;
448
449 /* Create the network configuration */
450 if (clone_flags & CLONE_NEWNET &&
451 conf_create_network(name, handler->pid)) {
452 ERROR("failed to create the configured network");
453 goto out_abort;
454 }
455
456 /* Tell the child to continue its initialization */
457 if (write(sv[1], &sync, sizeof(sync)) < 0) {
458 SYSERROR("failed to write the socket");
459 goto out_abort;
460 }
461
462 /* Wait for the child to exec or returning an error */
463 if (read(sv[1], &sync, sizeof(sync)) < 0) {
464 ERROR("failed to read the socket");
465 goto out_abort;
466 }
467
468 if (set_state(name, handler, RUNNING)) {
469 ERROR("failed to set state to %s",
470 lxc_state2str(RUNNING));
471 goto out_abort;
472 }
473
474 err = 0;
475
476 NOTICE("'%s' started with pid '%d'", argv[0], handler->pid);
477
478 out_close:
479 close(sv[0]);
480 close(sv[1]);
481 out:
482 return err;
483
484 out_abort:
485 lxc_abort(name, handler);
486 goto out_close;
487 }
488
489 int lxc_start(const char *name, char *const argv[])
490 {
491 struct lxc_handler *handler;
492 int err = -1;
493 int status;
494
495 handler = lxc_init(name);
496 if (!handler) {
497 ERROR("failed to initialize the container");
498 return -1;
499 }
500
501 err = lxc_spawn(name, handler, argv);
502 if (err) {
503 ERROR("failed to spawn '%s'", argv[0]);
504 goto out;
505 }
506
507 err = lxc_close_all_inherited_fd();
508 if (err) {
509 ERROR("unable to close inherited fds");
510 goto out_abort;
511 }
512
513 err = lxc_poll(name, handler);
514 if (err) {
515 ERROR("mainloop exited with an error");
516 goto out_abort;
517 }
518
519 while (waitpid(handler->pid, &status, 0) < 0 && errno == EINTR)
520 continue;
521
522 err = lxc_error_set_and_log(handler->pid, status);
523 out:
524 lxc_fini(name, handler);
525 return err;
526
527 out_abort:
528 lxc_abort(name, handler);
529 goto out;
530 }