#include <sys/ioctl.h>
#include <sys/xattr.h>
#include <unistd.h>
-#include "pidref.h"
#if HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
#include "openssl-util.h"
#include "parse-util.h"
#include "path-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "random-util.h"
#include "reread-partition-table.h"
_cleanup_free_ char *size_str = NULL;
bool re_open = false, re_mount = false;
- _cleanup_(pidref_done) PidRef resize_pidref = PIDREF_NULL, fsck_pidref = PIDREF_NULL;
+ _cleanup_(pidref_done) PidRef fsck_pidref = PIDREF_NULL;
int r, exit_status;
assert(setup);
r = pidref_safe_fork(
"(e2resize)",
FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
- &resize_pidref);
+ /* ret_pid= */ NULL);
if (r < 0)
return r;
if (r == 0) {
if (!callback)
callback = child_exit_callback;
- /* As an optimization we only do these checks on the first child event source created. */
- if (e->n_online_child_sources == 0) {
- r = verify_sigchld(options);
- if (r < 0)
- return r;
- }
+ r = verify_sigchld(options);
+ if (r < 0)
+ return r;
r = hashmap_ensure_allocated(&e->child_sources, NULL);
if (r < 0)
if (!callback)
callback = child_exit_callback;
- if (e->n_online_child_sources == 0) {
- r = verify_sigchld(options);
- if (r < 0)
- return r;
- }
+ r = verify_sigchld(options);
+ if (r < 0)
+ return r;
r = hashmap_ensure_allocated(&e->child_sources, NULL);
if (r < 0)
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
- // TODO: port to PidRef and donate child rather than destroying it
Operation *operation;
r = operation_new(manager, machine, &child, errno_pipe_fd[0], &operation);
if (r < 0)
return r;
TAKE_FD(errno_pipe_fd[0]);
- pidref_done(&child);
+ TAKE_PIDREF(child);
*ret = operation;
return 0;
return -ENOMEM;
*o = (Operation) {
- .pidref = TAKE_PIDREF(*child),
+ .pidref = *child,
.errno_fd = errno_fd,
.extra_fd = -EBADF
};
if (r < 0)
return r;
- TAKE_PIDREF(child);
+ pidref_done(&child);
}
if (!os_release)
if (r < 0)
return r;
- TAKE_PIDREF(child);
+ /* We don't need to disarm child cleanup here because operation_new() takes over ownership internally. */
errno_pipe_fd[0] = -EBADF;
return 1;
if (r < 0)
goto finish;
- TAKE_PIDREF(child);
+ pidref_done(&child);
n = read(error_pipe[0], &v, sizeof(v));
if (n < 0) {
_cleanup_(pidref_freep) PidRef *dup = NULL;
r = pidref_dup(&pidref, &dup);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to duplicate pid reference: %m");
r = hashmap_ensure_put(&pids, &pidref_hash_ops_free_free, dup, t);
if (r < 0)
}
while (!hashmap_isempty(pids)) {
+ _cleanup_(pidref_freep) PidRef *pidref = NULL;
_cleanup_free_ char *t = NULL;
- void *p;
- t = ASSERT_PTR(hashmap_steal_first_key_and_value(pids, &p));
- _cleanup_(pidref_freep) PidRef *pidref = p;
+ t = ASSERT_PTR(hashmap_steal_first_key_and_value(pids, (void**) &pidref));
r = pidref_wait_for_terminate_and_check(t, pidref, WAIT_LOG);
if (r < 0)
const char *process_name = strjoina("(", name, ")");
- PidRef executor_pidref = PIDREF_NULL;
+ _cleanup_(pidref_done) PidRef executor_pidref = PIDREF_NULL;
r = pidref_safe_fork(process_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &executor_pidref);
if (r < 0)
return r;
else if (si.si_code != CLD_EXITED || si.si_status != 0) {
/* Try to read error code from child */
r = read_errno(pfd[0]);
- if (r == -EIO)
+ if (r < 0 && 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(
SYNTHETIC_ERRNO(EPROTO),
"Remounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.",
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);
- TAKE_PIDREF(pidref); /* child exited (just not as we expected) hence don't kill anymore */
+ pidref_done(&pidref); /* child exited (just not as we expected) hence don't kill anymore */
}
return r;
else if (si.si_code != CLD_EXITED || si.si_status != 0) {
/* Try to read error code from child */
r = read_errno(pfd[0]);
- if (r == -EIO)
+ if (r < 0 && 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(
SYNTHETIC_ERRNO(EPROTO),
"Unmounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.",
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);
- TAKE_PIDREF(pidref); /* It died, but abnormally, no purpose in killing */
+ pidref_done(&pidref); /* It died, but abnormally, no purpose in killing */
}
return r;
si->si_pid, signal_to_string(si->si_status));
else
ret = log_error_errno(SYNTHETIC_ERRNO(EPROTO),
- "Got unexpected exit code %i from child,",
+ "Got unexpected exit code %i from child.",
si->si_code);
/* Regardless of whether the main qemu process or an auxiliary process died, let's exit either way