]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tmpfiles: try to handle read-only file systems gracefully
authorMichael Olbrich <m.olbrich@pengutronix.de>
Thu, 30 Apr 2015 18:50:38 +0000 (20:50 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 6 May 2015 04:10:40 +0000 (00:10 -0400)
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.

[zj: revert condition to whitelist rather then blacklisting, and add goto
to avoid stat'ting twice.]

src/tmpfiles/tmpfiles.c

index d574254e0fb80e203c9c341fb4be6f7d08bf269b..640ad4788da30152f97d8a583345e73e391c4aba 100644 (file)
@@ -984,8 +984,12 @@ static int write_one_file(Item *i, const char *path) {
                         return 0;
                 }
 
-                log_error_errno(errno, "Failed to create file %s: %m", path);
-                return -errno;
+                r = -errno;
+                if (!i->argument && errno == EROFS && stat(path, &st) == 0 &&
+                    (i->type == CREATE_FILE || st.st_size == 0))
+                        goto check_mode;
+
+                return log_error_errno(r, "Failed to create file %s: %m", path);
         }
 
         if (i->argument) {
@@ -1012,6 +1016,7 @@ static int write_one_file(Item *i, const char *path) {
         if (stat(path, &st) < 0)
                 return log_error_errno(errno, "stat(%s) failed: %m", path);
 
+ check_mode:
         if (!S_ISREG(st.st_mode)) {
                 log_error("%s is not a file.", path);
                 return -EEXIST;
@@ -1154,6 +1159,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;