]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/lxc_init.c
drop capabilities in lxc-init (V2)
[mirror_lxc.git] / src / lxc / lxc_init.c
CommitLineData
05f05512 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>
b0a33c1e 28#include <signal.h>
8559e703 29#include <libgen.h>
0e322d22 30#include <sys/stat.h>
05f05512 31#include <sys/types.h>
32#include <sys/wait.h>
0af683cf 33#include <sys/capability.h>
05f05512 34#define _GNU_SOURCE
35#include <getopt.h>
00b3c2e2 36
00b3c2e2 37#include <lxc/log.h>
00b3c2e2 38#include <lxc/error.h>
698287d8 39#include "utils.h"
8559e703
MN
40
41lxc_log_define(lxc_init, lxc);
05f05512 42
8559e703 43static int quiet;
05f05512 44
45static struct option options[] = {
8559e703
MN
46 { "quiet", no_argument, &quiet, 1 },
47 { 0, 0, 0, 0 },
05f05512 48};
49
e4b3fe58 50static int was_interrupted = 0;
51
0af683cf 52static int cap_reset(void)
53{
54 cap_t cap = cap_init();
55 int ret = 0;
56
57 if (!cap) {
58 ERROR("cap_init() failed : %m");
59 return -1;
60 }
61
62 if (cap_set_proc(cap)) {
63 ERROR("cap_set_proc() failed : %m");
64 ret = -1;
65 }
66
67 cap_free(cap);
68 return ret;
69}
70
05f05512 71int main(int argc, char *argv[])
72{
e4b3fe58 73
74 void interrupt_handler(int sig)
75 {
76 if (!was_interrupted)
77 was_interrupted = sig;
78 }
79
05f05512 80 pid_t pid;
05f05512 81 int nbargs = 0;
b0ed5e64 82 int err = -1;
05f05512 83 char **aargv;
e4b3fe58 84 sigset_t mask, omask;
85 int i;
05f05512 86
87 while (1) {
88 int ret = getopt_long_only(argc, argv, "", options, NULL);
8559e703 89 if (ret == -1) {
05f05512 90 break;
8559e703 91 }
341553f7 92 if (ret == '?')
b0ed5e64 93 exit(err);
341553f7 94
05f05512 95 nbargs++;
96 }
97
341553f7 98 if (lxc_log_init(NULL, 0, basename(argv[0]), quiet))
b0ed5e64 99 exit(err);
8559e703 100
05f05512 101 if (!argv[optind]) {
8559e703 102 ERROR("missing command to launch");
b0ed5e64 103 exit(err);
05f05512 104 }
105
106 aargv = &argv[optind];
107 argc -= nbargs;
108
e4b3fe58 109 sigfillset(&mask);
110 sigprocmask(SIG_SETMASK, &mask, &omask);
111
112 for (i = 1; i < NSIG; i++) {
113 struct sigaction act;
114
115 sigfillset(&act.sa_mask);
116 act.sa_flags = 0;
117 act.sa_handler = interrupt_handler;
118 sigaction(i, &act, NULL);
119 }
120
0af683cf 121 if (lxc_setup_fs())
122 exit(err);
123
124 if (cap_reset())
125 exit(err);
126
05f05512 127 pid = fork();
128
129 if (pid < 0)
b0ed5e64 130 exit(err);
05f05512 131
132 if (!pid) {
133
e4b3fe58 134 for (i = 1; i < NSIG; i++)
135 signal(i, SIG_DFL);
136 sigprocmask(SIG_SETMASK, &omask, NULL);
137
72439b9f
MN
138 NOTICE("about to exec '%s'", aargv[0]);
139
05f05512 140 execvp(aargv[0], aargv);
0af683cf 141 ERROR("failed to exec: '%s' : %m", aargv[0]);
b0ed5e64 142 exit(err);
05f05512 143 }
144
e4b3fe58 145 sigprocmask(SIG_SETMASK, &omask, NULL);
146
affaa6da
MN
147 /* no need of other inherited fds but stderr */
148 close(fileno(stdin));
149 close(fileno(stdout));
150
37c3dfc9 151 err = 0;
05f05512 152 for (;;) {
153 int status;
37c3dfc9 154 int orphan = 0;
b0ed5e64
MN
155 pid_t waited_pid;
156
e4b3fe58 157 if (was_interrupted) {
158 kill(pid, was_interrupted);
159 was_interrupted = 0;
160 }
161
b0ed5e64
MN
162 waited_pid = wait(&status);
163 if (waited_pid < 0) {
05f05512 164 if (errno == ECHILD)
b0ed5e64 165 goto out;
05f05512 166 if (errno == EINTR)
167 continue;
b0ed5e64
MN
168 ERROR("failed to wait child : %s", strerror(errno));
169 goto out;
05f05512 170 }
37c3dfc9
MN
171
172 /*
173 * keep the exit code of started application (not wrapped pid)
174 * and continue to wait for the end of the orphan group.
175 */
176 if ((waited_pid != pid) || (orphan ==1))
177 continue;
178 orphan = 1;
179 err = lxc_error_set_and_log(waited_pid, status);
05f05512 180 }
b0ed5e64
MN
181out:
182 return err;
05f05512 183}
6e4bb2e0 184