The other day I compiled Firefox 3.5-beta4, and, apart from many improvements, I noticed that I am now affected by the infamous ‘hiccups’. Firefox will stall for seconds at a time on my poor netbook. Details on how this relates to the many fsync() calls made by the persistance layer (SQLite) can be found all over the net.
But I don’t want Firefox to stall and I don’t want to keep my harddisk awake with all these writes when I’m on battery power.
Luckily, both these problems go away if you put your Firefox profile on a ramdisk. There are numerous guides out there that save you from working out the details; I used this one from the Gentoo forums.
The guide uses cron to sync the (presumably) modified contents of the ramdisk – bookmarks, cookies, whatever – back to permanent storage (harddisk). You and I both know that while it’s often convenient to use cron, it’s not always the Right Way of Doing Things®. Why sync if nothing’s changed? I wrote a script that employs the inotify system to do the syncing only when necessary. You’ll find it in the forum thread I linked to earlier, but I post it here “ter lering ende vermaeck”. Depending on your browser there might be a vertical scrollbar at the bottom which lets you read up to the EOL’s ;-)
You can find the latest version at my public repo.
#!/bin/bash # Packfox, a tool to facilitate running Firefox with its profile stored # in RAM (tmpfs). Copyright 2008-2009 Wicher Minnaard, wicher@gavagai.eu . # Distributed under the WTFPL, http://smormedia.gavagai.nl/dist/packfox/COPYING # Latest version available at http://smormedia.gavagai.nl/dist/packfox/ # Change this to match your profile PROFILE=$(hostname) PFDIR="${HOME}/.mozilla/firefox" # Tar every .. seconds (regardless of changes) TMOUT="1800" # But not more often than every .. seconds (regardless of changes) TMMIN="60" # Regex for which files not to act on when they're changed. # Use inotifywait -m -e modify -e move -e create -e delete --exclude '(/Cache/)' -r your_profile_dir # and watch the output while browsing to determine which regex will be right for YOU. IEXCL="(.sqlite-journal$)|(\-log.txt$)|(cookies.sqlite$)|(sessionstore\-[0-9].js$)|(/weave/)|(/Cache/)" # Have you read everything and have you made the necessary adjustments? Then remove the line below ;-) echo "I should read the README and adjust the script variables before running this." && exit 2 # No user servicable parts below this line. TGT="${PFDIR}/${PROFILE}" # Global vars INOTYPID="" SLEEPPID="" PACKLOCK="" # Cleanup function terminate(){ # If we are the daemon and we get SIGINTed/SIGTERMed, kill our children # and if not already packing, do one last round of packing. if [ "$(basename ${0})" == "packfox-daemon" ] then if [ -n "${INOTYPID}" ]; then kill ${INOTYPID}; fi if [ -n "${SLEEPPID}" ]; then kill ${SLEEPPID}; fi if [ -z "${PACKLOCK}" ];then packup; fi exit fi } # For cleaning up trap terminate SIGINT SIGTERM # Suicide with goodbye note. If gxmessage is installed, use that. seppuku(){ echo "${1}" 1>&2 which gxmessage > /dev/null 2>&1 && gxmessage -nofocus -title "$(basename ${0})" "${1}" || xmessage "${1}" exit 2 } # Checks and setup test -d "${PFDIR}" || seppuku "Profile dir doesn't exist" if [ -z "$(mount -t tmpfs | grep -F "${TGT}" )" ] then mount "${PFDIR}/${PROFILE}" || seppuku "Mounting of profile's tmpfs failed. Check /etc/fstab and the output of 'dmesg'." fi test -f "${TGT}/.unpacked" || tar -xpf "${PFDIR}/${PROFILE}.packed.tar" -C "${PFDIR}" \ && touch "${TGT}/.unpacked" || seppuku "Error unpacking the profile tarball. You might want to use the backup tarball located in ${PFDIR}." # This tars up the profile packup(){ PACKLOCK="locked" cd "${PFDIR}" tar --exclude '.unpacked' -cpf "${PFDIR}/${PROFILE}.packed.tmp.tar" "${PROFILE}" mv "${PFDIR}/${PROFILE}.packed.tar" "${PFDIR}/${PROFILE}.packed.tar.old" mv "${PFDIR}/${PROFILE}.packed.tmp.tar" "${PFDIR}/${PROFILE}.packed.tar" PACKLOCK="" } # No daemon, just packing if [ "$(basename ${0})" == "packfox" ]; then packup; fi # The daemon loop if [ "$(basename ${0})" == "packfox-daemon" ] then which inotifywait >/dev/null 2>&1 || seppuku " You'll need the 'inotify-tools' package for this script. Get it at http://inotify-tools.sourceforge.net or from your distro's repos". while true do inotifywait -q -q -t ${TMOUT} -e modify -e move -e create -e delete --exclude "${IEXCL}" \ -r "${PFDIR}/${PROFILE}" & INOTYPID=${!} wait ${INOTYPID}; INOTIFYPID="" packup sleep ${TMMIN} & SLEEPPID=${!} wait ${SLEEPPID}; SLEEPPID="" done exit fi
Tags: code, en_GB, firefox, inotify, tmpfs —

