1
0
mirror of https://github.com/systemd/systemd synced 2025-10-04 11:14:45 +02:00

Compare commits

..

No commits in common. "3d4977a12b0ed298c02fb3b757961de3229ce025" and "1cca606c55399d067272ea8a150df77d22a79c1c" have entirely different histories.

2 changed files with 34 additions and 43 deletions

View File

@ -7,7 +7,6 @@
#include "build-path.h" #include "build-path.h"
#include "device-private.h" #include "device-private.h"
#include "device-util.h" #include "device-util.h"
#include "errno-util.h"
#include "event-util.h" #include "event-util.h"
#include "exec-util.h" #include "exec-util.h"
#include "extract-word.h" #include "extract-word.h"
@ -47,7 +46,6 @@ typedef struct Spawn {
static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userdata) { static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
Spawn *spawn = ASSERT_PTR(userdata); Spawn *spawn = ASSERT_PTR(userdata);
bool read_to_result;
char buf[4096], *p; char buf[4096], *p;
size_t size; size_t size;
ssize_t l; ssize_t l;
@ -56,54 +54,35 @@ static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userd
assert(fd == spawn->fd_stdout || fd == spawn->fd_stderr); assert(fd == spawn->fd_stdout || fd == spawn->fd_stderr);
assert(!spawn->result || spawn->result_len < spawn->result_size); assert(!spawn->result || spawn->result_len < spawn->result_size);
if (fd == spawn->fd_stdout && spawn->result && !spawn->truncated) { if (fd == spawn->fd_stdout && spawn->result) {
/* When reading to the result buffer, use the maximum available size, to detect truncation. */
read_to_result = true;
p = spawn->result + spawn->result_len; p = spawn->result + spawn->result_len;
size = spawn->result_size - spawn->result_len; size = spawn->result_size - spawn->result_len;
assert(size > 0);
} else { } else {
/* When reading to the local buffer, keep the space for the trailing NUL. */
read_to_result = false;
p = buf; p = buf;
size = sizeof(buf) - 1; size = sizeof(buf);
} }
l = read(fd, p, size); l = read(fd, p, size - (p == buf));
if (l < 0) { if (l < 0) {
log_device_full_errno(spawn->device, if (errno == EAGAIN)
ERRNO_IS_TRANSIENT(errno) ? LOG_DEBUG : LOG_WARNING, goto reenable;
errno,
"Failed to read %s of '%s', ignoring: %m", log_device_error_errno(spawn->device, errno,
fd == spawn->fd_stdout ? "stdout" : "stderr", "Failed to read stdout of '%s': %m", spawn->cmd);
spawn->cmd);
return 0;
}
if (l == 0) { /* EOF */
r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
if (r < 0) {
log_device_warning_errno(spawn->device, r,
"Failed to disable %s event source of '%s': %m",
fd == spawn->fd_stdout ? "stdout" : "stderr",
spawn->cmd);
(void) sd_event_exit(sd_event_source_get_event(s), r); /* propagate negative errno */
return r;
}
return 0; return 0;
} }
if (read_to_result) { if ((size_t) l == size) {
if ((size_t) l == size) { log_device_warning(spawn->device, "Truncating stdout of '%s' up to %zu byte.",
log_device_warning(spawn->device, "Truncating stdout of '%s' up to %zu byte.", spawn->cmd, spawn->result_size);
spawn->cmd, spawn->result_size - 1); l--;
l--; spawn->truncated = true;
spawn->truncated = true;
}
spawn->result_len += l;
} }
p[l] = '\0'; p[l] = '\0';
if (fd == spawn->fd_stdout && spawn->result)
spawn->result_len += l;
/* Log output only if we watch stderr. */ /* Log output only if we watch stderr. */
if (l > 0 && spawn->fd_stderr >= 0) { if (l > 0 && spawn->fd_stderr >= 0) {
@ -120,6 +99,16 @@ static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userd
fd == spawn->fd_stdout ? "out" : "err", *q); fd == spawn->fd_stdout ? "out" : "err", *q);
} }
if (l == 0 || spawn->truncated)
return 0;
reenable:
/* Re-enable the event source if we did not encounter EOF */
r = sd_event_source_set_enabled(s, SD_EVENT_ONESHOT);
if (r < 0)
log_device_error_errno(spawn->device, r,
"Failed to reactivate IO source of '%s'", spawn->cmd);
return 0; return 0;
} }
@ -206,12 +195,18 @@ static int spawn_wait(Spawn *spawn) {
r = sd_event_add_io(e, &stdout_source, spawn->fd_stdout, EPOLLIN, on_spawn_io, spawn); r = sd_event_add_io(e, &stdout_source, spawn->fd_stdout, EPOLLIN, on_spawn_io, spawn);
if (r < 0) if (r < 0)
return log_device_debug_errno(spawn->device, r, "Failed to create stdio event source: %m"); return log_device_debug_errno(spawn->device, r, "Failed to create stdio event source: %m");
r = sd_event_source_set_enabled(stdout_source, SD_EVENT_ONESHOT);
if (r < 0)
return log_device_debug_errno(spawn->device, r, "Failed to enable stdio event source: %m");
} }
if (spawn->fd_stderr >= 0) { if (spawn->fd_stderr >= 0) {
r = sd_event_add_io(e, &stderr_source, spawn->fd_stderr, EPOLLIN, on_spawn_io, spawn); r = sd_event_add_io(e, &stderr_source, spawn->fd_stderr, EPOLLIN, on_spawn_io, spawn);
if (r < 0) if (r < 0)
return log_device_debug_errno(spawn->device, r, "Failed to create stderr event source: %m"); return log_device_debug_errno(spawn->device, r, "Failed to create stderr event source: %m");
r = sd_event_source_set_enabled(stderr_source, SD_EVENT_ONESHOT);
if (r < 0)
return log_device_debug_errno(spawn->device, r, "Failed to enable stderr event source: %m");
} }
r = event_add_child_pidref(e, &sigchld_source, &spawn->pidref, WEXITED, on_spawn_sigchld, spawn); r = event_add_child_pidref(e, &sigchld_source, &spawn->pidref, WEXITED, on_spawn_sigchld, spawn);

View File

@ -1259,9 +1259,7 @@ EOF
# Clear superblocks to make the MD device will not be restarted even if the VM is restarted. # Clear superblocks to make the MD device will not be restarted even if the VM is restarted.
# This is a workaround for issue #38240. # This is a workaround for issue #38240.
udevadm settle --timeout=30 mdadm -v --zero-superblock --force "${devices[@]}"
# shellcheck disable=SC2046
mdadm -v --zero-superblock --force $(readlink -f "${devices[@]}")
udevadm settle --timeout=30 udevadm settle --timeout=30
# Check if all expected symlinks were removed after the cleanup # Check if all expected symlinks were removed after the cleanup
@ -1324,9 +1322,7 @@ testcase_mdadm_lvm() {
# Clear superblocks to make the MD device will not be restarted even if the VM is restarted. # Clear superblocks to make the MD device will not be restarted even if the VM is restarted.
# This is a workaround for issue #38240. # This is a workaround for issue #38240.
udevadm settle --timeout=30 mdadm -v --zero-superblock --force "${devices[@]}"
# shellcheck disable=SC2046
mdadm -v --zero-superblock --force $(readlink -f "${devices[@]}")
udevadm settle --timeout=30 udevadm settle --timeout=30
# Check if all expected symlinks were removed after the cleanup # Check if all expected symlinks were removed after the cleanup