mirror of
https://github.com/graysky2/anything-sync-daemon.git
synced 2026-03-01 18:23:30 +01:00
Merge remote-tracking branch 'old/handle-mountpoints' into bind-mounting
Conflicts: common/anything-sync-daemon.in doc/asd.1
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
10
doc/asd.1
10
doc/asd.1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user