#!/bin/bash . /etc/rc.conf . /etc/rc.d/functions [ -f /etc/conf.d/readonly-root ] && . /etc/conf.d/readonly-root [ "z${ETCTMPFS}" = "z" ] && ETCTMPFS="/etc/.readonly-root.tmpfs" [ "z${ETCTMPFS_SIZE}" = "z" ] && ETCTMPFS_SIZE="1M" case "$1" in start) stat_busy "Remounting / Read-Only" ck_daemon readonly-root if [ $? -eq 1 ]; then stat_append ": Read-only / already set up" stat_fail exit fi grep -q aufs /proc/filesystems if [ $? -ne 0 ]; then modprobe aufs if [ $? -ne 0 ]; then stat_append ": Unable to load aufs module" stat_fail exit fi fi if [ -e $ETCTMPFS ]; then if [ ! -d $ETCTMPFS ]; then stat_append ": Mountpoint $ETCTMPFS exists and is not a directory" stat_fail exit fi else mkdir -p $ETCTMPFS if [ $? -ne 0 ]; then stat_busy "Unable to create tmpfs mountpoint $ETCTMPFS" stat_fail exit fi fi mount -t tmpfs -o size=${ETCTMPFS_SIZE} tmpfs $ETCTMPFS if [ $? -ne 0 ]; then stat_busy "Unable to mount tmpfs on $ETCTMPFS" stat_fail exit fi mount -n -o remount,ro / if [ $? -ne 0 ]; then stat_busy "Unable to remount / read-only" stat_fail umount ${ETCTMPFS} exit fi # NOTE: aufs mount won't appear in mtab, but we don't really need # it to as long as mounting / unmounting always handled by # this script mount -n -t aufs -o noplink,br=${ETCTMPFS}=rw:/etc=rr none /etc if [ $? -ne 0 ]; then stat_busy "Unable to mount aufs on /etc" stat_fail mount -n -o remount,rw / umount ${ETCTMPFS} exit fi # make mtab entry for / say ro mount -f -o remount,ro / # NOTE: aufs mount won't appear in mtab, but we don't really need # it to as long as mounting / unmounting always handled by # this script # --> however, if/when aufs supports mount's -f option, can # uncomment the following line to get it to appear in mtab # mount -f -t aufs -o noplink,br=${ETCTMPFS}=rw:/etc=rr none /etc add_daemon readonly-root stat_done ;; stop) stat_busy "Remounting / Read-Write" ck_daemon readonly-root if [ $? -eq 0 ]; then stat_append ": Read-only / not set up" stat_fail exit fi umount -n -t aufs /etc if [ $? -ne 0 ]; then stat_busy "Unable to unmount aufs on /etc" stat_fail exit fi mount -n -o remount,rw / mv ${ETCTMPFS}/mtab /etc/mtab # make mtab entry for / say rw mount -f -o remount,rw / # get rid of the stale unionfs mtab entry # --> currently not needed, see NOTE above # umount -t aufs /etc 2>/dev/null umount $ETCTMPFS rm_daemon readonly-root stat_done ;; restart) $0 stop $0 start ;; *) echo "usage: $0 {start|stop|restart}" esac