#include "dev-setup.h"
#include "fd-util.h"
#include "fs-util.h"
+#include "label.h"
#include "loop-util.h"
#include "loopback-setup.h"
#include "missing.h"
MountEntry *m, *mounts = NULL;
size_t root_hash_size = 0;
bool make_slave = false;
+ const char *root;
unsigned n_mounts;
int r = 0;
r = dissected_image_decrypt(dissected_image, NULL, root_hash, root_hash_size, dissect_image_flags, &decrypted_image);
if (r < 0)
return r;
-
- if (!root_directory) {
- /* Create a mount point for the image, if it's still missing. We use the same mount point for
- * all images, which is safe, since they all live in their own namespaces after all, and hence
- * won't see each other. */
- root_directory = "/run/systemd/unit-root";
- (void) mkdir(root_directory, 0700);
- }
}
+ if (root_directory)
+ root = root_directory;
+ else if (root_image || n_bind_mounts > 0) {
+
+ /* If we are booting from an image, create a mount point for the image, if it's still missing. We use
+ * the same mount point for all images, which is safe, since they all live in their own namespaces
+ * after all, and hence won't see each other. We also use such a root directory whenever there are bind
+ * mounts configured, so that their source mounts are never obstructed by mounts we already applied
+ * while we are applying them. */
+
+ root = "/run/systemd/unit-root";
+ (void) mkdir_label(root, 0700);
+ } else
+ root = NULL;
+
n_mounts = namespace_calculate_mounts(
- root_directory,
+ root,
ns_info,
read_write_paths,
read_only_paths,
protect_home, protect_system);
/* Set mount slave mode */
- if (root_directory || n_mounts > 0)
+ if (root || n_mounts > 0)
make_slave = true;
if (n_mounts > 0) {
if (r < 0)
goto finish;
- if (namespace_info_mount_apivfs(root_directory, ns_info)) {
+ if (namespace_info_mount_apivfs(root, ns_info)) {
r = append_static_mounts(&m, apivfs_table, ELEMENTSOF(apivfs_table), ns_info->ignore_protect_paths);
if (r < 0)
goto finish;
assert(mounts + n_mounts == m);
/* Prepend the root directory where that's necessary */
- r = prefix_where_needed(mounts, n_mounts, root_directory);
+ r = prefix_where_needed(mounts, n_mounts, root);
if (r < 0)
goto finish;
qsort(mounts, n_mounts, sizeof(MountEntry), mount_path_compare);
drop_duplicates(mounts, &n_mounts);
- drop_outside_root(root_directory, mounts, &n_mounts);
+ drop_outside_root(root, mounts, &n_mounts);
drop_inaccessible(mounts, &n_mounts);
drop_nop(mounts, &n_mounts);
}
}
/* Try to set up the new root directory before mounting anything there */
- if (root_directory)
- (void) base_filesystem_create(root_directory, UID_INVALID, GID_INVALID);
+ if (root)
+ (void) base_filesystem_create(root, UID_INVALID, GID_INVALID);
if (root_image) {
- r = dissected_image_mount(dissected_image, root_directory, dissect_image_flags);
+ /* A root image is specified, mount it to the right place */
+ r = dissected_image_mount(dissected_image, root, dissect_image_flags);
if (r < 0)
goto finish;
} else if (root_directory) {
- /* Turn directory into bind mount, if it isn't one yet */
- r = path_is_mount_point(root_directory, NULL, AT_SYMLINK_FOLLOW);
+ /* A root directory is specified. Turn its directory into bind mount, if it isn't one yet. */
+ r = path_is_mount_point(root, NULL, AT_SYMLINK_FOLLOW);
if (r < 0)
goto finish;
if (r == 0) {
- if (mount(root_directory, root_directory, NULL, MS_BIND|MS_REC, NULL) < 0) {
+ if (mount(root, root, NULL, MS_BIND|MS_REC, NULL) < 0) {
r = -errno;
goto finish;
}
}
+
+ } else if (root) {
+
+ /* Let's mount the main root directory to the root directory to use */
+ if (mount("/", root, NULL, MS_BIND|MS_REC, NULL) < 0) {
+ r = -errno;
+ goto finish;
+ }
}
if (n_mounts > 0) {
/* First round, add in all special mounts we need */
for (m = mounts; m < mounts + n_mounts; ++m) {
- r = apply_mount(root_directory, m, tmp_dir, var_tmp_dir);
+ r = apply_mount(root, m, tmp_dir, var_tmp_dir);
if (r < 0)
goto finish;
}
}
}
- if (root_directory) {
+ if (root) {
/* MS_MOVE does not work on MS_SHARED so the remount MS_SHARED will be done later */
- r = mount_move_root(root_directory);
+ r = mount_move_root(root);
if (r < 0)
goto finish;
}