mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
cgroup-util: add helpers for opening cgroup by id
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "log.h"
|
||||
#include "login-util.h"
|
||||
#include "macro.h"
|
||||
#include "missing_fs.h"
|
||||
#include "missing_magic.h"
|
||||
#include "missing_threads.h"
|
||||
#include "mkdir.h"
|
||||
@@ -39,6 +40,38 @@
|
||||
#include "user-util.h"
|
||||
#include "xattr-util.h"
|
||||
|
||||
int cg_path_open(const char *controller, const char *path) {
|
||||
_cleanup_free_ char *fs = NULL;
|
||||
int r;
|
||||
|
||||
r = cg_get_path(controller, path, /* item=*/ NULL, &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return RET_NERRNO(open(fs, O_DIRECTORY|O_CLOEXEC));
|
||||
}
|
||||
|
||||
int cg_cgroupid_open(int cgroupfs_fd, uint64_t id) {
|
||||
_cleanup_close_ int fsfd = -EBADF;
|
||||
|
||||
if (cgroupfs_fd < 0) {
|
||||
fsfd = open("/sys/fs/cgroup", O_CLOEXEC|O_DIRECTORY);
|
||||
if (fsfd < 0)
|
||||
return -errno;
|
||||
|
||||
cgroupfs_fd = fsfd;
|
||||
}
|
||||
|
||||
cg_file_handle fh = CG_FILE_HANDLE_INIT;
|
||||
CG_FILE_HANDLE_CGROUPID(fh) = id;
|
||||
|
||||
int fd = open_by_handle_at(cgroupfs_fd, &fh.file_handle, O_DIRECTORY|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int cg_enumerate_items(const char *controller, const char *path, FILE **ret, const char *item) {
|
||||
_cleanup_free_ char *fs = NULL;
|
||||
FILE *f;
|
||||
@@ -1404,7 +1437,7 @@ int cg_pid_get_machine_name(pid_t pid, char **ret_machine) {
|
||||
|
||||
int cg_path_get_cgroupid(const char *path, uint64_t *ret) {
|
||||
cg_file_handle fh = CG_FILE_HANDLE_INIT;
|
||||
int mnt_id = -1;
|
||||
int mnt_id;
|
||||
|
||||
assert(path);
|
||||
assert(ret);
|
||||
@@ -1418,6 +1451,20 @@ int cg_path_get_cgroupid(const char *path, uint64_t *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cg_fd_get_cgroupid(int fd, uint64_t *ret) {
|
||||
cg_file_handle fh = CG_FILE_HANDLE_INIT;
|
||||
int mnt_id = -1;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
if (name_to_handle_at(fd, "", &fh.file_handle, &mnt_id, AT_EMPTY_PATH) < 0)
|
||||
return -errno;
|
||||
|
||||
*ret = CG_FILE_HANDLE_CGROUPID(fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cg_path_get_session(const char *path, char **ret_session) {
|
||||
_cleanup_free_ char *unit = NULL;
|
||||
char *start, *end;
|
||||
|
||||
@@ -180,6 +180,9 @@ typedef enum CGroupUnified {
|
||||
* generate paths with multiple adjacent / removed.
|
||||
*/
|
||||
|
||||
int cg_path_open(const char *controller, const char *path);
|
||||
int cg_cgroupid_open(int fsfd, uint64_t id);
|
||||
|
||||
int cg_enumerate_processes(const char *controller, const char *path, FILE **ret);
|
||||
int cg_read_pid(FILE *f, pid_t *ret);
|
||||
int cg_read_pidref(FILE *f, PidRef *ret);
|
||||
@@ -267,6 +270,7 @@ 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_fd_get_cgroupid(int fd, uint64_t *ret);
|
||||
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);
|
||||
@@ -352,5 +356,10 @@ typedef union {
|
||||
uint8_t space[offsetof(struct file_handle, f_handle) + sizeof(uint64_t)];
|
||||
} cg_file_handle;
|
||||
|
||||
#define CG_FILE_HANDLE_INIT { .file_handle.handle_bytes = sizeof(uint64_t) }
|
||||
#define CG_FILE_HANDLE_INIT \
|
||||
(cg_file_handle) { \
|
||||
.file_handle.handle_bytes = sizeof(uint64_t), \
|
||||
.file_handle.handle_type = FILEID_KERNFS, \
|
||||
}
|
||||
|
||||
#define CG_FILE_HANDLE_CGROUPID(fh) (*(uint64_t*) (fh).file_handle.f_handle)
|
||||
|
||||
@@ -111,3 +111,8 @@ assert_cc(FS_PROJINHERIT_FL == 0x20000000);
|
||||
#else
|
||||
assert_cc(FS_KEY_DESCRIPTOR_SIZE == 8);
|
||||
#endif
|
||||
|
||||
/* linux/exportfs.h */
|
||||
#ifndef FILEID_KERNFS
|
||||
#define FILEID_KERNFS 0xfe
|
||||
#endif
|
||||
|
||||
@@ -150,18 +150,9 @@ static int show_cgroup_name(
|
||||
delegate = r > 0;
|
||||
|
||||
if (FLAGS_SET(flags, OUTPUT_CGROUP_ID)) {
|
||||
cg_file_handle fh = CG_FILE_HANDLE_INIT;
|
||||
int mnt_id = -1;
|
||||
|
||||
if (name_to_handle_at(
|
||||
fd,
|
||||
"",
|
||||
&fh.file_handle,
|
||||
&mnt_id,
|
||||
AT_EMPTY_PATH) < 0)
|
||||
r = cg_fd_get_cgroupid(fd, &cgroupid);
|
||||
if (r < 0)
|
||||
log_debug_errno(errno, "Failed to determine cgroup ID of %s, ignoring: %m", path);
|
||||
else
|
||||
cgroupid = CG_FILE_HANDLE_CGROUPID(fh);
|
||||
}
|
||||
|
||||
r = path_extract_filename(path, &b);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "cgroup-setup.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "string-util.h"
|
||||
@@ -129,4 +130,47 @@ TEST(cg_create) {
|
||||
assert_se(cg_rmdir(SYSTEMD_CGROUP_CONTROLLER, test_a) == 0);
|
||||
}
|
||||
|
||||
TEST(id) {
|
||||
_cleanup_free_ char *p = NULL, *p2 = NULL;
|
||||
_cleanup_close_ int fd = -EBADF, fd2 = -EBADF;
|
||||
uint64_t id, id2;
|
||||
int r;
|
||||
|
||||
r = cg_all_unified();
|
||||
if (r == 0) {
|
||||
log_tests_skipped("skipping cgroupid test, not running in unified mode");
|
||||
return;
|
||||
}
|
||||
if (IN_SET(r, -ENOMEDIUM, -ENOENT)) {
|
||||
log_tests_skipped("cgroupfs is not mounted");
|
||||
return;
|
||||
}
|
||||
assert_se(r > 0);
|
||||
|
||||
fd = cg_path_open(SYSTEMD_CGROUP_CONTROLLER, "/");
|
||||
assert_se(fd >= 0);
|
||||
|
||||
assert_se(fd_get_path(fd, &p) >= 0);
|
||||
assert_se(path_equal(p, "/sys/fs/cgroup"));
|
||||
|
||||
assert_se(cg_fd_get_cgroupid(fd, &id) >= 0);
|
||||
|
||||
fd2 = cg_cgroupid_open(fd, id);
|
||||
|
||||
if (ERRNO_IS_NEG_PRIVILEGE(fd2))
|
||||
log_notice("Skipping open-by-cgroup-id test because lacking privs.");
|
||||
else {
|
||||
assert_se(fd2 >= 0);
|
||||
|
||||
assert_se(fd_get_path(fd2, &p2) >= 0);
|
||||
assert_se(path_equal(p2, "/sys/fs/cgroup"));
|
||||
|
||||
assert_se(cg_fd_get_cgroupid(fd2, &id2) >= 0);
|
||||
|
||||
assert_se(id == id2);
|
||||
|
||||
assert_se(inode_same_at(fd, NULL, fd2, NULL, AT_EMPTY_PATH) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_DEBUG);
|
||||
|
||||
Reference in New Issue
Block a user