[systemd-devel] [PATCH] tmpfiles: only execute chmod()/chown() when needed
Michael Olbrich
m.olbrich at pengutronix.de
Fri Jul 11 06:05:05 PDT 2014
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
More information about the systemd-devel
mailing list