skip to content

Linux mounts carry a propagation type — shared, private or slave. What do those mean, and why does a filesystem mounted inside a separate mount namespace sometimes appear on the host and sometimes not?

level: seniorimportance: nice to knowfreq 28%

answer

  1. events, not just the table, are copied
  2. peer groups replicate both ways
  3. one type receives but never sends
  4. mountinfo records it per mount

basics

~20 s

Propagation controls whether mount and unmount events on one mount are replicated to its peers. Shared mounts propagate both ways, private mounts propagate nothing, and slave mounts receive events from their master but send none back — which is why a mount made in an isolated tree may or may not become visible elsewhere.

solid answer

~50 s

A mount namespace is a separate copy of the mount table, but copying the table does not decide what happens *afterwards*, and that is what propagation types are for. A **shared** mount belongs to a peer group: mounting something under it in one copy of the table causes the same mount to appear in all the peers, in both directions. A **private** mount propagates nothing — events stay where they happened. A **slave** mount receives events from its master but never sends any back, which is the useful asymmetry: the isolated tree keeps seeing new host mounts, but nothing it does leaks outward. On a systemd machine the root mount is made shared at boot, so naive namespace isolation actually does leak mounts, which is why tooling explicitly marks trees slave or private with `mount --make-rslave` or `mount --make-rprivate`. You can read the current state from `/proc/self/mountinfo`, where peers show as `shared:N` and slaves as `master:N`.

go deeper

for a junior

Know that mounts carry a propagation setting that decides whether a mount performed in one place shows up elsewhere; the detail is not expected at this level.

for a middle

Distinguish the types by direction of travel — shared both ways, private neither, slave inbound only — and know that the setting is per mount and visible in /proc/self/mountinfo.

for a senior

Explain why a root mount made shared at boot causes mounts to leak out of an isolated tree, and connect propagation to the busy-unmount case where the reference lives in a table you are not looking at.

for a principal

Own the convention for the fleet: which trees are marked slave versus private, who is responsible for cleaning up leaked mounts, and how that choice interacts with storage attached after a workload has started.

## The problem propagation solves A mount namespace gives a process its own copy of the mount table. The copy is taken once, at creation. That immediately raises a question the original Unix model never had to answer: when someone later mounts a USB stick, or an automounter attaches a network share, should that appear in the other copies? Answering "always" makes isolation useless. Answering "never" means an isolated tree goes stale the moment the host's storage changes — and, worse, that a mount made inside it can never be cleaned up from outside. Linux therefore attaches a *propagation type* to each mount, and the answer becomes per-mount policy. The kernel documentation calls this shared subtrees. ## The four types **shared** — the mount is in a peer group. A mount or unmount performed underneath it is replicated to every peer, in every direction. Two peers stay in step. **private** — no propagation at all, in or out. Events under this mount stay in the table where they happened. **slave** — one-directional. The mount has a master; events from the master propagate down to it, but events it originates do not travel back up. A mount can be both slave and shared, receiving from its master and propagating to its own peers. **unbindable** — private, and additionally cannot be used as the source of a bind mount. Its purpose is to stop pathological recursive binds when replicating a tree. They are set with `mount --make-shared`, `--make-private`, `--make-slave` and `--make-unbindable`, each with a recursive `r` variant (`--make-rslave`) that applies to a whole subtree. ## Reading the current state `/proc/self/mountinfo` carries optional fields per mount: `shared:N` for membership of peer group N, and `master:N` for a slave whose master is group N. A mount with neither is private. `findmnt` can print the same information as a column. ```bash findmnt -o TARGET,PROPAGATION / mount --make-rslave /mnt/isolated-root grep ' / ' /proc/self/mountinfo ``` ## Why systemd makes root shared Historically the default was private, and it caused a specific annoyance: mount a filesystem in one context and nothing else on the machine could see it. systemd sets the root mount shared during early boot so that mounts performed anywhere on the system propagate as operators expect — plug in a disk and it shows up for services, including those that were started with their own namespaces. The consequence is the behaviour in the question. Unsharing the mount namespace copies the table, but the copied mounts remain members of the same peer groups, so propagation continues in both directions. A filesystem mounted inside the new namespace appears on the host, and a host unmount removes it from the namespace. Isolation of the *table* is not isolation of *events*. Software that wants real isolation therefore does a second step immediately after unsharing: `mount --make-rslave /` (keep receiving host mounts, leak nothing) or `mount --make-rprivate /` (full separation). Which of the two is chosen is exactly why the same operation "sometimes appears on the host and sometimes not" — it depends on the propagation type in force, not on the namespace itself. ## The operational consequences **Leaked mounts.** A tree left shared will scatter mounts into the host table. They are frequently invisible to whoever created them and outlive the process that did. **Unmounts that will not complete.** If a peer in another namespace still holds a copy of a mount, the filesystem stays busy no matter how thoroughly you clear references in your own table. This is the case that produces "nothing has it open and it still says busy" — the reference is in a table you are not looking at. **Mounts that never arrive.** Make a tree fully private and it stops receiving later host mounts. A service that expected an automounted share to appear under its view will not see it, and the failure is silent: the path exists and is empty. **Recursion.** `--rbind` of a tree that contains shared mounts replicates the peer relationships too, which is why the unbindable type exists and why re-rooting a tree is usually done with an explicit propagation change afterwards. The practical takeaway is that when mounts appear where they should not, or refuse to go away, propagation type is the field to check first — and `/proc/self/mountinfo` is where it is written down.

  • Why do isolation tools usually choose slave rather than fully private for the tree they set up?
    Because slave keeps the useful half of propagation. The isolated tree continues to receive mounts performed on the host — an automounted share, an attached volume, a filesystem mounted after the tree was created — while nothing it does propagates outward. Fully private stops the leak too, but also freezes the view at creation time, so later host mounts never appear and the path silently stays empty.
  • A filesystem refuses to unmount even though nothing on the host has it open. How does propagation explain that?
    Another mount table holds a copy of the mount. If the mount was shared when a namespace was created, or was propagated into one afterwards, that copy is an independent reference and keeps the filesystem busy regardless of what you clear on the host. The fix is to unmount it in the namespace holding it, or to end the process owning that namespace — not to escalate to a lazy unmount.

saying these in an interview costs you the question

  • Thinks a new mount namespace is automatically isolated from host mounts
  • Believes propagation is a filesystem property rather than a per-mount one
  • Says private and slave are the same thing
  • Assumes shared propagation only travels one direction
  • Reaches for lazy unmount when another namespace holds the mount

context