]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/tools/lxc_init.c
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #include <sys/types.h>
39 #include "initutils.h"
40 #include "lxccontainer.h"
42 lxc_log_define(lxc_init
, lxc
);
46 static const struct option options
[] = {
47 { "name", required_argument
, NULL
, 'n' },
48 { "logpriority", required_argument
, NULL
, 'l' },
49 { "quiet", no_argument
, NULL
, 'q' },
50 { "lxcpath", required_argument
, NULL
, 'P' },
54 static sig_atomic_t was_interrupted
= 0;
56 static void interrupt_handler(int sig
)
59 was_interrupted
= sig
;
62 static void usage(void) {
63 fprintf(stderr
, "Usage: lxc-init [OPTION]...\n\n"
65 " -n, --name=NAME NAME of the container\n"
66 " -l, --logpriority=LEVEL Set log priority to LEVEL\n"
67 " -q, --quiet Don't produce any output\n"
68 " -P, --lxcpath=PATH Use specified container path\n"
69 " -?, --help Give this help list\n"
71 "Mandatory or optional arguments to long options are also mandatory or optional\n"
72 "for any corresponding short options.\n"
74 "NOTE: lxc-init is intended for use by lxc internally\n"
75 " and does not need to be run by hand\n\n");
78 int main(int argc
, char *argv
[])
84 int i
, have_status
= 0, shutdown
= 0;
86 char *lxcpath
= NULL
, *name
= NULL
, *logpriority
= NULL
;
89 while ((opt
= getopt_long(argc
, argv
, "n:l:qP:", options
, NULL
)) != -1) {
110 log
.file
= name
? NULL
: "none";
111 log
.level
= logpriority
;
112 log
.prefix
= basename(argv
[0]);
114 log
.lxcpath
= lxcpath
;
116 err
= lxc_log_init(&log
);
119 lxc_log_options_no_override();
122 ERROR("missing command to launch");
126 aargv
= &argv
[optind
];
129 * mask all the signals so we are safe to install a
130 * signal handler and to fork
132 if (sigfillset(&mask
) ||
133 sigdelset(&mask
, SIGILL
) ||
134 sigdelset(&mask
, SIGSEGV
) ||
135 sigdelset(&mask
, SIGBUS
) ||
136 sigprocmask(SIG_SETMASK
, &mask
, &omask
)) {
137 SYSERROR("failed to set signal mask");
141 for (i
= 1; i
< NSIG
; i
++) {
142 struct sigaction act
;
144 /* Exclude some signals: ILL, SEGV and BUS are likely to
145 * reveal a bug and we want a core. STOP and KILL cannot be
146 * handled anyway: they're here for documentation.
156 if (sigfillset(&act
.sa_mask
) ||
157 sigdelset(&act
.sa_mask
, SIGILL
) ||
158 sigdelset(&act
.sa_mask
, SIGSEGV
) ||
159 sigdelset(&act
.sa_mask
, SIGBUS
) ||
160 sigdelset(&act
.sa_mask
, SIGSTOP
) ||
161 sigdelset(&act
.sa_mask
, SIGKILL
)) {
162 ERROR("failed to set signal");
167 act
.sa_handler
= interrupt_handler
;
168 if (sigaction(i
, &act
, NULL
) && errno
!= EINVAL
) {
169 SYSERROR("failed to sigaction");
183 /* restore default signal handlers */
184 for (i
= 1; i
< NSIG
; i
++)
187 if (sigprocmask(SIG_SETMASK
, &omask
, NULL
)) {
188 SYSERROR("failed to set signal mask");
192 NOTICE("about to exec '%s'", aargv
[0]);
194 execvp(aargv
[0], aargv
);
195 ERROR("failed to exec: '%s' : %m", aargv
[0]);
199 /* let's process the signals now */
200 if (sigdelset(&omask
, SIGALRM
) ||
201 sigprocmask(SIG_SETMASK
, &omask
, NULL
)) {
202 SYSERROR("failed to set signal mask");
206 /* no need of other inherited fds but stderr */
207 close(fileno(stdin
));
208 close(fileno(stdout
));
215 switch (was_interrupted
) {
234 kill(pid
, was_interrupted
);
239 waited_pid
= wait(&status
);
240 if (waited_pid
< 0) {
246 ERROR("failed to wait child : %s",
251 /* reset timer each time a process exited */
256 * keep the exit code of started application
257 * (not wrapped pid) and continue to wait for
258 * the end of the orphan group.
260 if (waited_pid
== pid
&& !have_status
) {
261 err
= lxc_error_set_and_log(waited_pid
, status
);