-/*-*- Mode: C; c-basic-offset: 8 -*-*/
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
#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"
typedef struct MountPoint {
const char *what;
} MountPoint;
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 },
- { "devtmps", "/dev", "devtmpfs", "mode=755", MS_NOSUID, true },
- { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
- { "devpts", "/dev/pts", "devpts", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, false },
- { "cgroup", "/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
- { "debugfs", "/sys/kernel/debug", "debugfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, false },
- { "binfmt_misc", "/proc/sys/fs/binfmt_misc", "binfmt_misc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, false },
- { "mqueue", "/dev/mqueue", "mqueue", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, false },
+ { "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, true },
+ { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
+ { "devpts", "/dev/pts", "devpts", NULL, MS_NOSUID|MS_NOEXEC, false },
+ { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
+ { "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
+};
+
+/* These are API file systems that might be mounted by other software,
+ * we just list them here so that we know that we should igore them */
+
+static const char * const ignore_paths[] = {
+ "/selinux",
+ "/proc/bus/usb",
+ "/var/lib/nfs/rpc_pipefs",
+ "/proc/fs/nfsd"
};
bool mount_point_is_api(const char *path) {
* should be ignored */
for (i = 0; i < ELEMENTSOF(mount_table); i ++)
- if (path_startswith(path, mount_table[i].where))
+ if (path_equal(path, mount_table[i].where))
return true;
- return path_startswith(path, "/cgroup/");
+ for (i = 0; i < ELEMENTSOF(ignore_paths); i++)
+ if (path_equal(path, ignore_paths[i]))
+ return true;
+
+ return path_startswith(path, "/sys/fs/cgroup/");
}
static int mount_one(const MountPoint *p) {
return p->fatal ? -errno : 0;
}
+ label_fix(p->where);
+
return 0;
}
FILE *f;
char buf [256];
- /* Mount all available cgroup controllers. */
+ /* Mount all available cgroup controllers that are built into the kernel. */
if (!(f = fopen("/proc/cgroups", "re")))
return -ENOENT;
goto finish;
}
- if (asprintf(&where, "/cgroup/%s", controller) < 0) {
+ if (asprintf(&where, "/sys/fs/cgroup/%s", controller) < 0) {
free(controller);
r = -ENOMEM;
goto finish;
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) {
+
+ label_fix(fpath);
+ return 0;
+};
+
int mount_setup(void) {
+
+ 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"
+ "\0";
+
int r;
unsigned i;
+ const char *j, *k;
for (i = 0; i < ELEMENTSOF(mount_table); i ++)
if ((r = mount_one(mount_table+i)) < 0)
return r;
+ /* Nodes in devtmpfs need to be manually updated for the
+ * appropriate labels, after mounting. The other virtual API
+ * file systems do not need. */
+
+ if (unlink("/dev/.systemd/relabel-devtmpfs") >= 0)
+ nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS);
+
+ /* Create a few default symlinks, which are normally created
+ * bei udevd, but some scripts might need them before we start
+ * udevd. */
+
+ NULSTR_FOREACH_PAIR(j, k, symlinks)
+ symlink_and_label(j, k);
+
return mount_cgroup_controllers();
}