My SSD optimizations


In order to minimize writes to the SSD, I followed this and other guides and modified my fstab as shown (with my changes being bold):

# / was on /dev/sda2 during installation
UUID=xxa / ext4 errors=remount-ro,relatime,discard 0 1
# /boot was on /dev/sda1 during installation
UUID=xxb /boot ext4 defaults,relatime,discard 0 2
# swap was on /dev/sda3 during installation
UUID=xxc none swap sw,discard 0 0
# uses memory for tmp directories
tmpfs /tmp tmpfs defaults,relatime,mode=1777 0 0
 none /var/cache aufs dirs=/tmp:/var/cache=ro 0 0

I also added the following from http://ubuntuforums.org/showthread.php?t=1183113 to the end of /etc/sysctl.conf:

vm.swappiness=1 # Strongly discourage swapping
vm.vfs_cache_pressure=50 # Don't shrink the inode cache aggressively

Making /var/log a ramdisk causes a few services to have problems starting when they cannot access the log directories that were installed with the packages (since they disappear within a tmpfs each boot). So we need to make sure that the contents is saved at shutdown and restored at boot. This guide is the best approach for me. It saves the contents outside of /var/log, then restores it right after mounting /var/log as tmpfs. Additionally, each hour the contents of /var/log is saved in order to not lose as much in the event of a crash. Here is the script I used:

#!/bin/sh
### BEGIN INIT INFO
# Provides: transientlog
# X-Start-Before: $syslog
# X-Stop-After: $syslog
# X-Interactive: yes
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Keeps /var/log in RAM
# Description: Moves the contents of /var/log to RAM during boot
# and keeps it there until shutdown/reboot, when it
# copies the contents back to permanent storage.
### END INIT INFO

# Version 1.0
# Author: Matteo Cortese <[email protected]>
#
# Inspired by ramlog by Jan Andrejkovic.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=transientlog
DESC="Transient log directory"
LOCKFILE=/var/lock/$NAME.lock
VARLOG=/var/log
SIZE=16M
MODE=0755

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

if [ -z "$VARLOGPERM" ]; then
var=`dirname $VARLOG`
log=`basename $VARLOG`
VARLOGPERM="$var/permanent$log"
unset var log
fi
do_start()
{
# Return
# 0 if transient log has been started
# 1 if transient log was already running
# 2 if transient log could not be started

[ -f $LOCKFILE ] && return 1

# Check if I'm root
[ `id -u` -eq 0 ] || return 2

# If VARLOG does not exist?
[ -d $VARLOG ] || return 2

# VARLOGPERM either does not exist (first invocation)
# or is empty (left from previous invocation).
#
[ -d $VARLOGPERM ] || mkdir -p $VARLOGPERM || return 2

# Mount a tmpfs over VARLOG.
# The mount will shadow the current contents of VARLOG.
# So, before, make a bind mount so that looking into VARLOGPERM
# we'll see the current contents of VARLOG, which
# will not be available anymore as soon as we mount
# a tmpfs over it.
#
mount --bind $VARLOG $VARLOGPERM
mount -t tmpfs -o nosuid,noexec,nodev,mode=$MODE,size=$SIZE $NAME $VARLOG
if [ $? -eq 0 ]; then
# Populate the tmpfs
if cp -rfp $VARLOGPERM -T $VARLOG; then
# Success!
touch $LOCKFILE
return 0
fi

# Something went wrong...

# Rollback the mount
umount -l $VARLOG
fi

# Rollback the directory mangling
umount $VARLOGPERM

return 2
}

do_stop() {
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred

[ -f $LOCKFILE ] || return 1

# Check if I am root
[ `id -u` -eq 0 ] || return 2

# Merge back to permanent storage
cp -rfup $VARLOG -T $VARLOGPERM

# The following cannot fail... or can it?
umount -l $VARLOG
umount -l $VARLOGPERM
rm -f $LOCKFILE
return 0
}

do_reload() {
# Return
# 0 if transient log has been reloaded
# 1 if transient log was not running
# 2 if transient log could not be reloaded

[ -f $LOCKFILE ] || return 1

# Check if I am root
[ `id -u` -eq 0 ] || return 2

# Merge back to permanent storage
cp -rfup $VARLOG -T $VARLOGPERM
touch $LOCKFILE
return 0
}

 

 

case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
if [ -f $LOCKFILE ]; then
echo "$DESC is running"
else
echo "$DESC is stopped"
exit 1
fi
;;
reload)
log_daemon_msg "Reloading $DESC" "$NAME"
do_reload
log_end_msg $?
;;
*)
echo "Usage: $0 {start|stop|status|reload}" >&2
exit 3
;;
esac

You save that to /etc/init.d/transientlog then:

sudo chmod a+x /etc/init.d/transientlog
sudo update-rc.d transientlog start 00 2 3 4 5 . stop 99 0 1 6 .

Additionally, add a script into /etc/cron.daily/transientlog_reload with the following, then make it executible:

#!/bin/sh

[ -x /etc/init.d/transientlog ] || exit 0
[ -f /var/lock/transientlog.lock ] || exit 0
/etc/init.d/transientlog reload

Then reboot to start using tmpfs for the /var/log/.

Leave a Reply

Your email address will not be published.