nspawn: skip symlink to a combined cgroup hierarchy if it already exists

If a symlink to a combined cgroup hierarchy already exists and points to
the right path, skip it. This avoids an error when the cgroups are set
manually before calling nspawn.
This commit is contained in:
Iago López Galeiras 2015-05-13 15:45:49 +02:00 committed by Lennart Poettering
parent 54b4755f15
commit 875e1014dd
3 changed files with 30 additions and 3 deletions

View file

@ -1325,7 +1325,6 @@ static int mount_cgroup(const char *dest) {
if (r < 0)
return log_error_errno(r, "Failed to determine our own cgroup path: %m");
for (;;) {
_cleanup_free_ char *controller = NULL, *origin = NULL, *combined = NULL;
@ -1365,8 +1364,13 @@ static int mount_cgroup(const char *dest) {
if (r < 0)
return r;
if (symlink(combined, target) < 0)
return log_error_errno(errno, "Failed to create symlink for combined hierarchy: %m");
r = symlink_idempotent(combined, target);
if (r == -EINVAL) {
log_error("Invalid existing symlink for combined hierarchy");
return r;
}
if (r < 0)
return log_error_errno(r, "Failed to create symlink for combined hierarchy: %m");
}
}

View file

@ -2765,6 +2765,28 @@ int symlink_atomic(const char *from, const char *to) {
return 0;
}
int symlink_idempotent(const char *from, const char *to) {
_cleanup_free_ char *p = NULL;
int r;
assert(from);
assert(to);
if (symlink(from, to) < 0) {
if (errno != EEXIST)
return -errno;
r = readlink_malloc(to, &p);
if (r < 0)
return r;
if (!streq(p, from))
return -EINVAL;
}
return 0;
}
int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
_cleanup_free_ char *t = NULL;
int r;

View file

@ -404,6 +404,7 @@ bool machine_name_is_valid(const char *s) _pure_;
char* strshorten(char *s, size_t l);
int symlink_idempotent(const char *from, const char *to);
int symlink_atomic(const char *from, const char *to);
int mknod_atomic(const char *path, mode_t mode, dev_t dev);