Skip to content

Simplify config rewrite file handling and make it really atomic#7824

Merged
yossigo merged 1 commit intoredis:unstablefrom
ushachar:make_config_rewrite_atomic
Sep 25, 2020
Merged

Simplify config rewrite file handling and make it really atomic#7824
yossigo merged 1 commit intoredis:unstablefrom
ushachar:make_config_rewrite_atomic

Conversation

@ushachar
Copy link
Contributor

No description provided.

src/config.c Outdated
Comment on lines 1567 to 1573
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ushachar Please consider doing snprintf() into the buffer and check return code to confirm it was big enough, could be simpler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Fixed.

src/config.c Outdated
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a short write should also be handled here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep... was already in progress on it. Done.

src/config.c Outdated
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might make sense to fchmod() earlier, so once rename() is successful we're all done. In this order we may end up with the wrong permissions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Done.

@oranagra
Copy link
Member

summing up feedback i relayed privately few days ago:

  1. if you do keep the length check, you can change strncpy to memcpy if you want.
  2. if rename fails, maybe we want to delete the temp file.
  3. most importantly: I really think your commit comment needs to be improved. describe what was wrong with the previous code and what are you doing differently (for easier reading).

@ushachar ushachar force-pushed the make_config_rewrite_atomic branch from 6980e88 to 323e18e Compare September 22, 2020 21:40
@ushachar
Copy link
Contributor Author

@oranagra / @yossigo updated the PR.

src/config.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the first and only use of u_int (personally i don't think i ever encountered it).
i'm afraid of some platform compatibility issues, would feel better to use anything else

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok - switched to explicit 'unsigned int'

@ushachar ushachar force-pushed the make_config_rewrite_atomic branch from 323e18e to 2c63b6c Compare September 23, 2020 10:58
oranagra
oranagra previously approved these changes Sep 23, 2020
Copy link
Member

@oranagra oranagra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yossigo please review/approve

@oranagra oranagra requested a review from yossigo September 24, 2020 09:24
Make sure we handle short writes correctly, sync to disk after writing  and use
rename to make sure the replacement is actually atomic.
In any case of failure old configuration will remain in place.

Also, add some additional logging to make it easier to diagnose rewrite problems.
@yossigo yossigo merged commit c30bd02 into redis:unstable Sep 25, 2020
@yossigo
Copy link
Collaborator

yossigo commented Sep 25, 2020

Merged, thanks @ushachar!

@ushachar
Copy link
Contributor Author

@oranagra / @yossigo Is there a label to make sure something is mentioned in the release notes? Folks running without write perms on the config directory need to be aware of this change....

@oranagra oranagra added the release-notes indication that this issue needs to be mentioned in the release notes label Sep 25, 2020
@oranagra
Copy link
Member

I've added the release notes label, home we'll catch it when the day comes

@oranagra oranagra mentioned this pull request Oct 26, 2020
oranagra pushed a commit that referenced this pull request Oct 27, 2020
Make sure we handle short writes correctly, sync to disk after writing  and use
rename to make sure the replacement is actually atomic.
In any case of failure old configuration will remain in place.

Also, add some additional logging to make it easier to diagnose rewrite problems.

(cherry picked from commit c30bd02)
JackieXie168 pushed a commit to JackieXie168/redis that referenced this pull request Nov 4, 2020
Make sure we handle short writes correctly, sync to disk after writing  and use
rename to make sure the replacement is actually atomic.
In any case of failure old configuration will remain in place.

Also, add some additional logging to make it easier to diagnose rewrite problems.
jschmieg pushed a commit to memKeyDB/memKeyDB that referenced this pull request Nov 6, 2020
Make sure we handle short writes correctly, sync to disk after writing  and use
rename to make sure the replacement is actually atomic.
In any case of failure old configuration will remain in place.

Also, add some additional logging to make it easier to diagnose rewrite problems.

(cherry picked from commit c30bd02)
@remicollet
Copy link
Contributor

Looks like this break config rewrite, because of permission problem, as most of the time saving /etc/redis.conf imply write access to /etc, which is usually not allowed.

@ushachar
Copy link
Contributor Author

ushachar commented Nov 14, 2020

Looks like this break config rewrite, because of permission problem, as most of the time saving /etc/redis.conf imply write access to /etc, which is usually not allowed.

@remicollet - Yep - See comment in #7824 (comment).
There's no other way to make the rewrite truly atomic. If you want to keep the conf file under /etc, I suggest creating a subdirectory for redis (which would also be useful for other related config files like certificates) and only granting the Redis user write access to that.

@yossigo
Copy link
Collaborator

yossigo commented Nov 16, 2020

@remicollet Do you see a problem with the subdirectory approach? This seems to be what other distros are doing as well and as @ushachar mentioned it has other advantages.

@remicollet
Copy link
Contributor

@yossigo indeed subdirectory is a solution, but cannot be used, as it will break existing configuration (upgrade path)

@remicollet
Copy link
Contributor

See PR #8058

@yossigo
Copy link
Collaborator

yossigo commented Nov 20, 2020

@remicollet Thank you for proposing a fix in your PR.

However, I'm afraid in a way it goes against the motivation of the original fix - which was to ensure rewrites are atomic. If we take this approach rewrites are again not guaranteed to be atomic, because that would depend on what filesystem permissions are used and whether or not the fallback is triggered. For this reason we can't accept this fix.

This was referenced Jan 11, 2021
oranagra pushed a commit that referenced this pull request Jul 20, 2022
As an outstanding part mentioned in #10737, we could just make the cluster config file and
ACL file saving done with a more safe and atomic pattern (write to temp file, fsync, rename, fsync dir).

The cluster config file uses an in-place overwrite and truncation (which was also used by the
main config file before #7824).
The ACL file is using the temp file and rename approach, but was missing an fsync.

Co-authored-by: 朱天 <[email protected]>
enjoy-binbin pushed a commit to enjoy-binbin/redis that referenced this pull request Jul 31, 2023
As an outstanding part mentioned in redis#10737, we could just make the cluster config file and
ACL file saving done with a more safe and atomic pattern (write to temp file, fsync, rename, fsync dir).

The cluster config file uses an in-place overwrite and truncation (which was also used by the
main config file before redis#7824).
The ACL file is using the temp file and rename approach, but was missing an fsync.

Co-authored-by: 朱天 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-notes indication that this issue needs to be mentioned in the release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants