return r;
}
+static int pakfire_cgroup_create_recursive(struct pakfire_cgroup** cgroup,
+ struct pakfire_ctx* ctx, struct pakfire_cgroup* parent, const char* name, int flags) {
+ struct pakfire_cgroup* child = NULL;
+ char buffer[NAME_MAX];
+ char* p = NULL;
+ int r;
+
+ // Name cannot be empty
+ if (!name || !*name)
+ return -EINVAL;
+
+ // Does the name contain a /?
+ p = strchr(name, '/');
+
+ // We have reached the end of the recursion
+ if (!p)
+ return pakfire_cgroup_open(cgroup, ctx, parent, name, flags);
+
+ // Copy the string to the buffer
+ r = pakfire_string_format(buffer, "%.*s", (int)(p - name), name);
+ if (r < 0)
+ return r;
+
+ // Create the child cgroup
+ r = pakfire_cgroup_child(&child, parent, buffer, flags);
+ if (r < 0)
+ goto ERROR;
+
+ // Continue processing name...
+ r = pakfire_cgroup_create_recursive(cgroup, ctx, child, ++p, flags);
+ if (r < 0)
+ goto ERROR;
+
+ // Done
+
+ERROR:
+ if (child)
+ pakfire_cgroup_unref(child);
+
+ return r;
+}
+
int pakfire_cgroup_create(struct pakfire_cgroup** cgroup,
struct pakfire_ctx* ctx, struct pakfire_cgroup* parent, const char* name, int flags) {
struct pakfire_cgroup* root = NULL;
int r;
- // If parent is NULL, but name is set, we will create the root group and use it as parent
- if (name && !parent) {
+ // Name must be set
+ if (!name)
+ return -EINVAL;
+
+ // If parent is NULL, we open the root as parent
+ if (!parent) {
r = pakfire_cgroup_open(&root, ctx, NULL, NULL, 0);
if (r < 0)
return r;
}
// Recursively create the new cgroup
- r = pakfire_cgroup_open(cgroup, ctx, parent, name, flags);
+ r = pakfire_cgroup_create_recursive(cgroup, ctx, parent, name, flags);
// Cleanup
if (root)
return r;
}
+static int test_recursive(const struct test* t) {
+ struct pakfire_cgroup* cgroup = NULL;
+ int r = EXIT_FAILURE;
+
+ // Try to create some invalid cgroups
+ ASSERT(pakfire_cgroup_create(&cgroup, t->ctx, NULL, NULL, 0) == -EINVAL);
+ ASSERT(pakfire_cgroup_create(&cgroup, t->ctx, NULL, "pakfire-test/a/", 0) == -EINVAL);
+
+ // Open a new cgroup
+ ASSERT_SUCCESS(pakfire_cgroup_create(&cgroup, t->ctx, NULL, "pakfire-test/a/b/c", 0));
+
+ // Destroy the cgroup again
+ ASSERT_SUCCESS(pakfire_cgroup_destroy(cgroup));
+
+ // Success
+ r = EXIT_SUCCESS;
+
+FAIL:
+ if (cgroup)
+ pakfire_cgroup_unref(cgroup);
+
+ return r;
+}
+
static int test_child(const struct test* t) {
struct pakfire_cgroup* cgroup = NULL;
struct pakfire_cgroup* child = NULL;
int main(int argc, const char* argv[]) {
testsuite_add_test(test_create_and_destroy, 0);
+ testsuite_add_test(test_recursive, 0);
testsuite_add_test(test_child, 0);
testsuite_add_test(test_stats, TEST_WANTS_PAKFIRE);