Is `mount -o remount,ro` guaranteed to fail if there are files open for writing?
I am working on a safe and race-condition-free alternative to umount -l
with removable devices:
I’m planning on:
umount --move
under a000
permissions directory so no more files can be opened by absolute path- Interactively kill (or gracefully shutdown) processes with files open for writing
- Atomically remount read-only only if step (2) is complete
- Interactively kill / close read-only processes that may cause cause issues
- Finally have
umount
succeed
There is a race condition in step (3) where a file with relative path could be opened rw
after the last interactive kill and before the mount -o remount,ro
.
Is mount -o remount,ro
guaranteed to fail if there is any file on the filesystem opened for writing?
The manual page is silent on this, and I’m a bit paranoid after finding out that devices are writable even after blockdev --setro
.
Yes. The relevant code is in sb_prepare_remount_readonly
(as of Linux 4.0, the code may be organized differently on other versions). The logic is:
- For each instance of the mount:
- If that instance is not read-only:
- Prevent any new writer from registering (
MNT_WRITE_HOLD
). - If there are registered writers, set the error flag (return
EBUSY
).
- Prevent any new writer from registering (
- If that instance is not read-only:
- If there are any files that are removed (inode count = 0) but not yet deleted (still present because the file is open), set the error flag.
- If the error flag is not set, mark the partition as read-only.
- For each instance of the mount:
- Stop preventing writers from registering.
Registered writers are files open for writing as well as ongoing operations that write metadata (mkdir
, chmod
, etc.). Check out calls to mnt_want_write
which is where the count of registered writers is incremented.
The design of the system ensures that a read-only remount is a write registration barrier: if it succeeds then there is no registered writer, in particular there can’t be any file open for writing at the time of the remount operation. After the remount, no file can be opened for writing, so there is still no file that’s open for writing.