introduce report_errno_and_exit() helper (#35028)
This is a follow for https://github.com/systemd/systemd/pull/34853. In particular, this comment https://github.com/systemd/systemd/pull/34853#discussion_r1825837705.
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "io-util.h"
|
||||
#include "locale-util.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
@@ -2238,3 +2239,18 @@ static const char* const sched_policy_table[] = {
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
|
||||
|
||||
_noreturn_ void report_errno_and_exit(int errno_fd, int error) {
|
||||
int r;
|
||||
|
||||
if (error >= 0)
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
assert(errno_fd >= 0);
|
||||
|
||||
r = loop_write(errno_fd, &error, sizeof(error));
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to write errno to errno_fd=%d: %m", errno_fd);
|
||||
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -273,3 +273,5 @@ int posix_spawn_wrapper(
|
||||
int proc_dir_open(DIR **ret);
|
||||
int proc_dir_read(DIR *d, pid_t *ret);
|
||||
int proc_dir_read_pidref(DIR *d, PidRef *ret);
|
||||
|
||||
_noreturn_ void report_errno_and_exit(int errno_fd, int error);
|
||||
|
||||
+11
-14
@@ -2165,10 +2165,8 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
|
||||
errno_pipe[0] = safe_close(errno_pipe[0]);
|
||||
|
||||
/* Wait until the parent unshared the user namespace */
|
||||
if (read(unshare_ready_fd, &c, sizeof(c)) < 0) {
|
||||
r = -errno;
|
||||
goto child_fail;
|
||||
}
|
||||
if (read(unshare_ready_fd, &c, sizeof(c)) < 0)
|
||||
report_errno_and_exit(errno_pipe[1], -errno);
|
||||
|
||||
/* Disable the setgroups() system call in the child user namespace, for good. */
|
||||
a = procfs_file_alloca(ppid, "setgroups");
|
||||
@@ -2176,14 +2174,14 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
|
||||
if (fd < 0) {
|
||||
if (errno != ENOENT) {
|
||||
r = log_debug_errno(errno, "Failed to open %s: %m", a);
|
||||
goto child_fail;
|
||||
report_errno_and_exit(errno_pipe[1], r);
|
||||
}
|
||||
|
||||
/* If the file is missing the kernel is too old, let's continue anyway. */
|
||||
} else {
|
||||
if (write(fd, "deny\n", 5) < 0) {
|
||||
r = log_debug_errno(errno, "Failed to write \"deny\" to %s: %m", a);
|
||||
goto child_fail;
|
||||
report_errno_and_exit(errno_pipe[1], r);
|
||||
}
|
||||
|
||||
fd = safe_close(fd);
|
||||
@@ -2194,12 +2192,14 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
|
||||
fd = open(a, O_WRONLY|O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
r = log_debug_errno(errno, "Failed to open %s: %m", a);
|
||||
goto child_fail;
|
||||
report_errno_and_exit(errno_pipe[1], r);
|
||||
}
|
||||
|
||||
if (write(fd, gid_map, strlen(gid_map)) < 0) {
|
||||
r = log_debug_errno(errno, "Failed to write GID map to %s: %m", a);
|
||||
goto child_fail;
|
||||
report_errno_and_exit(errno_pipe[1], r);
|
||||
}
|
||||
|
||||
fd = safe_close(fd);
|
||||
|
||||
/* The write the UID map */
|
||||
@@ -2207,18 +2207,15 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
|
||||
fd = open(a, O_WRONLY|O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
r = log_debug_errno(errno, "Failed to open %s: %m", a);
|
||||
goto child_fail;
|
||||
report_errno_and_exit(errno_pipe[1], r);
|
||||
}
|
||||
|
||||
if (write(fd, uid_map, strlen(uid_map)) < 0) {
|
||||
r = log_debug_errno(errno, "Failed to write UID map to %s: %m", a);
|
||||
goto child_fail;
|
||||
report_errno_and_exit(errno_pipe[1], r);
|
||||
}
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
child_fail:
|
||||
(void) write(errno_pipe[1], &r, sizeof(r));
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
errno_pipe[1] = safe_close(errno_pipe[1]);
|
||||
|
||||
@@ -154,18 +154,3 @@ Operation *operation_free(Operation *o) {
|
||||
|
||||
return mfree(o);
|
||||
}
|
||||
|
||||
_noreturn_ void report_errno_and_exit(int errno_fd, int r) {
|
||||
if (r >= 0)
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
assert(errno_fd >= 0);
|
||||
|
||||
ssize_t n = write(errno_fd, &r, sizeof(r));
|
||||
if (n < 0)
|
||||
log_debug_errno(errno, "Failed to write operation's errno: %m");
|
||||
if (n != sizeof(r))
|
||||
log_debug_errno(SYNTHETIC_ERRNO(EIO), "Sent unexpectedly short message");
|
||||
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -39,5 +39,3 @@ static inline int operation_new_with_bus_reply(Manager *manager, Machine *machin
|
||||
static inline int operation_new_with_varlink_reply(Manager *manager, Machine *machine, pid_t child, sd_varlink *link, int errno_fd, Operation **ret) {
|
||||
return operation_new(manager, machine, child, /* message = */ NULL, link, errno_fd, ret);
|
||||
}
|
||||
|
||||
void report_errno_and_exit(int errno_fd, int r);
|
||||
|
||||
@@ -3522,7 +3522,7 @@ int dissected_image_acquire_metadata(
|
||||
r = detach_mount_namespace_userns(userns_fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to detach mount namespace: %m");
|
||||
goto inner_fail;
|
||||
report_errno_and_exit(error_pipe[1], r);
|
||||
}
|
||||
|
||||
r = dissected_image_mount(
|
||||
@@ -3537,7 +3537,7 @@ int dissected_image_acquire_metadata(
|
||||
DISSECT_IMAGE_USR_NO_ROOT);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to mount dissected image: %m");
|
||||
goto inner_fail;
|
||||
report_errno_and_exit(error_pipe[1], r);
|
||||
}
|
||||
|
||||
for (unsigned k = 0; k < _META_MAX; k++) {
|
||||
@@ -3609,7 +3609,7 @@ int dissected_image_acquire_metadata(
|
||||
|
||||
r = loop_write(fds[2*k+1], &found, sizeof(found));
|
||||
if (r < 0)
|
||||
goto inner_fail;
|
||||
report_errno_and_exit(error_pipe[1], r);
|
||||
|
||||
goto next;
|
||||
}
|
||||
@@ -3629,18 +3629,13 @@ int dissected_image_acquire_metadata(
|
||||
|
||||
r = copy_bytes(fd, fds[2*k+1], UINT64_MAX, 0);
|
||||
if (r < 0)
|
||||
goto inner_fail;
|
||||
report_errno_and_exit(error_pipe[1], r);
|
||||
|
||||
next:
|
||||
fds[2*k+1] = safe_close(fds[2*k+1]);
|
||||
}
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
inner_fail:
|
||||
/* Let parent know the error */
|
||||
(void) write(error_pipe[1], &r, sizeof(r));
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
error_pipe[1] = safe_close(error_pipe[1]);
|
||||
|
||||
+5
-11
@@ -827,12 +827,12 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork
|
||||
if (fork_disable_dump) {
|
||||
r = RET_NERRNO(prctl(PR_SET_DUMPABLE, 0));
|
||||
if (r < 0)
|
||||
goto child_fail;
|
||||
report_errno_and_exit(error_pipe[1], r);
|
||||
}
|
||||
|
||||
r = parse_elf(fd, executable, root, ret ? &buf : NULL, ret_package_metadata ? &package_metadata : NULL);
|
||||
if (r < 0)
|
||||
goto child_fail;
|
||||
report_errno_and_exit(error_pipe[1], r);
|
||||
|
||||
if (buf) {
|
||||
size_t len = strlen(buf);
|
||||
@@ -853,7 +853,7 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork
|
||||
if (r == -EAGAIN)
|
||||
log_warning("Write failed, backtrace will be truncated.");
|
||||
else if (r < 0)
|
||||
goto child_fail;
|
||||
report_errno_and_exit(error_pipe[1], r);
|
||||
|
||||
return_pipe[1] = safe_close(return_pipe[1]);
|
||||
}
|
||||
@@ -866,10 +866,8 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork
|
||||
(void) fcntl(json_pipe[1], F_SETPIPE_SZ, COREDUMP_PIPE_MAX);
|
||||
|
||||
json_out = take_fdopen(&json_pipe[1], "w");
|
||||
if (!json_out) {
|
||||
r = -errno;
|
||||
goto child_fail;
|
||||
}
|
||||
if (!json_out)
|
||||
report_errno_and_exit(error_pipe[1], -errno);
|
||||
|
||||
r = sd_json_variant_dump(package_metadata, SD_JSON_FORMAT_FLUSH, json_out, NULL);
|
||||
if (r < 0)
|
||||
@@ -877,10 +875,6 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork
|
||||
}
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
child_fail:
|
||||
(void) write(error_pipe[1], &r, sizeof(r));
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
error_pipe[1] = safe_close(error_pipe[1]);
|
||||
|
||||
+5
-19
@@ -1011,26 +1011,18 @@ static int mount_in_namespace_legacy(
|
||||
r = path_extract_filename(mount_outside, &mount_outside_fn);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to extract filename from propagation file or directory '%s': %m", mount_outside);
|
||||
goto child_fail;
|
||||
report_errno_and_exit(errno_pipe_fd[1], r);
|
||||
}
|
||||
|
||||
mount_inside = path_join(incoming_path, mount_outside_fn);
|
||||
if (!mount_inside) {
|
||||
r = log_oom_debug();
|
||||
goto child_fail;
|
||||
}
|
||||
if (!mount_inside)
|
||||
report_errno_and_exit(errno_pipe_fd[1], log_oom_debug());
|
||||
|
||||
r = mount_nofollow_verbose(LOG_DEBUG, mount_inside, dest, NULL, MS_MOVE, NULL);
|
||||
if (r < 0)
|
||||
goto child_fail;
|
||||
report_errno_and_exit(errno_pipe_fd[1], r);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
child_fail:
|
||||
(void) write(errno_pipe_fd[1], &r, sizeof(r));
|
||||
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
|
||||
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
|
||||
@@ -1224,14 +1216,8 @@ static int mount_in_namespace(
|
||||
|
||||
r = mount_exchange_graceful(new_mount_fd, dest, /* mount_beneath= */ true);
|
||||
}
|
||||
if (r < 0) {
|
||||
(void) write(errno_pipe_fd[1], &r, sizeof(r));
|
||||
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
|
||||
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
report_errno_and_exit(errno_pipe_fd[1], r);
|
||||
}
|
||||
|
||||
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
|
||||
|
||||
@@ -274,8 +274,7 @@ static int remount_with_timeout(MountPoint *m, bool last_try) {
|
||||
"Failed to remount '%s' read-only: %m",
|
||||
m->path);
|
||||
|
||||
(void) write(pfd[1], &r, sizeof(r)); /* try to send errno up */
|
||||
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
report_errno_and_exit(pfd[1], r);
|
||||
}
|
||||
|
||||
pfd[1] = safe_close(pfd[1]);
|
||||
@@ -337,8 +336,7 @@ static int umount_with_timeout(MountPoint *m, bool last_try) {
|
||||
log_umount_blockers(m->path);
|
||||
}
|
||||
|
||||
(void) write(pfd[1], &r, sizeof(r)); /* try to send errno up */
|
||||
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
report_errno_and_exit(pfd[1], r);
|
||||
}
|
||||
|
||||
pfd[1] = safe_close(pfd[1]);
|
||||
|
||||
Reference in New Issue
Block a user