-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make config file saving safe against write failures #34009
Conversation
In case of disk space depletion, writing a new version of config fails, leaving the config file empty. This patch improves safety of updates to config.php by saving the new version of the config into a randomly-named temporary file in the same directory, and then renaming it to config.php, which renaming is atomic in POSIX-compliant filesystems and shouldn't involve disk space allocation. If writing the new config version is impossible, the current config remains unchanged. This patch drops the use of file locking as unnecessary. File locking merely established order in which the concurrent independent processes attempted file writing. In the end, the process which was last to update the file "wins" - their changes persist and the changes of previous writers are dropped as there's no conflict detection or change merging mechanism anyway. With the current change, there is still some resulting ordering, and the last writer still wins in the same way. Readers don't need file locking as well, as opening config.php for reading always provides a certain consistent version of the file. Signed-off-by: Andriy Utkin <dev@autkin.net>
@andrey-utkin Is writing access to config directory a new requirement then? Apart from this it looks fine, I was worried about losing permissions setup by the admin but the old code was already doing a chmod anyway. |
Indeed, the config directory must have write permissions by the user running nextcloud code.
With the file being moved around, file locking won't work the way it used to (I should have written that in the commit message). A process has obtained the lock, but that file was replaces by a new file, and nobody's ever going to contend the lock on the old file handle, so it's become irrelevant. One way around is to define a special lock file, but some admins may not get the idea and remove the file or get worried... |
This is reassuring.
I see, flock works on a file resource and rename works with paths and not handles. |
Just like before. By HintException, which is supposed to notify the user.
Seems like Vim by default does some renaming business under the cover (as opposed to echo or cat with redirection), not sure it does "atomic update" but possibly so, see https://unix.stackexchange.com/a/37177 I think it's reasonable to put the responsibility onto the sysadmin and their tooling in case of editing configs by hand on a live system. Like, if sysadmin edits /etc/hosts on a live system, it better doesn't get read while in inconsistent state. |
Ok, looks good to me. |
can confirm this patch fix the issue when disk is full on a virtual HD on linux |
Thanks for your first pull request and welcome to the community! Feel free to keep them coming! If you are looking for issues to tackle then have a look at this selection: https://github.com/nextcloud/server/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22 |
/backport to stable24 |
/backport to stable23 |
Since this was merged into master I got my config.php file wiped multiple times. Already my reset script sometimes triggers it, as well as running talk integration tests. E.g. I set a couple of config values in my reset script via occ, the first bunch worked and then it gives a random write error:
|
Reverted temporarily in #34137 |
Was an alternative implementation ever proposed after this was reverted? I can't find one. |
Note: this hasn't been tested yet, is a speculative fix to the bug which has many bugreports, including #18620 and #25175 . I may go forward and create tests, for now it's to advance the conversation in this PR.
Make config file saving safe against write failures
In case of disk space depletion, writing a new version of config fails, leaving the config file empty.
This patch improves safety of updates to config.php by saving the new version of the config into a randomly-named temporary file in the same directory, and then renaming it to config.php, which renaming is atomic in POSIX-compliant filesystems and shouldn't involve disk space allocation. If writing the new config version is impossible, the current config remains unchanged.
This patch drops the use of file locking as unnecessary. File locking merely established order in which the concurrent independent processes attempted file writing. In the end, the process which was last to update the file "wins" - their changes persist and the changes of previous writers are dropped as there's no conflict detection or change merging mechanism anyway. With the current change, there is still some resulting ordering, and the last writer still wins in the same way. Readers don't need file locking as well, as opening config.php for reading always provides a certain consistent version of the file.