-
Notifications
You must be signed in to change notification settings - Fork 18.7k
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
Automatically set may_detach_mounts=1
on startup
#34886
Conversation
Looks good, ping @rhvgoyal |
LGTM. We already do this with the help of sysctl interface. So over a boot, all the sysctl settings are applied and this is already enabled by the time docker runs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nits, but LGTM otherwise :)
daemon/daemon_unix.go
Outdated
if os.IsNotExist(err) { | ||
return nil | ||
} | ||
return errors.Wrap(err, "error opening may_deatch_mounts kernel config file") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh! typo: s/may_deatch_mounts/may_detach_mounts/
// unprivileged container. Ignore the error, but log | ||
// it if we appear not to be in that situation. | ||
if !rsystem.RunningInUserNS() { | ||
logrus.Debugf("Permission denied writing %q to /proc/sys/fs/may_detach_mounts", "1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there's no need to use %q here, because "1"
is hardcoded
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it quotes it, which is pretty ugly to do otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
backticks for the string?
`Permission denied writing "1" to ....`
This is kernel config available in RHEL7.4 based kernels that enables mountpoint removal where the mountpoint exists in other namespaces. In particular this is important for making this pattern work: ``` umount -l /some/path rm -r /some/path ``` Where `/some/path` exists in another mount namespace. Setting this value will prevent `device or resource busy` errors when attempting to the removal of `/some/path` in the example. This setting is the default, and non-configurable, on upstream kernels since 3.15. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
b4a87a9
to
83c2152
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Wonderful! I was just going to work on a similar PR, but for the devmapper graph driver only (as its "deferred deletion" feature only works in case The alternative approach is to add a Yet another alternative is something like: // -q: not display the value set, -e: ignore non-existent key
err := exec.Command("sysctl", "-q", "-e", "fs.may_detach_mounts=1").Run()
... While exec sn ugly in general, this is only done once upon daemon (re)start so it's OK. |
I do like the alternative approach (cleaner); would the permissions denied error still be properly returned with that code? |
Well, what we'll get is an exit code (most probably a generic 1) and a text from stderr (which we can parse for "permission denied" but it's a slippery slope as the locale might change that). I suggest treating any error, not just EPERM, in the same way, like: s := "fs.may_detach_mounts=1"
// -q: not display the value set, -e: ignore non-existent key
err := exec.Command("sysctl", "-q", "-e", s).Run()
// ignore the error if the daemon is inside userns
if err != nil && !rsystem.RunningInUserNS() {
 logrus.Warnf("Error setting %s: %v", s, err)
} Or maybe even not try setting this at all if we're in userns: // do not try to set sysctls from inside userns
if !rsystem.RunningInUserNS() {
s := "fs.may_detach_mounts=1"
// -q: not display the value set, -e: ignore non-existent key
if err := exec.Command("sysctl", "-q", "-e", s).Run(); err != nil {
logrus.Warnf("Error setting %s sysctl: %v", s, err)
} |
(If @cpuguy83 agrees) feel free to open a PR with that change |
Why use exec here? |
I'd be fine with setting this in the systemd conf, however that's really a packaging issue which we don't really deal with in this repo (though there are some init scripts in contrib). |
As I said earlier, While exec sn ugly in general, this is only done once upon daemon (re)start so it's OK. The benefits I see are:
|
This is kernel config available in RHEL7.4 based kernels that enables
mountpoint removal where the mountpoint exists in other namespaces.
In particular this is important for making this pattern work:
Where
/some/path
exists in another mount namespace.Setting this value will prevent
device or resource busy
errors whenattempting to the removal of
/some/path
in the example.This setting is the default, and non-configurable, on upstream kernels
since 3.15.