Power-fail safe writes

Denys Vlasenko vda.linux at googlemail.com
Tue Apr 2 12:58:40 UTC 2019


On Tue, Apr 2, 2019 at 11:55 AM Cristian Ionescu-Idbohrn
<cristian.ionescu-idbohrn at axis.com> wrote:
>
> 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;


I removed NOATIME in git just now.


More information about the busybox mailing list