1 /***
2 This file is part of eudev, forked from systemd.
3
4 Copyright 2011 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <string.h>
21 #include <errno.h>
22 #include <unistd.h>
23
24 #include "util.h"
25 #include "process-util.h"
26 #include "virt.h"
27 #include "fileio.h"
28
detect_container(const char ** id)29 int detect_container(const char **id) {
30
31 static thread_local int cached_found = -1;
32 static thread_local const char *cached_id = NULL;
33
34 _cleanup_free_ char *m = NULL;
35 const char *_id = NULL, *e = NULL;
36 int r;
37
38 if (_likely_(cached_found >= 0)) {
39
40 if (id)
41 *id = cached_id;
42
43 return cached_found;
44 }
45
46 /* /proc/vz exists in container and outside of the container,
47 * /proc/bc only outside of the container. */
48 if (access("/proc/vz", F_OK) >= 0 &&
49 access("/proc/bc", F_OK) < 0) {
50 _id = "openvz";
51 r = 1;
52 goto finish;
53 }
54
55 if (getpid() == 1) {
56 /* If we are PID 1 we can just check our own
57 * environment variable */
58
59 e = getenv("container");
60 if (isempty(e)) {
61 r = 0;
62 goto finish;
63 }
64 } else {
65
66 /* Otherwise, PID 1 dropped this information into a
67 * file in UDEV_ROOT_RUN. This is better than accessing
68 * /proc/1/environ, since we don't need CAP_SYS_PTRACE
69 * for that. */
70
71 r = read_one_line_file(UDEV_ROOT_RUN "/systemd/container", &m);
72 if (r == -ENOENT) {
73 r = 0;
74 goto finish;
75 }
76 if (r < 0)
77 return r;
78
79 e = m;
80 }
81
82 /* We only recognize a selected few here, since we want to
83 * enforce a redacted namespace */
84 if (streq(e, "lxc"))
85 _id ="lxc";
86 else if (streq(e, "lxc-libvirt"))
87 _id = "lxc-libvirt";
88 else if (streq(e, "systemd-nspawn"))
89 _id = "systemd-nspawn";
90 else if (streq(e, "docker"))
91 _id = "docker";
92 else
93 _id = "other";
94
95 r = 1;
96
97 finish:
98 cached_found = r;
99
100 cached_id = _id;
101 if (id)
102 *id = _id;
103
104 return r;
105 }
106