static int apply_mount_namespace(
                const Unit *u,
                const ExecCommand *command,
                const ExecContext *context,
                const ExecParameters *params,
                const ExecRuntime *runtime) {

        _cleanup_strv_free_ char **empty_directories = NULL;
        char *tmp = NULL, *var = NULL;
        const char *root_dir = NULL, *root_image = NULL;
        NamespaceInfo ns_info;
        bool needs_sandboxing;
        BindMount *bind_mounts = NULL;
        size_t n_bind_mounts = 0;
        int r;

        assert(context);

        /* The runtime struct only contains the parent of the private /tmp,
         * which is non-accessible to world users. Inside of it there's a /tmp
         * that is sticky, and that's the one we want to use here. */

        if (context->private_tmp && runtime) {
                if (runtime->tmp_dir)
                        tmp = strjoina(runtime->tmp_dir, "/tmp");
                if (runtime->var_tmp_dir)
                        var = strjoina(runtime->var_tmp_dir, "/tmp");
        }

        if (params->flags & EXEC_APPLY_CHROOT) {
                root_image = context->root_image;

                if (!root_image)
                        root_dir = context->root_directory;
        }

        r = compile_bind_mounts(context, params, &bind_mounts, &n_bind_mounts, &empty_directories);
        if (r < 0)
                return r;

        needs_sandboxing = (params->flags & EXEC_APPLY_SANDBOXING) && !(command->flags & EXEC_COMMAND_FULLY_PRIVILEGED);
        if (needs_sandboxing)
                ns_info = (NamespaceInfo) {
                        .ignore_protect_paths = false,
                        .private_dev = context->private_devices,
                        .protect_control_groups = context->protect_control_groups,
                        .protect_kernel_tunables = context->protect_kernel_tunables,
                        .protect_kernel_modules = context->protect_kernel_modules,
                        .protect_hostname = context->protect_hostname,
                        .mount_apivfs = context->mount_apivfs,
                        .private_mounts = context->private_mounts,
                };
        else if (!context->dynamic_user && root_dir)
                /*
                 * If DynamicUser=no and RootDirectory= is set then lets pass a relaxed
                 * sandbox info, otherwise enforce it, don't ignore protected paths and
                 * fail if we are enable to apply the sandbox inside the mount namespace.
                 */
                ns_info = (NamespaceInfo) {
                        .ignore_protect_paths = true,
                };
        else
                ns_info = (NamespaceInfo) {};

        if (context->mount_flags == MS_SHARED)
                log_unit_debug(u, "shared mount propagation hidden by other fs namespacing unit settings: ignoring");

        r = setup_namespace(root_dir, root_image,
                            &ns_info, context->read_write_paths,
                            needs_sandboxing ? context->read_only_paths : NULL,
                            needs_sandboxing ? context->inaccessible_paths : NULL,
                            empty_directories,
                            bind_mounts,
                            n_bind_mounts,
                            context->temporary_filesystems,
                            context->n_temporary_filesystems,
                            tmp,
                            var,
                            needs_sandboxing ? context->protect_home : PROTECT_HOME_NO,
                            needs_sandboxing ? context->protect_system : PROTECT_SYSTEM_NO,
                            context->mount_flags,
                            DISSECT_IMAGE_DISCARD_ON_LOOP);

        bind_mount_free_many(bind_mounts, n_bind_mounts);

        /* If we couldn't set up the namespace this is probably due to a missing capability. setup_namespace() reports
         * that with a special, recognizable error ENOANO. In this case, silently proceeed, but only if exclusively
         * sandboxing options were used, i.e. nothing such as RootDirectory= or BindMount= that would result in a
         * completely different execution environment. */
        if (r == -ENOANO) {
                if (n_bind_mounts == 0 &&
                    context->n_temporary_filesystems == 0 &&
                    !root_dir && !root_image &&
                    !context->dynamic_user) {
                        log_unit_debug(u, "Failed to set up namespace, assuming containerized execution and ignoring.");
                        return 0;
                }

                log_unit_debug(u, "Failed to set up namespace, and refusing to continue since the selected namespacing options alter mount environment non-trivially.\n"
                               "Bind mounts: %zu, temporary filesystems: %zu, root directory: %s, root image: %s, dynamic user: %s",
                               n_bind_mounts, context->n_temporary_filesystems, yes_no(root_dir), yes_no(root_image), yes_no(context->dynamic_user));

                return -EOPNOTSUPP;
        }

        return r;
}