]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/lxc_init.c
use a default per-container logfile
[mirror_lxc.git] / src / lxc / lxc_init.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 <stdio.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 #include <signal.h>
29 #include <libgen.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #define _GNU_SOURCE
34 #include <getopt.h>
35
36 #include "log.h"
37 #include "caps.h"
38 #include "error.h"
39 #include "utils.h"
40
41 lxc_log_define(lxc_init, lxc);
42
43 static int quiet;
44
45 static struct option options[] = {
46 { "quiet", no_argument, &quiet, 1 },
47 { 0, 0, 0, 0 },
48 };
49
50 static int was_interrupted = 0;
51
52 int main(int argc, char *argv[])
53 {
54
55 void interrupt_handler(int sig)
56 {
57 if (!was_interrupted)
58 was_interrupted = sig;
59 }
60
61 pid_t pid;
62 int nbargs = 0;
63 int err = -1;
64 char **aargv;
65 sigset_t mask, omask;
66 int i, shutdown = 0;
67
68 while (1) {
69 int ret = getopt_long_only(argc, argv, "", options, NULL);
70 if (ret == -1) {
71 break;
72 }
73 if (ret == '?')
74 exit(err);
75
76 nbargs++;
77 }
78
79 if (lxc_caps_init())
80 exit(err);
81
82 if (lxc_log_init(NULL, "none", 0, basename(argv[0]), quiet))
83 exit(err);
84
85 if (!argv[optind]) {
86 ERROR("missing command to launch");
87 exit(err);
88 }
89
90 aargv = &argv[optind];
91 argc -= nbargs;
92
93 /*
94 * mask all the signals so we are safe to install a
95 * signal handler and to fork
96 */
97 sigfillset(&mask);
98 sigdelset(&mask, SIGILL);
99 sigdelset(&mask, SIGSEGV);
100 sigdelset(&mask, SIGBUS);
101 sigprocmask(SIG_SETMASK, &mask, &omask);
102
103 for (i = 1; i < NSIG; i++) {
104 struct sigaction act;
105
106 /* Exclude some signals: ILL, SEGV and BUS are likely to
107 * reveal a bug and we want a core. STOP and KILL cannot be
108 * handled anyway: they're here for documentation.
109 */
110 if (i == SIGILL ||
111 i == SIGSEGV ||
112 i == SIGBUS ||
113 i == SIGSTOP ||
114 i == SIGKILL)
115 continue;
116
117 sigfillset(&act.sa_mask);
118 sigdelset(&act.sa_mask, SIGILL);
119 sigdelset(&act.sa_mask, SIGSEGV);
120 sigdelset(&act.sa_mask, SIGBUS);
121 sigdelset(&act.sa_mask, SIGSTOP);
122 sigdelset(&act.sa_mask, SIGKILL);
123 act.sa_flags = 0;
124 act.sa_handler = interrupt_handler;
125 sigaction(i, &act, NULL);
126 }
127
128 if (lxc_setup_fs())
129 exit(err);
130
131 if (lxc_caps_reset())
132 exit(err);
133
134 pid = fork();
135
136 if (pid < 0)
137 exit(err);
138
139 if (!pid) {
140
141 /* restore default signal handlers */
142 for (i = 1; i < NSIG; i++)
143 signal(i, SIG_DFL);
144
145 sigprocmask(SIG_SETMASK, &omask, NULL);
146
147 NOTICE("about to exec '%s'", aargv[0]);
148
149 execvp(aargv[0], aargv);
150 ERROR("failed to exec: '%s' : %m", aargv[0]);
151 exit(err);
152 }
153
154 /* let's process the signals now */
155 sigdelset(&omask, SIGALRM);
156 sigprocmask(SIG_SETMASK, &omask, NULL);
157
158 /* no need of other inherited fds but stderr */
159 close(fileno(stdin));
160 close(fileno(stdout));
161
162 err = 0;
163 for (;;) {
164 int status;
165 int orphan = 0;
166 pid_t waited_pid;
167
168 switch (was_interrupted) {
169
170 case 0:
171 break;
172
173 case SIGTERM:
174 if (!shutdown) {
175 shutdown = 1;
176 kill(-1, SIGTERM);
177 alarm(1);
178 }
179 break;
180
181 case SIGALRM:
182 kill(-1, SIGKILL);
183 break;
184
185 default:
186 kill(pid, was_interrupted);
187 break;
188 }
189
190 was_interrupted = 0;
191 waited_pid = wait(&status);
192 if (waited_pid < 0) {
193 if (errno == ECHILD)
194 goto out;
195 if (errno == EINTR)
196 continue;
197
198 ERROR("failed to wait child : %s",
199 strerror(errno));
200 goto out;
201 }
202
203 /* reset timer each time a process exited */
204 if (shutdown)
205 alarm(1);
206
207 /*
208 * keep the exit code of started application
209 * (not wrapped pid) and continue to wait for
210 * the end of the orphan group.
211 */
212 if ((waited_pid != pid) || (orphan ==1))
213 continue;
214 orphan = 1;
215 err = lxc_error_set_and_log(waited_pid, status);
216 }
217 out:
218 return err;
219 }