mount.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <h2>How mount actually works</h2>
  2. <p>The <a href=https://landley.net/toybox/help.html#mount>mount comand</a>
  3. calls the <a href=https://man7.org/linux/man-pages/man2/mount.2.html>mount
  4. system call</a>, which has five arguments:</p>
  5. <blockquote><b>
  6. int mount(const char *source, const char *target, const char *filesystemtype,
  7. unsigned long mountflags, const void *data);
  8. </b></blockquote>
  9. <p>The command "<b>mount -t ext2 /dev/sda1 /path/to/mntpoint -o ro,noatime</b>"
  10. parses its command line arguments to feed them into those five system call
  11. arguments. In this example, the <b>source</b> is "/dev/sda1", the <b>target</b>
  12. is "/path/to/mountpoint", and the <b>filesystemtype</b> is "ext2".
  13. <p>The other two syscall arguments (<b>mountflags</b> and </b>data</b>)
  14. come from the "-o option,option,option" argument. The mountflags argument goes
  15. to the VFS (explained below), and the data argument is passed to the filesystem
  16. driver.</p>
  17. <p>The mount command's options string is a list of comma separated values. If
  18. there's more than one -o argument on the mount command line, they get glued
  19. together (in order) with a comma. The mount command also checks the file
  20. <b>/etc/fstab</b> for default options, and the options you specify on the command
  21. line get appended to those defaults (if any). Most other command line mount
  22. flags are just synonyms for adding option flags (for example
  23. "mount -o remount -w" is equivalent to "mount -o remount,rw"). Behind the
  24. scenes they all get appended to the -o string and fed to a common parser.</p>
  25. <p>VFS stands for "Virtual File System" and is the common infrastructure shared
  26. by different filesystems. It handles common things like making the filesystem
  27. read only. The mount command assembles an option string to supply to the "data"
  28. argument of the option syscall, but first it parses it for VFS options
  29. (ro,noexec,nodev,nosuid,noatime...) each of which corresponds to a flag
  30. from <b>#include &lt;sys/mount.h&gt;</b>. The mount command removes those options
  31. from the string and sets the corresponding bit in mountflags, then the
  32. remaining options (if any) form the data argument for the filesystem driver.</p>
  33. <blockquote>
  34. <p>Implementation details: the mountflag MS_SILENCE gets set by
  35. default even if there's nothing in /etc/fstab. Some actions (such as --bind
  36. and --move mounts, I.E. -o bind and -o move) are just VFS actions and don't
  37. require any specific filesystem at all. The "-o remount" flag requires looking
  38. up the filesystem in /proc/mounts and reassembling the full option string
  39. because you don't _just_ pass in the changed flags but have to reassemble
  40. the complete new filesystem state to give the system call. Some of the options
  41. in /etc/fstab are for the mount command (such as "user" which only does
  42. anything if the mount command has the suid bit set) and don't get passed
  43. through to the system call.</p>
  44. </blockquote>
  45. <p>When mounting a new filesystem, the "<b>filesystem</b>" argument to the mount system
  46. call specifies which filesystem driver to use. All the loaded drivers are
  47. listed in /proc/filesystems, but calling mount can also trigger a module load
  48. request to add another. A filesystem driver is responsible for putting files
  49. and subdirectories under the mount point: any time you open, close, read,
  50. write, truncate, list the contents of a directory, move, or delete a file,
  51. you're talking to a filesystem driver to do it. (Or when you call
  52. ioctl(), stat(), statvfs(), utime()...)</p>
  53. <h2>Four filesystem types (block backed, server backed, ramfs, synthetic).</h2>
  54. <p>Different drivers implement different filesystems, which come in four
  55. different types: the filesystem's backing store can be a fixed length
  56. block of storage, the backing store can be some server the driver connects to,
  57. the files can remain in memory with no backing store,
  58. or the filesystem driver can algorithmically create the filesystem's contents
  59. on the fly.</p>
  60. <ol>
  61. <li><h3>Block device backed filesystems, such as ext2 and vfat.</h3>
  62. <p>This kind of filesystem driver acts as a lens to look at a block device
  63. through. The source argument for block backed filesystems is a path to a
  64. block device (such as "/dev/hda1") which stores the contents of the
  65. filesystem in a fixed length block of sequential storage, with a seperate
  66. driver providing that block device.</p>
  67. <p>Block backed filesystems are the "conventional" filesystem type most people
  68. think of when they mount things. The name means that the "backing store"
  69. (where the data lives when the system is switched off) is on a block device.</p>
  70. </li>
  71. <li><h3>Server backed filesystems, such as cifs/samba or fuse.</h3>
  72. <p>These drivers convert filesystem operations into a sequential stream of
  73. bytes, which it can send through a pipe to talk to a program. The filesystem
  74. server could be a local Filesystem in Userspace daemon (connected to a local
  75. process through a pipe filehandle), behind a network socket (CIFS and v9fs),
  76. behind a char device (/dev/ttyS0), and so on. The common attribute is there's
  77. some program on the other end sending and receiving a sequential bytestream.
  78. The backing store is a server somewhere, and the filesystem driver is talking
  79. to a process that reads and writes data in some known protocol.</p>
  80. <p>The source argument for these filesystems indicates where the filesystem
  81. lives. It's often in a URL-like format for network filesystems, but it's
  82. really just a blob of data that the filesystem driver understands.</p>
  83. <p>A lot of server backed filesystems want to open their own connection so they
  84. don't have to pass their data through a persistent local userspace process,
  85. not really for performance reasons but because in low memory situations a
  86. chicken-and-egg situation can develop where all the process's pages have
  87. been swapped out but the filesystem needs to write data to its backing
  88. store in order to free up memory so it can swap the process's pages back in.
  89. If this mechanism is providing the root filesystem, this can deadlock and
  90. freeze the system solid. So while you _can_ pass some of them a filehandle,
  91. more often than not you don't.</p>
  92. <p>These are also known as "pipe backed" filesystems (or "network filesystems"
  93. because that's a common case, although a network doesn't need to be inolved).
  94. Conceptually they're char device backed filesystems analogous to the block
  95. backed filesystems (block devices provide seekable storage, char devices
  96. provide serial I/O), but you don't commonly specify a character device in
  97. /dev when mounting them because you're talking to a specific server process,
  98. not a whole machine.</p>
  99. </li>
  100. <li><h3>Ram backed filesystems (ramfs and tmpfs).</h3>
  101. <p>These are very simple filesystems that don't implement a backing store,
  102. but just keep the data in memory. Data
  103. written to these gets stored in the disk cache, and the driver ignores requests
  104. to flush it to backing store (reporting all the pages as pinned and
  105. unfreeable).</p>
  106. <p>These filesystem drivers essentially mount the VFS's page/dentry cache as if it was a
  107. filesystem. (Page cache stores file contents, dentry cache stores directory
  108. entries.) They grow and shrink dynamically as needed: when you write files
  109. into them they allocate more memory to store it, and when you delete files
  110. the memory is freed.</p>
  111. <p>The "ramfs" driver provides the simplest possible ram filesystem,
  112. which is too simple for most real use cases. The "tmpfs" driver adds
  113. a size limitation (by default 50% of system RAM, but it's adjustable as a mount
  114. option) so the system doesn't run out of memory and lock up if you
  115. "cat /dev/zero > file", can report how much space is remaining
  116. when asked (ramfs always says 0 bytes free), and can write its data
  117. out to swap space (like processes do) when the system is under memory pressure.</p>
  118. <blockquote>
  119. <p>Note that "ramdisk" is not the same as "ramfs". The ramdisk driver uses a
  120. chunk of memory to implement a block device, and then you can format that
  121. block device and mount it with a block device backed filesystem driver.
  122. (This is the same "two device drivers" approach you always have with block
  123. backed filesystems: one driver provides /dev/ram0 and the second driver mounts
  124. it as vfat.) Ram disks are significantly less efficient than ramfs,
  125. allocating a fixed amount of memory up front for the block device instead of
  126. dynamically resizing itself as files are written into an deleted from the
  127. page and dentry caches the way ramfs does.</p>
  128. </blockquote>
  129. <p>Initramfs (I.E. rootfs) is a ram backed filesystem mounted on / which
  130. can't be unmounted for the same reason PID 1 can't exit. The boot
  131. process can extract a cpio.gz archive into it (either statically linked
  132. into the kernel or loaded as a second file by the bootloader), and
  133. if it contains an executable "init" binary at the top level that
  134. will be run as PID 1. If you specify "root=" on the kernel command line,
  135. initramfs will be ramfs and will get overmounted with the specified
  136. filesystem if no "/init" binary can be run out of the initramfs.
  137. If you don't specify root= then initramfs will be tmpfs, which is probably
  138. what you want when the system is running from initramfs.</p>
  139. </li>
  140. <li><h3>Synthetic filesystems (proc, sysfs, devtmpfs, devpts...)</h3>
  141. <p>These filesystems don't have any backing store because they don't
  142. store arbitrary data the way the first three types of filesystems do.</p>
  143. <p>Instead they present artificial contents, which can represent processes or
  144. hardware or anything the driver writer wants them to show. Listing or reading
  145. from these files calls a driver function that produces whatever output it's
  146. programmed to, and writing to these files submits data to the driver which
  147. can do anything it wants with it.</p>
  148. <p>Synthetic filesystems are often implemented to provide monitoring and control
  149. knobs for parts of the operating system, as an alternative to adding more
  150. system calls (or ioctl, sysctl, etc). They provide a more human friendly user
  151. interface which programs can use but which users can also interact with
  152. directly from the command line via "cat" and redirecting the output of
  153. "echo" into special files.</p>
  154. <blockquote>
  155. <p>The first synthetic filesystem in Linux was "proc", which was initially
  156. intended to provide a directory for each process in the system to provide
  157. information to tools like "ps" and "top" (the /proc/[0-9]* entries)
  158. but became a dumping ground for any information the kernel wanted to export.
  159. Eventually the kernel developers <a href=https://lwn.net/Articles/57369/>genericized</a>
  160. the synthetic filesystem infrastructure so the system could have multiple
  161. different synthetic filesystems, but /proc remains full
  162. unrelated historic legacy exports kept for backwards compatibility.</p>
  163. </blockquote>
  164. </li>
  165. </ol>
  166. <p>TODO: explain overmounts, mount --move, mount namespaces.</p>