199ca880aSopenharmony_ci/*** 299ca880aSopenharmony_ci This file is part of eudev, forked from systemd. 399ca880aSopenharmony_ci 499ca880aSopenharmony_ci Copyright 2011 Lennart Poettering 599ca880aSopenharmony_ci 699ca880aSopenharmony_ci systemd is free software; you can redistribute it and/or modify it 799ca880aSopenharmony_ci under the terms of the GNU Lesser General Public License as published by 899ca880aSopenharmony_ci the Free Software Foundation; either version 2.1 of the License, or 999ca880aSopenharmony_ci (at your option) any later version. 1099ca880aSopenharmony_ci 1199ca880aSopenharmony_ci systemd is distributed in the hope that it will be useful, but 1299ca880aSopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1399ca880aSopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1499ca880aSopenharmony_ci Lesser General Public License for more details. 1599ca880aSopenharmony_ci 1699ca880aSopenharmony_ci You should have received a copy of the GNU Lesser General Public License 1799ca880aSopenharmony_ci along with systemd; If not, see <http://www.gnu.org/licenses/>. 1899ca880aSopenharmony_ci***/ 1999ca880aSopenharmony_ci 2099ca880aSopenharmony_ci#include <string.h> 2199ca880aSopenharmony_ci#include <errno.h> 2299ca880aSopenharmony_ci#include <unistd.h> 2399ca880aSopenharmony_ci 2499ca880aSopenharmony_ci#include "util.h" 2599ca880aSopenharmony_ci#include "process-util.h" 2699ca880aSopenharmony_ci#include "virt.h" 2799ca880aSopenharmony_ci#include "fileio.h" 2899ca880aSopenharmony_ci 2999ca880aSopenharmony_ciint detect_container(const char **id) { 3099ca880aSopenharmony_ci 3199ca880aSopenharmony_ci static thread_local int cached_found = -1; 3299ca880aSopenharmony_ci static thread_local const char *cached_id = NULL; 3399ca880aSopenharmony_ci 3499ca880aSopenharmony_ci _cleanup_free_ char *m = NULL; 3599ca880aSopenharmony_ci const char *_id = NULL, *e = NULL; 3699ca880aSopenharmony_ci int r; 3799ca880aSopenharmony_ci 3899ca880aSopenharmony_ci if (_likely_(cached_found >= 0)) { 3999ca880aSopenharmony_ci 4099ca880aSopenharmony_ci if (id) 4199ca880aSopenharmony_ci *id = cached_id; 4299ca880aSopenharmony_ci 4399ca880aSopenharmony_ci return cached_found; 4499ca880aSopenharmony_ci } 4599ca880aSopenharmony_ci 4699ca880aSopenharmony_ci /* /proc/vz exists in container and outside of the container, 4799ca880aSopenharmony_ci * /proc/bc only outside of the container. */ 4899ca880aSopenharmony_ci if (access("/proc/vz", F_OK) >= 0 && 4999ca880aSopenharmony_ci access("/proc/bc", F_OK) < 0) { 5099ca880aSopenharmony_ci _id = "openvz"; 5199ca880aSopenharmony_ci r = 1; 5299ca880aSopenharmony_ci goto finish; 5399ca880aSopenharmony_ci } 5499ca880aSopenharmony_ci 5599ca880aSopenharmony_ci if (getpid() == 1) { 5699ca880aSopenharmony_ci /* If we are PID 1 we can just check our own 5799ca880aSopenharmony_ci * environment variable */ 5899ca880aSopenharmony_ci 5999ca880aSopenharmony_ci e = getenv("container"); 6099ca880aSopenharmony_ci if (isempty(e)) { 6199ca880aSopenharmony_ci r = 0; 6299ca880aSopenharmony_ci goto finish; 6399ca880aSopenharmony_ci } 6499ca880aSopenharmony_ci } else { 6599ca880aSopenharmony_ci 6699ca880aSopenharmony_ci /* Otherwise, PID 1 dropped this information into a 6799ca880aSopenharmony_ci * file in UDEV_ROOT_RUN. This is better than accessing 6899ca880aSopenharmony_ci * /proc/1/environ, since we don't need CAP_SYS_PTRACE 6999ca880aSopenharmony_ci * for that. */ 7099ca880aSopenharmony_ci 7199ca880aSopenharmony_ci r = read_one_line_file(UDEV_ROOT_RUN "/systemd/container", &m); 7299ca880aSopenharmony_ci if (r == -ENOENT) { 7399ca880aSopenharmony_ci r = 0; 7499ca880aSopenharmony_ci goto finish; 7599ca880aSopenharmony_ci } 7699ca880aSopenharmony_ci if (r < 0) 7799ca880aSopenharmony_ci return r; 7899ca880aSopenharmony_ci 7999ca880aSopenharmony_ci e = m; 8099ca880aSopenharmony_ci } 8199ca880aSopenharmony_ci 8299ca880aSopenharmony_ci /* We only recognize a selected few here, since we want to 8399ca880aSopenharmony_ci * enforce a redacted namespace */ 8499ca880aSopenharmony_ci if (streq(e, "lxc")) 8599ca880aSopenharmony_ci _id ="lxc"; 8699ca880aSopenharmony_ci else if (streq(e, "lxc-libvirt")) 8799ca880aSopenharmony_ci _id = "lxc-libvirt"; 8899ca880aSopenharmony_ci else if (streq(e, "systemd-nspawn")) 8999ca880aSopenharmony_ci _id = "systemd-nspawn"; 9099ca880aSopenharmony_ci else if (streq(e, "docker")) 9199ca880aSopenharmony_ci _id = "docker"; 9299ca880aSopenharmony_ci else 9399ca880aSopenharmony_ci _id = "other"; 9499ca880aSopenharmony_ci 9599ca880aSopenharmony_ci r = 1; 9699ca880aSopenharmony_ci 9799ca880aSopenharmony_cifinish: 9899ca880aSopenharmony_ci cached_found = r; 9999ca880aSopenharmony_ci 10099ca880aSopenharmony_ci cached_id = _id; 10199ca880aSopenharmony_ci if (id) 10299ca880aSopenharmony_ci *id = _id; 10399ca880aSopenharmony_ci 10499ca880aSopenharmony_ci return r; 10599ca880aSopenharmony_ci} 106