]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/conf.c
Fix check against LXCROOTFSMOUNT to use strcmp
[mirror_lxc.git] / src / lxc / conf.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 #define _GNU_SOURCE
24 #include <stdio.h>
25 #undef _GNU_SOURCE
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <dirent.h>
31 #include <mntent.h>
32 #include <unistd.h>
33 #include <sys/wait.h>
34 #include <pty.h>
35
36 #include <linux/loop.h>
37
38 #include <sys/types.h>
39 #include <sys/utsname.h>
40 #include <sys/param.h>
41 #include <sys/stat.h>
42 #include <sys/socket.h>
43 #include <sys/mount.h>
44 #include <sys/mman.h>
45 #include <sys/prctl.h>
46 #include <sys/capability.h>
47 #include <sys/personality.h>
48
49 #include <arpa/inet.h>
50 #include <fcntl.h>
51 #include <netinet/in.h>
52 #include <net/if.h>
53 #include <libgen.h>
54
55 #include "network.h"
56 #include "error.h"
57 #include "parse.h"
58 #include "config.h"
59 #include "utils.h"
60 #include "conf.h"
61 #include "log.h"
62 #include "lxc.h" /* for lxc_cgroup_set() */
63 #include "caps.h" /* for lxc_caps_last_cap() */
64
65 #if HAVE_APPARMOR
66 #include <apparmor.h>
67 #endif
68
69 lxc_log_define(lxc_conf, lxc);
70
71 #define MAXHWLEN 18
72 #define MAXINDEXLEN 20
73 #define MAXMTULEN 16
74 #define MAXLINELEN 128
75
76 #ifndef MS_DIRSYNC
77 #define MS_DIRSYNC 128
78 #endif
79
80 #ifndef MS_REC
81 #define MS_REC 16384
82 #endif
83
84 #ifndef MNT_DETACH
85 #define MNT_DETACH 2
86 #endif
87
88 #ifndef MS_RELATIME
89 #define MS_RELATIME (1 << 21)
90 #endif
91
92 #ifndef MS_STRICTATIME
93 #define MS_STRICTATIME (1 << 24)
94 #endif
95
96 #ifndef CAP_SETFCAP
97 #define CAP_SETFCAP 31
98 #endif
99
100 #ifndef CAP_MAC_OVERRIDE
101 #define CAP_MAC_OVERRIDE 32
102 #endif
103
104 #ifndef CAP_MAC_ADMIN
105 #define CAP_MAC_ADMIN 33
106 #endif
107
108 #ifndef PR_CAPBSET_DROP
109 #define PR_CAPBSET_DROP 24
110 #endif
111
112 char *lxchook_names[NUM_LXC_HOOKS] = {
113 "pre-start", "pre-mount", "mount", "start", "post-stop" };
114
115 extern int pivot_root(const char * new_root, const char * put_old);
116
117 typedef int (*instanciate_cb)(struct lxc_handler *, struct lxc_netdev *);
118
119 struct mount_opt {
120 char *name;
121 int clear;
122 int flag;
123 };
124
125 struct caps_opt {
126 char *name;
127 int value;
128 };
129
130 static int instanciate_veth(struct lxc_handler *, struct lxc_netdev *);
131 static int instanciate_macvlan(struct lxc_handler *, struct lxc_netdev *);
132 static int instanciate_vlan(struct lxc_handler *, struct lxc_netdev *);
133 static int instanciate_phys(struct lxc_handler *, struct lxc_netdev *);
134 static int instanciate_empty(struct lxc_handler *, struct lxc_netdev *);
135
136 static instanciate_cb netdev_conf[LXC_NET_MAXCONFTYPE + 1] = {
137 [LXC_NET_VETH] = instanciate_veth,
138 [LXC_NET_MACVLAN] = instanciate_macvlan,
139 [LXC_NET_VLAN] = instanciate_vlan,
140 [LXC_NET_PHYS] = instanciate_phys,
141 [LXC_NET_EMPTY] = instanciate_empty,
142 };
143
144 static int shutdown_veth(struct lxc_handler *, struct lxc_netdev *);
145 static int shutdown_macvlan(struct lxc_handler *, struct lxc_netdev *);
146 static int shutdown_vlan(struct lxc_handler *, struct lxc_netdev *);
147 static int shutdown_phys(struct lxc_handler *, struct lxc_netdev *);
148 static int shutdown_empty(struct lxc_handler *, struct lxc_netdev *);
149
150 static instanciate_cb netdev_deconf[LXC_NET_MAXCONFTYPE + 1] = {
151 [LXC_NET_VETH] = shutdown_veth,
152 [LXC_NET_MACVLAN] = shutdown_macvlan,
153 [LXC_NET_VLAN] = shutdown_vlan,
154 [LXC_NET_PHYS] = shutdown_phys,
155 [LXC_NET_EMPTY] = shutdown_empty,
156 };
157
158 static struct mount_opt mount_opt[] = {
159 { "defaults", 0, 0 },
160 { "ro", 0, MS_RDONLY },
161 { "rw", 1, MS_RDONLY },
162 { "suid", 1, MS_NOSUID },
163 { "nosuid", 0, MS_NOSUID },
164 { "dev", 1, MS_NODEV },
165 { "nodev", 0, MS_NODEV },
166 { "exec", 1, MS_NOEXEC },
167 { "noexec", 0, MS_NOEXEC },
168 { "sync", 0, MS_SYNCHRONOUS },
169 { "async", 1, MS_SYNCHRONOUS },
170 { "dirsync", 0, MS_DIRSYNC },
171 { "remount", 0, MS_REMOUNT },
172 { "mand", 0, MS_MANDLOCK },
173 { "nomand", 1, MS_MANDLOCK },
174 { "atime", 1, MS_NOATIME },
175 { "noatime", 0, MS_NOATIME },
176 { "diratime", 1, MS_NODIRATIME },
177 { "nodiratime", 0, MS_NODIRATIME },
178 { "bind", 0, MS_BIND },
179 { "rbind", 0, MS_BIND|MS_REC },
180 { "relatime", 0, MS_RELATIME },
181 { "norelatime", 1, MS_RELATIME },
182 { "strictatime", 0, MS_STRICTATIME },
183 { "nostrictatime", 1, MS_STRICTATIME },
184 { NULL, 0, 0 },
185 };
186
187 static struct caps_opt caps_opt[] = {
188 { "chown", CAP_CHOWN },
189 { "dac_override", CAP_DAC_OVERRIDE },
190 { "dac_read_search", CAP_DAC_READ_SEARCH },
191 { "fowner", CAP_FOWNER },
192 { "fsetid", CAP_FSETID },
193 { "kill", CAP_KILL },
194 { "setgid", CAP_SETGID },
195 { "setuid", CAP_SETUID },
196 { "setpcap", CAP_SETPCAP },
197 { "linux_immutable", CAP_LINUX_IMMUTABLE },
198 { "net_bind_service", CAP_NET_BIND_SERVICE },
199 { "net_broadcast", CAP_NET_BROADCAST },
200 { "net_admin", CAP_NET_ADMIN },
201 { "net_raw", CAP_NET_RAW },
202 { "ipc_lock", CAP_IPC_LOCK },
203 { "ipc_owner", CAP_IPC_OWNER },
204 { "sys_module", CAP_SYS_MODULE },
205 { "sys_rawio", CAP_SYS_RAWIO },
206 { "sys_chroot", CAP_SYS_CHROOT },
207 { "sys_ptrace", CAP_SYS_PTRACE },
208 { "sys_pacct", CAP_SYS_PACCT },
209 { "sys_admin", CAP_SYS_ADMIN },
210 { "sys_boot", CAP_SYS_BOOT },
211 { "sys_nice", CAP_SYS_NICE },
212 { "sys_resource", CAP_SYS_RESOURCE },
213 { "sys_time", CAP_SYS_TIME },
214 { "sys_tty_config", CAP_SYS_TTY_CONFIG },
215 { "mknod", CAP_MKNOD },
216 { "lease", CAP_LEASE },
217 #ifdef CAP_AUDIT_WRITE
218 { "audit_write", CAP_AUDIT_WRITE },
219 #endif
220 #ifdef CAP_AUDIT_CONTROL
221 { "audit_control", CAP_AUDIT_CONTROL },
222 #endif
223 { "setfcap", CAP_SETFCAP },
224 { "mac_override", CAP_MAC_OVERRIDE },
225 { "mac_admin", CAP_MAC_ADMIN },
226 #ifdef CAP_SYSLOG
227 { "syslog", CAP_SYSLOG },
228 #endif
229 #ifdef CAP_WAKE_ALARM
230 { "wake_alarm", CAP_WAKE_ALARM },
231 #endif
232 };
233
234 static int run_script(const char *name, const char *section,
235 const char *script, ...)
236 {
237 int ret;
238 FILE *f;
239 char *buffer, *p, *output;
240 size_t size = 0;
241 va_list ap;
242
243 INFO("Executing script '%s' for container '%s', config section '%s'",
244 script, name, section);
245
246 va_start(ap, script);
247 while ((p = va_arg(ap, char *)))
248 size += strlen(p) + 1;
249 va_end(ap);
250
251 size += strlen(script);
252 size += strlen(name);
253 size += strlen(section);
254 size += 3;
255
256 if (size > INT_MAX)
257 return -1;
258
259 buffer = alloca(size);
260 if (!buffer) {
261 ERROR("failed to allocate memory");
262 return -1;
263 }
264
265 ret = snprintf(buffer, size, "%s %s %s", script, name, section);
266 if (ret < 0 || ret >= size) {
267 ERROR("Script name too long");
268 free(buffer);
269 return -1;
270 }
271
272 va_start(ap, script);
273 while ((p = va_arg(ap, char *))) {
274 int len = size-ret;
275 int rc;
276 rc = snprintf(buffer + ret, len, " %s", p);
277 if (rc < 0 || rc >= len) {
278 free(buffer);
279 ERROR("Script args too long");
280 return -1;
281 }
282 ret += rc;
283 }
284 va_end(ap);
285
286 f = popen(buffer, "r");
287 if (!f) {
288 SYSERROR("popen failed");
289 return -1;
290 }
291
292 output = malloc(LXC_LOG_BUFFER_SIZE);
293 if (!output) {
294 ERROR("failed to allocate memory for script output");
295 return -1;
296 }
297
298 while(fgets(output, LXC_LOG_BUFFER_SIZE, f))
299 DEBUG("script output: %s", output);
300
301 free(output);
302
303 if (pclose(f) == -1) {
304 SYSERROR("Script exited on error");
305 return -1;
306 }
307
308 return 0;
309 }
310
311 static int find_fstype_cb(char* buffer, void *data)
312 {
313 struct cbarg {
314 const char *rootfs;
315 const char *target;
316 int mntopt;
317 } *cbarg = data;
318
319 char *fstype;
320
321 /* we don't try 'nodev' entries */
322 if (strstr(buffer, "nodev"))
323 return 0;
324
325 fstype = buffer;
326 fstype += lxc_char_left_gc(fstype, strlen(fstype));
327 fstype[lxc_char_right_gc(fstype, strlen(fstype))] = '\0';
328
329 DEBUG("trying to mount '%s'->'%s' with fstype '%s'",
330 cbarg->rootfs, cbarg->target, fstype);
331
332 if (mount(cbarg->rootfs, cbarg->target, fstype, cbarg->mntopt, NULL)) {
333 DEBUG("mount failed with error: %s", strerror(errno));
334 return 0;
335 }
336
337 INFO("mounted '%s' on '%s', with fstype '%s'",
338 cbarg->rootfs, cbarg->target, fstype);
339
340 return 1;
341 }
342
343 static int mount_unknow_fs(const char *rootfs, const char *target, int mntopt)
344 {
345 int i;
346
347 struct cbarg {
348 const char *rootfs;
349 const char *target;
350 int mntopt;
351 } cbarg = {
352 .rootfs = rootfs,
353 .target = target,
354 .mntopt = mntopt,
355 };
356
357 /*
358 * find the filesystem type with brute force:
359 * first we check with /etc/filesystems, in case the modules
360 * are auto-loaded and fall back to the supported kernel fs
361 */
362 char *fsfile[] = {
363 "/etc/filesystems",
364 "/proc/filesystems",
365 };
366
367 for (i = 0; i < sizeof(fsfile)/sizeof(fsfile[0]); i++) {
368
369 int ret;
370
371 if (access(fsfile[i], F_OK))
372 continue;
373
374 ret = lxc_file_for_each_line(fsfile[i], find_fstype_cb, &cbarg);
375 if (ret < 0) {
376 ERROR("failed to parse '%s'", fsfile[i]);
377 return -1;
378 }
379
380 if (ret)
381 return 0;
382 }
383
384 ERROR("failed to determine fs type for '%s'", rootfs);
385 return -1;
386 }
387
388 static int mount_rootfs_dir(const char *rootfs, const char *target)
389 {
390 return mount(rootfs, target, "none", MS_BIND | MS_REC, NULL);
391 }
392
393 static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo)
394 {
395 int rfd;
396 int ret = -1;
397
398 rfd = open(rootfs, O_RDWR);
399 if (rfd < 0) {
400 SYSERROR("failed to open '%s'", rootfs);
401 return -1;
402 }
403
404 memset(loinfo, 0, sizeof(*loinfo));
405
406 loinfo->lo_flags = LO_FLAGS_AUTOCLEAR;
407
408 if (ioctl(fd, LOOP_SET_FD, rfd)) {
409 SYSERROR("failed to LOOP_SET_FD");
410 goto out;
411 }
412
413 if (ioctl(fd, LOOP_SET_STATUS64, loinfo)) {
414 SYSERROR("failed to LOOP_SET_STATUS64");
415 goto out;
416 }
417
418 ret = 0;
419 out:
420 close(rfd);
421
422 return ret;
423 }
424
425 static int mount_rootfs_file(const char *rootfs, const char *target)
426 {
427 struct dirent dirent, *direntp;
428 struct loop_info64 loinfo;
429 int ret = -1, fd = -1, rc;
430 DIR *dir;
431 char path[MAXPATHLEN];
432
433 dir = opendir("/dev");
434 if (!dir) {
435 SYSERROR("failed to open '/dev'");
436 return -1;
437 }
438
439 while (!readdir_r(dir, &dirent, &direntp)) {
440
441 if (!direntp)
442 break;
443
444 if (!strcmp(direntp->d_name, "."))
445 continue;
446
447 if (!strcmp(direntp->d_name, ".."))
448 continue;
449
450 if (strncmp(direntp->d_name, "loop", 4))
451 continue;
452
453 rc = snprintf(path, MAXPATHLEN, "/dev/%s", direntp->d_name);
454 if (rc < 0 || rc >= MAXPATHLEN)
455 continue;
456
457 fd = open(path, O_RDWR);
458 if (fd < 0)
459 continue;
460
461 if (ioctl(fd, LOOP_GET_STATUS64, &loinfo) == 0) {
462 close(fd);
463 continue;
464 }
465
466 if (errno != ENXIO) {
467 WARN("unexpected error for ioctl on '%s': %m",
468 direntp->d_name);
469 continue;
470 }
471
472 DEBUG("found '%s' free lodev", path);
473
474 ret = setup_lodev(rootfs, fd, &loinfo);
475 if (!ret)
476 ret = mount_unknow_fs(path, target, 0);
477 close(fd);
478
479 break;
480 }
481
482 if (closedir(dir))
483 WARN("failed to close directory");
484
485 return ret;
486 }
487
488 static int mount_rootfs_block(const char *rootfs, const char *target)
489 {
490 return mount_unknow_fs(rootfs, target, 0);
491 }
492
493 /*
494 * pin_rootfs
495 * if rootfs is a directory, then open ${rootfs}.hold for writing for the
496 * duration of the container run, to prevent the container from marking the
497 * underlying fs readonly on shutdown.
498 * return -1 on error.
499 * return -2 if nothing needed to be pinned.
500 * return an open fd (>=0) if we pinned it.
501 */
502 int pin_rootfs(const char *rootfs)
503 {
504 char absrootfs[MAXPATHLEN];
505 char absrootfspin[MAXPATHLEN];
506 struct stat s;
507 int ret, fd;
508
509 if (rootfs == NULL || strlen(rootfs) == 0)
510 return 0;
511
512 if (!realpath(rootfs, absrootfs)) {
513 SYSERROR("failed to get real path for '%s'", rootfs);
514 return -1;
515 }
516
517 if (access(absrootfs, F_OK)) {
518 SYSERROR("'%s' is not accessible", absrootfs);
519 return -1;
520 }
521
522 if (stat(absrootfs, &s)) {
523 SYSERROR("failed to stat '%s'", absrootfs);
524 return -1;
525 }
526
527 if (!__S_ISTYPE(s.st_mode, S_IFDIR))
528 return -2;
529
530 ret = snprintf(absrootfspin, MAXPATHLEN, "%s%s", absrootfs, ".hold");
531 if (ret >= MAXPATHLEN) {
532 SYSERROR("pathname too long for rootfs hold file");
533 return -1;
534 }
535
536 fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR);
537 INFO("opened %s as fd %d\n", absrootfspin, fd);
538 return fd;
539 }
540
541 static int mount_rootfs(const char *rootfs, const char *target)
542 {
543 char absrootfs[MAXPATHLEN];
544 struct stat s;
545 int i;
546
547 typedef int (*rootfs_cb)(const char *, const char *);
548
549 struct rootfs_type {
550 int type;
551 rootfs_cb cb;
552 } rtfs_type[] = {
553 { S_IFDIR, mount_rootfs_dir },
554 { S_IFBLK, mount_rootfs_block },
555 { S_IFREG, mount_rootfs_file },
556 };
557
558 if (!realpath(rootfs, absrootfs)) {
559 SYSERROR("failed to get real path for '%s'", rootfs);
560 return -1;
561 }
562
563 if (access(absrootfs, F_OK)) {
564 SYSERROR("'%s' is not accessible", absrootfs);
565 return -1;
566 }
567
568 if (stat(absrootfs, &s)) {
569 SYSERROR("failed to stat '%s'", absrootfs);
570 return -1;
571 }
572
573 for (i = 0; i < sizeof(rtfs_type)/sizeof(rtfs_type[0]); i++) {
574
575 if (!__S_ISTYPE(s.st_mode, rtfs_type[i].type))
576 continue;
577
578 return rtfs_type[i].cb(absrootfs, target);
579 }
580
581 ERROR("unsupported rootfs type for '%s'", absrootfs);
582 return -1;
583 }
584
585 static int setup_utsname(struct utsname *utsname)
586 {
587 if (!utsname)
588 return 0;
589
590 if (sethostname(utsname->nodename, strlen(utsname->nodename))) {
591 SYSERROR("failed to set the hostname to '%s'", utsname->nodename);
592 return -1;
593 }
594
595 INFO("'%s' hostname has been setup", utsname->nodename);
596
597 return 0;
598 }
599
600 static int setup_tty(const struct lxc_rootfs *rootfs,
601 const struct lxc_tty_info *tty_info, char *ttydir)
602 {
603 char path[MAXPATHLEN], lxcpath[MAXPATHLEN];
604 int i, ret;
605
606 if (!rootfs->path)
607 return 0;
608
609 for (i = 0; i < tty_info->nbtty; i++) {
610
611 struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
612
613 ret = snprintf(path, sizeof(path), "%s/dev/tty%d",
614 rootfs->mount, i + 1);
615 if (ret >= sizeof(path)) {
616 ERROR("pathname too long for ttys");
617 return -1;
618 }
619 if (ttydir) {
620 /* create dev/lxc/tty%d" */
621 ret = snprintf(lxcpath, sizeof(lxcpath), "%s/dev/%s/tty%d",
622 rootfs->mount, ttydir, i + 1);
623 if (ret >= sizeof(lxcpath)) {
624 ERROR("pathname too long for ttys");
625 return -1;
626 }
627 ret = creat(lxcpath, 0660);
628 if (ret==-1 && errno != EEXIST) {
629 SYSERROR("error creating %s\n", lxcpath);
630 return -1;
631 }
632 close(ret);
633 ret = unlink(path);
634 if (ret && errno != ENOENT) {
635 SYSERROR("error unlinking %s\n", path);
636 return -1;
637 }
638
639 if (mount(pty_info->name, lxcpath, "none", MS_BIND, 0)) {
640 WARN("failed to mount '%s'->'%s'",
641 pty_info->name, path);
642 continue;
643 }
644
645 ret = snprintf(lxcpath, sizeof(lxcpath), "%s/tty%d", ttydir, i+1);
646 if (ret >= sizeof(lxcpath)) {
647 ERROR("tty pathname too long");
648 return -1;
649 }
650 ret = symlink(lxcpath, path);
651 if (ret) {
652 SYSERROR("failed to create symlink for tty %d\n", i+1);
653 return -1;
654 }
655 } else {
656 if (mount(pty_info->name, path, "none", MS_BIND, 0)) {
657 WARN("failed to mount '%s'->'%s'",
658 pty_info->name, path);
659 continue;
660 }
661 }
662 }
663
664 INFO("%d tty(s) has been setup", tty_info->nbtty);
665
666 return 0;
667 }
668
669 static int setup_rootfs_pivot_root_cb(char *buffer, void *data)
670 {
671 struct lxc_list *mountlist, *listentry, *iterator;
672 char *pivotdir, *mountpoint, *mountentry;
673 int found;
674 void **cbparm;
675
676 mountentry = buffer;
677 cbparm = (void **)data;
678
679 mountlist = cbparm[0];
680 pivotdir = cbparm[1];
681
682 /* parse entry, first field is mountname, ignore */
683 mountpoint = strtok(mountentry, " ");
684 if (!mountpoint)
685 return -1;
686
687 /* second field is mountpoint */
688 mountpoint = strtok(NULL, " ");
689 if (!mountpoint)
690 return -1;
691
692 /* only consider mountpoints below old root fs */
693 if (strncmp(mountpoint, pivotdir, strlen(pivotdir)))
694 return 0;
695
696 /* filter duplicate mountpoints */
697 found = 0;
698 lxc_list_for_each(iterator, mountlist) {
699 if (!strcmp(iterator->elem, mountpoint)) {
700 found = 1;
701 break;
702 }
703 }
704 if (found)
705 return 0;
706
707 /* add entry to list */
708 listentry = malloc(sizeof(*listentry));
709 if (!listentry) {
710 SYSERROR("malloc for mountpoint listentry failed");
711 return -1;
712 }
713
714 listentry->elem = strdup(mountpoint);
715 if (!listentry->elem) {
716 SYSERROR("strdup failed");
717 return -1;
718 }
719 lxc_list_add_tail(mountlist, listentry);
720
721 return 0;
722 }
723
724 static int umount_oldrootfs(const char *oldrootfs)
725 {
726 char path[MAXPATHLEN];
727 void *cbparm[2];
728 struct lxc_list mountlist, *iterator;
729 int ok, still_mounted, last_still_mounted;
730 int rc;
731
732 /* read and parse /proc/mounts in old root fs */
733 lxc_list_init(&mountlist);
734
735 /* oldrootfs is on the top tree directory now */
736 rc = snprintf(path, sizeof(path), "/%s", oldrootfs);
737 if (rc >= sizeof(path)) {
738 ERROR("rootfs name too long");
739 return -1;
740 }
741 cbparm[0] = &mountlist;
742
743 cbparm[1] = strdup(path);
744 if (!cbparm[1]) {
745 SYSERROR("strdup failed");
746 return -1;
747 }
748
749 rc = snprintf(path, sizeof(path), "%s/proc/mounts", oldrootfs);
750 if (rc >= sizeof(path)) {
751 ERROR("container proc/mounts name too long");
752 return -1;
753 }
754
755 ok = lxc_file_for_each_line(path,
756 setup_rootfs_pivot_root_cb, &cbparm);
757 if (ok < 0) {
758 SYSERROR("failed to read or parse mount list '%s'", path);
759 return -1;
760 }
761
762 /* umount filesystems until none left or list no longer shrinks */
763 still_mounted = 0;
764 do {
765 last_still_mounted = still_mounted;
766 still_mounted = 0;
767
768 lxc_list_for_each(iterator, &mountlist) {
769
770 /* umount normally */
771 if (!umount(iterator->elem)) {
772 DEBUG("umounted '%s'", (char *)iterator->elem);
773 lxc_list_del(iterator);
774 continue;
775 }
776
777 still_mounted++;
778 }
779
780 } while (still_mounted > 0 && still_mounted != last_still_mounted);
781
782
783 lxc_list_for_each(iterator, &mountlist) {
784
785 /* let's try a lazy umount */
786 if (!umount2(iterator->elem, MNT_DETACH)) {
787 INFO("lazy unmount of '%s'", (char *)iterator->elem);
788 continue;
789 }
790
791 /* be more brutal (nfs) */
792 if (!umount2(iterator->elem, MNT_FORCE)) {
793 INFO("forced unmount of '%s'", (char *)iterator->elem);
794 continue;
795 }
796
797 WARN("failed to unmount '%s'", (char *)iterator->elem);
798 }
799
800 return 0;
801 }
802
803 static int setup_rootfs_pivot_root(const char *rootfs, const char *pivotdir)
804 {
805 char path[MAXPATHLEN];
806 int remove_pivotdir = 0;
807 int rc;
808
809 /* change into new root fs */
810 if (chdir(rootfs)) {
811 SYSERROR("can't chdir to new rootfs '%s'", rootfs);
812 return -1;
813 }
814
815 if (!pivotdir)
816 pivotdir = "lxc_putold";
817
818 /* compute the full path to pivotdir under rootfs */
819 rc = snprintf(path, sizeof(path), "%s/%s", rootfs, pivotdir);
820 if (rc >= sizeof(path)) {
821 ERROR("pivot dir name too long");
822 return -1;
823 }
824
825 if (access(path, F_OK)) {
826
827 if (mkdir_p(path, 0755)) {
828 SYSERROR("failed to create pivotdir '%s'", path);
829 return -1;
830 }
831
832 remove_pivotdir = 1;
833 DEBUG("created '%s' directory", path);
834 }
835
836 DEBUG("mountpoint for old rootfs is '%s'", path);
837
838 /* pivot_root into our new root fs */
839 if (pivot_root(".", path)) {
840 SYSERROR("pivot_root syscall failed");
841 return -1;
842 }
843
844 if (chdir("/")) {
845 SYSERROR("can't chdir to / after pivot_root");
846 return -1;
847 }
848
849 DEBUG("pivot_root syscall to '%s' successful", rootfs);
850
851 /* we switch from absolute path to relative path */
852 if (umount_oldrootfs(pivotdir))
853 return -1;
854
855 /* remove temporary mount point, we don't consider the removing
856 * as fatal */
857 if (remove_pivotdir && rmdir(pivotdir))
858 WARN("can't remove mountpoint '%s': %m", pivotdir);
859
860 return 0;
861 }
862
863 static int setup_rootfs(const struct lxc_rootfs *rootfs)
864 {
865 if (!rootfs->path)
866 return 0;
867
868 if (access(rootfs->mount, F_OK)) {
869 SYSERROR("failed to access to '%s', check it is present",
870 rootfs->mount);
871 return -1;
872 }
873
874 if (mount_rootfs(rootfs->path, rootfs->mount)) {
875 ERROR("failed to mount rootfs");
876 return -1;
877 }
878
879 DEBUG("mounted '%s' on '%s'", rootfs->path, rootfs->mount);
880
881 return 0;
882 }
883
884 int setup_pivot_root(const struct lxc_rootfs *rootfs)
885 {
886 if (!rootfs->path)
887 return 0;
888
889 if (setup_rootfs_pivot_root(rootfs->mount, rootfs->pivot)) {
890 ERROR("failed to setup pivot root");
891 return -1;
892 }
893
894 return 0;
895 }
896
897 static int setup_pts(int pts)
898 {
899 char target[PATH_MAX];
900
901 if (!pts)
902 return 0;
903
904 if (!access("/dev/pts/ptmx", F_OK) && umount("/dev/pts")) {
905 SYSERROR("failed to umount 'dev/pts'");
906 return -1;
907 }
908
909 if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL,
910 "newinstance,ptmxmode=0666")) {
911 SYSERROR("failed to mount a new instance of '/dev/pts'");
912 return -1;
913 }
914
915 if (access("/dev/ptmx", F_OK)) {
916 if (!symlink("/dev/pts/ptmx", "/dev/ptmx"))
917 goto out;
918 SYSERROR("failed to symlink '/dev/pts/ptmx'->'/dev/ptmx'");
919 return -1;
920 }
921
922 if (realpath("/dev/ptmx", target) && !strcmp(target, "/dev/pts/ptmx"))
923 goto out;
924
925 /* fallback here, /dev/pts/ptmx exists just mount bind */
926 if (mount("/dev/pts/ptmx", "/dev/ptmx", "none", MS_BIND, 0)) {
927 SYSERROR("mount failed '/dev/pts/ptmx'->'/dev/ptmx'");
928 return -1;
929 }
930
931 INFO("created new pts instance");
932
933 out:
934 return 0;
935 }
936
937 static int setup_personality(int persona)
938 {
939 if (persona == -1)
940 return 0;
941
942 if (personality(persona) < 0) {
943 SYSERROR("failed to set personality to '0x%x'", persona);
944 return -1;
945 }
946
947 INFO("set personality to '0x%x'", persona);
948
949 return 0;
950 }
951
952 static int setup_dev_console(const struct lxc_rootfs *rootfs,
953 const struct lxc_console *console)
954 {
955 char path[MAXPATHLEN];
956 struct stat s;
957 int ret;
958
959 ret = snprintf(path, sizeof(path), "%s/dev/console", rootfs->mount);
960 if (ret >= sizeof(path)) {
961 ERROR("console path too long\n");
962 return -1;
963 }
964
965 if (access(path, F_OK)) {
966 WARN("rootfs specified but no console found at '%s'", path);
967 return 0;
968 }
969
970 if (console->peer == -1) {
971 INFO("no console output required");
972 return 0;
973 }
974
975 if (stat(path, &s)) {
976 SYSERROR("failed to stat '%s'", path);
977 return -1;
978 }
979
980 if (chmod(console->name, s.st_mode)) {
981 SYSERROR("failed to set mode '0%o' to '%s'",
982 s.st_mode, console->name);
983 return -1;
984 }
985
986 if (mount(console->name, path, "none", MS_BIND, 0)) {
987 ERROR("failed to mount '%s' on '%s'", console->name, path);
988 return -1;
989 }
990
991 INFO("console has been setup");
992 return 0;
993 }
994
995 static int setup_ttydir_console(const struct lxc_rootfs *rootfs,
996 const struct lxc_console *console,
997 char *ttydir)
998 {
999 char path[MAXPATHLEN], lxcpath[MAXPATHLEN];
1000 int ret;
1001
1002 /* create rootfs/dev/<ttydir> directory */
1003 ret = snprintf(path, sizeof(path), "%s/dev/%s", rootfs->mount,
1004 ttydir);
1005 if (ret >= sizeof(path))
1006 return -1;
1007 ret = mkdir(path, 0755);
1008 if (ret && errno != EEXIST) {
1009 SYSERROR("failed with errno %d to create %s\n", errno, path);
1010 return -1;
1011 }
1012 INFO("created %s\n", path);
1013
1014 ret = snprintf(lxcpath, sizeof(lxcpath), "%s/dev/%s/console",
1015 rootfs->mount, ttydir);
1016 if (ret >= sizeof(lxcpath)) {
1017 ERROR("console path too long\n");
1018 return -1;
1019 }
1020
1021 snprintf(path, sizeof(path), "%s/dev/console", rootfs->mount);
1022 ret = unlink(path);
1023 if (ret && errno != ENOENT) {
1024 SYSERROR("error unlinking %s\n", path);
1025 return -1;
1026 }
1027
1028 ret = creat(lxcpath, 0660);
1029 if (ret==-1 && errno != EEXIST) {
1030 SYSERROR("error %d creating %s\n", errno, lxcpath);
1031 return -1;
1032 }
1033 close(ret);
1034
1035 if (console->peer == -1) {
1036 INFO("no console output required");
1037 return 0;
1038 }
1039
1040 if (mount(console->name, lxcpath, "none", MS_BIND, 0)) {
1041 ERROR("failed to mount '%s' on '%s'", console->name, lxcpath);
1042 return -1;
1043 }
1044
1045 /* create symlink from rootfs/dev/console to 'lxc/console' */
1046 ret = snprintf(lxcpath, sizeof(lxcpath), "%s/console", ttydir);
1047 if (ret >= sizeof(lxcpath)) {
1048 ERROR("lxc/console path too long");
1049 return -1;
1050 }
1051 ret = symlink(lxcpath, path);
1052 if (ret) {
1053 SYSERROR("failed to create symlink for console");
1054 return -1;
1055 }
1056
1057 INFO("console has been setup on %s", lxcpath);
1058
1059 return 0;
1060 }
1061
1062 static int setup_console(const struct lxc_rootfs *rootfs,
1063 const struct lxc_console *console,
1064 char *ttydir)
1065 {
1066 /* We don't have a rootfs, /dev/console will be shared */
1067 if (!rootfs->path)
1068 return 0;
1069 if (!ttydir)
1070 return setup_dev_console(rootfs, console);
1071
1072 return setup_ttydir_console(rootfs, console, ttydir);
1073 }
1074
1075 static int setup_kmsg(const struct lxc_rootfs *rootfs,
1076 const struct lxc_console *console)
1077 {
1078 char kpath[MAXPATHLEN];
1079 int ret;
1080
1081 ret = snprintf(kpath, sizeof(kpath), "%s/dev/kmsg", rootfs->mount);
1082 if (ret < 0 || ret >= sizeof(kpath))
1083 return -1;
1084
1085 ret = unlink(kpath);
1086 if (ret && errno != ENOENT) {
1087 SYSERROR("error unlinking %s\n", kpath);
1088 return -1;
1089 }
1090
1091 ret = symlink("console", kpath);
1092 if (ret) {
1093 SYSERROR("failed to create symlink for kmsg");
1094 return -1;
1095 }
1096
1097 return 0;
1098 }
1099
1100 static int setup_cgroup(const char *name, struct lxc_list *cgroups)
1101 {
1102 struct lxc_list *iterator;
1103 struct lxc_cgroup *cg;
1104 int ret = -1;
1105
1106 if (lxc_list_empty(cgroups))
1107 return 0;
1108
1109 lxc_list_for_each(iterator, cgroups) {
1110
1111 cg = iterator->elem;
1112
1113 if (lxc_cgroup_set(name, cg->subsystem, cg->value))
1114 goto out;
1115
1116 DEBUG("cgroup '%s' set to '%s'", cg->subsystem, cg->value);
1117 }
1118
1119 ret = 0;
1120 INFO("cgroup has been setup");
1121 out:
1122 return ret;
1123 }
1124
1125 static void parse_mntopt(char *opt, unsigned long *flags, char **data)
1126 {
1127 struct mount_opt *mo;
1128
1129 /* If opt is found in mount_opt, set or clear flags.
1130 * Otherwise append it to data. */
1131
1132 for (mo = &mount_opt[0]; mo->name != NULL; mo++) {
1133 if (!strncmp(opt, mo->name, strlen(mo->name))) {
1134 if (mo->clear)
1135 *flags &= ~mo->flag;
1136 else
1137 *flags |= mo->flag;
1138 return;
1139 }
1140 }
1141
1142 if (strlen(*data))
1143 strcat(*data, ",");
1144 strcat(*data, opt);
1145 }
1146
1147 static int parse_mntopts(const char *mntopts, unsigned long *mntflags,
1148 char **mntdata)
1149 {
1150 char *s, *data;
1151 char *p, *saveptr = NULL;
1152
1153 *mntdata = NULL;
1154 *mntflags = 0L;
1155
1156 if (!mntopts)
1157 return 0;
1158
1159 s = strdup(mntopts);
1160 if (!s) {
1161 SYSERROR("failed to allocate memory");
1162 return -1;
1163 }
1164
1165 data = malloc(strlen(s) + 1);
1166 if (!data) {
1167 SYSERROR("failed to allocate memory");
1168 free(s);
1169 return -1;
1170 }
1171 *data = 0;
1172
1173 for (p = strtok_r(s, ",", &saveptr); p != NULL;
1174 p = strtok_r(NULL, ",", &saveptr))
1175 parse_mntopt(p, mntflags, &data);
1176
1177 if (*data)
1178 *mntdata = data;
1179 else
1180 free(data);
1181 free(s);
1182
1183 return 0;
1184 }
1185
1186 static int mount_entry(const char *fsname, const char *target,
1187 const char *fstype, unsigned long mountflags,
1188 const char *data)
1189 {
1190 if (mount(fsname, target, fstype, mountflags & ~MS_REMOUNT, data)) {
1191 SYSERROR("failed to mount '%s' on '%s'", fsname, target);
1192 return -1;
1193 }
1194
1195 if ((mountflags & MS_REMOUNT) || (mountflags & MS_BIND)) {
1196
1197 DEBUG("remounting %s on %s to respect bind or remount options",
1198 fsname, target);
1199
1200 if (mount(fsname, target, fstype,
1201 mountflags | MS_REMOUNT, data)) {
1202 SYSERROR("failed to mount '%s' on '%s'",
1203 fsname, target);
1204 return -1;
1205 }
1206 }
1207
1208 DEBUG("mounted '%s' on '%s', type '%s'", fsname, target, fstype);
1209
1210 return 0;
1211 }
1212
1213 static inline int mount_entry_on_systemfs(struct mntent *mntent)
1214 {
1215 unsigned long mntflags;
1216 char *mntdata;
1217 int ret;
1218
1219 if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
1220 ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
1221 return -1;
1222 }
1223
1224 ret = mount_entry(mntent->mnt_fsname, mntent->mnt_dir,
1225 mntent->mnt_type, mntflags, mntdata);
1226
1227 free(mntdata);
1228
1229 return ret;
1230 }
1231
1232 static int mount_entry_on_absolute_rootfs(struct mntent *mntent,
1233 const struct lxc_rootfs *rootfs,
1234 const char *lxc_name)
1235 {
1236 char *aux;
1237 char path[MAXPATHLEN];
1238 unsigned long mntflags;
1239 char *mntdata;
1240 int r, ret = 0, offset;
1241
1242 if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
1243 ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
1244 return -1;
1245 }
1246
1247 /* if rootfs->path is a blockdev path, allow container fstab to
1248 * use /var/lib/lxc/CN/rootfs as the target prefix */
1249 r = snprintf(path, MAXPATHLEN, "/var/lib/lxc/%s/rootfs", lxc_name);
1250 if (r < 0 || r >= MAXPATHLEN)
1251 goto skipvarlib;
1252
1253 aux = strstr(mntent->mnt_dir, path);
1254 if (aux) {
1255 offset = strlen(path);
1256 goto skipabs;
1257 }
1258
1259 skipvarlib:
1260 aux = strstr(mntent->mnt_dir, rootfs->path);
1261 if (!aux) {
1262 WARN("ignoring mount point '%s'", mntent->mnt_dir);
1263 goto out;
1264 }
1265 offset = strlen(rootfs->path);
1266
1267 skipabs:
1268
1269 r = snprintf(path, MAXPATHLEN, "%s/%s", rootfs->mount,
1270 aux + offset);
1271 if (r < 0 || r >= MAXPATHLEN) {
1272 WARN("pathnme too long for '%s'", mntent->mnt_dir);
1273 ret = -1;
1274 goto out;
1275 }
1276
1277
1278 ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
1279 mntflags, mntdata);
1280
1281 out:
1282 free(mntdata);
1283 return ret;
1284 }
1285
1286 static int mount_entry_on_relative_rootfs(struct mntent *mntent,
1287 const char *rootfs)
1288 {
1289 char path[MAXPATHLEN];
1290 unsigned long mntflags;
1291 char *mntdata;
1292 int ret;
1293
1294 if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
1295 ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
1296 return -1;
1297 }
1298
1299 /* relative to root mount point */
1300 ret = snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir);
1301 if (ret >= sizeof(path)) {
1302 ERROR("path name too long");
1303 return -1;
1304 }
1305
1306 ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
1307 mntflags, mntdata);
1308
1309 free(mntdata);
1310
1311 return ret;
1312 }
1313
1314 static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file,
1315 const char *lxc_name)
1316 {
1317 struct mntent *mntent;
1318 int ret = -1;
1319
1320 while ((mntent = getmntent(file))) {
1321
1322 if (!rootfs->path) {
1323 if (mount_entry_on_systemfs(mntent))
1324 goto out;
1325 continue;
1326 }
1327
1328 /* We have a separate root, mounts are relative to it */
1329 if (mntent->mnt_dir[0] != '/') {
1330 if (mount_entry_on_relative_rootfs(mntent,
1331 rootfs->mount))
1332 goto out;
1333 continue;
1334 }
1335
1336 if (mount_entry_on_absolute_rootfs(mntent, rootfs, lxc_name))
1337 goto out;
1338 }
1339
1340 ret = 0;
1341
1342 INFO("mount points have been setup");
1343 out:
1344 return ret;
1345 }
1346
1347 static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab,
1348 const char *lxc_name)
1349 {
1350 FILE *file;
1351 int ret;
1352
1353 if (!fstab)
1354 return 0;
1355
1356 file = setmntent(fstab, "r");
1357 if (!file) {
1358 SYSERROR("failed to use '%s'", fstab);
1359 return -1;
1360 }
1361
1362 ret = mount_file_entries(rootfs, file, lxc_name);
1363
1364 endmntent(file);
1365 return ret;
1366 }
1367
1368 static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount,
1369 const char *lxc_name)
1370 {
1371 FILE *file;
1372 struct lxc_list *iterator;
1373 char *mount_entry;
1374 int ret;
1375
1376 file = tmpfile();
1377 if (!file) {
1378 ERROR("tmpfile error: %m");
1379 return -1;
1380 }
1381
1382 lxc_list_for_each(iterator, mount) {
1383 mount_entry = iterator->elem;
1384 fprintf(file, "%s\n", mount_entry);
1385 }
1386
1387 rewind(file);
1388
1389 ret = mount_file_entries(rootfs, file, lxc_name);
1390
1391 fclose(file);
1392 return ret;
1393 }
1394
1395 static int setup_caps(struct lxc_list *caps)
1396 {
1397 struct lxc_list *iterator;
1398 char *drop_entry;
1399 char *ptr;
1400 int i, capid;
1401
1402 lxc_list_for_each(iterator, caps) {
1403
1404 drop_entry = iterator->elem;
1405
1406 capid = -1;
1407
1408 for (i = 0; i < sizeof(caps_opt)/sizeof(caps_opt[0]); i++) {
1409
1410 if (strcmp(drop_entry, caps_opt[i].name))
1411 continue;
1412
1413 capid = caps_opt[i].value;
1414 break;
1415 }
1416
1417 if (capid < 0) {
1418 /* try to see if it's numeric, so the user may specify
1419 * capabilities that the running kernel knows about but
1420 * we don't */
1421 capid = strtol(drop_entry, &ptr, 10);
1422 if (!ptr || *ptr != '\0' ||
1423 capid == LONG_MIN || capid == LONG_MAX)
1424 /* not a valid number */
1425 capid = -1;
1426 else if (capid > lxc_caps_last_cap())
1427 /* we have a number but it's not a valid
1428 * capability */
1429 capid = -1;
1430 }
1431
1432 if (capid < 0) {
1433 ERROR("unknown capability %s", drop_entry);
1434 return -1;
1435 }
1436
1437 DEBUG("drop capability '%s' (%d)", drop_entry, capid);
1438
1439 if (prctl(PR_CAPBSET_DROP, capid, 0, 0, 0)) {
1440 SYSERROR("failed to remove %s capability", drop_entry);
1441 return -1;
1442 }
1443
1444 }
1445
1446 DEBUG("capabilities has been setup");
1447
1448 return 0;
1449 }
1450
1451 static int setup_hw_addr(char *hwaddr, const char *ifname)
1452 {
1453 struct sockaddr sockaddr;
1454 struct ifreq ifr;
1455 int ret, fd;
1456
1457 ret = lxc_convert_mac(hwaddr, &sockaddr);
1458 if (ret) {
1459 ERROR("mac address '%s' conversion failed : %s",
1460 hwaddr, strerror(-ret));
1461 return -1;
1462 }
1463
1464 memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
1465 memcpy((char *) &ifr.ifr_hwaddr, (char *) &sockaddr, sizeof(sockaddr));
1466
1467 fd = socket(AF_INET, SOCK_DGRAM, 0);
1468 if (fd < 0) {
1469 ERROR("socket failure : %s", strerror(errno));
1470 return -1;
1471 }
1472
1473 ret = ioctl(fd, SIOCSIFHWADDR, &ifr);
1474 close(fd);
1475 if (ret)
1476 ERROR("ioctl failure : %s", strerror(errno));
1477
1478 DEBUG("mac address '%s' on '%s' has been setup", hwaddr, ifname);
1479
1480 return ret;
1481 }
1482
1483 static int setup_ipv4_addr(struct lxc_list *ip, int ifindex)
1484 {
1485 struct lxc_list *iterator;
1486 struct lxc_inetdev *inetdev;
1487 int err;
1488
1489 lxc_list_for_each(iterator, ip) {
1490
1491 inetdev = iterator->elem;
1492
1493 err = lxc_ipv4_addr_add(ifindex, &inetdev->addr,
1494 &inetdev->bcast, inetdev->prefix);
1495 if (err) {
1496 ERROR("failed to setup_ipv4_addr ifindex %d : %s",
1497 ifindex, strerror(-err));
1498 return -1;
1499 }
1500 }
1501
1502 return 0;
1503 }
1504
1505 static int setup_ipv6_addr(struct lxc_list *ip, int ifindex)
1506 {
1507 struct lxc_list *iterator;
1508 struct lxc_inet6dev *inet6dev;
1509 int err;
1510
1511 lxc_list_for_each(iterator, ip) {
1512
1513 inet6dev = iterator->elem;
1514
1515 err = lxc_ipv6_addr_add(ifindex, &inet6dev->addr,
1516 &inet6dev->mcast, &inet6dev->acast,
1517 inet6dev->prefix);
1518 if (err) {
1519 ERROR("failed to setup_ipv6_addr ifindex %d : %s",
1520 ifindex, strerror(-err));
1521 return -1;
1522 }
1523 }
1524
1525 return 0;
1526 }
1527
1528 static int setup_netdev(struct lxc_netdev *netdev)
1529 {
1530 char ifname[IFNAMSIZ];
1531 char *current_ifname = ifname;
1532 int err;
1533
1534 /* empty network namespace */
1535 if (!netdev->ifindex) {
1536 if (netdev->flags & IFF_UP) {
1537 err = lxc_netdev_up("lo");
1538 if (err) {
1539 ERROR("failed to set the loopback up : %s",
1540 strerror(-err));
1541 return -1;
1542 }
1543 }
1544 return 0;
1545 }
1546
1547 /* retrieve the name of the interface */
1548 if (!if_indextoname(netdev->ifindex, current_ifname)) {
1549 ERROR("no interface corresponding to index '%d'",
1550 netdev->ifindex);
1551 return -1;
1552 }
1553
1554 /* default: let the system to choose one interface name */
1555 if (!netdev->name)
1556 netdev->name = netdev->type == LXC_NET_PHYS ?
1557 netdev->link : "eth%d";
1558
1559 /* rename the interface name */
1560 err = lxc_netdev_rename_by_name(ifname, netdev->name);
1561 if (err) {
1562 ERROR("failed to rename %s->%s : %s", ifname, netdev->name,
1563 strerror(-err));
1564 return -1;
1565 }
1566
1567 /* Re-read the name of the interface because its name has changed
1568 * and would be automatically allocated by the system
1569 */
1570 if (!if_indextoname(netdev->ifindex, current_ifname)) {
1571 ERROR("no interface corresponding to index '%d'",
1572 netdev->ifindex);
1573 return -1;
1574 }
1575
1576 /* set a mac address */
1577 if (netdev->hwaddr) {
1578 if (setup_hw_addr(netdev->hwaddr, current_ifname)) {
1579 ERROR("failed to setup hw address for '%s'",
1580 current_ifname);
1581 return -1;
1582 }
1583 }
1584
1585 /* setup ipv4 addresses on the interface */
1586 if (setup_ipv4_addr(&netdev->ipv4, netdev->ifindex)) {
1587 ERROR("failed to setup ip addresses for '%s'",
1588 ifname);
1589 return -1;
1590 }
1591
1592 /* setup ipv6 addresses on the interface */
1593 if (setup_ipv6_addr(&netdev->ipv6, netdev->ifindex)) {
1594 ERROR("failed to setup ipv6 addresses for '%s'",
1595 ifname);
1596 return -1;
1597 }
1598
1599 /* set the network device up */
1600 if (netdev->flags & IFF_UP) {
1601 int err;
1602
1603 err = lxc_netdev_up(current_ifname);
1604 if (err) {
1605 ERROR("failed to set '%s' up : %s", current_ifname,
1606 strerror(-err));
1607 return -1;
1608 }
1609
1610 /* the network is up, make the loopback up too */
1611 err = lxc_netdev_up("lo");
1612 if (err) {
1613 ERROR("failed to set the loopback up : %s",
1614 strerror(-err));
1615 return -1;
1616 }
1617 }
1618
1619 /* We can only set up the default routes after bringing
1620 * up the interface, sine bringing up the interface adds
1621 * the link-local routes and we can't add a default
1622 * route if the gateway is not reachable. */
1623
1624 /* setup ipv4 gateway on the interface */
1625 if (netdev->ipv4_gateway) {
1626 if (!(netdev->flags & IFF_UP)) {
1627 ERROR("Cannot add ipv4 gateway for %s when not bringing up the interface", ifname);
1628 return -1;
1629 }
1630
1631 if (lxc_list_empty(&netdev->ipv4)) {
1632 ERROR("Cannot add ipv4 gateway for %s when not assigning an address", ifname);
1633 return -1;
1634 }
1635
1636 err = lxc_ipv4_gateway_add(netdev->ifindex, netdev->ipv4_gateway);
1637 if (err) {
1638 ERROR("failed to setup ipv4 gateway for '%s': %s",
1639 ifname, strerror(-err));
1640 if (netdev->ipv4_gateway_auto) {
1641 char buf[INET_ADDRSTRLEN];
1642 inet_ntop(AF_INET, netdev->ipv4_gateway, buf, sizeof(buf));
1643 ERROR("tried to set autodetected ipv4 gateway '%s'", buf);
1644 }
1645 return -1;
1646 }
1647 }
1648
1649 /* setup ipv6 gateway on the interface */
1650 if (netdev->ipv6_gateway) {
1651 if (!(netdev->flags & IFF_UP)) {
1652 ERROR("Cannot add ipv6 gateway for %s when not bringing up the interface", ifname);
1653 return -1;
1654 }
1655
1656 if (lxc_list_empty(&netdev->ipv6) && !IN6_IS_ADDR_LINKLOCAL(netdev->ipv6_gateway)) {
1657 ERROR("Cannot add ipv6 gateway for %s when not assigning an address", ifname);
1658 return -1;
1659 }
1660
1661 err = lxc_ipv6_gateway_add(netdev->ifindex, netdev->ipv6_gateway);
1662 if (err) {
1663 ERROR("failed to setup ipv6 gateway for '%s': %s",
1664 ifname, strerror(-err));
1665 if (netdev->ipv6_gateway_auto) {
1666 char buf[INET6_ADDRSTRLEN];
1667 inet_ntop(AF_INET6, netdev->ipv6_gateway, buf, sizeof(buf));
1668 ERROR("tried to set autodetected ipv6 gateway '%s'", buf);
1669 }
1670 return -1;
1671 }
1672 }
1673
1674 DEBUG("'%s' has been setup", current_ifname);
1675
1676 return 0;
1677 }
1678
1679 static int setup_network(struct lxc_list *network)
1680 {
1681 struct lxc_list *iterator;
1682 struct lxc_netdev *netdev;
1683
1684 lxc_list_for_each(iterator, network) {
1685
1686 netdev = iterator->elem;
1687
1688 if (setup_netdev(netdev)) {
1689 ERROR("failed to setup netdev");
1690 return -1;
1691 }
1692 }
1693
1694 if (!lxc_list_empty(network))
1695 INFO("network has been setup");
1696
1697 return 0;
1698 }
1699
1700 static int setup_private_host_hw_addr(char *veth1)
1701 {
1702 struct ifreq ifr;
1703 int err;
1704 int sockfd;
1705
1706 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
1707 if (sockfd < 0)
1708 return -errno;
1709
1710 snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
1711 err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
1712 if (err < 0) {
1713 close(sockfd);
1714 return -errno;
1715 }
1716
1717 ifr.ifr_hwaddr.sa_data[0] = 0xfe;
1718 err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
1719 close(sockfd);
1720 if (err < 0)
1721 return -errno;
1722
1723 DEBUG("mac address of host interface '%s' changed to private "
1724 "%02x:%02x:%02x:%02x:%02x:%02x", veth1,
1725 ifr.ifr_hwaddr.sa_data[0] & 0xff,
1726 ifr.ifr_hwaddr.sa_data[1] & 0xff,
1727 ifr.ifr_hwaddr.sa_data[2] & 0xff,
1728 ifr.ifr_hwaddr.sa_data[3] & 0xff,
1729 ifr.ifr_hwaddr.sa_data[4] & 0xff,
1730 ifr.ifr_hwaddr.sa_data[5] & 0xff);
1731
1732 return 0;
1733 }
1734
1735 struct lxc_conf *lxc_conf_init(void)
1736 {
1737 struct lxc_conf *new;
1738 int i;
1739
1740 new = malloc(sizeof(*new));
1741 if (!new) {
1742 ERROR("lxc_conf_init : %m");
1743 return NULL;
1744 }
1745 memset(new, 0, sizeof(*new));
1746
1747 new->personality = -1;
1748 new->console.path = NULL;
1749 new->console.peer = -1;
1750 new->console.master = -1;
1751 new->console.slave = -1;
1752 new->console.name[0] = '\0';
1753 new->rootfs.mount = LXCROOTFSMOUNT;
1754 lxc_list_init(&new->cgroup);
1755 lxc_list_init(&new->network);
1756 lxc_list_init(&new->mount_list);
1757 lxc_list_init(&new->caps);
1758 for (i=0; i<NUM_LXC_HOOKS; i++)
1759 lxc_list_init(&new->hooks[i]);
1760 #if HAVE_APPARMOR
1761 new->aa_profile = NULL;
1762 #endif
1763 #if HAVE_APPARMOR /* || HAVE_SMACK || HAVE_SELINUX */
1764 new->lsm_umount_proc = 0;
1765 #endif
1766
1767 return new;
1768 }
1769
1770 static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
1771 {
1772 char veth1buf[IFNAMSIZ], *veth1;
1773 char veth2buf[IFNAMSIZ], *veth2;
1774 int err;
1775
1776 if (netdev->priv.veth_attr.pair)
1777 veth1 = netdev->priv.veth_attr.pair;
1778 else {
1779 err = snprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX");
1780 if (err >= sizeof(veth1buf)) { /* can't *really* happen, but... */
1781 ERROR("veth1 name too long");
1782 return -1;
1783 }
1784 veth1 = mktemp(veth1buf);
1785 /* store away for deconf */
1786 memcpy(netdev->priv.veth_attr.veth1, veth1, IFNAMSIZ);
1787 }
1788
1789 snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX");
1790 veth2 = mktemp(veth2buf);
1791
1792 if (!strlen(veth1) || !strlen(veth2)) {
1793 ERROR("failed to allocate a temporary name");
1794 return -1;
1795 }
1796
1797 err = lxc_veth_create(veth1, veth2);
1798 if (err) {
1799 ERROR("failed to create %s-%s : %s", veth1, veth2,
1800 strerror(-err));
1801 return -1;
1802 }
1803
1804 /* changing the high byte of the mac address to 0xfe, the bridge interface
1805 * will always keep the host's mac address and not take the mac address
1806 * of a container */
1807 err = setup_private_host_hw_addr(veth1);
1808 if (err) {
1809 ERROR("failed to change mac address of host interface '%s' : %s",
1810 veth1, strerror(-err));
1811 goto out_delete;
1812 }
1813
1814 if (netdev->mtu) {
1815 err = lxc_netdev_set_mtu(veth1, atoi(netdev->mtu));
1816 if (!err)
1817 err = lxc_netdev_set_mtu(veth2, atoi(netdev->mtu));
1818 if (err) {
1819 ERROR("failed to set mtu '%s' for %s-%s : %s",
1820 netdev->mtu, veth1, veth2, strerror(-err));
1821 goto out_delete;
1822 }
1823 }
1824
1825 if (netdev->link) {
1826 err = lxc_bridge_attach(netdev->link, veth1);
1827 if (err) {
1828 ERROR("failed to attach '%s' to the bridge '%s' : %s",
1829 veth1, netdev->link, strerror(-err));
1830 goto out_delete;
1831 }
1832 }
1833
1834 netdev->ifindex = if_nametoindex(veth2);
1835 if (!netdev->ifindex) {
1836 ERROR("failed to retrieve the index for %s", veth2);
1837 goto out_delete;
1838 }
1839
1840 err = lxc_netdev_up(veth1);
1841 if (err) {
1842 ERROR("failed to set %s up : %s", veth1, strerror(-err));
1843 goto out_delete;
1844 }
1845
1846 if (netdev->upscript) {
1847 err = run_script(handler->name, "net", netdev->upscript, "up",
1848 "veth", veth1, (char*) NULL);
1849 if (err)
1850 goto out_delete;
1851 }
1852
1853 DEBUG("instanciated veth '%s/%s', index is '%d'",
1854 veth1, veth2, netdev->ifindex);
1855
1856 return 0;
1857
1858 out_delete:
1859 lxc_netdev_delete_by_name(veth1);
1860 return -1;
1861 }
1862
1863 static int shutdown_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
1864 {
1865 char *veth1;
1866 int err;
1867
1868 if (netdev->priv.veth_attr.pair)
1869 veth1 = netdev->priv.veth_attr.pair;
1870 else
1871 veth1 = netdev->priv.veth_attr.veth1;
1872
1873 if (netdev->downscript) {
1874 err = run_script(handler->name, "net", netdev->downscript,
1875 "down", "veth", veth1, (char*) NULL);
1876 if (err)
1877 return -1;
1878 }
1879 return 0;
1880 }
1881
1882 static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
1883 {
1884 char peerbuf[IFNAMSIZ], *peer;
1885 int err;
1886
1887 if (!netdev->link) {
1888 ERROR("no link specified for macvlan netdev");
1889 return -1;
1890 }
1891
1892 err = snprintf(peerbuf, sizeof(peerbuf), "mcXXXXXX");
1893 if (err >= sizeof(peerbuf))
1894 return -1;
1895
1896 peer = mktemp(peerbuf);
1897 if (!strlen(peer)) {
1898 ERROR("failed to make a temporary name");
1899 return -1;
1900 }
1901
1902 err = lxc_macvlan_create(netdev->link, peer,
1903 netdev->priv.macvlan_attr.mode);
1904 if (err) {
1905 ERROR("failed to create macvlan interface '%s' on '%s' : %s",
1906 peer, netdev->link, strerror(-err));
1907 return -1;
1908 }
1909
1910 netdev->ifindex = if_nametoindex(peer);
1911 if (!netdev->ifindex) {
1912 ERROR("failed to retrieve the index for %s", peer);
1913 lxc_netdev_delete_by_name(peer);
1914 return -1;
1915 }
1916
1917 if (netdev->upscript) {
1918 err = run_script(handler->name, "net", netdev->upscript, "up",
1919 "macvlan", netdev->link, (char*) NULL);
1920 if (err)
1921 return -1;
1922 }
1923
1924 DEBUG("instanciated macvlan '%s', index is '%d' and mode '%d'",
1925 peer, netdev->ifindex, netdev->priv.macvlan_attr.mode);
1926
1927 return 0;
1928 }
1929
1930 static int shutdown_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
1931 {
1932 int err;
1933
1934 if (netdev->downscript) {
1935 err = run_script(handler->name, "net", netdev->downscript,
1936 "down", "macvlan", netdev->link,
1937 (char*) NULL);
1938 if (err)
1939 return -1;
1940 }
1941 return 0;
1942 }
1943
1944 /* XXX: merge with instanciate_macvlan */
1945 static int instanciate_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
1946 {
1947 char peer[IFNAMSIZ];
1948 int err;
1949
1950 if (!netdev->link) {
1951 ERROR("no link specified for vlan netdev");
1952 return -1;
1953 }
1954
1955 err = snprintf(peer, sizeof(peer), "vlan%d", netdev->priv.vlan_attr.vid);
1956 if (err >= sizeof(peer)) {
1957 ERROR("peer name too long");
1958 return -1;
1959 }
1960
1961 err = lxc_vlan_create(netdev->link, peer, netdev->priv.vlan_attr.vid);
1962 if (err) {
1963 ERROR("failed to create vlan interface '%s' on '%s' : %s",
1964 peer, netdev->link, strerror(-err));
1965 return -1;
1966 }
1967
1968 netdev->ifindex = if_nametoindex(peer);
1969 if (!netdev->ifindex) {
1970 ERROR("failed to retrieve the ifindex for %s", peer);
1971 lxc_netdev_delete_by_name(peer);
1972 return -1;
1973 }
1974
1975 DEBUG("instanciated vlan '%s', ifindex is '%d'", " vlan1000",
1976 netdev->ifindex);
1977
1978 return 0;
1979 }
1980
1981 static int shutdown_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
1982 {
1983 return 0;
1984 }
1985
1986 static int instanciate_phys(struct lxc_handler *handler, struct lxc_netdev *netdev)
1987 {
1988 if (!netdev->link) {
1989 ERROR("no link specified for the physical interface");
1990 return -1;
1991 }
1992
1993 netdev->ifindex = if_nametoindex(netdev->link);
1994 if (!netdev->ifindex) {
1995 ERROR("failed to retrieve the index for %s", netdev->link);
1996 return -1;
1997 }
1998
1999 if (netdev->upscript) {
2000 int err;
2001 err = run_script(handler->name, "net", netdev->upscript,
2002 "up", "phys", netdev->link, (char*) NULL);
2003 if (err)
2004 return -1;
2005 }
2006
2007 return 0;
2008 }
2009
2010 static int shutdown_phys(struct lxc_handler *handler, struct lxc_netdev *netdev)
2011 {
2012 int err;
2013
2014 if (netdev->downscript) {
2015 err = run_script(handler->name, "net", netdev->downscript,
2016 "down", "phys", netdev->link, (char*) NULL);
2017 if (err)
2018 return -1;
2019 }
2020 return 0;
2021 }
2022
2023 static int instanciate_empty(struct lxc_handler *handler, struct lxc_netdev *netdev)
2024 {
2025 netdev->ifindex = 0;
2026 if (netdev->upscript) {
2027 int err;
2028 err = run_script(handler->name, "net", netdev->upscript,
2029 "up", "empty", (char*) NULL);
2030 if (err)
2031 return -1;
2032 }
2033 return 0;
2034 }
2035
2036 static int shutdown_empty(struct lxc_handler *handler, struct lxc_netdev *netdev)
2037 {
2038 int err;
2039
2040 if (netdev->downscript) {
2041 err = run_script(handler->name, "net", netdev->downscript,
2042 "down", "empty", (char*) NULL);
2043 if (err)
2044 return -1;
2045 }
2046 return 0;
2047 }
2048
2049 int lxc_create_network(struct lxc_handler *handler)
2050 {
2051 struct lxc_list *network = &handler->conf->network;
2052 struct lxc_list *iterator;
2053 struct lxc_netdev *netdev;
2054
2055 lxc_list_for_each(iterator, network) {
2056
2057 netdev = iterator->elem;
2058
2059 if (netdev->type < 0 || netdev->type > LXC_NET_MAXCONFTYPE) {
2060 ERROR("invalid network configuration type '%d'",
2061 netdev->type);
2062 return -1;
2063 }
2064
2065 if (netdev_conf[netdev->type](handler, netdev)) {
2066 ERROR("failed to create netdev");
2067 return -1;
2068 }
2069
2070 }
2071
2072 return 0;
2073 }
2074
2075 void lxc_delete_network(struct lxc_handler *handler)
2076 {
2077 struct lxc_list *network = &handler->conf->network;
2078 struct lxc_list *iterator;
2079 struct lxc_netdev *netdev;
2080
2081 lxc_list_for_each(iterator, network) {
2082 netdev = iterator->elem;
2083
2084 if (netdev->ifindex != 0 && netdev->type == LXC_NET_PHYS) {
2085 if (lxc_netdev_rename_by_index(netdev->ifindex, netdev->link))
2086 WARN("failed to rename to the initial name the " \
2087 "netdev '%s'", netdev->link);
2088 continue;
2089 }
2090
2091 if (netdev_deconf[netdev->type](handler, netdev)) {
2092 WARN("failed to destroy netdev");
2093 }
2094
2095 /* Recent kernel remove the virtual interfaces when the network
2096 * namespace is destroyed but in case we did not moved the
2097 * interface to the network namespace, we have to destroy it
2098 */
2099 if (netdev->ifindex != 0 &&
2100 lxc_netdev_delete_by_index(netdev->ifindex))
2101 WARN("failed to remove interface '%s'", netdev->name);
2102 }
2103 }
2104
2105 int lxc_assign_network(struct lxc_list *network, pid_t pid)
2106 {
2107 struct lxc_list *iterator;
2108 struct lxc_netdev *netdev;
2109 int err;
2110
2111 lxc_list_for_each(iterator, network) {
2112
2113 netdev = iterator->elem;
2114
2115 /* empty network namespace, nothing to move */
2116 if (!netdev->ifindex)
2117 continue;
2118
2119 err = lxc_netdev_move_by_index(netdev->ifindex, pid);
2120 if (err) {
2121 ERROR("failed to move '%s' to the container : %s",
2122 netdev->link, strerror(-err));
2123 return -1;
2124 }
2125
2126 DEBUG("move '%s' to '%d'", netdev->name, pid);
2127 }
2128
2129 return 0;
2130 }
2131
2132 int lxc_find_gateway_addresses(struct lxc_handler *handler)
2133 {
2134 struct lxc_list *network = &handler->conf->network;
2135 struct lxc_list *iterator;
2136 struct lxc_netdev *netdev;
2137 int link_index;
2138
2139 lxc_list_for_each(iterator, network) {
2140 netdev = iterator->elem;
2141
2142 if (!netdev->ipv4_gateway_auto && !netdev->ipv6_gateway_auto)
2143 continue;
2144
2145 if (netdev->type != LXC_NET_VETH && netdev->type != LXC_NET_MACVLAN) {
2146 ERROR("gateway = auto only supported for "
2147 "veth and macvlan");
2148 return -1;
2149 }
2150
2151 if (!netdev->link) {
2152 ERROR("gateway = auto needs a link interface");
2153 return -1;
2154 }
2155
2156 link_index = if_nametoindex(netdev->link);
2157 if (!link_index)
2158 return -EINVAL;
2159
2160 if (netdev->ipv4_gateway_auto) {
2161 if (lxc_ipv4_addr_get(link_index, &netdev->ipv4_gateway)) {
2162 ERROR("failed to automatically find ipv4 gateway "
2163 "address from link interface '%s'", netdev->link);
2164 return -1;
2165 }
2166 }
2167
2168 if (netdev->ipv6_gateway_auto) {
2169 if (lxc_ipv6_addr_get(link_index, &netdev->ipv6_gateway)) {
2170 ERROR("failed to automatically find ipv6 gateway "
2171 "address from link interface '%s'", netdev->link);
2172 return -1;
2173 }
2174 }
2175 }
2176
2177 return 0;
2178 }
2179
2180 int lxc_create_tty(const char *name, struct lxc_conf *conf)
2181 {
2182 struct lxc_tty_info *tty_info = &conf->tty_info;
2183 int i;
2184
2185 /* no tty in the configuration */
2186 if (!conf->tty)
2187 return 0;
2188
2189 tty_info->pty_info =
2190 malloc(sizeof(*tty_info->pty_info)*conf->tty);
2191 if (!tty_info->pty_info) {
2192 SYSERROR("failed to allocate pty_info");
2193 return -1;
2194 }
2195
2196 for (i = 0; i < conf->tty; i++) {
2197
2198 struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
2199
2200 if (openpty(&pty_info->master, &pty_info->slave,
2201 pty_info->name, NULL, NULL)) {
2202 SYSERROR("failed to create pty #%d", i);
2203 tty_info->nbtty = i;
2204 lxc_delete_tty(tty_info);
2205 return -1;
2206 }
2207
2208 DEBUG("allocated pty '%s' (%d/%d)",
2209 pty_info->name, pty_info->master, pty_info->slave);
2210
2211 /* Prevent leaking the file descriptors to the container */
2212 fcntl(pty_info->master, F_SETFD, FD_CLOEXEC);
2213 fcntl(pty_info->slave, F_SETFD, FD_CLOEXEC);
2214
2215 pty_info->busy = 0;
2216 }
2217
2218 tty_info->nbtty = conf->tty;
2219
2220 INFO("tty's configured");
2221
2222 return 0;
2223 }
2224
2225 void lxc_delete_tty(struct lxc_tty_info *tty_info)
2226 {
2227 int i;
2228
2229 for (i = 0; i < tty_info->nbtty; i++) {
2230 struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
2231
2232 close(pty_info->master);
2233 close(pty_info->slave);
2234 }
2235
2236 free(tty_info->pty_info);
2237 tty_info->nbtty = 0;
2238 }
2239
2240 int lxc_setup(const char *name, struct lxc_conf *lxc_conf)
2241 {
2242 #if HAVE_APPARMOR /* || HAVE_SMACK || HAVE_SELINUX */
2243 int mounted;
2244 #endif
2245
2246 if (setup_utsname(lxc_conf->utsname)) {
2247 ERROR("failed to setup the utsname for '%s'", name);
2248 return -1;
2249 }
2250
2251 if (setup_network(&lxc_conf->network)) {
2252 ERROR("failed to setup the network for '%s'", name);
2253 return -1;
2254 }
2255
2256 if (run_lxc_hooks(name, "pre-mount", lxc_conf)) {
2257 ERROR("failed to run pre-mount hooks for container '%s'.", name);
2258 return -1;
2259 }
2260
2261 if (setup_rootfs(&lxc_conf->rootfs)) {
2262 ERROR("failed to setup rootfs for '%s'", name);
2263 return -1;
2264 }
2265
2266 if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab, name)) {
2267 ERROR("failed to setup the mounts for '%s'", name);
2268 return -1;
2269 }
2270
2271 if (setup_mount_entries(&lxc_conf->rootfs, &lxc_conf->mount_list, name)) {
2272 ERROR("failed to setup the mount entries for '%s'", name);
2273 return -1;
2274 }
2275
2276 if (run_lxc_hooks(name, "mount", lxc_conf)) {
2277 ERROR("failed to run mount hooks for container '%s'.", name);
2278 return -1;
2279 }
2280
2281 if (setup_cgroup(name, &lxc_conf->cgroup)) {
2282 ERROR("failed to setup the cgroups for '%s'", name);
2283 return -1;
2284 }
2285
2286 if (setup_console(&lxc_conf->rootfs, &lxc_conf->console, lxc_conf->ttydir)) {
2287 ERROR("failed to setup the console for '%s'", name);
2288 return -1;
2289 }
2290
2291 if (setup_kmsg(&lxc_conf->rootfs, &lxc_conf->console)) {
2292 ERROR("failed to setup kmsg for '%s'", name);
2293 return -1;
2294 }
2295
2296 if (setup_tty(&lxc_conf->rootfs, &lxc_conf->tty_info, lxc_conf->ttydir)) {
2297 ERROR("failed to setup the ttys for '%s'", name);
2298 return -1;
2299 }
2300
2301 #if HAVE_APPARMOR /* || HAVE_SMACK || HAVE_SELINUX */
2302 INFO("rootfs path is .%s., mount is .%s.", lxc_conf->rootfs.path,
2303 lxc_conf->rootfs.mount);
2304 if (lxc_conf->rootfs.path == NULL || strlen(lxc_conf->rootfs.path) == 0)
2305 mounted = 0;
2306 else
2307 mounted = lsm_mount_proc_if_needed(lxc_conf->rootfs.path, lxc_conf->rootfs.mount);
2308 if (mounted == -1) {
2309 SYSERROR("failed to mount /proc in the container.");
2310 return -1;
2311 } else if (mounted == 1) {
2312 lxc_conf->lsm_umount_proc = 1;
2313 }
2314 #endif
2315
2316 if (setup_pivot_root(&lxc_conf->rootfs)) {
2317 ERROR("failed to set rootfs for '%s'", name);
2318 return -1;
2319 }
2320
2321 if (setup_pts(lxc_conf->pts)) {
2322 ERROR("failed to setup the new pts instance");
2323 return -1;
2324 }
2325
2326 if (setup_personality(lxc_conf->personality)) {
2327 ERROR("failed to setup personality");
2328 return -1;
2329 }
2330
2331 if (setup_caps(&lxc_conf->caps)) {
2332 ERROR("failed to drop capabilities");
2333 return -1;
2334 }
2335
2336 NOTICE("'%s' is setup.", name);
2337
2338 return 0;
2339 }
2340
2341 int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf)
2342 {
2343 int which = -1;
2344 struct lxc_list *it;
2345
2346 if (strcmp(hook, "pre-start") == 0)
2347 which = LXCHOOK_PRESTART;
2348 else if (strcmp(hook, "pre-mount") == 0)
2349 which = LXCHOOK_PREMOUNT;
2350 else if (strcmp(hook, "mount") == 0)
2351 which = LXCHOOK_MOUNT;
2352 else if (strcmp(hook, "start") == 0)
2353 which = LXCHOOK_START;
2354 else if (strcmp(hook, "post-stop") == 0)
2355 which = LXCHOOK_POSTSTOP;
2356 else
2357 return -1;
2358 lxc_list_for_each(it, &conf->hooks[which]) {
2359 int ret;
2360 char *hookname = it->elem;
2361 ret = run_script(name, "lxc", hookname, hook, NULL);
2362 if (ret)
2363 return ret;
2364 }
2365 return 0;
2366 }
2367
2368 static void lxc_remove_nic(struct lxc_list *it)
2369 {
2370 struct lxc_netdev *netdev = it->elem;
2371 struct lxc_list *it2;
2372
2373 lxc_list_del(it);
2374
2375 if (netdev->link)
2376 free(netdev->link);
2377 if (netdev->name)
2378 free(netdev->name);
2379 if (netdev->upscript)
2380 free(netdev->upscript);
2381 if (netdev->hwaddr)
2382 free(netdev->hwaddr);
2383 if (netdev->mtu)
2384 free(netdev->mtu);
2385 if (netdev->ipv4_gateway)
2386 free(netdev->ipv4_gateway);
2387 if (netdev->ipv6_gateway)
2388 free(netdev->ipv6_gateway);
2389 lxc_list_for_each(it2, &netdev->ipv4) {
2390 lxc_list_del(it2);
2391 free(it2->elem);
2392 free(it2);
2393 }
2394 lxc_list_for_each(it2, &netdev->ipv6) {
2395 lxc_list_del(it2);
2396 free(it2->elem);
2397 free(it2);
2398 }
2399 free(it);
2400 }
2401
2402 /* we get passed in something like '0', '0.ipv4' or '1.ipv6' */
2403 int lxc_clear_nic(struct lxc_conf *c, char *key)
2404 {
2405 char *p1;
2406 int ret, idx, i;
2407 struct lxc_list *it;
2408 struct lxc_netdev *netdev;
2409
2410 p1 = index(key, '.');
2411 if (!p1 || *(p1+1) == '\0')
2412 p1 = NULL;
2413
2414 ret = sscanf(key, "%d", &idx);
2415 if (ret != 1) return -1;
2416 if (idx < 0)
2417 return -1;
2418
2419 i = 0;
2420 lxc_list_for_each(it, &c->network) {
2421 if (i == idx)
2422 break;
2423 i++;
2424 }
2425 if (i < idx) // we don't have that many nics defined
2426 return -1;
2427
2428 if (!it || !it->elem)
2429 return -1;
2430
2431 netdev = it->elem;
2432
2433 if (!p1) {
2434 lxc_remove_nic(it);
2435 } else if (strcmp(p1, "ipv4") == 0) {
2436 struct lxc_list *it2;
2437 lxc_list_for_each(it2, &netdev->ipv4) {
2438 lxc_list_del(it2);
2439 free(it2->elem);
2440 free(it2);
2441 }
2442 } else if (strcmp(p1, "ipv6") == 0) {
2443 struct lxc_list *it2;
2444 lxc_list_for_each(it2, &netdev->ipv6) {
2445 lxc_list_del(it2);
2446 free(it2->elem);
2447 free(it2);
2448 }
2449 } else if (strcmp(p1, "link") == 0) {
2450 if (netdev->link) {
2451 free(netdev->link);
2452 netdev->link = NULL;
2453 }
2454 } else if (strcmp(p1, "name") == 0) {
2455 if (netdev->name) {
2456 free(netdev->name);
2457 netdev->name = NULL;
2458 }
2459 } else if (strcmp(p1, "script.up") == 0) {
2460 if (netdev->upscript) {
2461 free(netdev->upscript);
2462 netdev->upscript = NULL;
2463 }
2464 } else if (strcmp(p1, "hwaddr") == 0) {
2465 if (netdev->hwaddr) {
2466 free(netdev->hwaddr);
2467 netdev->hwaddr = NULL;
2468 }
2469 } else if (strcmp(p1, "mtu") == 0) {
2470 if (netdev->mtu) {
2471 free(netdev->mtu);
2472 netdev->mtu = NULL;
2473 }
2474 } else if (strcmp(p1, "ipv4_gateway") == 0) {
2475 if (netdev->ipv4_gateway) {
2476 free(netdev->ipv4_gateway);
2477 netdev->ipv4_gateway = NULL;
2478 }
2479 } else if (strcmp(p1, "ipv6_gateway") == 0) {
2480 if (netdev->ipv6_gateway) {
2481 free(netdev->ipv6_gateway);
2482 netdev->ipv6_gateway = NULL;
2483 }
2484 }
2485 else return -1;
2486
2487 return 0;
2488 }
2489
2490 int lxc_clear_config_network(struct lxc_conf *c)
2491 {
2492 struct lxc_list *it;
2493 lxc_list_for_each(it, &c->network) {
2494 lxc_remove_nic(it);
2495 }
2496 return 0;
2497 }
2498
2499 int lxc_clear_config_caps(struct lxc_conf *c)
2500 {
2501 struct lxc_list *it;
2502
2503 lxc_list_for_each(it, &c->caps) {
2504 lxc_list_del(it);
2505 free(it->elem);
2506 free(it);
2507 }
2508 return 0;
2509 }
2510
2511 int lxc_clear_cgroups(struct lxc_conf *c, char *key)
2512 {
2513 struct lxc_list *it;
2514 bool all = false;
2515 char *k = key + 11;
2516
2517 if (strcmp(key, "lxc.cgroup") == 0)
2518 all = true;
2519
2520 lxc_list_for_each(it, &c->cgroup) {
2521 struct lxc_cgroup *cg = it->elem;
2522 if (!all && strcmp(cg->subsystem, k) != 0)
2523 continue;
2524 lxc_list_del(it);
2525 free(cg->subsystem);
2526 free(cg->value);
2527 free(cg);
2528 free(it);
2529 }
2530 return 0;
2531 }
2532
2533 int lxc_clear_mount_entries(struct lxc_conf *c)
2534 {
2535 struct lxc_list *it;
2536
2537 lxc_list_for_each(it, &c->mount_list) {
2538 lxc_list_del(it);
2539 free(it->elem);
2540 free(it);
2541 }
2542 return 0;
2543 }
2544
2545 int lxc_clear_hooks(struct lxc_conf *c, char *key)
2546 {
2547 struct lxc_list *it;
2548 bool all = false, done = false;
2549 char *k = key + 9;
2550 int i;
2551
2552 if (strcmp(key, "lxc.hook") == 0)
2553 all = true;
2554
2555 for (i=0; i<NUM_LXC_HOOKS; i++) {
2556 if (all || strcmp(k, lxchook_names[i]) == 0) {
2557 lxc_list_for_each(it, &c->hooks[i]) {
2558 lxc_list_del(it);
2559 free(it->elem);
2560 free(it);
2561 }
2562 done = true;
2563 }
2564 }
2565
2566 if (!done) {
2567 ERROR("Invalid hook key: %s", key);
2568 return -1;
2569 }
2570 return 0;
2571 }
2572
2573 void lxc_conf_free(struct lxc_conf *conf)
2574 {
2575 if (!conf)
2576 return;
2577 if (conf->console.path)
2578 free(conf->console.path);
2579 if (strcmp(conf->rootfs.mount, LXCROOTFSMOUNT) != 0)
2580 free(conf->rootfs.mount);
2581 lxc_clear_config_network(conf);
2582 #if HAVE_APPARMOR
2583 if (conf->aa_profile)
2584 free(conf->aa_profile);
2585 #endif
2586 lxc_clear_config_caps(conf);
2587 lxc_clear_cgroups(conf, "lxc.cgroup");
2588 lxc_clear_hooks(conf, "lxc.hook");
2589 lxc_clear_mount_entries(conf);
2590 free(conf);
2591 }