summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rwxr-xr-xsrc/btarfs105
2 files changed, 106 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 6489f43..bcf851b 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ prefix?=/usr/local
2 2
3all: samizdat-paths.sh 3all: samizdat-paths.sh
4 4
5bin_programs=$(addprefix src/, xorriso-usb.sh btrfs-functions.sh btrfs-receive-root.sh btrfs-send-root.sh var.sh grub-efi.sh keygen.sh initrd.sh qemu.sh) samizdat-paths.sh 5bin_programs=$(addprefix src/, xorriso-usb.sh btrfs-functions.sh btrfs-receive-root.sh btrfs-send-root.sh var.sh grub-efi.sh keygen.sh initrd.sh qemu.sh btarfs) samizdat-paths.sh
6 6
7# TODO: compile these here 7# TODO: compile these here
8samizdat_execs=$(addprefix /home/d/src/samizdat/, wait_for_files samizdat-pinentry dynmenu src/samizdat-password-agent src/samizdat-gpg-agent) 8samizdat_execs=$(addprefix /home/d/src/samizdat/, wait_for_files samizdat-pinentry dynmenu src/samizdat-password-agent src/samizdat-gpg-agent)
diff --git a/src/btarfs b/src/btarfs
new file mode 100755
index 0000000..bdd44de
--- /dev/null
+++ b/src/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=.~."$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 "$@"