4

I'm mounting couple of directories (bind mount) in a chroot environment, but they behave differently on CentOS 6 and 7 - exactly the same commands.

Example:

I have my chroot env in /chroot/base.

Then I mount it on every user:

mount --bind /chroot/base /chroot/$user

Then I mount /home/$user in the same user's chroot:

mount --bind /home/$user /chroot/$user/home/$user

On CentOS 6 it works fine and it mounts exactly those directories, but on CentOS 7 I get something like this:

/dev/mapper/cl_cp-home /chroot/user1/home/user1 xfs rw,relatime,attr2,inode64,usrquota 0 0
/dev/mapper/cl_cp-home /chroot/user2/home/user1 xfs rw,relatime,attr2,inode64,usrquota 0 0
/dev/mapper/cl_cp-home /chroot/user3/home/user1 xfs rw,relatime,attr2,inode64,usrquota 0 0
/dev/mapper/cl_cp-home /chroot/user2/home/user2 xfs rw,relatime,attr2,inode64,usrquota 0 0
/dev/mapper/cl_cp-home /chroot/user3/home/user2 xfs rw,relatime,attr2,inode64,usrquota 0 0
/dev/mapper/cl_cp-home /chroot/user1/home/user2 xfs rw,relatime,attr2,inode64,usrquota 0 0
/dev/mapper/cl_cp-home /chroot/user3/home/user3 xfs rw,relatime,attr2,inode64,usrquota 0 0

Every user's homedir gets mounted in the chroot env of the other users.

Why is this happening? What changed between CentOS6/7 that could be causing this?

Edit:

Running ls on the folder for user1 for example (123user1 is a simple touch /home/user1/123user1 file):

root@server:~# ls /chroot/user1/home/user1/
123user1
root@server:~# ls /chroot/user2/home/user1/
123user1
root@server:~# ls /chroot/user3/home/user1/
123user1

Even more strange is this:

root@server:~# ls /chroot/base/home/user1/
123user1

I haven't mounted this at any stage

plamer
  • 205
  • 2
  • 10
  • The contents of e.g. `/chroot/user1/home/user1` should reflect the ones in `/home/user1` and not the complete `/home` folder. Can you quickly confirm this with `ls` on the folders?. `mount` just shows the filesystem the folder is stored on. – Thomas May 21 '18 at 09:31
  • I've added more info in the question. It's the right folder that's mounted, but it get's mounted on every user and on the `base` folder, which it shouldn't do... at least it doesn't on C6 :D – plamer May 21 '18 at 09:49
  • I think the problem is not related to the `mount --bind /home/$user /chroot/$user/home/$user` command but it rather looks like your `/home` is mounted or symlinked in `/chroot/base/home`. Can you `unmount` the bind mounts and check what is in `/chroot/base/home`. – Thomas May 21 '18 at 10:06
  • After unmounting them there is nothing in `/chroot/base/home` - it's empty directory (no symlink, nothing). The same in `/chroot/base/user1/home/user1` - just an empty directory. – plamer May 21 '18 at 10:32
  • Oh yes, you are right. I think the default mount option `private` changed to `shared` somewhen. Documents I have found so far ( e.g. *Documentation/filesystems/sharedsubtree.txt* ) refer to that `private` is the default, but if you look at `/proc/self/mountinfo`, that shows something different. – Thomas May 21 '18 at 11:17
  • Yes! Ah thank you! That's it :) Please write it as an answer so I can mark it :) – plamer May 21 '18 at 13:03

1 Answers1

3

The source of the behaviour seems the changed default of the shared subtrees operation. The kernel documentation Documentation/sharedsubtree.txt mentions that private is the default, whereas actually it is shared which can be obtained by viewing /proc/self/mountinfo after mounting a directory with --bind.

root@localhost ~]# mount --bind /chroot/base /chroot/test
[root@localhost ~]# grep test /proc/self/mountinfo
234 62 253:1 /chroot/base /chroot/test rw,relatime shared:1 - xfs /dev/vda1 rw,attr2,inode64,noquota

This causes propagation of mounts under /chroot/test back to /chroot/base which then affects the other bind-mounts derived from /chroot/base.

To get back the old behaviour, one has to specifiy --make-private explicitly or private as mount option in /etc/fstab.

[root@localhost ~]# umount /chroot/test
[root@localhost ~]# mount --bind --make-private /chroot/base /chroot/test
[root@localhost ~]# grep test /proc/self/mountinfo
234 62 253:1 /chroot/base /chroot/test rw,relatime - xfs /dev/vda1 rw,attr2,inode64,noquota

I think it is save to apply the private option to any bind-mount you want the old behaviour back.


Update

The kernel default is still private but systemd is remounting the filesystems as shared due to better container support. From the systemd github site:

Mark the root directory as shared in regards to mount propagation. The kernel defaults to "private", but we think it makes more sense to have a default of "shared" so that nspawn and the container tools work out of the box. If specific setups need other settings they can reset the propagation mode to private if needed. Note that we set this only when we are invoked directly by the kernel. If we are invoked by a container manager we assume the container manager knows what it is doing (for example, because it set up some directories with different propagation modes).

Thomas
  • 4,225
  • 5
  • 23
  • 28