From 01948f97d109ede85471cd678a75e870cb725a44 Mon Sep 17 00:00:00 2001 From: Ethan Dye Date: Mon, 7 Feb 2022 12:10:37 -0700 Subject: [PATCH 1/3] Allow sync to persistent storage Using the same merge functionality in overlayfs-tools already used to write changes to persistent storage it is possible to write changes to disk without completely reseting the zram device. This allows for a quick sync to persistent storage to be run whenever desired. Without the ability to sync, any changes made to the underlying filesystem will be lost if there was a sudden power loss or system shutdown. This can be mitigated by periodically running the sync command which will write the changes to persistent storage ensuring that the data will not be lost if anything goes wrong. A default service that runs the sync every night is included in this change, however, it is not installed by default. Fixes #72 Signed-off-by: Ethan Dye --- README.md | 14 +++++++++++++ install.bash | 8 ++++++++ uninstall.bash | 4 ++++ zram-config | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- zsync.service | 8 ++++++++ zsync.timer | 11 +++++++++++ 6 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 zsync.service create mode 100644 zsync.timer 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..702bb22 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 @@ -15,6 +22,7 @@ if [[ -f /usr/local/sbin/zram-config ]]; then exit 1 fi + if ! dpkg -s 'gcc' 'make' 'libc6-dev' &> /dev/null; then echo "Installing needed packages (gcc, make, libc6-dev)" apt-get install --yes gcc make libc6-dev || exit 1 diff --git a/uninstall.bash b/uninstall.bash index 10b22e6..c124661 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/zync.timer ]]; then + systemctl disable zsync.timer + rm -f /etc/systemd/system/zync.* +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 From 63ade04858dcaa697c4d68fa34ef6fcd3d266374 Mon Sep 17 00:00:00 2001 From: Ethan Dye Date: Mon, 7 Feb 2022 12:21:36 -0700 Subject: [PATCH 2/3] Remove extraneous blank line Signed-off-by: Ethan Dye --- install.bash | 1 - 1 file changed, 1 deletion(-) diff --git a/install.bash b/install.bash index 702bb22..d0b882f 100755 --- a/install.bash +++ b/install.bash @@ -22,7 +22,6 @@ if [[ -f /usr/local/sbin/zram-config ]]; then exit 1 fi - if ! dpkg -s 'gcc' 'make' 'libc6-dev' &> /dev/null; then echo "Installing needed packages (gcc, make, libc6-dev)" apt-get install --yes gcc make libc6-dev || exit 1 From 0d61491e9d09393c6bf34db8aa92462d05dca370 Mon Sep 17 00:00:00 2001 From: Ethan Dye Date: Mon, 7 Feb 2022 12:22:24 -0700 Subject: [PATCH 3/3] Fix spelling of zsync Signed-off-by: Ethan Dye --- uninstall.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uninstall.bash b/uninstall.bash index c124661..9ed2727 100755 --- a/uninstall.bash +++ b/uninstall.bash @@ -15,9 +15,9 @@ 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/zync.timer ]]; then +if [[ -f /etc/systemd/system/zsync.timer ]]; then systemctl disable zsync.timer - rm -f /etc/systemd/system/zync.* + 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