diff --git a/README.md b/README.md index 8497224..3f4d58c 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ See [raspberrypi/linux@cef3970381](https://github.com/raspberrypi/linux/commit/c 1. [Install](#install) - [Manually start or stop](#manually-start-or-stop) + - [Sync files to disk](#sync-files-to-disk) 2. [Update](#update) 3. [Uninstall](#uninstall) 4. [Configure](#customize) @@ -59,6 +60,19 @@ sudo ./zram-config/install.bash Use `sudo systemctl {start|stop} zram-config.service` to start or stop zram-config. This will ensure that any changes are properly synced to the persistent storage before system poweroff. +#### Sync files to disk + +Run `sudo zram-config sync` to sync any changes in the zram filesystems managed by zram-config to persistent storage. +If you have concerns about losing data due to sudden power loss you could use this to ensure that changes are synced to disk periodically. + +A default sync service that will sync files to disk every night can be installed by running the following. + +``` shell +sudo /path/to/zram-config/install.bash sync +``` + +Note that this sync service is not installed by default, you must install it separately. + ### Update ``` shell diff --git a/install.bash b/install.bash index c4f6ce8..d0b882f 100755 --- a/install.bash +++ b/install.bash @@ -6,6 +6,13 @@ if [[ "$(id -u)" -ne 0 ]]; then echo "ERROR: You need to be ROOT (sudo can be used)." exit 1 fi +if [[ $1 == "sync" ]]; then + install -m 644 "$BASEDIR"/zsync.* /etc/systemd/system/ + systemctl daemon-reload + systemctl enable --now zsync.timer + echo "##### zsync service is now installed #####" + exit 0 +fi if [[ $(systemctl is-active zram-config.service) == "active" ]]; then echo -e "ERROR: zram-config service is still running.\\nPlease run \"sudo ${BASEDIR}/update.bash\" to update zram-config instead." exit 1 diff --git a/uninstall.bash b/uninstall.bash index 10b22e6..9ed2727 100755 --- a/uninstall.bash +++ b/uninstall.bash @@ -15,6 +15,10 @@ zram-config "stop" tar -cf "${BASEDIR}/logs.tar" --directory=/usr/local/share/zram-config log systemctl disable zram-config.service rm -f /etc/systemd/system/zram-config.service +if [[ -f /etc/systemd/system/zsync.timer ]]; then + systemctl disable zsync.timer + rm -f /etc/systemd/system/zsync.* +fi sed -i '\|^ReadWritePaths=/usr/local/share/zram-config/log$|d' /lib/systemd/system/logrotate.service systemctl daemon-reload rm -f /usr/local/sbin/zram-config diff --git a/zram-config b/zram-config index 8a4af74..e803a3b 100755 --- a/zram-config +++ b/zram-config @@ -160,6 +160,23 @@ removeZswap() { echo "removeZswap: Device /dev$ZRAM_DEV removed." >> "$ZLOG" } +syncZdir() { + echo "syncZdir: Beginning sync of device /dev${ZRAM_DEV}." >> "$ZLOG" + + [[ -z $TARGET_DIR ]] && return 1 + if ! (umount --verbose "${TARGET_DIR}/" >> "$ZLOG" 2>&1); then + [[ -x $(command -v lsof) ]] && lsof "${TARGET_DIR}/" >> "$ZLOG" 2>&1 + umount --verbose --lazy "${TARGET_DIR}/" >> "$ZLOG" 2>&1 || return 1 + fi + + mergeOverlay >> "$ZLOG" 2>&1 || return 1 + + mkdir -p "${ZDIR}${ZRAM_DEV}/upper" "${ZDIR}${ZRAM_DEV}/workdir" "$TARGET_DIR" >> "$ZLOG" 2>&1 || return 1 + mount --verbose --types overlay -o "redirect_dir=on,lowerdir=${ZDIR}${BIND_DIR},upperdir=${ZDIR}${ZRAM_DEV}/upper,workdir=${ZDIR}${ZRAM_DEV}/workdir" "overlay${ZRAM_DEV//[!0-9]/}" "$TARGET_DIR" >> "$ZLOG" 2>&1 || return 1 + + echo "syncZdir: Device /dev$ZRAM_DEV synced." >> "$ZLOG" +} + serviceConfiguration() { if [[ $1 == "stop" ]]; then echo "Stopping services that interfere with zram device configuration." >> "$ZLOG" @@ -292,8 +309,42 @@ case "$1" in rm -fv "$TMPDIR"/zram-device-list.rev "$TMPDIR"/zram-device-list >> "$ZLOG" ;; + sync) + echo "zram-config sync $(date +%Y-%m-%d-%H:%M:%S)" | tee -a "$ZLOG" + tac "$TMPDIR"/zram-device-list > "$TMPDIR"/zram-device-list.rev + while read -r line; do + case "$line" in + "#"*) + # Skip comment line + continue + ;; + + "") + # Skip empty line + continue + ;; + + *) + # shellcheck disable=SC2086 + set -- $line + echo "ztab sync ${1} ${2} ${3} ${4}" >> "$ZLOG" + case "$1" in + dir|log) + ZRAM_DEV="$2" + TARGET_DIR="$3" + BIND_DIR="$4" + [[ -z $SERVICE ]] && serviceConfiguration "stop" + syncZdir + ;; + esac + ;; + esac + done < "$TMPDIR"/zram-device-list.rev + rm -fv "$TMPDIR"/zram-device-list.rev >> "$ZLOG" + ;; + *) - echo "Usage: zram-config {start|stop}" + echo "Usage: zram-config {start|stop|sync}" exit 0 ;; esac diff --git a/zsync.service b/zsync.service new file mode 100644 index 0000000..18c59f9 --- /dev/null +++ b/zsync.service @@ -0,0 +1,8 @@ +[Unit] +Description=Perform nightly zram sync to persistent storage +After=zram-config.service +Wants=zsync.timer + +[Service] +Type=oneshot +ExecStart=/usr/local/sbin/zram-config "sync" diff --git a/zsync.timer b/zsync.timer new file mode 100644 index 0000000..2fe12fa --- /dev/null +++ b/zsync.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Perform nightly zram sync to persistent storage + +[Timer] +Unit=zsync.service +OnCalendar=*-*-* 00:55 +RandomizedDelaySec=10m +Persistent=true + +[Install] +WantedBy=timers.target