Create backup file when writing new xml file?
Thiago Macieira
thiago at macieira.org
Mon Feb 17 14:54:27 UTC 2014
Em seg 17 fev 2014, às 10:22:19, Linus Torvalds escreveu:
> You have two choices:
>
> - locking - either using flock or using a lock directory (and the
> really traditional and safe way really is to use a directory, because
> "O_CREAT | O_EXCL" is not necessarily actually reliable on NFS)
That's the "easy" way out. I'm wondering if there's something we could do that
would avoid the lock file.
>
> - never actually use "unlink()", instead use "link()" to a unique
> name, and then you can unlink the original backup file. And then you
> can unlink the "backup of the backup" that is under the unique name
> *after* you've done everything else, so that you are never in the
> situation that two different processes could have unlinked things to
> the point where no backup exists.
Let me see if I understand:
1) create temp file
2) write data to it
3) fsync
4) link backup to backup^2
5) rename $ORIG to backup
6) rename temp to $ORIG
7) unlink backup^2
The $ORIG file name disappeared between 5 and 6. I was wondering if there's a
way to prevent that. If I instead did:
4bis) rename backup to backup^2 (ignoring ENOENT)
5bis) link $ORIG to backup
In this sequence, there's no point at which $ORIG disappears.
However, if another process comes in and does the same, the link call will
fail. I guess I could just repeat steps 4bis and 5bis, giving up after a few
tries.
> Eventually (and it looks like it is going to be 3.15), on LInux we'll
> also have a new "rename2()" system call that takes an optional
> RENAME_NOREPLACE flag (and RENAME_EXCHANGE), which makes things like
> this easier.
>
> But that will obviously be Linux-specific. Not that I know how well
> the whole hardlink model works under Windows.
I don't mind having Linux-specific calls that improve safety. We already do use
pipe2, dup3, accept4, SOCK_CLOEXEC and O_CLOEXEC (though POSIX.1-2008 added
this last one).
I haven't tested hardlinks on Windows, so I'll worry about it when I get to
it. I know it's supported since Windows XP, but it occurs to me now that it's
not supported on FAT filesystems. That's still a valid use-case, as in people
saving files on USB sticks. Then again, link(2) would also fail on Linux for
that case, so the handling needs to be done for all platforms anyway.
> There's no sane way to guarantee you won't have stale temporary files.
> You can minimize them with various tricks, but I don't think it's
> really worth worrying about.
Fair enough.
> For now, I'd suggest against playing games. Yes, you'll get temporary
> files if things crash. Try to be careful in the sequence that does
> this, so that you don't have operations that might cause problems, and
> don't call out to user code. Minimize the risk of crashes instead.
Everything is contained in one single function (QSaveFile::commit) and it does
not call back out to user code.
However, that does not stop another thread from crashing the process or
another process from trying to save to the same file at the same time. Or our
making a mistake somewhere in the abstraction layers.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
More information about the subsurface
mailing list