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 29int 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 97finish: 98 cached_found = r; 99 100 cached_id = _id; 101 if (id) 102 *id = _id; 103 104 return r; 105} 106