Created attachment 801183 [details] makeshift test code. Description of problem: Once bind-mount point is marked as MS_SLAVE, it cannot be converted to MS_SHARED again. For example, mount("/root/orig", "/root/bind", NULL, MS_BIND|MS_REC, NULL); mount(NULL, "/root/bind", NULL, MS_SLAVE|MS_REC, NULL); This makes "/root/bind" a salve mount point, that is, additional bind-mount under /root/bind is not seen from /root/orig. After this operation, mount(NULL, "/root/bind", NULL, MS_SHARED, NULL) I expect this will make "/root/bind" a shared mount point. But "/root/bind" still behaves as MS_SLAVE. I checked this with the attached makeshift test code. The resulst is as below. ============== # ./bindtest mount --bind /root/orig /root/bind ---- mark /root/bind as shared mount --bind /tmp /root/bind/tmp ls /root/orig/tmp ### /root/bind/tmp can be seen from /root/orig/tmp as expected. yum_save_tx.2013-09-22.04-53.Cu432Q.yumtx ---- mark /root/bind as slave mount --bind /tmp /root/bind/tmp ls /root/orig/tmp ### /root/bind/tmp can't be seen from /root/orig/tmp as expected. ---- mark /root/bind as shared, again mount --bind /tmp /root/bind/tmp ls /root/orig/tmp ### /root/bind/tmp can't be seen from /root/orig/tmp though it's marked as MS_SHARE ---- ============== Is this an intentional behavior of the kernel??? Version-Release number of selected component (if applicable): # rpm -q kernel kernel-3.9.5-301.fc19.x86_64 # rpm -q glibc glibc-2.17-14.fc19.x86_64 # cat /etc/redhat-release Fedora release 19 (Schrödinger’s Cat)
OK, so I spent some time looking at this today. Essentially, your second call to make /root/bind shared is making it shared, but it doesn't clear the slave state. What you wind up with is a mount that is in 'shared and slave' state. Basically, that mount point will receive propagation events from it's master (in this case /root/orig), and it will forward propagation events to it's peer group and it's slaves. It's peer group isn't the same group as it's master, so the master (/root/orig) doesn't receive mount events. You can see the shared slave state and group info in /proc/self/mountinfo. I've illustrated it below: [root@hansolo ~]# mount --bind /root/orig /root/bind [root@hansolo ~]# mount --make-shared /root/bind [root@hansolo ~]# mount --bind /tmp /root/bind/tmp [root@hansolo ~]# ls -l /root/orig/tmp total 24 -rw------- 1 jwboyer jwboyer 939 Sep 23 08:24 krb5cc_500 drwx------ 2 gdm gdm 4096 Sep 23 08:23 pulse-sXQxnhVNJ4r5 drwx------ 2 jwboyer jwboyer 4096 Sep 23 08:24 ssh-BnhXwo2226 drwx------ 2 jwboyer jwboyer 4096 Sep 25 14:31 ssh-DzXbh11272 drwx------ 2 jwboyer jwboyer 4096 Sep 17 08:47 ssh-feBoQ23013 drwx------ 2 jwboyer jwboyer 4096 Sep 23 08:22 ssh-mFlElp2103 [root@hansolo ~]# umount /root/bind/tmp [root@hansolo ~]# mount --make-slave /root/bind [root@hansolo ~]# mount --bind /tmp /root/bind/tmp [root@hansolo ~]# ls /root/orig/tmp [root@hansolo ~]# umount /root/bind/tmp [root@hansolo ~]# mount --make-shared /root/bind [root@hansolo ~]# mount --bind /tmp /root/bind/tmp [root@hansolo ~]# ls /root/orig/tmp [root@hansolo ~]# ls /root/bind/tmp krb5cc_500 ssh-BnhXwo2226 ssh-feBoQ23013 pulse-sXQxnhVNJ4r5 ssh-DzXbh11272 ssh-mFlElp2103 [root@hansolo ~]# umount /root/bind/tmp Everything up to this point is identical to your example. Now we bind mount /tmp to /root/orig/tmp and we can see it in both /root/orig/tmp and /root/bind/tmp: [root@hansolo ~]# mount --bind /tmp /root/orig/tmp [root@hansolo ~]# ls /root/orig/tmp krb5cc_500 ssh-BnhXwo2226 ssh-feBoQ23013 pulse-sXQxnhVNJ4r5 ssh-DzXbh11272 ssh-mFlElp2103 [root@hansolo ~]# ls /root/bind/tmp krb5cc_500 ssh-BnhXwo2226 ssh-feBoQ23013 pulse-sXQxnhVNJ4r5 ssh-DzXbh11272 ssh-mFlElp2103 [root@hansolo ~]# umount /root/orig/tmp Then if we look at mountinfo for the /root/* mounts: [root@hansolo ~]# cat /proc/self/mountinfo | grep "/root" 48 21 8:3 /root/orig /root/bind rw,relatime shared:2 master:1 - ext3 /dev/sda3 rw,data=ordered [root@hansolo ~]# We see that /root/bind is in shared slave mode, with the master being group 1 (or / in our example) and the shared peer group being 2. If you want to make a slave mount go back to shared mode, and not shared slave, you can make it private and then make it shared again. As far as I can tell, that is the only way to clear slave mode. I think this is working as intended, and as documented for shared slave in Documentation/filesystems/sharedsubtrees.txt in the kernel source tree. If you have further questions, I would recommend emailing the VFS maintainers and LKML with your example and I'm sure they'll be able to answer them more quickly than I can.