{
    "content": [
        {
            "type": "text",
            "text": "# mount_namespaces(7) (man)\n\n**Summary:** mountnamespaces - overview of Linux mount namespaces\n\n## Examples\n\n- `See pivotroot(2).`\n\n## See Also\n\n- unshare(1)\n- clone(2)\n- mount(2)\n- pivotroot(2)\n- setns(2)\n- umount(2)\n- unshare(2)\n- proc(5)\n- namespaces(7)\n- usernamespaces(7)\n- findmnt(8)\n- mount(8)\n- pivotroot(8)\n- umount(8)\n\n## Section Outline\n\n- **NAME** (2 lines)\n- **DESCRIPTION** (24 lines) — 1 subsections\n  - Restrictions on mount namespaces (35 lines)\n- **SHARED SUBTREES** (341 lines) — 3 subsections\n  - Propagation type transitions (63 lines)\n  - Mount semantics (8 lines)\n  - Unmount semantics (89 lines)\n- **VERSIONS** (2 lines)\n- **CONFORMING TO** (2 lines)\n- **NOTES** (30 lines)\n- **EXAMPLES** (2 lines)\n- **SEE ALSO** (5 lines)\n- **COLOPHON** (7 lines)\n\n## Full Content\n\n### NAME\n\nmountnamespaces - overview of Linux mount namespaces\n\n### DESCRIPTION\n\nFor an overview of namespaces, see namespaces(7).\n\nMount  namespaces provide isolation of the list of mount points seen by the processes in each\nnamespace instance.  Thus, the processes in each of the mount namespace  instances  will  see\ndistinct single-directory hierarchies.\n\nThe    views    provided    by    the    /proc/[pid]/mounts,    /proc/[pid]/mountinfo,    and\n/proc/[pid]/mountstats files (all described in proc(5)) correspond to the mount namespace  in\nwhich  the process with the PID [pid] resides.  (All of the processes that reside in the same\nmount namespace will see the same view in these files.)\n\nA new mount namespace is created using either clone(2) or  unshare(2)  with  the  CLONENEWNS\nflag.  When a new mount namespace is created, its mount point list is initialized as follows:\n\n*  If  the namespace is created using clone(2), the mount point list of the child's namespace\nis a copy of the mount point list in the parent's namespace.\n\n*  If the namespace is created using unshare(2), the mount point list of the new namespace is\na copy of the mount point list in the caller's previous mount namespace.\n\nSubsequent  modifications  to  the  mount point list (mount(2) and umount(2)) in either mount\nnamespace will not (by default) affect the mount point list seen in the other namespace  (but\nsee the following discussion of shared subtrees).\n\n#### Restrictions on mount namespaces\n\nNote the following points with respect to mount namespaces:\n\n*  Each  mount  namespace  has an owner user namespace.  As explained above, when a new mount\nnamespace is created, its mount point list is initialized as a copy  of  the  mount  point\nlist  of  another  mount namespace.  If the new namespace and the namespace from which the\nmount point list was copied are owned by different user namespaces,  then  the  new  mount\nnamespace is considered less privileged.\n\n*  When  creating  a  less  privileged  mount  namespace,  shared mounts are reduced to slave\nmounts.  (Shared and slave mounts are discussed below.)  This ensures that  mappings  per‐\nformed  in  less  privileged  mount namespaces will not propagate to more privileged mount\nnamespaces.\n\n*  Mounts that come as a single unit from a more privileged mount namespace  are  locked  to‐\ngether  and  may  not  be separated in a less privileged mount namespace.  (The unshare(2)\nCLONENEWNS operation brings across all of the mounts from the original mount namespace as\na single unit, and recursive mounts that propagate between mount namespaces propagate as a\nsingle unit.)\n\n*  The mount(2) flags MSRDONLY, MSNOSUID, MSNOEXEC, and  the  \"atime\"  flags  (MSNOATIME,\nMSNODIRATIME,  MSRELATIME) settings become locked when propagated from a more privileged\nto a less privileged mount namespace, and may not be changed in the less privileged  mount\nnamespace.\n\n*  A  file  or  directory that is a mount point in one namespace that is not a mount point in\nanother namespace, may be renamed, unlinked, or removed (rmdir(2)) in the mount  namespace\nin  which it is not a mount point (subject to the usual permission checks).  Consequently,\nthe mount point is removed in the mount namespace where it was a mount point.\n\nPreviously (before Linux 3.18), attempting to unlink, rename, or remove a file  or  direc‐\ntory  that  was  a mount point in another mount namespace would result in the error EBUSY.\nThat behavior had technical problems of enforcement (e.g., for NFS) and permitted  denial-\nof-service attacks against more privileged users.  (i.e., preventing individual files from\nbeing updated by bind mounting on top of them).\n\n### SHARED SUBTREES\n\nAfter the implementation of mount namespaces was completed, experience showed that the isola‐\ntion that they provided was, in some cases, too great.  For example, in order to make a newly\nloaded optical disk available in all mount namespaces, a mount operation was required in each\nnamespace.  For this use case, and others, the shared subtree feature was introduced in Linux\n2.6.15.  This feature allows for automatic,  controlled  propagation  of  mount  and  unmount\nevents  between  namespaces (or, more precisely, between the members of a peer group that are\npropagating events to one another).\n\nEach mount point is marked (via mount(2)) as having one of the following propagation types:\n\nMSSHARED\nThis mount point shares events with members of a peer group.  Mount and unmount events\nimmediately  under  this mount point will propagate to the other mount points that are\nmembers of the peer group.  Propagation here means that the same mount or unmount will\nautomatically  occur  under  all  of  the  other mount points in the peer group.  Con‐\nversely, mount and unmount events that take place under peer mount points will  propa‐\ngate to this mount point.\n\nMSPRIVATE\nThis  mount point is private; it does not have a peer group.  Mount and unmount events\ndo not propagate into or out of this mount point.\n\nMSSLAVE\nMount and unmount events propagate into this mount point from a (master)  shared  peer\ngroup.  Mount and unmount events under this mount point do not propagate to any peer.\n\nNote  that a mount point can be the slave of another peer group while at the same time\nsharing mount and unmount events with a peer group of which it  is  a  member.   (More\nprecisely, one peer group can be the slave of another peer group.)\n\nMSUNBINDABLE\nThis  is  like a private mount, and in addition this mount can't be bind mounted.  At‐\ntempts to bind mount this mount (mount(2) with the MSBIND flag) will fail.\n\nWhen a recursive bind mount (mount(2) with the MSBIND and MSREC flags) is  performed\non  a  directory  subtree, any bind mounts within the subtree are automatically pruned\n(i.e., not replicated) when replicating that subtree to produce the target subtree.\n\nFor a discussion of the propagation type assigned to a new mount, see NOTES.\n\nThe propagation type is a per-mount-point setting; some mount points may be marked as  shared\n(with each shared mount point being a member of a distinct peer group), while others are pri‐\nvate (or slaved or unbindable).\n\nNote that a mount's propagation type determines whether mounts and unmounts of  mount  points\nimmediately under the mount point are propagated.  Thus, the propagation type does not affect\npropagation of events for grandchildren and further removed descendant  mount  points.   What\nhappens  if the mount point itself is unmounted is determined by the propagation type that is\nin effect for the parent of the mount point.\n\nMembers are added to a peer group when a mount point is marked as shared and either:\n\n*  the mount point is replicated during the creation of a new mount namespace; or\n\n*  a new bind mount is created from the mount point.\n\nIn both of these cases, the new mount point joins the peer group of which the existing  mount\npoint is a member.\n\nA  new peer group is also created when a child mount point is created under an existing mount\npoint that is marked as shared.  In this case, the new child mount point is  also  marked  as\nshared  and the resulting peer group consists of all the mount points that are replicated un‐\nder the peers of parent mount.\n\nA mount ceases to be a member of a peer group when either the mount is explicitly  unmounted,\nor  when  the  mount is implicitly unmounted because a mount namespace is removed (because it\nhas no more member processes).\n\nThe propagation type of the mount points in a mount namespace can be discovered via the  \"op‐\ntional  fields\"  exposed  in  /proc/[pid]/mountinfo.  (See proc(5) for details of this file.)\nThe following tags can appear in the optional fields for a record in that file:\n\nshared:X\nThis mount point is shared in peer group X.  Each peer group has a unique ID  that  is\nautomatically  generated  by  the  kernel, and all mount points in the same peer group\nwill show the same ID.  (These IDs are assigned starting from the value 1, and may  be\nrecycled when a peer group ceases to have any members.)\n\nmaster:X\nThis mount is a slave to shared peer group X.\n\npropagatefrom:X (since Linux 2.6.26)\nThis  mount  is  a  slave and receives propagation from shared peer group X.  This tag\nwill always appear in conjunction with a master:X tag.  Here, X is the  closest  domi‐\nnant  peer  group under the process's root directory.  If X is the immediate master of\nthe mount, or if there is no dominant peer group under the same root,  then  only  the\nmaster:X  field  is  present and not the propagatefrom:X field.  For further details,\nsee below.\n\nunbindable\nThis is an unbindable mount.\n\nIf none of the above tags is present, then this is a private mount.\n\nMSSHARED and MSPRIVATE example\nSuppose that on a terminal in the initial mount namespace, we mark one mount point as  shared\nand another as private, and then view the mounts in /proc/self/mountinfo:\n\nsh1# mount --make-shared /mntS\nsh1# mount --make-private /mntP\nsh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n77 61 8:17 / /mntS rw,relatime shared:1\n83 61 8:15 / /mntP rw,relatime\n\nFrom  the  /proc/self/mountinfo  output, we see that /mntS is a shared mount in peer group 1,\nand that /mntP has no optional tags, indicating that it is a private mount.   The  first  two\nfields  in each record in this file are the unique ID for this mount, and the mount ID of the\nparent mount.  We can further inspect this file to see that the parent mount point  of  /mntS\nand /mntP is the root directory, /, which is mounted as private:\n\nsh1# cat /proc/self/mountinfo | awk '$1 == 61' | sed 's/ - .*//'\n61 0 8:2 / / rw,relatime\n\nOn a second terminal, we create a new mount namespace where we run a second shell and inspect\nthe mounts:\n\n$ PS1='sh2# ' sudo unshare -m --propagation unchanged sh\nsh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n222 145 8:17 / /mntS rw,relatime shared:1\n225 145 8:15 / /mntP rw,relatime\n\nThe new mount namespace received a copy of the initial mount namespace's mount points.  These\nnew  mount  points  maintain  the  same  propagation  types, but have unique mount IDs.  (The\n--propagation unchanged option prevents unshare(1) from marking all mounts  as  private  when\ncreating a new mount namespace, which it does by default.)\n\nIn  the  second  terminal, we then create submounts under each of /mntS and /mntP and inspect\nthe set-up:\n\nsh2# mkdir /mntS/a\nsh2# mount /dev/sdb6 /mntS/a\nsh2# mkdir /mntP/b\nsh2# mount /dev/sdb7 /mntP/b\nsh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n222 145 8:17 / /mntS rw,relatime shared:1\n225 145 8:15 / /mntP rw,relatime\n178 222 8:22 / /mntS/a rw,relatime shared:2\n230 225 8:23 / /mntP/b rw,relatime\n\nFrom the above, it can be seen that /mntS/a was created as shared  (inheriting  this  setting\nfrom its parent mount) and /mntP/b was created as a private mount.\n\nReturning  to the first terminal and inspecting the set-up, we see that the new mount created\nunder the shared mount point /mntS propagated to its peer mount (in the initial  mount  name‐\nspace), but the new mount created under the private mount point /mntP did not propagate:\n\nsh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n77 61 8:17 / /mntS rw,relatime shared:1\n83 61 8:15 / /mntP rw,relatime\n179 77 8:22 / /mntS/a rw,relatime shared:2\n\nMSSLAVE example\nMaking  a mount point a slave allows it to receive propagated mount and unmount events from a\nmaster shared peer group, while preventing it from propagating events to that  master.   This\nis  useful  if  we want to (say) receive a mount event when an optical disk is mounted in the\nmaster shared peer group (in another mount namespace), but want to prevent mount and  unmount\nevents under the slave mount from having side effects in other namespaces.\n\nWe  can  demonstrate the effect of slaving by first marking two mount points as shared in the\ninitial mount namespace:\n\nsh1# mount --make-shared /mntX\nsh1# mount --make-shared /mntY\nsh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n132 83 8:23 / /mntX rw,relatime shared:1\n133 83 8:22 / /mntY rw,relatime shared:2\n\nOn a second terminal, we create a new mount namespace and inspect the mount points:\n\nsh2# unshare -m --propagation unchanged sh\nsh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n168 167 8:23 / /mntX rw,relatime shared:1\n169 167 8:22 / /mntY rw,relatime shared:2\n\nIn the new mount namespace, we then mark one of the mount points as a slave:\n\nsh2# mount --make-slave /mntY\nsh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n168 167 8:23 / /mntX rw,relatime shared:1\n169 167 8:22 / /mntY rw,relatime master:2\n\nFrom the above output, we see that /mntY is now a slave mount that is  receiving  propagation\nevents from the shared peer group with the ID 2.\n\nContinuing in the new namespace, we create submounts under each of /mntX and /mntY:\n\nsh2# mkdir /mntX/a\nsh2# mount /dev/sda3 /mntX/a\nsh2# mkdir /mntY/b\nsh2# mount /dev/sda5 /mntY/b\n\nWhen we inspect the state of the mount points in the new mount namespace, we see that /mntX/a\nwas created as a new shared mount (inheriting the \"shared\" setting from its parent mount) and\n/mntY/b was created as a private mount:\n\nsh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n168 167 8:23 / /mntX rw,relatime shared:1\n169 167 8:22 / /mntY rw,relatime master:2\n173 168 8:3 / /mntX/a rw,relatime shared:3\n175 169 8:5 / /mntY/b rw,relatime\n\nReturning  to  the  first  terminal  (in  the initial mount namespace), we see that the mount\n/mntX/a propagated to the peer (the shared /mntX), but the mount /mntY/b was not propagated:\n\nsh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n132 83 8:23 / /mntX rw,relatime shared:1\n133 83 8:22 / /mntY rw,relatime shared:2\n174 132 8:3 / /mntX/a rw,relatime shared:3\n\nNow we create a new mount point under /mntY in the first shell:\n\nsh1# mkdir /mntY/c\nsh1# mount /dev/sda1 /mntY/c\nsh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n132 83 8:23 / /mntX rw,relatime shared:1\n133 83 8:22 / /mntY rw,relatime shared:2\n174 132 8:3 / /mntX/a rw,relatime shared:3\n178 133 8:1 / /mntY/c rw,relatime shared:4\n\nWhen we examine the mount points in the second mount namespace, we see that in this case  the\nnew  mount  has  been propagated to the slave mount point, and that the new mount is itself a\nslave mount (to peer group 4):\n\nsh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n168 167 8:23 / /mntX rw,relatime shared:1\n169 167 8:22 / /mntY rw,relatime master:2\n173 168 8:3 / /mntX/a rw,relatime shared:3\n175 169 8:5 / /mntY/b rw,relatime\n179 169 8:1 / /mntY/c rw,relatime master:4\n\nMSUNBINDABLE example\nOne of the primary purposes of unbindable mounts is to  avoid  the  \"mount  point  explosion\"\nproblem  when  repeatedly  performing  bind mounts of a higher-level subtree at a lower-level\nmount point.  The problem is illustrated by the following shell session.\n\nSuppose we have a system with the following mount points:\n\n# mount | awk '{print $1, $2, $3}'\n/dev/sda1 on /\n/dev/sdb6 on /mntX\n/dev/sdb7 on /mntY\n\nSuppose furthermore that we wish to recursively bind mount the root directory  under  several\nusers' home directories.  We do this for the first user, and inspect the mount points:\n\n# mount --rbind / /home/cecilia/\n# mount | awk '{print $1, $2, $3}'\n/dev/sda1 on /\n/dev/sdb6 on /mntX\n/dev/sdb7 on /mntY\n/dev/sda1 on /home/cecilia\n/dev/sdb6 on /home/cecilia/mntX\n/dev/sdb7 on /home/cecilia/mntY\n\nWhen we repeat this operation for the second user, we start to see the explosion problem:\n\n# mount --rbind / /home/henry\n# mount | awk '{print $1, $2, $3}'\n/dev/sda1 on /\n/dev/sdb6 on /mntX\n/dev/sdb7 on /mntY\n/dev/sda1 on /home/cecilia\n/dev/sdb6 on /home/cecilia/mntX\n/dev/sdb7 on /home/cecilia/mntY\n/dev/sda1 on /home/henry\n/dev/sdb6 on /home/henry/mntX\n/dev/sdb7 on /home/henry/mntY\n/dev/sda1 on /home/henry/home/cecilia\n/dev/sdb6 on /home/henry/home/cecilia/mntX\n/dev/sdb7 on /home/henry/home/cecilia/mntY\n\nUnder  /home/henry,  we  have not only recursively added the /mntX and /mntY mounts, but also\nthe recursive mounts of those directories under /home/cecilia that were created in the previ‐\nous step.  Upon repeating the step for a third user, it becomes obvious that the explosion is\nexponential in nature:\n\n# mount --rbind / /home/otto\n# mount | awk '{print $1, $2, $3}'\n/dev/sda1 on /\n/dev/sdb6 on /mntX\n/dev/sdb7 on /mntY\n/dev/sda1 on /home/cecilia\n/dev/sdb6 on /home/cecilia/mntX\n/dev/sdb7 on /home/cecilia/mntY\n/dev/sda1 on /home/henry\n/dev/sdb6 on /home/henry/mntX\n/dev/sdb7 on /home/henry/mntY\n/dev/sda1 on /home/henry/home/cecilia\n/dev/sdb6 on /home/henry/home/cecilia/mntX\n/dev/sdb7 on /home/henry/home/cecilia/mntY\n/dev/sda1 on /home/otto\n/dev/sdb6 on /home/otto/mntX\n/dev/sdb7 on /home/otto/mntY\n/dev/sda1 on /home/otto/home/cecilia\n/dev/sdb6 on /home/otto/home/cecilia/mntX\n/dev/sdb7 on /home/otto/home/cecilia/mntY\n/dev/sda1 on /home/otto/home/henry\n/dev/sdb6 on /home/otto/home/henry/mntX\n/dev/sdb7 on /home/otto/home/henry/mntY\n/dev/sda1 on /home/otto/home/henry/home/cecilia\n/dev/sdb6 on /home/otto/home/henry/home/cecilia/mntX\n/dev/sdb7 on /home/otto/home/henry/home/cecilia/mntY\n\nThe mount explosion problem in the above scenario can be avoided by making each  of  the  new\nmounts  unbindable.   The effect of doing this is that recursive mounts of the root directory\nwill not replicate the unbindable mounts.  We make such a mount for the first user:\n\n# mount --rbind --make-unbindable / /home/cecilia\n\nBefore going further, we show that unbindable mounts are indeed unbindable:\n\n# mkdir /mntZ\n# mount --bind /home/cecilia /mntZ\nmount: wrong fs type, bad option, bad superblock on /home/cecilia,\nmissing codepage or helper program, or other error\n\nIn some cases useful info is found in syslog - try\ndmesg | tail or so.\n\nNow we create unbindable recursive bind mounts for the other two users:\n\n# mount --rbind --make-unbindable / /home/henry\n# mount --rbind --make-unbindable / /home/otto\n\nUpon examining the list of mount points, we see there has been no explosion of mount  points,\nbecause the unbindable mounts were not replicated under each user's directory:\n\n# mount | awk '{print $1, $2, $3}'\n/dev/sda1 on /\n/dev/sdb6 on /mntX\n/dev/sdb7 on /mntY\n/dev/sda1 on /home/cecilia\n/dev/sdb6 on /home/cecilia/mntX\n/dev/sdb7 on /home/cecilia/mntY\n/dev/sda1 on /home/henry\n/dev/sdb6 on /home/henry/mntX\n/dev/sdb7 on /home/henry/mntY\n/dev/sda1 on /home/otto\n/dev/sdb6 on /home/otto/mntX\n/dev/sdb7 on /home/otto/mntY\n\n#### Propagation type transitions\n\nThe  following  table  shows  the  effect  that  applying a new propagation type (i.e., mount\n--make-xxxx) has on the existing propagation type of a mount point.  The rows  correspond  to\nexisting propagation types, and the columns are the new propagation settings.  For reasons of\nspace, \"private\" is abbreviated as \"priv\" and \"unbindable\" as \"unbind\".\n\nmake-shared   make-slave      make-priv  make-unbind\n─────────────┬───────────────────────────────────────────────────────\nshared       │shared        slave/priv [1]  priv       unbind\nslave        │slave+shared  slave [2]       priv       unbind\nslave+shared │slave+shared  slave           priv       unbind\nprivate      │shared        priv [2]        priv       unbind\nunbindable   │shared        unbind [2]      priv       unbind\n\nNote the following details to the table:\n\n[1] If a shared mount is the only mount in its peer group, making it  a  slave  automatically\nmakes it private.\n\n[2] Slaving a nonshared mount has no effect on the mount.\n\nBind (MSBIND) semantics\nSuppose that the following command is performed:\n\nmount --bind A/a B/b\n\nHere, A is the source mount point, B is the destination mount point, a is a subdirectory path\nunder the mount point A, and b is a subdirectory path under the mount point B.  The  propaga‐\ntion type of the resulting mount, B/b, depends on the propagation types of the mount points A\nand B, and is summarized in the following table.\n\nsource(A)\nshared  private    slave         unbind\n──────────────────┬──────────────────────────────────────────\ndest(B)  shared   │shared  shared     slave+shared  invalid\nnonshared│shared  private    slave         invalid\n\nNote that a recursive bind of a subtree follows the same semantics as for a bind operation on\neach  mount  in the subtree.  (Unbindable mounts are automatically pruned at the target mount\npoint.)\n\nFor further details, see Documentation/filesystems/sharedsubtree.txt  in  the  kernel  source\ntree.\n\nMove (MSMOVE) semantics\nSuppose that the following command is performed:\n\nmount --move A B/b\n\nHere,  A is the source mount point, B is the destination mount point, and b is a subdirectory\npath under the mount point B.  The propagation type of the resulting mount, B/b,  depends  on\nthe propagation types of the mount points A and B, and is summarized in the following table.\n\nsource(A)\nshared  private    slave         unbind\n──────────────────┬─────────────────────────────────────────────\ndest(B)  shared   │shared  shared     slave+shared  invalid\nnonshared│shared  private    slave         unbindable\n\nNote: moving a mount that resides under a shared mount is invalid.\n\nFor  further  details,  see  Documentation/filesystems/sharedsubtree.txt in the kernel source\ntree.\n\n#### Mount semantics\n\nSuppose that we use the following command to create a mount point:\n\nmount device B/b\n\nHere, B is the destination mount point, and b is a subdirectory path under the mount point B.\nThe propagation type of the resulting mount, B/b, follows the same rules as for a bind mount,\nwhere the propagation type of the source mount is considered always to be private.\n\n#### Unmount semantics\n\nSuppose that we use the following command to tear down a mount point:\n\nunmount A\n\nHere, A is a mount point on B/b, where B is the parent mount and b is a subdirectory path un‐\nder  the mount point B.  If B is shared, then all most-recently-mounted mounts at b on mounts\nthat receive propagation from mount B and do not have submounts under them are unmounted.\n\nThe /proc/[pid]/mountinfo propagatefrom tag\nThe propagatefrom:X tag is shown in the optional fields of a /proc/[pid]/mountinfo record in\ncases  where a process can't see a slave's immediate master (i.e., the pathname of the master\nis not reachable from the filesystem root directory) and so cannot  determine  the  chain  of\npropagation between the mounts it can see.\n\nIn  the  following  example, we first create a two-link master-slave chain between the mounts\n/mnt, /tmp/etc, and /mnt/tmp/etc.  Then the chroot(1) command is used to  make  the  /tmp/etc\nmount  point  unreachable  from  the root directory, creating a situation where the master of\n/mnt/tmp/etc is not reachable from the (new) root directory of the process.\n\nFirst, we bind mount the root directory onto /mnt and then bind mount /proc at  /mnt/proc  so\nthat after the later chroot(1) the proc(5) filesystem remains visible at the correct location\nin the chroot-ed environment.\n\n# mkdir -p /mnt/proc\n# mount --bind / /mnt\n# mount --bind /proc /mnt/proc\n\nNext, we ensure that the /mnt mount is a shared mount in a new peer group (with no peers):\n\n# mount --make-private /mnt  # Isolate from any previous peer group\n# mount --make-shared /mnt\n# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'\n239 61 8:2 / /mnt ... shared:102\n248 239 0:4 / /mnt/proc ... shared:5\n\nNext, we bind mount /mnt/etc onto /tmp/etc:\n\n# mkdir -p /tmp/etc\n# mount --bind /mnt/etc /tmp/etc\n# cat /proc/self/mountinfo | egrep '/mnt|/tmp/' | sed 's/ - .*//'\n239 61 8:2 / /mnt ... shared:102\n248 239 0:4 / /mnt/proc ... shared:5\n267 40 8:2 /etc /tmp/etc ... shared:102\n\nInitially, these two mount points are in the same peer group, but we then make the /tmp/etc a\nslave  of /mnt/etc, and then make /tmp/etc shared as well, so that it can propagate events to\nthe next slave in the chain:\n\n# mount --make-slave /tmp/etc\n# mount --make-shared /tmp/etc\n# cat /proc/self/mountinfo | egrep '/mnt|/tmp/' | sed 's/ - .*//'\n239 61 8:2 / /mnt ... shared:102\n248 239 0:4 / /mnt/proc ... shared:5\n267 40 8:2 /etc /tmp/etc ... shared:105 master:102\n\nThen we bind mount /tmp/etc onto /mnt/tmp/etc.  Again, the two mount points are initially  in\nthe same peer group, but we then make /mnt/tmp/etc a slave of /tmp/etc:\n\n# mkdir -p /mnt/tmp/etc\n# mount --bind /tmp/etc /mnt/tmp/etc\n# mount --make-slave /mnt/tmp/etc\n# cat /proc/self/mountinfo | egrep '/mnt|/tmp/' | sed 's/ - .*//'\n239 61 8:2 / /mnt ... shared:102\n248 239 0:4 / /mnt/proc ... shared:5\n267 40 8:2 /etc /tmp/etc ... shared:105 master:102\n273 239 8:2 /etc /mnt/tmp/etc ... master:105\n\nFrom  the  above,  we see that /mnt is the master of the slave /tmp/etc, which in turn is the\nmaster of the slave /mnt/tmp/etc.\n\nWe then chroot(1) to the /mnt directory, which renders the mount with ID 267 unreachable from\nthe (new) root directory:\n\n# chroot /mnt\n\nWhen  we examine the state of the mounts inside the chroot-ed environment, we see the follow‐\ning:\n\n# cat /proc/self/mountinfo | sed 's/ - .*//'\n239 61 8:2 / / ... shared:102\n248 239 0:4 / /proc ... shared:5\n273 239 8:2 /etc /tmp/etc ... master:105 propagatefrom:102\n\nAbove, we see that the mount with ID 273 is a slave whose master is the peer group 105.   The\nmount  point  for that master is unreachable, and so a propagatefrom tag is displayed, indi‐\ncating that the closest dominant peer group (i.e., the nearest reachable mount in  the  slave\nchain)  is  the  peer group with the ID 102 (corresponding to the /mnt mount point before the\nchroot(1) was performed.\n\n### VERSIONS\n\nMount namespaces first appeared in Linux 2.4.19.\n\n### CONFORMING TO\n\nNamespaces are a Linux-specific feature.\n\n### NOTES\n\nThe propagation type assigned to a new mount point depends on the  propagation  type  of  the\nparent  mount.   If the mount point has a parent (i.e., it is a non-root mount point) and the\npropagation type of the parent is MSSHARED, then the propagation type of the  new  mount  is\nalso MSSHARED.  Otherwise, the propagation type of the new mount is MSPRIVATE.\n\nNotwithstanding  the  fact  that the default propagation type for new mount points is in many\ncases MSPRIVATE, MSSHARED is typically more useful.  For this reason, systemd(1)  automati‐\ncally  remounts  all  mount points as MSSHARED on system startup.  Thus, on most modern sys‐\ntems, the default propagation type is in practice MSSHARED.\n\nSince, when one uses unshare(1) to create a mount namespace, the goal is commonly to  provide\nfull isolation of the mount points in the new namespace, unshare(1) (since util-linux version\n2.27) in turn reverses the step performed by systemd(1), by making all mount  points  private\nin  the  new  namespace.  That is, unshare(1) performs the equivalent of the following in the\nnew mount namespace:\n\nmount --make-rprivate /\n\nTo prevent this, one can use the --propagation unchanged option to unshare(1).\n\nAn application that creates a new mount namespace directly using clone(2) or  unshare(2)  may\ndesire  to  prevent  propagation of mount events to other mount namespaces (as is done by un‐‐\nshare(1)).  This can be done by changing the propagation type of  mount  points  in  the  new\nnamespace to either MSSLAVE or MSPRIVATE.  using a call such as the following:\n\nmount(NULL, \"/\", MSSLAVE | MSREC, NULL);\n\nFor  a  discussion of propagation types when moving mounts (MSMOVE) and creating bind mounts\n(MSBIND), see Documentation/filesystems/sharedsubtree.txt.\n\n### EXAMPLES\n\nSee pivotroot(2).\n\n### SEE ALSO\n\nunshare(1), clone(2), mount(2),  pivotroot(2),  setns(2),  umount(2),  unshare(2),  proc(5),\nnamespaces(7), usernamespaces(7), findmnt(8), mount(8), pivotroot(8), umount(8)\n\nDocumentation/filesystems/sharedsubtree.txt in the kernel source tree.\n\n### COLOPHON\n\nThis  page  is  part  of  release  5.10 of the Linux man-pages project.  A description of the\nproject, information about reporting bugs, and the latest version of this page, can be  found\nat https://www.kernel.org/doc/man-pages/.\n\n\n\nLinux                                        2020-11-01                          MOUNTNAMESPACES(7)\n\n"
        }
    ],
    "structuredContent": {
        "command": "mount_namespaces",
        "section": "7",
        "mode": "man",
        "summary": "mountnamespaces - overview of Linux mount namespaces",
        "synopsis": null,
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [
            "See pivotroot(2)."
        ],
        "see_also": [
            {
                "name": "unshare",
                "section": "1",
                "url": "https://www.chedong.com/phpMan.php/man/unshare/1/json"
            },
            {
                "name": "clone",
                "section": "2",
                "url": "https://www.chedong.com/phpMan.php/man/clone/2/json"
            },
            {
                "name": "mount",
                "section": "2",
                "url": "https://www.chedong.com/phpMan.php/man/mount/2/json"
            },
            {
                "name": "pivotroot",
                "section": "2",
                "url": "https://www.chedong.com/phpMan.php/man/pivotroot/2/json"
            },
            {
                "name": "setns",
                "section": "2",
                "url": "https://www.chedong.com/phpMan.php/man/setns/2/json"
            },
            {
                "name": "umount",
                "section": "2",
                "url": "https://www.chedong.com/phpMan.php/man/umount/2/json"
            },
            {
                "name": "unshare",
                "section": "2",
                "url": "https://www.chedong.com/phpMan.php/man/unshare/2/json"
            },
            {
                "name": "proc",
                "section": "5",
                "url": "https://www.chedong.com/phpMan.php/man/proc/5/json"
            },
            {
                "name": "namespaces",
                "section": "7",
                "url": "https://www.chedong.com/phpMan.php/man/namespaces/7/json"
            },
            {
                "name": "usernamespaces",
                "section": "7",
                "url": "https://www.chedong.com/phpMan.php/man/usernamespaces/7/json"
            },
            {
                "name": "findmnt",
                "section": "8",
                "url": "https://www.chedong.com/phpMan.php/man/findmnt/8/json"
            },
            {
                "name": "mount",
                "section": "8",
                "url": "https://www.chedong.com/phpMan.php/man/mount/8/json"
            },
            {
                "name": "pivotroot",
                "section": "8",
                "url": "https://www.chedong.com/phpMan.php/man/pivotroot/8/json"
            },
            {
                "name": "umount",
                "section": "8",
                "url": "https://www.chedong.com/phpMan.php/man/umount/8/json"
            }
        ],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 24,
                "subsections": [
                    {
                        "name": "Restrictions on mount namespaces",
                        "lines": 35
                    }
                ]
            },
            {
                "name": "SHARED SUBTREES",
                "lines": 341,
                "subsections": [
                    {
                        "name": "Propagation type transitions",
                        "lines": 63
                    },
                    {
                        "name": "Mount semantics",
                        "lines": 8
                    },
                    {
                        "name": "Unmount semantics",
                        "lines": 89
                    }
                ]
            },
            {
                "name": "VERSIONS",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "CONFORMING TO",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "NOTES",
                "lines": 30,
                "subsections": []
            },
            {
                "name": "EXAMPLES",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SEE ALSO",
                "lines": 5,
                "subsections": []
            },
            {
                "name": "COLOPHON",
                "lines": 7,
                "subsections": []
            }
        ]
    }
}