{
    "content": [
        {
            "type": "text",
            "text": "# mount_namespaces (man)\n\n## NAME\n\nmountnamespaces - overview of Linux mount namespaces\n\n## DESCRIPTION\n\nFor an overview of namespaces, see namespaces(7).\n\n## Sections\n\n- **NAME**\n- **DESCRIPTION**\n- **SHARED SUBTREES** (9 subsections)\n- **STANDARDS**\n- **HISTORY**\n- **NOTES** (1 subsections)\n- **EXAMPLES**\n- **SEE ALSO**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "mount_namespaces",
        "section": "",
        "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": "mountsetattr",
                "section": "2",
                "url": "https://www.chedong.com/phpMan.php/man/mountsetattr/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": "share",
                "section": "2",
                "url": "https://www.chedong.com/phpMan.php/man/share/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": "pamnamespace",
                "section": "8",
                "url": "https://www.chedong.com/phpMan.php/man/pamnamespace/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": "SHARED SUBTREES",
                "lines": 93,
                "subsections": [
                    {
                        "name": "MS_SHARED and MS_PRIVATE example",
                        "lines": 56
                    },
                    {
                        "name": "MS_SLAVE example",
                        "lines": 78
                    },
                    {
                        "name": "MS_UNBINDABLE example",
                        "lines": 110
                    },
                    {
                        "name": "Propagation type transitions",
                        "lines": 19
                    },
                    {
                        "name": "Bind (MS_BIND) semantics",
                        "lines": 22
                    },
                    {
                        "name": "Move (MS_MOVE) semantics",
                        "lines": 19
                    },
                    {
                        "name": "Mount semantics",
                        "lines": 8
                    },
                    {
                        "name": "Unmount semantics",
                        "lines": 8
                    },
                    {
                        "name": "The /proc/ pid /mountinfo propagate_from tag",
                        "lines": 80
                    }
                ]
            },
            {
                "name": "STANDARDS",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "HISTORY",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "NOTES",
                "lines": 29,
                "subsections": [
                    {
                        "name": "Restrictions on mount namespaces",
                        "lines": 160
                    }
                ]
            },
            {
                "name": "EXAMPLES",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SEE ALSO",
                "lines": 7,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "mountnamespaces - overview of Linux mount namespaces\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "For an overview of namespaces, see namespaces(7).\n\nMount  namespaces provide isolation of the list of mounts seen by the processes in each name‐\nspace instance.  Thus, the processes in each of the mount namespace instances will  see  dis‐\ntinct single-directory hierarchies.\n\nThe  views  provided  by  the /proc/pid/mounts, /proc/pid/mountinfo, and /proc/pid/mountstats\nfiles (all described in proc(5)) correspond to the mount namespace in which the process  with\nthe  PID pid resides.  (All of the processes that reside in the same mount namespace will see\nthe 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 list is initialized as follows:\n\n•  If  the  namespace is created using clone(2), the mount list of the child's namespace is a\ncopy of the mount list in the parent process's mount namespace.\n\n•  If the namespace is created using unshare(2), the mount list of the  new  namespace  is  a\ncopy of the mount list in the caller's previous mount namespace.\n\nSubsequent modifications to the mount list (mount(2) and umount(2)) in either mount namespace\nwill  not (by default) affect the mount list seen in the other namespace (but see the follow‐\ning discussion of shared subtrees).\n",
                "subsections": []
            },
            "SHARED SUBTREES": {
                "content": "After 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(2) and  umount(2)\nevents  between namespaces (or, more precisely, between the mounts that are members of a peer\ngroup that are propagating events to one another).\n\nEach mount is marked (via mount(2)) as having one of the following propagation types:\n\nMSSHARED\nThis mount shares events with members of a peer group.  mount(2) and umount(2)  events\nimmediately  under  this  mount will propagate to the other mounts that are members of\nthe peer group.  Propagation here means that the same mount(2) or umount(2) will auto‐\nmatically occur under all of the other mounts in the peer group.  Conversely, mount(2)\nand umount(2) events that take place under peer mounts will propagate to this mount.\n\nMSPRIVATE\nThis mount is private; it does not have a peer group.  mount(2) and  umount(2)  events\ndo not propagate into or out of this mount.\n\nMSSLAVE\nmount(2)  and  umount(2)  events propagate into this mount from a (master) shared peer\ngroup.  mount(2) and umount(2) events under this mount do not propagate to any peer.\n\nNote that a mount can be the slave of another peer group while at the same time  shar‐\ning  mount(2)  and  umount(2) 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 mounts may be marked as shared (with\neach shared mount being a member of a distinct peer group),  while  others  are  private  (or\nslaved or unbindable).\n\nNote  that a mount's propagation type determines whether mount(2) and umount(2) of mounts im‐\nmediately under the mount are propagated.  Thus, the propagation type does not affect  propa‐\ngation  of  events  for grandchildren and further removed descendant mounts.  What happens if\nthe mount itself is unmounted is determined by the propagation type that is in effect for the\nparent of the mount.\n\nMembers are added to a peer group when a mount is marked as shared and either:\n\n(a)  the mount is replicated during the creation of a new mount namespace; or\n\n(b)  a new bind mount is created from the mount.\n\nIn both of these cases, the new mount joins the peer group of which the existing mount  is  a\nmember.\n\nA  new  peer group is also created when a child mount is created under an existing mount that\nis marked as shared.  In this case, the new child mount is also marked as shared and the  re‐\nsulting  peer  group consists of all the mounts that are replicated under the peers of parent\nmounts.\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 mounts in a mount namespace can be discovered via  the  \"optional\nfields\" exposed in /proc/pid/mountinfo.  (See proc(5) for details of this file.)  The follow‐\ning tags can appear in the optional fields for a record in that file:\n\nshared:X\nThis  mount  is shared in peer group X.  Each peer group has a unique ID that is auto‐\nmatically generated by the kernel, and all mounts in the same peer group will show the\nsame ID.  (These IDs are assigned starting from the value 1, and may be recycled  when\na 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",
                "subsections": [
                    {
                        "name": "MS_SHARED and MS_PRIVATE example",
                        "content": "Suppose that on a terminal in the initial mount namespace, we mark one mount  as  shared  and\nanother 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  of  /mntS  and\n/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 mounts.  These new\nmounts maintain the same propagation types, but  have  unique  mount  IDs.   (The  --propaga‐\ntion  unchanged option prevents unshare(1) from marking all mounts as private when creating a\nnew 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 /mntS propagated to its peer mount (in the initial mount namespace),\nbut the new mount created under the private mount /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"
                    },
                    {
                        "name": "MS_SLAVE example",
                        "content": "Making a mount a slave allows it to receive propagated mount(2) and umount(2) 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(2) and\numount(2) events under the slave mount from having side effects in other namespaces.\n\nWe can demonstrate the effect of slaving by first marking two mounts as shared in the initial\nmount 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 mounts:\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 mounts 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 mounts in the new mount namespace, we see that /mntX/a was\ncreated 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 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 mounts in the second mount namespace, we see that in this  case  the  new\nmount  has been propagated to the slave mount, and that the new mount is itself a slave mount\n(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"
                    },
                    {
                        "name": "MS_UNBINDABLE example",
                        "content": "One of the primary purposes of unbindable mounts is to avoid the  \"mount  explosion\"  problem\nwhen repeatedly performing bind mounts of a higher-level subtree at a lower-level mount.  The\nproblem is illustrated by the following shell session.\n\nSuppose we have a system with the following mounts:\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 mounts:\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 mounts, we see there has been no explosion of mounts, because the\nunbindable 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"
                    },
                    {
                        "name": "Propagation type transitions",
                        "content": "The  following  table  shows  the  effect  that  applying  a  new  propagation  type   (i.e.,\nmount  --make-xxxx)  has on the existing propagation type of a mount.  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\".\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"
                    },
                    {
                        "name": "Bind (MS_BIND) semantics",
                        "content": "Suppose that the following command is performed:\n\nmount --bind A/a B/b\n\nHere,  A  is the source mount, B is the destination mount, a is a subdirectory path under the\nmount point A, and b is a subdirectory path under the mount point B.  The propagation type of\nthe resulting mount, B/b, depends on the propagation types of the mounts A and B, and is sum‐\nmarized 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.rst in the kernel source\ntree.\n"
                    },
                    {
                        "name": "Move (MS_MOVE) semantics",
                        "content": "Suppose that the following command is performed:\n\nmount --move A B/b\n\nHere, A is the source mount, B is the destination mount, and b is a subdirectory  path  under\nthe mount point B.  The propagation type of the resulting mount, B/b, depends on the propaga‐\ntion types of the mounts 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.rst in the kernel source\ntree.\n"
                    },
                    {
                        "name": "Mount semantics",
                        "content": "Suppose that we use the following command to create a mount:\n\nmount device B/b\n\nHere, B is the destination mount, and b is a subdirectory path under the mount point B.   The\npropagation  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"
                    },
                    {
                        "name": "Unmount semantics",
                        "content": "Suppose that we use the following command to tear down a mount:\n\numount A\n\nHere, A is a mount on B/b, where B is the parent mount and b is a subdirectory path under the\nmount point B.  If B is shared, then all most-recently-mounted mounts at b on mounts that re‐\nceive propagation from mount B and do not have submounts under them are unmounted.\n"
                    },
                    {
                        "name": "The /proc/ pid /mountinfo propagate_from tag",
                        "content": "The 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 mounts are in the same peer group, but we then make the /tmp/etc a slave\nof  /mnt/etc,  and  then make /tmp/etc shared as well, so that it can propagate events to the\nnext 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 mounts are  initially  in  the\nsame 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"
                    }
                ]
            },
            "STANDARDS": {
                "content": "Linux.\n",
                "subsections": []
            },
            "HISTORY": {
                "content": "Linux 2.4.19.\n",
                "subsections": []
            },
            "NOTES": {
                "content": "The  propagation  type  assigned to a new mount depends on the propagation type of the parent\nmount.  If the mount has a parent (i.e., it is a non-root mount point)  and  the  propagation\ntype  of  the  parent  is  MSSHARED,  then  the  propagation  type  of the new mount is also\nMSSHARED.  Otherwise, the propagation type of the new mount is MSPRIVATE.\n\nNotwithstanding the fact that the default propagation type for new mount  is  in  many  cases\nMSPRIVATE,  MSSHARED  is  typically more useful.  For this reason, systemd(1) automatically\nremounts all mounts as MSSHARED on system startup.  Thus, on most modern  systems,  the  de‐\nfault 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 mounts in the new namespace, unshare(1) (since util-linux 2.27) in turn\nreverses the step performed by systemd(1), by making all mounts private in the new namespace.\nThat is, unshare(1) performs the equivalent of the following in the new 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 mounts in the new  namespace\nto 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.rst.\n",
                "subsections": [
                    {
                        "name": "Restrictions on mount namespaces",
                        "content": "Note the following points with respect to mount namespaces:\n\n[1]  Each mount namespace has an owner user namespace.  As explained above, when a new  mount\nnamespace  is  created, its mount list is initialized as a copy of the mount list of an‐\nother mount namespace.  If the new namespace and the namespace from which the mount list\nwas copied are owned by different user namespaces, then the new mount namespace is  con‐\nsidered less privileged.\n\n[2]  When  creating  a  less  privileged  mount namespace, shared mounts are reduced to slave\nmounts.  This ensures that mappings performed in less privileged mount  namespaces  will\nnot propagate to more privileged mount namespaces.\n\n[3]  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\nas a single unit, and recursive mounts that propagate between mount namespaces propagate\nas a single unit.)\n\nIn this context, \"may not be separated\" means that the mounts are locked  so  that  they\nmay not be individually unmounted.  Consider the following example:\n\n$ sudo sh\n# mount --bind /dev/null /etc/shadow\n# cat /etc/shadow       # Produces no output\n\nThe  above  steps,  performed  in a more privileged mount namespace, have created a bind\nmount that obscures the contents of the shadow password file, /etc/shadow.  For security\nreasons, it should not be possible to umount(2) that mount in a  less  privileged  mount\nnamespace, since that would reveal the contents of /etc/shadow.\n\nSuppose  we  now  create  a  new mount namespace owned by a new user namespace.  The new\nmount namespace will inherit copies of all of the mounts from the previous  mount  name‐\nspace.   However,  those  mounts  will be locked because the new mount namespace is less\nprivileged.  Consequently, an attempt to umount(2) the mount fails as show in  the  fol‐\nlowing step:\n\n# unshare --user --map-root-user --mount \\\nstrace -o /tmp/log \\\numount /mnt/dir\numount: /etc/shadow: not mounted.\n# grep '^umount' /tmp/log\numount2(\"/etc/shadow\", 0)     = -1 EINVAL (Invalid argument)\n\nThe  error message from mount(8) is a little confusing, but the strace(1) output reveals\nthat the underlying umount2(2) system call failed with the error EINVAL,  which  is  the\nerror that the kernel returns to indicate that the mount is locked.\n\nNote,  however,  that it is possible to stack (and unstack) a mount on top of one of the\ninherited locked mounts in a less privileged mount namespace:\n\n# echo 'aaaaa' > /tmp/a    # File to mount onto /etc/shadow\n# unshare --user --map-root-user --mount \\\nsh -c 'mount --bind /tmp/a /etc/shadow; cat /etc/shadow'\naaaaa\n# umount /etc/shadow\n\nThe final umount(8) command above, which is performed in the  initial  mount  namespace,\nmakes the original /etc/shadow file once more visible in that namespace.\n\n[4]  Following  on from point [3], note that it is possible to umount(2) an entire subtree of\nmounts that propagated as a unit into a less privileged mount namespace, as  illustrated\nin the following example.\n\nFirst, we create new user and mount namespaces using unshare(1).  In the new mount name‐\nspace,  the  propagation  type of all mounts is set to private.  We then create a shared\nbind mount at /mnt, and a small hierarchy of mounts underneath that mount.\n\n$ PS1='ns1# ' sudo unshare --user --map-root-user \\\n--mount --propagation private bash\nns1# echo $$        # We need the PID of this shell later\n778501\nns1# mount --make-shared --bind /mnt /mnt\nns1# mkdir /mnt/x\nns1# mount --make-private -t tmpfs none /mnt/x\nns1# mkdir /mnt/x/y\nns1# mount --make-private -t tmpfs none /mnt/x/y\nns1# grep /mnt /proc/self/mountinfo | sed 's/ - .*//'\n986 83 8:5 /mnt /mnt rw,relatime shared:344\n989 986 0:56 / /mnt/x rw,relatime\n990 989 0:57 / /mnt/x/y rw,relatime\n\nContinuing in the same shell session, we then create a second shell in a new user  name‐\nspace  and a new (less privileged) mount namespace and check the state of the propagated\nmounts rooted at /mnt.\n\nns1# PS1='ns2# ' unshare --user --map-root-user \\\n--mount --propagation unchanged bash\nns2# grep /mnt /proc/self/mountinfo | sed 's/ - .*//'\n1239 1204 8:5 /mnt /mnt rw,relatime master:344\n1240 1239 0:56 / /mnt/x rw,relatime\n1241 1240 0:57 / /mnt/x/y rw,relatime\n\nOf note in the above output is that the propagation type of the mount /mnt has been  re‐\nduced  to slave, as explained in point [2].  This means that submount events will propa‐\ngate from the master /mnt in \"ns1\", but propagation will not occur in the  opposite  di‐\nrection.\n\nFrom  a  separate  terminal  window,  we then use nsenter(1) to enter the mount and user\nnamespaces corresponding to \"ns1\".  In that terminal window, we  then  recursively  bind\nmount /mnt/x at the location /mnt/ppp.\n\n$ PS1='ns3# ' sudo nsenter -t 778501 --user --mount\nns3# mount --rbind --make-private /mnt/x /mnt/ppp\nns3# grep /mnt /proc/self/mountinfo | sed 's/ - .*//'\n986 83 8:5 /mnt /mnt rw,relatime shared:344\n989 986 0:56 / /mnt/x rw,relatime\n990 989 0:57 / /mnt/x/y rw,relatime\n1242 986 0:56 / /mnt/ppp rw,relatime\n1243 1242 0:57 / /mnt/ppp/y rw,relatime shared:518\n\nBecause  the  propagation type of the parent mount, /mnt, was shared, the recursive bind\nmount propagated a small subtree of mounts under the slave mount /mnt into \"ns2\", as can\nbe verified by executing the following command in that shell session:\n\nns2# grep /mnt /proc/self/mountinfo | sed 's/ - .*//'\n1239 1204 8:5 /mnt /mnt rw,relatime master:344\n1240 1239 0:56 / /mnt/x rw,relatime\n1241 1240 0:57 / /mnt/x/y rw,relatime\n1244 1239 0:56 / /mnt/ppp rw,relatime\n1245 1244 0:57 / /mnt/ppp/y rw,relatime master:518\n\nWhile it is not possible to umount(2) a part of the propagated subtree  (/mnt/ppp/y)  in\n\"ns2\",  it  is  possible to umount(2) the entire subtree, as shown by the following com‐\nmands:\n\nns2# umount /mnt/ppp/y\numount: /mnt/ppp/y: not mounted.\nns2# umount -l /mnt/ppp | sed 's/ - .*//'      # Succeeds...\nns2# grep /mnt /proc/self/mountinfo\n1239 1204 8:5 /mnt /mnt rw,relatime master:344\n1240 1239 0:56 / /mnt/x rw,relatime\n1241 1240 0:57 / /mnt/x/y rw,relatime\n\n[5]  The mount(2) flags MSRDONLY, MSNOSUID, MSNOEXEC, and the \"atime\"  flags  (MSNOATIME,\nMSNODIRATIME,  MSRELATIME)  settings  become locked when propagated from a more privi‐\nleged to a less privileged mount namespace, and may not be changed in  the  less  privi‐\nleged mount namespace.\n\nThis  point  is  illustrated  in the following example where, in a more privileged mount\nnamespace, we create a bind mount that is marked as read-only.  For security reasons, it\nshould not be possible to make the mount writable in a less privileged mount  namespace,\nand indeed the kernel prevents this:\n\n$ sudo mkdir /mnt/dir\n$ sudo mount --bind -o ro /some/path /mnt/dir\n$ sudo unshare --user --map-root-user --mount \\\nmount -o remount,rw /mnt/dir\nmount: /mnt/dir: permission denied.\n\n[6]  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  name‐\nspace in which it is not a mount point (subject to the usual permission checks).  Conse‐\nquently, the 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  de‐\nnial-of-service attacks against more privileged users (i.e., preventing individual files\nfrom being updated by bind mounting on top of them).\n"
                    }
                ]
            },
            "EXAMPLES": {
                "content": "See pivotroot(2).\n",
                "subsections": []
            },
            "SEE ALSO": {
                "content": "unshare(1),  clone(2),  mount(2),  mountsetattr(2),  pivotroot(2), setns(2), umount(2), un‐\nshare(2), proc(5), namespaces(7), usernamespaces(7), findmnt(8), mount(8), pamnamespace(8),\npivotroot(8), umount(8)\n\nDocumentation/filesystems/sharedsubtree.rst in the kernel source tree.\n\nLinux man-pages 6.7                          2023-10-31                          mountnamespaces(7)",
                "subsections": []
            }
        }
    }
}