Merge pull request #29594 from poettering/cgroup-rename-ret-params

more pidfdification
This commit is contained in:
Lennart Poettering
2023-10-18 17:25:44 +02:00
committed by GitHub
49 changed files with 708 additions and 422 deletions
+7 -7
View File
@@ -241,14 +241,14 @@ Features:
a local key to it.
* PidRef conversion work:
- pid_is_unwaited() → pidref_is_unwaited()
- pid_is_alive() → pidref_is_alive()
- is_kernel_thread() → pidref_is_kernel_thread()
- pid_is_my_child() → pidref_is_my_child()
- get_process_uid() → pidref_get_uid()
- cg_pid_get_xyz()
- pid_from_same_root_fs()
- get_ctty_devnr()
- mount_image_in_namespace()
- bind_mount_in_namespace()
- pid1: sd_notify() receiver should use SCM_PIDFD to authenticate client
- actually wait for POLLIN on pidref's pidfd in service logic
- exec_spawn()
- cg_pid_get_unit()
- exec_spawn() + safe_fork()
- openpt_allocate_in_namespace()
- sd_bus_creds
- unit_attach_pid_to_cgroup_via_bus()
+76 -72
View File
@@ -291,7 +291,6 @@ static int cg_kill_items(
_cleanup_set_free_ Set *allocated_set = NULL;
bool done = false;
int r, ret = 0, ret_log_kill = 0;
pid_t my_pid;
assert(sig >= 0);
@@ -310,11 +309,8 @@ static int cg_kill_items(
return -ENOMEM;
}
my_pid = getpid_cached();
do {
_cleanup_fclose_ FILE *f = NULL;
pid_t pid = 0;
done = true;
r = cg_enumerate_items(SYSTEMD_CGROUP_CONTROLLER, path, &f, item);
@@ -325,25 +321,32 @@ static int cg_kill_items(
return ret;
}
while ((r = cg_read_pid(f, &pid)) > 0) {
for (;;) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
if ((flags & CGROUP_IGNORE_SELF) && pid == my_pid)
r = cg_read_pidref(f, &pidref);
if (r < 0)
return r;
if (r == 0)
break;
if ((flags & CGROUP_IGNORE_SELF) && pidref_is_self(&pidref))
continue;
if (set_get(s, PID_TO_PTR(pid)) == PID_TO_PTR(pid))
if (set_get(s, PID_TO_PTR(pidref.pid)) == PID_TO_PTR(pidref.pid))
continue;
if (log_kill)
ret_log_kill = log_kill(pid, sig, userdata);
ret_log_kill = log_kill(&pidref, sig, userdata);
/* If we haven't killed this process yet, kill
* it */
if (kill(pid, sig) < 0) {
if (ret >= 0 && errno != ESRCH)
ret = -errno;
/* If we haven't killed this process yet, kill it */
r = pidref_kill(&pidref, sig);
if (r < 0) {
if (ret >= 0 && r != -ESRCH)
ret = r;
} else {
if (flags & CGROUP_SIGCONT)
(void) kill(pid, SIGCONT);
(void) pidref_kill(&pidref, SIGCONT);
if (ret == 0) {
if (log_kill)
@@ -355,7 +358,7 @@ static int cg_kill_items(
done = false;
r = set_put(s, PID_TO_PTR(pid));
r = set_put(s, PID_TO_PTR(pidref.pid));
if (r < 0) {
if (ret >= 0)
return r;
@@ -622,11 +625,11 @@ static int controller_is_v1_accessible(const char *root, const char *controller)
return laccess(cpath, root ? W_OK : F_OK);
}
int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) {
int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **ret) {
int r;
assert(controller);
assert(fs);
assert(ret);
if (!cg_controller_is_valid(controller))
return -EINVAL;
@@ -646,7 +649,7 @@ int cg_get_path_and_check(const char *controller, const char *path, const char *
return r;
}
return cg_get_path(controller, path, suffix, fs);
return cg_get_path(controller, path, suffix, ret);
}
int cg_set_xattr(const char *path, const char *name, const void *value, size_t size, int flags) {
@@ -809,7 +812,7 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **ret_path) {
}
}
int cg_pidref_get_path(const char *controller, PidRef *pidref, char **ret_path) {
int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret_path) {
_cleanup_free_ char *path = NULL;
int r;
@@ -1052,30 +1055,30 @@ int cg_split_spec(const char *spec, char **ret_controller, char **ret_path) {
return 0;
}
int cg_mangle_path(const char *path, char **result) {
int cg_mangle_path(const char *path, char **ret) {
_cleanup_free_ char *c = NULL, *p = NULL;
int r;
assert(path);
assert(result);
assert(ret);
/* First, check if it already is a filesystem path */
if (path_startswith(path, "/sys/fs/cgroup"))
return path_simplify_alloc(path, result);
return path_simplify_alloc(path, ret);
/* Otherwise, treat it as cg spec */
r = cg_split_spec(path, &c, &p);
if (r < 0)
return r;
return cg_get_path(c ?: SYSTEMD_CGROUP_CONTROLLER, p ?: "/", NULL, result);
return cg_get_path(c ?: SYSTEMD_CGROUP_CONTROLLER, p ?: "/", NULL, ret);
}
int cg_get_root_path(char **path) {
int cg_get_root_path(char **ret_path) {
char *p, *e;
int r;
assert(path);
assert(ret_path);
r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p);
if (r < 0)
@@ -1089,17 +1092,17 @@ int cg_get_root_path(char **path) {
if (e)
*e = 0;
*path = p;
*ret_path = p;
return 0;
}
int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
int cg_shift_path(const char *cgroup, const char *root, const char **ret_shifted) {
_cleanup_free_ char *rt = NULL;
char *p;
int r;
assert(cgroup);
assert(shifted);
assert(ret_shifted);
if (!root) {
/* If the root was specified let's use that, otherwise
@@ -1114,20 +1117,20 @@ int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
p = path_startswith(cgroup, root);
if (p && p > cgroup)
*shifted = p - 1;
*ret_shifted = p - 1;
else
*shifted = cgroup;
*ret_shifted = cgroup;
return 0;
}
int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
int cg_pid_get_path_shifted(pid_t pid, const char *root, char **ret_cgroup) {
_cleanup_free_ char *raw = NULL;
const char *c;
int r;
assert(pid >= 0);
assert(cgroup);
assert(ret_cgroup);
r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &raw);
if (r < 0)
@@ -1138,7 +1141,7 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
return r;
if (c == raw)
*cgroup = TAKE_PTR(raw);
*ret_cgroup = TAKE_PTR(raw);
else {
char *n;
@@ -1146,18 +1149,18 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
if (!n)
return -ENOMEM;
*cgroup = n;
*ret_cgroup = n;
}
return 0;
}
int cg_path_decode_unit(const char *cgroup, char **unit) {
int cg_path_decode_unit(const char *cgroup, char **ret_unit) {
char *c, *s;
size_t n;
assert(cgroup);
assert(unit);
assert(ret_unit);
n = strcspn(cgroup, "/");
if (n < 3)
@@ -1173,7 +1176,7 @@ int cg_path_decode_unit(const char *cgroup, char **unit) {
if (!s)
return -ENOMEM;
*unit = s;
*ret_unit = s;
return 0;
}
@@ -1261,17 +1264,17 @@ int cg_path_get_unit_path(const char *path, char **ret) {
return 0;
}
int cg_pid_get_unit(pid_t pid, char **unit) {
int cg_pid_get_unit(pid_t pid, char **ret_unit) {
_cleanup_free_ char *cgroup = NULL;
int r;
assert(unit);
assert(ret_unit);
r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
if (r < 0)
return r;
return cg_path_get_unit(cgroup, unit);
return cg_path_get_unit(cgroup, ret_unit);
}
/**
@@ -1381,20 +1384,20 @@ int cg_path_get_user_unit(const char *path, char **ret) {
return cg_path_get_unit(t, ret);
}
int cg_pid_get_user_unit(pid_t pid, char **unit) {
int cg_pid_get_user_unit(pid_t pid, char **ret_unit) {
_cleanup_free_ char *cgroup = NULL;
int r;
assert(unit);
assert(ret_unit);
r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
if (r < 0)
return r;
return cg_path_get_user_unit(cgroup, unit);
return cg_path_get_user_unit(cgroup, ret_unit);
}
int cg_path_get_machine_name(const char *path, char **machine) {
int cg_path_get_machine_name(const char *path, char **ret_machine) {
_cleanup_free_ char *u = NULL;
const char *sl;
int r;
@@ -1404,20 +1407,20 @@ int cg_path_get_machine_name(const char *path, char **machine) {
return r;
sl = strjoina("/run/systemd/machines/unit:", u);
return readlink_malloc(sl, machine);
return readlink_malloc(sl, ret_machine);
}
int cg_pid_get_machine_name(pid_t pid, char **machine) {
int cg_pid_get_machine_name(pid_t pid, char **ret_machine) {
_cleanup_free_ char *cgroup = NULL;
int r;
assert(machine);
assert(ret_machine);
r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
if (r < 0)
return r;
return cg_path_get_machine_name(cgroup, machine);
return cg_path_get_machine_name(cgroup, ret_machine);
}
int cg_path_get_cgroupid(const char *path, uint64_t *ret) {
@@ -1436,7 +1439,7 @@ int cg_path_get_cgroupid(const char *path, uint64_t *ret) {
return 0;
}
int cg_path_get_session(const char *path, char **session) {
int cg_path_get_session(const char *path, char **ret_session) {
_cleanup_free_ char *unit = NULL;
char *start, *end;
int r;
@@ -1458,20 +1461,20 @@ int cg_path_get_session(const char *path, char **session) {
if (!session_id_valid(start))
return -ENXIO;
if (session) {
if (ret_session) {
char *rr;
rr = strdup(start);
if (!rr)
return -ENOMEM;
*session = rr;
*ret_session = rr;
}
return 0;
}
int cg_pid_get_session(pid_t pid, char **session) {
int cg_pid_get_session(pid_t pid, char **ret_session) {
_cleanup_free_ char *cgroup = NULL;
int r;
@@ -1479,10 +1482,10 @@ int cg_pid_get_session(pid_t pid, char **session) {
if (r < 0)
return r;
return cg_path_get_session(cgroup, session);
return cg_path_get_session(cgroup, ret_session);
}
int cg_path_get_owner_uid(const char *path, uid_t *uid) {
int cg_path_get_owner_uid(const char *path, uid_t *ret_uid) {
_cleanup_free_ char *slice = NULL;
char *start, *end;
int r;
@@ -1496,18 +1499,19 @@ int cg_path_get_owner_uid(const char *path, uid_t *uid) {
start = startswith(slice, "user-");
if (!start)
return -ENXIO;
end = endswith(start, ".slice");
if (!end)
return -ENXIO;
*end = 0;
if (parse_uid(start, uid) < 0)
if (parse_uid(start, ret_uid) < 0)
return -ENXIO;
return 0;
}
int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) {
int cg_pid_get_owner_uid(pid_t pid, uid_t *ret_uid) {
_cleanup_free_ char *cgroup = NULL;
int r;
@@ -1515,14 +1519,14 @@ int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) {
if (r < 0)
return r;
return cg_path_get_owner_uid(cgroup, uid);
return cg_path_get_owner_uid(cgroup, ret_uid);
}
int cg_path_get_slice(const char *p, char **slice) {
int cg_path_get_slice(const char *p, char **ret_slice) {
const char *e = NULL;
assert(p);
assert(slice);
assert(ret_slice);
/* Finds the right-most slice unit from the beginning, but
* stops before we come to the first non-slice unit. */
@@ -1542,11 +1546,11 @@ int cg_path_get_slice(const char *p, char **slice) {
if (!s)
return -ENOMEM;
*slice = s;
*ret_slice = s;
return 0;
}
return cg_path_decode_unit(e, slice);
return cg_path_decode_unit(e, ret_slice);
}
e = p;
@@ -1554,44 +1558,44 @@ int cg_path_get_slice(const char *p, char **slice) {
}
}
int cg_pid_get_slice(pid_t pid, char **slice) {
int cg_pid_get_slice(pid_t pid, char **ret_slice) {
_cleanup_free_ char *cgroup = NULL;
int r;
assert(slice);
assert(ret_slice);
r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
if (r < 0)
return r;
return cg_path_get_slice(cgroup, slice);
return cg_path_get_slice(cgroup, ret_slice);
}
int cg_path_get_user_slice(const char *p, char **slice) {
int cg_path_get_user_slice(const char *p, char **ret_slice) {
const char *t;
assert(p);
assert(slice);
assert(ret_slice);
t = skip_user_prefix(p);
if (!t)
return -ENXIO;
/* And now it looks pretty much the same as for a system
* slice, so let's just use the same parser from here on. */
return cg_path_get_slice(t, slice);
/* And now it looks pretty much the same as for a system slice, so let's just use the same parser
* from here on. */
return cg_path_get_slice(t, ret_slice);
}
int cg_pid_get_user_slice(pid_t pid, char **slice) {
int cg_pid_get_user_slice(pid_t pid, char **ret_slice) {
_cleanup_free_ char *cgroup = NULL;
int r;
assert(slice);
assert(ret_slice);
r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
if (r < 0)
return r;
return cg_path_get_user_slice(cgroup, slice);
return cg_path_get_user_slice(cgroup, ret_slice);
}
bool cg_needs_escape(const char *p) {
+24 -24
View File
@@ -191,20 +191,20 @@ typedef enum CGroupFlags {
CGROUP_REMOVE = 1 << 2,
} CGroupFlags;
typedef int (*cg_kill_log_func_t)(pid_t pid, int sig, void *userdata);
typedef int (*cg_kill_log_func_t)(const PidRef *pid, int sig, void *userdata);
int cg_kill(const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata);
int cg_kill_kernel_sigkill(const char *path);
int cg_kill_recursive(const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata);
int cg_split_spec(const char *spec, char **ret_controller, char **ret_path);
int cg_mangle_path(const char *path, char **result);
int cg_mangle_path(const char *path, char **ret);
int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs);
int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs);
int cg_get_path(const char *controller, const char *path, const char *suffix, char **ret);
int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **ret);
int cg_pid_get_path(const char *controller, pid_t pid, char **path);
int cg_pidref_get_path(const char *controller, PidRef *pidref, char **path);
int cg_pid_get_path(const char *controller, pid_t pid, char **ret);
int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret);
int cg_rmdir(const char *controller, const char *path);
@@ -263,27 +263,27 @@ int cg_is_empty_recursive(const char *controller, const char *path);
int cg_get_root_path(char **path);
int cg_path_get_cgroupid(const char *path, uint64_t *ret);
int cg_path_get_session(const char *path, char **session);
int cg_path_get_owner_uid(const char *path, uid_t *uid);
int cg_path_get_unit(const char *path, char **unit);
int cg_path_get_unit_path(const char *path, char **unit);
int cg_path_get_user_unit(const char *path, char **unit);
int cg_path_get_machine_name(const char *path, char **machine);
int cg_path_get_slice(const char *path, char **slice);
int cg_path_get_user_slice(const char *path, char **slice);
int cg_path_get_session(const char *path, char **ret_session);
int cg_path_get_owner_uid(const char *path, uid_t *ret_uid);
int cg_path_get_unit(const char *path, char **ret_unit);
int cg_path_get_unit_path(const char *path, char **ret_unit);
int cg_path_get_user_unit(const char *path, char **ret_unit);
int cg_path_get_machine_name(const char *path, char **ret_machine);
int cg_path_get_slice(const char *path, char **ret_slice);
int cg_path_get_user_slice(const char *path, char **ret_slice);
int cg_shift_path(const char *cgroup, const char *cached_root, const char **shifted);
int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **cgroup);
int cg_shift_path(const char *cgroup, const char *cached_root, const char **ret_shifted);
int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **ret_cgroup);
int cg_pid_get_session(pid_t pid, char **session);
int cg_pid_get_owner_uid(pid_t pid, uid_t *uid);
int cg_pid_get_unit(pid_t pid, char **unit);
int cg_pid_get_user_unit(pid_t pid, char **unit);
int cg_pid_get_machine_name(pid_t pid, char **machine);
int cg_pid_get_slice(pid_t pid, char **slice);
int cg_pid_get_user_slice(pid_t pid, char **slice);
int cg_pid_get_session(pid_t pid, char **ret_session);
int cg_pid_get_owner_uid(pid_t pid, uid_t *ret_uid);
int cg_pid_get_unit(pid_t pid, char **ret_unit);
int cg_pid_get_user_unit(pid_t pid, char **ret_unit);
int cg_pid_get_machine_name(pid_t pid, char **ret_machine);
int cg_pid_get_slice(pid_t pid, char **ret_slice);
int cg_pid_get_user_slice(pid_t pid, char **ret_slice);
int cg_path_decode_unit(const char *cgroup, char **unit);
int cg_path_decode_unit(const char *cgroup, char **ret_unit);
bool cg_needs_escape(const char *p);
int cg_escape(const char *p, char **ret);
+1 -1
View File
@@ -1451,7 +1451,7 @@ void log_received_signal(int level, const struct signalfd_siginfo *si) {
if (pid_is_valid(si->ssi_pid)) {
_cleanup_free_ char *p = NULL;
(void) get_process_comm(si->ssi_pid, &p);
(void) pid_get_comm(si->ssi_pid, &p);
log_full(level,
"Received SIG%s from PID %"PRIu32" (%s).",
+14 -4
View File
@@ -186,7 +186,7 @@ int pidref_new_from_pid(pid_t pid, PidRef **ret) {
return 0;
}
int pidref_kill(PidRef *pidref, int sig) {
int pidref_kill(const PidRef *pidref, int sig) {
if (!pidref)
return -ESRCH;
@@ -200,7 +200,7 @@ int pidref_kill(PidRef *pidref, int sig) {
return -ESRCH;
}
int pidref_kill_and_sigcont(PidRef *pidref, int sig) {
int pidref_kill_and_sigcont(const PidRef *pidref, int sig) {
int r;
r = pidref_kill(pidref, sig);
@@ -213,7 +213,7 @@ int pidref_kill_and_sigcont(PidRef *pidref, int sig) {
return 0;
}
int pidref_sigqueue(PidRef *pidref, int sig, int value) {
int pidref_sigqueue(const PidRef *pidref, int sig, int value) {
if (!pidref)
return -ESRCH;
@@ -240,7 +240,7 @@ int pidref_sigqueue(PidRef *pidref, int sig, int value) {
return -ESRCH;
}
int pidref_verify(PidRef *pidref) {
int pidref_verify(const PidRef *pidref) {
int r;
/* This is a helper that is supposed to be called after reading information from procfs via a
@@ -250,6 +250,9 @@ int pidref_verify(PidRef *pidref) {
if (!pidref_is_set(pidref))
return -ESRCH;
if (pidref->pid == 1)
return 1; /* PID 1 can never go away, hence never be recycled to a different process → return 1 */
if (pidref->fd < 0)
return 0; /* If we don't have a pidfd we cannot validate it, hence we assume it's all OK → return 0 */
@@ -260,6 +263,13 @@ int pidref_verify(PidRef *pidref) {
return 1; /* We have a pidfd and it still points to the PID we have, hence all is *really* OK → return 1 */
}
bool pidref_is_self(const PidRef *pidref) {
if (!pidref)
return false;
return pidref->pid == getpid_cached();
}
static void pidref_hash_func(const PidRef *pidref, struct siphash *state) {
siphash24_compress(&pidref->pid, sizeof(pidref->pid), state);
}
+6 -4
View File
@@ -43,6 +43,8 @@ static inline int pidref_set_self(PidRef *pidref) {
return pidref_set_pid(pidref, 0);
}
bool pidref_is_self(const PidRef *pidref);
void pidref_done(PidRef *pidref);
PidRef *pidref_free(PidRef *pidref);
DEFINE_TRIVIAL_CLEANUP_FUNC(PidRef*, pidref_free);
@@ -51,11 +53,11 @@ int pidref_dup(const PidRef *pidref, PidRef **ret);
int pidref_new_from_pid(pid_t pid, PidRef **ret);
int pidref_kill(PidRef *pidref, int sig);
int pidref_kill_and_sigcont(PidRef *pidref, int sig);
int pidref_sigqueue(PidRef *pidfref, int sig, int value);
int pidref_kill(const PidRef *pidref, int sig);
int pidref_kill_and_sigcont(const PidRef *pidref, int sig);
int pidref_sigqueue(const PidRef *pidfref, int sig, int value);
int pidref_verify(PidRef *pidref);
int pidref_verify(const PidRef *pidref);
#define TAKE_PIDREF(p) TAKE_GENERIC((p), PidRef, PIDREF_NULL)
+2 -2
View File
@@ -128,7 +128,7 @@ int proc_cmdline(char **ret) {
}
if (detect_container() > 0)
return get_process_cmdline(1, SIZE_MAX, 0, ret);
return pid_get_cmdline(1, SIZE_MAX, 0, ret);
else
return read_full_file("/proc/cmdline", ret, NULL);
}
@@ -147,7 +147,7 @@ static int proc_cmdline_strv_internal(char ***ret, bool filter_pid1_args) {
if (detect_container() > 0) {
_cleanup_strv_free_ char **args = NULL;
r = get_process_cmdline_strv(1, /* flags = */ 0, &args);
r = pid_get_cmdline_strv(1, /* flags = */ 0, &args);
if (r < 0)
return r;
+250 -21
View File
@@ -25,6 +25,7 @@
#include "alloc-util.h"
#include "architecture.h"
#include "argv-util.h"
#include "dirent-util.h"
#include "env-file.h"
#include "env-util.h"
#include "errno-util.h"
@@ -94,7 +95,7 @@ static int get_process_state(pid_t pid) {
return (unsigned char) state;
}
int get_process_comm(pid_t pid, char **ret) {
int pid_get_comm(pid_t pid, char **ret) {
_cleanup_free_ char *escaped = NULL, *comm = NULL;
int r;
@@ -132,15 +133,35 @@ int get_process_comm(pid_t pid, char **ret) {
return 0;
}
static int get_process_cmdline_nulstr(
int pidref_get_comm(const PidRef *pid, char **ret) {
_cleanup_free_ char *comm = NULL;
int r;
if (!pidref_is_set(pid))
return -ESRCH;
r = pid_get_comm(pid->pid, &comm);
if (r < 0)
return r;
r = pidref_verify(pid);
if (r < 0)
return r;
if (ret)
*ret = TAKE_PTR(comm);
return 0;
}
static int pid_get_cmdline_nulstr(
pid_t pid,
size_t max_size,
ProcessCmdlineFlags flags,
char **ret,
size_t *ret_size) {
_cleanup_free_ char *t = NULL;
const char *p;
char *t;
size_t k;
int r;
@@ -164,18 +185,17 @@ static int get_process_cmdline_nulstr(
return r;
if (k == 0) {
t = mfree(t);
if (!(flags & PROCESS_CMDLINE_COMM_FALLBACK))
return -ENOENT;
/* Kernel threads have no argv[] */
_cleanup_free_ char *comm = NULL;
r = get_process_comm(pid, &comm);
r = pid_get_comm(pid, &comm);
if (r < 0)
return r;
free(t);
t = strjoin("[", comm, "]");
if (!t)
return -ENOMEM;
@@ -186,12 +206,15 @@ static int get_process_cmdline_nulstr(
t[max_size] = '\0';
}
*ret = t;
*ret_size = k;
if (ret)
*ret = TAKE_PTR(t);
if (ret_size)
*ret_size = k;
return r;
}
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
int pid_get_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
_cleanup_free_ char *t = NULL;
size_t k;
char *ans;
@@ -213,7 +236,7 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
* Returns -ESRCH if the process doesn't exist, and -ENOENT if the process has no command line (and
* PROCESS_CMDLINE_COMM_FALLBACK is not specified). Returns 0 and sets *line otherwise. */
int full = get_process_cmdline_nulstr(pid, max_columns, flags, &t, &k);
int full = pid_get_cmdline_nulstr(pid, max_columns, flags, &t, &k);
if (full < 0)
return full;
@@ -256,7 +279,27 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
return 0;
}
int get_process_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret) {
int pidref_get_cmdline(const PidRef *pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
_cleanup_free_ char *s = NULL;
int r;
if (!pidref_is_set(pid))
return -ESRCH;
r = pid_get_cmdline(pid->pid, max_columns, flags, &s);
if (r < 0)
return r;
r = pidref_verify(pid);
if (r < 0)
return r;
if (ret)
*ret = TAKE_PTR(s);
return 0;
}
int pid_get_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret) {
_cleanup_free_ char *t = NULL;
char **args;
size_t k;
@@ -266,7 +309,7 @@ int get_process_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret)
assert((flags & ~PROCESS_CMDLINE_COMM_FALLBACK) == 0);
assert(ret);
r = get_process_cmdline_nulstr(pid, SIZE_MAX, flags, &t, &k);
r = pid_get_cmdline_nulstr(pid, SIZE_MAX, flags, &t, &k);
if (r < 0)
return r;
@@ -278,6 +321,27 @@ int get_process_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret)
return 0;
}
int pidref_get_cmdline_strv(const PidRef *pid, ProcessCmdlineFlags flags, char ***ret) {
_cleanup_strv_free_ char **args = NULL;
int r;
if (!pidref_is_set(pid))
return -ESRCH;
r = pid_get_cmdline_strv(pid->pid, flags, &args);
if (r < 0)
return r;
r = pidref_verify(pid);
if (r < 0)
return r;
if (ret)
*ret = TAKE_PTR(args);
return 0;
}
int container_get_leader(const char *machine, pid_t *pid) {
_cleanup_free_ char *s = NULL, *class = NULL;
const char *p;
@@ -346,7 +410,7 @@ int namespace_get_leader(pid_t pid, NamespaceType type, pid_t *ret) {
}
}
int is_kernel_thread(pid_t pid) {
int pid_is_kernel_thread(pid_t pid) {
_cleanup_free_ char *line = NULL;
unsigned long long flags;
size_t l, i;
@@ -404,6 +468,23 @@ int is_kernel_thread(pid_t pid) {
return !!(flags & PF_KTHREAD);
}
int pidref_is_kernel_thread(const PidRef *pid) {
int result, r;
if (!pidref_is_set(pid))
return -ESRCH;
result = pid_is_kernel_thread(pid->pid);
if (result < 0)
return result;
r = pidref_verify(pid); /* Verify that the PID wasn't reused since */
if (r < 0)
return r;
return result;
}
int get_process_capeff(pid_t pid, char **ret) {
const char *p;
int r;
@@ -492,7 +573,8 @@ static int get_process_id(pid_t pid, const char *field, uid_t *ret) {
return -EIO;
}
int get_process_uid(pid_t pid, uid_t *ret) {
int pid_get_uid(pid_t pid, uid_t *ret) {
assert(ret);
if (pid == 0 || pid == getpid_cached()) {
*ret = getuid();
@@ -502,6 +584,26 @@ int get_process_uid(pid_t pid, uid_t *ret) {
return get_process_id(pid, "Uid:", ret);
}
int pidref_get_uid(const PidRef *pid, uid_t *ret) {
uid_t uid;
int r;
if (!pidref_is_set(pid))
return -ESRCH;
r = pid_get_uid(pid->pid, &uid);
if (r < 0)
return r;
r = pidref_verify(pid);
if (r < 0)
return r;
if (ret)
*ret = uid;
return 0;
}
int get_process_gid(pid_t pid, gid_t *ret) {
if (pid == 0 || pid == getpid_cached()) {
@@ -692,7 +794,7 @@ int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) {
assert(pid > 1);
if (!name) {
r = get_process_comm(pid, &buffer);
r = pid_get_comm(pid, &buffer);
if (r < 0)
log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pid);
else
@@ -914,6 +1016,9 @@ int pid_is_my_child(pid_t pid) {
pid_t ppid;
int r;
if (pid < 0)
return -ESRCH;
if (pid <= 1)
return false;
@@ -924,11 +1029,28 @@ int pid_is_my_child(pid_t pid) {
return ppid == getpid_cached();
}
bool pid_is_unwaited(pid_t pid) {
int pidref_is_my_child(const PidRef *pid) {
int r, result;
if (!pidref_is_set(pid))
return -ESRCH;
result = pid_is_my_child(pid->pid);
if (result < 0)
return result;
r = pidref_verify(pid);
if (r < 0)
return r;
return result;
}
int pid_is_unwaited(pid_t pid) {
/* Checks whether a PID is still valid at all, including a zombie */
if (pid < 0)
return false;
return -ESRCH;
if (pid <= 1) /* If we or PID 1 would be dead and have been waited for, this code would not be running */
return true;
@@ -942,13 +1064,31 @@ bool pid_is_unwaited(pid_t pid) {
return errno != ESRCH;
}
bool pid_is_alive(pid_t pid) {
int pidref_is_unwaited(const PidRef *pid) {
int r;
if (!pidref_is_set(pid))
return -ESRCH;
if (pid->pid == 1 || pidref_is_self(pid))
return true;
r = pidref_kill(pid, 0);
if (r == -ESRCH)
return false;
if (r < 0)
return r;
return true;
}
int pid_is_alive(pid_t pid) {
int r;
/* Checks whether a PID is still valid and not a zombie */
if (pid < 0)
return false;
return -ESRCH;
if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
return true;
@@ -957,10 +1097,31 @@ bool pid_is_alive(pid_t pid) {
return true;
r = get_process_state(pid);
if (IN_SET(r, -ESRCH, 'Z'))
if (r == -ESRCH)
return false;
if (r < 0)
return r;
return true;
return r != 'Z';
}
int pidref_is_alive(const PidRef *pidref) {
int r, result;
if (!pidref_is_set(pidref))
return -ESRCH;
result = pid_is_alive(pidref->pid);
if (result < 0)
return result;
r = pidref_verify(pidref);
if (r == -ESRCH)
return false;
if (r < 0)
return r;
return result;
}
int pid_from_same_root_fs(pid_t pid) {
@@ -1803,6 +1964,74 @@ fail:
return -r;
}
int proc_dir_open(DIR **ret) {
DIR *d;
assert(ret);
d = opendir("/proc");
if (!d)
return -errno;
*ret = d;
return 0;
}
int proc_dir_read(DIR *d, pid_t *ret) {
assert(d);
for (;;) {
struct dirent *de;
errno = 0;
de = readdir_no_dot(d);
if (!de) {
if (errno != 0)
return -errno;
break;
}
if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
continue;
if (parse_pid(de->d_name, ret) >= 0)
return 1;
}
if (ret)
*ret = 0;
return 0;
}
int proc_dir_read_pidref(DIR *d, PidRef *ret) {
int r;
assert(d);
for (;;) {
pid_t pid;
r = proc_dir_read(d, &pid);
if (r < 0)
return r;
if (r == 0)
break;
r = pidref_set_pid(ret, pid);
if (r == -ESRCH) /* gone by now? skip it */
continue;
if (r < 0)
return r;
return 1;
}
if (ret)
*ret = PIDREF_NULL;
return 0;
}
static const char *const sigchld_code_table[] = {
[CLD_EXITED] = "exited",
[CLD_KILLED] = "killed",
+19 -7
View File
@@ -39,11 +39,15 @@ typedef enum ProcessCmdlineFlags {
PROCESS_CMDLINE_QUOTE_POSIX = 1 << 3,
} ProcessCmdlineFlags;
int get_process_comm(pid_t pid, char **ret);
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret);
int get_process_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret);
int pid_get_comm(pid_t pid, char **ret);
int pidref_get_comm(const PidRef *pid, char **ret);
int pid_get_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret);
int pidref_get_cmdline(const PidRef *pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret);
int pid_get_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret);
int pidref_get_cmdline_strv(const PidRef *pid, ProcessCmdlineFlags flags, char ***ret);
int get_process_exe(pid_t pid, char **ret);
int get_process_uid(pid_t pid, uid_t *ret);
int pid_get_uid(pid_t pid, uid_t *ret);
int pidref_get_uid(const PidRef *pid, uid_t *ret);
int get_process_gid(pid_t pid, gid_t *ret);
int get_process_capeff(pid_t pid, char **ret);
int get_process_cwd(pid_t pid, char **ret);
@@ -77,13 +81,17 @@ void sigkill_nowaitp(pid_t *pid);
int kill_and_sigcont(pid_t pid, int sig);
int is_kernel_thread(pid_t pid);
int pid_is_kernel_thread(pid_t pid);
int pidref_is_kernel_thread(const PidRef *pid);
int getenv_for_pid(pid_t pid, const char *field, char **_value);
bool pid_is_alive(pid_t pid);
bool pid_is_unwaited(pid_t pid);
int pid_is_alive(pid_t pid);
int pidref_is_alive(const PidRef *pidref);
int pid_is_unwaited(pid_t pid);
int pidref_is_unwaited(const PidRef *pidref);
int pid_is_my_child(pid_t pid);
int pidref_is_my_child(const PidRef *pidref);
int pid_from_same_root_fs(pid_t pid);
bool is_main_thread(void);
@@ -215,3 +223,7 @@ int is_reaper_process(void);
int make_reaper_process(bool b);
int posix_spawn_wrapper(const char *path, char *const *argv, char *const *envp, pid_t *ret_pid);
int proc_dir_open(DIR **ret);
int proc_dir_read(DIR *d, pid_t *ret);
int proc_dir_read_pidref(DIR *d, PidRef *ret);
+1 -1
View File
@@ -209,7 +209,7 @@ static int process(
g->n_tasks = 0;
while (cg_read_pid(f, &pid) > 0) {
if (arg_count == COUNT_USERSPACE_PROCESSES && is_kernel_thread(pid) > 0)
if (arg_count == COUNT_USERSPACE_PROCESSES && pid_is_kernel_thread(pid) > 0)
continue;
g->n_tasks++;
+1 -1
View File
@@ -991,7 +991,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
if (packet.v5_packet.pid > 0) {
_cleanup_free_ char *p = NULL;
(void) get_process_comm(packet.v5_packet.pid, &p);
(void) pid_get_comm(packet.v5_packet.pid, &p);
log_unit_info(UNIT(a), "Got automount request for %s, triggered by %"PRIu32" (%s)", a->where, packet.v5_packet.pid, strna(p));
} else
log_unit_debug(UNIT(a), "Got direct mount request on %s", a->where);
+2 -2
View File
@@ -3175,7 +3175,7 @@ int unit_search_main_pid(Unit *u, PidRef *ret) {
if (pidref_equal(&pidref, &npidref)) /* seen already, cgroupfs reports duplicates! */
continue;
if (pid_is_my_child(npidref.pid) == 0) /* ignore processes further down the tree */
if (pidref_is_my_child(&npidref) <= 0) /* ignore processes further down the tree */
continue;
if (pidref_is_set(&pidref) != 0)
@@ -3913,7 +3913,7 @@ Unit *manager_get_unit_by_pidref(Manager *m, PidRef *pid) {
if (!pidref_is_set(pid))
return NULL;
if (pid->pid == getpid_cached())
if (pidref_is_self(pid))
return hashmap_get(m->units, SPECIAL_INIT_SCOPE);
if (pid->pid == 1)
return NULL;
+26 -18
View File
@@ -1232,21 +1232,21 @@ static int property_get_cgroup(
return sd_bus_message_append(reply, "s", t);
}
static int append_process(sd_bus_message *reply, const char *p, pid_t pid, Set *pids) {
static int append_process(sd_bus_message *reply, const char *p, PidRef *pid, Set *pids) {
_cleanup_free_ char *buf = NULL, *cmdline = NULL;
int r;
assert(reply);
assert(pid > 0);
assert(pidref_is_set(pid));
r = set_put(pids, PID_TO_PTR(pid));
r = set_put(pids, PID_TO_PTR(pid->pid));
if (IN_SET(r, 0, -EEXIST))
return 0;
if (r < 0)
return r;
if (!p) {
r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &buf);
r = cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &buf);
if (r == -ESRCH)
return 0;
if (r < 0)
@@ -1255,14 +1255,16 @@ static int append_process(sd_bus_message *reply, const char *p, pid_t pid, Set *
p = buf;
}
(void) get_process_cmdline(pid, SIZE_MAX,
PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE,
&cmdline);
(void) pidref_get_cmdline(
pid,
SIZE_MAX,
PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE,
&cmdline);
return sd_bus_message_append(reply,
"(sus)",
p,
(uint32_t) pid,
(uint32_t) pid->pid,
cmdline);
}
@@ -1281,22 +1283,28 @@ static int append_cgroup(sd_bus_message *reply, const char *p, Set *pids) {
return r;
for (;;) {
pid_t pid;
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
/* libvirt / qemu uses threaded mode and cgroup.procs cannot be read at the lower levels.
* From https://docs.kernel.org/admin-guide/cgroup-v2.html#threads,
* “cgroup.procs” in a threaded domain cgroup contains the PIDs of all processes in
* the subtree and is not readable in the subtree proper. */
r = cg_read_pid(f, &pid);
* From https://docs.kernel.org/admin-guide/cgroup-v2.html#threads, “cgroup.procs” in a
* threaded domain cgroup contains the PIDs of all processes in the subtree and is not
* readable in the subtree proper. */
r = cg_read_pidref(f, &pidref);
if (IN_SET(r, 0, -EOPNOTSUPP))
break;
if (r < 0)
return r;
if (is_kernel_thread(pid) > 0)
r = pidref_is_kernel_thread(&pidref);
if (r == -ESRCH) /* gone by now */
continue;
if (r < 0)
log_debug_errno(r, "Failed to determine if " PID_FMT " is a kernel thread, assuming not: %m", pidref.pid);
if (r > 0)
continue;
r = append_process(reply, p, pid, pids);
r = append_process(reply, p, &pidref, pids);
if (r < 0)
return r;
}
@@ -1361,14 +1369,14 @@ int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bu
/* The main and control pids might live outside of the cgroup, hence fetch them separately */
PidRef *pid = unit_main_pid(u);
if (pidref_is_set(pid)) {
r = append_process(reply, NULL, pid->pid, pids);
r = append_process(reply, NULL, pid, pids);
if (r < 0)
return r;
}
pid = unit_control_pid(u);
if (pidref_is_set(pid)) {
r = append_process(reply, NULL, pid->pid, pids);
r = append_process(reply, NULL, pid, pids);
if (r < 0)
return r;
}
@@ -1522,7 +1530,7 @@ int bus_unit_method_attach_processes(sd_bus_message *message, void *userdata, sd
/* Let's validate security: if the sender is root, then all is OK. If the sender is any other unit,
* then the process' UID and the target unit's UID have to match the sender's UID */
if (sender_uid != 0 && sender_uid != getuid()) {
r = get_process_uid(pidref->pid, &process_uid);
r = pidref_get_uid(pidref, &process_uid);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to retrieve process UID: %m");
+1 -1
View File
@@ -2823,7 +2823,7 @@ static int manager_dispatch_sigchld(sd_event_source *source, void *userdata) {
_cleanup_free_ char *name = NULL;
Unit *u1, *u2, **array;
(void) get_process_comm(si.si_pid, &name);
(void) pid_get_comm(si.si_pid, &name);
log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)",
si.si_pid, strna(name),
+1 -1
View File
@@ -796,7 +796,7 @@ static int mount_coldplug(Unit *u) {
return 0;
if (pidref_is_set(&m->control_pid) &&
pid_is_unwaited(m->control_pid.pid) &&
pidref_is_unwaited(&m->control_pid) > 0 &&
MOUNT_STATE_WITH_PROCESS(m->deserialized_state)) {
r = unit_watch_pidref(UNIT(m), &m->control_pid, /* exclusive= */ false);
+18 -9
View File
@@ -180,6 +180,8 @@ static void service_unwatch_pid_file(Service *s) {
}
static int service_set_main_pidref(Service *s, PidRef *pidref) {
int r;
assert(s);
/* Takes ownership of the specified pidref on success, but not on failure. */
@@ -190,7 +192,7 @@ static int service_set_main_pidref(Service *s, PidRef *pidref) {
if (pidref->pid <= 1)
return -EINVAL;
if (pidref->pid == getpid_cached())
if (pidref_is_self(pidref))
return -EINVAL;
if (pidref_equal(&s->main_pid, pidref) && s->main_pid_known) {
@@ -205,11 +207,14 @@ static int service_set_main_pidref(Service *s, PidRef *pidref) {
s->main_pid = TAKE_PIDREF(*pidref);
s->main_pid_known = true;
s->main_pid_alien = pid_is_my_child(s->main_pid.pid) == 0;
if (s->main_pid_alien)
r = pidref_is_my_child(&s->main_pid);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "Can't determine if process "PID_FMT" is our child, assuming it is not: %m", s->main_pid.pid);
else if (r == 0)
log_unit_warning(UNIT(s), "Supervising process "PID_FMT" which is not our child. We'll most likely not notice when it exits.", s->main_pid.pid);
s->main_pid_alien = r <= 0;
return 0;
}
@@ -1053,6 +1058,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
static int service_is_suitable_main_pid(Service *s, PidRef *pid, int prio) {
Unit *owner;
int r;
assert(s);
assert(pidref_is_set(pid));
@@ -1061,14 +1067,17 @@ static int service_is_suitable_main_pid(Service *s, PidRef *pid, int prio) {
* PID is questionnable but should be accepted if the source of configuration is trusted. > 0 if the PID is
* good */
if (pid->pid == getpid_cached() || pid->pid == 1)
if (pidref_is_self(pid) || pid->pid == 1)
return log_unit_full_errno(UNIT(s), prio, SYNTHETIC_ERRNO(EPERM), "New main PID "PID_FMT" is the manager, refusing.", pid->pid);
if (pidref_equal(pid, &s->control_pid))
return log_unit_full_errno(UNIT(s), prio, SYNTHETIC_ERRNO(EPERM), "New main PID "PID_FMT" is the control process, refusing.", pid->pid);
if (!pid_is_alive(pid->pid))
r = pidref_is_alive(pid);
if (r == 0)
return log_unit_full_errno(UNIT(s), prio, SYNTHETIC_ERRNO(ESRCH), "New main PID "PID_FMT" does not exist or is a zombie.", pid->pid);
if (r < 0)
return log_unit_full_errno(UNIT(s), prio, r, "Failed to check if main PID "PID_FMT" exists or is a zombie.", pid->pid);
owner = manager_get_unit_by_pidref(UNIT(s)->manager, pid);
if (owner == UNIT(s)) {
@@ -1317,7 +1326,7 @@ static int service_coldplug(Unit *u) {
return r;
if (pidref_is_set(&s->main_pid) &&
pid_is_unwaited(s->main_pid.pid) &&
pidref_is_unwaited(&s->main_pid) > 0 &&
(IN_SET(s->deserialized_state,
SERVICE_START, SERVICE_START_POST,
SERVICE_RUNNING,
@@ -1330,7 +1339,7 @@ static int service_coldplug(Unit *u) {
}
if (pidref_is_set(&s->control_pid) &&
pid_is_unwaited(s->control_pid.pid) &&
pidref_is_unwaited(&s->control_pid) > 0 &&
IN_SET(s->deserialized_state,
SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY,
@@ -1827,7 +1836,7 @@ static int main_pid_good(Service *s) {
/* If it's an alien child let's check if it is still alive ... */
if (s->main_pid_alien && pidref_is_set(&s->main_pid))
return pid_is_alive(s->main_pid.pid);
return pidref_is_alive(&s->main_pid);
/* .. otherwise assume we'll get a SIGCHLD for it, which we really should wait for to collect
* exit status and code */
@@ -2295,7 +2304,7 @@ static void service_kill_control_process(Service *s) {
if (r < 0) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(s->control_pid.pid, &comm);
(void) pidref_get_comm(&s->control_pid, &comm);
log_unit_debug_errno(UNIT(s), r, "Failed to kill control process " PID_FMT " (%s), ignoring: %m",
s->control_pid.pid, strna(comm));
+1 -1
View File
@@ -1852,7 +1852,7 @@ static int socket_coldplug(Unit *u) {
return 0;
if (pidref_is_set(&s->control_pid) &&
pid_is_unwaited(s->control_pid.pid) &&
pidref_is_unwaited(&s->control_pid) > 0 &&
IN_SET(s->deserialized_state,
SOCKET_START_PRE,
SOCKET_START_CHOWN,
+1 -1
View File
@@ -557,7 +557,7 @@ static int swap_coldplug(Unit *u) {
return 0;
if (pidref_is_set(&s->control_pid) &&
pid_is_unwaited(s->control_pid.pid) &&
pidref_is_unwaited(&s->control_pid) > 0 &&
SWAP_STATE_WITH_PROCESS(new_state)) {
r = unit_watch_pidref(UNIT(s), &s->control_pid, /* exclusive= */ false);
+28 -22
View File
@@ -2982,7 +2982,7 @@ static void unit_tidy_watch_pids(Unit *u) {
if (pidref_equal(except1, e) || pidref_equal(except2, e))
continue;
if (!pid_is_unwaited(e->pid))
if (pidref_is_unwaited(e) <= 0)
unit_unwatch_pidref(u, e);
}
}
@@ -4006,13 +4006,14 @@ static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
return TAKE_PTR(pid_set);
}
static int kill_common_log(pid_t pid, int signo, void *userdata) {
static int kill_common_log(const PidRef *pid, int signo, void *userdata) {
_cleanup_free_ char *comm = NULL;
Unit *u = ASSERT_PTR(userdata);
(void) get_process_comm(pid, &comm);
(void) pidref_get_comm(pid, &comm);
log_unit_info(u, "Sending signal SIG%s to process " PID_FMT " (%s) on client request.",
signal_to_string(signo), pid, strna(comm));
signal_to_string(signo), pid->pid, strna(comm));
return 1;
}
@@ -4081,7 +4082,7 @@ int unit_kill(
if (pidref_is_set(control_pid) &&
IN_SET(who, KILL_CONTROL, KILL_CONTROL_FAIL, KILL_ALL, KILL_ALL_FAIL)) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(control_pid->pid, &comm);
(void) pidref_get_comm(control_pid, &comm);
r = kill_or_sigqueue(control_pid, signo, code, value);
if (r < 0) {
@@ -4105,9 +4106,8 @@ int unit_kill(
if (pidref_is_set(main_pid) &&
IN_SET(who, KILL_MAIN, KILL_MAIN_FAIL, KILL_ALL, KILL_ALL_FAIL)) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(main_pid->pid, &comm);
(void) pidref_get_comm(main_pid, &comm);
r = kill_or_sigqueue(main_pid, signo, code, value);
if (r < 0) {
@@ -4729,10 +4729,12 @@ int unit_make_transient(Unit *u) {
return 0;
}
static int log_kill(pid_t pid, int sig, void *userdata) {
static int log_kill(const PidRef *pid, int sig, void *userdata) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(pid, &comm);
assert(pidref_is_set(pid));
(void) pidref_get_comm(pid, &comm);
/* Don't log about processes marked with brackets, under the assumption that these are temporary processes
only, like for example systemd's own PAM stub process. */
@@ -4743,7 +4745,7 @@ static int log_kill(pid_t pid, int sig, void *userdata) {
log_unit_notice(userdata,
"Killing process " PID_FMT " (%s) with signal SIG%s.",
pid,
pid->pid,
strna(comm),
signal_to_string(sig));
@@ -4815,12 +4817,12 @@ int unit_kill_context(
if (pidref_is_set(main_pid)) {
if (log_func)
log_func(main_pid->pid, sig, u);
log_func(main_pid, sig, u);
r = pidref_kill_and_sigcont(main_pid, sig);
if (r < 0 && r != -ESRCH) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(main_pid->pid, &comm);
(void) pidref_get_comm(main_pid, &comm);
log_unit_warning_errno(u, r, "Failed to kill main process " PID_FMT " (%s), ignoring: %m", main_pid->pid, strna(comm));
} else {
@@ -4834,12 +4836,12 @@ int unit_kill_context(
if (pidref_is_set(control_pid)) {
if (log_func)
log_func(control_pid->pid, sig, u);
log_func(control_pid, sig, u);
r = pidref_kill_and_sigcont(control_pid, sig);
if (r < 0 && r != -ESRCH) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(control_pid->pid, &comm);
(void) pidref_get_comm(control_pid, &comm);
log_unit_warning_errno(u, r, "Failed to kill control process " PID_FMT " (%s), ignoring: %m", control_pid->pid, strna(comm));
} else {
@@ -5862,10 +5864,12 @@ static bool ignore_leftover_process(const char *comm) {
return comm && comm[0] == '('; /* Most likely our own helper process (PAM?), ignore */
}
int unit_log_leftover_process_start(pid_t pid, int sig, void *userdata) {
int unit_log_leftover_process_start(const PidRef *pid, int sig, void *userdata) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(pid, &comm);
assert(pidref_is_set(pid));
(void) pidref_get_comm(pid, &comm);
if (ignore_leftover_process(comm))
return 0;
@@ -5875,15 +5879,17 @@ int unit_log_leftover_process_start(pid_t pid, int sig, void *userdata) {
log_unit_warning(userdata,
"Found left-over process " PID_FMT " (%s) in control group while starting unit. Ignoring.\n"
"This usually indicates unclean termination of a previous run, or service implementation deficiencies.",
pid, strna(comm));
pid->pid, strna(comm));
return 1;
}
int unit_log_leftover_process_stop(pid_t pid, int sig, void *userdata) {
int unit_log_leftover_process_stop(const PidRef *pid, int sig, void *userdata) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(pid, &comm);
assert(pidref_is_set(pid));
(void) pidref_get_comm(pid, &comm);
if (ignore_leftover_process(comm))
return 0;
@@ -5892,7 +5898,7 @@ int unit_log_leftover_process_stop(pid_t pid, int sig, void *userdata) {
log_unit_info(userdata,
"Unit process " PID_FMT " (%s) remains running after unit stopped.",
pid, strna(comm));
pid->pid, strna(comm));
return 1;
}
@@ -5949,11 +5955,11 @@ int unit_pid_attachable(Unit *u, PidRef *pid, sd_bus_error *error) {
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Process identifier is not valid.");
/* Some extra safety check */
if (pid->pid == 1 || pid->pid == getpid_cached())
if (pid->pid == 1 || pidref_is_self(pid))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Process " PID_FMT " is a manager process, refusing.", pid->pid);
/* Don't even begin to bother with kernel threads */
r = is_kernel_thread(pid->pid);
r = pidref_is_kernel_thread(pid);
if (r == -ESRCH)
return sd_bus_error_setf(error, SD_BUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, "Process with ID " PID_FMT " does not exist.", pid->pid);
if (r < 0)
+3 -2
View File
@@ -1036,8 +1036,9 @@ void unit_unlink_state_files(Unit *u);
int unit_prepare_exec(Unit *u);
int unit_log_leftover_process_start(pid_t pid, int sig, void *userdata);
int unit_log_leftover_process_stop(pid_t pid, int sig, void *userdata);
int unit_log_leftover_process_start(const PidRef* pid, int sig, void *userdata);
int unit_log_leftover_process_stop(const PidRef* pid, int sig, void *userdata);
int unit_warn_leftover_processes(Unit *u, cg_kill_log_func_t log_func);
bool unit_needs_console(Unit *u);
+3 -3
View File
@@ -744,7 +744,7 @@ static int get_process_container_parent_cmdline(pid_t pid, char** cmdline) {
if (r < 0)
return r;
r = get_process_cmdline(container_pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, cmdline);
r = pid_get_cmdline(container_pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, cmdline);
if (r < 0)
return r;
@@ -1218,7 +1218,7 @@ static int gather_pid_metadata_from_procfs(struct iovec_wrapper *iovw, Context *
pid = context->pid;
/* The following is mandatory */
r = get_process_comm(pid, &t);
r = pid_get_comm(pid, &t);
if (r < 0)
return log_error_errno(r, "Failed to get COMM: %m");
@@ -1251,7 +1251,7 @@ static int gather_pid_metadata_from_procfs(struct iovec_wrapper *iovw, Context *
if (sd_pid_get_slice(pid, &t) >= 0)
(void) iovw_put_string_field_free(iovw, "COREDUMP_SLICE=", t);
if (get_process_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &t) >= 0)
if (pid_get_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &t) >= 0)
(void) iovw_put_string_field_free(iovw, "COREDUMP_CMDLINE=", t);
if (cg_pid_get_path_shifted(pid, NULL, &t) >= 0)
+1 -1
View File
@@ -66,7 +66,7 @@ void server_forward_console(
/* Second: identifier and PID */
if (ucred) {
if (!identifier) {
(void) get_process_comm(ucred->pid, &ident_buf);
(void) pid_get_comm(ucred->pid, &ident_buf);
identifier = ident_buf;
}
+4 -4
View File
@@ -210,7 +210,7 @@ static void client_context_read_uid_gid(ClientContext *c, const struct ucred *uc
if (ucred && uid_is_valid(ucred->uid))
c->uid = ucred->uid;
else
(void) get_process_uid(c->pid, &c->uid);
(void) pid_get_uid(c->pid, &c->uid);
if (ucred && gid_is_valid(ucred->gid))
c->gid = ucred->gid;
@@ -224,13 +224,13 @@ static void client_context_read_basic(ClientContext *c) {
assert(c);
assert(pid_is_valid(c->pid));
if (get_process_comm(c->pid, &t) >= 0)
if (pid_get_comm(c->pid, &t) >= 0)
free_and_replace(c->comm, t);
if (get_process_exe(c->pid, &t) >= 0)
free_and_replace(c->exe, t);
if (get_process_cmdline(c->pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &t) >= 0)
if (pid_get_cmdline(c->pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &t) >= 0)
free_and_replace(c->cmdline, t);
if (get_process_capeff(c->pid, &t) >= 0)
@@ -609,7 +609,7 @@ static void client_context_try_shrink_to(Server *s, size_t limit) {
assert(c->n_ref == 0);
if (!pid_is_unwaited(c->pid))
if (pid_is_unwaited(c->pid) == 0)
client_context_free(s, c);
else
idx ++;
+1 -1
View File
@@ -61,7 +61,7 @@ void server_forward_kmsg(
/* Second: identifier and PID */
if (ucred) {
if (!identifier) {
(void) get_process_comm(ucred->pid, &ident_buf);
(void) pid_get_comm(ucred->pid, &ident_buf);
identifier = ident_buf;
}
+1 -1
View File
@@ -154,7 +154,7 @@ void server_forward_syslog(Server *s, int priority, const char *identifier, cons
/* Third: identifier and PID */
if (ucred) {
if (!identifier) {
(void) get_process_comm(ucred->pid, &ident_buf);
(void) pid_get_comm(ucred->pid, &ident_buf);
identifier = ident_buf;
}
+1 -1
View File
@@ -27,7 +27,7 @@ void server_forward_wall(
if (ucred) {
if (!identifier) {
(void) get_process_comm(ucred->pid, &ident_buf);
(void) pid_get_comm(ucred->pid, &ident_buf);
identifier = ident_buf;
}
+16 -16
View File
@@ -139,7 +139,7 @@ sd_bus_creds* bus_creds_new(void) {
}
_public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
sd_bus_creds *c;
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL;
int r;
assert_return(pid >= 0, -EINVAL);
@@ -154,19 +154,18 @@ _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t m
return -ENOMEM;
r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
if (r < 0) {
sd_bus_creds_unref(c);
if (r < 0)
return r;
}
/* Check if the process existed at all, in case we haven't
* figured that out already */
if (!pid_is_alive(pid)) {
sd_bus_creds_unref(c);
r = pid_is_alive(pid);
if (r < 0)
return r;
if (r == 0)
return -ESRCH;
}
*ret = c;
*ret = TAKE_PTR(c);
return 0;
}
@@ -969,7 +968,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
}
if (missing & SD_BUS_CREDS_COMM) {
r = get_process_comm(pid, &c->comm);
r = pid_get_comm(pid, &c->comm);
if (r < 0) {
if (!ERRNO_IS_PRIVILEGE(r))
return r;
@@ -1089,15 +1088,16 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
c->mask |= SD_BUS_CREDS_TTY;
}
/* In case only the exe path was to be read we cannot
* distinguish the case where the exe path was unreadable
* because the process was a kernel thread, or when the
* process didn't exist at all. Hence, let's do a final check,
* to be sure. */
if (!pid_is_alive(pid))
/* In case only the exe path was to be read we cannot distinguish the case where the exe path was
* unreadable because the process was a kernel thread, or when the process didn't exist at
* all. Hence, let's do a final check, to be sure. */
r = pid_is_alive(pid);
if (r < 0)
return r;
if (r == 0)
return -ESRCH;
if (tid > 0 && tid != pid && !pid_is_unwaited(tid))
if (tid > 0 && tid != pid && pid_is_unwaited(tid) == 0)
return -ESRCH;
c->augmented = missing & c->mask;
+1 -1
View File
@@ -920,7 +920,7 @@ static int bind_description(sd_bus *b, int fd, int family) {
* - a random 64-bit value (to avoid collisions)
* - our "comm" process name (suppressed if contains "/" to avoid parsing issues)
* - the description string of the bus connection. */
(void) get_process_comm(0, &comm);
(void) pid_get_comm(0, &comm);
if (comm && strchr(comm, '/'))
comm = mfree(comm);
@@ -47,7 +47,7 @@ static void *server(void *p) {
const char *comm;
assert_se(sd_bus_creds_get_comm(c, &comm) >= 0);
assert_se(get_process_comm(0, &our_comm) >= 0);
assert_se(pid_get_comm(0, &our_comm) >= 0);
assert_se(streq_ptr(comm, our_comm));
const char *description;
+1 -1
View File
@@ -91,7 +91,7 @@ static int print_inhibitors(sd_bus *bus) {
if (arg_mode && !streq(mode, arg_mode))
continue;
(void) get_process_comm(pid, &comm);
(void) pid_get_comm(pid, &comm);
u = uid_to_name(uid);
r = table_add_many(table,
+1 -1
View File
@@ -525,7 +525,7 @@ static int print_session_status_info(sd_bus *bus, const char *path) {
if (i.leader > 0) {
_cleanup_free_ char *name = NULL;
(void) get_process_comm(i.leader, &name);
(void) pid_get_comm(i.leader, &name);
r = table_add_cell(table, NULL, TABLE_FIELD, "Leader");
if (r < 0)
+1 -1
View File
@@ -239,7 +239,7 @@ int manager_handle_action(
manager_is_inhibited(m, inhibit_operation, INHIBIT_BLOCK, NULL, false, false, 0, &offending)) {
_cleanup_free_ char *comm = NULL, *u = NULL;
(void) get_process_comm(offending->pid.pid, &comm);
(void) pidref_get_comm(&offending->pid, &comm);
u = uid_to_name(offending->uid);
/* If this is just a recheck of the lid switch then don't warn about anything */
+1 -1
View File
@@ -1650,7 +1650,7 @@ int manager_dispatch_delayed(Manager *manager, bool timeout) {
if (!timeout)
return 0;
(void) get_process_comm(offending->pid.pid, &comm);
(void) pidref_get_comm(&offending->pid, &comm);
u = uid_to_name(offending->uid);
log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
+1 -1
View File
@@ -526,7 +526,7 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
printf("\t Leader: %u", (unsigned) i->leader);
(void) get_process_comm(i->leader, &t);
(void) pid_get_comm(i->leader, &t);
if (t)
printf(" (%s)", t);
+2 -2
View File
@@ -26,8 +26,8 @@ DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
OomdCGroupContext,
oomd_cgroup_context_free);
static int log_kill(pid_t pid, int sig, void *userdata) {
log_debug("oomd attempting to kill " PID_FMT " with %s", pid, signal_to_string(sig));
static int log_kill(const PidRef *pid, int sig, void *userdata) {
log_debug("oomd attempting to kill " PID_FMT " with %s", pid->pid, signal_to_string(sig));
return 0;
}
+1 -1
View File
@@ -611,7 +611,7 @@ int cg_migrate(
* them there. */
if (cfrom &&
empty_or_root(pfrom) &&
is_kernel_thread(pid) > 0)
pid_is_kernel_thread(pid) > 0)
continue;
r = cg_attach(cto, pto, pid);
+9 -9
View File
@@ -31,14 +31,14 @@
static void show_pid_array(
pid_t pids[],
unsigned n_pids,
size_t n_pids,
const char *prefix,
size_t n_columns,
bool extra,
bool more,
OutputFlags flags) {
unsigned i, j, pid_width;
size_t i, j, pid_width;
if (n_pids == 0)
return;
@@ -65,9 +65,9 @@ static void show_pid_array(
for (i = 0; i < n_pids; i++) {
_cleanup_free_ char *t = NULL;
(void) get_process_cmdline(pids[i], n_columns,
PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_USE_LOCALE,
&t);
(void) pid_get_cmdline(pids[i], n_columns,
PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_USE_LOCALE,
&t);
if (extra)
printf("%s%s ", prefix, special_glyph(SPECIAL_GLYPH_TRIANGULAR_BULLET));
@@ -114,7 +114,7 @@ static int show_cgroup_one_by_path(
if (r < 0)
return r;
if (!(flags & OUTPUT_KERNEL_THREADS) && is_kernel_thread(pid) > 0)
if (!(flags & OUTPUT_KERNEL_THREADS) && pid_is_kernel_thread(pid) > 0)
continue;
if (!GREEDY_REALLOC(pids, n + 1))
@@ -334,11 +334,11 @@ static int show_extra_pids(
const char *prefix,
size_t n_columns,
const pid_t pids[],
unsigned n_pids,
size_t n_pids,
OutputFlags flags) {
_cleanup_free_ pid_t *copy = NULL;
unsigned i, j;
size_t i, j;
int r;
assert(path);
@@ -379,7 +379,7 @@ int show_cgroup_and_extra(
const char *prefix,
size_t n_columns,
const pid_t extra_pids[],
unsigned n_extra_pids,
size_t n_extra_pids,
OutputFlags flags) {
int r;
+1 -1
View File
@@ -12,7 +12,7 @@
int show_cgroup_by_path(const char *path, const char *prefix, size_t n_columns, OutputFlags flags);
int show_cgroup(const char *controller, const char *path, const char *prefix, size_t n_columns, OutputFlags flags);
int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, size_t n_columns, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags);
int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, size_t n_columns, const pid_t extra_pids[], size_t n_extra_pids, OutputFlags flags);
int show_cgroup_get_unit_path_and_warn(
sd_bus *bus,
+1 -1
View File
@@ -14,7 +14,7 @@ int sigrtmin18_handler(sd_event_source *s, const struct signalfd_siginfo *si, vo
assert(s);
assert(si);
(void) get_process_comm(si->ssi_pid, &comm);
(void) pid_get_comm(si->ssi_pid, &comm);
if (si->ssi_code != SI_QUEUE) {
log_notice("Received control signal %s from process " PID_FMT " (%s) without command value, ignoring.",
+46 -44
View File
@@ -46,13 +46,15 @@ static bool argv_has_at(pid_t pid) {
return c == '@';
}
static bool is_survivor_cgroup(pid_t pid) {
static bool is_survivor_cgroup(const PidRef *pid) {
_cleanup_free_ char *cgroup_path = NULL;
int r;
r = cg_pid_get_path(/* root= */ NULL, pid, &cgroup_path);
assert(pidref_is_set(pid));
r = cg_pidref_get_path(/* root= */ NULL, pid, &cgroup_path);
if (r < 0) {
log_warning_errno(r, "Failed to get cgroup path of process " PID_FMT ", ignoring: %m", pid);
log_warning_errno(r, "Failed to get cgroup path of process " PID_FMT ", ignoring: %m", pid->pid);
return false;
}
@@ -68,16 +70,18 @@ static bool is_survivor_cgroup(pid_t pid) {
return r > 0;
}
static bool ignore_proc(pid_t pid, bool warn_rootfs) {
static bool ignore_proc(const PidRef *pid, bool warn_rootfs) {
uid_t uid;
int r;
assert(pidref_is_set(pid));
/* We are PID 1, let's not commit suicide */
if (pid <= 1)
if (pid->pid == 1)
return true;
/* Ignore kernel threads */
r = is_kernel_thread(pid);
r = pidref_is_kernel_thread(pid);
if (r != 0)
return true; /* also ignore processes where we can't determine this */
@@ -85,7 +89,7 @@ static bool ignore_proc(pid_t pid, bool warn_rootfs) {
if (is_survivor_cgroup(pid))
return true;
r = get_process_uid(pid, &uid);
r = pidref_get_uid(pid, &uid);
if (r < 0)
return true; /* not really, but better safe than sorry */
@@ -93,20 +97,20 @@ static bool ignore_proc(pid_t pid, bool warn_rootfs) {
if (uid != 0)
return false;
if (!argv_has_at(pid))
if (!argv_has_at(pid->pid))
return false;
if (warn_rootfs &&
pid_from_same_root_fs(pid) == 0) {
pid_from_same_root_fs(pid->pid) == 0) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(pid, &comm);
(void) pidref_get_comm(pid, &comm);
log_notice("Process " PID_FMT " (%s) has been marked to be excluded from killing. It is "
"running from the root file system, and thus likely to block re-mounting of the "
"root file system to read-only. Please consider moving it into an initrd file "
"system instead.", pid, strna(comm));
"system instead.", pid->pid, strna(comm));
}
return true;
@@ -120,12 +124,12 @@ static void log_children_no_yet_killed(Set *pids) {
SET_FOREACH(p, pids) {
_cleanup_free_ char *s = NULL;
if (get_process_comm(PTR_TO_PID(p), &s) >= 0)
if (pid_get_comm(PTR_TO_PID(p), &s) >= 0)
r = strextendf(&lst_child, ", " PID_FMT " (%s)", PTR_TO_PID(p), s);
else
r = strextendf(&lst_child, ", " PID_FMT, PTR_TO_PID(p));
if (r < 0)
return (void) log_oom();
return (void) log_oom_warning();
}
if (isempty(lst_child))
@@ -223,59 +227,57 @@ static int wait_for_children(Set *pids, sigset_t *mask, usec_t timeout) {
static int killall(int sig, Set *pids, bool send_sighup) {
_cleanup_closedir_ DIR *dir = NULL;
int n_killed = 0;
int n_killed = 0, r;
/* Send the specified signal to all remaining processes, if not excluded by ignore_proc().
* Returns the number of processes to which the specified signal was sent */
dir = opendir("/proc");
if (!dir)
return log_warning_errno(errno, "opendir(/proc) failed: %m");
r = proc_dir_open(&dir);
if (r < 0)
return log_warning_errno(r, "opendir(/proc) failed: %m");
FOREACH_DIRENT_ALL(de, dir, break) {
pid_t pid;
int r;
for (;;) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
continue;
r = proc_dir_read_pidref(dir, &pidref);
if (r < 0)
return log_warning_errno(r, "Failed to enumerate /proc: %m");
if (r == 0)
break;
if (parse_pid(de->d_name, &pid) < 0)
continue;
if (ignore_proc(pid, sig == SIGKILL && !in_initrd()))
if (ignore_proc(&pidref, sig == SIGKILL && !in_initrd()))
continue;
if (sig == SIGKILL) {
_cleanup_free_ char *s = NULL;
(void) get_process_comm(pid, &s);
log_notice("Sending SIGKILL to PID "PID_FMT" (%s).", pid, strna(s));
(void) pidref_get_comm(&pidref, &s);
log_notice("Sending SIGKILL to PID "PID_FMT" (%s).", pidref.pid, strna(s));
}
if (kill(pid, sig) >= 0) {
r = pidref_kill(&pidref, sig);
if (r < 0) {
if (errno != -ESRCH)
log_warning_errno(errno, "Could not kill " PID_FMT ", ignoring: %m", pidref.pid);
} else {
n_killed++;
if (pids) {
r = set_put(pids, PID_TO_PTR(pid));
r = set_put(pids, PID_TO_PTR(pidref.pid));
if (r < 0)
log_oom();
(void) log_oom_warning();
}
} else if (errno != ENOENT)
log_warning_errno(errno, "Could not kill %d: %m", pid);
}
if (send_sighup) {
/* Optionally, also send a SIGHUP signal, but
only if the process has a controlling
tty. This is useful to allow handling of
shells which ignore SIGTERM but react to
SIGHUP. We do not send this to processes that
have no controlling TTY since we don't want to
trigger reloads of daemon processes. Also we
make sure to only send this after SIGTERM so
that SIGTERM is always first in the queue. */
/* Optionally, also send a SIGHUP signal, but only if the process has a controlling
* tty. This is useful to allow handling of shells which ignore SIGTERM but react to
* SIGHUP. We do not send this to processes that have no controlling TTY since we
* don't want to trigger reloads of daemon processes. Also we make sure to only send
* this after SIGTERM so that SIGTERM is always first in the queue. */
if (get_ctty_devnr(pid, NULL) >= 0)
if (get_ctty_devnr(pidref.pid, NULL) >= 0)
/* it's OK if the process is gone, just ignore the result */
(void) kill(pid, SIGHUP);
(void) pidref_kill(&pidref, SIGHUP);
}
}
+1 -1
View File
@@ -222,7 +222,7 @@ static void log_umount_blockers(const char *mnt) {
continue;
_cleanup_free_ char *comm = NULL;
r = get_process_comm(pid, &comm);
r = pid_get_comm(pid, &comm);
if (r < 0) {
if (r != -ESRCH) /* process gone by now */
log_debug_errno(r, "Failed to read process name of PID " PID_FMT ": %m", pid);
+1 -1
View File
@@ -168,7 +168,7 @@ int logind_check_inhibitors(enum action a) {
ACTION_KEXEC) ? "shutdown" : "sleep"))
continue;
(void) get_process_comm(pid, &comm);
(void) pid_get_comm(pid, &comm);
user = uid_to_name(uid);
log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
+2 -2
View File
@@ -626,7 +626,7 @@ static void print_status_info(
if (arg_transport == BUS_TRANSPORT_LOCAL) {
_cleanup_free_ char *comm = NULL;
(void) get_process_comm(i->main_pid, &comm);
(void) pid_get_comm(i->main_pid, &comm);
if (comm)
printf(" (%s)", comm);
}
@@ -661,7 +661,7 @@ static void print_status_info(
printf(PID_FMT, i->control_pid);
if (arg_transport == BUS_TRANSPORT_LOCAL) {
(void) get_process_comm(i->control_pid, &c);
(void) pid_get_comm(i->control_pid, &c);
if (c)
printf(" (%s)", c);
}
+2 -2
View File
@@ -35,13 +35,13 @@ static void test_rename_process_now(const char *p, int ret) {
return;
#endif
assert_se(get_process_comm(0, &comm) >= 0);
assert_se(pid_get_comm(0, &comm) >= 0);
log_debug("comm = <%s>", comm);
assert_se(strneq(comm, p, TASK_COMM_LEN-1));
/* We expect comm to be at most 16 bytes (TASK_COMM_LEN). The kernel may raise this limit in the
* future. We'd only check the initial part, at least until we recompile, but this will still pass. */
r = get_process_cmdline(0, SIZE_MAX, 0, &cmdline);
r = pid_get_cmdline(0, SIZE_MAX, 0, &cmdline);
assert_se(r >= 0);
/* we cannot expect cmdline to be renamed properly without privileges */
if (geteuid() == 0) {
+19 -21
View File
@@ -194,35 +194,33 @@ TEST(proc) {
_cleanup_closedir_ DIR *d = NULL;
int r;
d = opendir("/proc");
assert_se(d);
assert_se(proc_dir_open(&d) >= 0);
FOREACH_DIRENT(de, d, break) {
for (;;) {
_cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *slice = NULL;
pid_t pid;
_cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
uid_t uid = UID_INVALID;
if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
r = proc_dir_read_pidref(d, &pid);
assert_se(r >= 0);
if (r == 0)
break;
if (pidref_is_kernel_thread(&pid) != 0)
continue;
r = parse_pid(de->d_name, &pid);
if (r < 0)
continue;
if (is_kernel_thread(pid))
continue;
cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &path);
cg_pid_get_path_shifted(pid, NULL, &path_shifted);
cg_pid_get_owner_uid(pid, &uid);
cg_pid_get_session(pid, &session);
cg_pid_get_unit(pid, &unit);
cg_pid_get_user_unit(pid, &user_unit);
cg_pid_get_machine_name(pid, &machine);
cg_pid_get_slice(pid, &slice);
cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid.pid, &path);
cg_pid_get_path_shifted(pid.pid, NULL, &path_shifted);
cg_pid_get_owner_uid(pid.pid, &uid);
cg_pid_get_session(pid.pid, &session);
cg_pid_get_unit(pid.pid, &unit);
cg_pid_get_user_unit(pid.pid, &user_unit);
cg_pid_get_machine_name(pid.pid, &machine);
cg_pid_get_slice(pid.pid, &slice);
printf(PID_FMT"\t%s\t%s\t"UID_FMT"\t%s\t%s\t%s\t%s\t%s\n",
pid,
pid.pid,
path,
path_shifted,
uid,
+4
View File
@@ -61,6 +61,10 @@ TEST(cg_create) {
log_info("Paths for test:\n%s\n%s", test_a, test_b);
/* Possibly clean up left-overs from aboted previous runs */
(void) cg_trim(SYSTEMD_CGROUP_CONTROLLER, test_a, /* delete_root= */ true);
(void) cg_trim(SYSTEMD_CGROUP_CONTROLLER, test_b, /* delete_root= */ true);
r = cg_create(SYSTEMD_CGROUP_CONTROLLER, test_a);
if (IN_SET(r, -EPERM, -EACCES, -EROFS)) {
log_info_errno(r, "Skipping %s: %m", __func__);
+1 -1
View File
@@ -274,7 +274,7 @@ TEST(proc_cmdline_key_startswith) {
_cleanup_strv_free_ char **a = NULL, **b = NULL; \
const char s[] = (nulstr); \
\
/* This emulates get_process_cmdline_strv(). */ \
/* This emulates pid_get_cmdline_strv(). */ \
assert_se(a = strv_parse_nulstr_full(s, ELEMENTSOF(s), \
/* drop_trailing_nuls = */ true)); \
assert_se(proc_cmdline_filter_pid1_args(a, &b) >= 0); \
+101 -100
View File
@@ -38,7 +38,7 @@
#include "user-util.h"
#include "virt.h"
static void test_get_process_comm_one(pid_t pid) {
static void test_pid_get_comm_one(pid_t pid) {
struct stat st;
_cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
_cleanup_free_ char *env = NULL;
@@ -54,19 +54,19 @@ static void test_get_process_comm_one(pid_t pid) {
xsprintf(path, "/proc/"PID_FMT"/comm", pid);
if (stat(path, &st) == 0) {
assert_se(get_process_comm(pid, &a) >= 0);
assert_se(pid_get_comm(pid, &a) >= 0);
log_info("PID"PID_FMT" comm: '%s'", pid, a);
} else
log_warning("%s not exist.", path);
assert_se(get_process_cmdline(pid, 0, PROCESS_CMDLINE_COMM_FALLBACK, &c) >= 0);
assert_se(pid_get_cmdline(pid, 0, PROCESS_CMDLINE_COMM_FALLBACK, &c) >= 0);
log_info("PID"PID_FMT" cmdline: '%s'", pid, c);
assert_se(get_process_cmdline(pid, 8, 0, &d) >= 0);
assert_se(pid_get_cmdline(pid, 8, 0, &d) >= 0);
log_info("PID"PID_FMT" cmdline truncated to 8: '%s'", pid, d);
free(d);
assert_se(get_process_cmdline(pid, 1, 0, &d) >= 0);
assert_se(pid_get_cmdline(pid, 1, 0, &d) >= 0);
log_info("PID"PID_FMT" cmdline truncated to 1: '%s'", pid, d);
r = get_process_ppid(pid, &e);
@@ -76,13 +76,13 @@ static void test_get_process_comm_one(pid_t pid) {
assert_se(e > 0);
}
assert_se(is_kernel_thread(pid) == 0 || pid != 1);
assert_se(pid_is_kernel_thread(pid) == 0 || pid != 1);
r = get_process_exe(pid, &f);
assert_se(r >= 0 || r == -EACCES);
log_info("PID"PID_FMT" exe: '%s'", pid, strna(f));
assert_se(get_process_uid(pid, &u) == 0);
assert_se(pid_get_uid(pid, &u) == 0);
log_info("PID"PID_FMT" UID: "UID_FMT, pid, u);
assert_se(get_process_gid(pid, &g) == 0);
@@ -99,100 +99,101 @@ static void test_get_process_comm_one(pid_t pid) {
log_info("PID"PID_FMT" $PATH: '%s'", pid, strna(i));
}
TEST(get_process_comm) {
TEST(pid_get_comm) {
if (saved_argc > 1) {
pid_t pid = 0;
(void) parse_pid(saved_argv[1], &pid);
test_get_process_comm_one(pid);
test_pid_get_comm_one(pid);
} else {
TEST_REQ_RUNNING_SYSTEMD(test_get_process_comm_one(1));
test_get_process_comm_one(getpid());
TEST_REQ_RUNNING_SYSTEMD(test_pid_get_comm_one(1));
test_pid_get_comm_one(getpid());
}
}
static void test_get_process_cmdline_one(pid_t pid) {
static void test_pid_get_cmdline_one(pid_t pid) {
_cleanup_free_ char *c = NULL, *d = NULL, *e = NULL, *f = NULL, *g = NULL, *h = NULL, *joined = NULL;
_cleanup_strv_free_ char **strv_a = NULL, **strv_b = NULL;
int r;
r = get_process_cmdline(pid, SIZE_MAX, 0, &c);
r = pid_get_cmdline(pid, SIZE_MAX, 0, &c);
log_info("PID "PID_FMT": %s", pid, r >= 0 ? c : errno_to_name(r));
r = get_process_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &d);
r = pid_get_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &d);
log_info(" %s", r >= 0 ? d : errno_to_name(r));
r = get_process_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &e);
r = pid_get_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &e);
log_info(" %s", r >= 0 ? e : errno_to_name(r));
r = get_process_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE | PROCESS_CMDLINE_COMM_FALLBACK, &f);
r = pid_get_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE | PROCESS_CMDLINE_COMM_FALLBACK, &f);
log_info(" %s", r >= 0 ? f : errno_to_name(r));
r = get_process_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &g);
r = pid_get_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &g);
log_info(" %s", r >= 0 ? g : errno_to_name(r));
r = get_process_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX | PROCESS_CMDLINE_COMM_FALLBACK, &h);
r = pid_get_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX | PROCESS_CMDLINE_COMM_FALLBACK, &h);
log_info(" %s", r >= 0 ? h : errno_to_name(r));
r = get_process_cmdline_strv(pid, 0, &strv_a);
r = pid_get_cmdline_strv(pid, 0, &strv_a);
if (r >= 0)
assert_se(joined = strv_join(strv_a, "\", \""));
log_info(" \"%s\"", r >= 0 ? joined : errno_to_name(r));
joined = mfree(joined);
r = get_process_cmdline_strv(pid, PROCESS_CMDLINE_COMM_FALLBACK, &strv_b);
r = pid_get_cmdline_strv(pid, PROCESS_CMDLINE_COMM_FALLBACK, &strv_b);
if (r >= 0)
assert_se(joined = strv_join(strv_b, "\", \""));
log_info(" \"%s\"", r >= 0 ? joined : errno_to_name(r));
}
TEST(get_process_cmdline) {
TEST(pid_get_cmdline) {
_cleanup_closedir_ DIR *d = NULL;
int r;
assert_se(d = opendir("/proc"));
assert_se(proc_dir_open(&d) >= 0);
FOREACH_DIRENT(de, d, return) {
for (;;) {
pid_t pid;
if (de->d_type != DT_DIR)
continue;
r = proc_dir_read(d, &pid);
assert_se(r >= 0);
if (parse_pid(de->d_name, &pid) < 0)
continue;
if (r == 0) /* EOF */
break;
test_get_process_cmdline_one(pid);
test_pid_get_cmdline_one(pid);
}
}
static void test_get_process_comm_escape_one(const char *input, const char *output) {
static void test_pid_get_comm_escape_one(const char *input, const char *output) {
_cleanup_free_ char *n = NULL;
log_debug("input: <%s> — output: <%s>", input, output);
assert_se(prctl(PR_SET_NAME, input) >= 0);
assert_se(get_process_comm(0, &n) >= 0);
assert_se(pid_get_comm(0, &n) >= 0);
log_debug("got: <%s>", n);
assert_se(streq_ptr(n, output));
}
TEST(get_process_comm_escape) {
TEST(pid_get_comm_escape) {
_cleanup_free_ char *saved = NULL;
assert_se(get_process_comm(0, &saved) >= 0);
assert_se(pid_get_comm(0, &saved) >= 0);
test_get_process_comm_escape_one("", "");
test_get_process_comm_escape_one("foo", "foo");
test_get_process_comm_escape_one("012345678901234", "012345678901234");
test_get_process_comm_escape_one("0123456789012345", "012345678901234");
test_get_process_comm_escape_one("äöüß", "\\303\\244\\303\\266\\303\\274\\303\\237");
test_get_process_comm_escape_one("xäöüß", "x\\303\\244\\303\\266\\303\\274\\303\\237");
test_get_process_comm_escape_one("xxäöüß", "xx\\303\\244\\303\\266\\303\\274\\303\\237");
test_get_process_comm_escape_one("xxxäöüß", "xxx\\303\\244\\303\\266\\303\\274\\303\\237");
test_get_process_comm_escape_one("xxxxäöüß", "xxxx\\303\\244\\303\\266\\303\\274\\303\\237");
test_get_process_comm_escape_one("xxxxxäöüß", "xxxxx\\303\\244\\303\\266\\303\\274\\303\\237");
test_pid_get_comm_escape_one("", "");
test_pid_get_comm_escape_one("foo", "foo");
test_pid_get_comm_escape_one("012345678901234", "012345678901234");
test_pid_get_comm_escape_one("0123456789012345", "012345678901234");
test_pid_get_comm_escape_one("äöüß", "\\303\\244\\303\\266\\303\\274\\303\\237");
test_pid_get_comm_escape_one("xäöüß", "x\\303\\244\\303\\266\\303\\274\\303\\237");
test_pid_get_comm_escape_one("xxäöüß", "xx\\303\\244\\303\\266\\303\\274\\303\\237");
test_pid_get_comm_escape_one("xxxäöüß", "xxx\\303\\244\\303\\266\\303\\274\\303\\237");
test_pid_get_comm_escape_one("xxxxäöüß", "xxxx\\303\\244\\303\\266\\303\\274\\303\\237");
test_pid_get_comm_escape_one("xxxxxäöüß", "xxxxx\\303\\244\\303\\266\\303\\274\\303\\237");
assert_se(prctl(PR_SET_NAME, saved) >= 0);
}
@@ -207,11 +208,11 @@ TEST(pid_is_unwaited) {
} else {
int status;
waitpid(pid, &status, 0);
assert_se(!pid_is_unwaited(pid));
assert_se(waitpid(pid, &status, 0) == pid);
assert_se(pid_is_unwaited(pid) == 0);
}
assert_se(pid_is_unwaited(getpid_cached()));
assert_se(!pid_is_unwaited(-1));
assert_se(pid_is_unwaited(getpid_cached()) > 0);
assert_se(pid_is_unwaited(-1) < 0);
}
TEST(pid_is_alive) {
@@ -224,11 +225,11 @@ TEST(pid_is_alive) {
} else {
int status;
waitpid(pid, &status, 0);
assert_se(!pid_is_alive(pid));
assert_se(waitpid(pid, &status, 0) == pid);
assert_se(pid_is_alive(pid) == 0);
}
assert_se(pid_is_alive(getpid_cached()));
assert_se(!pid_is_alive(-1));
assert_se(pid_is_alive(getpid_cached()) > 0);
assert_se(pid_is_alive(-1) < 0);
}
TEST(personality) {
@@ -253,7 +254,7 @@ TEST(personality) {
#endif
}
TEST(get_process_cmdline_harder) {
TEST(pid_get_cmdline_harder) {
char path[] = "/tmp/test-cmdlineXXXXXX";
_cleanup_close_ int fd = -EBADF;
_cleanup_free_ char *line = NULL;
@@ -273,7 +274,7 @@ TEST(get_process_cmdline_harder) {
#if HAVE_VALGRIND_VALGRIND_H
/* valgrind patches open(/proc//cmdline)
* so, test_get_process_cmdline_harder fails always
* so, test_pid_get_cmdline_harder fails always
* See https://github.com/systemd/systemd/pull/3555#issuecomment-226564908 */
if (RUNNING_ON_VALGRIND) {
log_info("Skipping %s: running on valgrind", __func__);
@@ -323,56 +324,56 @@ TEST(get_process_cmdline_harder) {
assert_se(prctl(PR_SET_NAME, "testa") >= 0);
assert_se(get_process_cmdline(0, SIZE_MAX, 0, &line) == -ENOENT);
assert_se(pid_get_cmdline(0, SIZE_MAX, 0, &line) == -ENOENT);
assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "[testa]"));
line = mfree(line);
assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "\"[testa]\"")); /* quoting is enabled here */
line = mfree(line);
assert_se(get_process_cmdline(0, 0, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 0, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, ""));
line = mfree(line);
assert_se(get_process_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(streq(line, "…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(streq(line, "[…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(streq(line, "[t…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(streq(line, "[te…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(streq(line, "[tes…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(streq(line, "[test…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(streq(line, "[testa]"));
line = mfree(line);
assert_se(get_process_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(streq(line, "[testa]"));
line = mfree(line);
assert_se(get_process_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0);
assert_se(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0);
assert_se(strv_equal(args, STRV_MAKE("[testa]")));
args = strv_free(args);
@@ -380,135 +381,135 @@ TEST(get_process_cmdline_harder) {
assert_se(write(fd, "foo\0bar", 8) == 8);
assert_se(get_process_cmdline(0, SIZE_MAX, 0, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, 0, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar"));
line = mfree(line);
assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(streq(line, "foo bar"));
line = mfree(line);
assert_se(get_process_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0);
assert_se(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0);
assert_se(strv_equal(args, STRV_MAKE("foo", "bar")));
args = strv_free(args);
assert_se(write(fd, "quux", 4) == 4);
assert_se(get_process_cmdline(0, SIZE_MAX, 0, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, 0, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
assert_se(get_process_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "f…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "fo…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo …"));
line = mfree(line);
assert_se(get_process_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo b…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo ba…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 9, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 9, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar …"));
line = mfree(line);
assert_se(get_process_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar q…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar qu…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
assert_se(get_process_cmdline(0, 13, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 13, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
assert_se(get_process_cmdline(0, 14, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 14, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
assert_se(get_process_cmdline(0, 1000, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 1000, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
assert_se(get_process_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0);
assert_se(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0);
assert_se(strv_equal(args, STRV_MAKE("foo", "bar", "quux")));
args = strv_free(args);
assert_se(ftruncate(fd, 0) >= 0);
assert_se(prctl(PR_SET_NAME, "aaaa bbbb cccc") >= 0);
assert_se(get_process_cmdline(0, SIZE_MAX, 0, &line) == -ENOENT);
assert_se(pid_get_cmdline(0, SIZE_MAX, 0, &line) == -ENOENT);
assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "[aaaa bbbb cccc]"));
line = mfree(line);
assert_se(get_process_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "[aaaa bbb…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "[aaaa bbbb…"));
line = mfree(line);
assert_se(get_process_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
assert_se(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0);
log_debug("'%s'", line);
assert_se(streq(line, "[aaaa bbbb …"));
line = mfree(line);
assert_se(get_process_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0);
assert_se(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0);
assert_se(strv_equal(args, STRV_MAKE("[aaaa bbbb cccc]")));
args = strv_free(args);
@@ -523,19 +524,19 @@ TEST(get_process_cmdline_harder) {
assert_se(write(fd, CMDLINE1, sizeof CMDLINE1) == sizeof CMDLINE1);
assert_se(ftruncate(fd, sizeof CMDLINE1) == 0);
assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line) >= 0);
log_debug("got: ==%s==", line);
log_debug("exp: ==%s==", EXPECT1);
assert_se(streq(line, EXPECT1));
line = mfree(line);
assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line) >= 0);
log_debug("got: ==%s==", line);
log_debug("exp: ==%s==", EXPECT1p);
assert_se(streq(line, EXPECT1p));
line = mfree(line);
assert_se(get_process_cmdline_strv(0, 0, &args) >= 0);
assert_se(pid_get_cmdline_strv(0, 0, &args) >= 0);
assert_se(strv_equal(args, EXPECT1v));
args = strv_free(args);
@@ -548,19 +549,19 @@ TEST(get_process_cmdline_harder) {
assert_se(write(fd, CMDLINE2, sizeof CMDLINE2) == sizeof CMDLINE2);
assert_se(ftruncate(fd, sizeof CMDLINE2) == 0);
assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line) >= 0);
log_debug("got: ==%s==", line);
log_debug("exp: ==%s==", EXPECT2);
assert_se(streq(line, EXPECT2));
line = mfree(line);
assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line) >= 0);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line) >= 0);
log_debug("got: ==%s==", line);
log_debug("exp: ==%s==", EXPECT2p);
assert_se(streq(line, EXPECT2p));
line = mfree(line);
assert_se(get_process_cmdline_strv(0, 0, &args) >= 0);
assert_se(pid_get_cmdline_strv(0, 0, &args) >= 0);
assert_se(strv_equal(args, EXPECT2v));
args = strv_free(args);
@@ -811,8 +812,8 @@ TEST(get_process_ppid) {
assert_se(r >= 0);
assert_se(get_process_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c1) >= 0);
assert_se(get_process_cmdline(ppid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c2) >= 0);
assert_se(pid_get_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c1) >= 0);
assert_se(pid_get_cmdline(ppid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c2) >= 0);
log_info("Parent of " PID_FMT " (%s) is " PID_FMT " (%s).", pid, c1, ppid, c2);
@@ -207,7 +207,7 @@ static int process_one_password_file(const char *filename) {
if (not_after > 0 && now(CLOCK_MONOTONIC) > not_after)
return 0;
if (pid > 0 && !pid_is_alive(pid))
if (pid > 0 && pid_is_alive(pid) <= 0)
return 0;
switch (arg_action) {