Power-fail safe writes

Cristian Ionescu-Idbohrn cristian.ionescu-idbohrn at axis.com
Tue Apr 2 09:55:47 UTC 2019


On Tue, 2 Apr 2019, Sebastian Brand wrote:
> 
> I recently had problems when updating a configuration file using sed 
> with in-place edit option (-i), shortly followed by a power fail, 
> which has the end result of an empty configuration file and a system 
> that won't boot.
> The reason behind this is me relying on sed and sed in-place editing 
> not using a power-fail safe write pattern (copy, edit copy, 
> synchronize copy, rename, synchronize folder).
> I have locally written a feature to enable "safe write" for sed, but 
> since this is a problem for many flash filesystems there might be 
> more people interested in this? (Perhaps especially people using 
> Busybox for embedded systems?) And this is probably not only 
> relevant for sed?
> 
> There is also a part 2 that arises when trying to "manually" do a 
> safe write: since the fsync applet uses the O_NOATIME flag it is 
> impossible for user1:group1 to synchronize a directory owned by 
> user2:group1 (you get an "Operation not permitted" error from 
> fsync). Is this intended? (Using gnu sync [8.26] and synchronizing 
> on a specific folder works for the same situation.)

GNU sync command is doing this on a file:

,----
| openat(AT_FDCWD, "/tmp/foo/bar", O_RDONLY|O_NONBLOCK) = 3
| fcntl(3, F_GETFL)                       = 0x8800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE)
| fcntl(3, F_SETFL, O_RDONLY|O_LARGEFILE) = 0
| fsync(3)                                = 0
| close(3)                                = 0
`----

and this on a directory:

,----
| openat(AT_FDCWD, "/tmp/foo", O_RDONLY|O_NONBLOCK) = 3
| fcntl(3, F_GETFL)                       = 0x8800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE)
| fcntl(3, F_SETFL, O_RDONLY|O_LARGEFILE) = 0
| fsync(3)                                = 0
| close(3)                                = 0
`----

Note, no O_NOATIME.

namei.c:        /* O_NOATIME can only be set by the owner or superuser */
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
namei.c:        if (flag & O_NOATIME && !inode_owner_or_capable(inode))
namei.c-                return -EPERM;


Cheers,

-- 
Cristian


More information about the busybox mailing list