summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@cryptonomic.net>2020-10-29 22:52:19 -0400
committerAndrew Cady <d@cryptonomic.net>2020-10-29 22:52:19 -0400
commit9a884151852eafa00889e414b381b3defbf1be16 (patch)
tree0aea03b819e7a20346ca82ee03a2634a417eae86
parent7730c4915fbeb7121d8dff0bcca7fa9f81846a43 (diff)
btrfs-shrink: support shrinking the .patch.btrfs
-rwxr-xr-xbtrfs-shrink37
1 files changed, 16 insertions, 21 deletions
diff --git a/btrfs-shrink b/btrfs-shrink
index 1d059ff..a9bbee7 100755
--- a/btrfs-shrink
+++ b/btrfs-shrink
@@ -6,7 +6,7 @@ shrink()
6{ 6{
7 local shrinkmegs=100 mountpoint="$1" 7 local shrinkmegs=100 mountpoint="$1"
8 while true; do 8 while true; do
9 while ! btrfs filesystem resize -${shrinkmegs}M "$mountpoint"/; do 9 while ! btrfs filesystem resize "${DEVICE_ID}:-${shrinkmegs}M" "$mountpoint"/; do
10 shrinkmegs=$((shrinkmegs - 10 )) 10 shrinkmegs=$((shrinkmegs - 10 ))
11 if [ $shrinkmegs -lt 10 ]; then 11 if [ $shrinkmegs -lt 10 ]; then
12 return 12 return
@@ -18,47 +18,42 @@ shrink()
18smart_shrink() 18smart_shrink()
19{ 19{
20 local min_dev_size mountpoint="$1" 20 local min_dev_size mountpoint="$1"
21 if min_dev_size=$(btrfs inspect-internal min-dev-size --id 1 "$mountpoint") && [ "$min_dev_size" ] 21 if min_dev_size=$(btrfs inspect-internal min-dev-size --id "$DEVICE_ID" "$mountpoint") && [ "$min_dev_size" ]
22 then 22 then
23 set -- $min_dev_size 23 set -- $min_dev_size
24 [ "$2" = bytes ] || die "Unexpected output from btrfs inspect-internal min-dev-size: '$min_dev_size'" 24 [ "$2" = bytes ] || die "Unexpected output from btrfs inspect-internal min-dev-size: '$min_dev_size'"
25 btrfs filesystem resize "$1" "$mountpoint" && return 25 btrfs filesystem resize "$DEVICE_ID:$1" "$mountpoint" && return
26 fi 26 fi
27 shrink "$mountpoint" 27 shrink "$mountpoint"
28} 28}
29 29
30btrfs_truncate() 30parse_btrfs_dev()
31{
32 local img="$1" bytes
33# 548044800/1176715264 bytes used
34 bytes=$(file "$img" | sed -ne 's?.*/\([0-9]*\) bytes used.*?\1?p')
35 if [ "$bytes" ]; then
36 truncate -s "$bytes" "$img"
37 fi
38}
39
40parse_btrfs_dev_size()
41{ 31{
42 local dev="$1" 32 local dev="$1"
43 sed -n 's?.* size \([0-9]*\) .* path \([^ ]*\)$?\1 \2? p' | 33 sed -n 's?^ devid *\([0-9]*\) size \([0-9]*\) .* path \([^ ]*\)$?\1 \2 \3? p' |
44 while read size name 34 while read devid size name
45 do [ "$name" = "$dev" ] || continue 35 do [ "$name" = "$dev" ] || continue
46 echo $size 36 echo "$devid $size"
47 break 37 break
48 done 38 done
49} 39}
50 40
51get_truncate_size() 41get_btrfs_dev()
52{ 42{
53 local imgfile="$1" mountpoint="$2" loop_dev dev_size 43 local imgfile="$1" mountpoint="$2" loop_dev dev_size
44 losetup -nj "$imgfile" >&2
54 loop_dev=$(losetup -ONAME --raw -nj "$imgfile") 45 loop_dev=$(losetup -ONAME --raw -nj "$imgfile")
55 btrfs fi sh --raw "$mountpoint" | parse_btrfs_dev_size "$loop_dev" 46 ds=$(btrfs fi sh --raw "$mountpoint" | parse_btrfs_dev "$loop_dev")
47 [ "$ds" ] || return
48 DEVICE_ID=${ds% *}
49 DEVICE_SIZE=${ds#* }
56} 50}
57 51
58main() 52main()
59{ 53{
60 [ "$(id -u)" = 0 ] || die 'you are not root' 54 [ "$(id -u)" = 0 ] || die 'you are not root'
61 if [ -d "$1" ]; then 55 if [ -d "$1" ]; then
56 exit 1
62 mountpoint=$1 57 mountpoint=$1
63 mountpoint -q "$mountpoint" || die "not a mountpoint: $1" 58 mountpoint -q "$mountpoint" || die "not a mountpoint: $1"
64 smart_shrink "$mountpoint" 59 smart_shrink "$mountpoint"
@@ -70,11 +65,11 @@ main()
70 result=$? 65 result=$?
71 66
72 if [ $result = 0 ]; then 67 if [ $result = 0 ]; then
73 smart_shrink "$mountpoint" 68 get_btrfs_dev "$1" "$mountpoint" && smart_shrink "$mountpoint"
74 result=$? 69 result=$?
75 if [ $result = 0 ] 70 if [ $result = 0 ]
76 then 71 then
77 truncate=$(get_truncate_size "$1" "$mountpoint") 72 get_btrfs_dev "$1" "$mountpoint" && truncate=$DEVICE_SIZE
78 fi 73 fi
79 umount "$mountpoint" 74 umount "$mountpoint"
80 fi 75 fi