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