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 runsystemctl 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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
RAMDISK_SIZE="256m" | |
MOUNT_POINT="/mnt/ramdisk" | |
USER=root | |
GROUP=root | |
PERMISSIONS=775 | |
PRE_STOP_SCRIPT="/usr/local/bin/stop_ramdisk.sh" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 $? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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 |