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;
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");
}
}
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;
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);