Skip to content

Commit

Permalink
cgroup: rmdir the entire systemd scope
Browse files Browse the repository at this point in the history
commit 7ea7617 caused a regression on
cgroup v1, and some directories that are created manually are not
cleaned up on container termination causing a cgroup leak.

Fix it by deleting the entire systemd scope directory instead of
deleting only the final cgroup.

Closes: containers#1144

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Feb 20, 2023
1 parent 04a2c9e commit 0b2da80
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 2 deletions.
33 changes: 32 additions & 1 deletion src/libcrun/cgroup-systemd.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,10 +951,39 @@ libcrun_cgroup_enter_systemd (struct libcrun_cgroup_args *args,
return 0;
}

char *
get_cgroup_scope_path (const char *cgroup_path, const char *scope)
{
char *path_to_scope = NULL;
char *cur;

path_to_scope = xstrdup (cgroup_path);

cur = strchr (path_to_scope, '/');
while (cur)
{
char *next = strchr (cur + 1, '/');
if (next == NULL)
break;

*next = '\0';
if (strcmp (cur, scope) == 0)
return path_to_scope;
*next = '/';

cur = next;
while (*cur == '/')
cur++;
}

return path_to_scope;
}

static int
libcrun_destroy_cgroup_systemd (struct libcrun_cgroup_status *cgroup_status,
libcrun_error_t *err)
{
cleanup_free char *path_to_scope = NULL;
int mode;
int ret;

Expand All @@ -970,7 +999,9 @@ libcrun_destroy_cgroup_systemd (struct libcrun_cgroup_status *cgroup_status,
if (UNLIKELY (ret < 0))
crun_error_release (err);

return destroy_cgroup_path (cgroup_status->path, mode, err);
path_to_scope = get_cgroup_scope_path (cgroup_status->path, cgroup_status->scope);

return destroy_cgroup_path (path_to_scope, mode, err);
}

static int
Expand Down
2 changes: 2 additions & 0 deletions src/libcrun/cgroup-systemd.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

int parse_sd_array (char *s, char **out, char **next, libcrun_error_t *err);

char *get_cgroup_scope_path (const char *cgroup_path, const char *scope);

extern struct libcrun_cgroup_manager cgroup_manager_systemd;

#endif
27 changes: 26 additions & 1 deletion tests/tests_libcrun_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,30 @@ test_parse_sd_array ()
}
return 0;
}

static int
test_get_scope_path ()
{
#define CHECK(x, y) \
{ \
cleanup_free char *r = x; \
if (strcmp (r, y)) \
{ \
fprintf (stderr, "expected %s, got %s\n", y, r); \
return -1; \
} \
}

CHECK (get_cgroup_scope_path ("foo.scope", "foo.scope"), "foo.scope");
CHECK (get_cgroup_scope_path ("/foo/bar/user.slice/foo.scope/a/b/c", "foo.scope"), "/foo/bar/user.slice/foo.scope");
CHECK (get_cgroup_scope_path ("/foo/bar-foo.scope/user.slice/foo.scope/a/b/c", "foo.scope"), "/foo/bar-foo.scope/user.slice/foo.scope");
CHECK (get_cgroup_scope_path ("/foo/foo.scope-bar/user.slice/foo.scope/a/b/c", "foo.scope"), "/foo/foo.scope-bar/user.slice/foo.scope");
CHECK (get_cgroup_scope_path ("////foo.scope", "foo.scope"), "////foo.scope");

#undef CHECK
return 0;
}

#endif

static void
Expand All @@ -423,7 +447,7 @@ main ()
{
int id = 1;
#ifdef HAVE_SYSTEMD
printf ("1..9\n");
printf ("1..10\n");
#else
printf ("1..8\n");
#endif
Expand All @@ -437,6 +461,7 @@ main ()
RUN_TEST (test_path_is_slash_dev);
#ifdef HAVE_SYSTEMD
RUN_TEST (test_parse_sd_array);
RUN_TEST (test_get_scope_path);
#endif
return 0;
}

0 comments on commit 0b2da80

Please sign in to comment.