the_simple_computer

Oh /dev/sda! How Have I Displeased Thee?

Updated October, 14, 2014.

This site is no longer being maintained so anything below could still be accurate, or very outdated.


/etc/fstab is the primary file which tell a Linux box what partitions, drives and devices to mount and at which places in the filesystem to do so. When you start your computer, the command mount -a is run from a boot script and this invokes fstab, bringing your disk partitions to life.

What else is fstab? A compromise. It’s a one-size-fits-all solution to give the best general performance on the largest amount of hardware possible. Hard drives (including SSDs) and filesystems are finicky things which can behave inconsistently under similar circumstances. It boils down to the fact that for optimal settings, you must benchmark your own setup because if you really want to tune your equipment, there’s no quick copy & paste fix.

Having said that, fstab changes do not give a large performance increase and there is nothing shameful about a default fstab. Besides, if you really want to fine-tune the I/O performance of your system's storage, you'll need to go further than just fstab tweaks.

The Arch Linux and Ubuntu wikis are helpful introductions to fstab which you should definitely read through. The mount command's man page (or run man mount in a terminal) gives you most of what you need to know but to Linux nooblets, its contents are abstractions from a distant universe.

Using a few basic fstab tweaks, it is possible to squeeze out some extra security and performance from the filesystem without any negative effects. What I attempt in this installation of tSc goodness is to condense the fstab experience into something more palatable for new(ish) users yet more advanced than the wiki intro pages. I have for you a range of settings to choose from and I’ve done some light benchmarks for some of those settings, but keep in mind that your results WILL vary and just because a setting is available, doesn't mean you should use it.

I always put / and /home on separate partitions unless a different setup is specifically needed. Why? Because this allows better control of each partition individually through fstab, LUKS encryption and backup imaging. Not that those are always needed simultaneously, but I highly suggest you take advantage of them as much as possible.

For this writeup I’m using Ubuntu 13.04 with both the default ext4 filesystem and 3.8 kernel. The light testing I did on a bare metal installed system but the two screenshots below are from a virtual machine. Most of this also applies to other distros using ext4 and some with ext3.


Get to Know Your fstab

Before all else, let us familiarize ourselves with the filesystem in its default state. Open up a terminal window and enter:



cat /proc/mounts
	

The exact readout will vary depending on your distro, partition setup and kernel of choice, but you will see something like this:


Since I installed the VM to two partitions, / is labeled with /dev/disk/by-uuid/huge_device_identifier and /home is just /dev/sda2. If you encrypted your partitions with Cryptsetup and dm_crypt, they will each show as /dev/mapper/device_name. In the screenshot, you can see that / is mounted with the options rw, relatime, errors=remount-ro, and data=ordered. Then /home is mounted with rw, relatime, data=ordered.

Now let’s go over to fstab.



cat /etc/fstab
	

Raring’s default fstab looks like below. In addition to what we saw in /proc/mounts, /home also uses the mount option "defaults".



Confusingly, / also uses defaults even though it’s not listed. Mount’s man page tells of mount options specified directly by the kernel. These are suid, dev, exec, auto, nouser, async and relatime and they’re summed up into the one defaults option. Now combine these kernel options with what you see for each partition in fstab and /proc/mounts; these are your filesystem’s default mount options.

Ok, so what do these mount options mean? No need for me to reinvent the wheel here, the Arch and Ubuntu wikis clearly lay out the basics. For the bigger picture, mount’s man page to the rescue and the two areas you want to focus on are Filesystem Independent Mount Options and then ext4 under Filesystem Dependent Mount Options.


Mount Option Etiquette

Before we start changing things, there are some rules to how mount options are used. Options are applied from left to right and you should always avoid contradicting and redundant entries. For example, there is no need to add rw, relatime or data=ordered to fstab because those mount options are already set as default by the kernel.

Certain mount options also include other options. One example is the option owner, which allows only the owner of a device or filesystem to mount it. The owner option already includes nodev and nosuid so you don’t need to add them individually.

Your New fstab

Let’s create a thought exercise. Summon in your mind an average desktop computer for average home use, running whatever distro you prefer (within reasonable averageness, of course). Whether it single or multi-boots other operating systems does not matter. Let us assign 4GB of RAM to our new friend and give it a single mechanical hard drive. This computer also does not have any kind of battery backup or external power supply because again, it’s completely average.

If this desktop were under my watch, below is what I would make its fstab file look like. The bold is what I added.



# <file> <system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/sda1 during installation
UUID=***    /    ext4    noatime,errors=remount-ro 0 1

# /home was on /dev/sda2 during installation
UUID=***    /home    ext4    nodev,nosuid,noatime,errors=remount-ro 0 2

# swap was on /dev/sda3 during installation
UUID=***    none    swap    sw 0 0

tmpfs /tmp tmpfs nosuid,nodev 0 0
none /run/shm tmpfs nosuid,nodev,noexec 0 0
	

No drastic change from default, it leans more towards usability and safety rather than ironclad security and cutting-edge speed, but while nothing is written in stone, fstab really isn't the place to aim for either of those things; fstab would be a small layer, at best.

Let’s break these added settings down. The mount options and the last two lines are the biggest areas of interest so from here, I will presume you have skimmed through at least Ubuntu’s wiki on fstab.

noatime

Starting with the system partition, noatime is the first mount option and the Arch Wiki explains well what atime is. Noatime is just turning that off, which is especially good for minimizing power consumption and disk writes but does not affect a file’s Last Modified date in a file manager. I assume this average user will not be using a CLI based mail client, so noatime would be desirable.

nodev

This is a security option. Here are two great explanations on Super User [1] [2].

nosuid

Also a security option; SUID means Set User ID but nosuid also includes SGID, Set Group ID. nosuid disallows any executable on the partition from having SUID and SGID permissions so it would be unable to change from your user account's ownership and group, to a different user or group with elevated privileges.

The last two fstab lines we will get to shortly.


Other Popular Mount Options

The mount options you use should be appropriate for the user and/or the system but this also requires some quick mental risk management. If you’re working with a laptop or a computer with an uninterruptible power supply, that allows you to (more) safely use some mount options you otherwise wouldn’t want to include. The differences in performance between using these or not is virtually unnoticeable and many people would probably argue they’re not worth the risk of corrupted data in event of a crash. However, do as you will.

data=writeback

Ext 3 and 4 have three journaling modes. Both ordered (the default) and writeback only journal metatdata, not the file data itself, so they’re a sort of half-journaling (and no, writeback does not disable journaling altogether).

From the tune2fs man page entry on writeback mode, “This may increase throughput, however, it may allow old data to appear in files after a crash and journal recovery.” Full journaling of both file and metadata is what you get with data=journal and that gives you the most safety with the largest performance decrease.

According to mount’s man page, the proper way to change the journaling mode of your system partition is to modify GRUB rather than fstab. Other partitions will obey fstab.



gksu gedit /etc/default/grub
	

Add the bold.



GRUB_CMDLINE_LINUX_DEFAULT="quiet splash rootflags=data=writeback"
	

Then update GRUB.



sudo update-grub
	

If you change the system partition's journaling mode, you MUST inform tune2fs about it. If you do not, the computer won’t boot.



sudo tune2fs -o journal_data_writeback /dev/sdxy
	

commit

By default, this syncs file data with its journaled metadata every 5 seconds. If you’re on a stable system with battery backup, you can up this to 30 seconds, 120 seconds, or (theoretically) whatever duration you’re comfortable with. For reference, the script in the laptop-mode-tools package changes the commit time to 10 minutes (which I personally would not want so high).

Increasing the commit time will decrease disk writes and power use by a small amount. The downside is that you go longer with a discrepancy between a file’s data and its journaled metadata so if you do have a crash, you could loose more work with a higher commit time than a lower one. To set the commit interval in fstab, the syntax is:



commit=30
	

nobarrier

Write barriers are enabled by default on Linux’s ext4 filesystem. From mount’s man page, “If your disks are battery-backed in one way or another, disabling barriers may safely improve performance.” For more info on write barriers, see this article from Linux Weekly News but note that from kernel 2.6.33, mapper devices like logical or encrypted volumes can use nobarrier too.

noexec

This disallows executables from running on the device. You could add noexec to /home as a security enhancement but then things like .deb packages and scripts would not be able to run from there; you'd need to move them to /opt or /tmp and either change their ownership or run as root. This could be a useful on LDAP and other centrally managed Active Directory-esque areas.


TRIM for SSDs

From the operating system, TRIM for solid state drives is called either by the Discard mount option or an fstrim script. Discard tells the filesystem to tell the SDD’s firmware to run TRIM immediately after you delete any file. Discard is only for ext4 filesystems but via TRIM, it is supported by both ATA and SCSI devices. It used to be that because TRIM by discard happens right away, it would cause stuttering or even temporary freezes. More recent trials from users posting in the comments of this 2011 blog article indicate that discard times may be decreasing due to firmware and kernel advances.

The alternative to discard is a cron job which runs fstrim. fstrim calls FITRIM to asynchronously do batch cleanups all at once at a scheduled time. FITRIM will work on ext3 & 4, xfs and several other filesystem types but only on ATA devices. For an LVM or dm_crypt setup, you would actually use both fstrim and discard. However, know that enabling TRIM on encrypted volumes has security implications.

Ubuntu 14.04 and derivatives install with a weekly cron job by default which runs /sbin/fstrim-all. This checks if your SSD is whitelisted and if so, runs fstrim (see /sbin/fstrim-all). Forcing fstrim for non-whitelisted manufacturers comes with an At Your Own Risk! disclaimer and may still not work since some SSDs are blacklisted from fstrim in the kernel until proven reliable.

To use fstrim with non-Ubuntu 14.04+ distros, you'll need to manually add a cron job. First verify that your SSD supports TRIM.



sudo hdparm -I /dev/sdx | grep TRIM
	

If it does, you will see something like this:



*    Data Set Management TRIM supported (limit 1 block)
	

Create the job script.



gksu gedit /etc/cron.monthly/trim
	

Make the contents:



#!/bin/sh
LOG=/var/log/trim.log
echo "$(date -R)" >> $LOG
/sbin/fstrim / >> $LOG
/sbin/fstrim /home >> $LOG
	

And make the job executable.



sudo chmod +x /etc/cron.monthly/trim
	

Any mount point you want trimmed must be included in the job script. I chose a monthly cron job to allow the disk to fill up more before cleanup which should help with wear leveling. If you fill the disk too quickly or find the cleanup time too obtrusive, use a weekly job.


Mounting as tmpfs

Tmpfs means temporary filesystem. It’s located entirely in RAM but it can still use swap space. This is another area of information deprecation on Linux forums because what is mounted into tmpfs by default has changed over the years so there are a lot of outdated suggestions to stick all kinds of things in tmpfs.

/tmp

One tip which is still useful is to mount /tmp as a temporary filesystem. /tmp is designed as a place of non-persistence between boot sessions but according to one System V developer /tmp should not be binded to /run/shm.

The two main reasons for mounting /tmp in RAM are to speed up file access and to reduce SSD writes. Arch Linux does this by default while Debian and Ubuntu both delete the contents of /tmp on boot (see /etc/default/rcS). Ideally though, contents should be deleted on shutdown so nothing malicious there survives beyond the session. Mounting /tmp as tmpfs accomplishes this.

You don’t need to worry about filling up your RAM either because tmpfs grows in size only as you need it; it does not pre-allocate its full size like a ramdisk. Once tmpfs hits 50% of your system memory, it starts using swap space. If you don’t have a swap area, then the program which needs that RAM will complain. For example, Brasero asks where you want it to put temporary files for DVD burning, but not all applications will be so polite.

Here is the second to last line in the example fstab file above:



tmpfs /tmp tmpfs nosuid,nodev 0 0
	

Mounting /tmp as nosuid,nodev and noexec is a useful security improvement but using noexec will give you problems with apt. Updates will still happen, but apt will give the error, “TMPDIR is mounted noexec, will not cache run scripts.” Same if you manually run update-initramfs. Some packages will not install properly because they rely on scripts executing from /tmp. That is rare but you won’t necessarily know unless you watch the terminal output or go through apt’s logs.

Rather than chance something not updating or installing correctly, there is a fix. You create a file with instructions to unmount /tmp only for updates and remount it with execution ability. After the update, /tmp then remounted as noexec.



gksu gedit /etc/apt/apt.conf.d/99remount-tmpexec
	

The contents should be:



DPkg::Pre-Invoke {"mount -o remount,exec /tmp";};
DPkg::Post-Invoke {"mount -o remount /tmp";};
	

Since /tmp is being unmounted, if you have anything stored there, that data will be lost. Thus if you want to use /tmp with noexec and this apt config file, give thought to your update patterns so you’re not removing temporary files which your applications need at that moment.

/run

The entire /run filesystem tree is already mounted in RAM as tmpfs with /run/shm of course being part of this. The mount options, however, are different. /run/shm is shared memory space, capable of hosting interprocess communication and world-writable by whatever needs it. Not all distros ship using shared memory but Debian and Ubuntu do and we want this to be one less place with ability for execution. By default, Debain mounts /run/shm as noexec but Ubuntu does not. This entry is the last line in my fstab file above.



none /run/shm tmpfs nosuid,nodev,noexec 0 0
	

Notice the line starts with "none", not "tmpfs". That is intentional. On some distros, using the tmpfs label will give you two /run/shm mount points in RAM, one for each label. Obviously only the none mount point will actually be used but we want to to modify the existing mount point, not duplicate it. Use none.

Browser Caches

Browsers can have their caches placed in RAM too, and there are multiple ways to do this. fstab is one way, and a good way, but it looses practicality for computers with many users. fstab can't do wildcards so you would need one line per browser for each user account. Here are some example fstab entries for browser caches:



chrome-cache /home/username/.cache/google-chrome tmpfs noexec,nosuid,nodev,noatime 0 0

chromium-cache /home/username/.cache/chromium tmpfs noexec,nosuid,nodev,noatime 0 0

midori-cache /home/username/.cache/midori/web tmpfs noatime,nodev,noexec,nosuid 0 0
/home/username/.local/share/webkit/databases /home/username/.cache/midori/web none bind 0 0
	

From here, two things:

  1. Midori's local database storage location can be binded to the cache location so they'll both live in tmpfs. That's the second line for Midori above. It's optional.
  2. For Firefox, you're better off going into about:config and creating a parent directory string to relocate the cache.

Other caching options are to use the binary switch for Chromium-based browsers and Arch’s Wiki has several more choices for Firefox & forks.

To start using the browser's tmpfs immediately, you only need to mount it.



sudo mount -l chrome-cache
	


fstab Entries to Avoid

/dev/shm

/dev/shm is mostly deprecated so do not use it. Since Ubuntu 11.10, /dev/shm symlinks to /run/shm which we already covered.

/var/cache

It's expected for this to remain as persistent storage between boots. The data is removed by the programs which use it so don’t use tmpfs here.

/var/lock and /var/run

/var/lock symlinks to /run/lock and /var/run to /run. No need to make them tmpfs because they already are.

/var/log

This is where 99% your operating system’s log files are. I’m all about minimizing disk writes but putting system logs into volatile RAM isn’t the answer. Log files are too important for when you do need to troubleshoot.

/var/tmp

The entire purpose of /var/tmp is a place for temporary data to survive boot sessions, don’t use tmpfs on it.

mode=1777

This is often in guides which mount /tmp as tmpfs. This permissions mode 1777 sets /tmp to 777 and sets the sticky bit so that a file or directory can only be renamed or deleted by its owner, the directory owner or root. Other users can still modify the file’s contents so setting a sticky bit here is not a big security increase.

777 permissions on /tmp is actually a decrease in security because you're loosening default permissions by making /tmp an executable area by any user. Run ls -ld /tmp in a terminal. You’ll see the default permissions as drwxrwxrwt. The t at the end means the sticky bit is already set and notice that there is no x just before it. Any user can read and write to /tmp but only root and users who are members of the appropriate groups can execute there. Chmod 1777 will change that so any user can execute in /tmp—bad for security and unneeded. Don't do it.

nobh

This is deprecated since Ubuntu 11.10.


My Tests

I only used dd for this. For some reason, Gnome’s Disks application refused to work on a mounted drive and I didn't care to investigate. A full disk benchmarking utility like Bonnie++ or ioZone would be more appropriate but I was just looking for basic read and write results. Since one does not simply discuss filesystem tuning without mentioning the disk I/O scheduler, I checked them out too.

The hard drive was a 2.5″ Hitachi Travelstar. It’s a single platter, 5400 RPM drive approaching 3 years in age with a 500 GB capacity and 309 GB available. I left write caching enabled. To measure writes, I made a bash script to run dd every 20 seconds, 10 times total.

Here’s the script's contents. The dd command creates a 524 MB file in your home folder, then shows you the time it took and the average write speed, then it erases the file. For each fstab change and each scheduler, I ran the script once and averaged the results. I put all the raw data and some pretty graphs in an .odt file in the Resources area below.



#!/bin/bash
echo
for run in {1..10}
do
  dd if=/dev/zero of=~/output.img conv=fdatasync bs=10k count=50k; rm ~/output.img

sleep 20

done
	

And just because it’s useful, if you want to see the non-cached read speed of your drive, use:



sudo hdparm -t /dev/sdx
	

Most of my numbers are uneventful. The biggest differences were between I/O schedulers, with Deadline performing the best. Deadline is default in Ubuntu 14.04 but Debian 7 and Ubuntu 12.04 use CFQ.

Everything else showed no consistent increase in speed, nor throughput and there was not even a difference of 1 MB/s for any of the mount option averages. I’ve done other dd write trials when 12.04 was first released, but on different hardware. Nobarrier alone gave me an improvement in the area of 4 MB/s on an older Seagate mechanical drive. Again, it’s all about what your hardware likes and the kind of files you’re working with.

So, I'm sorry for the most anti-climatic write speed comparison in the history of the world, but it’s actually a good thing. My numbers indicate that ext4 in Linux is fast, stable and renders it unnecessary to push the limits of data safety by crowding your fstab with risky mount options.

From here, it’s possible to get creatively complicated by mixing file system types or using rsync and cron to copy certain directories into tmpfs on boot, then mirror that directory back on disk for shutdown. I prefer keeping things simple but the whole point of this writeup is that you have many options so read, experiment and enjoy the fstab.

Share this page.

Resources