1cf06612cSMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0 2cf06612cSMauro Carvalho Chehab 3cf06612cSMauro Carvalho Chehab=============== 4cf06612cSMauro Carvalho ChehabShared Subtrees 5cf06612cSMauro Carvalho Chehab=============== 6cf06612cSMauro Carvalho Chehab 7cf06612cSMauro Carvalho Chehab.. Contents: 8cf06612cSMauro Carvalho Chehab 1) Overview 9cf06612cSMauro Carvalho Chehab 2) Features 10cf06612cSMauro Carvalho Chehab 3) Setting mount states 11cf06612cSMauro Carvalho Chehab 4) Use-case 12cf06612cSMauro Carvalho Chehab 5) Detailed semantics 13cf06612cSMauro Carvalho Chehab 6) Quiz 14cf06612cSMauro Carvalho Chehab 7) FAQ 15cf06612cSMauro Carvalho Chehab 8) Implementation 16cf06612cSMauro Carvalho Chehab 17cf06612cSMauro Carvalho Chehab 18cf06612cSMauro Carvalho Chehab1) Overview 19cf06612cSMauro Carvalho Chehab----------- 20cf06612cSMauro Carvalho Chehab 21cf06612cSMauro Carvalho ChehabConsider the following situation: 22cf06612cSMauro Carvalho Chehab 23cf06612cSMauro Carvalho ChehabA process wants to clone its own namespace, but still wants to access the CD 24cf06612cSMauro Carvalho Chehabthat got mounted recently. Shared subtree semantics provide the necessary 25cf06612cSMauro Carvalho Chehabmechanism to accomplish the above. 26cf06612cSMauro Carvalho Chehab 27cf06612cSMauro Carvalho ChehabIt provides the necessary building blocks for features like per-user-namespace 28cf06612cSMauro Carvalho Chehaband versioned filesystem. 29cf06612cSMauro Carvalho Chehab 30cf06612cSMauro Carvalho Chehab2) Features 31cf06612cSMauro Carvalho Chehab----------- 32cf06612cSMauro Carvalho Chehab 33cf06612cSMauro Carvalho ChehabShared subtree provides four different flavors of mounts; struct vfsmount to be 34cf06612cSMauro Carvalho Chehabprecise 35cf06612cSMauro Carvalho Chehab 36cf06612cSMauro Carvalho Chehab a. shared mount 37cf06612cSMauro Carvalho Chehab b. slave mount 38cf06612cSMauro Carvalho Chehab c. private mount 39cf06612cSMauro Carvalho Chehab d. unbindable mount 40cf06612cSMauro Carvalho Chehab 41cf06612cSMauro Carvalho Chehab 42cf06612cSMauro Carvalho Chehab2a) A shared mount can be replicated to as many mountpoints and all the 43cf06612cSMauro Carvalho Chehabreplicas continue to be exactly same. 44cf06612cSMauro Carvalho Chehab 45cf06612cSMauro Carvalho Chehab Here is an example: 46cf06612cSMauro Carvalho Chehab 47cf06612cSMauro Carvalho Chehab Let's say /mnt has a mount that is shared:: 48cf06612cSMauro Carvalho Chehab 49cf06612cSMauro Carvalho Chehab mount --make-shared /mnt 50cf06612cSMauro Carvalho Chehab 51cf06612cSMauro Carvalho Chehab Note: mount(8) command now supports the --make-shared flag, 52cf06612cSMauro Carvalho Chehab so the sample 'smount' program is no longer needed and has been 53cf06612cSMauro Carvalho Chehab removed. 54cf06612cSMauro Carvalho Chehab 55cf06612cSMauro Carvalho Chehab :: 56cf06612cSMauro Carvalho Chehab 57cf06612cSMauro Carvalho Chehab # mount --bind /mnt /tmp 58cf06612cSMauro Carvalho Chehab 59cf06612cSMauro Carvalho Chehab The above command replicates the mount at /mnt to the mountpoint /tmp 60cf06612cSMauro Carvalho Chehab and the contents of both the mounts remain identical. 61cf06612cSMauro Carvalho Chehab 62cf06612cSMauro Carvalho Chehab :: 63cf06612cSMauro Carvalho Chehab 64cf06612cSMauro Carvalho Chehab #ls /mnt 65cf06612cSMauro Carvalho Chehab a b c 66cf06612cSMauro Carvalho Chehab 67cf06612cSMauro Carvalho Chehab #ls /tmp 68cf06612cSMauro Carvalho Chehab a b c 69cf06612cSMauro Carvalho Chehab 70cf06612cSMauro Carvalho Chehab Now let's say we mount a device at /tmp/a:: 71cf06612cSMauro Carvalho Chehab 72cf06612cSMauro Carvalho Chehab # mount /dev/sd0 /tmp/a 73cf06612cSMauro Carvalho Chehab 74cf06612cSMauro Carvalho Chehab #ls /tmp/a 75cf06612cSMauro Carvalho Chehab t1 t2 t3 76cf06612cSMauro Carvalho Chehab 77cf06612cSMauro Carvalho Chehab #ls /mnt/a 78cf06612cSMauro Carvalho Chehab t1 t2 t3 79cf06612cSMauro Carvalho Chehab 80cf06612cSMauro Carvalho Chehab Note that the mount has propagated to the mount at /mnt as well. 81cf06612cSMauro Carvalho Chehab 82cf06612cSMauro Carvalho Chehab And the same is true even when /dev/sd0 is mounted on /mnt/a. The 83cf06612cSMauro Carvalho Chehab contents will be visible under /tmp/a too. 84cf06612cSMauro Carvalho Chehab 85cf06612cSMauro Carvalho Chehab 86cf06612cSMauro Carvalho Chehab2b) A slave mount is like a shared mount except that mount and umount events 87cf06612cSMauro Carvalho Chehab only propagate towards it. 88cf06612cSMauro Carvalho Chehab 89cf06612cSMauro Carvalho Chehab All slave mounts have a master mount which is a shared. 90cf06612cSMauro Carvalho Chehab 91cf06612cSMauro Carvalho Chehab Here is an example: 92cf06612cSMauro Carvalho Chehab 93cf06612cSMauro Carvalho Chehab Let's say /mnt has a mount which is shared. 94cf06612cSMauro Carvalho Chehab # mount --make-shared /mnt 95cf06612cSMauro Carvalho Chehab 96cf06612cSMauro Carvalho Chehab Let's bind mount /mnt to /tmp 97cf06612cSMauro Carvalho Chehab # mount --bind /mnt /tmp 98cf06612cSMauro Carvalho Chehab 99cf06612cSMauro Carvalho Chehab the new mount at /tmp becomes a shared mount and it is a replica of 100cf06612cSMauro Carvalho Chehab the mount at /mnt. 101cf06612cSMauro Carvalho Chehab 102cf06612cSMauro Carvalho Chehab Now let's make the mount at /tmp; a slave of /mnt 103cf06612cSMauro Carvalho Chehab # mount --make-slave /tmp 104cf06612cSMauro Carvalho Chehab 105cf06612cSMauro Carvalho Chehab let's mount /dev/sd0 on /mnt/a 106cf06612cSMauro Carvalho Chehab # mount /dev/sd0 /mnt/a 107cf06612cSMauro Carvalho Chehab 108cf06612cSMauro Carvalho Chehab #ls /mnt/a 109cf06612cSMauro Carvalho Chehab t1 t2 t3 110cf06612cSMauro Carvalho Chehab 111cf06612cSMauro Carvalho Chehab #ls /tmp/a 112cf06612cSMauro Carvalho Chehab t1 t2 t3 113cf06612cSMauro Carvalho Chehab 114cf06612cSMauro Carvalho Chehab Note the mount event has propagated to the mount at /tmp 115cf06612cSMauro Carvalho Chehab 116cf06612cSMauro Carvalho Chehab However let's see what happens if we mount something on the mount at /tmp 117cf06612cSMauro Carvalho Chehab 118cf06612cSMauro Carvalho Chehab # mount /dev/sd1 /tmp/b 119cf06612cSMauro Carvalho Chehab 120cf06612cSMauro Carvalho Chehab #ls /tmp/b 121cf06612cSMauro Carvalho Chehab s1 s2 s3 122cf06612cSMauro Carvalho Chehab 123cf06612cSMauro Carvalho Chehab #ls /mnt/b 124cf06612cSMauro Carvalho Chehab 125cf06612cSMauro Carvalho Chehab Note how the mount event has not propagated to the mount at 126cf06612cSMauro Carvalho Chehab /mnt 127cf06612cSMauro Carvalho Chehab 128cf06612cSMauro Carvalho Chehab 129cf06612cSMauro Carvalho Chehab2c) A private mount does not forward or receive propagation. 130cf06612cSMauro Carvalho Chehab 131cf06612cSMauro Carvalho Chehab This is the mount we are familiar with. Its the default type. 132cf06612cSMauro Carvalho Chehab 133cf06612cSMauro Carvalho Chehab 134cf06612cSMauro Carvalho Chehab2d) A unbindable mount is a unbindable private mount 135cf06612cSMauro Carvalho Chehab 136cf06612cSMauro Carvalho Chehab let's say we have a mount at /mnt and we make it unbindable:: 137cf06612cSMauro Carvalho Chehab 138cf06612cSMauro Carvalho Chehab # mount --make-unbindable /mnt 139cf06612cSMauro Carvalho Chehab 140cf06612cSMauro Carvalho Chehab Let's try to bind mount this mount somewhere else:: 141cf06612cSMauro Carvalho Chehab 142cf06612cSMauro Carvalho Chehab # mount --bind /mnt /tmp 143cf06612cSMauro Carvalho Chehab mount: wrong fs type, bad option, bad superblock on /mnt, 144cf06612cSMauro Carvalho Chehab or too many mounted file systems 145cf06612cSMauro Carvalho Chehab 146cf06612cSMauro Carvalho Chehab Binding a unbindable mount is a invalid operation. 147cf06612cSMauro Carvalho Chehab 148cf06612cSMauro Carvalho Chehab 149cf06612cSMauro Carvalho Chehab3) Setting mount states 150*7b38ecfdSRandy Dunlap----------------------- 151cf06612cSMauro Carvalho Chehab 152cf06612cSMauro Carvalho Chehab The mount command (util-linux package) can be used to set mount 153cf06612cSMauro Carvalho Chehab states:: 154cf06612cSMauro Carvalho Chehab 155cf06612cSMauro Carvalho Chehab mount --make-shared mountpoint 156cf06612cSMauro Carvalho Chehab mount --make-slave mountpoint 157cf06612cSMauro Carvalho Chehab mount --make-private mountpoint 158cf06612cSMauro Carvalho Chehab mount --make-unbindable mountpoint 159cf06612cSMauro Carvalho Chehab 160cf06612cSMauro Carvalho Chehab 161cf06612cSMauro Carvalho Chehab4) Use cases 162cf06612cSMauro Carvalho Chehab------------ 163cf06612cSMauro Carvalho Chehab 164cf06612cSMauro Carvalho Chehab A) A process wants to clone its own namespace, but still wants to 165cf06612cSMauro Carvalho Chehab access the CD that got mounted recently. 166cf06612cSMauro Carvalho Chehab 167cf06612cSMauro Carvalho Chehab Solution: 168cf06612cSMauro Carvalho Chehab 169cf06612cSMauro Carvalho Chehab The system administrator can make the mount at /cdrom shared:: 170cf06612cSMauro Carvalho Chehab 171cf06612cSMauro Carvalho Chehab mount --bind /cdrom /cdrom 172cf06612cSMauro Carvalho Chehab mount --make-shared /cdrom 173cf06612cSMauro Carvalho Chehab 174cf06612cSMauro Carvalho Chehab Now any process that clones off a new namespace will have a 175cf06612cSMauro Carvalho Chehab mount at /cdrom which is a replica of the same mount in the 176cf06612cSMauro Carvalho Chehab parent namespace. 177cf06612cSMauro Carvalho Chehab 178cf06612cSMauro Carvalho Chehab So when a CD is inserted and mounted at /cdrom that mount gets 179cf06612cSMauro Carvalho Chehab propagated to the other mount at /cdrom in all the other clone 180cf06612cSMauro Carvalho Chehab namespaces. 181cf06612cSMauro Carvalho Chehab 182cf06612cSMauro Carvalho Chehab B) A process wants its mounts invisible to any other process, but 183cf06612cSMauro Carvalho Chehab still be able to see the other system mounts. 184cf06612cSMauro Carvalho Chehab 185cf06612cSMauro Carvalho Chehab Solution: 186cf06612cSMauro Carvalho Chehab 187cf06612cSMauro Carvalho Chehab To begin with, the administrator can mark the entire mount tree 188cf06612cSMauro Carvalho Chehab as shareable:: 189cf06612cSMauro Carvalho Chehab 190cf06612cSMauro Carvalho Chehab mount --make-rshared / 191cf06612cSMauro Carvalho Chehab 192cf06612cSMauro Carvalho Chehab A new process can clone off a new namespace. And mark some part 193cf06612cSMauro Carvalho Chehab of its namespace as slave:: 194cf06612cSMauro Carvalho Chehab 195cf06612cSMauro Carvalho Chehab mount --make-rslave /myprivatetree 196cf06612cSMauro Carvalho Chehab 197cf06612cSMauro Carvalho Chehab Hence forth any mounts within the /myprivatetree done by the 198cf06612cSMauro Carvalho Chehab process will not show up in any other namespace. However mounts 199cf06612cSMauro Carvalho Chehab done in the parent namespace under /myprivatetree still shows 200cf06612cSMauro Carvalho Chehab up in the process's namespace. 201cf06612cSMauro Carvalho Chehab 202cf06612cSMauro Carvalho Chehab 203cf06612cSMauro Carvalho Chehab Apart from the above semantics this feature provides the 204cf06612cSMauro Carvalho Chehab building blocks to solve the following problems: 205cf06612cSMauro Carvalho Chehab 206cf06612cSMauro Carvalho Chehab C) Per-user namespace 207cf06612cSMauro Carvalho Chehab 208cf06612cSMauro Carvalho Chehab The above semantics allows a way to share mounts across 209cf06612cSMauro Carvalho Chehab namespaces. But namespaces are associated with processes. If 210cf06612cSMauro Carvalho Chehab namespaces are made first class objects with user API to 211cf06612cSMauro Carvalho Chehab associate/disassociate a namespace with userid, then each user 212cf06612cSMauro Carvalho Chehab could have his/her own namespace and tailor it to his/her 213cf06612cSMauro Carvalho Chehab requirements. This needs to be supported in PAM. 214cf06612cSMauro Carvalho Chehab 215cf06612cSMauro Carvalho Chehab D) Versioned files 216cf06612cSMauro Carvalho Chehab 217cf06612cSMauro Carvalho Chehab If the entire mount tree is visible at multiple locations, then 218cf06612cSMauro Carvalho Chehab an underlying versioning file system can return different 219cf06612cSMauro Carvalho Chehab versions of the file depending on the path used to access that 220cf06612cSMauro Carvalho Chehab file. 221cf06612cSMauro Carvalho Chehab 222cf06612cSMauro Carvalho Chehab An example is:: 223cf06612cSMauro Carvalho Chehab 224cf06612cSMauro Carvalho Chehab mount --make-shared / 225cf06612cSMauro Carvalho Chehab mount --rbind / /view/v1 226cf06612cSMauro Carvalho Chehab mount --rbind / /view/v2 227cf06612cSMauro Carvalho Chehab mount --rbind / /view/v3 228cf06612cSMauro Carvalho Chehab mount --rbind / /view/v4 229cf06612cSMauro Carvalho Chehab 230cf06612cSMauro Carvalho Chehab and if /usr has a versioning filesystem mounted, then that 231cf06612cSMauro Carvalho Chehab mount appears at /view/v1/usr, /view/v2/usr, /view/v3/usr and 232cf06612cSMauro Carvalho Chehab /view/v4/usr too 233cf06612cSMauro Carvalho Chehab 234cf06612cSMauro Carvalho Chehab A user can request v3 version of the file /usr/fs/namespace.c 235cf06612cSMauro Carvalho Chehab by accessing /view/v3/usr/fs/namespace.c . The underlying 236cf06612cSMauro Carvalho Chehab versioning filesystem can then decipher that v3 version of the 237cf06612cSMauro Carvalho Chehab filesystem is being requested and return the corresponding 238cf06612cSMauro Carvalho Chehab inode. 239cf06612cSMauro Carvalho Chehab 240cf06612cSMauro Carvalho Chehab5) Detailed semantics 241cf06612cSMauro Carvalho Chehab--------------------- 242cf06612cSMauro Carvalho Chehab The section below explains the detailed semantics of 243cf06612cSMauro Carvalho Chehab bind, rbind, move, mount, umount and clone-namespace operations. 244cf06612cSMauro Carvalho Chehab 245cf06612cSMauro Carvalho Chehab Note: the word 'vfsmount' and the noun 'mount' have been used 246cf06612cSMauro Carvalho Chehab to mean the same thing, throughout this document. 247cf06612cSMauro Carvalho Chehab 248cf06612cSMauro Carvalho Chehab5a) Mount states 249cf06612cSMauro Carvalho Chehab 250cf06612cSMauro Carvalho Chehab A given mount can be in one of the following states 251cf06612cSMauro Carvalho Chehab 252cf06612cSMauro Carvalho Chehab 1) shared 253cf06612cSMauro Carvalho Chehab 2) slave 254cf06612cSMauro Carvalho Chehab 3) shared and slave 255cf06612cSMauro Carvalho Chehab 4) private 256cf06612cSMauro Carvalho Chehab 5) unbindable 257cf06612cSMauro Carvalho Chehab 258cf06612cSMauro Carvalho Chehab A 'propagation event' is defined as event generated on a vfsmount 259cf06612cSMauro Carvalho Chehab that leads to mount or unmount actions in other vfsmounts. 260cf06612cSMauro Carvalho Chehab 261cf06612cSMauro Carvalho Chehab A 'peer group' is defined as a group of vfsmounts that propagate 262cf06612cSMauro Carvalho Chehab events to each other. 263cf06612cSMauro Carvalho Chehab 264cf06612cSMauro Carvalho Chehab (1) Shared mounts 265cf06612cSMauro Carvalho Chehab 266cf06612cSMauro Carvalho Chehab A 'shared mount' is defined as a vfsmount that belongs to a 267cf06612cSMauro Carvalho Chehab 'peer group'. 268cf06612cSMauro Carvalho Chehab 269cf06612cSMauro Carvalho Chehab For example:: 270cf06612cSMauro Carvalho Chehab 271cf06612cSMauro Carvalho Chehab mount --make-shared /mnt 272cf06612cSMauro Carvalho Chehab mount --bind /mnt /tmp 273cf06612cSMauro Carvalho Chehab 274cf06612cSMauro Carvalho Chehab The mount at /mnt and that at /tmp are both shared and belong 275cf06612cSMauro Carvalho Chehab to the same peer group. Anything mounted or unmounted under 276cf06612cSMauro Carvalho Chehab /mnt or /tmp reflect in all the other mounts of its peer 277cf06612cSMauro Carvalho Chehab group. 278cf06612cSMauro Carvalho Chehab 279cf06612cSMauro Carvalho Chehab 280cf06612cSMauro Carvalho Chehab (2) Slave mounts 281cf06612cSMauro Carvalho Chehab 282cf06612cSMauro Carvalho Chehab A 'slave mount' is defined as a vfsmount that receives 283cf06612cSMauro Carvalho Chehab propagation events and does not forward propagation events. 284cf06612cSMauro Carvalho Chehab 285cf06612cSMauro Carvalho Chehab A slave mount as the name implies has a master mount from which 286cf06612cSMauro Carvalho Chehab mount/unmount events are received. Events do not propagate from 287cf06612cSMauro Carvalho Chehab the slave mount to the master. Only a shared mount can be made 288cf06612cSMauro Carvalho Chehab a slave by executing the following command:: 289cf06612cSMauro Carvalho Chehab 290cf06612cSMauro Carvalho Chehab mount --make-slave mount 291cf06612cSMauro Carvalho Chehab 292cf06612cSMauro Carvalho Chehab A shared mount that is made as a slave is no more shared unless 293cf06612cSMauro Carvalho Chehab modified to become shared. 294cf06612cSMauro Carvalho Chehab 295cf06612cSMauro Carvalho Chehab (3) Shared and Slave 296cf06612cSMauro Carvalho Chehab 297cf06612cSMauro Carvalho Chehab A vfsmount can be both shared as well as slave. This state 298cf06612cSMauro Carvalho Chehab indicates that the mount is a slave of some vfsmount, and 299cf06612cSMauro Carvalho Chehab has its own peer group too. This vfsmount receives propagation 300cf06612cSMauro Carvalho Chehab events from its master vfsmount, and also forwards propagation 301cf06612cSMauro Carvalho Chehab events to its 'peer group' and to its slave vfsmounts. 302cf06612cSMauro Carvalho Chehab 303cf06612cSMauro Carvalho Chehab Strictly speaking, the vfsmount is shared having its own 304cf06612cSMauro Carvalho Chehab peer group, and this peer-group is a slave of some other 305cf06612cSMauro Carvalho Chehab peer group. 306cf06612cSMauro Carvalho Chehab 307cf06612cSMauro Carvalho Chehab Only a slave vfsmount can be made as 'shared and slave' by 308cf06612cSMauro Carvalho Chehab either executing the following command:: 309cf06612cSMauro Carvalho Chehab 310cf06612cSMauro Carvalho Chehab mount --make-shared mount 311cf06612cSMauro Carvalho Chehab 312cf06612cSMauro Carvalho Chehab or by moving the slave vfsmount under a shared vfsmount. 313cf06612cSMauro Carvalho Chehab 314cf06612cSMauro Carvalho Chehab (4) Private mount 315cf06612cSMauro Carvalho Chehab 316cf06612cSMauro Carvalho Chehab A 'private mount' is defined as vfsmount that does not 317cf06612cSMauro Carvalho Chehab receive or forward any propagation events. 318cf06612cSMauro Carvalho Chehab 319cf06612cSMauro Carvalho Chehab (5) Unbindable mount 320cf06612cSMauro Carvalho Chehab 321cf06612cSMauro Carvalho Chehab A 'unbindable mount' is defined as vfsmount that does not 322cf06612cSMauro Carvalho Chehab receive or forward any propagation events and cannot 323cf06612cSMauro Carvalho Chehab be bind mounted. 324cf06612cSMauro Carvalho Chehab 325cf06612cSMauro Carvalho Chehab 326cf06612cSMauro Carvalho Chehab State diagram: 327cf06612cSMauro Carvalho Chehab 328cf06612cSMauro Carvalho Chehab The state diagram below explains the state transition of a mount, 329cf06612cSMauro Carvalho Chehab in response to various commands:: 330cf06612cSMauro Carvalho Chehab 331cf06612cSMauro Carvalho Chehab ----------------------------------------------------------------------- 332cf06612cSMauro Carvalho Chehab | |make-shared | make-slave | make-private |make-unbindab| 333cf06612cSMauro Carvalho Chehab --------------|------------|--------------|--------------|-------------| 334cf06612cSMauro Carvalho Chehab |shared |shared |*slave/private| private | unbindable | 335cf06612cSMauro Carvalho Chehab | | | | | | 336cf06612cSMauro Carvalho Chehab |-------------|------------|--------------|--------------|-------------| 337cf06612cSMauro Carvalho Chehab |slave |shared | **slave | private | unbindable | 338cf06612cSMauro Carvalho Chehab | |and slave | | | | 339cf06612cSMauro Carvalho Chehab |-------------|------------|--------------|--------------|-------------| 340cf06612cSMauro Carvalho Chehab |shared |shared | slave | private | unbindable | 341cf06612cSMauro Carvalho Chehab |and slave |and slave | | | | 342cf06612cSMauro Carvalho Chehab |-------------|------------|--------------|--------------|-------------| 343cf06612cSMauro Carvalho Chehab |private |shared | **private | private | unbindable | 344cf06612cSMauro Carvalho Chehab |-------------|------------|--------------|--------------|-------------| 345cf06612cSMauro Carvalho Chehab |unbindable |shared |**unbindable | private | unbindable | 346cf06612cSMauro Carvalho Chehab ------------------------------------------------------------------------ 347cf06612cSMauro Carvalho Chehab 348cf06612cSMauro Carvalho Chehab * if the shared mount is the only mount in its peer group, making it 349cf06612cSMauro Carvalho Chehab slave, makes it private automatically. Note that there is no master to 350cf06612cSMauro Carvalho Chehab which it can be slaved to. 351cf06612cSMauro Carvalho Chehab 352cf06612cSMauro Carvalho Chehab ** slaving a non-shared mount has no effect on the mount. 353cf06612cSMauro Carvalho Chehab 354cf06612cSMauro Carvalho Chehab Apart from the commands listed below, the 'move' operation also changes 355cf06612cSMauro Carvalho Chehab the state of a mount depending on type of the destination mount. Its 356cf06612cSMauro Carvalho Chehab explained in section 5d. 357cf06612cSMauro Carvalho Chehab 358cf06612cSMauro Carvalho Chehab5b) Bind semantics 359cf06612cSMauro Carvalho Chehab 360cf06612cSMauro Carvalho Chehab Consider the following command:: 361cf06612cSMauro Carvalho Chehab 362cf06612cSMauro Carvalho Chehab mount --bind A/a B/b 363cf06612cSMauro Carvalho Chehab 364cf06612cSMauro Carvalho Chehab where 'A' is the source mount, 'a' is the dentry in the mount 'A', 'B' 365cf06612cSMauro Carvalho Chehab is the destination mount and 'b' is the dentry in the destination mount. 366cf06612cSMauro Carvalho Chehab 367cf06612cSMauro Carvalho Chehab The outcome depends on the type of mount of 'A' and 'B'. The table 368cf06612cSMauro Carvalho Chehab below contains quick reference:: 369cf06612cSMauro Carvalho Chehab 370cf06612cSMauro Carvalho Chehab -------------------------------------------------------------------------- 371cf06612cSMauro Carvalho Chehab | BIND MOUNT OPERATION | 372cf06612cSMauro Carvalho Chehab |************************************************************************| 373cf06612cSMauro Carvalho Chehab |source(A)->| shared | private | slave | unbindable | 374cf06612cSMauro Carvalho Chehab | dest(B) | | | | | 375cf06612cSMauro Carvalho Chehab | | | | | | | 376cf06612cSMauro Carvalho Chehab | v | | | | | 377cf06612cSMauro Carvalho Chehab |************************************************************************| 378cf06612cSMauro Carvalho Chehab | shared | shared | shared | shared & slave | invalid | 379cf06612cSMauro Carvalho Chehab | | | | | | 380cf06612cSMauro Carvalho Chehab |non-shared| shared | private | slave | invalid | 381cf06612cSMauro Carvalho Chehab ************************************************************************** 382cf06612cSMauro Carvalho Chehab 383cf06612cSMauro Carvalho Chehab Details: 384cf06612cSMauro Carvalho Chehab 385cf06612cSMauro Carvalho Chehab 1. 'A' is a shared mount and 'B' is a shared mount. A new mount 'C' 386cf06612cSMauro Carvalho Chehab which is clone of 'A', is created. Its root dentry is 'a' . 'C' is 387cf06612cSMauro Carvalho Chehab mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ... 388cf06612cSMauro Carvalho Chehab are created and mounted at the dentry 'b' on all mounts where 'B' 389cf06612cSMauro Carvalho Chehab propagates to. A new propagation tree containing 'C1',..,'Cn' is 390cf06612cSMauro Carvalho Chehab created. This propagation tree is identical to the propagation tree of 391cf06612cSMauro Carvalho Chehab 'B'. And finally the peer-group of 'C' is merged with the peer group 392cf06612cSMauro Carvalho Chehab of 'A'. 393cf06612cSMauro Carvalho Chehab 394cf06612cSMauro Carvalho Chehab 2. 'A' is a private mount and 'B' is a shared mount. A new mount 'C' 395cf06612cSMauro Carvalho Chehab which is clone of 'A', is created. Its root dentry is 'a'. 'C' is 396cf06612cSMauro Carvalho Chehab mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ... 397cf06612cSMauro Carvalho Chehab are created and mounted at the dentry 'b' on all mounts where 'B' 398cf06612cSMauro Carvalho Chehab propagates to. A new propagation tree is set containing all new mounts 399cf06612cSMauro Carvalho Chehab 'C', 'C1', .., 'Cn' with exactly the same configuration as the 400cf06612cSMauro Carvalho Chehab propagation tree for 'B'. 401cf06612cSMauro Carvalho Chehab 402cf06612cSMauro Carvalho Chehab 3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. A new 403cf06612cSMauro Carvalho Chehab mount 'C' which is clone of 'A', is created. Its root dentry is 'a' . 404cf06612cSMauro Carvalho Chehab 'C' is mounted on mount 'B' at dentry 'b'. Also new mounts 'C1', 'C2', 405cf06612cSMauro Carvalho Chehab 'C3' ... are created and mounted at the dentry 'b' on all mounts where 406cf06612cSMauro Carvalho Chehab 'B' propagates to. A new propagation tree containing the new mounts 407cf06612cSMauro Carvalho Chehab 'C','C1',.. 'Cn' is created. This propagation tree is identical to the 408cf06612cSMauro Carvalho Chehab propagation tree for 'B'. And finally the mount 'C' and its peer group 409cf06612cSMauro Carvalho Chehab is made the slave of mount 'Z'. In other words, mount 'C' is in the 410cf06612cSMauro Carvalho Chehab state 'slave and shared'. 411cf06612cSMauro Carvalho Chehab 412cf06612cSMauro Carvalho Chehab 4. 'A' is a unbindable mount and 'B' is a shared mount. This is a 413cf06612cSMauro Carvalho Chehab invalid operation. 414cf06612cSMauro Carvalho Chehab 415cf06612cSMauro Carvalho Chehab 5. 'A' is a private mount and 'B' is a non-shared(private or slave or 416cf06612cSMauro Carvalho Chehab unbindable) mount. A new mount 'C' which is clone of 'A', is created. 417cf06612cSMauro Carvalho Chehab Its root dentry is 'a'. 'C' is mounted on mount 'B' at dentry 'b'. 418cf06612cSMauro Carvalho Chehab 419cf06612cSMauro Carvalho Chehab 6. 'A' is a shared mount and 'B' is a non-shared mount. A new mount 'C' 420cf06612cSMauro Carvalho Chehab which is a clone of 'A' is created. Its root dentry is 'a'. 'C' is 421cf06612cSMauro Carvalho Chehab mounted on mount 'B' at dentry 'b'. 'C' is made a member of the 422cf06612cSMauro Carvalho Chehab peer-group of 'A'. 423cf06612cSMauro Carvalho Chehab 424cf06612cSMauro Carvalho Chehab 7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount. A 425cf06612cSMauro Carvalho Chehab new mount 'C' which is a clone of 'A' is created. Its root dentry is 426cf06612cSMauro Carvalho Chehab 'a'. 'C' is mounted on mount 'B' at dentry 'b'. Also 'C' is set as a 427cf06612cSMauro Carvalho Chehab slave mount of 'Z'. In other words 'A' and 'C' are both slave mounts of 428cf06612cSMauro Carvalho Chehab 'Z'. All mount/unmount events on 'Z' propagates to 'A' and 'C'. But 429cf06612cSMauro Carvalho Chehab mount/unmount on 'A' do not propagate anywhere else. Similarly 430cf06612cSMauro Carvalho Chehab mount/unmount on 'C' do not propagate anywhere else. 431cf06612cSMauro Carvalho Chehab 432cf06612cSMauro Carvalho Chehab 8. 'A' is a unbindable mount and 'B' is a non-shared mount. This is a 433cf06612cSMauro Carvalho Chehab invalid operation. A unbindable mount cannot be bind mounted. 434cf06612cSMauro Carvalho Chehab 435cf06612cSMauro Carvalho Chehab5c) Rbind semantics 436cf06612cSMauro Carvalho Chehab 437cf06612cSMauro Carvalho Chehab rbind is same as bind. Bind replicates the specified mount. Rbind 438cf06612cSMauro Carvalho Chehab replicates all the mounts in the tree belonging to the specified mount. 439cf06612cSMauro Carvalho Chehab Rbind mount is bind mount applied to all the mounts in the tree. 440cf06612cSMauro Carvalho Chehab 441cf06612cSMauro Carvalho Chehab If the source tree that is rbind has some unbindable mounts, 442cf06612cSMauro Carvalho Chehab then the subtree under the unbindable mount is pruned in the new 443cf06612cSMauro Carvalho Chehab location. 444cf06612cSMauro Carvalho Chehab 445cf06612cSMauro Carvalho Chehab eg: 446cf06612cSMauro Carvalho Chehab 447cf06612cSMauro Carvalho Chehab let's say we have the following mount tree:: 448cf06612cSMauro Carvalho Chehab 449cf06612cSMauro Carvalho Chehab A 450cf06612cSMauro Carvalho Chehab / \ 451cf06612cSMauro Carvalho Chehab B C 452cf06612cSMauro Carvalho Chehab / \ / \ 453cf06612cSMauro Carvalho Chehab D E F G 454cf06612cSMauro Carvalho Chehab 455cf06612cSMauro Carvalho Chehab Let's say all the mount except the mount C in the tree are 456cf06612cSMauro Carvalho Chehab of a type other than unbindable. 457cf06612cSMauro Carvalho Chehab 458cf06612cSMauro Carvalho Chehab If this tree is rbound to say Z 459cf06612cSMauro Carvalho Chehab 460cf06612cSMauro Carvalho Chehab We will have the following tree at the new location:: 461cf06612cSMauro Carvalho Chehab 462cf06612cSMauro Carvalho Chehab Z 463cf06612cSMauro Carvalho Chehab | 464cf06612cSMauro Carvalho Chehab A' 465cf06612cSMauro Carvalho Chehab / 466cf06612cSMauro Carvalho Chehab B' Note how the tree under C is pruned 467cf06612cSMauro Carvalho Chehab / \ in the new location. 468cf06612cSMauro Carvalho Chehab D' E' 469cf06612cSMauro Carvalho Chehab 470cf06612cSMauro Carvalho Chehab 471cf06612cSMauro Carvalho Chehab 472cf06612cSMauro Carvalho Chehab5d) Move semantics 473cf06612cSMauro Carvalho Chehab 474cf06612cSMauro Carvalho Chehab Consider the following command 475cf06612cSMauro Carvalho Chehab 476cf06612cSMauro Carvalho Chehab mount --move A B/b 477cf06612cSMauro Carvalho Chehab 478cf06612cSMauro Carvalho Chehab where 'A' is the source mount, 'B' is the destination mount and 'b' is 479cf06612cSMauro Carvalho Chehab the dentry in the destination mount. 480cf06612cSMauro Carvalho Chehab 481cf06612cSMauro Carvalho Chehab The outcome depends on the type of the mount of 'A' and 'B'. The table 482cf06612cSMauro Carvalho Chehab below is a quick reference:: 483cf06612cSMauro Carvalho Chehab 484cf06612cSMauro Carvalho Chehab --------------------------------------------------------------------------- 485cf06612cSMauro Carvalho Chehab | MOVE MOUNT OPERATION | 486cf06612cSMauro Carvalho Chehab |************************************************************************** 487cf06612cSMauro Carvalho Chehab | source(A)->| shared | private | slave | unbindable | 488cf06612cSMauro Carvalho Chehab | dest(B) | | | | | 489cf06612cSMauro Carvalho Chehab | | | | | | | 490cf06612cSMauro Carvalho Chehab | v | | | | | 491cf06612cSMauro Carvalho Chehab |************************************************************************** 492cf06612cSMauro Carvalho Chehab | shared | shared | shared |shared and slave| invalid | 493cf06612cSMauro Carvalho Chehab | | | | | | 494cf06612cSMauro Carvalho Chehab |non-shared| shared | private | slave | unbindable | 495cf06612cSMauro Carvalho Chehab *************************************************************************** 496cf06612cSMauro Carvalho Chehab 497cf06612cSMauro Carvalho Chehab .. Note:: moving a mount residing under a shared mount is invalid. 498cf06612cSMauro Carvalho Chehab 499cf06612cSMauro Carvalho Chehab Details follow: 500cf06612cSMauro Carvalho Chehab 501cf06612cSMauro Carvalho Chehab 1. 'A' is a shared mount and 'B' is a shared mount. The mount 'A' is 502cf06612cSMauro Carvalho Chehab mounted on mount 'B' at dentry 'b'. Also new mounts 'A1', 'A2'...'An' 503cf06612cSMauro Carvalho Chehab are created and mounted at dentry 'b' on all mounts that receive 504cf06612cSMauro Carvalho Chehab propagation from mount 'B'. A new propagation tree is created in the 505cf06612cSMauro Carvalho Chehab exact same configuration as that of 'B'. This new propagation tree 506cf06612cSMauro Carvalho Chehab contains all the new mounts 'A1', 'A2'... 'An'. And this new 507cf06612cSMauro Carvalho Chehab propagation tree is appended to the already existing propagation tree 508cf06612cSMauro Carvalho Chehab of 'A'. 509cf06612cSMauro Carvalho Chehab 510cf06612cSMauro Carvalho Chehab 2. 'A' is a private mount and 'B' is a shared mount. The mount 'A' is 511cf06612cSMauro Carvalho Chehab mounted on mount 'B' at dentry 'b'. Also new mount 'A1', 'A2'... 'An' 512cf06612cSMauro Carvalho Chehab are created and mounted at dentry 'b' on all mounts that receive 513cf06612cSMauro Carvalho Chehab propagation from mount 'B'. The mount 'A' becomes a shared mount and a 514cf06612cSMauro Carvalho Chehab propagation tree is created which is identical to that of 515cf06612cSMauro Carvalho Chehab 'B'. This new propagation tree contains all the new mounts 'A1', 516cf06612cSMauro Carvalho Chehab 'A2'... 'An'. 517cf06612cSMauro Carvalho Chehab 518cf06612cSMauro Carvalho Chehab 3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. The 519cf06612cSMauro Carvalho Chehab mount 'A' is mounted on mount 'B' at dentry 'b'. Also new mounts 'A1', 520cf06612cSMauro Carvalho Chehab 'A2'... 'An' are created and mounted at dentry 'b' on all mounts that 521cf06612cSMauro Carvalho Chehab receive propagation from mount 'B'. A new propagation tree is created 522cf06612cSMauro Carvalho Chehab in the exact same configuration as that of 'B'. This new propagation 523cf06612cSMauro Carvalho Chehab tree contains all the new mounts 'A1', 'A2'... 'An'. And this new 524cf06612cSMauro Carvalho Chehab propagation tree is appended to the already existing propagation tree of 525cf06612cSMauro Carvalho Chehab 'A'. Mount 'A' continues to be the slave mount of 'Z' but it also 526cf06612cSMauro Carvalho Chehab becomes 'shared'. 527cf06612cSMauro Carvalho Chehab 528cf06612cSMauro Carvalho Chehab 4. 'A' is a unbindable mount and 'B' is a shared mount. The operation 529cf06612cSMauro Carvalho Chehab is invalid. Because mounting anything on the shared mount 'B' can 530cf06612cSMauro Carvalho Chehab create new mounts that get mounted on the mounts that receive 531cf06612cSMauro Carvalho Chehab propagation from 'B'. And since the mount 'A' is unbindable, cloning 532cf06612cSMauro Carvalho Chehab it to mount at other mountpoints is not possible. 533cf06612cSMauro Carvalho Chehab 534cf06612cSMauro Carvalho Chehab 5. 'A' is a private mount and 'B' is a non-shared(private or slave or 535cf06612cSMauro Carvalho Chehab unbindable) mount. The mount 'A' is mounted on mount 'B' at dentry 'b'. 536cf06612cSMauro Carvalho Chehab 537cf06612cSMauro Carvalho Chehab 6. 'A' is a shared mount and 'B' is a non-shared mount. The mount 'A' 538cf06612cSMauro Carvalho Chehab is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a 539cf06612cSMauro Carvalho Chehab shared mount. 540cf06612cSMauro Carvalho Chehab 541cf06612cSMauro Carvalho Chehab 7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount. 542cf06612cSMauro Carvalho Chehab The mount 'A' is mounted on mount 'B' at dentry 'b'. Mount 'A' 543cf06612cSMauro Carvalho Chehab continues to be a slave mount of mount 'Z'. 544cf06612cSMauro Carvalho Chehab 545cf06612cSMauro Carvalho Chehab 8. 'A' is a unbindable mount and 'B' is a non-shared mount. The mount 546cf06612cSMauro Carvalho Chehab 'A' is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a 547cf06612cSMauro Carvalho Chehab unbindable mount. 548cf06612cSMauro Carvalho Chehab 549cf06612cSMauro Carvalho Chehab5e) Mount semantics 550cf06612cSMauro Carvalho Chehab 551cf06612cSMauro Carvalho Chehab Consider the following command:: 552cf06612cSMauro Carvalho Chehab 553cf06612cSMauro Carvalho Chehab mount device B/b 554cf06612cSMauro Carvalho Chehab 555cf06612cSMauro Carvalho Chehab 'B' is the destination mount and 'b' is the dentry in the destination 556cf06612cSMauro Carvalho Chehab mount. 557cf06612cSMauro Carvalho Chehab 558cf06612cSMauro Carvalho Chehab The above operation is the same as bind operation with the exception 559cf06612cSMauro Carvalho Chehab that the source mount is always a private mount. 560cf06612cSMauro Carvalho Chehab 561cf06612cSMauro Carvalho Chehab 562cf06612cSMauro Carvalho Chehab5f) Unmount semantics 563cf06612cSMauro Carvalho Chehab 564cf06612cSMauro Carvalho Chehab Consider the following command:: 565cf06612cSMauro Carvalho Chehab 566cf06612cSMauro Carvalho Chehab umount A 567cf06612cSMauro Carvalho Chehab 568cf06612cSMauro Carvalho Chehab where 'A' is a mount mounted on mount 'B' at dentry 'b'. 569cf06612cSMauro Carvalho Chehab 570cf06612cSMauro Carvalho Chehab If mount 'B' is shared, then all most-recently-mounted mounts at dentry 571cf06612cSMauro Carvalho Chehab 'b' on mounts that receive propagation from mount 'B' and does not have 572cf06612cSMauro Carvalho Chehab sub-mounts within them are unmounted. 573cf06612cSMauro Carvalho Chehab 574cf06612cSMauro Carvalho Chehab Example: Let's say 'B1', 'B2', 'B3' are shared mounts that propagate to 575cf06612cSMauro Carvalho Chehab each other. 576cf06612cSMauro Carvalho Chehab 577cf06612cSMauro Carvalho Chehab let's say 'A1', 'A2', 'A3' are first mounted at dentry 'b' on mount 578cf06612cSMauro Carvalho Chehab 'B1', 'B2' and 'B3' respectively. 579cf06612cSMauro Carvalho Chehab 580cf06612cSMauro Carvalho Chehab let's say 'C1', 'C2', 'C3' are next mounted at the same dentry 'b' on 581cf06612cSMauro Carvalho Chehab mount 'B1', 'B2' and 'B3' respectively. 582cf06612cSMauro Carvalho Chehab 583cf06612cSMauro Carvalho Chehab if 'C1' is unmounted, all the mounts that are most-recently-mounted on 584cf06612cSMauro Carvalho Chehab 'B1' and on the mounts that 'B1' propagates-to are unmounted. 585cf06612cSMauro Carvalho Chehab 586cf06612cSMauro Carvalho Chehab 'B1' propagates to 'B2' and 'B3'. And the most recently mounted mount 587cf06612cSMauro Carvalho Chehab on 'B2' at dentry 'b' is 'C2', and that of mount 'B3' is 'C3'. 588cf06612cSMauro Carvalho Chehab 589cf06612cSMauro Carvalho Chehab So all 'C1', 'C2' and 'C3' should be unmounted. 590cf06612cSMauro Carvalho Chehab 591cf06612cSMauro Carvalho Chehab If any of 'C2' or 'C3' has some child mounts, then that mount is not 592cf06612cSMauro Carvalho Chehab unmounted, but all other mounts are unmounted. However if 'C1' is told 593cf06612cSMauro Carvalho Chehab to be unmounted and 'C1' has some sub-mounts, the umount operation is 594cf06612cSMauro Carvalho Chehab failed entirely. 595cf06612cSMauro Carvalho Chehab 596cf06612cSMauro Carvalho Chehab5g) Clone Namespace 597cf06612cSMauro Carvalho Chehab 598cf06612cSMauro Carvalho Chehab A cloned namespace contains all the mounts as that of the parent 599cf06612cSMauro Carvalho Chehab namespace. 600cf06612cSMauro Carvalho Chehab 601cf06612cSMauro Carvalho Chehab Let's say 'A' and 'B' are the corresponding mounts in the parent and the 602cf06612cSMauro Carvalho Chehab child namespace. 603cf06612cSMauro Carvalho Chehab 604cf06612cSMauro Carvalho Chehab If 'A' is shared, then 'B' is also shared and 'A' and 'B' propagate to 605cf06612cSMauro Carvalho Chehab each other. 606cf06612cSMauro Carvalho Chehab 607cf06612cSMauro Carvalho Chehab If 'A' is a slave mount of 'Z', then 'B' is also the slave mount of 608cf06612cSMauro Carvalho Chehab 'Z'. 609cf06612cSMauro Carvalho Chehab 610cf06612cSMauro Carvalho Chehab If 'A' is a private mount, then 'B' is a private mount too. 611cf06612cSMauro Carvalho Chehab 612cf06612cSMauro Carvalho Chehab If 'A' is unbindable mount, then 'B' is a unbindable mount too. 613cf06612cSMauro Carvalho Chehab 614cf06612cSMauro Carvalho Chehab 615cf06612cSMauro Carvalho Chehab6) Quiz 616*7b38ecfdSRandy Dunlap------- 617cf06612cSMauro Carvalho Chehab 618cf06612cSMauro Carvalho Chehab A. What is the result of the following command sequence? 619cf06612cSMauro Carvalho Chehab 620cf06612cSMauro Carvalho Chehab :: 621cf06612cSMauro Carvalho Chehab 622cf06612cSMauro Carvalho Chehab mount --bind /mnt /mnt 623cf06612cSMauro Carvalho Chehab mount --make-shared /mnt 624cf06612cSMauro Carvalho Chehab mount --bind /mnt /tmp 625cf06612cSMauro Carvalho Chehab mount --move /tmp /mnt/1 626cf06612cSMauro Carvalho Chehab 627cf06612cSMauro Carvalho Chehab what should be the contents of /mnt /mnt/1 /mnt/1/1 should be? 628cf06612cSMauro Carvalho Chehab Should they all be identical? or should /mnt and /mnt/1 be 629cf06612cSMauro Carvalho Chehab identical only? 630cf06612cSMauro Carvalho Chehab 631cf06612cSMauro Carvalho Chehab 632cf06612cSMauro Carvalho Chehab B. What is the result of the following command sequence? 633cf06612cSMauro Carvalho Chehab 634cf06612cSMauro Carvalho Chehab :: 635cf06612cSMauro Carvalho Chehab 636cf06612cSMauro Carvalho Chehab mount --make-rshared / 637cf06612cSMauro Carvalho Chehab mkdir -p /v/1 638cf06612cSMauro Carvalho Chehab mount --rbind / /v/1 639cf06612cSMauro Carvalho Chehab 640cf06612cSMauro Carvalho Chehab what should be the content of /v/1/v/1 be? 641cf06612cSMauro Carvalho Chehab 642cf06612cSMauro Carvalho Chehab 643cf06612cSMauro Carvalho Chehab C. What is the result of the following command sequence? 644cf06612cSMauro Carvalho Chehab 645cf06612cSMauro Carvalho Chehab :: 646cf06612cSMauro Carvalho Chehab 647cf06612cSMauro Carvalho Chehab mount --bind /mnt /mnt 648cf06612cSMauro Carvalho Chehab mount --make-shared /mnt 649cf06612cSMauro Carvalho Chehab mkdir -p /mnt/1/2/3 /mnt/1/test 650cf06612cSMauro Carvalho Chehab mount --bind /mnt/1 /tmp 651cf06612cSMauro Carvalho Chehab mount --make-slave /mnt 652cf06612cSMauro Carvalho Chehab mount --make-shared /mnt 653cf06612cSMauro Carvalho Chehab mount --bind /mnt/1/2 /tmp1 654cf06612cSMauro Carvalho Chehab mount --make-slave /mnt 655cf06612cSMauro Carvalho Chehab 656cf06612cSMauro Carvalho Chehab At this point we have the first mount at /tmp and 657cf06612cSMauro Carvalho Chehab its root dentry is 1. Let's call this mount 'A' 658cf06612cSMauro Carvalho Chehab And then we have a second mount at /tmp1 with root 659cf06612cSMauro Carvalho Chehab dentry 2. Let's call this mount 'B' 660cf06612cSMauro Carvalho Chehab Next we have a third mount at /mnt with root dentry 661cf06612cSMauro Carvalho Chehab mnt. Let's call this mount 'C' 662cf06612cSMauro Carvalho Chehab 663cf06612cSMauro Carvalho Chehab 'B' is the slave of 'A' and 'C' is a slave of 'B' 664cf06612cSMauro Carvalho Chehab A -> B -> C 665cf06612cSMauro Carvalho Chehab 666cf06612cSMauro Carvalho Chehab at this point if we execute the following command 667cf06612cSMauro Carvalho Chehab 668cf06612cSMauro Carvalho Chehab mount --bind /bin /tmp/test 669cf06612cSMauro Carvalho Chehab 670cf06612cSMauro Carvalho Chehab The mount is attempted on 'A' 671cf06612cSMauro Carvalho Chehab 672cf06612cSMauro Carvalho Chehab will the mount propagate to 'B' and 'C' ? 673cf06612cSMauro Carvalho Chehab 674cf06612cSMauro Carvalho Chehab what would be the contents of 675cf06612cSMauro Carvalho Chehab /mnt/1/test be? 676cf06612cSMauro Carvalho Chehab 677cf06612cSMauro Carvalho Chehab7) FAQ 678*7b38ecfdSRandy Dunlap------ 679cf06612cSMauro Carvalho Chehab 680cf06612cSMauro Carvalho Chehab Q1. Why is bind mount needed? How is it different from symbolic links? 681cf06612cSMauro Carvalho Chehab symbolic links can get stale if the destination mount gets 682cf06612cSMauro Carvalho Chehab unmounted or moved. Bind mounts continue to exist even if the 683cf06612cSMauro Carvalho Chehab other mount is unmounted or moved. 684cf06612cSMauro Carvalho Chehab 685cf06612cSMauro Carvalho Chehab Q2. Why can't the shared subtree be implemented using exportfs? 686cf06612cSMauro Carvalho Chehab 687cf06612cSMauro Carvalho Chehab exportfs is a heavyweight way of accomplishing part of what 688cf06612cSMauro Carvalho Chehab shared subtree can do. I cannot imagine a way to implement the 689cf06612cSMauro Carvalho Chehab semantics of slave mount using exportfs? 690cf06612cSMauro Carvalho Chehab 691cf06612cSMauro Carvalho Chehab Q3 Why is unbindable mount needed? 692cf06612cSMauro Carvalho Chehab 693cf06612cSMauro Carvalho Chehab Let's say we want to replicate the mount tree at multiple 694cf06612cSMauro Carvalho Chehab locations within the same subtree. 695cf06612cSMauro Carvalho Chehab 696cf06612cSMauro Carvalho Chehab if one rbind mounts a tree within the same subtree 'n' times 697cf06612cSMauro Carvalho Chehab the number of mounts created is an exponential function of 'n'. 698cf06612cSMauro Carvalho Chehab Having unbindable mount can help prune the unneeded bind 699cf06612cSMauro Carvalho Chehab mounts. Here is an example. 700cf06612cSMauro Carvalho Chehab 701cf06612cSMauro Carvalho Chehab step 1: 702cf06612cSMauro Carvalho Chehab let's say the root tree has just two directories with 703cf06612cSMauro Carvalho Chehab one vfsmount:: 704cf06612cSMauro Carvalho Chehab 705cf06612cSMauro Carvalho Chehab root 706cf06612cSMauro Carvalho Chehab / \ 707cf06612cSMauro Carvalho Chehab tmp usr 708cf06612cSMauro Carvalho Chehab 709cf06612cSMauro Carvalho Chehab And we want to replicate the tree at multiple 710cf06612cSMauro Carvalho Chehab mountpoints under /root/tmp 711cf06612cSMauro Carvalho Chehab 712cf06612cSMauro Carvalho Chehab step 2: 713cf06612cSMauro Carvalho Chehab :: 714cf06612cSMauro Carvalho Chehab 715cf06612cSMauro Carvalho Chehab 716cf06612cSMauro Carvalho Chehab mount --make-shared /root 717cf06612cSMauro Carvalho Chehab 718cf06612cSMauro Carvalho Chehab mkdir -p /tmp/m1 719cf06612cSMauro Carvalho Chehab 720cf06612cSMauro Carvalho Chehab mount --rbind /root /tmp/m1 721cf06612cSMauro Carvalho Chehab 722cf06612cSMauro Carvalho Chehab the new tree now looks like this:: 723cf06612cSMauro Carvalho Chehab 724cf06612cSMauro Carvalho Chehab root 725cf06612cSMauro Carvalho Chehab / \ 726cf06612cSMauro Carvalho Chehab tmp usr 727cf06612cSMauro Carvalho Chehab / 728cf06612cSMauro Carvalho Chehab m1 729cf06612cSMauro Carvalho Chehab / \ 730cf06612cSMauro Carvalho Chehab tmp usr 731cf06612cSMauro Carvalho Chehab / 732cf06612cSMauro Carvalho Chehab m1 733cf06612cSMauro Carvalho Chehab 734cf06612cSMauro Carvalho Chehab it has two vfsmounts 735cf06612cSMauro Carvalho Chehab 736cf06612cSMauro Carvalho Chehab step 3: 737cf06612cSMauro Carvalho Chehab :: 738cf06612cSMauro Carvalho Chehab 739cf06612cSMauro Carvalho Chehab mkdir -p /tmp/m2 740cf06612cSMauro Carvalho Chehab mount --rbind /root /tmp/m2 741cf06612cSMauro Carvalho Chehab 742cf06612cSMauro Carvalho Chehab the new tree now looks like this:: 743cf06612cSMauro Carvalho Chehab 744cf06612cSMauro Carvalho Chehab root 745cf06612cSMauro Carvalho Chehab / \ 746cf06612cSMauro Carvalho Chehab tmp usr 747cf06612cSMauro Carvalho Chehab / \ 748cf06612cSMauro Carvalho Chehab m1 m2 749cf06612cSMauro Carvalho Chehab / \ / \ 750cf06612cSMauro Carvalho Chehab tmp usr tmp usr 751cf06612cSMauro Carvalho Chehab / \ / 752cf06612cSMauro Carvalho Chehab m1 m2 m1 753cf06612cSMauro Carvalho Chehab / \ / \ 754cf06612cSMauro Carvalho Chehab tmp usr tmp usr 755cf06612cSMauro Carvalho Chehab / / \ 756cf06612cSMauro Carvalho Chehab m1 m1 m2 757cf06612cSMauro Carvalho Chehab / \ 758cf06612cSMauro Carvalho Chehab tmp usr 759cf06612cSMauro Carvalho Chehab / \ 760cf06612cSMauro Carvalho Chehab m1 m2 761cf06612cSMauro Carvalho Chehab 762cf06612cSMauro Carvalho Chehab it has 6 vfsmounts 763cf06612cSMauro Carvalho Chehab 764cf06612cSMauro Carvalho Chehab step 4: 765cf06612cSMauro Carvalho Chehab :: 766cf06612cSMauro Carvalho Chehab mkdir -p /tmp/m3 767cf06612cSMauro Carvalho Chehab mount --rbind /root /tmp/m3 768cf06612cSMauro Carvalho Chehab 769cf06612cSMauro Carvalho Chehab I won't draw the tree..but it has 24 vfsmounts 770cf06612cSMauro Carvalho Chehab 771cf06612cSMauro Carvalho Chehab 772cf06612cSMauro Carvalho Chehab at step i the number of vfsmounts is V[i] = i*V[i-1]. 773cf06612cSMauro Carvalho Chehab This is an exponential function. And this tree has way more 774cf06612cSMauro Carvalho Chehab mounts than what we really needed in the first place. 775cf06612cSMauro Carvalho Chehab 776cf06612cSMauro Carvalho Chehab One could use a series of umount at each step to prune 777cf06612cSMauro Carvalho Chehab out the unneeded mounts. But there is a better solution. 778cf06612cSMauro Carvalho Chehab Unclonable mounts come in handy here. 779cf06612cSMauro Carvalho Chehab 780cf06612cSMauro Carvalho Chehab step 1: 781cf06612cSMauro Carvalho Chehab let's say the root tree has just two directories with 782cf06612cSMauro Carvalho Chehab one vfsmount:: 783cf06612cSMauro Carvalho Chehab 784cf06612cSMauro Carvalho Chehab root 785cf06612cSMauro Carvalho Chehab / \ 786cf06612cSMauro Carvalho Chehab tmp usr 787cf06612cSMauro Carvalho Chehab 788cf06612cSMauro Carvalho Chehab How do we set up the same tree at multiple locations under 789cf06612cSMauro Carvalho Chehab /root/tmp 790cf06612cSMauro Carvalho Chehab 791cf06612cSMauro Carvalho Chehab step 2: 792cf06612cSMauro Carvalho Chehab :: 793cf06612cSMauro Carvalho Chehab 794cf06612cSMauro Carvalho Chehab 795cf06612cSMauro Carvalho Chehab mount --bind /root/tmp /root/tmp 796cf06612cSMauro Carvalho Chehab 797cf06612cSMauro Carvalho Chehab mount --make-rshared /root 798cf06612cSMauro Carvalho Chehab mount --make-unbindable /root/tmp 799cf06612cSMauro Carvalho Chehab 800cf06612cSMauro Carvalho Chehab mkdir -p /tmp/m1 801cf06612cSMauro Carvalho Chehab 802cf06612cSMauro Carvalho Chehab mount --rbind /root /tmp/m1 803cf06612cSMauro Carvalho Chehab 804cf06612cSMauro Carvalho Chehab the new tree now looks like this:: 805cf06612cSMauro Carvalho Chehab 806cf06612cSMauro Carvalho Chehab root 807cf06612cSMauro Carvalho Chehab / \ 808cf06612cSMauro Carvalho Chehab tmp usr 809cf06612cSMauro Carvalho Chehab / 810cf06612cSMauro Carvalho Chehab m1 811cf06612cSMauro Carvalho Chehab / \ 812cf06612cSMauro Carvalho Chehab tmp usr 813cf06612cSMauro Carvalho Chehab 814cf06612cSMauro Carvalho Chehab step 3: 815cf06612cSMauro Carvalho Chehab :: 816cf06612cSMauro Carvalho Chehab 817cf06612cSMauro Carvalho Chehab mkdir -p /tmp/m2 818cf06612cSMauro Carvalho Chehab mount --rbind /root /tmp/m2 819cf06612cSMauro Carvalho Chehab 820cf06612cSMauro Carvalho Chehab the new tree now looks like this:: 821cf06612cSMauro Carvalho Chehab 822cf06612cSMauro Carvalho Chehab root 823cf06612cSMauro Carvalho Chehab / \ 824cf06612cSMauro Carvalho Chehab tmp usr 825cf06612cSMauro Carvalho Chehab / \ 826cf06612cSMauro Carvalho Chehab m1 m2 827cf06612cSMauro Carvalho Chehab / \ / \ 828cf06612cSMauro Carvalho Chehab tmp usr tmp usr 829cf06612cSMauro Carvalho Chehab 830cf06612cSMauro Carvalho Chehab step 4: 831cf06612cSMauro Carvalho Chehab :: 832cf06612cSMauro Carvalho Chehab 833cf06612cSMauro Carvalho Chehab mkdir -p /tmp/m3 834cf06612cSMauro Carvalho Chehab mount --rbind /root /tmp/m3 835cf06612cSMauro Carvalho Chehab 836cf06612cSMauro Carvalho Chehab the new tree now looks like this:: 837cf06612cSMauro Carvalho Chehab 838cf06612cSMauro Carvalho Chehab root 839cf06612cSMauro Carvalho Chehab / \ 840cf06612cSMauro Carvalho Chehab tmp usr 841cf06612cSMauro Carvalho Chehab / \ \ 842cf06612cSMauro Carvalho Chehab m1 m2 m3 843cf06612cSMauro Carvalho Chehab / \ / \ / \ 844cf06612cSMauro Carvalho Chehab tmp usr tmp usr tmp usr 845cf06612cSMauro Carvalho Chehab 846cf06612cSMauro Carvalho Chehab8) Implementation 847*7b38ecfdSRandy Dunlap----------------- 848cf06612cSMauro Carvalho Chehab 849cf06612cSMauro Carvalho Chehab8A) Datastructure 850cf06612cSMauro Carvalho Chehab 851cf06612cSMauro Carvalho Chehab 4 new fields are introduced to struct vfsmount: 852cf06612cSMauro Carvalho Chehab 853cf06612cSMauro Carvalho Chehab * ->mnt_share 854cf06612cSMauro Carvalho Chehab * ->mnt_slave_list 855cf06612cSMauro Carvalho Chehab * ->mnt_slave 856cf06612cSMauro Carvalho Chehab * ->mnt_master 857cf06612cSMauro Carvalho Chehab 858cf06612cSMauro Carvalho Chehab ->mnt_share 859cf06612cSMauro Carvalho Chehab links together all the mount to/from which this vfsmount 860cf06612cSMauro Carvalho Chehab send/receives propagation events. 861cf06612cSMauro Carvalho Chehab 862cf06612cSMauro Carvalho Chehab ->mnt_slave_list 863cf06612cSMauro Carvalho Chehab links all the mounts to which this vfsmount propagates 864cf06612cSMauro Carvalho Chehab to. 865cf06612cSMauro Carvalho Chehab 866cf06612cSMauro Carvalho Chehab ->mnt_slave 867cf06612cSMauro Carvalho Chehab links together all the slaves that its master vfsmount 868cf06612cSMauro Carvalho Chehab propagates to. 869cf06612cSMauro Carvalho Chehab 870cf06612cSMauro Carvalho Chehab ->mnt_master 871cf06612cSMauro Carvalho Chehab points to the master vfsmount from which this vfsmount 872cf06612cSMauro Carvalho Chehab receives propagation. 873cf06612cSMauro Carvalho Chehab 874cf06612cSMauro Carvalho Chehab ->mnt_flags 875cf06612cSMauro Carvalho Chehab takes two more flags to indicate the propagation status of 876cf06612cSMauro Carvalho Chehab the vfsmount. MNT_SHARE indicates that the vfsmount is a shared 877cf06612cSMauro Carvalho Chehab vfsmount. MNT_UNCLONABLE indicates that the vfsmount cannot be 878cf06612cSMauro Carvalho Chehab replicated. 879cf06612cSMauro Carvalho Chehab 880cf06612cSMauro Carvalho Chehab All the shared vfsmounts in a peer group form a cyclic list through 881cf06612cSMauro Carvalho Chehab ->mnt_share. 882cf06612cSMauro Carvalho Chehab 883cf06612cSMauro Carvalho Chehab All vfsmounts with the same ->mnt_master form on a cyclic list anchored 884cf06612cSMauro Carvalho Chehab in ->mnt_master->mnt_slave_list and going through ->mnt_slave. 885cf06612cSMauro Carvalho Chehab 886cf06612cSMauro Carvalho Chehab ->mnt_master can point to arbitrary (and possibly different) members 887cf06612cSMauro Carvalho Chehab of master peer group. To find all immediate slaves of a peer group 888cf06612cSMauro Carvalho Chehab you need to go through _all_ ->mnt_slave_list of its members. 889cf06612cSMauro Carvalho Chehab Conceptually it's just a single set - distribution among the 890cf06612cSMauro Carvalho Chehab individual lists does not affect propagation or the way propagation 891cf06612cSMauro Carvalho Chehab tree is modified by operations. 892cf06612cSMauro Carvalho Chehab 893cf06612cSMauro Carvalho Chehab All vfsmounts in a peer group have the same ->mnt_master. If it is 894cf06612cSMauro Carvalho Chehab non-NULL, they form a contiguous (ordered) segment of slave list. 895cf06612cSMauro Carvalho Chehab 896cf06612cSMauro Carvalho Chehab A example propagation tree looks as shown in the figure below. 897cf06612cSMauro Carvalho Chehab [ NOTE: Though it looks like a forest, if we consider all the shared 898cf06612cSMauro Carvalho Chehab mounts as a conceptual entity called 'pnode', it becomes a tree]:: 899cf06612cSMauro Carvalho Chehab 900cf06612cSMauro Carvalho Chehab 901cf06612cSMauro Carvalho Chehab A <--> B <--> C <---> D 902cf06612cSMauro Carvalho Chehab /|\ /| |\ 903cf06612cSMauro Carvalho Chehab / F G J K H I 904cf06612cSMauro Carvalho Chehab / 905cf06612cSMauro Carvalho Chehab E<-->K 906cf06612cSMauro Carvalho Chehab /|\ 907cf06612cSMauro Carvalho Chehab M L N 908cf06612cSMauro Carvalho Chehab 909cf06612cSMauro Carvalho Chehab In the above figure A,B,C and D all are shared and propagate to each 910cf06612cSMauro Carvalho Chehab other. 'A' has got 3 slave mounts 'E' 'F' and 'G' 'C' has got 2 slave 911cf06612cSMauro Carvalho Chehab mounts 'J' and 'K' and 'D' has got two slave mounts 'H' and 'I'. 912cf06612cSMauro Carvalho Chehab 'E' is also shared with 'K' and they propagate to each other. And 913cf06612cSMauro Carvalho Chehab 'K' has 3 slaves 'M', 'L' and 'N' 914cf06612cSMauro Carvalho Chehab 915cf06612cSMauro Carvalho Chehab A's ->mnt_share links with the ->mnt_share of 'B' 'C' and 'D' 916cf06612cSMauro Carvalho Chehab 917cf06612cSMauro Carvalho Chehab A's ->mnt_slave_list links with ->mnt_slave of 'E', 'K', 'F' and 'G' 918cf06612cSMauro Carvalho Chehab 919cf06612cSMauro Carvalho Chehab E's ->mnt_share links with ->mnt_share of K 920cf06612cSMauro Carvalho Chehab 921cf06612cSMauro Carvalho Chehab 'E', 'K', 'F', 'G' have their ->mnt_master point to struct vfsmount of 'A' 922cf06612cSMauro Carvalho Chehab 923cf06612cSMauro Carvalho Chehab 'M', 'L', 'N' have their ->mnt_master point to struct vfsmount of 'K' 924cf06612cSMauro Carvalho Chehab 925cf06612cSMauro Carvalho Chehab K's ->mnt_slave_list links with ->mnt_slave of 'M', 'L' and 'N' 926cf06612cSMauro Carvalho Chehab 927cf06612cSMauro Carvalho Chehab C's ->mnt_slave_list links with ->mnt_slave of 'J' and 'K' 928cf06612cSMauro Carvalho Chehab 929cf06612cSMauro Carvalho Chehab J and K's ->mnt_master points to struct vfsmount of C 930cf06612cSMauro Carvalho Chehab 931cf06612cSMauro Carvalho Chehab and finally D's ->mnt_slave_list links with ->mnt_slave of 'H' and 'I' 932cf06612cSMauro Carvalho Chehab 933cf06612cSMauro Carvalho Chehab 'H' and 'I' have their ->mnt_master pointing to struct vfsmount of 'D'. 934cf06612cSMauro Carvalho Chehab 935cf06612cSMauro Carvalho Chehab 936cf06612cSMauro Carvalho Chehab NOTE: The propagation tree is orthogonal to the mount tree. 937cf06612cSMauro Carvalho Chehab 938cf06612cSMauro Carvalho Chehab8B Locking: 939cf06612cSMauro Carvalho Chehab 940cf06612cSMauro Carvalho Chehab ->mnt_share, ->mnt_slave, ->mnt_slave_list, ->mnt_master are protected 941cf06612cSMauro Carvalho Chehab by namespace_sem (exclusive for modifications, shared for reading). 942cf06612cSMauro Carvalho Chehab 943cf06612cSMauro Carvalho Chehab Normally we have ->mnt_flags modifications serialized by vfsmount_lock. 944cf06612cSMauro Carvalho Chehab There are two exceptions: do_add_mount() and clone_mnt(). 945cf06612cSMauro Carvalho Chehab The former modifies a vfsmount that has not been visible in any shared 946cf06612cSMauro Carvalho Chehab data structures yet. 947cf06612cSMauro Carvalho Chehab The latter holds namespace_sem and the only references to vfsmount 948cf06612cSMauro Carvalho Chehab are in lists that can't be traversed without namespace_sem. 949cf06612cSMauro Carvalho Chehab 950cf06612cSMauro Carvalho Chehab8C Algorithm: 951cf06612cSMauro Carvalho Chehab 952cf06612cSMauro Carvalho Chehab The crux of the implementation resides in rbind/move operation. 953cf06612cSMauro Carvalho Chehab 954cf06612cSMauro Carvalho Chehab The overall algorithm breaks the operation into 3 phases: (look at 955cf06612cSMauro Carvalho Chehab attach_recursive_mnt() and propagate_mnt()) 956cf06612cSMauro Carvalho Chehab 957cf06612cSMauro Carvalho Chehab 1. prepare phase. 958cf06612cSMauro Carvalho Chehab 2. commit phases. 959cf06612cSMauro Carvalho Chehab 3. abort phases. 960cf06612cSMauro Carvalho Chehab 961cf06612cSMauro Carvalho Chehab Prepare phase: 962cf06612cSMauro Carvalho Chehab 963cf06612cSMauro Carvalho Chehab for each mount in the source tree: 964cf06612cSMauro Carvalho Chehab 965cf06612cSMauro Carvalho Chehab a) Create the necessary number of mount trees to 966cf06612cSMauro Carvalho Chehab be attached to each of the mounts that receive 967cf06612cSMauro Carvalho Chehab propagation from the destination mount. 968cf06612cSMauro Carvalho Chehab b) Do not attach any of the trees to its destination. 969cf06612cSMauro Carvalho Chehab However note down its ->mnt_parent and ->mnt_mountpoint 970cf06612cSMauro Carvalho Chehab c) Link all the new mounts to form a propagation tree that 971cf06612cSMauro Carvalho Chehab is identical to the propagation tree of the destination 972cf06612cSMauro Carvalho Chehab mount. 973cf06612cSMauro Carvalho Chehab 974cf06612cSMauro Carvalho Chehab If this phase is successful, there should be 'n' new 975cf06612cSMauro Carvalho Chehab propagation trees; where 'n' is the number of mounts in the 976cf06612cSMauro Carvalho Chehab source tree. Go to the commit phase 977cf06612cSMauro Carvalho Chehab 978cf06612cSMauro Carvalho Chehab Also there should be 'm' new mount trees, where 'm' is 979cf06612cSMauro Carvalho Chehab the number of mounts to which the destination mount 980cf06612cSMauro Carvalho Chehab propagates to. 981cf06612cSMauro Carvalho Chehab 982cf06612cSMauro Carvalho Chehab if any memory allocations fail, go to the abort phase. 983cf06612cSMauro Carvalho Chehab 984cf06612cSMauro Carvalho Chehab Commit phase 985cf06612cSMauro Carvalho Chehab attach each of the mount trees to their corresponding 986cf06612cSMauro Carvalho Chehab destination mounts. 987cf06612cSMauro Carvalho Chehab 988cf06612cSMauro Carvalho Chehab Abort phase 989cf06612cSMauro Carvalho Chehab delete all the newly created trees. 990cf06612cSMauro Carvalho Chehab 991cf06612cSMauro Carvalho Chehab .. Note:: 992cf06612cSMauro Carvalho Chehab all the propagation related functionality resides in the file pnode.c 993cf06612cSMauro Carvalho Chehab 994cf06612cSMauro Carvalho Chehab 995cf06612cSMauro Carvalho Chehab------------------------------------------------------------------------ 996cf06612cSMauro Carvalho Chehab 997cf06612cSMauro Carvalho Chehabversion 0.1 (created the initial document, Ram Pai linuxram@us.ibm.com) 998cf06612cSMauro Carvalho Chehab 999cf06612cSMauro Carvalho Chehabversion 0.2 (Incorporated comments from Al Viro) 1000