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>
... | ... |
@@ -1297,7 +1297,39 @@ func rootFSToAPIType(rootfs *image.RootFS) types.RootFS { |
1297 | 1297 |
// setupDaemonProcess sets various settings for the daemon's process |
1298 | 1298 |
func setupDaemonProcess(config *config.Config) error { |
1299 | 1299 |
// setup the daemons oom_score_adj |
1300 |
- return setupOOMScoreAdj(config.OOMScoreAdjust) |
|
1300 |
+ if err := setupOOMScoreAdj(config.OOMScoreAdjust); err != nil { |
|
1301 |
+ return err |
|
1302 |
+ } |
|
1303 |
+ return setMayDetachMounts() |
|
1304 |
+} |
|
1305 |
+ |
|
1306 |
+// This is used to allow removal of mountpoints that may be mounted in other |
|
1307 |
+// namespaces on RHEL based kernels starting from RHEL 7.4. |
|
1308 |
+// Without this setting, removals on these RHEL based kernels may fail with |
|
1309 |
+// "device or resource busy". |
|
1310 |
+// This setting is not available in upstream kernels as it is not configurable, |
|
1311 |
+// but has been in the upstream kernels since 3.15. |
|
1312 |
+func setMayDetachMounts() error { |
|
1313 |
+ f, err := os.OpenFile("/proc/sys/fs/may_detach_mounts", os.O_WRONLY, 0) |
|
1314 |
+ if err != nil { |
|
1315 |
+ if os.IsNotExist(err) { |
|
1316 |
+ return nil |
|
1317 |
+ } |
|
1318 |
+ return errors.Wrap(err, "error opening may_detach_mounts kernel config file") |
|
1319 |
+ } |
|
1320 |
+ defer f.Close() |
|
1321 |
+ |
|
1322 |
+ _, err = f.WriteString("1") |
|
1323 |
+ if os.IsPermission(err) { |
|
1324 |
+ // Setting may_detach_mounts does not work in an |
|
1325 |
+ // unprivileged container. Ignore the error, but log |
|
1326 |
+ // it if we appear not to be in that situation. |
|
1327 |
+ if !rsystem.RunningInUserNS() { |
|
1328 |
+ logrus.Debugf("Permission denied writing %q to /proc/sys/fs/may_detach_mounts", "1") |
|
1329 |
+ } |
|
1330 |
+ return nil |
|
1331 |
+ } |
|
1332 |
+ return err |
|
1301 | 1333 |
} |
1302 | 1334 |
|
1303 | 1335 |
func setupOOMScoreAdj(score int) error { |