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