#include "env-util.h"
#include "errno-list.h"
#include "errno-util.h"
+#include "event-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "filesystems.h"
.aliases = TAKE_PTR(aliases),
.uid = hr->uid,
.state = _HOME_STATE_INVALID,
+ .worker_pid = PIDREF_NULL,
.worker_stdout_fd = -EBADF,
.sysfs = TAKE_PTR(ns),
.signed_locally = -1,
if (h->sysfs)
(void) hashmap_remove_value(h->manager->homes_by_sysfs, h->sysfs, h);
- if (h->worker_pid > 0)
- (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h);
+ if (pidref_is_set(&h->worker_pid))
+ (void) hashmap_remove_value(h->manager->homes_by_worker_pid, &h->worker_pid, h);
if (h->manager->gc_focus == h)
h->manager->gc_focus = NULL;
user_record_unref(h->record);
user_record_unref(h->secret);
+ pidref_done_sigkill_wait(&h->worker_pid);
h->worker_event_source = sd_event_source_disable_unref(h->worker_event_source);
safe_close(h->worker_stdout_fd);
free(h->user_name);
assert(s);
assert(si);
- assert(h->worker_pid == si->si_pid);
+ assert(h->worker_pid.pid == si->si_pid);
assert(h->worker_event_source);
assert(h->worker_stdout_fd >= 0);
- (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h);
+ (void) hashmap_remove_value(h->manager->homes_by_worker_pid, &h->worker_pid, h);
- h->worker_pid = 0;
+ pidref_done(&h->worker_pid);
h->worker_event_source = sd_event_source_disable_unref(h->worker_event_source);
if (si->si_code != CLD_EXITED) {
_cleanup_(erase_and_freep) char *formatted = NULL;
_cleanup_close_ int stdin_fd = -EBADF, stdout_fd = -EBADF;
_cleanup_free_ int *blob_fds = NULL;
- pid_t pid = 0;
int r;
assert(h);
assert(verb);
assert(hr);
- if (h->worker_pid != 0)
+ if (pidref_is_set(&h->worker_pid))
return -EBUSY;
assert(h->worker_stdout_fd < 0);
if (stdout_fd < 0)
return stdout_fd;
- r = safe_fork_full("(sd-homework)",
+ _cleanup_(pidref_done_sigkill_wait) PidRef pid = PIDREF_NULL;
+ r = pidref_safe_fork_full("(sd-homework)",
(int[]) { stdin_fd, stdout_fd, STDERR_FILENO },
blob_fds, hashmap_size(blobs),
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_CLOEXEC_OFF|FORK_PACK_FDS|FORK_DEATHSIG_SIGTERM|
_exit(EXIT_FAILURE);
}
- r = sd_event_add_child(h->manager->event, &h->worker_event_source, pid, WEXITED, home_on_worker_process, h);
+ r = event_add_child_pidref(h->manager->event, &h->worker_event_source, &pid, WEXITED, home_on_worker_process, h);
if (r < 0)
return r;
(void) sd_event_source_set_description(h->worker_event_source, "worker");
- r = hashmap_put(h->manager->homes_by_worker_pid, PID_TO_PTR(pid), h);
+ h->worker_pid = TAKE_PIDREF(pid);
+ r = hashmap_put(h->manager->homes_by_worker_pid, &h->worker_pid, h);
if (r < 0) {
+ pidref_done_sigkill_wait(&h->worker_pid);
h->worker_event_source = sd_event_source_disable_unref(h->worker_event_source);
return r;
}
h->worker_stdout_fd = TAKE_FD(stdout_fd);
- h->worker_pid = pid;
h->worker_error_code = 0;
return 0;
assert(h);
- if (h->worker_pid <= 0)
+ if (!pidref_is_set(&h->worker_pid))
return 0;
log_info("Worker process for home %s is still running while exiting. Waiting for it to finish.", h->user_name);
- r = wait_for_terminate_with_timeout(h->worker_pid, 30 * USEC_PER_SEC);
+ r = wait_for_terminate_with_timeout(h->worker_pid.pid, 30 * USEC_PER_SEC);
if (r == -ETIMEDOUT)
log_warning_errno(r, "Waiting for worker process for home %s timed out. Ignoring.", h->user_name);
else if (r < 0)
log_warning_errno(r, "Failed to wait for worker process for home %s. Ignoring.", h->user_name);
- (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h);
- h->worker_pid = 0;
+ (void) hashmap_remove_value(h->manager->homes_by_worker_pid, &h->worker_pid, h);
+ pidref_done(&h->worker_pid);
return 1;
}
#define UID_CLAMP_INTO_HOME_RANGE(rnd) (((uid_t) (rnd) % (HOME_UID_MAX - HOME_UID_MIN + 1)) + HOME_UID_MIN)
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_uid_hash_ops, void, trivial_hash_func, trivial_compare_func, Home, home_free);
-DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_worker_pid_hash_ops, void, trivial_hash_func, trivial_compare_func, Home, home_free);
+DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_worker_pid_hash_ops, PidRef, pidref_hash_func, pidref_compare_func, Home, home_free);
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_sysfs_hash_ops, char, path_hash_func, path_compare, Home, home_free);
static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata);
return 0;
}
- Home *h = hashmap_get(m->homes_by_worker_pid, PID_TO_PTR(sender.pid));
+ Home *h = hashmap_get(m->homes_by_worker_pid, &sender);
if (!h) {
log_warning("Received notify datagram of unknown process, ignoring.");
return 0;