deal with resource allocation bugs in arcmsr
[pv_ops_mirror.git] / Documentation / sharedsubtree.txt
blob736540045dc7b7c9e448fb90bd72fc63346e082d
1 Shared Subtrees
2 ---------------
4 Contents:
5         1) Overview
6         2) Features
7         3) smount command
8         4) Use-case
9         5) Detailed semantics
10         6) Quiz
11         7) FAQ
12         8) Implementation
15 1) Overview
16 -----------
18 Consider the following situation:
20 A process wants to clone its own namespace, but still wants to access the CD
21 that got mounted recently.  Shared subtree semantics provide the necessary
22 mechanism to accomplish the above.
24 It provides the necessary building blocks for features like per-user-namespace
25 and versioned filesystem.
27 2) Features
28 -----------
30 Shared subtree provides four different flavors of mounts; struct vfsmount to be
31 precise
33         a. shared mount
34         b. slave mount
35         c. private mount
36         d. unbindable mount
39 2a) A shared mount can be replicated to as many mountpoints and all the
40 replicas continue to be exactly same.
42         Here is an example:
44         Lets say /mnt has a mount that is shared.
45         mount --make-shared /mnt
47         note: mount command does not yet support the --make-shared flag.
48         I have included a small C program which does the same by executing
49         'smount /mnt shared'
51         #mount --bind /mnt /tmp
52         The above command replicates the mount at /mnt to the mountpoint /tmp
53         and the contents of both the mounts remain identical.
55         #ls /mnt
56         a b c
58         #ls /tmp
59         a b c
61         Now lets say we mount a device at /tmp/a
62         #mount /dev/sd0  /tmp/a
64         #ls /tmp/a
65         t1 t2 t2
67         #ls /mnt/a
68         t1 t2 t2
70         Note that the mount has propagated to the mount at /mnt as well.
72         And the same is true even when /dev/sd0 is mounted on /mnt/a. The
73         contents will be visible under /tmp/a too.
76 2b) A slave mount is like a shared mount except that mount and umount events
77         only propagate towards it.
79         All slave mounts have a master mount which is a shared.
81         Here is an example:
83         Lets say /mnt has a mount which is shared.
84         #mount --make-shared /mnt
86         Lets bind mount /mnt to /tmp
87         #mount --bind /mnt /tmp
89         the new mount at /tmp becomes a shared mount and it is a replica of
90         the mount at /mnt.
92         Now lets make the mount at /tmp; a slave of /mnt
93         #mount --make-slave /tmp
94         [or smount /tmp slave]
96         lets mount /dev/sd0 on /mnt/a
97         #mount /dev/sd0 /mnt/a
99         #ls /mnt/a
100         t1 t2 t3
102         #ls /tmp/a
103         t1 t2 t3
105         Note the mount event has propagated to the mount at /tmp
107         However lets see what happens if we mount something on the mount at /tmp
109         #mount /dev/sd1 /tmp/b
111         #ls /tmp/b
112         s1 s2 s3
114         #ls /mnt/b
116         Note how the mount event has not propagated to the mount at
117         /mnt
120 2c) A private mount does not forward or receive propagation.
122         This is the mount we are familiar with. Its the default type.
125 2d) A unbindable mount is a unbindable private mount
127         lets say we have a mount at /mnt and we make is unbindable
129         #mount --make-unbindable /mnt
130          [ smount /mnt  unbindable ]
132          Lets try to bind mount this mount somewhere else.
133          # mount --bind /mnt /tmp
134          mount: wrong fs type, bad option, bad superblock on /mnt,
135                 or too many mounted file systems
137         Binding a unbindable mount is a invalid operation.
140 3) smount command
142         Currently the mount command is not aware of shared subtree features.
143         Work is in progress to add the support in mount ( util-linux package ).
144         Till then use the following program.
146         ------------------------------------------------------------------------
147         //
148         //this code was developed my Miklos Szeredi <miklos@szeredi.hu>
149         //and modified by Ram Pai <linuxram@us.ibm.com>
150         // sample usage:
151         //              smount /tmp shared
152         //
153         #include <stdio.h>
154         #include <stdlib.h>
155         #include <unistd.h>
156         #include <string.h>
157         #include <sys/mount.h>
158         #include <sys/fsuid.h>
160         #ifndef MS_REC
161         #define MS_REC          0x4000  /* 16384: Recursive loopback */
162         #endif
164         #ifndef MS_SHARED
165         #define MS_SHARED               1<<20   /* Shared */
166         #endif
168         #ifndef MS_PRIVATE
169         #define MS_PRIVATE              1<<18   /* Private */
170         #endif
172         #ifndef MS_SLAVE
173         #define MS_SLAVE                1<<19   /* Slave */
174         #endif
176         #ifndef MS_UNBINDABLE
177         #define MS_UNBINDABLE           1<<17   /* Unbindable */
178         #endif
180         int main(int argc, char *argv[])
181         {
182                 int type;
183                 if(argc != 3) {
184                         fprintf(stderr, "usage: %s dir "
185                         "<rshared|rslave|rprivate|runbindable|shared|slave"
186                         "|private|unbindable>\n" , argv[0]);
187                         return 1;
188                 }
190                 fprintf(stdout, "%s %s %s\n", argv[0], argv[1], argv[2]);
192                 if (strcmp(argv[2],"rshared")==0)
193                         type=(MS_SHARED|MS_REC);
194                 else if (strcmp(argv[2],"rslave")==0)
195                         type=(MS_SLAVE|MS_REC);
196                 else if (strcmp(argv[2],"rprivate")==0)
197                         type=(MS_PRIVATE|MS_REC);
198                 else if (strcmp(argv[2],"runbindable")==0)
199                         type=(MS_UNBINDABLE|MS_REC);
200                 else if (strcmp(argv[2],"shared")==0)
201                         type=MS_SHARED;
202                 else if (strcmp(argv[2],"slave")==0)
203                         type=MS_SLAVE;
204                 else if (strcmp(argv[2],"private")==0)
205                         type=MS_PRIVATE;
206                 else if (strcmp(argv[2],"unbindable")==0)
207                         type=MS_UNBINDABLE;
208                 else {
209                         fprintf(stderr, "invalid operation: %s\n", argv[2]);
210                         return 1;
211                 }
212                 setfsuid(getuid());
214                 if(mount("", argv[1], "dontcare", type, "") == -1) {
215                         perror("mount");
216                         return 1;
217                 }
218                 return 0;
219         }
220         -----------------------------------------------------------------------
222         Copy the above code snippet into smount.c
223         gcc -o smount smount.c
226         (i) To mark all the mounts under /mnt as shared execute the following
227         command:
229                 smount /mnt rshared
230                 the corresponding syntax planned for mount command is
231                 mount --make-rshared /mnt
233             just to mark a mount /mnt as shared, execute the following
234             command:
235                 smount /mnt shared
236                 the corresponding syntax planned for mount command is
237                 mount --make-shared /mnt
239         (ii) To mark all the shared mounts under /mnt as slave execute the
240         following
242              command:
243                 smount /mnt rslave
244                 the corresponding syntax planned for mount command is
245                 mount --make-rslave /mnt
247             just to mark a mount /mnt as slave, execute the following
248             command:
249                 smount /mnt slave
250                 the corresponding syntax planned for mount command is
251                 mount --make-slave /mnt
253         (iii) To mark all the mounts under /mnt as private execute the
254         following command:
256                 smount /mnt rprivate
257                 the corresponding syntax planned for mount command is
258                 mount --make-rprivate /mnt
260             just to mark a mount /mnt as private, execute the following
261             command:
262                 smount /mnt private
263                 the corresponding syntax planned for mount command is
264                 mount --make-private /mnt
266               NOTE: by default all the mounts are created as private. But if
267               you want to change some shared/slave/unbindable  mount as
268               private at a later point in time, this command can help.
270         (iv) To mark all the mounts under /mnt as unbindable execute the
271         following
273              command:
274                 smount /mnt runbindable
275                 the corresponding syntax planned for mount command is
276                 mount --make-runbindable /mnt
278             just to mark a mount /mnt as unbindable, execute the following
279             command:
280                 smount /mnt unbindable
281                 the corresponding syntax planned for mount command is
282                 mount --make-unbindable /mnt
285 4) Use cases
286 ------------
288         A) A process wants to clone its own namespace, but still wants to
289            access the CD that got mounted recently.
291            Solution:
293                 The system administrator can make the mount at /cdrom shared
294                 mount --bind /cdrom /cdrom
295                 mount --make-shared /cdrom
297                 Now any process that clones off a new namespace will have a
298                 mount at /cdrom which is a replica of the same mount in the
299                 parent namespace.
301                 So when a CD is inserted and mounted at /cdrom that mount gets
302                 propagated to the other mount at /cdrom in all the other clone
303                 namespaces.
305         B) A process wants its mounts invisible to any other process, but
306         still be able to see the other system mounts.
308            Solution:
310                 To begin with, the administrator can mark the entire mount tree
311                 as shareable.
313                 mount --make-rshared /
315                 A new process can clone off a new namespace. And mark some part
316                 of its namespace as slave
318                 mount --make-rslave /myprivatetree
320                 Hence forth any mounts within the /myprivatetree done by the
321                 process will not show up in any other namespace. However mounts
322                 done in the parent namespace under /myprivatetree still shows
323                 up in the process's namespace.
326         Apart from the above semantics this feature provides the
327         building blocks to solve the following problems:
329         C)  Per-user namespace
331                 The above semantics allows a way to share mounts across
332                 namespaces.  But namespaces are associated with processes. If
333                 namespaces are made first class objects with user API to
334                 associate/disassociate a namespace with userid, then each user
335                 could have his/her own namespace and tailor it to his/her
336                 requirements. Offcourse its needs support from PAM.
338         D)  Versioned files
340                 If the entire mount tree is visible at multiple locations, then
341                 a underlying versioning file system can return different
342                 version of the file depending on the path used to access that
343                 file.
345                 An example is:
347                 mount --make-shared /
348                 mount --rbind / /view/v1
349                 mount --rbind / /view/v2
350                 mount --rbind / /view/v3
351                 mount --rbind / /view/v4
353                 and if /usr has a versioning filesystem mounted, than that
354                 mount appears at /view/v1/usr, /view/v2/usr, /view/v3/usr and
355                 /view/v4/usr too
357                 A user can request v3 version of the file /usr/fs/namespace.c
358                 by accessing /view/v3/usr/fs/namespace.c . The underlying
359                 versioning filesystem can then decipher that v3 version of the
360                 filesystem is being requested and return the corresponding
361                 inode.
363 5) Detailed semantics:
364 -------------------
365         The section below explains the detailed semantics of
366         bind, rbind, move, mount, umount and clone-namespace operations.
368         Note: the word 'vfsmount' and the noun 'mount' have been used
369         to mean the same thing, throughout this document.
371 5a) Mount states
373         A given mount can be in one of the following states
374         1) shared
375         2) slave
376         3) shared and slave
377         4) private
378         5) unbindable
380         A 'propagation event' is defined as event generated on a vfsmount
381         that leads to mount or unmount actions in other vfsmounts.
383         A 'peer group' is defined as a group of vfsmounts that propagate
384         events to each other.
386         (1) Shared mounts
388                 A 'shared mount' is defined as a vfsmount that belongs to a
389                 'peer group'.
391                 For example:
392                         mount --make-shared /mnt
393                         mount --bin /mnt /tmp
395                 The mount at /mnt and that at /tmp are both shared and belong
396                 to the same peer group. Anything mounted or unmounted under
397                 /mnt or /tmp reflect in all the other mounts of its peer
398                 group.
401         (2) Slave mounts
403                 A 'slave mount' is defined as a vfsmount that receives
404                 propagation events and does not forward propagation events.
406                 A slave mount as the name implies has a master mount from which
407                 mount/unmount events are received. Events do not propagate from
408                 the slave mount to the master.  Only a shared mount can be made
409                 a slave by executing the following command
411                         mount --make-slave mount
413                 A shared mount that is made as a slave is no more shared unless
414                 modified to become shared.
416         (3) Shared and Slave
418                 A vfsmount can be both shared as well as slave.  This state
419                 indicates that the mount is a slave of some vfsmount, and
420                 has its own peer group too.  This vfsmount receives propagation
421                 events from its master vfsmount, and also forwards propagation
422                 events to its 'peer group' and to its slave vfsmounts.
424                 Strictly speaking, the vfsmount is shared having its own
425                 peer group, and this peer-group is a slave of some other
426                 peer group.
428                 Only a slave vfsmount can be made as 'shared and slave' by
429                 either executing the following command
430                         mount --make-shared mount
431                 or by moving the slave vfsmount under a shared vfsmount.
433         (4) Private mount
435                 A 'private mount' is defined as vfsmount that does not
436                 receive or forward any propagation events.
438         (5) Unbindable mount
440                 A 'unbindable mount' is defined as vfsmount that does not
441                 receive or forward any propagation events and cannot
442                 be bind mounted.
445         State diagram:
446         The state diagram below explains the state transition of a mount,
447         in response to various commands.
448         ------------------------------------------------------------------------
449         |             |make-shared |  make-slave  | make-private |make-unbindab|
450         --------------|------------|--------------|--------------|-------------|
451         |shared       |shared      |*slave/private|   private    | unbindable  |
452         |             |            |              |              |             |
453         |-------------|------------|--------------|--------------|-------------|
454         |slave        |shared      |    **slave   |    private   | unbindable  |
455         |             |and slave   |              |              |             |
456         |-------------|------------|--------------|--------------|-------------|
457         |shared       |shared      |    slave     |    private   | unbindable  |
458         |and slave    |and slave   |              |              |             |
459         |-------------|------------|--------------|--------------|-------------|
460         |private      |shared      |  **private   |    private   | unbindable  |
461         |-------------|------------|--------------|--------------|-------------|
462         |unbindable   |shared      |**unbindable  |    private   | unbindable  |
463         ------------------------------------------------------------------------
465         * if the shared mount is the only mount in its peer group, making it
466         slave, makes it private automatically. Note that there is no master to
467         which it can be slaved to.
469         ** slaving a non-shared mount has no effect on the mount.
471         Apart from the commands listed below, the 'move' operation also changes
472         the state of a mount depending on type of the destination mount. Its
473         explained in section 5d.
475 5b) Bind semantics
477         Consider the following command
479         mount --bind A/a  B/b
481         where 'A' is the source mount, 'a' is the dentry in the mount 'A', 'B'
482         is the destination mount and 'b' is the dentry in the destination mount.
484         The outcome depends on the type of mount of 'A' and 'B'. The table
485         below contains quick reference.
486    ---------------------------------------------------------------------------
487    |         BIND MOUNT OPERATION                                            |
488    |**************************************************************************
489    |source(A)->| shared       |       private  |       slave    | unbindable |
490    | dest(B)  |               |                |                |            |
491    |   |      |               |                |                |            |
492    |   v      |               |                |                |            |
493    |**************************************************************************
494    |  shared  | shared        |     shared     | shared & slave |  invalid   |
495    |          |               |                |                |            |
496    |non-shared| shared        |      private   |      slave     |  invalid   |
497    ***************************************************************************
499         Details:
501         1. 'A' is a shared mount and 'B' is a shared mount. A new mount 'C'
502         which is clone of 'A', is created. Its root dentry is 'a' . 'C' is
503         mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...
504         are created and mounted at the dentry 'b' on all mounts where 'B'
505         propagates to. A new propagation tree containing 'C1',..,'Cn' is
506         created. This propagation tree is identical to the propagation tree of
507         'B'.  And finally the peer-group of 'C' is merged with the peer group
508         of 'A'.
510         2. 'A' is a private mount and 'B' is a shared mount. A new mount 'C'
511         which is clone of 'A', is created. Its root dentry is 'a'. 'C' is
512         mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...
513         are created and mounted at the dentry 'b' on all mounts where 'B'
514         propagates to. A new propagation tree is set containing all new mounts
515         'C', 'C1', .., 'Cn' with exactly the same configuration as the
516         propagation tree for 'B'.
518         3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. A new
519         mount 'C' which is clone of 'A', is created. Its root dentry is 'a' .
520         'C' is mounted on mount 'B' at dentry 'b'. Also new mounts 'C1', 'C2',
521         'C3' ... are created and mounted at the dentry 'b' on all mounts where
522         'B' propagates to. A new propagation tree containing the new mounts
523         'C','C1',..  'Cn' is created. This propagation tree is identical to the
524         propagation tree for 'B'. And finally the mount 'C' and its peer group
525         is made the slave of mount 'Z'.  In other words, mount 'C' is in the
526         state 'slave and shared'.
528         4. 'A' is a unbindable mount and 'B' is a shared mount. This is a
529         invalid operation.
531         5. 'A' is a private mount and 'B' is a non-shared(private or slave or
532         unbindable) mount. A new mount 'C' which is clone of 'A', is created.
533         Its root dentry is 'a'. 'C' is mounted on mount 'B' at dentry 'b'.
535         6. 'A' is a shared mount and 'B' is a non-shared mount. A new mount 'C'
536         which is a clone of 'A' is created. Its root dentry is 'a'. 'C' is
537         mounted on mount 'B' at dentry 'b'.  'C' is made a member of the
538         peer-group of 'A'.
540         7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount. A
541         new mount 'C' which is a clone of 'A' is created. Its root dentry is
542         'a'.  'C' is mounted on mount 'B' at dentry 'b'. Also 'C' is set as a
543         slave mount of 'Z'. In other words 'A' and 'C' are both slave mounts of
544         'Z'.  All mount/unmount events on 'Z' propagates to 'A' and 'C'. But
545         mount/unmount on 'A' do not propagate anywhere else. Similarly
546         mount/unmount on 'C' do not propagate anywhere else.
548         8. 'A' is a unbindable mount and 'B' is a non-shared mount. This is a
549         invalid operation. A unbindable mount cannot be bind mounted.
551 5c) Rbind semantics
553         rbind is same as bind. Bind replicates the specified mount.  Rbind
554         replicates all the mounts in the tree belonging to the specified mount.
555         Rbind mount is bind mount applied to all the mounts in the tree.
557         If the source tree that is rbind has some unbindable mounts,
558         then the subtree under the unbindable mount is pruned in the new
559         location.
561         eg: lets say we have the following mount tree.
563                 A
564               /   \
565               B   C
566              / \ / \
567              D E F G
569              Lets say all the mount except the mount C in the tree are
570              of a type other than unbindable.
572              If this tree is rbound to say Z
574              We will have the following tree at the new location.
576                 Z
577                 |
578                 A'
579                /
580               B'                Note how the tree under C is pruned
581              / \                in the new location.
582             D' E'
586 5d) Move semantics
588         Consider the following command
590         mount --move A  B/b
592         where 'A' is the source mount, 'B' is the destination mount and 'b' is
593         the dentry in the destination mount.
595         The outcome depends on the type of the mount of 'A' and 'B'. The table
596         below is a quick reference.
597    ---------------------------------------------------------------------------
598    |                    MOVE MOUNT OPERATION                                 |
599    |**************************************************************************
600    | source(A)->| shared      |       private  |       slave    | unbindable |
601    | dest(B)  |               |                |                |            |
602    |   |      |               |                |                |            |
603    |   v      |               |                |                |            |
604    |**************************************************************************
605    |  shared  | shared        |     shared     |shared and slave|  invalid   |
606    |          |               |                |                |            |
607    |non-shared| shared        |      private   |    slave       | unbindable |
608    ***************************************************************************
609         NOTE: moving a mount residing under a shared mount is invalid.
611       Details follow:
613         1. 'A' is a shared mount and 'B' is a shared mount.  The mount 'A' is
614         mounted on mount 'B' at dentry 'b'.  Also new mounts 'A1', 'A2'...'An'
615         are created and mounted at dentry 'b' on all mounts that receive
616         propagation from mount 'B'. A new propagation tree is created in the
617         exact same configuration as that of 'B'. This new propagation tree
618         contains all the new mounts 'A1', 'A2'...  'An'.  And this new
619         propagation tree is appended to the already existing propagation tree
620         of 'A'.
622         2. 'A' is a private mount and 'B' is a shared mount. The mount 'A' is
623         mounted on mount 'B' at dentry 'b'. Also new mount 'A1', 'A2'... 'An'
624         are created and mounted at dentry 'b' on all mounts that receive
625         propagation from mount 'B'. The mount 'A' becomes a shared mount and a
626         propagation tree is created which is identical to that of
627         'B'. This new propagation tree contains all the new mounts 'A1',
628         'A2'...  'An'.
630         3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount.  The
631         mount 'A' is mounted on mount 'B' at dentry 'b'.  Also new mounts 'A1',
632         'A2'... 'An' are created and mounted at dentry 'b' on all mounts that
633         receive propagation from mount 'B'. A new propagation tree is created
634         in the exact same configuration as that of 'B'. This new propagation
635         tree contains all the new mounts 'A1', 'A2'...  'An'.  And this new
636         propagation tree is appended to the already existing propagation tree of
637         'A'.  Mount 'A' continues to be the slave mount of 'Z' but it also
638         becomes 'shared'.
640         4. 'A' is a unbindable mount and 'B' is a shared mount. The operation
641         is invalid. Because mounting anything on the shared mount 'B' can
642         create new mounts that get mounted on the mounts that receive
643         propagation from 'B'.  And since the mount 'A' is unbindable, cloning
644         it to mount at other mountpoints is not possible.
646         5. 'A' is a private mount and 'B' is a non-shared(private or slave or
647         unbindable) mount. The mount 'A' is mounted on mount 'B' at dentry 'b'.
649         6. 'A' is a shared mount and 'B' is a non-shared mount.  The mount 'A'
650         is mounted on mount 'B' at dentry 'b'.  Mount 'A' continues to be a
651         shared mount.
653         7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount.
654         The mount 'A' is mounted on mount 'B' at dentry 'b'.  Mount 'A'
655         continues to be a slave mount of mount 'Z'.
657         8. 'A' is a unbindable mount and 'B' is a non-shared mount. The mount
658         'A' is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a
659         unbindable mount.
661 5e) Mount semantics
663         Consider the following command
665         mount device  B/b
667         'B' is the destination mount and 'b' is the dentry in the destination
668         mount.
670         The above operation is the same as bind operation with the exception
671         that the source mount is always a private mount.
674 5f) Unmount semantics
676         Consider the following command
678         umount A
680         where 'A' is a mount mounted on mount 'B' at dentry 'b'.
682         If mount 'B' is shared, then all most-recently-mounted mounts at dentry
683         'b' on mounts that receive propagation from mount 'B' and does not have
684         sub-mounts within them are unmounted.
686         Example: Lets say 'B1', 'B2', 'B3' are shared mounts that propagate to
687         each other.
689         lets say 'A1', 'A2', 'A3' are first mounted at dentry 'b' on mount
690         'B1', 'B2' and 'B3' respectively.
692         lets say 'C1', 'C2', 'C3' are next mounted at the same dentry 'b' on
693         mount 'B1', 'B2' and 'B3' respectively.
695         if 'C1' is unmounted, all the mounts that are most-recently-mounted on
696         'B1' and on the mounts that 'B1' propagates-to are unmounted.
698         'B1' propagates to 'B2' and 'B3'. And the most recently mounted mount
699         on 'B2' at dentry 'b' is 'C2', and that of mount 'B3' is 'C3'.
701         So all 'C1', 'C2' and 'C3' should be unmounted.
703         If any of 'C2' or 'C3' has some child mounts, then that mount is not
704         unmounted, but all other mounts are unmounted. However if 'C1' is told
705         to be unmounted and 'C1' has some sub-mounts, the umount operation is
706         failed entirely.
708 5g) Clone Namespace
710         A cloned namespace contains all the mounts as that of the parent
711         namespace.
713         Lets say 'A' and 'B' are the corresponding mounts in the parent and the
714         child namespace.
716         If 'A' is shared, then 'B' is also shared and 'A' and 'B' propagate to
717         each other.
719         If 'A' is a slave mount of 'Z', then 'B' is also the slave mount of
720         'Z'.
722         If 'A' is a private mount, then 'B' is a private mount too.
724         If 'A' is unbindable mount, then 'B' is a unbindable mount too.
727 6) Quiz
729         A. What is the result of the following command sequence?
731                 mount --bind /mnt /mnt
732                 mount --make-shared /mnt
733                 mount --bind /mnt /tmp
734                 mount --move /tmp /mnt/1
736                 what should be the contents of /mnt /mnt/1 /mnt/1/1 should be?
737                 Should they all be identical? or should /mnt and /mnt/1 be
738                 identical only?
741         B. What is the result of the following command sequence?
743                 mount --make-rshared /
744                 mkdir -p /v/1
745                 mount --rbind / /v/1
747                 what should be the content of /v/1/v/1 be?
750         C. What is the result of the following command sequence?
752                 mount --bind /mnt /mnt
753                 mount --make-shared /mnt
754                 mkdir -p /mnt/1/2/3 /mnt/1/test
755                 mount --bind /mnt/1 /tmp
756                 mount --make-slave /mnt
757                 mount --make-shared /mnt
758                 mount --bind /mnt/1/2 /tmp1
759                 mount --make-slave /mnt
761                 At this point we have the first mount at /tmp and
762                 its root dentry is 1. Lets call this mount 'A'
763                 And then we have a second mount at /tmp1 with root
764                 dentry 2. Lets call this mount 'B'
765                 Next we have a third mount at /mnt with root dentry
766                 mnt. Lets call this mount 'C'
768                 'B' is the slave of 'A' and 'C' is a slave of 'B'
769                 A -> B -> C
771                 at this point if we execute the following command
773                 mount --bind /bin /tmp/test
775                 The mount is attempted on 'A'
777                 will the mount propagate to 'B' and 'C' ?
779                 what would be the contents of
780                 /mnt/1/test be?
782 7) FAQ
784         Q1. Why is bind mount needed? How is it different from symbolic links?
785                 symbolic links can get stale if the destination mount gets
786                 unmounted or moved. Bind mounts continue to exist even if the
787                 other mount is unmounted or moved.
789         Q2. Why can't the shared subtree be implemented using exportfs?
791                 exportfs is a heavyweight way of accomplishing part of what
792                 shared subtree can do. I cannot imagine a way to implement the
793                 semantics of slave mount using exportfs?
795         Q3 Why is unbindable mount needed?
797                 Lets say we want to replicate the mount tree at multiple
798                 locations within the same subtree.
800                 if one rbind mounts a tree within the same subtree 'n' times
801                 the number of mounts created is an exponential function of 'n'.
802                 Having unbindable mount can help prune the unneeded bind
803                 mounts. Here is a example.
805                 step 1:
806                    lets say the root tree has just two directories with
807                    one vfsmount.
808                                     root
809                                    /    \
810                                   tmp    usr
812                     And we want to replicate the tree at multiple
813                     mountpoints under /root/tmp
815                 step2:
816                       mount --make-shared /root
818                       mkdir -p /tmp/m1
820                       mount --rbind /root /tmp/m1
822                       the new tree now looks like this:
824                                     root
825                                    /    \
826                                  tmp    usr
827                                 /
828                                m1
829                               /  \
830                              tmp  usr
831                              /
832                             m1
834                           it has two vfsmounts
836                 step3:
837                             mkdir -p /tmp/m2
838                             mount --rbind /root /tmp/m2
840                         the new tree now looks like this:
842                                       root
843                                      /    \
844                                    tmp     usr
845                                   /    \
846                                 m1       m2
847                                / \       /  \
848                              tmp  usr   tmp  usr
849                              / \          /
850                             m1  m2      m1
851                                 / \     /  \
852                               tmp usr  tmp   usr
853                               /        / \
854                              m1       m1  m2
855                             /  \
856                           tmp   usr
857                           /  \
858                          m1   m2
860                        it has 6 vfsmounts
862                 step 4:
863                           mkdir -p /tmp/m3
864                           mount --rbind /root /tmp/m3
866                           I wont' draw the tree..but it has 24 vfsmounts
869                 at step i the number of vfsmounts is V[i] = i*V[i-1].
870                 This is an exponential function. And this tree has way more
871                 mounts than what we really needed in the first place.
873                 One could use a series of umount at each step to prune
874                 out the unneeded mounts. But there is a better solution.
875                 Unclonable mounts come in handy here.
877                 step 1:
878                    lets say the root tree has just two directories with
879                    one vfsmount.
880                                     root
881                                    /    \
882                                   tmp    usr
884                     How do we set up the same tree at multiple locations under
885                     /root/tmp
887                 step2:
888                       mount --bind /root/tmp /root/tmp
890                       mount --make-rshared /root
891                       mount --make-unbindable /root/tmp
893                       mkdir -p /tmp/m1
895                       mount --rbind /root /tmp/m1
897                       the new tree now looks like this:
899                                     root
900                                    /    \
901                                  tmp    usr
902                                 /
903                                m1
904                               /  \
905                              tmp  usr
907                 step3:
908                             mkdir -p /tmp/m2
909                             mount --rbind /root /tmp/m2
911                       the new tree now looks like this:
913                                     root
914                                    /    \
915                                  tmp    usr
916                                 /   \
917                                m1     m2
918                               /  \     / \
919                              tmp  usr tmp usr
921                 step4:
923                             mkdir -p /tmp/m3
924                             mount --rbind /root /tmp/m3
926                       the new tree now looks like this:
928                                           root
929                                       /           \
930                                      tmp           usr
931                                  /    \    \
932                                m1     m2     m3
933                               /  \     / \    /  \
934                              tmp  usr tmp usr tmp usr
936 8) Implementation
938 8A) Datastructure
940         4 new fields are introduced to struct vfsmount
941         ->mnt_share
942         ->mnt_slave_list
943         ->mnt_slave
944         ->mnt_master
946         ->mnt_share links together all the mount to/from which this vfsmount
947                 send/receives propagation events.
949         ->mnt_slave_list links all the mounts to which this vfsmount propagates
950                 to.
952         ->mnt_slave links together all the slaves that its master vfsmount
953                 propagates to.
955         ->mnt_master points to the master vfsmount from which this vfsmount
956                 receives propagation.
958         ->mnt_flags takes two more flags to indicate the propagation status of
959                 the vfsmount.  MNT_SHARE indicates that the vfsmount is a shared
960                 vfsmount.  MNT_UNCLONABLE indicates that the vfsmount cannot be
961                 replicated.
963         All the shared vfsmounts in a peer group form a cyclic list through
964         ->mnt_share.
966         All vfsmounts with the same ->mnt_master form on a cyclic list anchored
967         in ->mnt_master->mnt_slave_list and going through ->mnt_slave.
969          ->mnt_master can point to arbitrary (and possibly different) members
970          of master peer group.  To find all immediate slaves of a peer group
971          you need to go through _all_ ->mnt_slave_list of its members.
972          Conceptually it's just a single set - distribution among the
973          individual lists does not affect propagation or the way propagation
974          tree is modified by operations.
976         A example propagation tree looks as shown in the figure below.
977         [ NOTE: Though it looks like a forest, if we consider all the shared
978         mounts as a conceptual entity called 'pnode', it becomes a tree]
981                         A <--> B <--> C <---> D
982                        /|\            /|      |\
983                       / F G          J K      H I
984                      /
985                     E<-->K
986                         /|\
987                        M L N
989         In the above figure  A,B,C and D all are shared and propagate to each
990         other.   'A' has got 3 slave mounts 'E' 'F' and 'G' 'C' has got 2 slave
991         mounts 'J' and 'K'  and  'D' has got two slave mounts 'H' and 'I'.
992         'E' is also shared with 'K' and they propagate to each other.  And
993         'K' has 3 slaves 'M', 'L' and 'N'
995         A's ->mnt_share links with the ->mnt_share of 'B' 'C' and 'D'
997         A's ->mnt_slave_list links with ->mnt_slave of 'E', 'K', 'F' and 'G'
999         E's ->mnt_share links with ->mnt_share of K
1000         'E', 'K', 'F', 'G' have their ->mnt_master point to struct
1001                                 vfsmount of 'A'
1002         'M', 'L', 'N' have their ->mnt_master point to struct vfsmount of 'K'
1003         K's ->mnt_slave_list links with ->mnt_slave of 'M', 'L' and 'N'
1005         C's ->mnt_slave_list links with ->mnt_slave of 'J' and 'K'
1006         J and K's ->mnt_master points to struct vfsmount of C
1007         and finally D's ->mnt_slave_list links with ->mnt_slave of 'H' and 'I'
1008         'H' and 'I' have their ->mnt_master pointing to struct vfsmount of 'D'.
1011         NOTE: The propagation tree is orthogonal to the mount tree.
1014 8B Algorithm:
1016         The crux of the implementation resides in rbind/move operation.
1018         The overall algorithm breaks the operation into 3 phases: (look at
1019         attach_recursive_mnt() and propagate_mnt())
1021         1. prepare phase.
1022         2. commit phases.
1023         3. abort phases.
1025         Prepare phase:
1027         for each mount in the source tree:
1028                    a) Create the necessary number of mount trees to
1029                         be attached to each of the mounts that receive
1030                         propagation from the destination mount.
1031                    b) Do not attach any of the trees to its destination.
1032                       However note down its ->mnt_parent and ->mnt_mountpoint
1033                    c) Link all the new mounts to form a propagation tree that
1034                       is identical to the propagation tree of the destination
1035                       mount.
1037                    If this phase is successful, there should be 'n' new
1038                    propagation trees; where 'n' is the number of mounts in the
1039                    source tree.  Go to the commit phase
1041                    Also there should be 'm' new mount trees, where 'm' is
1042                    the number of mounts to which the destination mount
1043                    propagates to.
1045                    if any memory allocations fail, go to the abort phase.
1047         Commit phase
1048                 attach each of the mount trees to their corresponding
1049                 destination mounts.
1051         Abort phase
1052                 delete all the newly created trees.
1054         NOTE: all the propagation related functionality resides in the file
1055         pnode.c
1058 ------------------------------------------------------------------------
1060 version 0.1  (created the initial document, Ram Pai linuxram@us.ibm.com)
1061 version 0.2  (Incorporated comments from Al Viro)