This avoids errors like this, when the paths are already there with the correct permissions and owner:
chmod(/var/spool) failed: Read-only file system --- src/tmpfiles/tmpfiles.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 68cfa55..4f41f28 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -453,35 +453,41 @@ finish: } static int item_set_perms(Item *i, const char *path) { + struct stat st; + mode_t old_m = ~0; + uid_t old_uid = -1; + gid_t old_gid = -1; + assert(i); assert(path); + if (stat(path, &st) >= 0) { + old_m = st.st_mode & 07777; + old_uid = st.st_uid; + old_gid = st.st_gid; + } /* not using i->path directly because it may be a glob */ if (i->mode_set) { mode_t m = i->mode; - if (i->mask_perms) { - struct stat st; - - if (stat(path, &st) >= 0) { - if (!(st.st_mode & 0111)) - m &= ~0111; - if (!(st.st_mode & 0222)) - m &= ~0222; - if (!(st.st_mode & 0444)) - m &= ~0444; - if (!S_ISDIR(st.st_mode)) - m &= ~07000; /* remove sticky/sgid/suid bit, unless directory */ - } + if (i->mask_perms && old_m != ~0) { + if (!(st.st_mode & 0111)) + m &= ~0111; + if (!(st.st_mode & 0222)) + m &= ~0222; + if (!(st.st_mode & 0444)) + m &= ~0444; + if (!S_ISDIR(st.st_mode)) + m &= ~07000; /* remove sticky/sgid/suid bit, unless directory */ } - if (chmod(path, m) < 0) { + if (m != old_m && chmod(path, m) < 0) { log_error("chmod(%s) failed: %m", path); return -errno; } } - if (i->uid_set || i->gid_set) + if ((i->uid_set || i->gid_set) && (i->uid != old_uid || i->gid != old_gid)) if (chown(path, i->uid_set ? i->uid : (uid_t) -1, i->gid_set ? i->gid : (gid_t) -1) < 0) { -- 2.0.1 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel