The New Linux Filesystem Standard [ draft 93 09 18 ] -*- text -*- Compiled and written by Daniel Quinlan . This draft is a product of the FSSTND channel of the linux-activists mailing list. Many users, developers, and system administrators gave input into this standard at all points during its development. In addition, many other people quietly monitored the proceedings or privately gave their encouragement and comments. Credit for making this draft a reality goes to the people who did not turn the channel into a flame war and allowed discussion to continue at a rational level throughout the writing and formation of this, a consensus standard. ------------------------------------------------------------------------ Introduction This is the first draft of the new Linux filesystem standard. The new standard is an extensive attempt to correct current problems with the de-facto (and broken) filesystem standard that is used by developers of Linux installations packages. Our aim is to produce a standard of exceptional quality that developers will voluntarily adopt to solve these well acknowledged problems: o The directories are not well structured and differ gratuitously from more modern standards. o The current organization is known to be confusing to the new user and equally frustrating (different reasons, same cause) in nature for the experienced Unix user. o There are incompatibilities between installation packages and other releases that are usually solved by methods of a less than appealing nature. o Overall, symbolic links are used too often within the filesystem to fix problems. However, there are times when symbolic links need to be used to ensure backward compatibility. o Linux is not well prepared for a network installation including the possibility of a read-only /usr partition and diskless (or small local disk) workstations. ------------------------------------------------------------------------ History (how we got started) The original post that motivated this effort to restructure the Linux filesystem was written by: Olaf Kirsh on August 2, 1993 in the NORMAL channel of the Linux activists mailing list. Soon thereafter, it was decided that the best way to accomplish such a restructuring of the Linux filesystem would be to create a mailing list for the purpose of trying to develop a consensus standard. After a comprehensive discussion, with surprisingly few flames, a preliminary draft was written. Then, with the help of several dedicated people, the draft was finished and that resulting draft submitted to the FSSTND channel for more discussion. This is that draft. ------------------------------------------------------------------------ Some specific (and common) problems o There is no single well-accepted Linux directory structure. Instead, there are many, each incompatible with each other, and this alone is enough of a problem to justify this effort. o The primary binary directories, /bin and /usr/bin, do not have well defined divisions. The binaries that are in each path change in the different Linux installation packages. o The legacy of /etc configuration files that are not essential appear in /etc non-essential binaries, such as networking binaries are often "dumped" into /etc and symbolic links applied to fix compatibility problems including both binaries and configuration files makes /etc more confusing and harder to maintain especially for inexperienced users or administrators with especially large systems o The current implementation of /usr cannot be mounted read-only because it contains variable files and directories that need to be written to. o In a networked environment, certain filesystems contain information specific to a single machine. Therefore these filesystems cannot be shared (with NFS). o More than one temporary mount point is needed on the multiple disk systems of today. ------------------------------------------------------------------------ Objectives In trying to solve the above problems, however, we saw several objectives that must be accomplished in addition to technical matters. These goals comprise the correction of outstanding problems as well as the validation of our discussion and work. o Solve the above problems while also creating as few possible problems with the past de-facto standards. o Gain approval of distributors, developers, and other important people in the Linux movement, as well as their suggestions. o Provide a standard that all of the Linux community wishes to follow because it will solve the above problems as well as provide the most elegant structure for Linux's filesystem. o While conformance to this or any other standard in Linux is obviously completely voluntary, we wish to impress upon developers that this standard is the best way to organize a Linux filesystem. If you, as a developer, wish to suggest any improvements, I am eager to listen. ======================================================================== The Filesystem Standard This is the root directory structure. In general, enough should be contained in root partition to boot, restore, recover, and/or repair the system. Our primary concern was to keep root as small as reasonably possible in terms of number of directories, files, and disk space. You might ask, "Why is this desirable?" * The root is often mounted from very small media. For example, most people using Linux install and do recovery by mounting root off of a RAM disk which is copied from a single 1.44M or 1.2M floppy disk. * Root has many system unique configuration files in it, a kernel that may be specific to the system, a different hostname, etc. This means that root isn't usually shareable between networked systems. Keeping root small on networked systems minimizes the amount of space lost on servers to non-shareable files. It also allows workstations with smaller local hard drives. * While you may have a large root partition, and may be able to fill it to your heart's content, there will be people with smaller partitions. If you have more files installed, you may find incompatibilities with other systems using limited root partitions. If you are a developer then the problem is no longer just a personal one. No single package should have its own specific root directory. This structure provides more than enough flexibility for any package. Any package which does occupy a directory under root suffers from sheer arrogance. / : the root directory | |- bin : Command directory with essential binaries |- dev : Device files |- etc : Miscellaneous essential system administration files |- home : User home directories |- lib : Shared libaries (libc and libm) |- lost+found : Files and directories found by 'fsck' |- mnt : Mount points of temporary partitions |- proc : Proc based process system (procps) |- root : Home directory for 'root' |- sbin : System binaries (those binaries once contained in /etc) |- tmp : Temporary files |- usr : Second major mount point (permanent) |- var : Directories of all files that vary with time \- {kernel image} The root directory typically contains the kernel image. The kernel image name is user configurable, but my personal feeling is that Linus Torvalds has and always should have the say in what the recommended names for kernels will be. Currently, I believe that his preference is 'vmlinux' and 'vmlinuz' for uncompressed and compressed kernels, respectively. ------------------------------------------------------------------------ /bin : Essential binaries only (for use by all users) There should be no subdirectories within /bin. The /bin directory should not contain binaries that are only for use by root only. All root-only binaries such as standard daemons, init, getty, et al (usually found in /etc), shall now be placed in /sbin or /usr/sbin (depending on the necessity of the command). However, there are some considerations you should make before deciding what belongs in /bin and what doesn't. For instance, if users are allowed to mount floppies (as I feel they should be), then you would want to make certain that fsck and the mount utilities are placed in /bin. The specific recommendations below assume that users will have access to floppy drives and therefore places the mount and file system utilities in /bin. If you wish to be a fascist, you can change this without too much effort (changing your setup is probably easier than giving up fascism, but that doesn't mean it is the best way). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . REQUIRED files for /bin: general commands: The following commands have been added because of their essential nature in the system. A few have been added because of their traditional placement in /bin. { cat, chgrp, chmod, chown, cmp, compress, cp, date, dd, df du, ed, expr, false, free, grep, hostname, kill, killall, ln, login, ls, mkdir, mknod, mv, nm, od, ps, pwd, rm, rmdir, sh, stty, su, sync, test, touch, true, uncompress, uptime, zcat } note: For compatibility reasons we might want a symbolic link for mail to /usr/bin/mail where it _probably_ should belong. /* moved down to "optional": basename, dirname -- I have never seen any shell scripts that rely on basename and dirname being placed in /bin. */ filesystem commands: { fsck, fsck.*, tunefs, mkfs, mkfs.*, mount, umount } Normal users should be allowed to mount devices - provided the mount device is readable - they own the mount point - suid programs are disallowed on the mounted filesystem networking: These are deemed the only necessary networking binaries that both root and users will want or need to execute other than the ones in /usr/bin, obviously. { ftp, netstat, ping, telnet } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . RECOMMENDED files for /bin: These files should appear in /bin if space is not at a premium { more/less, passwd, write, wall } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OPTIONAL files for /bin: These may appear in /bin at the discretion of system administrators, but are in no way required. { basename, bash, csh, dirname, head, tcsh, pstree, tload, top } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ONES WE AREN'T SURE ABOUT: awk, sed : these are often referenced by shell scripts expr : many installations stick this in /bin ------------------------------------------------------------------------ /dev : Device files There are no subdirectories within /dev. /dev usually also contains a file, MAKEDEV, a shell script designed to create devices as needed. It also often contains a MAKEDEV.local for any local-only devices. Symbolic links within /dev "to make it easier to understand" are dangerous and not a good idea. The largest problem with symlinks in /dev is that they are often not updated when other devices are. If you feel you absolutely MUST create links in /dev then use hard links, and not symbolic ones. A good standard already exists for Linux devices. We believe that the current standard should by followed in all cases (although certain people still wonder about the serial device naming scheme). The device list is maintained by Rick Miller, the Linux Device Registrar, . ------------------------------------------------------------------------ /etc : Miscellaneous system administration files (including net configuration) |- lilo : LILO boot sector utilities and configuration \- {essential system configuration files} No binaries should go directly into /etc. Commands which would have in the past been found in /etc should now be placed in /sbin. This includes such commands as init, getty, and update. Binaries such as hostname which are used by users as well as root should not be placed in /sbin, but in /bin. ------------------------------------------------------------------------ /home : User home directories Administrators of larger systems may wish to subdivide users into seperate directories such as 'staff', 'faculty', 'students', or 'guests'. /home is a fairly standard concept, but it is clearly a local filesystem. The setup will likely differ from machine to machine. Many people prefer to place user accounts in a variety of places and because of this reason, no programming should rely on this location. If you want to find out a user's home directory, you should use the field in /etc/passwd or another reliable method (I know of no other reliable methods). ------------------------------------------------------------------------ /lib : Shared libraries (needed to run dynamically linked binaries) Only the shared library images necessary to boot the system should be placed in /lib. The shared library images are "/lib/libc.so.*" and "/lib/libm.so.*" and not the actual ".a" files. Xfree86 libaries do not belong in /lib. Gcc belongs in /usr/bin. Essentially, only the dynamic shared libraries needed to run programs in /bin and /sbin need to be here. A symbolic link should be added for gcc in /lib pointing to /usr/bin/gcc. Many Linux programs (such as xrdb) have hardcoded gcc to be in this, the wrong directory. /* note: the debate rages on */ ------------------------------------------------------------------------ /mnt : Major mount points for temporary partitions from local devices This directory should contain all temporary mount points. The naming convention that we recommend using is naming the mount point (subdirectories of /mnt) after the device that it is being mounted from. Examples are /mnt/fd0 and /mnt/hda2. It solves the problem of wanting to temporarily mount two drives at once as well as making the entire temporary mount business more logical and less confusing. Although DOS drives can be easily temporarily handled within this arrangement, some people may wish to have a permanent mounting point for their DOS drives. I do not use DOS, but the most sensible proposals that have been put forth is to place DOS in a directory tree named '/dos' with subdirectores named according to traditional DOS schemes, i.e. '/dos/a', '/dos/b', and '/dos/c'. This however, is NOT an offical part of the filesystem standard. ------------------------------------------------------------------------ /proc : Proc based process system The procps filesystem is becoming the standard Linux method for containing process information rather than /dev/kmem and other nasty methods. This is only recommended, but should in time become the standard for the storage and retrieval of process information as well as other kernel and memory information. ------------------------------------------------------------------------ /sbin : System binaries (binaries once kept in /etc) This is simple. If a user will need to run it, then it should go somewhere else. If it will only be run by root (i.e. system administration, networking daemons, system startup), then it should go in /sbin or in /usr/sbin if the item is not essential. Files such as 'chfn' and 'rlogin' which users only occasionally use should be placed in /usr/bin. 'ping', although it is absolutely necessary for root (network recovery and diagnosis) is often used by users and should live in /bin for that reason. Also, any local-only system administration stuff should probably go into /usr/local/sbin. Let me say it one more time, if there is any chance at all that a user should need to run it, do not put it here! Users should never have to place /sbin (or any of the 'sbin' directories) in their path. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . REQUIRED files for /sbin: general: { getty, init, update, mkswap, swapon, swapoff } networking: { ifconfig, routed, inetd, named, syslogd } /* reasonable arguments exist to reduce this to just 'ifconfig' */ /* route is needed and probably belongs in /sbin. A method is needed to add static routes. */ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . /sbin is traditionally known for statically linked files although as you can see we have not even mentioned linking anything statically yet. This is because we feel that the need for statically linked files is not great except in several cases: RECOMMENDED to be linked statically: ln, sync Yes, neither 'ln' or 'sync' are normally in /sbin, but we feel that static versions (if they are included) belong in /sbin as well as dynamically linked versions in /bin ======================================================================== /usr : Second major mount point (permanent) | |- X11 : The X windows directory version 11 |- bin : Most user commands |- dict : Spelling dictionaries |- doc : Miscellaneous documentation |- emacs : GNU Emacs installation directory |- etc : Other configuration files (for programs in /usr/bin) |- g++-include : GNU C++ include files |- games : Games and educational binaries |- include : Header files included by C programs |- info : The GNU info documentation system's primary directory |- lib : Libraries |- local : Local directory (empty after main installation) |- man : Online manuals |- sbin : Non-essential system administration binaries \- src : Source code Unfortunately, at least the following symbolic links need to be added to preserve compatibility unless it can be assumed: /usr/X386 -> /usr/X11 /usr/adm -> /var/adm /usr/emacs/lock -> /var/emacs/lock /usr/preserve -> /var/preserve /usr/spool -> /var/spool /usr/tmp -> /var/tmp ------------------------------------------------------------------------ /usr/X11 : X386 X11 installation directory |- bin |- doc |- include |- lib \- man This hierarchy is reserved for the use of the X386 release. The name "X386" is out of date and should really be replaced with the more accepted, X11, but in order to simplify matters and make X386 more compatible with other X11 packages from XFree86, our recommendation is to place a symbolic link, /usr/X386 pointing to /usr/X11. ------------------------------------------------------------------------ /usr/emacs : GNU Emacs installation directory |- {version-number} : Emacs files for current version |- lock : Lock directory for Emacs \- site-lisp : Site specific Emacs-Lisp files /usr/emacs/{version-number} : Emacs files pertaining to current version only |- etc |- i386-linux \- lisp Note that info files should be placed in /usr/info, and not in /usr/emacs/info. A symlink may be needed to link /usr/emacs/info to /usr/info. In order to have Emacs on /usr and allow for the possibility of a read-only /usr partition it is necessary to link /usr/emacs/lock to /var/emacs/lock. /* I think this should be /var/lock/emacs rather than /var/emacs/lock */ ------------------------------------------------------------------------ /usr/etc This will ultimately depend on what goes into /usr/sbin, for instance, if inetd lives in /usr/sbin, then inetd.conf goes here, if syslogd is in /usr/sbin, then syslog.conf goes here, etc. /* should programs be looking in both /etc and /usr/etc rather than one specifically? */ ------------------------------------------------------------------------ /usr/lib : Libraries for programming (and administative commands?) |- groff : Libaries/directories for the GNU groff system |- gcc-lib : System specific files/directories for GNU C compiler |- terminfo : Directories for terminfo database |- uucp : Commands for uucp \- zoneinfo : Timezone information and configuration The word, library, includes static data files and some internal binaries as well. ------------------------------------------------------------------------ /usr/local : Local directory |- bin : Local only binaries |- etc : Configuration for local only binaries |- games : Locally installed games |- lib : Libraries for /usr/local |- info : Local info pages |- man : Man page hierarchy for /usr/local |- sbin : Local only system administration \- src : Local source code This should be 100% empty after installing Linux, no exceptions other than the listed _empty_ directories. Let me spell it out for the concept impaired, " E M P T Y ". It should also be untouched during system upgrades. ------------------------------------------------------------------------ /usr/sbin : Non-essential standard system binaries Any non-essential system administration binaries, non-essential networking daemons (most other than those mentioned to be in /sbin), large system administration tools, interface programs, or anything used only by the sysadmin that isn't essential. Local system binaries and shell scripts belong in /usr/local/sbin. ------------------------------------------------------------------------ /usr/src : Source code | \- linux : Source code for Linus' kernel Any non-local source code should be placed in this subdirectory, the only thing in /usr/src that should always be placed in a certain location is the kernel source (when present or linked in part to the /usr/include structure). Also, if you have any taste, you'll learn to use subdirectories. The source code for the kernel should always be in place or at least the include files from the kernel source. Those files are located in these directories: /usr/src/linux/include/asm /usr/src/linux/include/linux /usr/include usually contains links to 'asm' and 'linux' in the source directory, therefore, at least those include files should always be distributed with installations. They should also be distributed in the /usr/src/linux directory so there are no problems when system adminstrators upgrade their kernel version. ------------------------------------------------------------------------ /var : Directories of files that vary on different systems and machines |- adm : System logging and accounting files |- locks : Lock files // David H. Silber is working on this |- preserve : Used to save text edited by 'vi' after crash or hangup |- spool : Directories for queuing work to be performed later \- tmp : Second temporary directory This directory contains the directories of all files that vary with time and is usually a local directory. These include logging files, accounting files, backup files for editors and other programs, and spool directories. The reason for a /var is to make it possible to mount /usr read-only. Everything that once went into /usr that is written to on a temporary basis, now goes into /var. Symbolic links, mentioned below, should be added to /usr for compatibility. This is very helpful if you are mounting /usr through NFS or if you just want a read-only /usr. /* /var/domain should be included in the standard (with forward and reverse subdirectories) */ ------------------------------------------------------------------------ /var/spool : Spooling directories (queue work, work to be done later) |- at : at jobs |- cron : Cron jobs |- lpd : Printer spool directory |- mail : Directory for user mailboxes |- mqueue : Outgoing mail queue \- uucp : Spool directory for uucp /var/spool/lpd : Printer spool directory |- lpd/{printer device name} : Spools for a given printer \- {lpd lock files} /* I think all lock files belong in /var/locks */ ------------------------------------------------------------------------ ISSUES: What is Essential? The answer is: essential to clean, create, prepare, check, find and mount other filesystems (possibly on remote machines). There are other definitions, but this is a general definition that most peple will at least incorporate into their own. ------------------------------------------------------------------------ Networking Networking presented an interesting dilemma. Many people like to place networking binaries and configuration seperate from other binaries and configuration. However, we disagree. We feel that networking is not a "package" in the way of Emacs or X386, but an integral part of most Unix machines. Networking files are certainly not required on a system, but once they do appear on a system, it is rare that they will need to be deinstalled or upgraded in the same manner than one upgrades Emacs or Gcc. /bin : anything a user will want to use that is also considered essential (telnet, ping, ftp) /sbin : anything only root needs and is considered essential (ifconfig) /usr/bin : any binaries a user will want to use, that are not essential (rcp, rlogin, ...) /usr/sbin : any root only networking binaries that are not essential (networking daemons, lpd, et al.) While this may seem confusing at first (and it does take a moment to digest) it makes good sense. If you can only mount root for some reason and you need access to networking to repair your system, you don't need the files to be off in /usr/etc (as they often are). Files that are needed to mount /usr in normal (and emergency situations) are placed on the root subtree and any others are placed in /usr in order to keep the size of root small. Configuration files for networking similarly go into /etc and /usr/etc dependent on how they are deemed, essential, or non-essential. This should coincide with any respective binaries in /sbin or /usr/sbin. ------------------------------------------------------------------------ Symbolic Links The possibilities for using symbolic links on your system is practically endless. While symlinks are not encouraged for default setup (found after installing Linux) in a standard such as this, they are often used with good purpose on different systems. The point is that symlinks should be there to keep everything where everyone ELSE expects it, but you don't want it. Be prepared to accept that certain directories, even those contained on the root directory, are still going to be symlinks. For instance, on some systems /home will not be on the root, but symlinked to a /var directory, or to somewhere else. /home could also have its own physical partition, of course, and be mounted on its own. Similarly, because /usr might be on a central fileserver mounted via NFS, /usr/local could be symlinked to /var/local. Like /usr/emacs/lock, this change can be justified by recalling the definition of /var: "directories of files that vary on different systems and machines". Sometimes systems will also link /tmp to /var/tmp if the root partition becomes too small (or starts out too small). There are more examples of "good" uses of symbolic links, but the entire issue boils down to two things: packages should be able to find things where they expect them (within reason) and symbolic links can be used to solve the problem in many cases, but problems also can arise from using too many symbolic links. Problems include getting psychosomatic ailments while typing "ls -al" in symlink-populated areas and being plain old confused by too many. ------------------------------------------------------------------------ Statically linked binaries Linux is currently running on a wide variety of systems, some single user with small disks, some as servers in large networked environments. Because of this variety, this standard sets no rule regarding what binaries are static or dynamic with the following two exceptions. Both 'ln' and 'sync' should have static versions in /sbin in addition to dynamic versions in /bin since everyday users may wish to run these too. Large Linux systems may wish to include other statically linked binaries (sh, init, mkfs, fsck, tunefs, mount, umount, swapon, swapoff, getty, login, et al). The developers and/or system administrators are free to statically/dynamically link these and other binaries as they see fit, as long as the location of the binaries doesn't change. Networked systems (especially those of the future which may lack floppy drives), may want to make ifconfig, route, hostname, and ftp (meaning an additional static copy in /sbin) static as well. ------------------------------------------------------------------------ CONTRIBUTORS: Drew Eckhardt Ian Jackson Ian McCloghrie Daniel Quinlan Mike Sangrey David H. Silber Theodore Ts'o Stephen Tweedie ------------------------------------------------------------------------