overlay2: use index=off if possible (fix EBUSY on mount)#37993
overlay2: use index=off if possible (fix EBUSY on mount)#37993yongtang merged 2 commits intomoby:masterfrom
Conversation
There was a problem hiding this comment.
No need to convert this from fmt.Sprint
There was a problem hiding this comment.
To me, it looks more readable that way (as the option arguments are right there next to options), and Sprintf() does nothing but string concatenating here.
Using fmt.Sprintf() in Golang to merely concatenate a few strings (without doing anything else like padding, quoting etc.) looks like a coding pattern that came straight from C, where you can't concatenate more than 2 strings at once, and should be discouraged unless necessary.
Concatenation is also quite faster (not that it matters in this particular case).
There was a problem hiding this comment.
@dmcgowan please let me know what you think about ^^^ , and I'll surrender and obey :)
There was a problem hiding this comment.
This change is fine, neither has great readability but not worth making it an array and joining
780ea19 to
c685bdb
Compare
|
CI failures due to my careless typos ⌨️ should now be fixed |
Codecov Report
@@ Coverage Diff @@
## master #37993 +/- ##
=========================================
Coverage ? 36.12%
=========================================
Files ? 610
Lines ? 45170
Branches ? 0
=========================================
Hits ? 16318
Misses ? 26614
Partials ? 2238 |
|
v2: moved the detection code to driver's |
There was a problem hiding this comment.
What's the result if it's not supported and we set this option? Will it fail?
There was a problem hiding this comment.
Yes, it will most probably result in kernel returning EINVAL from mount() syscall. This will only happen if:
- kernel is > 4.13rc1 (and the relevant feature is not backported);
and - for some reason /sys/module/overlay/parameters/index is present but
stat()returns an error.
The former is quite possible, say on older distros.
The latter is highly unlikely to happen, from the top of my head I can only think of a severe kernel memory shortage, or using any security mechanisms (say selinux) to disallow dockerd access to e.g. /sys/module/ directory.
There was a problem hiding this comment.
Right, so I was thinking if we should take the safe approach, and only add index=off if we're successfully able to detect that it's supported (i.e. os.Stat() was successfull), so:
os.Stat()was successful; addindex=offos.Stat()produces anIsNotExist: don't addindex=off, and continue silently (as this is an expected situation)os.Stat()produces any other error: log a warning ("unable to detect if index=off is supported: <original error message>"), but continue as usual (but don't addindex=off)
There was a problem hiding this comment.
Logging a warning at least makes it visible that we were unable to detect, and may assist in troubleshooting why we failed to detect.
There was a problem hiding this comment.
Makes sense; please see updated commit
This simplifies the code a lot. Signed-off-by: Kir Kolyshkin <[email protected]>
As pointed out in moby#37970, Docker overlay driver can't work with index=on feature of the Linux kernel "overlay" filesystem. In case the global default is set to "yes", Docker will fail with EBUSY when trying to mount, like this: > error creating overlay mount to ...../merged: device or resource busy and the kernel log should contain something like: > overlayfs: upperdir is in-use by another mount, mount with > '-o index=off' to override exclusive upperdir protection. A workaround is to set index=off in overlay kernel module parameters, or even recompile the kernel with CONFIG_OVERLAY_FS_INDEX=n in .config. Surely this is not always practical or even possible. The solution, as pointed out my Amir Goldstein (as well as the above kernel message:) is to use 'index=off' option when mounting. NOTE since older (< 4.13rc1) kernels do not support "index=" overlayfs parameter, try to figure out whether the option is supported. In case it's not possible to figure out, assume it is not. NOTE the default can be changed anytime (by writing to /sys/module/overlay/parameters/index) so we need to always use index=off. [v2: move the detection code to Init()] [v3: don't set index=off if stat() failed] Signed-off-by: Kir Kolyshkin <[email protected]>
| defer func() { | ||
| if err := os.RemoveAll(td); err != nil { | ||
| logrus.WithField("storage-driver", "overlay2").Warnf("Failed to remove check directory %v: %v", td, err) | ||
| logger.Warnf("Failed to remove check directory %v: %v", td, err) |
There was a problem hiding this comment.
We should also start using .WithError() for these;
logger.WithError(err).Warnf("Failed to remove check directory %v", td)There was a problem hiding this comment.
right (also in this case there's no need to print filename, as it should be a part of error message returned from os.RemoveAll())
kernel version > 4.13rc1 support index=on feature, it will be failed with EBUSY when trying to mount. Related: moby/moby#37993 Signed-off-by: Rudy Zhang <[email protected]>
kernel version > 4.13rc1 support index=on feature, it will be failed with EBUSY when trying to mount. Related: moby/moby#37993 Signed-off-by: Rudy Zhang <[email protected]>
kernel version > 4.13rc1 support index=on feature, it will be failed with EBUSY when trying to mount. Related: moby/moby#37993 Signed-off-by: Rudy Zhang <[email protected]>
|
It looks like this change blocks a docker image from setting up an NFS export of a directory in the root file system (ie, what's enabled by this overlay Linux kernel module addition). Is there no way to export the filesystem with the overlay driver in Docker? In the past I've used the AUFS driver, but that's deprecated and going away bit by bit. |
|
@cody-c-lewis how were you planing to enable nfs_export in overlayfs? Without changing docker?
|
Since there isn't any docker setting for this then my next thought was to set it via the kernel module parameters (such as
It sounds like these two issues were the motivation behind this PR so I guess the real question is if they've been resolved in the intervening 3 years. If that's the case then maybe undoing this PR would be a solution, or adding first class support to docker as you describe. |
The kernel module config gets overridden by the mount options set here. I rebuilt the kernel module to ignore these two mount options and just use the default parameters set, and starting a single container with a nfs export does seem to work at least superficially. |
|
Just trying to understand, you are trying to create an nfs export on a path inside the container which is just part of the normal container rootfs (ie. overlay) and not a bind-mount from the host? Have you considered bind-mounting a dir here (or just an anonymous volume) so that it bypasses overlay entirely? You can still create the nfs export in the container, just now it doesn't have to depend on the details of the container rootfs. |
|
That is correct. I originally posted about this on the docker forums, you might find the details there more interesting: https://forums.docker.com/t/nfs-export-disabled-with-overlay2-as-storage-driver/121325 I have considered other options for the source of the files in the nfs export, but as I would like the files to be versioned alongside the rest of the container content, updating them as a single unit is logistically easier. |
|
I've had some more time to work with this over the past couple days. So far it seems that for my specific use case, there aren't any issues with enabling index and nfs_export. I've created an issue so that discussion can happen there rather than a 4 year old PR. #43299 |
As pointed out in #37970,
Docker overlay driver can't work with
index=onfeature ofthe Linux kernel "overlay" filesystem. In case the global
default is set to "yes", Docker will fail with EBUSY when
trying to mount, like this:
and the kernel log should contain something like:
A workaround is to set index=off in overlay kernel module
parameters, or even recompile the kernel with
CONFIG_OVERLAY_FS_INDEX=nin.config. Surely this is notalways practical or even possible.
The solution, as pointed out my Amir Goldstein (as well as
the above kernel message 😄) is to use
index=offoptionwhen mounting.
NOTE since older (< 4.13rc1) kernels do not support
index=overlayfs parameter, try to figure out whether the option
is supported by the running kernel. In case it's not possible
to figure it out, assume the kernel is new enough to support it.
NOTE the default can be changed anytime (by writing to
/sys/module/overlay/parameters/index) so we need to alwaysuse
index=off.Fixes: #37970