1
0
mirror of https://github.com/systemd/systemd synced 2025-12-23 09:24:46 +01:00

Compare commits

..

No commits in common. "f9708c53aa28bd2ba8273c5c132c1e8a83f2056e" and "65d173a02d4eeca9ad28c8d7d0c4f6a47d465503" have entirely different histories.

23 changed files with 145 additions and 270 deletions

View File

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h>
#include "alloc-util.h" #include "alloc-util.h"
#include "dirent-util.h" #include "dirent-util.h"
@ -434,25 +433,30 @@ int recurse_dir(
i, i,
statx_mask != 0 ? &sx : NULL, /* only pass sx if user asked for it */ statx_mask != 0 ? &sx : NULL, /* only pass sx if user asked for it */
userdata); userdata);
if (r == RECURSE_DIR_CONTINUE) { if (r == RECURSE_DIR_LEAVE_DIRECTORY)
r = recurse_dir(subdir_fd, break;
p, if (r == RECURSE_DIR_SKIP_ENTRY)
statx_mask, continue;
n_depth_max - 1, if (r != RECURSE_DIR_CONTINUE)
flags & ~RECURSE_DIR_TOPLEVEL, /* we already called the callback for this entry */ return r;
func,
userdata);
if (r != 0)
return r;
r = func(RECURSE_DIR_LEAVE, r = recurse_dir(subdir_fd,
p, p,
dir_fd, statx_mask,
subdir_fd, n_depth_max - 1,
i, flags & ~RECURSE_DIR_TOPLEVEL, /* we already called the callback for this entry */
statx_mask != 0 ? &sx : NULL, /* only pass sx if user asked for it */ func,
userdata); userdata);
} if (r != 0)
return r;
r = func(RECURSE_DIR_LEAVE,
p,
dir_fd,
subdir_fd,
i,
statx_mask != 0 ? &sx : NULL, /* only pass sx if user asked for it */
userdata);
} else } else
/* Non-directory inode */ /* Non-directory inode */
r = func(RECURSE_DIR_ENTRY, r = func(RECURSE_DIR_ENTRY,
@ -465,21 +469,7 @@ int recurse_dir(
if (r == RECURSE_DIR_LEAVE_DIRECTORY) if (r == RECURSE_DIR_LEAVE_DIRECTORY)
break; break;
if (!IN_SET(r, RECURSE_DIR_SKIP_ENTRY, RECURSE_DIR_CONTINUE))
if (IN_SET(r, RECURSE_DIR_UNLINK, RECURSE_DIR_UNLINK_GRACEFUL)) {
int f = subdir_fd >= 0 ? AT_REMOVEDIR : 0;
/* Close inodes before we try to delete them */
subdir_fd = safe_close(subdir_fd);
inode_fd = safe_close(inode_fd);
if (unlinkat(dir_fd, i->d_name, f) < 0) {
if (r != RECURSE_DIR_UNLINK_GRACEFUL)
return -errno;
log_debug_errno(errno, "Unable to remove '%s', ignoring: %m", p);
}
} else if (!IN_SET(r, RECURSE_DIR_SKIP_ENTRY, RECURSE_DIR_CONTINUE))
return r; return r;
} }

View File

@ -53,8 +53,6 @@ typedef enum RecurseDirEvent {
#define RECURSE_DIR_CONTINUE 0 #define RECURSE_DIR_CONTINUE 0
#define RECURSE_DIR_LEAVE_DIRECTORY INT_MIN #define RECURSE_DIR_LEAVE_DIRECTORY INT_MIN
#define RECURSE_DIR_SKIP_ENTRY (INT_MIN+1) #define RECURSE_DIR_SKIP_ENTRY (INT_MIN+1)
#define RECURSE_DIR_UNLINK (INT_MIN+2)
#define RECURSE_DIR_UNLINK_GRACEFUL (INT_MIN+3)
/* Make sure that the negative errno range and these two special returns don't overlap */ /* Make sure that the negative errno range and these two special returns don't overlap */
assert_cc(RECURSE_DIR_LEAVE_DIRECTORY < -ERRNO_MAX); assert_cc(RECURSE_DIR_LEAVE_DIRECTORY < -ERRNO_MAX);

View File

@ -31,15 +31,6 @@ static inline void iovec_done(struct iovec *iovec) {
iovec->iov_len = 0; iovec->iov_len = 0;
} }
static inline void iovec_done_many_and_free(struct iovec *iovec, size_t n) {
if (n > 0) {
assert(iovec);
FOREACH_ARRAY(j, iovec, n)
iovec_done(j);
}
free(iovec);
}
static inline bool iovec_is_set(const struct iovec *iovec) { static inline bool iovec_is_set(const struct iovec *iovec) {
/* Checks if the iovec points to a non-empty chunk of memory */ /* Checks if the iovec points to a non-empty chunk of memory */
return iovec && iovec->iov_len > 0 && iovec->iov_base; return iovec && iovec->iov_len > 0 && iovec->iov_base;

View File

@ -7,6 +7,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/xattr.h> #include <sys/xattr.h>
#include <unistd.h> #include <unistd.h>
#include "pidref.h"
#if HAVE_VALGRIND_MEMCHECK_H #if HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h> #include <valgrind/memcheck.h>
#endif #endif
@ -51,7 +52,6 @@
#include "openssl-util.h" #include "openssl-util.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pidref.h"
#include "process-util.h" #include "process-util.h"
#include "random-util.h" #include "random-util.h"
#include "reread-partition-table.h" #include "reread-partition-table.h"
@ -2606,7 +2606,7 @@ static int ext4_offline_resize_fs(
_cleanup_free_ char *size_str = NULL; _cleanup_free_ char *size_str = NULL;
bool re_open = false, re_mount = false; bool re_open = false, re_mount = false;
_cleanup_(pidref_done) PidRef fsck_pidref = PIDREF_NULL; _cleanup_(pidref_done) PidRef resize_pidref = PIDREF_NULL, fsck_pidref = PIDREF_NULL;
int r, exit_status; int r, exit_status;
assert(setup); assert(setup);
@ -2665,7 +2665,7 @@ static int ext4_offline_resize_fs(
r = pidref_safe_fork( r = pidref_safe_fork(
"(e2resize)", "(e2resize)",
FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS, FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
/* ret_pid= */ NULL); &resize_pidref);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0) { if (r == 0) {

View File

@ -257,7 +257,7 @@ static int tar_import_fork_tar(TarImport *i) {
return r; return r;
_cleanup_close_ int directory_fd = -EBADF; _cleanup_close_ int directory_fd = -EBADF;
r = mountfsd_make_directory(d, MODE_INVALID, /* flags= */ 0, &directory_fd); r = mountfsd_make_directory(d, /* flags= */ 0, &directory_fd);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -297,7 +297,7 @@ static int tar_pull_make_local_copy(TarPull *p) {
} }
_cleanup_close_ int directory_fd = -EBADF; _cleanup_close_ int directory_fd = -EBADF;
r = mountfsd_make_directory(t, MODE_INVALID, /* flags= */ 0, &directory_fd); r = mountfsd_make_directory(t, /* flags= */ 0, &directory_fd);
if (r < 0) if (r < 0)
return r; return r;
@ -609,7 +609,7 @@ static int tar_pull_job_on_open_disk_tar(PullJob *j) {
return r; return r;
_cleanup_close_ int directory_fd = -EBADF; _cleanup_close_ int directory_fd = -EBADF;
r = mountfsd_make_directory(where, MODE_INVALID, /* flags= */ 0, &directory_fd); r = mountfsd_make_directory(where, /* flags= */ 0, &directory_fd);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -1619,9 +1619,12 @@ _public_ int sd_event_add_child(
if (!callback) if (!callback)
callback = child_exit_callback; callback = child_exit_callback;
r = verify_sigchld(options); /* As an optimization we only do these checks on the first child event source created. */
if (r < 0) if (e->n_online_child_sources == 0) {
return r; r = verify_sigchld(options);
if (r < 0)
return r;
}
r = hashmap_ensure_allocated(&e->child_sources, NULL); r = hashmap_ensure_allocated(&e->child_sources, NULL);
if (r < 0) if (r < 0)
@ -1701,9 +1704,11 @@ _public_ int sd_event_add_child_pidfd(
if (!callback) if (!callback)
callback = child_exit_callback; callback = child_exit_callback;
r = verify_sigchld(options); if (e->n_online_child_sources == 0) {
if (r < 0) r = verify_sigchld(options);
return r; if (r < 0)
return r;
}
r = hashmap_ensure_allocated(&e->child_sources, NULL); r = hashmap_ensure_allocated(&e->child_sources, NULL);
if (r < 0) if (r < 0)

View File

@ -701,45 +701,3 @@ int json_variant_new_fd_info(sd_json_variant **ret, int fd) {
JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE("mountId", mntid), JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE("mountId", mntid),
SD_JSON_BUILD_PAIR_VARIANT("fileHandle", w)); SD_JSON_BUILD_PAIR_VARIANT("fileHandle", w));
} }
int json_dispatch_access_mode(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
mode_t *m = ASSERT_PTR(userdata);
int r;
if (sd_json_variant_is_null(variant)) {
*m = MODE_INVALID;
return 0;
}
/* Let the SD_JSON_STRICT determine if we allow suid/sgid/sticky or not */
mode_t limit = FLAGS_SET(flags, SD_JSON_STRICT) ? 0777 : 07777;
if (sd_json_variant_is_string(variant)) {
/* NB: we parse the mode in the usual octal if a string is specified. */
mode_t mode;
r = parse_mode(sd_json_variant_string(variant), &mode);
if (r < 0)
return json_log(variant, flags, r, "JSON field '%s' is not a valid access mode string.", strna(name));
if (mode > limit)
return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE),
"JSON field '%s' outside of valid range 0%s0%o.",
strna(name), glyph(GLYPH_ELLIPSIS), limit);
*m = mode;
} else if (sd_json_variant_is_unsigned(variant)) {
uint64_t k = sd_json_variant_unsigned(variant);
if (k > (uint64_t) limit)
return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE),
"JSON field '%s' outside of valid range 0%s0%o.",
strna(name), glyph(GLYPH_ELLIPSIS), limit);
*m = (mode_t) k;
} else
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is neither a number nor a string.", strna(name));
return 0;
}

View File

@ -127,7 +127,6 @@ int json_dispatch_devnum(const char *name, sd_json_variant *variant, sd_json_dis
int json_dispatch_ifindex(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata); int json_dispatch_ifindex(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_log_level(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata); int json_dispatch_log_level(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_strv_environment(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata); int json_dispatch_strv_environment(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_access_mode(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
static inline int json_variant_unbase64_iovec(sd_json_variant *v, struct iovec *ret) { static inline int json_variant_unbase64_iovec(sd_json_variant *v, struct iovec *ret) {
return sd_json_variant_unbase64(v, ret ? &ret->iov_base : NULL, ret ? &ret->iov_len : NULL); return sd_json_variant_unbase64(v, ret ? &ret->iov_base : NULL, ret ? &ret->iov_len : NULL);

View File

@ -1242,13 +1242,14 @@ int machine_copy_from_to_operation(
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]); errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
// TODO: port to PidRef and donate child rather than destroying it
Operation *operation; Operation *operation;
r = operation_new(manager, machine, &child, errno_pipe_fd[0], &operation); r = operation_new(manager, machine, &child, errno_pipe_fd[0], &operation);
if (r < 0) if (r < 0)
return r; return r;
TAKE_FD(errno_pipe_fd[0]); TAKE_FD(errno_pipe_fd[0]);
TAKE_PIDREF(child); pidref_done(&child);
*ret = operation; *ret = operation;
return 0; return 0;

View File

@ -111,7 +111,7 @@ int operation_new(Manager *manager, Machine *machine, PidRef *child, int errno_f
return -ENOMEM; return -ENOMEM;
*o = (Operation) { *o = (Operation) {
.pidref = *child, .pidref = TAKE_PIDREF(*child),
.errno_fd = errno_fd, .errno_fd = errno_fd,
.extra_fd = -EBADF .extra_fd = -EBADF
}; };

View File

@ -124,7 +124,7 @@ static int validate_image_fd(int fd, MountImageParameters *p) {
return r; return r;
} }
fl = fd_verify_safe_flags_full(fd, O_NONBLOCK); fl = fd_verify_safe_flags(fd);
if (fl < 0) if (fl < 0)
return log_debug_errno(fl, "Image file descriptor has unsafe flags set: %m"); return log_debug_errno(fl, "Image file descriptor has unsafe flags set: %m");
@ -353,8 +353,6 @@ static int vl_method_mount_image(
} }
r = validate_image_fd(image_fd, &p); r = validate_image_fd(image_fd, &p);
if (r == -EREMOTEIO)
return sd_varlink_errorbo(link, "io.systemd.MountFileSystem.BadFileDescriptorFlags", SD_JSON_BUILD_PAIR_STRING("parameter", "imageFileDescriptor"));
if (r < 0) if (r < 0)
return r; return r;
@ -1005,7 +1003,6 @@ static int vl_method_mount_directory(
typedef struct MakeDirectoryParameters { typedef struct MakeDirectoryParameters {
unsigned parent_fd_idx; unsigned parent_fd_idx;
const char *name; const char *name;
mode_t mode;
} MakeDirectoryParameters; } MakeDirectoryParameters;
static int vl_method_make_directory( static int vl_method_make_directory(
@ -1015,16 +1012,14 @@ static int vl_method_make_directory(
void *userdata) { void *userdata) {
static const sd_json_dispatch_field dispatch_table[] = { static const sd_json_dispatch_field dispatch_table[] = {
{ "parentFileDescriptor", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, offsetof(MakeDirectoryParameters, parent_fd_idx), SD_JSON_MANDATORY }, { "parentFileDescriptor", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint, offsetof(MakeDirectoryParameters, parent_fd_idx), SD_JSON_MANDATORY },
{ "name", SD_JSON_VARIANT_STRING, json_dispatch_const_filename, offsetof(MakeDirectoryParameters, name), SD_JSON_MANDATORY }, { "name", SD_JSON_VARIANT_STRING, json_dispatch_const_filename, offsetof(MakeDirectoryParameters, name), SD_JSON_MANDATORY },
{ "mode", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, offsetof(MakeDirectoryParameters, mode), SD_JSON_STRICT },
VARLINK_DISPATCH_POLKIT_FIELD, VARLINK_DISPATCH_POLKIT_FIELD,
{} {}
}; };
MakeDirectoryParameters p = { MakeDirectoryParameters p = {
.parent_fd_idx = UINT_MAX, .parent_fd_idx = UINT_MAX,
.mode = MODE_INVALID,
}; };
Hashmap **polkit_registry = ASSERT_PTR(userdata); Hashmap **polkit_registry = ASSERT_PTR(userdata);
int r; int r;
@ -1033,11 +1028,6 @@ static int vl_method_make_directory(
if (r != 0) if (r != 0)
return r; return r;
if (p.mode == MODE_INVALID)
p.mode = 0700;
else
p.mode &= 0775; /* refuse generating world writable dirs */
if (p.parent_fd_idx == UINT_MAX) if (p.parent_fd_idx == UINT_MAX)
return sd_varlink_error_invalid_parameter_name(link, "parentFileDescriptor"); return sd_varlink_error_invalid_parameter_name(link, "parentFileDescriptor");
@ -1099,11 +1089,11 @@ static int vl_method_make_directory(
if (r < 0) if (r < 0)
return r; return r;
_cleanup_close_ int fd = open_mkdir_at(parent_fd, t, O_CLOEXEC, p.mode); _cleanup_close_ int fd = open_mkdir_at(parent_fd, t, O_CLOEXEC, 0700);
if (fd < 0) if (fd < 0)
return fd; return fd;
r = RET_NERRNO(fchmod(fd, p.mode)); /* Set mode explicitly, as paranoia regarding umask games */ r = RET_NERRNO(fchmod(fd, 0700)); /* Set mode explicitly, as paranoia regarding umask games */
if (r < 0) if (r < 0)
goto fail; goto fail;

View File

@ -542,7 +542,7 @@ static int portable_extract_by_path(
if (r < 0) if (r < 0)
return r; return r;
pidref_done(&child); TAKE_PIDREF(child);
} }
if (!os_release) if (!os_release)

View File

@ -554,7 +554,7 @@ int bus_image_common_remove(
if (r < 0) if (r < 0)
return r; return r;
/* We don't need to disarm child cleanup here because operation_new() takes over ownership internally. */ TAKE_PIDREF(child);
errno_pipe_fd[0] = -EBADF; errno_pipe_fd[0] = -EBADF;
return 1; return 1;

View File

@ -1491,7 +1491,6 @@ static int unpriviled_clone(Image *i, const char *new_path) {
_cleanup_close_ int new_fd = -EBADF; _cleanup_close_ int new_fd = -EBADF;
r = mountfsd_make_directory( r = mountfsd_make_directory(
new_path, new_path,
MODE_INVALID,
/* flags= */ 0, /* flags= */ 0,
&new_fd); &new_fd);
if (r < 0) if (r < 0)

View File

@ -630,35 +630,7 @@ static void check_partition_flags(
log_debug("Unexpected partition flag %llu set on %s!", bit, node); log_debug("Unexpected partition flag %llu set on %s!", bit, node);
} }
} }
#endif
static int make_image_name(const char *path, char **ret) {
int r;
assert(path);
assert(ret);
_cleanup_free_ char *filename = NULL;
r = path_extract_filename(path, &filename);
if (r < 0)
return r;
_cleanup_free_ char *name = NULL;
r = raw_strip_suffixes(filename, &name);
if (r < 0)
return r;
if (!image_name_is_valid(name)) {
log_debug("Image name %s is not valid, ignoring.", strna(name));
*ret = NULL;
return 0;
}
*ret = TAKE_PTR(name);
return 1;
}
#if HAVE_BLKID
static int dissected_image_new(const char *path, DissectedImage **ret) { static int dissected_image_new(const char *path, DissectedImage **ret) {
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
_cleanup_free_ char *name = NULL; _cleanup_free_ char *name = NULL;
@ -667,9 +639,20 @@ static int dissected_image_new(const char *path, DissectedImage **ret) {
assert(ret); assert(ret);
if (path) { if (path) {
r = make_image_name(path, &name); _cleanup_free_ char *filename = NULL;
r = path_extract_filename(path, &filename);
if (r < 0) if (r < 0)
return r; return r;
r = raw_strip_suffixes(filename, &name);
if (r < 0)
return r;
if (!image_name_is_valid(name)) {
log_debug("Image name %s is not valid, ignoring.", strna(name));
name = mfree(name);
}
} }
m = new(DissectedImage, 1); m = new(DissectedImage, 1);
@ -4445,7 +4428,7 @@ int dissected_image_acquire_metadata(
if (r < 0) if (r < 0)
goto finish; goto finish;
pidref_done(&child); TAKE_PIDREF(child);
n = read(error_pipe[0], &v, sizeof(v)); n = read(error_pipe[0], &v, sizeof(v));
if (n < 0) { if (n < 0) {
@ -5039,8 +5022,8 @@ static void mount_image_reply_parameters_done(MountImageReplyParameters *p) {
#endif #endif
int mountfsd_mount_image_fd( int mountfsd_mount_image(
int image_fd, const char *path,
int userns_fd, int userns_fd,
const ImagePolicy *image_policy, const ImagePolicy *image_policy,
const VeritySettings *verity, const VeritySettings *verity,
@ -5060,13 +5043,13 @@ int mountfsd_mount_image_fd(
}; };
_cleanup_(dissected_image_unrefp) DissectedImage *di = NULL; _cleanup_(dissected_image_unrefp) DissectedImage *di = NULL;
_cleanup_close_ int verity_data_fd = -EBADF; _cleanup_close_ int image_fd = -EBADF, verity_data_fd = -EBADF;
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
_cleanup_free_ char *ps = NULL; _cleanup_free_ char *ps = NULL;
const char *error_id; const char *error_id;
int r; int r;
assert(image_fd >= 0); assert(path);
assert(ret); assert(ret);
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem"); r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem");
@ -5081,11 +5064,9 @@ int mountfsd_mount_image_fd(
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enable varlink fd passing for write: %m"); return log_error_errno(r, "Failed to enable varlink fd passing for write: %m");
_cleanup_close_ int reopened_fd = -EBADF; image_fd = open(path, O_RDONLY|O_CLOEXEC);
image_fd = fd_reopen_condition(image_fd, O_CLOEXEC|O_NOCTTY|O_NONBLOCK|(FLAGS_SET(flags, DISSECT_IMAGE_MOUNT_READ_ONLY) ? O_RDONLY : O_RDWR), O_PATH, &reopened_fd);
if (image_fd < 0) if (image_fd < 0)
return log_error_errno(image_fd, "Failed to reopen fd: %m"); return log_error_errno(errno, "Failed to open '%s': %m", path);
r = sd_varlink_push_dup_fd(vl, image_fd); r = sd_varlink_push_dup_fd(vl, image_fd);
if (r < 0) if (r < 0)
@ -5178,7 +5159,7 @@ int mountfsd_mount_image_fd(
assert(pp.designator >= 0); assert(pp.designator >= 0);
if (!di) { if (!di) {
r = dissected_image_new(/* path= */ NULL, &di); r = dissected_image_new(path, &di);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to allocated new dissected image structure: %m"); return log_error_errno(r, "Failed to allocated new dissected image structure: %m");
} }
@ -5213,38 +5194,6 @@ int mountfsd_mount_image_fd(
#endif #endif
} }
int mountfsd_mount_image(
const char *path,
int userns_fd,
const ImagePolicy *image_policy,
const VeritySettings *verity,
DissectImageFlags flags,
DissectedImage **ret) {
int r;
assert(path);
assert(ret);
_cleanup_close_ int image_fd = open(path, O_RDONLY|O_CLOEXEC);
if (image_fd < 0)
return log_error_errno(errno, "Failed to open '%s': %m", path);
_cleanup_(dissected_image_unrefp) DissectedImage *di = NULL;
r = mountfsd_mount_image_fd(image_fd, userns_fd, image_policy, verity, flags, &di);
if (r < 0)
return r;
if (!di->image_name) {
r = make_image_name(path, &di->image_name);
if (r < 0)
return r;
}
*ret = TAKE_PTR(di);
return 0;
}
int mountfsd_mount_directory_fd( int mountfsd_mount_directory_fd(
int directory_fd, int directory_fd,
int userns_fd, int userns_fd,
@ -5335,7 +5284,6 @@ int mountfsd_mount_directory(
int mountfsd_make_directory_fd( int mountfsd_make_directory_fd(
int parent_fd, int parent_fd,
const char *name, const char *name,
mode_t mode,
DissectImageFlags flags, DissectImageFlags flags,
int *ret_directory_fd) { int *ret_directory_fd) {
@ -5343,6 +5291,7 @@ int mountfsd_make_directory_fd(
assert(parent_fd >= 0); assert(parent_fd >= 0);
assert(name); assert(name);
assert(ret_directory_fd);
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem"); r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem");
@ -5370,7 +5319,6 @@ int mountfsd_make_directory_fd(
&error_id, &error_id,
SD_JSON_BUILD_PAIR_UNSIGNED("parentFileDescriptor", 0), SD_JSON_BUILD_PAIR_UNSIGNED("parentFileDescriptor", 0),
SD_JSON_BUILD_PAIR_STRING("name", name), SD_JSON_BUILD_PAIR_STRING("name", name),
SD_JSON_BUILD_PAIR_CONDITION(!IN_SET(mode, MODE_INVALID, 0700), "mode", SD_JSON_BUILD_UNSIGNED(mode)), /* suppress this field if default/unset */
SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH))); SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH)));
if (r < 0) if (r < 0)
return r; return r;
@ -5389,14 +5337,12 @@ int mountfsd_make_directory_fd(
if (directory_fd < 0) if (directory_fd < 0)
return log_error_errno(directory_fd, "Failed to take directory fd from Varlink connection: %m"); return log_error_errno(directory_fd, "Failed to take directory fd from Varlink connection: %m");
if (ret_directory_fd) *ret_directory_fd = TAKE_FD(directory_fd);
*ret_directory_fd = TAKE_FD(directory_fd);
return 0; return 0;
} }
int mountfsd_make_directory( int mountfsd_make_directory(
const char *path, const char *path,
mode_t mode,
DissectImageFlags flags, DissectImageFlags flags,
int *ret_directory_fd) { int *ret_directory_fd) {
@ -5416,5 +5362,5 @@ int mountfsd_make_directory(
if (fd < 0) if (fd < 0)
return log_error_errno(r, "Failed to open '%s': %m", parent); return log_error_errno(r, "Failed to open '%s': %m", parent);
return mountfsd_make_directory_fd(fd, dirname, mode, flags, ret_directory_fd); return mountfsd_make_directory_fd(fd, dirname, flags, ret_directory_fd);
} }

View File

@ -268,10 +268,9 @@ 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_fd(int image_fd, int userns_fd, const ImagePolicy *image_policy, const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret);
int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret); int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret);
int mountfsd_mount_directory_fd(int directory_fd, int userns_fd, DissectImageFlags flags, int *ret_mount_fd); int mountfsd_mount_directory_fd(int directory_fd, int userns_fd, DissectImageFlags flags, int *ret_mount_fd);
int mountfsd_mount_directory(const char *path, int userns_fd, DissectImageFlags flags, int *ret_mount_fd); int mountfsd_mount_directory(const char *path, int userns_fd, DissectImageFlags flags, int *ret_mount_fd);
int mountfsd_make_directory_fd(int parent_fd, const char *name, mode_t mode, DissectImageFlags flags, int *ret_directory_fd); int mountfsd_make_directory_fd(int parent_fd, const char *name, DissectImageFlags flags, int *ret_directory_fd);
int mountfsd_make_directory(const char *path, mode_t mode, DissectImageFlags flags, int *ret_directory_fd); int mountfsd_make_directory(const char *path, DissectImageFlags flags, int *ret_directory_fd);

View File

@ -174,7 +174,7 @@ static int do_execute(
_cleanup_(pidref_freep) PidRef *dup = NULL; _cleanup_(pidref_freep) PidRef *dup = NULL;
r = pidref_dup(&pidref, &dup); r = pidref_dup(&pidref, &dup);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to duplicate pid reference: %m"); return r;
r = hashmap_ensure_put(&pids, &pidref_hash_ops_free_free, dup, t); r = hashmap_ensure_put(&pids, &pidref_hash_ops_free_free, dup, t);
if (r < 0) if (r < 0)
@ -222,10 +222,11 @@ static int do_execute(
} }
while (!hashmap_isempty(pids)) { while (!hashmap_isempty(pids)) {
_cleanup_(pidref_freep) PidRef *pidref = NULL;
_cleanup_free_ char *t = NULL; _cleanup_free_ char *t = NULL;
void *p;
t = ASSERT_PTR(hashmap_steal_first_key_and_value(pids, (void**) &pidref)); t = ASSERT_PTR(hashmap_steal_first_key_and_value(pids, &p));
_cleanup_(pidref_freep) PidRef *pidref = p;
r = pidref_wait_for_terminate_and_check(t, pidref, WAIT_LOG); r = pidref_wait_for_terminate_and_check(t, pidref, WAIT_LOG);
if (r < 0) if (r < 0)
@ -274,7 +275,7 @@ int execute_strv(
const char *process_name = strjoina("(", name, ")"); const char *process_name = strjoina("(", name, ")");
_cleanup_(pidref_done) PidRef executor_pidref = PIDREF_NULL; PidRef executor_pidref = PIDREF_NULL;
r = pidref_safe_fork(process_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &executor_pidref); r = pidref_safe_fork(process_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &executor_pidref);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -462,6 +462,50 @@ static int json_dispatch_image_path(const char *name, sd_json_variant *variant,
return 0; return 0;
} }
static int json_dispatch_umask(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
mode_t *m = userdata;
uint64_t k;
if (sd_json_variant_is_null(variant)) {
*m = MODE_INVALID;
return 0;
}
if (!sd_json_variant_is_unsigned(variant))
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a number.", strna(name));
k = sd_json_variant_unsigned(variant);
if (k > 0777)
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL),
"JSON field '%s' outside of valid range 0%s0777.",
strna(name), glyph(GLYPH_ELLIPSIS));
*m = (mode_t) k;
return 0;
}
static int json_dispatch_access_mode(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
mode_t *m = userdata;
uint64_t k;
if (sd_json_variant_is_null(variant)) {
*m = MODE_INVALID;
return 0;
}
if (!sd_json_variant_is_unsigned(variant))
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a number.", strna(name));
k = sd_json_variant_unsigned(variant);
if (k > 07777)
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL),
"JSON field '%s' outside of valid range 0%s07777.",
strna(name), glyph(GLYPH_ELLIPSIS));
*m = (mode_t) k;
return 0;
}
static int json_dispatch_locale(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) { static int json_dispatch_locale(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
char **s = userdata; char **s = userdata;
const char *n; const char *n;
@ -1229,7 +1273,7 @@ static int dispatch_per_machine(const char *name, sd_json_variant *variant, sd_j
{ "iconName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, icon_name), SD_JSON_STRICT }, { "iconName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, icon_name), SD_JSON_STRICT },
{ "location", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, location), 0 }, { "location", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, location), 0 },
{ "shell", SD_JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, shell), 0 }, { "shell", SD_JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, shell), 0 },
{ "umask", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, offsetof(UserRecord, umask), SD_JSON_STRICT }, { "umask", SD_JSON_VARIANT_UNSIGNED, json_dispatch_umask, offsetof(UserRecord, umask), 0 },
{ "environment", SD_JSON_VARIANT_ARRAY, json_dispatch_strv_environment, offsetof(UserRecord, environment), 0 }, { "environment", SD_JSON_VARIANT_ARRAY, json_dispatch_strv_environment, offsetof(UserRecord, environment), 0 },
{ "timeZone", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, time_zone), SD_JSON_STRICT }, { "timeZone", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, time_zone), SD_JSON_STRICT },
{ "preferredLanguage", SD_JSON_VARIANT_STRING, json_dispatch_locale, offsetof(UserRecord, preferred_language), 0 }, { "preferredLanguage", SD_JSON_VARIANT_STRING, json_dispatch_locale, offsetof(UserRecord, preferred_language), 0 },
@ -1243,7 +1287,7 @@ static int dispatch_per_machine(const char *name, sd_json_variant *variant, sd_j
{ "diskSize", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, disk_size), 0 }, { "diskSize", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, disk_size), 0 },
{ "diskSizeRelative", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, disk_size_relative), 0 }, { "diskSizeRelative", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, disk_size_relative), 0 },
{ "skeletonDirectory", SD_JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, skeleton_directory), SD_JSON_STRICT }, { "skeletonDirectory", SD_JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, skeleton_directory), SD_JSON_STRICT },
{ "accessMode", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 }, { "accessMode", SD_JSON_VARIANT_UNSIGNED, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 },
{ "tasksMax", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, tasks_max), 0 }, { "tasksMax", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, tasks_max), 0 },
{ "memoryHigh", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_high), 0 }, { "memoryHigh", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_high), 0 },
{ "memoryMax", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_max), 0 }, { "memoryMax", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_max), 0 },
@ -1353,7 +1397,7 @@ static int dispatch_status(const char *name, sd_json_variant *variant, sd_json_d
{ "rateLimitBeginUSec", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, ratelimit_begin_usec), 0 }, { "rateLimitBeginUSec", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, ratelimit_begin_usec), 0 },
{ "rateLimitCount", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, ratelimit_count), 0 }, { "rateLimitCount", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, ratelimit_count), 0 },
{ "removable", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(UserRecord, removable), 0 }, { "removable", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(UserRecord, removable), 0 },
{ "accessMode", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 }, { "accessMode", SD_JSON_VARIANT_UNSIGNED, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 },
{ "fileSystemType", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, file_system_type), SD_JSON_STRICT }, { "fileSystemType", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, file_system_type), SD_JSON_STRICT },
{ "fallbackShell", SD_JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, fallback_shell), 0 }, { "fallbackShell", SD_JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, fallback_shell), 0 },
{ "fallbackHomeDirectory", SD_JSON_VARIANT_STRING, json_dispatch_home_directory, offsetof(UserRecord, fallback_home_directory), 0 }, { "fallbackHomeDirectory", SD_JSON_VARIANT_STRING, json_dispatch_home_directory, offsetof(UserRecord, fallback_home_directory), 0 },
@ -1589,7 +1633,7 @@ int user_record_load(UserRecord *h, sd_json_variant *v, UserRecordLoadFlags load
{ "lastChangeUSec", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, last_change_usec), 0 }, { "lastChangeUSec", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, last_change_usec), 0 },
{ "lastPasswordChangeUSec", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, last_password_change_usec), 0 }, { "lastPasswordChangeUSec", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, last_password_change_usec), 0 },
{ "shell", SD_JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, shell), 0 }, { "shell", SD_JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, shell), 0 },
{ "umask", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, offsetof(UserRecord, umask), SD_JSON_STRICT }, { "umask", SD_JSON_VARIANT_UNSIGNED, json_dispatch_umask, offsetof(UserRecord, umask), 0 },
{ "environment", SD_JSON_VARIANT_ARRAY, json_dispatch_strv_environment, offsetof(UserRecord, environment), 0 }, { "environment", SD_JSON_VARIANT_ARRAY, json_dispatch_strv_environment, offsetof(UserRecord, environment), 0 },
{ "timeZone", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, time_zone), SD_JSON_STRICT }, { "timeZone", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(UserRecord, time_zone), SD_JSON_STRICT },
{ "preferredLanguage", SD_JSON_VARIANT_STRING, json_dispatch_locale, offsetof(UserRecord, preferred_language), 0 }, { "preferredLanguage", SD_JSON_VARIANT_STRING, json_dispatch_locale, offsetof(UserRecord, preferred_language), 0 },
@ -1603,7 +1647,7 @@ int user_record_load(UserRecord *h, sd_json_variant *v, UserRecordLoadFlags load
{ "diskSize", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, disk_size), 0 }, { "diskSize", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, disk_size), 0 },
{ "diskSizeRelative", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, disk_size_relative), 0 }, { "diskSizeRelative", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(UserRecord, disk_size_relative), 0 },
{ "skeletonDirectory", SD_JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, skeleton_directory), SD_JSON_STRICT }, { "skeletonDirectory", SD_JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, skeleton_directory), SD_JSON_STRICT },
{ "accessMode", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 }, { "accessMode", SD_JSON_VARIANT_UNSIGNED, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 },
{ "tasksMax", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, tasks_max), 0 }, { "tasksMax", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, tasks_max), 0 },
{ "memoryHigh", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_high), 0 }, { "memoryHigh", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_high), 0 },
{ "memoryMax", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_max), 0 }, { "memoryMax", SD_JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_max), 0 },

View File

@ -113,8 +113,6 @@ static SD_VARLINK_DEFINE_METHOD(
SD_VARLINK_DEFINE_INPUT(parentFileDescriptor, SD_VARLINK_INT, 0), SD_VARLINK_DEFINE_INPUT(parentFileDescriptor, SD_VARLINK_INT, 0),
SD_VARLINK_FIELD_COMMENT("Name of the directory to create."), SD_VARLINK_FIELD_COMMENT("Name of the directory to create."),
SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0), SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Access mode of the directory to create. Note that the suid, sgid, sticky, world-writable bit is unconditionally masked off."),
SD_VARLINK_DEFINE_INPUT(mode, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
VARLINK_DEFINE_POLKIT_INPUT, VARLINK_DEFINE_POLKIT_INPUT,
SD_VARLINK_FIELD_COMMENT("File descriptor referencing the newly created directory."), SD_VARLINK_FIELD_COMMENT("File descriptor referencing the newly created directory."),
SD_VARLINK_DEFINE_OUTPUT(directoryFileDescriptor, SD_VARLINK_INT, 0)); SD_VARLINK_DEFINE_OUTPUT(directoryFileDescriptor, SD_VARLINK_INT, 0));

View File

@ -294,17 +294,18 @@ static int remount_with_timeout(MountPoint *m, bool last_try) {
else if (si.si_code != CLD_EXITED || si.si_status != 0) { else if (si.si_code != CLD_EXITED || si.si_status != 0) {
/* Try to read error code from child */ /* Try to read error code from child */
r = read_errno(pfd[0]); r = read_errno(pfd[0]);
if (r < 0 && r != -EIO) if (r == -EIO)
log_debug_errno(r,
"Remounting '%s' failed abnormally, child process " PID_FMT " failed: %m",
m->path, pidref.pid);
else
r = log_debug_errno( r = log_debug_errno(
SYNTHETIC_ERRNO(EPROTO), SYNTHETIC_ERRNO(EPROTO),
"Remounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.", "Remounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.",
m->path, pidref.pid); m->path, pidref.pid);
else if (r < 0)
log_debug_errno(
r,
"Remounting '%s' failed abnormally, child process " PID_FMT " failed: %m",
m->path, pidref.pid);
pidref_done(&pidref); /* child exited (just not as we expected) hence don't kill anymore */ TAKE_PIDREF(pidref); /* child exited (just not as we expected) hence don't kill anymore */
} }
return r; return r;
@ -363,17 +364,18 @@ static int umount_with_timeout(MountPoint *m, bool last_try) {
else if (si.si_code != CLD_EXITED || si.si_status != 0) { else if (si.si_code != CLD_EXITED || si.si_status != 0) {
/* Try to read error code from child */ /* Try to read error code from child */
r = read_errno(pfd[0]); r = read_errno(pfd[0]);
if (r < 0 && r != -EIO) if (r == -EIO)
log_debug_errno(r,
"Unmounting '%s' failed abnormally, child process " PID_FMT " failed: %m",
m->path, pidref.pid);
else
r = log_debug_errno( r = log_debug_errno(
SYNTHETIC_ERRNO(EPROTO), SYNTHETIC_ERRNO(EPROTO),
"Unmounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.", "Unmounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.",
m->path, pidref.pid); m->path, pidref.pid);
else if (r < 0)
log_debug_errno(
r,
"Unmounting '%s' failed abnormally, child process " PID_FMT " failed: %m",
m->path, pidref.pid);
pidref_done(&pidref); /* It died, but abnormally, no purpose in killing */ TAKE_PIDREF(pidref); /* It died, but abnormally, no purpose in killing */
} }
return r; return r;

View File

@ -1477,50 +1477,4 @@ TEST(unit_name) {
&data), EINVAL); &data), EINVAL);
} }
TEST(access_mode) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
ASSERT_OK(sd_json_parse("{"
" \"a\" : \"0755\", "
" \"b\" : 448, "
" \"c\" : null, "
" \"d\" : \"01755\" "
"}",
/* flags= */ 0,
&v,
/* reterr_line= */ NULL,
/* reterr_column= */ NULL));
struct {
mode_t a, b, c, d;
} mm = { 1, 2, 3, 4 };
ASSERT_OK(sd_json_dispatch(
v,
(const sd_json_dispatch_field[]) {
{ "a", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, voffsetof(mm, a), 0 },
{ "b", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, voffsetof(mm, b), 0 },
{ "c", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, voffsetof(mm, c), 0 },
{ "d", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, voffsetof(mm, d), 0 },
{},
},
/* flags= */ 0,
&mm));
ASSERT_EQ(mm.a, (mode_t) 0755);
ASSERT_EQ(mm.b, (mode_t) 0700);
ASSERT_EQ(mm.c, MODE_INVALID);
ASSERT_EQ(mm.d, (mode_t) 01755);
/* retry with SD_JSON_STRICT, where 'd' should not parse anymore */
ASSERT_ERROR(sd_json_dispatch(
v,
(const sd_json_dispatch_field[]) {
{ "d", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, voffsetof(mm, d), SD_JSON_STRICT },
{},
},
/* flags= */ SD_JSON_ALLOW_EXTENSIONS,
&mm), ERANGE);
}
DEFINE_TEST_MAIN(LOG_DEBUG); DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -1085,7 +1085,7 @@ static int on_child_exit(sd_event_source *s, const siginfo_t *si, void *userdata
si->si_pid, signal_to_string(si->si_status)); si->si_pid, signal_to_string(si->si_status));
else else
ret = log_error_errno(SYNTHETIC_ERRNO(EPROTO), ret = log_error_errno(SYNTHETIC_ERRNO(EPROTO),
"Got unexpected exit code %i from child.", "Got unexpected exit code %i from child,",
si->si_code); si->si_code);
/* Regardless of whether the main qemu process or an auxiliary process died, let's exit either way /* Regardless of whether the main qemu process or an auxiliary process died, let's exit either way