Skip to content

Proc Mount Export Interface

1. Overview

DragonOS exports the mount-namespace view to userspace through procfs. The main entry points are:

PathTypeViewpoint
/proc/mountssymlink → self/mountscurrent reading process
/proc/self/mountsregular filecurrent reading process
/proc/[pid]/mountsregular filetarget pid
/proc/[pid]/mountinforegular filetarget pid
/proc/[pid]/mountstatsregular filetarget pid

Of these:

  • mounts: traditional format with fewer fields; compatible with mount(8), shell scripts, and similar tools.
  • mountinfo: modern format that includes mount id, parent/child relationships, propagation tags, superblock options, and more.
  • mountstats: one descriptive prefix line per mount, with optional filesystem-specific statistics appended (proc_show_mount_stats).

Propagation types (shared / master / propagate_from / unbindable) appear only in the optional fields of mountinfo. They are never written into the ordinary option column of /proc/*/mounts.

2. Role of Each Interface

2.1 /proc/mounts and /proc/self/mounts

/proc/mounts is implemented as a symlink to self/mounts (readlink returns self/mounts). After resolution it is equivalent to reading /proc/self/mounts, i.e. the mount list of the current reading process under its mount namespace and fs root.

Each line typically contains:

  • device name (or filesystem name)
  • mount point
  • filesystem type
  • mount options (rw and per-mount options such as nosuid,nodev,...; no propagation tags)
  • two compatibility fields 0 0

2.2 /proc/[pid]/mounts

The format is the same as /proc/self/mounts, but open binds the target thread-group leader's mnt_ns and fs_struct.root(), so the export is the set of mounts visible from the target process's viewpoint.

2.3 /proc/[pid]/mountinfo

On top of mounts, this interface adds:

  • mount id and parent mount id
  • major device number (major:minor)
  • mount root (proc_show_mountinfo_root)
  • per-mount options and superblock options (two optional-field segments separated by -)
  • propagation tagged fields (MountPropagation::proc_mountinfo_tags())
  • filesystem type name

2.4 /proc/[pid]/mountstats

Each visible mount has at least one line:

text
device <dev> mounted on <mountpoint> with fstype <type>

If the underlying filesystem returns extra content through proc_show_mount_stats, that content is appended to the same line. The permission is 0400 (owner-readable only), unlike the 0444 of mounts / mountinfo.

3. Kernel Source Layout

Mount-export logic is concentrated in kernel/src/filesystem/procfs/mount/. The historical single-file mount_view.rs and the scattered procfs/mounts.rs / pid/mountinfo.rs implementations are no longer used.

kernel/src/filesystem/procfs/mount/
├── mod.rs                 # module entry; export render API
├── collect.rs             # ProcMountEntry, collect_visible_mounts()
├── fields.rs              # MountProcFields: precompute export fields before open
├── escape.rs              # proc field escaping (space, tab, backslash, ...)
├── render.rs              # ProcMountRenderKind; render on open + read from cache
├── format/
│   ├── mounts_line.rs     # /proc/*/mounts line format
│   ├── mountinfo_line.rs  # /proc/*/mountinfo line format
│   └── mountstats_line.rs # /proc/*/mountstats line format
└── inode/
    ├── mounts_symlink.rs  # /proc/mounts → self/mounts (MountsSymOps)
    └── pid_mount.rs       # /proc/[pid]/{mounts,mountinfo,mountstats} (MountProcFileOps)

Registration sites:

  • kernel/src/filesystem/procfs/root.rs: root directory entry ("mounts", MountsSymOps::new_inode)
  • kernel/src/filesystem/procfs/pid/mod.rs: PidDirOps::STATIC_ENTRIES registers one MountProcFileOps each for mountinfo / mounts / mountstats (format selected via ProcMountRenderKind)

Related dependencies that live outside procfs/mount/:

  • kernel/src/filesystem/vfs/mount/mod.rs: MountFlags::proc_rw_token(), proc_per_mount_options(), proc_super_block_options(), options_string()
  • kernel/src/filesystem/vfs/mod.rs: filesystem trait hooks proc_show_devname, proc_show_mount_options, proc_show_mountinfo_root, proc_show_mount_stats
  • kernel/src/process/namespace/propagation.rs: MountPropagation::proc_mountinfo_tags()

Userspace test: user/apps/tests/dunitest/suites/normal/proc_mount_exports.cc (whitelist: normal/proc_mount_exports).

4. DragonOS Implementation

4.1 Unified Render Pipeline

The three proc files share one pipeline (render.rs):

  1. open() (MountProcFileOps::open, or opening /proc/self/mounts via the symlink)
    • Resolve the target: ProcPidTarget → thread-group leader ProcessControlBlock
  2. collect_visible_mounts() (collect.rs)
    • Walk the target mnt_ns.mount_list(), sorted by mount id
    • Apply visibility clipping against the target fs_struct.root() (visible_mountpoint)
  3. MountProcFields::from_entry() (fields.rs)
    • Snapshot each ProcMountEntry: devname, fstype, the various options, mountinfo root/tags, and so on
  4. Call format::*_line::render according to ProcMountRenderKind
  5. Write the complete text into FilePrivateData::Procfs.data
  6. read_at() only copies from the cache via read_cached_mount_file()proc_read()

The current model is therefore: the entire file snapshot is generated at open time; reads during the same open do not re-walk the mount tree.

4.2 Target-Process Viewpoint

  • /proc/mountsself/mounts → the mounts file under the current process's pid directory
  • /proc/[pid]/mounts|mountinfo|mountstats is bound at open time to that pid's thread-group namespace and root

The exported content reflects the target process's mnt_ns + fs root, not the reader's own mount table (unless the reader is opening its own /proc/self/...).

4.3 Visibility Clipping

visible_mountpoint(mount_path, root_path) in collect.rs:

  • When the target root is /, mount-point paths are exported as-is
  • When the target is under a restricted root such as chroot, only mounts inside that root subtree are kept, and displayed paths are normalized to a view rooted at /

4.4 Split of Options and Propagation Fields

Field sourceUsed byNotes
MountFlags::proc_rw_token()mounts / mountinfo per-mountro or rw
MountFlags::proc_per_mount_options()mountinfo per-mountnosuid,nodev,..., without rw
MountFlags::proc_super_block_options() + sb read-only statemountinfo superblock segmentsync,mand,...
FileSystem::proc_show_mount_options()mounts line, mountinfo superblock segmentfilesystem-private options
MountPropagation::proc_mountinfo_tags()mountinfo tail onlyshared:N and similar; never enter mounts

mounts_line uses the pre-merged mounts_options; mountinfo_line separates per-mount and superblock options with -, then appends propagation tags.

4.5 Responsibilities of the Three Formats

  • format/mounts_line.rs: device, mount point, type, options, 0 0
  • format/mountinfo_line.rs: id, parent, major:minor, root, mount point, option segments, -, fstype, super options, tags
  • format/mountstats_line.rs: common device ... mounted on ... prefix + optional fs stats

Filesystem-specific differences are injected through VFS trait hooks. procfs itself only owns the common line structure and escaping.

5. Semantic Characteristics of the Current Interfaces

5.1 mounts

Highly compatible, few fields; does not include propagation tags. As on Linux, the current-process view should be accessed through the /proc/mounts symlink.

5.2 mountinfo

The preferred interface for recovering mount topology and propagation attributes. Per-mount options, superblock options, and propagation tags are shown in separate columns.

5.3 mountstats

  • Not a mount-change notification interface
  • Content within a single open() is a snapshot; a new open() can see an updated mount set and statistics
  • The line format allows a device or no device prefix (chosen by whether devname is empty; see proc_mount_exports.cc)

6. Differences from Linux

6.1 Overview of Differences

DimensionLinuxDragonOS current implementation
Open modelseq_file + iteratorone-shot render and cache at open()
Read modelgenerated on demand while readingread from the FilePrivateData cache
/proc/mountssymlink → self/mountsimplemented (MountsSymOps)
Viewpoint bindingtarget task's mnt_ns + fs rootsame as Linux (collect_visible_mounts)
mounts / mountinfo pollmount-namespace eventsnot implemented
Traversal basisnamespace list + cursoriterate mnt_ns.mount_list() after sorting
Code organizationfs/proc_namespace.c and relatedprocfs/mount/{collect,fields,format,render,inode}

6.2 Linux seq_file Semantics

Linux uses mounts_open_common() + seq_file to iterate the mount list during read. DragonOS concatenates the full string at open and caches it. The implementation is simpler and the result is stable for a given fd, but it is not fully equivalent to Linux's iterator model.

6.3 poll on mounts / mountinfo

Linux can poll/epoll mounts / mountinfo via mount-namespace events. DragonOS has not yet implemented the namespace event sequence number or wait queue, so these files cannot serve as a mount-change notification source.

6.4 Dynamism of mountstats and poll

Linux has no dedicated mountstats poll semantics; DragonOS likewise does not invent extra poll behavior for mountstats. Changes in statistics and topology are observed by reopening the file.

6.5 Visibility-Clipping Semantics

Linux uses path-object-based root clipping such as seq_path_root. DragonOS currently compares absolute path strings against the target fs root. The overall direction matches, but details still differ from Linux path-object semantics.

6.6 Traversal and Authoritative Data Source

Linux treats the namespace-level mount linked list as the authoritative source. DragonOS takes the table from MntNamespace::mount_list() and sorts it, rather than DFS-walking a single mount tree. Aligning Linux iteration order and the event model later will require further evolution on the MntNamespace side.

7. Current Use Cases and Recommendations

Already supported:

  • Read the current process's mount table via /proc/mounts (symlink) or /proc/self/mounts
  • Read /proc/[pid]/mounts, mountinfo, and mountstats while debugging
  • Container/namespace tools can parse propagation fields in mountinfo

Notes:

  • Userspace tools that depend on mount-namespace poll notification are not yet compatible
  • Programs that strongly depend on Linux seq_file line-by-line iteration semantics may observe behavioral differences
  • When changing export logic, update both procfs/mount/ and the proc_mount_exports test

8. Summary

DragonOS consolidates proc mount export into kernel/src/filesystem/procfs/mount/:

  • inode layer: /proc/mounts symlink + unified MountProcFileOps for /proc/[pid]/*
  • data layer: collectfields snapshot → format for the three line renderers
  • option semantics: propagation tags appear only in mountinfo; MountFlags and VFS hooks split the export work

The external functional surface is already close to Linux. The underlying model is still open-time snapshot + string clipping, and work continues on poll, the iteration model, and path semantics.