5 ms·
> Overwriting a file replaces the file as a unit; other readers see the old file until the writer closes and the reader reopens. This is the semantic rename pr
by wahern 6y ago
> Overwriting a file replaces the file as a unit; other readers see the old file until the writer closes and the reader reopens.
This is the semantic rename provides, and the strength of that semantic is a common complaint from many in the anti-POSIX crowd. I suspect you knew that already, but the number of syscalls would be similar in either case except that the latter file would need to be visible before the rename. Linux does provide O_TMPFILE + AT_SYMLINK_FOLLOW which provides the nearly ideal behavior. (Nearly because it still requires /proc/self/fd access, AFAIU.)
> Log files. Append-only mode, enforced
Both chflags (BSD) and chattr (Linux) provide append-only modes attached to the file/inode (instead of the file descriptor or open file table entry)[1].[2] Neither command nor their options are defined by POSIX, but adding more requirements to POSIX filesystem conformance goes against the grain of prevailing sentiments.
> Temp files. Not persistent over restarts. Not backed up. Can be memory-mapped as read/write. On a crash, disappears.
Again, the semantics of unlinking deliberately provide this, though it does make it invisible in the normal namespace. But there's a tension between leveraging the namespace for implicit semantics (Plan 9) vs adding a multitude of options and modes attached to each particular file (Windows).
It's also not uncommon for temporary filesystems like /tmp to be reformatted on boot if the backing store is persistent. That's one reason to use multiple filesystems for a Unix install.
[1] Note that O_APPEND mode is attached to the open file table entry, not the file descriptor, so the mode is inherited across dup and interprocess descriptor passing. Interestingly, on Linux /proc/self/fd (also /dev/fd, which is a symlink) has the semantics of open, not dup, so file table entry state like O_APPEND is lost; whereas on BSD /dev/fd has the semantics of dup so O_APPEND is preserved/enforced.
[2] Solaris lacks chattr and chflags, but chmod supports an append-only option.
- deleted 6y ago[deleted]
- dan-robertson 6y agoRenaming is commonly proposed for rewriting files but does not provide the guarantees people usually think it does. Posix renames are only atomic during normal operation. But here atomic merely means that other syscalls will not return results for some partially-renamed state. The operation does not need to be atomic in the case of a crash (where here “atomic” means “you can’t read the file system in some partially renamed state after a crash”, a different definition but one which people commonly assume when they hear that rename is atomic). I’m not aware of any normal Linux file system where renames are always atomic over a crash
- dmm 6y agoZFS is really well behaved. It never reorders metadata in an observable way so renames should truely be atomic. In the event of a crash you'll get the old or the new name.
- fiddlerwoaroof 6y agoWhat I’d prefer to atomicity is automatic file versioning such that a file descriptor opened at time t0 always points to the same contents, unless you refresh it. You’d also need CoW and/or writing patches rather than rewriting the whole file and a GC/compactor for cleaning up transient versions of a file. The workflows this would be enable is that, when vim wants syntax checking, it writes a transient version of the file to the fs without updating the “HEAD” pointer and then hands a fd to the syntax checker that points to that new transient version.
- a1369209993 6y agoYeah, the way you're 'supposed' (as near as I can tell) to do this is: read 'foo' write 'foo~' hardlink 'foo~' onto 'foo' unlink 'foo~' on crash: if 'foo' exists: it's the correct state for the file unlink 'foo~' continue otherwise: hardlink 'foo~' onto 'foo' unlink 'foo~' I'm not sure Posix actually requires link and unlink to be atomic enough on crash for this work, but it seems to be fine for any sane filesystem (where the fs itself doesn't fall apart in presence of crashes).
- tomtomtom777 6y agoThis doesn't work because the link() syscall fails if the target exists. You use a hardlink only for atomic creation of the initial data: write 'foo~' hardlink 'foo~' onto 'foo' To atomically update you simply use rename: read 'foo' write 'foo~' rename 'foo~' into 'foo' I don't know what dan-robertson's claim is based on, but this surely is atomic even on a crash, as the filesystem will never be in a state where 'foo' contains only partially updated data. That would require some severe fs corruption.
- skissane 6y ago> Both chflags (BSD) and chattr (Linux) provide append-only modes attached to the file/inode (instead of the file descriptor or open file table entry) On Linux, by default only the superuser can set the append-only flag. That severely limits its usefulness for many applications > adding more requirements to POSIX filesystem conformance goes against the grain of prevailing sentiments POSIX is of declining relevance. What really matters nowadays is can you get Linux and *BSD (including macOS) to agree on implementing something new. Get one to add it, and convince the others to copy it. If you can do that, then getting it added to the POSIX standard is likely to be easy. Vendors hardly care about POSIX certification anymore. The latest version of POSIX/SUS, UNIX V7, currently has zero certified implementations. (Oracle Solaris did achieve V7 certification, but has since lost it; I don't know exactly what happened, but I suspect Oracle refused to pay the certification renewal fees.)
- wahern 6y ago> On Linux, by default only the superuser can set the append-only flag. That severely limits its usefulness for many applications Ah, good point. > Get one to add it, and convince the others to copy it. If you can do that, then getting it added to the POSIX standard is likely to be easy. In actuality it usually works in reverse: Red Hat (now IBM), which has the most dominate presence on the committee, convinces POSIX to add or modify something, and then everybody else adopts it. Examples: asprintf, fmemopen, stpcpy, vdprintf. I can't really think of an example that worked the other way around, though there may be some in the next specification. The fact that nobody is certified to V7 is beside the point. Nobody is certified to the latest HTML5 standard, either, AFAIK. The point is to provide a shared target. Few people want to copy Linux or glibc because the semantics are invariably underspecified and in part accidental, and people would prefer to avoid those aspects even if they have no other choice but to nominally adopt the interface. Standardization provides a chance to clarify behavior and to fix the bounds of what a portable program can expect long term. If I have to support epoll + kqueue in perpetuity (and I assume I do), I'll structure my program differently.[1] However, if I want to use pselect (or the forthcoming ppoll), I'll target the POSIX-defined semantics, provide a best effort wrapper (or none at all), and tell users on slower evolving platforms to complain to their vendor. The Linux kernel strives for strong ABI backward compatibility, but it hardly has a perfect track record in that regard (e.g. sysctl(2)), and the future is even more unclear given the various directions it's being pulled. Even POSIX can change course, but it does so more methodically than with a Github code search. And while Linux doesn't make promises regarding POSIX compliance, it's less likely to break POSIX semantics than its own semantics, ceteris paribus. Whether that's because kernel developers value POSIX compliance, or merely because POSIX-vetted semantics are narrower and less accidental is irrelevant. [1] Also, I'll take the bet that epoll is never standardized, precisely because of its accidental and sometimes very undesirable semantics as compared to kqueue. At best we'll get a greatest common denominator interface that can be built around both--or possibly taking into consideration Solaris ports.
- Animats 6y agoWhenever I bring this up, I get a list of complicated platform-specific workarounds. My point here is that unit file behavior, as outlined, should be the default. You should never have an incomplete unit file around and readable.
- Pxtl 6y agoAgreed. There are so many infuriating software bugs I've hit by "something was watching file X and tried to consume it mid-write and pooped it's pants because there was invalid data". Not small things, either - I mean like "IIS crashed all our apps are down we have minutes before SLA problems".