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