summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-login/sd-login.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-09-04 09:54:14 +0200
committerLennart Poettering <lennart@poettering.net>2015-09-05 14:56:23 +0200
commitf5aaf575626022313b07d505699fa1af25d248ac (patch)
tree72f56593684aff2f66c67f079886f6de3ac30372 /src/libsystemd/sd-login/sd-login.c
parent19af675e99d32172b58f1c91c8281ba2efd5d863 (diff)
sd-login: add new sd_pid_get_cgroup() API
This adds a new sd_pid_get_cgroup() call to sd-login which may be used to query the control path of a process. This is useful for programs when making use of delegation units, in order to figure out which subtree has been delegated. In light of the unified control group hierarchy this is finally safe to do, hence let's add a proper API for it, to make it easier to use this.
Diffstat (limited to 'src/libsystemd/sd-login/sd-login.c')
-rw-r--r--src/libsystemd/sd-login/sd-login.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 180bdd09ad..55da26e9d9 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -101,6 +101,32 @@ _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
return cg_pid_get_owner_uid(pid, uid);
}
+_public_ int sd_pid_get_cgroup(pid_t pid, char **cgroup) {
+ char *c;
+ int r;
+
+ assert_return(pid >= 0, -EINVAL);
+ assert_return(cgroup, -EINVAL);
+
+ r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &c);
+ if (r < 0)
+ return r;
+
+ /* The internal APIs return the empty string for the root
+ * cgroup, let's return the "/" in the public APIs instead, as
+ * that's easier and less ambigious for people to grok. */
+ if (isempty(c)) {
+ free(c);
+ c = strdup("/");
+ if (!c)
+ return -ENOMEM;
+
+ }
+
+ *cgroup = c;
+ return 0;
+}
+
_public_ int sd_peer_get_session(int fd, char **session) {
struct ucred ucred = {};
int r;
@@ -199,6 +225,20 @@ _public_ int sd_peer_get_user_slice(int fd, char **slice) {
return cg_pid_get_user_slice(ucred.pid, slice);
}
+_public_ int sd_peer_get_cgroup(int fd, char **cgroup) {
+ struct ucred ucred;
+ int r;
+
+ assert_return(fd >= 0, -EBADF);
+ assert_return(cgroup, -EINVAL);
+
+ r = getpeercred(fd, &ucred);
+ if (r < 0)
+ return r;
+
+ return sd_pid_get_cgroup(ucred.pid, cgroup);
+}
+
static int file_of_uid(uid_t uid, char **p) {
assert_return(uid_is_valid(uid), -EINVAL);