Power-fail safe writes

Cristian Ionescu-Idbohrn cristian.ionescu-idbohrn at axis.com
Tue Apr 2 13:52:44 UTC 2019


On Tue, 2 Apr 2019, Denys Vlasenko wrote:
> 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.


Cheers,

-- 
Cristian


More information about the busybox mailing list