Merge pull request #29594 from poettering/cgroup-rename-ret-params
more pidfdification
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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",
|
||||
|
||||
@@ -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
@@ -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++;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ++;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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\".",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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__);
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user