return 0;
}
+
+int pakfire_cgroup_attach(Pakfire pakfire, const char* group, pid_t pid) {
+ int r = pakfire_cgroup_fprintf(pakfire, group, "cgroup.procs", "%d", pid);
+ if (r < 0) {
+ ERROR(pakfire, "Could not attach process %d to cgroup %s: %s\n",
+ pid, group, strerror(errno));
+ return r;
+ }
+
+ DEBUG(pakfire, "Attached process %d to cgroup %s\n", pid, group);
+ return 0;
+}
+
+int pakfire_cgroup_detach(Pakfire pakfire, const char* group, pid_t pid) {
+ char* parent = pakfire_cgroup_parent_name(group);
+ if (!parent)
+ return EINVAL;
+
+ while (parent) {
+ int r = pakfire_cgroup_attach(pakfire, parent, pid);
+
+ // Break on success
+ if (r == 0) {
+ free(parent);
+ return 0;
+ }
+
+ // Move on to the next parent group
+ char* p = parent;
+ parent = pakfire_cgroup_parent_name(p);
+ free(p);
+ }
+
+ ERROR(pakfire, "Could not detach process %d from %s\n", pid, group);
+ return 1;
+}
+
+static ssize_t pakfire_cgroup_procs_callback(Pakfire pakfire, const char* group,
+ int (*func)(Pakfire pakfire, pid_t pid)) {
+ FILE* f = pakfire_cgroup_fopen(pakfire, group, "cgroup.procs", "r");
+ if (!f)
+ return -1;
+
+ ssize_t num_processes = 0;
+
+ char* line = NULL;
+ size_t l = 0;
+
+ while (1) {
+ ssize_t bytes_read = getline(&line, &l, f);
+ if (bytes_read < 0)
+ break;
+
+ // Increment process counter
+ num_processes++;
+
+ DEBUG(pakfire, "Read line %s\n", line);
+ }
+
+ fclose(f);
+
+ // Returns the number of processes
+ return num_processes;
+}
+
+ssize_t pakfire_cgroup_num_processes(Pakfire pakfire, const char* group) {
+ return pakfire_cgroup_procs_callback(pakfire, group, NULL);
+}
#ifdef PAKFIRE_PRIVATE
+#include <sys/types.h>
+
#include <pakfire/types.h>
int pakfire_cgroup_create(Pakfire pakfire, const char* group);
int pakfire_cgroup_destroy(Pakfire pakfire, const char* group);
+int pakfire_cgroup_attach(Pakfire pakfire, const char* group, pid_t pid);
+int pakfire_cgroup_detach(Pakfire pakfire, const char* group, pid_t pid);
+
+ssize_t pakfire_cgroup_num_processes(Pakfire pakfire, const char* group);
+
#endif
#endif /* PAKFIRE_CGROUP_H */
# #
#############################################################################*/
+#include <sys/types.h>
+#include <unistd.h>
+
#include <pakfire/cgroup.h>
#include "../testsuite.h"
return EXIT_SUCCESS;
}
+static int test_attach(const struct test* t) {
+ ssize_t num_processes;
+
+ // Fetch the PID of the test process
+ pid_t pid = getpid();
+
+ printf("This process's PID: %d\n", pid);
+
+ ASSERT_SUCCESS(
+ pakfire_cgroup_create(t->pakfire, "pakfire/test")
+ );
+
+ // Check that there are no processes in this group
+ num_processes = pakfire_cgroup_num_processes(t->pakfire, "pakfire/test");
+ ASSERT(num_processes == 0);
+
+ ASSERT_SUCCESS(
+ pakfire_cgroup_attach(t->pakfire, "pakfire/test", pid)
+ );
+
+ // Check that there is exactly one process in this group
+ num_processes = pakfire_cgroup_num_processes(t->pakfire, "pakfire/test");
+ ASSERT(num_processes == 1);
+
+ ASSERT_SUCCESS(
+ pakfire_cgroup_detach(t->pakfire, "pakfire/test", pid)
+ );
+
+ // Check that there are no processes in this group
+ num_processes = pakfire_cgroup_num_processes(t->pakfire, "pakfire/test");
+ ASSERT(num_processes == 0);
+
+ ASSERT_SUCCESS(
+ pakfire_cgroup_destroy(t->pakfire, "pakfire/test")
+ );
+
+ return EXIT_SUCCESS;
+}
+
int main(int argc, char** argv) {
testsuite_add_test(test_create_and_destroy);
+ testsuite_add_test(test_attach);
return testsuite_run();
}