Implemented automatic toplevel mounting
snapsh now checks if the toplevel subvolume is mounted at the path defined in TOPLEVEL, and if not, does it automatically.
This commit is contained in:
parent
d003820acb
commit
a13cba3790
99
snapsh
99
snapsh
|
@ -42,27 +42,40 @@ snapsh [OPTIONS]
|
||||||
Options:
|
Options:
|
||||||
-h, --help Display this help message
|
-h, --help Display this help message
|
||||||
-s SUBVOL, --snapshot SUBVOL Take a snapshot of subvolume named SUBVOL.
|
-s SUBVOL, --snapshot SUBVOL Take a snapshot of subvolume named SUBVOL.
|
||||||
-d STR, --description STR Add a description for the snapshot displayed in the
|
-d STR, --description STR Add a description for the snapshot displayed
|
||||||
snapshots listing.
|
in the snapshots listing.
|
||||||
-t TYPE, --type TYPE Set the type of snapshot, where TYPE=manual|auto|boot|backup
|
-t TYPE, --type TYPE Set the type of snapshot, where
|
||||||
Can be used with -l, --list to filter results
|
TYPE=manual|auto|boot|backup
|
||||||
|
Can be used with --list to filter results
|
||||||
-l, --list List snapshots
|
-l, --list List snapshots
|
||||||
-r NUMBER, --remove NUMBER Remove snapshot NUMBER. See snapshot numbers with
|
-r NUMBER, --remove NUMBER Remove snapshot NUMBER. See snapshot numbers
|
||||||
snapsh -l
|
with snapsh -l
|
||||||
--rollback NUMBER Roll back to snapshot NUMBER. See snapshot numbers
|
--rollback NUMBER Roll back to snapshot NUMBER. See snapshot
|
||||||
with snapsh -l. Target subvolume is detected from
|
numbers with snapsh -l. Target subvolume is
|
||||||
snapshot automatically.\n"
|
detected from snapshot automatically.\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mount_check() {
|
||||||
|
|
||||||
|
# Check that the toplevel subvolume (id=5) is mounted, and if not,
|
||||||
|
# mount it to path defined in $TOPLEVEL
|
||||||
|
|
||||||
snapshot() {
|
mount | grep subvolid=5 | grep "${TOPLEVEL}" > /dev/null
|
||||||
|
if [[ "$?" -ne 0 ]]; then
|
||||||
|
# Get the UUID of the current btrfs volume
|
||||||
|
MOUNT_UUID=$(btrfs filesystem show | grep uuid | cut -d ':' -f 3)
|
||||||
|
# Create the mountpoint for the toplevel if needed
|
||||||
|
[[ -d ${TOPLEVEL} ]] || mkdir -p ${TOPLEVEL}
|
||||||
|
# Mount the toplevel
|
||||||
|
mount -U ${MOUNT_UUID} -o subvolid=5 ${TOPLEVEL}
|
||||||
|
fi
|
||||||
|
|
||||||
EXIT_CODE=0
|
if [[ -n ${SNAPSHOT} ]]; then
|
||||||
root_check #Check that script is run with root privileges.
|
# If taking a snapshot,
|
||||||
|
# check that the subvolume storing snapshots exists and if not, ask
|
||||||
# Check that the subvolume storing snapshots exists
|
# to create it.
|
||||||
if [[ ! -d ${SNAPSHOTS_LOCATION} ]]; then
|
${BTRFS_EXECUTABLE} subvolume show ${SNAPSHOTS_LOCATION} > /dev/null
|
||||||
|
if [[ "$?" -ne 0 ]]; then
|
||||||
printf "Subvolume ${SNAPSHOTS_LOCATION} does not exist. Create it now?\n"
|
printf "Subvolume ${SNAPSHOTS_LOCATION} does not exist. Create it now?\n"
|
||||||
read -n 1 -p "y/n: "
|
read -n 1 -p "y/n: "
|
||||||
|
|
||||||
|
@ -71,15 +84,38 @@ snapshot() {
|
||||||
${BTRFS_EXECUTABLE} subvolume create ${SNAPSHOTS_LOCATION}
|
${BTRFS_EXECUTABLE} subvolume create ${SNAPSHOTS_LOCATION}
|
||||||
unset ${REPLY}
|
unset ${REPLY}
|
||||||
else
|
else
|
||||||
EXIT_CODE=1
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
# Otherwise, just check that the subvolume in SNAPSHOTS_LOCATION
|
||||||
|
# exists, and notify if not.
|
||||||
|
${BTRFS_EXECUTABLE} subvolume show ${SNAPSHOTS_LOCATION} > /dev/null
|
||||||
|
if [[ "$?" -ne 0 ]]; then
|
||||||
|
printf "Subvolume ${SNAPSHOTS_LOCATION} does not exist.\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
snapshot() {
|
||||||
|
|
||||||
|
EXIT_CODE=0
|
||||||
|
root_check #Check that script is run with root privileges.
|
||||||
|
mount_check #Check that the toplevel subvolume is mounted
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TYPE defaults to manual
|
# TYPE defaults to manual
|
||||||
if [[ -z "${SET_TYPE}" ]]; then
|
if [[ -z "${SET_TYPE}" ]]; then
|
||||||
SET_TYPE="manual"
|
SET_TYPE="manual"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf "Creating snapshot of subvolume ${SUBVOLUME} as ${SUBVOLUME}_snapshot_${TIMESTAMP}\n"
|
printf "Creating snapshot of subvolume ${SUBVOLUME} as \
|
||||||
|
${SUBVOLUME}_snapshot_${TIMESTAMP}\n"
|
||||||
|
|
||||||
# Create info file for listing snapshots
|
# Create info file for listing snapshots
|
||||||
# Created first on the source subvolume, then deleted from the source
|
# Created first on the source subvolume, then deleted from the source
|
||||||
|
@ -89,7 +125,10 @@ snapshot() {
|
||||||
TYPE=\"${SET_TYPE}\"\n" > ${TOPLEVEL}/${SUBVOLUME}/.snapsh
|
TYPE=\"${SET_TYPE}\"\n" > ${TOPLEVEL}/${SUBVOLUME}/.snapsh
|
||||||
|
|
||||||
# Create readonly subvolume
|
# Create readonly subvolume
|
||||||
${BTRFS_EXECUTABLE} subvolume snapshot -r ${TOPLEVEL}/${SUBVOLUME} ${SNAPSHOTS_LOCATION}/${SUBVOLUME}_snapshot_${TIMESTAMP}
|
${BTRFS_EXECUTABLE} subvolume snapshot -r ${TOPLEVEL}/${SUBVOLUME} \
|
||||||
|
${SNAPSHOTS_LOCATION}/${SUBVOLUME}_snapshot_${TIMESTAMP}
|
||||||
|
|
||||||
|
let EXIT_CODE=${EXIT_CODE}+$?
|
||||||
|
|
||||||
# Delete info file from source
|
# Delete info file from source
|
||||||
rm -f ${TOPLEVEL}/${SUBVOLUME}/.snapsh
|
rm -f ${TOPLEVEL}/${SUBVOLUME}/.snapsh
|
||||||
|
@ -101,7 +140,6 @@ snapshot() {
|
||||||
DESCRIPTION=${DESCRIPTION}
|
DESCRIPTION=${DESCRIPTION}
|
||||||
TYPE=\"${SET_TYPE}\"\n"
|
TYPE=\"${SET_TYPE}\"\n"
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit ${EXIT_CODE}
|
exit ${EXIT_CODE}
|
||||||
}
|
}
|
||||||
|
@ -110,6 +148,8 @@ snapshot() {
|
||||||
|
|
||||||
list() {
|
list() {
|
||||||
root_check
|
root_check
|
||||||
|
mount_check
|
||||||
|
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
NUM=1
|
NUM=1
|
||||||
SNAPSHOTS=(${SNAPSHOTS_LOCATION}/*/)
|
SNAPSHOTS=(${SNAPSHOTS_LOCATION}/*/)
|
||||||
|
@ -117,14 +157,18 @@ list() {
|
||||||
printf "No snapshots found in ${SNAPSHOTS_LOCATION}.\n"
|
printf "No snapshots found in ${SNAPSHOTS_LOCATION}.\n"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
printf "%6s %s %s %26s %s %s %6s %s %s\n" "Number" "|" "Time:" "|" "Source" "|" "Type" "|" "Description"
|
printf "%6s %s %s %26s %10s %s %6s %s %s\n" "Number" "|" "Time:" "|" \
|
||||||
|
"Source" "|" "Type" "|" "Description"
|
||||||
for snapshot in ${SNAPSHOTS[@]}; do
|
for snapshot in ${SNAPSHOTS[@]}; do
|
||||||
if [[ -z "${SET_TYPE}" ]]; then
|
if [[ -z "${SET_TYPE}" ]]; then
|
||||||
. ${snapshot}/.snapsh
|
. ${snapshot}/.snapsh
|
||||||
printf "%8s %32s %8s %8s %s\n" "${NUM} |" "${DATE} |" "${SOURCE_SUBVOLUME} |" "${TYPE} |" "${DESCRIPTION}"
|
printf "%8s %32s %12s %8s %s\n" "${NUM} |" "${DATE} |" \
|
||||||
|
"${SOURCE_SUBVOLUME} |" "${TYPE} |" "${DESCRIPTION}"
|
||||||
elif [[ -n "${SET_TYPE}" ]]; then
|
elif [[ -n "${SET_TYPE}" ]]; then
|
||||||
. ${snapshot}/.snapsh
|
. ${snapshot}/.snapsh
|
||||||
[[ "${SET_TYPE}" == "${TYPE}" ]] && printf "%8s %32s %8s %8s %s\n" "${NUM} |" "${DATE} |" "${SOURCE_SUBVOLUME} |" "${TYPE} |" "${DESCRIPTION}"
|
[[ "${SET_TYPE}" == "${TYPE}" ]] && printf "%8s %32s %12s %8s %s\n" \
|
||||||
|
"${NUM} |" "${DATE} |" "${SOURCE_SUBVOLUME} |" "${TYPE} |" \
|
||||||
|
"${DESCRIPTION}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
let NUM=NUM+1
|
let NUM=NUM+1
|
||||||
|
@ -136,6 +180,7 @@ list() {
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
root_check
|
root_check
|
||||||
|
mount_check
|
||||||
|
|
||||||
# List snapshots in to array SNAPSHOTS
|
# List snapshots in to array SNAPSHOTS
|
||||||
SNAPSHOTS=(${SNAPSHOTS_LOCATION}/*/)
|
SNAPSHOTS=(${SNAPSHOTS_LOCATION}/*/)
|
||||||
|
@ -170,6 +215,8 @@ remove() {
|
||||||
|
|
||||||
rollback() {
|
rollback() {
|
||||||
root_check # Check root privileges
|
root_check # Check root privileges
|
||||||
|
mount_check # Check that the toplevel subvolume is mounted
|
||||||
|
|
||||||
SNAPSHOTS=(${SNAPSHOTS_LOCATION}/*/) # List snapshots to array
|
SNAPSHOTS=(${SNAPSHOTS_LOCATION}/*/) # List snapshots to array
|
||||||
|
|
||||||
# Check that NUBER to roll back to is a valid snapshot
|
# Check that NUBER to roll back to is a valid snapshot
|
||||||
|
@ -302,7 +349,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
# Options parsing:
|
# Options parsing:
|
||||||
OPTIONS=$(getopt -a -n snapsh -o hs:d:lr:t: --long help,snapshot:,description:,list,remove:,rollback:,type:,post-rollback -- "$@")
|
OPTIONS=$(getopt -a -n snapsh -o hs:d:lr:t: --long help,snapshot:,description:,list,remove:,rollback:,type:,post-rollback,mount -- "$@")
|
||||||
|
|
||||||
# Invalid options (getopt returns nonzero)
|
# Invalid options (getopt returns nonzero)
|
||||||
if [[ "$?" -ne 0 ]]; then
|
if [[ "$?" -ne 0 ]]; then
|
||||||
|
@ -373,6 +420,12 @@ while true; do
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
--mount)
|
||||||
|
mount_check
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
|
||||||
--)
|
--)
|
||||||
shift
|
shift
|
||||||
break
|
break
|
||||||
|
|
Loading…
Reference in New Issue