+ assert(what);
+
+ r = mount(what, m->path, NULL, MS_BIND|MS_REC, NULL);
+ if (r >= 0)
+ log_debug("Successfully mounted %s to %s", what, m->path);
+ else if (m->ignore && errno == ENOENT)
+ return 0;
+
+ return r;
+}
+
+static int make_read_only(BindMount *m) {
+ int r;
+
+ assert(m);
+
+ if (IN_SET(m->mode, INACCESSIBLE, READONLY))
+ r = bind_remount_recursive(m->path, true);
+ else if (IN_SET(m->mode, READWRITE, PRIVATE_TMP, PRIVATE_VAR_TMP, PRIVATE_DEV))
+ r = bind_remount_recursive(m->path, false);
+ else
+ r = 0;
+
+ if (m->ignore && r == -ENOENT)
+ return 0;
+
+ return r;
+}
+
+int setup_namespace(
+ char** read_write_dirs,
+ char** read_only_dirs,
+ char** inaccessible_dirs,
+ char* tmp_dir,
+ char* var_tmp_dir,
+ char* bus_endpoint_path,
+ bool private_dev,
+ ProtectHome protect_home,
+ ProtectSystem protect_system,
+ unsigned mount_flags) {
+
+ BindMount *m, *mounts = NULL;
+ unsigned n;
+ int r = 0;
+
+ if (mount_flags == 0)
+ mount_flags = MS_SHARED;
+
+ if (unshare(CLONE_NEWNS) < 0)
+ return -errno;
+
+ n = !!tmp_dir + !!var_tmp_dir + !!bus_endpoint_path +
+ strv_length(read_write_dirs) +
+ strv_length(read_only_dirs) +
+ strv_length(inaccessible_dirs) +
+ private_dev +
+ (protect_home != PROTECT_HOME_NO ? 3 : 0) +
+ (protect_system != PROTECT_SYSTEM_NO ? 2 : 0) +
+ (protect_system == PROTECT_SYSTEM_FULL ? 1 : 0);
+
+ if (n > 0) {
+ m = mounts = (BindMount *) alloca0(n * sizeof(BindMount));
+ r = append_mounts(&m, read_write_dirs, READWRITE);