[systemd-devel] [PATCH] tmpfiles: only execute chmod()/chown() when needed

Michael Olbrich m.olbrich at pengutronix.de
Thu Jul 31 00:42:57 PDT 2014


On Fri, Jul 11, 2014 at 03:05:05PM +0200, Michael Olbrich wrote:
> 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

Ping. These warnings are rather annoying and they make it hard to find
those that are actually a problem :-/.

Michael

> ---
>  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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


More information about the systemd-devel mailing list