parent
46c8f5a9b4
commit
d30d814f74
|
@ -7,15 +7,32 @@ module_load path
|
||||||
# NOTE: set this for sudo
|
# NOTE: set this for sudo
|
||||||
# ALL ALL = (root) NOPASSWD:/bin/btrfs
|
# ALL ALL = (root) NOPASSWD:/bin/btrfs
|
||||||
|
|
||||||
is_subvol () {
|
is_subv () {
|
||||||
if [[ $1 == "-r" ]]; then
|
if [[ $1 == "-r" ]]; then
|
||||||
if ! btrfs subvolume show "$2" 2> /dev/null | grep readonly &> /dev/null; then return 1; fi
|
if ! btrfs subvolume show "$2" 2> /dev/null | grep readonly &> /dev/null; then return 1; fi
|
||||||
else
|
else
|
||||||
btrfs subvolume show "$1" &> /dev/null
|
return $(btrfs subvolume show "$1" &> /dev/null)
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
make_subvol() {
|
|
||||||
|
is_subvv () {
|
||||||
|
if [[ $1 == "-r" ]]; then
|
||||||
|
if ! btrfs subvolume show "$2" 2> /dev/null | grep readonly &> /dev/null; then
|
||||||
|
echo not a readonly subvolume
|
||||||
|
else
|
||||||
|
echo readonly subvoluem
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if btrfs subvolume show "$1" &> /dev/null; then
|
||||||
|
echo subvolume
|
||||||
|
else
|
||||||
|
echo not a subvolume
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
subv_make() {
|
||||||
local usesudo
|
local usesudo
|
||||||
local uid
|
local uid
|
||||||
local gid
|
local gid
|
||||||
|
@ -29,7 +46,7 @@ make_subvol() {
|
||||||
$usesudo chown "$uid":"$gid" "$1"
|
$usesudo chown "$uid":"$gid" "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
del_subvol() {
|
subv_del() {
|
||||||
local usesudo; local delete
|
local usesudo; local delete
|
||||||
[[ $1 == "-d" ]] && delete=true && shift
|
[[ $1 == "-d" ]] && delete=true && shift
|
||||||
[[ $EUID -ne 0 ]] && usesudo=sudo
|
[[ $EUID -ne 0 ]] && usesudo=sudo
|
||||||
|
@ -49,29 +66,30 @@ del_subvol() {
|
||||||
# BTRFSDATAROOT=${BTRFSDATAROOT:-/mnt/data}
|
# BTRFSDATAROOT=${BTRFSDATAROOT:-/mnt/data}
|
||||||
# # cd $BTRFSDATAROOT || exit
|
# # cd $BTRFSDATAROOT || exit
|
||||||
# for svol in $svols; do
|
# for svol in $svols; do
|
||||||
# make_subvol $BTRFSDATAROOT/$svol $@
|
# subv_make $BTRFSDATAROOT/$svol $@
|
||||||
# done
|
# done
|
||||||
# }
|
# }
|
||||||
|
|
||||||
#ssudo mount -o subvol=opt /dev/sda4 /test
|
#ssudo mount -o subvol=opt /dev/sda4 /test
|
||||||
|
|
||||||
snapshot_restore () {
|
# FIXME: use subv_xfer
|
||||||
local src=$1
|
# snapshot_restore () {
|
||||||
local dest=$2
|
# local src=$1
|
||||||
local name=${3:-$(echo "$src"| rev | cut -f 2- -d '.' | rev)}
|
# local dest=$2
|
||||||
local usesudo
|
# local name=${3:-$(echo "$src"| rev | cut -f 2- -d '.' | rev)}
|
||||||
echo copying "$src" at "$PWD" to "$2" then renaming to "$name"
|
# local usesudo
|
||||||
# TODO check for snapshot, strip volume from source path, remove extra snapshot when done
|
# echo copying "$src" at "$PWD" to "$2" then renaming to "$name"
|
||||||
[[ $EUID -ne 0 ]] && usesudo=sudo
|
# # TODO check for snapshot, strip volume from source path, remove extra snapshot when done
|
||||||
$usesudo "$BTRFS_BIN" send "$src" | $usesudo "$BTRFS_BIN" -q receive "$dest"
|
# [[ $EUID -ne 0 ]] && usesudo=sudo
|
||||||
# cd $2 || return
|
# $usesudo "$BTRFS_BIN" send "$src" | $usesudo "$BTRFS_BIN" -q receive "$dest"
|
||||||
$usesudo "$BTRFS_BIN" subvolume snapshot "$dest"/"$src" "$dest"/"$name"
|
# # cd $2 || return
|
||||||
# todo check for snapshot then delete transfered one
|
# $usesudo "$BTRFS_BIN" subvolume snapshot "$dest"/"$src" "$dest"/"$name"
|
||||||
}
|
# # todo check for snapshot then delete transfered one
|
||||||
|
# }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
subvolume_size () {
|
subv_size () {
|
||||||
local all;
|
local all;
|
||||||
[[ $1 == "-a" ]] && all=true
|
[[ $1 == "-a" ]] && all=true
|
||||||
if [[ $all ]]; then
|
if [[ $all ]]; then
|
||||||
|
@ -132,11 +150,11 @@ folder_snapshot() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
snapshot_send() {
|
subv_xfer() {
|
||||||
|
|
||||||
# Show usage and exit with status
|
# Show usage and exit with status
|
||||||
help () {
|
help () {
|
||||||
echo 'usage: snapshot_send -h,-r <source_path, full or relative> <destination_parent_dir> <optional, alternate directory name>'
|
echo 'usage: subv_xfer -h,-r <source_path, full or relative> <destination_parent_dir> <optional, alternate directory name>'
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ $1 == "-h" ]]; then help; return; fi
|
if [[ $1 == "-h" ]]; then help; return; fi
|
||||||
|
@ -151,7 +169,7 @@ snapshot_send() {
|
||||||
if [[ $# -lt 2 ]]; then help; return 1; fi
|
if [[ $# -lt 2 ]]; then help; return 1; fi
|
||||||
|
|
||||||
# Check for directories
|
# Check for directories
|
||||||
if ! is_subvol "$1"; then
|
if ! is_subv "$1"; then
|
||||||
echo source "$1" not a subvolume
|
echo source "$1" not a subvolume
|
||||||
help
|
help
|
||||||
return 2
|
return 2
|
||||||
|
@ -173,7 +191,7 @@ snapshot_send() {
|
||||||
[[ $3 ]] && ext=".$3"
|
[[ $3 ]] && ext=".$3"
|
||||||
|
|
||||||
local tsnap
|
local tsnap
|
||||||
if ! is_subvol -r "$src"; then
|
if ! is_subv -r "$src"; then
|
||||||
tsnap=$psrc/$name.tmp
|
tsnap=$psrc/$name.tmp
|
||||||
$dr sudo "$BTRFS_BIN" sub snap -r "$src" "$tsnap"
|
$dr sudo "$BTRFS_BIN" sub snap -r "$src" "$tsnap"
|
||||||
fi
|
fi
|
||||||
|
@ -182,18 +200,26 @@ snapshot_send() {
|
||||||
echo "sudo $BTRFS_BIN send $([[ $tsnap ]] && echo "$tsnap" || echo "$src") | btrfs receive $dest"
|
echo "sudo $BTRFS_BIN send $([[ $tsnap ]] && echo "$tsnap" || echo "$src") | btrfs receive $dest"
|
||||||
echo "sudo mv $dest/$name.tmp $dest/$name$ext"
|
echo "sudo mv $dest/$name.tmp $dest/$name$ext"
|
||||||
echo "[[ ""$tsnap"" ]] && sudo $BTRFS_BIN sub del $tsnap"
|
echo "[[ ""$tsnap"" ]] && sudo $BTRFS_BIN sub del $tsnap"
|
||||||
|
echo "sudo ""$BTRFS_BIN"" sub snap $dest/$name.tmp $dest/$name$ext"
|
||||||
|
echo "sudo ""$BTRFS_BIN"" sub del $dest/$name.tmp"
|
||||||
else
|
else
|
||||||
sudo "$BTRFS_BIN" send $([[ $tsnap ]] && echo "$tsnap" || echo "$src") | btrfs receive "$dest"
|
sudo "$BTRFS_BIN" send $([[ $tsnap ]] && echo "$tsnap" || echo "$src") | btrfs receive "$dest"
|
||||||
sudo mv "$dest"/"$name".tmp "$dest"/"$name"$ext
|
# FIXME: take a snapshot of the destination .tmp then remove .tmp, otherwise it will be readonly
|
||||||
[[ "$tsnap" ]] && sudo "$BTRFS_BIN" sub del "$tsnap"
|
# sudo mv "$dest"/"$name".tmp "$dest"/"$name"$ext
|
||||||
|
if is_subv -r "$dest"/"$name".tmp; then
|
||||||
|
sudo "$BTRFS_BIN" sub snap "$dest"/"$name".tmp "$dest"/"$name""$ext"
|
||||||
|
sudo "$BTRFS_BIN" sub del "$dest"/"$name".tmp
|
||||||
echo transfer is complete
|
echo transfer is complete
|
||||||
|
fi
|
||||||
|
[[ "$tsnap" ]] && sudo "$BTRFS_BIN" sub del "$tsnap"
|
||||||
|
|
||||||
ls -la "$dest"
|
ls -la "$dest"
|
||||||
ls -la "$dest"/"$name"$ext
|
ls -la "$dest"/"$name""$ext"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mount_subvolume () {
|
subv_mount () {
|
||||||
# echo sudo mount $1 -o subvol=$2 $3
|
# echo sudo mount $1 -o subvol=$2 $3
|
||||||
if mountpoint "$3" &> /dev/null; then
|
if mountpoint "$3" &> /dev/null; then
|
||||||
echo "$3" already a mountpoint, aborting subvolume mount
|
echo "$3" already a mountpoint, aborting subvolume mount
|
||||||
|
@ -230,7 +256,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
# finds device and subvolume of a mountpoint (or a mountpoint above the given path)
|
# finds device and subvolume of a mountpoint (or a mountpoint above the given path)
|
||||||
mp_subvol () {
|
subv_mp () {
|
||||||
module_load filesystem
|
module_load filesystem
|
||||||
local mp; local subvol
|
local mp; local subvol
|
||||||
mp=$(find_mountpoint "$1")
|
mp=$(find_mountpoint "$1")
|
||||||
|
@ -257,10 +283,10 @@ btrfs_clone () {
|
||||||
$usesudo umount /tmp/source &> /dev/null
|
$usesudo umount /tmp/source &> /dev/null
|
||||||
sudo mount "$src" /tmp/source
|
sudo mount "$src" /tmp/source
|
||||||
# $usesudo umount /tmp/dest &> /dev/null
|
# $usesudo umount /tmp/dest &> /dev/null
|
||||||
# if mount_subvolume $src $subvol /tmp/source; then
|
# if subv_mount $src $subvol /tmp/source; then
|
||||||
if ! make_subvol "$dest"/$(basename "$subvol") &> /dev/null; then echo unable to make subvolume "$1" at "$dest"; return 2; fi
|
if ! subv_make "$dest"/$(basename "$subvol") &> /dev/null; then echo unable to make subvolume "$1" at "$dest"; return 2; fi
|
||||||
# $usesudo btrfs subvolume show $dest/$(basename $subvol)
|
# $usesudo btrfs subvolume show $dest/$(basename $subvol)
|
||||||
# if mount_subvolume $(mp_subvol $dest/$(basename $subvol)) /tmp/dest; then
|
# if subv_mount $(subv_mp $dest/$(basename $subvol)) /tmp/dest; then
|
||||||
# echo cloning now
|
# echo cloning now
|
||||||
# # echo $usesudo btrfs-clone --toplevel $dr -v /tmp/source /tmp/dest
|
# # echo $usesudo btrfs-clone --toplevel $dr -v /tmp/source /tmp/dest
|
||||||
cmd="$usesudo btrbk $dr archive /tmp/source/$1 $dest/$1"
|
cmd="$usesudo btrbk $dr archive /tmp/source/$1 $dest/$1"
|
||||||
|
@ -293,29 +319,61 @@ alias btsub="sudo $BTRFS_BIN subvolume"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dir2subvol () {
|
dir2subv () {
|
||||||
# Directory to convert into BTRFS subvolume
|
# Directory to convert into BTRFS subvolume
|
||||||
|
|
||||||
|
|
||||||
dirPath="$1"
|
dirPath="$1"
|
||||||
|
if [[ ! -d $dirPath ]]; then echo no directory at "$dirPath"; return 1; fi
|
||||||
|
dirSub="$2"
|
||||||
|
perms=/tmp/perms_$(basename "$dirPath")
|
||||||
|
|
||||||
getfacl -R "$dirPath" > /tmp/_perms
|
|
||||||
|
|
||||||
# Rename original dierctory
|
if is_subv "$dirPath"; then echo "$dirPath" is already a subvolume, exiting; return 0; fi
|
||||||
sudo mv "${dirPath}" "${dirPath}_original"
|
|
||||||
|
|
||||||
# Create btrfs subvolume
|
if ! confirm transform "$dirPath" into a subvolume at "${dirSub:-$dirPath}"; then return 1; fi
|
||||||
sudo "$BTRFS_BIN" subvolume create "${dirPath}"
|
|
||||||
|
|
||||||
# Copy as "reflink" for speed and save space
|
pushd "$dirPath" &> /dev/null || return
|
||||||
sudo cp --archive --one-file-system --reflink=always \
|
echo saving permissions at "$PWD" to "$perms"
|
||||||
"${dirPath}_original/." "${dirPath}"
|
getfacl -R . | sudo tee "$perms"
|
||||||
|
cat "$perms"
|
||||||
|
|
||||||
# Remove old directory
|
if [[ ! $dirSub ]]; then
|
||||||
sudo rm -rf --one-file-system "${dirPath}_original"
|
echo moving "$dirPath" to "${dirPath}_temp"
|
||||||
|
sudo mv "${dirPath}" "${dirPath}_temp"
|
||||||
|
fi
|
||||||
|
|
||||||
setfacl --restore=/tmp/_perms
|
echo creating subvolume at "${dirSub:-$dirPath}"
|
||||||
|
sudo "$BTRFS_BIN" subvolume create "${dirSub:-$dirPath}"
|
||||||
|
|
||||||
rm -f /tmp/_perms
|
# Copy as reflink for speed and save space
|
||||||
|
if [[ $dirSub ]]; then
|
||||||
|
echo copying "$dirPath" to "$dirSub"
|
||||||
|
sudo cp --archive --one-file-system --reflink=always "${dirPath}/." "${dirSub}"
|
||||||
|
pushd "$dirSub" &> /dev/null || return 1
|
||||||
|
else
|
||||||
|
echo copying "${dirPath}"_temp back to subvolume at "$dirPath"
|
||||||
|
sudo cp --archive --one-file-system --reflink=always "${dirPath}_temp/." "${dirPath}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# echo for debugging changing permissions at "$PWD"
|
||||||
|
# sudo chmod -R 777 .
|
||||||
|
# sudo chown -R nobody:nobody .
|
||||||
|
# ls -la .
|
||||||
|
# echo "---------------------"
|
||||||
|
|
||||||
|
echo restore saved permissions to "$perms"
|
||||||
|
sudo setfacl --restore="$perms"
|
||||||
|
sudo rm -f "$perms"
|
||||||
|
|
||||||
|
echo "$dirPath" has been converted into a subvolume at "${dirSub:-$dirPath}"
|
||||||
|
if [[ -d ${dirPath}_temp ]];then
|
||||||
|
if confirm -s do you want to now delete the copy at "${dirPath}"_temp; then
|
||||||
|
sudo rm -rf --one-file-system "${dirPath}_temp"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
popd &> /dev/null || return 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue