mirror of
https://github.com/systemd/systemd.git
synced 2025-01-06 17:18:12 +03:00
dissect-image: add client side API wrapper for MountDirectory() varlink call
This commit is contained in:
parent
6e50124e24
commit
1703d200f8
@ -2170,6 +2170,9 @@ int dissected_image_mount(
|
|||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
|
if (FLAGS_SET(flags, DISSECT_IMAGE_FOREIGN_UID)) /* For image based mounts we currently require an identity mapping */
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
/* If 'where' is NULL then we'll use the new mount API to create fsmount() fds for the mounts and
|
/* If 'where' is NULL then we'll use the new mount API to create fsmount() fds for the mounts and
|
||||||
* store them in DissectedPartition.fsmount_fd.
|
* store them in DissectedPartition.fsmount_fd.
|
||||||
*
|
*
|
||||||
@ -4406,3 +4409,84 @@ int mountfsd_mount_image(
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct MountDirectoryReplyParameters {
|
||||||
|
unsigned fsmount_fd_idx;
|
||||||
|
} MountDirectoryReplyParameters;
|
||||||
|
|
||||||
|
int mountfsd_mount_directory(
|
||||||
|
const char *path,
|
||||||
|
int userns_fd,
|
||||||
|
DissectImageFlags flags,
|
||||||
|
int *ret_mount_fd) {
|
||||||
|
|
||||||
|
MountDirectoryReplyParameters p = {
|
||||||
|
.fsmount_fd_idx = UINT_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const sd_json_dispatch_field dispatch_table[] = {
|
||||||
|
{ "mountFileDescriptor", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, offsetof(struct MountDirectoryReplyParameters, fsmount_fd_idx), SD_JSON_MANDATORY },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Pick one identity, not both, that makes no sense. */
|
||||||
|
assert(!FLAGS_SET(flags, DISSECT_IMAGE_FOREIGN_UID|DISSECT_IMAGE_IDENTITY_UID));
|
||||||
|
|
||||||
|
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
|
||||||
|
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem");
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to connect to mountfsd: %m");
|
||||||
|
|
||||||
|
r = sd_varlink_set_allow_fd_passing_input(vl, true);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to enable varlink fd passing for read: %m");
|
||||||
|
|
||||||
|
r = sd_varlink_set_allow_fd_passing_output(vl, true);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to enable varlink fd passing for write: %m");
|
||||||
|
|
||||||
|
_cleanup_close_ int directory_fd = open(path, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
|
||||||
|
if (directory_fd < 0)
|
||||||
|
return log_error_errno(errno, "Failed to open '%s': %m", path);
|
||||||
|
|
||||||
|
r = sd_varlink_push_dup_fd(vl, directory_fd);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to push image fd into varlink connection: %m");
|
||||||
|
|
||||||
|
if (userns_fd >= 0) {
|
||||||
|
r = sd_varlink_push_dup_fd(vl, userns_fd);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to push image fd into varlink connection: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
sd_json_variant *reply = NULL;
|
||||||
|
const char *error_id = NULL;
|
||||||
|
r = sd_varlink_callbo(
|
||||||
|
vl,
|
||||||
|
"io.systemd.MountFileSystem.MountDirectory",
|
||||||
|
&reply,
|
||||||
|
&error_id,
|
||||||
|
SD_JSON_BUILD_PAIR_UNSIGNED("directoryFileDescriptor", 0),
|
||||||
|
SD_JSON_BUILD_PAIR_CONDITION(userns_fd >= 0, "userNamespaceFileDescriptor", SD_JSON_BUILD_UNSIGNED(1)),
|
||||||
|
SD_JSON_BUILD_PAIR_BOOLEAN("readOnly", FLAGS_SET(flags, DISSECT_IMAGE_MOUNT_READ_ONLY)),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("mode", FLAGS_SET(flags, DISSECT_IMAGE_FOREIGN_UID) ? "foreign" :
|
||||||
|
FLAGS_SET(flags, DISSECT_IMAGE_IDENTITY_UID) ? "identity" : "auto"),
|
||||||
|
SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH)));
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to call MountDirectory() varlink call: %m");
|
||||||
|
if (!isempty(error_id))
|
||||||
|
return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to call MountDirectory() varlink call: %s", error_id);
|
||||||
|
|
||||||
|
r = sd_json_dispatch(reply, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &p);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse MountImage() reply: %m");
|
||||||
|
|
||||||
|
_cleanup_close_ int fsmount_fd = sd_varlink_take_fd(vl, p.fsmount_fd_idx);
|
||||||
|
if (fsmount_fd < 0)
|
||||||
|
return log_error_errno(fsmount_fd, "Failed to take mount fd from Varlink connection: %m");
|
||||||
|
|
||||||
|
*ret_mount_fd = TAKE_FD(fsmount_fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -89,6 +89,8 @@ typedef enum DissectImageFlags {
|
|||||||
DISSECT_IMAGE_TRY_ATOMIC_MOUNT_EXCHANGE = 1 << 25, /* Try to mount the image beneath the specified mountpoint, rather than on top of it, and then umount the top */
|
DISSECT_IMAGE_TRY_ATOMIC_MOUNT_EXCHANGE = 1 << 25, /* Try to mount the image beneath the specified mountpoint, rather than on top of it, and then umount the top */
|
||||||
DISSECT_IMAGE_ALLOW_USERSPACE_VERITY = 1 << 26, /* Allow userspace verity keyring in /etc/verity.d/ and related dirs */
|
DISSECT_IMAGE_ALLOW_USERSPACE_VERITY = 1 << 26, /* Allow userspace verity keyring in /etc/verity.d/ and related dirs */
|
||||||
DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH = 1 << 27, /* Allow interactive authorization when going through mountfsd */
|
DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH = 1 << 27, /* Allow interactive authorization when going through mountfsd */
|
||||||
|
DISSECT_IMAGE_FOREIGN_UID = 1 << 28, /* Request a foreign UID range mapping */
|
||||||
|
DISSECT_IMAGE_IDENTITY_UID = 1 << 29, /* Explicitly request an identity UID range mapping */
|
||||||
} DissectImageFlags;
|
} DissectImageFlags;
|
||||||
|
|
||||||
struct DissectedImage {
|
struct DissectedImage {
|
||||||
@ -244,3 +246,4 @@ static inline const char* dissected_partition_fstype(const DissectedPartition *m
|
|||||||
int get_common_dissect_directory(char **ret);
|
int get_common_dissect_directory(char **ret);
|
||||||
|
|
||||||
int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, DissectImageFlags flags, DissectedImage **ret);
|
int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, DissectImageFlags flags, DissectedImage **ret);
|
||||||
|
int mountfsd_mount_directory(const char *path, int userns_fd, DissectImageFlags flags, int *ret_mount_fd);
|
||||||
|
Loading…
Reference in New Issue
Block a user