13 March 2017

I run some servers that use a ramdisk to increase performance for recording audio files. Since ramdisks evaporate on a reboot, and I have services that depend on the ramdisk to operate properly, I needed a way to:

  • Automatically create the ramdisk on boot
  • Ensure it’s set up prior to the services that depend on it
  • Perform cleanup on the ramdisk when the server is shut down

The set of scripts below accomplish this nicely by leveraging systemd. Here’s a quick rundown of what each does:

  • ramdisk: The script is written as a System V init script, and would be placed at /etc/init/ramdisk. Does the work of:
    • Creating the ramdisk
    • Calling an optionally configured script to perform cleanup prior to tearing down the ramdisk
  • customize: This is an optional file to override the default settings of the first script. Place it at /etc/default/ramdisk with any customizations you like.
  • ramdisk.service: systemd service file that calls the start/stop functions of ramdisk. Place this anywhere systemd recognizes service scripts, and run systemctl daemon-reload.

The nice thing about this setup through systemd is that any other systemd services that depend on the ramdisk being set up can simply include this in their service description:

Requires=ramdisk.service
After=ramdisk.service

true

#!/bin/sh
RAMDISK_SIZE="256m"
MOUNT_POINT="/mnt/ramdisk"
USER=root
GROUP=root
PERMISSIONS=775
PRE_STOP_SCRIPT="/usr/local/bin/stop_ramdisk.sh"
view raw customize hosted with ❤ by GitHub
#!/bin/sh
# kFreeBSD do not accept scripts as interpreters, using #!/bin/sh and sourcing.
if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
fi
### BEGIN INIT INFO
# Provides: ramdisk
# Required-Start: $local_fs $syslog
# Required-Stop: $local_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Creates a filesystem and mounts a RAMDISK
# Description: Creates a filesystem and mounts a RAMDISK.
### END INIT INFO
# Author: Chad Phillips <chad@apartmentlines.com>
RAMDISK_SIZE="64m"
MOUNT_POINT=""
OWNER=root
GROUP=root
PERMISSIONS=755
PRE_STOP_SCRIPT=""
RETVAL=0
if [ -f /etc/default/ramdisk ]; then
. /etc/default/ramdisk
fi
start() {
# Exit if already mounted.
check_status
if [ "$?" = "0" ]; then
echo "tmpfs is already mounted on $MOUNT_POINT"
exit 0
fi
if [ -n "$MOUNT_POINT" ] && [ -d $MOUNT_POINT ]; then
log_daemon_msg "Mounting tmpfs on $MOUNT_POINT" "ramdisk\n"
mount -t tmpfs -osize=${RAMDISK_SIZE} tmpfs $MOUNT_POINT
RETVAL=$?
if [ "$RETVAL" = "0" ]; then
log_daemon_msg "Setting owner $OWNER, group $GROUP, permissions $PERMISSIONS" "ramdisk\n"
chown ${OWNER}:${GROUP} $MOUNT_POINT && chmod $PERMISSIONS $MOUNT_POINT
RETVAL=$?
if [ "$RETVAL" != "0" ]; then
log_failure_msg "Could not set ownership/permissions on $MOUNT_POINT\n"
exit 1
fi
else
log_failure_msg "Could not mount $MOUNT_POINT\n"
exit 1
fi
else
log_failure_msg "$MOUNT_POINT is not a valid directory\n"
exit 1
fi
return $RETVAL
}
stop() {
# Exit if already unmounted.
check_status
if [ "$?" = "7" ]; then
echo "tmpfs is already unmounted from $MOUNT_POINT"
exit 0
fi
if [ -n "$PRE_STOP_SCRIPT" ] && [ -x $PRE_STOP_SCRIPT ]; then
log_daemon_msg "Running pre-stop script ${PRE_STOP_SCRIPT} for tmpfs on ${MOUNT_POINT}" "ramdisk\n"
$PRE_STOP_SCRIPT
fi
# Unmount ramdisk.
log_daemon_msg "Unmounting tmpfs on ${MOUNT_POINT}" "ramdisk\n"
umount $MOUNT_POINT
if [ "$RETVAL" != "0" ]; then
log_failure_msg "Could not unmount $MOUNT_POINT\n"
fi
RETVAL=$?
return $RETVAL
}
status() {
check_status
if [ "$?" = "0" ]; then
echo "tmpfs mounted at $MOUNT_POINT"
else
echo "tmpfs not mounted at $MOUNT_POINT"
fi
return 0
}
check_status() {
if [ "`mount | grep tmpfs | grep $MOUNT_POINT`" = "" ]; then
return 7
else
return 0
fi
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop;
start;
;;
status)
status
;;
*)
echo "Usage: ramdisk {start|stop|restart|status}"
exit 1
esac
exit $?
view raw ramdisk hosted with ❤ by GitHub
[Unit]
Description=ramdisk
After=syslog.target local-fs.target remote-fs.target
[Service]
Type=oneshot
ExecStart=/etc/init.d/ramdisk start
ExecStop=/etc/init.d/ramdisk stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
; vi: ft=dosini
view raw ramdisk.service hosted with ❤ by GitHub