• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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