summaryrefslogtreecommitdiff
path: root/src/btrfs-utils/btarfs
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2017-03-29 22:50:05 -0400
committerAndrew Cady <d@jerkface.net>2017-03-29 22:50:30 -0400
commitb30a2be0105bae41479e518711364a4ae21fbcbd (patch)
tree857c96f118541671d2ad18572bc54491818e53f6 /src/btrfs-utils/btarfs
parent0ec9e1b2b1f4c08d8588f9cfe01712c34a6eb8ab (diff)
split btrfs-shrink out of btarfs
Diffstat (limited to 'src/btrfs-utils/btarfs')
-rwxr-xr-xsrc/btrfs-utils/btarfs105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/btrfs-utils/btarfs b/src/btrfs-utils/btarfs
new file mode 100755
index 0000000..a51b2ef
--- /dev/null
+++ b/src/btrfs-utils/btarfs
@@ -0,0 +1,105 @@
1#!/bin/sh
2
3die() { printf "%s: Error: %s\n" "$0" "$*" >&2; exit 1; }
4
5[ "$(id -u)" = 0 ] || die 'you are not root'
6
7TEMP="$(getopt -o 'f:vcxz' --long size:,file:,create,extract,gzip,gunzip,ungzip -n "$0" -- "$@")" ||
8 die 'getopt error'
9eval set -- "$TEMP"
10
11MIN_BYTES=$((128 * 1024 * 1024))
12
13FILE=
14MODE=
15ZIP=y
16BYTES=$((256 * 1024 * 1024))
17while [ $# -gt 0 ]; do
18 case "$1" in
19 --size)
20 BYTES=$(( $2 * 1024 * 1024))
21 [ "$BYTES" -ge "$MIN_BYTES" ] || die "invalid size (too small or not a number)"
22 SIZE="$2"
23 shift 2 ;;
24 -f|--file)
25 [ "$FILE" ] && die "only one archive file can be specified"
26 FILE="$2"
27 shift 2 ;;
28 -c|--create)
29 [ "$MODE" ] && die "incompatible modes"
30 MODE=create
31 shift ;;
32 -x|--extract)
33 [ "$MODE" ] && die "incompatible modes"
34 MODE=extract
35 shift ;;
36 -v)
37 VERBOSE=y
38 shift ;;
39 -z|--gzip|--gunzip|--ungzip)
40 ZIP=y
41 shift ;;
42 --)
43 shift; break;;
44 *) die 'getopt error';;
45 esac
46done
47[ "$FILE" ] || die "you must specify a file (this is not tar, there is no stdout)"
48
49create()
50{
51 TMPFILE=$(dirname "$FILE")/.~.$(basename "$FILE")
52# [ ! -e "$FILE" ] || die "refusing to overwrite '$FILE'"
53# [ ! -e "$TMPFILE" ] || die "refusing to overwrite '.~.$FILE'"
54 rm -f "$TMPFILE"
55 fallocate -l "$BYTES" "$TMPFILE"
56 mountpoint=$(mktemp -d) || die
57 trap 'umount "$mountpoint"; rmdir "$mountpoint"; rm "$TMPFILE"' EXIT
58 mkfs.btrfs "$TMPFILE" || die
59 mount -o ${ZIP:+compress,}loop "$TMPFILE" "$mountpoint" || die
60 rsync -a ${VERBOSE:+ -i} "$@" "$mountpoint" || die
61
62 shrink "$mountpoint"
63 umount "$mountpoint" || die
64 btrfs_truncate "$TMPFILE"
65
66 rmdir "$mountpoint"
67 btrfstune -S1 "$TMPFILE" || die
68 mv "$TMPFILE" "$FILE"
69 trap '' EXIT
70}
71
72btrfs_truncate()
73{
74 local img="$1" bytes
75 bytes=$(file "$img" | sed -ne 's?.*/\([0-9]*\) bytes used.*?\1?p')
76 if [ "$bytes" ]; then
77 truncate -s "$bytes" "$img"
78 fi
79}
80
81
82get_k()
83{
84 local mountpoint="$1" kilos
85 kilos=$(btrfs fi usage -k "$mountpoint"|sed -ne 's/[\t ]*Device size:[\t ]*//p')
86 case "$kilos" in
87 *.00KiB) echo "${kilos%.00KiB}";;
88 *) return 1;;
89 esac
90}
91
92shrink()
93{
94 shrinkmegs=100
95 while true; do
96 while ! btrfs filesystem resize -${shrinkmegs}M "$mountpoint"/; do
97 shrinkmegs=$((shrinkmegs - 10 ))
98 if [ $shrinkmegs -lt 10 ]; then
99 return
100 fi
101 done
102 done
103}
104
105$MODE "$@"