[systemd-devel] [PATCH v2 2/2] nspawn: skip symlink to a combined cgroup hierarchy if it already exists
Iago López Galeiras
iago at endocode.com
Wed May 13 06:45:49 PDT 2015
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.
---
src/nspawn/nspawn.c | 10 ++++++++--
src/shared/util.c | 23 +++++++++++++++++++++++
src/shared/util.h | 1 +
3 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index f292c63..e9e703f 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -1365,8 +1365,14 @@ 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 < 0) {
+ if (r == -EINVAL) {
+ log_error("Invalid existing symlink for combined hierarchy");
+ return r;
+ } else
+ return log_error_errno(r, "Failed to create symlink for combined hierarchy: %m");
+ }
}
}
diff --git a/src/shared/util.c b/src/shared/util.c
index 466dce4..22e00a6 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2765,6 +2765,29 @@ 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) {
+ r = readlink_malloc(to, &p);
+ if (r < 0)
+ return r;
+
+ if (!streq(p, from)) {
+ return -EINVAL;
+ }
+ } else
+ return -errno;
+ }
+
+ return 0;
+}
+
int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
_cleanup_free_ char *t = NULL;
int r;
diff --git a/src/shared/util.h b/src/shared/util.h
index 4a67d5c..8565fd6 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -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);
--
2.4.0
More information about the systemd-devel
mailing list