diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/loopback-setup.c | 274 | ||||
-rw-r--r-- | src/shared/loopback-setup.h | 27 | ||||
-rw-r--r-- | src/shared/machine-id-setup.c | 265 | ||||
-rw-r--r-- | src/shared/machine-id-setup.h | 27 | ||||
-rw-r--r-- | src/shared/mount-setup.c | 423 | ||||
-rw-r--r-- | src/shared/mount-setup.h | 36 |
6 files changed, 0 insertions, 1052 deletions
diff --git a/src/shared/loopback-setup.c b/src/shared/loopback-setup.c deleted file mode 100644 index 46c1fc843a..0000000000 --- a/src/shared/loopback-setup.c +++ /dev/null @@ -1,274 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <errno.h> -#include <sys/socket.h> -#include <net/if.h> -#include <asm/types.h> -#include <netinet/in.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> - -#include "util.h" -#include "macro.h" -#include "loopback-setup.h" -#include "socket-util.h" - -#define NLMSG_TAIL(nmsg) \ - ((struct rtattr *) (((uint8_t*) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) - -static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type, const void *data, size_t data_length) { - size_t length; - struct rtattr *rta; - - length = RTA_LENGTH(data_length); - - if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length) - return -E2BIG; - - rta = NLMSG_TAIL(n); - rta->rta_type = type; - rta->rta_len = length; - memcpy(RTA_DATA(rta), data, data_length); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length); - - return 0; -} - -static ssize_t sendto_loop(int fd, const void *buf, size_t buf_len, int flags, const struct sockaddr *sa, socklen_t sa_len) { - - for (;;) { - ssize_t l; - - if ((l = sendto(fd, buf, buf_len, flags, sa, sa_len)) >= 0) - return l; - - if (errno != EINTR) - return -errno; - } -} - -static ssize_t recvfrom_loop(int fd, void *buf, size_t buf_len, int flags, struct sockaddr *sa, socklen_t *sa_len) { - - for (;;) { - ssize_t l; - - if ((l = recvfrom(fd, buf, buf_len, flags, sa, sa_len)) >= 0) - return l; - - if (errno != EINTR) - return -errno; - } -} - -static int add_adresses(int fd, int if_loopback, unsigned *requests) { - union { - struct sockaddr sa; - struct sockaddr_nl nl; - } sa; - union { - struct nlmsghdr header; - uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct ifaddrmsg)) + - RTA_LENGTH(sizeof(struct in6_addr))]; - } request; - - struct ifaddrmsg *ifaddrmsg; - uint32_t ipv4_address = htonl(INADDR_LOOPBACK); - int r; - - zero(request); - - request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - request.header.nlmsg_type = RTM_NEWADDR; - request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK; - request.header.nlmsg_seq = *requests + 1; - - ifaddrmsg = NLMSG_DATA(&request.header); - ifaddrmsg->ifa_family = AF_INET; - ifaddrmsg->ifa_prefixlen = 8; - ifaddrmsg->ifa_flags = IFA_F_PERMANENT; - ifaddrmsg->ifa_scope = RT_SCOPE_HOST; - ifaddrmsg->ifa_index = if_loopback; - - if ((r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &ipv4_address, sizeof(ipv4_address))) < 0) - return r; - - zero(sa); - sa.nl.nl_family = AF_NETLINK; - - if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0) - return -errno; - (*requests)++; - - if (!socket_ipv6_is_supported()) - return 0; - - request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - request.header.nlmsg_seq = *requests + 1; - - ifaddrmsg->ifa_family = AF_INET6; - ifaddrmsg->ifa_prefixlen = 128; - - if ((r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &in6addr_loopback, sizeof(in6addr_loopback))) < 0) - return r; - - if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0) - return -errno; - (*requests)++; - - return 0; -} - -static int start_interface(int fd, int if_loopback, unsigned *requests) { - union { - struct sockaddr sa; - struct sockaddr_nl nl; - } sa; - union { - struct nlmsghdr header; - uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct ifinfomsg))]; - } request; - - struct ifinfomsg *ifinfomsg; - - zero(request); - - request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - request.header.nlmsg_type = RTM_NEWLINK; - request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; - request.header.nlmsg_seq = *requests + 1; - - ifinfomsg = NLMSG_DATA(&request.header); - ifinfomsg->ifi_family = AF_UNSPEC; - ifinfomsg->ifi_index = if_loopback; - ifinfomsg->ifi_flags = IFF_UP; - ifinfomsg->ifi_change = IFF_UP; - - zero(sa); - sa.nl.nl_family = AF_NETLINK; - - if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0) - return -errno; - - (*requests)++; - - return 0; -} - -static int read_response(int fd, unsigned requests_max) { - union { - struct sockaddr sa; - struct sockaddr_nl nl; - } sa; - union { - struct nlmsghdr header; - uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct nlmsgerr))]; - } response; - - ssize_t l; - socklen_t sa_len = sizeof(sa); - struct nlmsgerr *nlmsgerr; - - if ((l = recvfrom_loop(fd, &response, sizeof(response), 0, &sa.sa, &sa_len)) < 0) - return -errno; - - if (sa_len != sizeof(sa.nl) || - sa.nl.nl_family != AF_NETLINK) - return -EIO; - - if (sa.nl.nl_pid != 0) - return 0; - - if ((size_t) l < sizeof(struct nlmsghdr)) - return -EIO; - - if (response.header.nlmsg_type != NLMSG_ERROR || - (pid_t) response.header.nlmsg_pid != getpid() || - response.header.nlmsg_seq >= requests_max) - return 0; - - if ((size_t) l < NLMSG_LENGTH(sizeof(struct nlmsgerr)) || - response.header.nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) - return -EIO; - - nlmsgerr = NLMSG_DATA(&response.header); - - if (nlmsgerr->error < 0 && nlmsgerr->error != -EEXIST) { - log_warning("Netlink failure for request %i: %s", response.header.nlmsg_seq, strerror(-nlmsgerr->error)); - return nlmsgerr->error; - } - - return response.header.nlmsg_seq; -} - -int loopback_setup(void) { - int r, if_loopback; - union { - struct sockaddr sa; - struct sockaddr_nl nl; - struct sockaddr_storage storage; - } sa; - unsigned requests = 0, i; - int fd; - - errno = 0; - if ((if_loopback = (int) if_nametoindex("lo")) <= 0) - return errno ? -errno : -ENODEV; - - if ((fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) - return -errno; - - zero(sa); - sa.nl.nl_family = AF_NETLINK; - - if (bind(fd, &sa.sa, sizeof(sa)) < 0) { - r = -errno; - goto finish; - } - - if ((r = add_adresses(fd, if_loopback, &requests)) < 0) - goto finish; - - if ((r = start_interface(fd, if_loopback, &requests)) < 0) - goto finish; - - for (i = 0; i < requests; i++) { - if ((r = read_response(fd, requests)) < 0) - goto finish; - } - - r = 0; - -finish: - if (r < 0) - log_warning("Failed to configure loopback device: %s", strerror(-r)); - - if (fd >= 0) - close_nointr_nofail(fd); - - return r; -} diff --git a/src/shared/loopback-setup.h b/src/shared/loopback-setup.h deleted file mode 100644 index cbb969e1e4..0000000000 --- a/src/shared/loopback-setup.h +++ /dev/null @@ -1,27 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#ifndef fooloopbacksetuphfoo -#define fooloopbacksetuphfoo - -/*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -int loopback_setup(void); - -#endif diff --git a/src/shared/machine-id-setup.c b/src/shared/machine-id-setup.c deleted file mode 100644 index 9e84ac0cb9..0000000000 --- a/src/shared/machine-id-setup.c +++ /dev/null @@ -1,265 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <fcntl.h> -#include <sys/mount.h> - -#include <systemd/sd-id128.h> - -#include "machine-id-setup.h" -#include "macro.h" -#include "util.h" -#include "mkdir.h" -#include "log.h" -#include "virt.h" - -static int shorten_uuid(char destination[36], const char *source) { - unsigned i, j; - - for (i = 0, j = 0; i < 36 && j < 32; i++) { - int t; - - t = unhexchar(source[i]); - if (t < 0) - continue; - - destination[j++] = hexchar(t); - } - - if (i == 36 && j == 32) { - destination[32] = '\n'; - destination[33] = 0; - return 0; - } - - return -EINVAL; -} - -static int generate(char id[34]) { - int fd, r; - unsigned char *p; - sd_id128_t buf; - char *q; - ssize_t k; - const char *vm_id; - - assert(id); - - /* First, try reading the D-Bus machine id, unless it is a symlink */ - fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); - if (fd >= 0) { - - k = loop_read(fd, id, 32, false); - close_nointr_nofail(fd); - - if (k >= 32) { - id[32] = '\n'; - id[33] = 0; - - log_info("Initializing machine ID from D-Bus machine ID."); - return 0; - } - } - - /* If that didn't work, see if we are running in qemu/kvm and a - * machine ID was passed in via -uuid on the qemu/kvm command - * line */ - - r = detect_vm(&vm_id); - if (r > 0 && streq(vm_id, "kvm")) { - char uuid[37]; - - fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); - if (fd >= 0) { - k = loop_read(fd, uuid, 36, false); - close_nointr_nofail(fd); - - if (k >= 36) { - r = shorten_uuid(id, uuid); - if (r >= 0) { - log_info("Initializing machine ID from KVM UUID"); - return 0; - } - } - } - } - - /* If that didn't work either, see if we are running in a - * container, and a machine ID was passed in via - * $container_uuid the way libvirt/LXC does it */ - - r = detect_container(NULL); - if (r > 0) { - FILE *f; - - f = fopen("/proc/1/environ", "re"); - if (f) { - bool done = false; - - do { - char line[LINE_MAX]; - unsigned i; - - for (i = 0; i < sizeof(line)-1; i++) { - int c; - - c = getc(f); - if (_unlikely_(c == EOF)) { - done = true; - break; - } else if (c == 0) - break; - - line[i] = c; - } - line[i] = 0; - - if (startswith(line, "container_uuid=") && - strlen(line + 15) >= 36) { - r = shorten_uuid(id, line + 15); - if (r >= 0) { - log_info("Initializing machine ID from container UUID"); - return 0; - } - } - - } while (!done); - - fclose(f); - } - } - - /* If that didn't work, generate a random machine id */ - r = sd_id128_randomize(&buf); - if (r < 0) { - log_error("Failed to open /dev/urandom: %s", strerror(-r)); - return r; - } - - for (p = buf.bytes, q = id; p < buf.bytes + sizeof(buf); p++, q += 2) { - q[0] = hexchar(*p >> 4); - q[1] = hexchar(*p & 15); - } - - id[32] = '\n'; - id[33] = 0; - - log_info("Initializing machine ID from random generator."); - - return 0; -} - -int machine_id_setup(void) { - int fd, r; - bool writable; - struct stat st; - char id[34]; /* 32 + \n + \0 */ - mode_t m; - - m = umask(0000); - - /* We create this 0444, to indicate that this isn't really - * something you should ever modify. Of course, since the file - * will be owned by root it doesn't matter much, but maybe - * people look. */ - - fd = open("/etc/machine-id", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444); - if (fd >= 0) - writable = true; - else { - fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY); - if (fd < 0) { - umask(m); - log_error("Cannot open /etc/machine-id: %m"); - return -errno; - } - - writable = false; - } - - umask(m); - - if (fstat(fd, &st) < 0) { - log_error("fstat() failed: %m"); - r = -errno; - goto finish; - } - - if (S_ISREG(st.st_mode)) { - if (loop_read(fd, id, 32, false) >= 32) { - r = 0; - goto finish; - } - } - - /* Hmm, so, the id currently stored is not useful, then let's - * generate one */ - - r = generate(id); - if (r < 0) - goto finish; - - if (S_ISREG(st.st_mode) && writable) { - lseek(fd, 0, SEEK_SET); - - if (loop_write(fd, id, 33, false) == 33) { - r = 0; - goto finish; - } - } - - close_nointr_nofail(fd); - fd = -1; - - /* Hmm, we couldn't write it? So let's write it to - * /run/machine-id as a replacement */ - - m = umask(0022); - r = write_one_line_file("/run/machine-id", id); - umask(m); - - if (r < 0) { - log_error("Cannot write /run/machine-id: %s", strerror(-r)); - - unlink("/run/machine-id"); - goto finish; - } - - /* And now, let's mount it over */ - r = mount("/run/machine-id", "/etc/machine-id", "bind", MS_BIND|MS_RDONLY, NULL) < 0 ? -errno : 0; - if (r < 0) { - unlink("/run/machine-id"); - log_error("Failed to mount /etc/machine-id: %s", strerror(-r)); - } else - log_info("Installed transient /etc/machine-id file."); - -finish: - - if (fd >= 0) - close_nointr_nofail(fd); - - return r; -} diff --git a/src/shared/machine-id-setup.h b/src/shared/machine-id-setup.h deleted file mode 100644 index 16f45d86d3..0000000000 --- a/src/shared/machine-id-setup.h +++ /dev/null @@ -1,27 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#ifndef foomachineidsetuphfoo -#define foomachineidsetuphfoo - -/*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -int machine_id_setup(void); - -#endif diff --git a/src/shared/mount-setup.c b/src/shared/mount-setup.c deleted file mode 100644 index 52fe523674..0000000000 --- a/src/shared/mount-setup.c +++ /dev/null @@ -1,423 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <sys/mount.h> -#include <errno.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <string.h> -#include <libgen.h> -#include <assert.h> -#include <unistd.h> -#include <ftw.h> - -#include "mount-setup.h" -#include "log.h" -#include "macro.h" -#include "util.h" -#include "label.h" -#include "set.h" -#include "strv.h" -#include "mkdir.h" - -#ifndef TTY_GID -#define TTY_GID 5 -#endif - -typedef struct MountPoint { - const char *what; - const char *where; - const char *type; - const char *options; - unsigned long flags; - bool fatal; -} MountPoint; - -/* The first three entries we might need before SELinux is up. The - * fourth (securityfs) is needed by IMA to load a custom policy. The - * other ones we can delay until SELinux and IMA are loaded. */ -#define N_EARLY_MOUNT 4 - -static const MountPoint mount_table[] = { - { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, - { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, - { "devtmpfs", "/dev", "devtmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true }, - { "securityfs", "/sys/kernel/security", "securityfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, false }, - { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true }, - { "devpts", "/dev/pts", "devpts", "mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, false }, - { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true }, - { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, false }, - { "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, false }, -}; - -/* These are API file systems that might be mounted by other software, - * we just list them here so that we know that we should ignore them */ - -static const char * const ignore_paths[] = { - "/sys/fs/selinux", - "/selinux", - "/proc/bus/usb" -}; - -bool mount_point_is_api(const char *path) { - unsigned i; - - /* Checks if this mount point is considered "API", and hence - * should be ignored */ - - for (i = 0; i < ELEMENTSOF(mount_table); i ++) - if (path_equal(path, mount_table[i].where)) - return true; - - return path_startswith(path, "/sys/fs/cgroup/"); -} - -bool mount_point_ignore(const char *path) { - unsigned i; - - for (i = 0; i < ELEMENTSOF(ignore_paths); i++) - if (path_equal(path, ignore_paths[i])) - return true; - - return false; -} - -static int mount_one(const MountPoint *p, bool relabel) { - int r; - - assert(p); - - /* Relabel first, just in case */ - if (relabel) - label_fix(p->where, true); - - if ((r = path_is_mount_point(p->where, true)) < 0) - return r; - - if (r > 0) - return 0; - - /* The access mode here doesn't really matter too much, since - * the mounted file system will take precedence anyway. */ - mkdir_p(p->where, 0755); - - log_debug("Mounting %s to %s of type %s with options %s.", - p->what, - p->where, - p->type, - strna(p->options)); - - if (mount(p->what, - p->where, - p->type, - p->flags, - p->options) < 0) { - log_error("Failed to mount %s: %s", p->where, strerror(errno)); - return p->fatal ? -errno : 0; - } - - /* Relabel again, since we now mounted something fresh here */ - if (relabel) - label_fix(p->where, false); - - return 1; -} - -int mount_setup_early(void) { - unsigned i; - int r = 0; - - assert_cc(N_EARLY_MOUNT <= ELEMENTSOF(mount_table)); - - /* Do a minimal mount of /proc and friends to enable the most - * basic stuff, such as SELinux */ - for (i = 0; i < N_EARLY_MOUNT; i ++) { - int j; - - j = mount_one(mount_table + i, false); - if (r == 0) - r = j; - } - - return r; -} - -int mount_cgroup_controllers(char ***join_controllers) { - int r; - FILE *f; - char buf[LINE_MAX]; - Set *controllers; - - /* Mount all available cgroup controllers that are built into the kernel. */ - - f = fopen("/proc/cgroups", "re"); - if (!f) { - log_error("Failed to enumerate cgroup controllers: %m"); - return 0; - } - - controllers = set_new(string_hash_func, string_compare_func); - if (!controllers) { - r = -ENOMEM; - log_error("Failed to allocate controller set."); - goto finish; - } - - /* Ignore the header line */ - (void) fgets(buf, sizeof(buf), f); - - for (;;) { - char *controller; - int enabled = 0; - - if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) { - - if (feof(f)) - break; - - log_error("Failed to parse /proc/cgroups."); - r = -EIO; - goto finish; - } - - if (!enabled) { - free(controller); - continue; - } - - r = set_put(controllers, controller); - if (r < 0) { - log_error("Failed to add controller to set."); - free(controller); - goto finish; - } - } - - for (;;) { - MountPoint p; - char *controller, *where, *options; - char ***k = NULL; - - controller = set_steal_first(controllers); - if (!controller) - break; - - if (join_controllers) - for (k = join_controllers; *k; k++) - if (strv_find(*k, controller)) - break; - - if (k && *k) { - char **i, **j; - - for (i = *k, j = *k; *i; i++) { - - if (!streq(*i, controller)) { - char *t; - - t = set_remove(controllers, *i); - if (!t) { - free(*i); - continue; - } - free(t); - } - - *(j++) = *i; - } - - *j = NULL; - - options = strv_join(*k, ","); - if (!options) { - log_error("Failed to join options"); - free(controller); - r = -ENOMEM; - goto finish; - } - - } else { - options = controller; - controller = NULL; - } - - where = strappend("/sys/fs/cgroup/", options); - if (!where) { - log_error("Failed to build path"); - free(options); - r = -ENOMEM; - goto finish; - } - - zero(p); - p.what = "cgroup"; - p.where = where; - p.type = "cgroup"; - p.options = options; - p.flags = MS_NOSUID|MS_NOEXEC|MS_NODEV; - p.fatal = false; - - r = mount_one(&p, true); - free(controller); - free(where); - - if (r < 0) { - free(options); - goto finish; - } - - if (r > 0 && k && *k) { - char **i; - - for (i = *k; *i; i++) { - char *t; - - t = strappend("/sys/fs/cgroup/", *i); - if (!t) { - log_error("Failed to build path"); - r = -ENOMEM; - free(options); - goto finish; - } - - r = symlink(options, t); - free(t); - - if (r < 0 && errno != EEXIST) { - log_error("Failed to create symlink: %m"); - r = -errno; - free(options); - goto finish; - } - } - } - - free(options); - } - - r = 0; - -finish: - set_free_free(controllers); - - fclose(f); - - return r; -} - -static int symlink_and_label(const char *old_path, const char *new_path) { - int r; - - assert(old_path); - assert(new_path); - - if ((r = label_symlinkfile_set(new_path)) < 0) - return r; - - if (symlink(old_path, new_path) < 0) - r = -errno; - - label_file_clear(); - - return r; -} - -static int nftw_cb( - const char *fpath, - const struct stat *sb, - int tflag, - struct FTW *ftwbuf) { - - /* No need to label /dev twice in a row... */ - if (_unlikely_(ftwbuf->level == 0)) - return FTW_CONTINUE; - - label_fix(fpath, true); - - /* /run/initramfs is static data and big, no need to - * dynamically relabel its contents at boot... */ - if (_unlikely_(ftwbuf->level == 1 && - tflag == FTW_D && - streq(fpath, "/run/initramfs"))) - return FTW_SKIP_SUBTREE; - - return FTW_CONTINUE; -}; - -int mount_setup(bool loaded_policy) { - - static const char symlinks[] = - "/proc/kcore\0" "/dev/core\0" - "/proc/self/fd\0" "/dev/fd\0" - "/proc/self/fd/0\0" "/dev/stdin\0" - "/proc/self/fd/1\0" "/dev/stdout\0" - "/proc/self/fd/2\0" "/dev/stderr\0"; - - static const char relabel[] = - "/run/initramfs/root-fsck\0" - "/run/initramfs/shutdown\0"; - - int r; - unsigned i; - const char *j, *k; - - for (i = 0; i < ELEMENTSOF(mount_table); i ++) { - r = mount_one(mount_table + i, true); - - if (r < 0) - return r; - } - - /* Nodes in devtmpfs and /run need to be manually updated for - * the appropriate labels, after mounting. The other virtual - * API file systems like /sys and /proc do not need that, they - * use the same label for all their files. */ - if (loaded_policy) { - usec_t before_relabel, after_relabel; - char timespan[FORMAT_TIMESPAN_MAX]; - - before_relabel = now(CLOCK_MONOTONIC); - - nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); - nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); - - /* Explicitly relabel these */ - NULSTR_FOREACH(j, relabel) - label_fix(j, true); - - after_relabel = now(CLOCK_MONOTONIC); - - log_info("Relabelled /dev and /run in %s.", - format_timespan(timespan, sizeof(timespan), after_relabel - before_relabel)); - } - - /* Create a few default symlinks, which are normally created - * by udevd, but some scripts might need them before we start - * udevd. */ - NULSTR_FOREACH_PAIR(j, k, symlinks) - symlink_and_label(j, k); - - /* Create a few directories we always want around */ - label_mkdir("/run/systemd", 0755); - label_mkdir("/run/systemd/system", 0755); - - return 0; -} diff --git a/src/shared/mount-setup.h b/src/shared/mount-setup.h deleted file mode 100644 index 720b66f76c..0000000000 --- a/src/shared/mount-setup.h +++ /dev/null @@ -1,36 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#ifndef foomountsetuphfoo -#define foomountsetuphfoo - -/*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <stdbool.h> - -int mount_setup_early(void); - -int mount_setup(bool loaded_policy); - -int mount_cgroup_controllers(char ***join_controllers); - -bool mount_point_is_api(const char *path); -bool mount_point_ignore(const char *path); - -#endif |