Merge remote-tracking branch 'old/handle-mountpoints' into bind-mounting

Conflicts:
	common/anything-sync-daemon.in
	doc/asd.1
This commit is contained in:
Naughtylus
2016-11-27 18:03:11 +01:00
3 changed files with 70 additions and 69 deletions

View File

@@ -1,5 +1,5 @@
#Anything-sync-daemon
Anything-sync-daemon (asd) is a tiny pseudo-daemon designed to manage user defined dirs in tmpfs and to periodically sync back to the physical disc (HDD/SSD). This is accomplished via a symlinking step and an innovative use of rsync to maintain back-up and synchronization between the two. One of the major design goals of asd is a completely transparent user experience.
Anything-sync-daemon (asd) is a tiny pseudo-daemon designed to manage user defined dirs in tmpfs and to periodically sync back to the physical disc (HDD/SSD). This is accomplished via several bind mounting steps and an innovative use of rsync to maintain back-up and synchronization between the two. One of the major design goals of asd is a completely transparent user experience.
##Documentation
Consult the man page or the wiki page: https://wiki.archlinux.org/index.php/Anything-sync-daemon

View File

@@ -194,10 +194,14 @@ root_check() {
}
ungraceful_state_check() {
# if the machine was ungracefully shutdown then the backup will be
# on the filesystem and the link to tmpfs will be on the filesystem
# but the contents will be empty we need to simply remove the link
# and rotate the backup into place
# if the machine was ungracefully shutdown then the backup folders will
# remain, but the mounts and tmpfs won't.
# This leaves the target directories in the state of the last sync so they're
# usable as is, but data may have been lost. We may not be able to recover
# that data, but at least we can take a snapshot of the current state for the
# record.
# Besides, if using overlayfs technology, we do need to restore from the upper
# directory backup.
local DIR USER BACKUP TMP
for DIR in "${WHATTOSYNC[@]}"; do
# did user define a real dir
@@ -216,48 +220,46 @@ ungraceful_state_check() {
if [[ -e "$TMP"/.flagged ]]; then
# all is well so continue
return
else
elif [[ -d "$BACKUP" ]]; then
NOW=$(date +%Y%m%d_%H%M%S)
if [[ -h "$DIR" ]]; then
echo "Ungraceful state detected for $DIR so fixing"
unlink "$DIR"
fi
echo "Ungraceful state detected for $DIR so fixing"
if [[ -d "$BACKUP" ]]; then
if [[ -d "$BACK_OVFS" ]]; then
# always snapshot the most recent of these two dirs...
# if using overlayfs $BACK_OVFS and $BACKUP should be compared
# against each other to see which is newer and then that should
# be what psd snapshots since BACKUP (the lowerdir) is readonly
# at the time the user started psd could be many resync cycles
# in the past
if [[ -d "$BACK_OVFS" ]]; then
# always snapshot the most recent of these two dirs...
# if using overlayfs $BACK_OVFS and $BACKUP should be compared
# against each other to see which is newer and then that should
# be what asd snapshots since $BACKUP (the lowerdir) is readonly
# at the time the user started asd could be many resync cycles
# in the past
# Because we're using bind mounts, $BACKUP was only reflecting
# the contents of the original $DIR and will be empty
# when recovering from ungraceful state.
# Thus we have to get the contents directly from $DIR
BACKUP_TIME=$(stat "$BACKUP" | grep Change | awk '{ print $2,$3 }')
BACK_OVFS_TIME=$(stat "$BACK_OVFS" | grep Change | awk '{ print $2,$3 }')
BACKUP_TIME=$(stat "$BACKUP" | grep Change | awk '{ print $2,$3 }')
BACK_OVFS_TIME=$(stat "$BACK_OVFS" | grep Change | awk '{ print $2,$3 }')
[[ $(date -d "$BACK_OVFS_TIME" "+%s") -ge $(date -d "$BACKUP_TIME" "+%s") ]] &&
TARGETTOKEEP="$BACK_OVFS" ||
TARGETTOKEEP="$BACKUP"
[[ $(date -d "$BACK_OVFS_TIME" "+%s") -ge $(date -d "$BACKUP_TIME" "+%s") ]] &&
TARGETTOKEEP="$BACK_OVFS" ||
TARGETTOKEEP="$DIR"
if [[ $CRRE -eq 1 ]]; then
opts="-a --reflink=auto"
cp $opts "$TARGETTOKEEP" "$BACKUP-crashrecovery-$NOW"
fi
if [[ $CRRE -eq 1 ]]; then
opts="-a --reflink=auto"
cp $opts "$TARGETTOKEEP" "$BACKUP-crashrecovery-$NOW"
fi
mv --no-target-directory "$TARGETTOKEEP" "$DIR"
rm -rf "$BACKUP"
else
# we only find the BACKUP and no BACKOVFS then either the initial resync
# never occurred before the crash using overlayfs or we aren't using overlayfs
# at all which can be treated the same way
rsync -aogX --delete-after --inplace --no-whole-file --exclude .flagged "$TARGETTOKEEP/" "$DIR/"
else
# we only find the BACKUP and no BACKOVFS then either the initial resync
# never occurred before the crash using overlayfs or we aren't using overlayfs
# at all which can be treated the same way
if [[ $CRRE -eq 1 ]]; then
opts="-a --reflink=auto"
cp $opts "$BACKUP" "$BACKUP-crashrecovery-$NOW"
mv --no-target-directory "$BACKUP" "$DIR"
fi
if [[ $CRRE -eq 1 ]]; then
opts="-a --reflink=auto"
cp $opts "$DIR" "$BACKUP-crashrecovery-$NOW"
fi
fi
rm -rf "$BACKUP"
fi
# if overlayfs was active but is no longer, remove $BACK_OVFS
[[ $OLFS -eq 1 ]] || rm -rf "$BACK_OVFS"
@@ -345,13 +347,6 @@ do_sync() {
fi
fi
# backup target and link to tmpfs container
if [[ $(readlink "$DIR") != "$TMP" ]]; then
mv --no-target-directory "$DIR" "$BACKUP"
ln -s "$TMP" "$DIR"
chown -h "$USER":"$GROUP" "$DIR"
fi
# sync the tmpfs targets to the disc
if [[ -e "$TMP"/.flagged ]]; then
if [[ $OLFS -eq 1 ]]; then
@@ -361,6 +356,11 @@ do_sync() {
fi
else
# initial sync
# bind mounting the target to the backup location
install -dm$PREFIXP --owner="$USER" --group="$GROUP" "$BACKUP"
mount --rbind --make-private "$DIR" "$BACKUP"
if [[ $OLFS -eq 1 ]]; then
if [[ $OLFSVER -eq 23 ]]; then
mount -t overlay overlaid -olowerdir="$BACKUP",upperdir="$UPPER",workdir="$WORK" "$TMP"
@@ -370,6 +370,10 @@ do_sync() {
else
rsync -aogX --inplace --no-whole-file "$BACKUP/" "$TMP/"
fi
# bind mounting the tmpfs dir on top of the target
mount --rbind --make-private "$TMP" "$DIR"
touch "$DIR"/.flagged
fi
fi
@@ -393,22 +397,19 @@ do_unsync() {
UPPER="$VOLATILE/asd-$USER$DIR-rw"
WORK="$VOLATILE/.asd-$USER$DIR"
# remove link and move data from tmpfs to disk
if [[ -h "$DIR" ]]; then
unlink "$DIR"
# this assumes that the backup is always
# updated so be sure to invoke a sync before an unsync
# restore original dirtree
[[ -d "$BACKUP" ]] && mv --no-target-directory "$BACKUP" "$DIR"
if [[ $OLFS -eq 1 ]] && mountpoint -q "$TMP"; then
rsync -aogX --delete-after --inplace --no-whole-file --exclude .flagged "$BACK_OVFS/" "$DIR/"
umount -l "$TMP"
rm -rf "$VOLATILE/asd-$USER" "$VOLATILE/asd-$USER-rw" "$VOLATILE/.asd-$USER" &>/dev/null
else
[[ -d "$TMP" ]] && rm -rf "$VOLATILE/asd-$USER"
fi
# unmounting everything and deleting tmpfs
# this assumes that the backup is up to date so be sure to invoke a sync
# before an unsync
umount -l "$DIR"
if [[ $OLFS -eq 1 ]] && mountpoint -q "$TMP"; then
rsync -aogX --delete-after --inplace --no-whole-file --exclude .flagged "$BACK_OVFS/" "$DIR/"
umount -l "$TMP"
rm -rf "$VOLATILE/asd-$USER" "$VOLATILE/asd-$USER-rw" "$VOLATILE/.asd-$USER" &>/dev/null
else
[[ -d "$TMP" ]] && rm -rf "$VOLATILE/asd-$USER"
fi
umount -l "$BACKUP"
rmdir "$BACKUP"
done
echo -e "${BLD}Unsync successful${NRM}"
}
@@ -535,16 +536,16 @@ case "$1" in
echo -e " ${BLD}Instead, use systemd to start/stop anything-sync-daemon.${NRM}"
echo
echo -e " ${BLD}systemctl ${NRM}${GRN}[option]${NRM}${BLD} asd asd-resync${NRM}"
echo -e " ${BLD} ${NRM}${GRN}start${NRM}${BLD} Turn on daemon; make symlinks and actively manage targets in tmpfs.${NRM}"
echo -e " ${BLD} ${NRM}${GRN}stop${NRM}${BLD} Turn off daemon; remove symlinks and rotate tmpfs data back to disc.${NRM}"
echo -e " ${BLD} ${NRM}${GRN}start${NRM}${BLD} Turn on daemon; make bind mounts and actively manage targets in tmpfs.${NRM}"
echo -e " ${BLD} ${NRM}${GRN}stop${NRM}${BLD} Turn off daemon; undo bind mounts and rotate tmpfs data back to disc.${NRM}"
echo -e " ${BLD} ${NRM}${GRN}enable${NRM}${BLD} Autostart daemon when system comes up.${NRM}"
echo -e " ${BLD} ${NRM}${GRN}disable${NRM}${BLD} Remove daemon from the list of autostart daemons.${NRM}"
elif [[ -f /etc/init.d/asd ]]; then
echo -e " ${BLD}Instead, use the init system to start/stop anything-sync-daemon.${NRM}"
echo
echo -e " ${BLD}sudo service asd ${NRM}${GRN}[option]${NRM}${BLD} or /etc/init.d/asd ${NRM}${GRN}[option]${NRM}"
echo -e " ${BLD} ${NRM}${GRN}start${NRM}${BLD} Turn on daemon; make symlinks and actively manage targets in tmpfs.${NRM}"
echo -e " ${BLD} ${NRM}${GRN}stop${NRM}${BLD} Turn off daemon; remove symlinks and rotate tmpfs data back to disc.${NRM}"
echo -e " ${BLD} ${NRM}${GRN}start${NRM}${BLD} Turn on daemon; make bind mounts and actively manage targets in tmpfs.${NRM}"
echo -e " ${BLD} ${NRM}${GRN}stop${NRM}${BLD} Turn off daemon; undo bind mounts and rotate tmpfs data back to disc.${NRM}"
fi
;;
esac

View File

@@ -1,10 +1,10 @@
.\" Text automatically generated by txt2man
.TH anything-sync-daemon 1 "26 November 2016" "" ""
.SH NAME
\fBanything-sync-daemon \fP- Symlinks and syncs user specified dirs to RAM thus reducing HDD/SDD calls and speeding-up the system.
\fBanything-sync-daemon \fP- Bind mounts and syncs user specified dirs to RAM thus reducing HDD/SDD calls and speeding-up the system.
\fB
.SH DESCRIPTION
Anything-sync-daemon (asd) is a tiny pseudo-daemon designed to manage user specified directories referred to as sync targets from here on out, in tmpfs and to periodically sync them back to the physical disc (HDD/SSD). This is accomplished via a symlinking step and an innovative use of rsync to maintain synchronization between a tmpfs copy and media-bound backups. Additionally, asd features several crash-recovery features.
Anything-sync-daemon (asd) is a tiny pseudo-daemon designed to manage user specified directories referred to as sync targets from here on out, in tmpfs and to periodically sync them back to the physical disc (HDD/SSD). This is accomplished via several bind mounting steps and an innovative use of rsync to maintain synchronization between a tmpfs copy and media-bound backups. Additionally, asd features several crash recovery features.
.PP
Design goals of asd:
.RS
@@ -150,9 +150,9 @@ Q2: Why do I see another directory ".foo-back-ovfs" when I enable overlayfs?
.PP
A2: The way overlayfs works is to mount a read-only base copy (so-called lower dir) of the target, and manage the new data on top of that. In order to avoid resyncing to the read-only file system, a copy is used instead. So using overlayfs is a trade off: faster initial sync times and less memory usage vs. disk space.
.PP
Q3: My system crashed and asd didn't sync back. What do I do?
Q3: What happens to my data when my system crashes?
.PP
A3: The "last good" backup of your sync targets is just fine still sitting happily on your filesystem. Upon restarting asd (on a reboot for example), a check is preformed to see if the symlink to the tmpfs copy of your sync target is valid. If it is invalid, asd will snapshot the "last good" backup before it rotates it back into place. This is more for a sanity check that asd did no harm and that any data loss was a function of something else.
A3: While the different bind mounts that asd performs allow for your targets to sit entirely and seemlessly on your RAM, they also make sure that the original directory that's still on your HDD gets synced regularly. So in case of power failure or system crash, you will find your data in the state that it has been last synced to. Upon restarting asd (on a reboot for example), a check is performed to see if asd has been interrupted abruptly. If it's the case, a snapshot of the "last good" state of your directories is taken, before syncing everything back into place. This is more for a sanity check that asd did no harm and that any data loss was a function of something else.
.PP
Q4: Where can I find this snapshot?
.PP
@@ -165,7 +165,7 @@ A5: Follow these steps:
.IP 1. 4
Stop asd.
.IP 2. 4
Confirm that there is no symlink to the sync target. If there is, asd did not stop correctly for other reasons.
Confirm that there are no un-date-time-stamped hidden backup directory (e.g. ".foo-backup_asd" or ".foo-back-ovfs"). If there are, asd did not stop correctly for other reasons.
.IP 3. 4
Move the "bad" copy of the sync taget to a backup (don't blindly delete anything).
.IP 4. 4