[systemd-devel] [PATCH] tmpfiles: try to handle read-only file systems gracefully

Zbigniew Jędrzejewski-Szmek zbyszek at in.waw.pl
Tue May 5 21:11:57 PDT 2015


On Thu, Apr 30, 2015 at 08:50:38PM +0200, Michael Olbrich wrote:
> On read-only filesystems trying to create the target will not fail with
> EEXIST but with EROFS. Handle EROFS by checking if the target already
> exists, and if empty when truncating.
> This avoids reporting errors if tmpfiles doesn't actually needs to do
> anything.
> ---
> 
> This is a rework of a patch I wrote some time ago[1]. This time reacting to
> EROFS instead of preempting it.
Applied, with some small changes, see below.

> 
> Michael
> 
> [1] http://lists.freedesktop.org/archives/systemd-devel/2014-August/022158.html
> 
>  src/tmpfiles/tmpfiles.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
> index 218d55051410..4473bf019911 100644
> --- a/src/tmpfiles/tmpfiles.c
> +++ b/src/tmpfiles/tmpfiles.c
> @@ -983,9 +983,11 @@ static int write_one_file(Item *i, const char *path) {
>                          log_debug_errno(errno, "Not writing \"%s\": %m", path);
>                          return 0;
>                  }
> -
> -                log_error_errno(errno, "Failed to create file %s: %m", path);
> -                return -errno;
> +                r = -errno;
> +                if (i->argument || r != -EROFS || stat(path, &st) < 0 || (i->type == TRUNCATE_FILE && st.st_size > 0)) {
> +                        log_error_errno(r, "Failed to create file %s: %m", path);
> +                        return r;
> +                }
I reverted the condition, because it seems safer to whitelist instead of
blacklisting. Also, if the condition didn't succeed, we'd do stat twice.
Please check that it still works as intended.

>          }
>  
>          if (i->argument) {
> @@ -1154,6 +1156,10 @@ static int create_item(Item *i) {
>  
>                  log_debug("Copying tree \"%s\" to \"%s\".", resolved, i->path);
>                  r = copy_tree(resolved, i->path, false);
> +
> +                if (r == -EROFS && stat(i->path, &st) == 0)
> +                        r = -EEXIST;
> +
>                  if (r < 0) {
>                          struct stat a, b;

Zbyszek


More information about the systemd-devel mailing list