]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/start.c
Remove the usage of a lock file
[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 /* Begin the set the state to STARTING*/
250 if (set_state(name, handler, STARTING)) {
251 ERROR("failed to set state '%s'", lxc_state2str(STARTING));
252 goto out_free;
253 }
254
255 if (lxc_conf_init(&handler->conf)) {
256 ERROR("failed to initialize the configuration");
257 goto out_aborting;
258 }
259
260 snprintf(path, sizeof(path), LXCPATH "/%s/config", name);
261
262 if (!access(path, F_OK) && lxc_config_read(path, &handler->conf)) {
263 ERROR("failed to read the configuration file");
264 goto out_aborting;
265 }
266
267 if (console_init(handler->conf.console,
268 sizeof(handler->conf.console))) {
269 ERROR("failed to initialize the console");
270 goto out_aborting;
271 }
272
273 if (lxc_create_tty(name, &handler->conf)) {
274 ERROR("failed to create the ttys");
275 goto out_aborting;
276 }
277
278 /* the signal fd has to be created before forking otherwise
279 * if the child process exits before we setup the signal fd,
280 * the event will be lost and the command will be stuck */
281 handler->sigfd = setup_sigchld_fd(&handler->oldmask);
282 if (handler->sigfd < 0) {
283 ERROR("failed to set sigchild fd handler");
284 goto out_delete_tty;
285 }
286
287 /* Avoid signals from terminal */
288 LXC_TTY_ADD_HANDLER(SIGINT);
289 LXC_TTY_ADD_HANDLER(SIGQUIT);
290
291 out:
292 if (handler)
293 INFO("'%s' is initialized", name);
294
295 return handler;
296
297 out_delete_tty:
298 lxc_delete_tty(&handler->conf.tty_info);
299 out_aborting:
300 set_state(name, handler, ABORTING);
301 out_free:
302 free(handler);
303 handler = NULL;
304 goto out;
305 }
306
307 void lxc_fini(const char *name, struct lxc_handler *handler)
308 {
309 /* The STOPPING state is there for future cleanup code
310 * which can take awhile
311 */
312 set_state(name, handler, STOPPING);
313 set_state(name, handler, STOPPED);
314 lxc_unlink_nsgroup(name);
315
316 if (handler) {
317 remove_init_pid(name, handler->pid);
318 lxc_delete_tty(&handler->conf.tty_info);
319 free(handler);
320 }
321
322 LXC_TTY_DEL_HANDLER(SIGQUIT);
323 LXC_TTY_DEL_HANDLER(SIGINT);
324 }
325
326 void lxc_abort(const char *name, struct lxc_handler *handler)
327 {
328 set_state(name, handler, ABORTING);
329 kill(handler->pid, SIGKILL);
330 }
331
332 struct start_arg {
333 const char *name;
334 char *const *argv;
335 struct lxc_handler *handler;
336 int *sv;
337 };
338
339 static int do_start(void *arg)
340 {
341 struct start_arg *start_arg = arg;
342 struct lxc_handler *handler = start_arg->handler;
343 const char *name = start_arg->name;
344 char *const *argv = start_arg->argv;
345 int *sv = start_arg->sv;
346 int err = -1, sync;
347
348 if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) {
349 SYSERROR("failed to set sigprocmask");
350 goto out_child;
351 }
352
353 close(sv[1]);
354
355 /* Be sure we don't inherit this after the exec */
356 fcntl(sv[0], F_SETFD, FD_CLOEXEC);
357
358 /* Tell our father he can begin to configure the container */
359 if (write(sv[0], &sync, sizeof(sync)) < 0) {
360 SYSERROR("failed to write socket");
361 goto out_child;
362 }
363
364 /* Wait for the father to finish the configuration */
365 if (read(sv[0], &sync, sizeof(sync)) < 0) {
366 SYSERROR("failed to read socket");
367 goto out_child;
368 }
369
370 /* Setup the container, ip, names, utsname, ... */
371 if (lxc_setup(name, &handler->conf)) {
372 ERROR("failed to setup the container");
373 goto out_warn_father;
374 }
375
376 if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) {
377 SYSERROR("failed to remove CAP_SYS_BOOT capability");
378 goto out_child;
379 }
380
381 if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
382 SYSERROR("failed to set pdeath signal");
383 goto out_child;
384 }
385
386 NOTICE("exec'ing '%s'", argv[0]);
387
388 execvp(argv[0], argv);
389 SYSERROR("failed to exec %s", argv[0]);
390
391 out_warn_father:
392 /* If the exec fails, tell that to our father */
393 if (write(sv[0], &err, sizeof(err)) < 0)
394 SYSERROR("failed to write the socket");
395 out_child:
396 return -1;
397 }
398
399 int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[])
400 {
401 int sv[2];
402 int clone_flags;
403 int err = -1, sync;
404
405 struct start_arg start_arg = {
406 .name = name,
407 .argv = argv,
408 .handler = handler,
409 .sv = sv,
410 };
411
412 /* Synchro socketpair */
413 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
414 SYSERROR("failed to create communication socketpair");
415 goto out;
416 }
417
418 clone_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
419 if (!lxc_list_empty(&handler->conf.network)) {
420
421 clone_flags |= CLONE_NEWNET;
422
423 /* that should be done before the clone because we will
424 * fill the netdev index and use them in the child
425 */
426 if (lxc_create_network(&handler->conf.network)) {
427 ERROR("failed to create the network");
428 goto out_close;
429 }
430 }
431
432 /* Create a process in a new set of namespaces */
433 handler->pid = lxc_clone(do_start, &start_arg, clone_flags);
434 if (handler->pid < 0) {
435 SYSERROR("failed to fork into a new namespace");
436 goto out_close;
437 }
438
439 close(sv[0]);
440
441 /* Wait for the child to be ready */
442 if (read(sv[1], &sync, sizeof(sync)) < 0) {
443 SYSERROR("failed to read the socket");
444 goto out_abort;
445 }
446
447 if (lxc_rename_nsgroup(name, handler))
448 goto out_abort;
449
450 /* Create the network configuration */
451 if (clone_flags & CLONE_NEWNET) {
452 if (lxc_assign_network(&handler->conf.network, handler->pid)) {
453 ERROR("failed to create the configured network");
454 goto out_abort;
455 }
456 }
457
458 /* Tell the child to continue its initialization */
459 if (write(sv[1], &sync, sizeof(sync)) < 0) {
460 SYSERROR("failed to write the socket");
461 goto out_abort;
462 }
463
464 /* Wait for the child to exec or returning an error */
465 if (read(sv[1], &sync, sizeof(sync)) < 0) {
466 ERROR("failed to read the socket");
467 goto out_abort;
468 }
469
470 if (set_state(name, handler, RUNNING)) {
471 ERROR("failed to set state to %s",
472 lxc_state2str(RUNNING));
473 goto out_abort;
474 }
475
476 err = 0;
477
478 NOTICE("'%s' started with pid '%d'", argv[0], handler->pid);
479
480 out_close:
481 close(sv[0]);
482 close(sv[1]);
483 out:
484 return err;
485
486 out_abort:
487 lxc_abort(name, handler);
488 goto out_close;
489 }
490
491 int lxc_start(const char *name, char *const argv[])
492 {
493 struct lxc_handler *handler;
494 int err = -1;
495 int status;
496
497 handler = lxc_init(name);
498 if (!handler) {
499 ERROR("failed to initialize the container");
500 return -1;
501 }
502
503 err = lxc_spawn(name, handler, argv);
504 if (err) {
505 ERROR("failed to spawn '%s'", argv[0]);
506 goto out;
507 }
508
509 err = lxc_close_all_inherited_fd();
510 if (err) {
511 ERROR("unable to close inherited fds");
512 goto out_abort;
513 }
514
515 err = lxc_poll(name, handler);
516 if (err) {
517 ERROR("mainloop exited with an error");
518 goto out_abort;
519 }
520
521 while (waitpid(handler->pid, &status, 0) < 0 && errno == EINTR)
522 continue;
523
524 err = lxc_error_set_and_log(handler->pid, status);
525 out:
526 lxc_fini(name, handler);
527 return err;
528
529 out_abort:
530 lxc_abort(name, handler);
531 goto out;
532 }