From b30a2be0105bae41479e518711364a4ae21fbcbd Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Wed, 29 Mar 2017 22:50:05 -0400 Subject: split btrfs-shrink out of btarfs --- src/btarfs | 105 ---------------------------------------- src/btrfs-utils/btarfs | 105 ++++++++++++++++++++++++++++++++++++++++ src/btrfs-utils/btrfs-shrink | 52 ++++++++++++++++++++ src/btrfs-utils/with-btrfs-seed | 99 +++++++++++++++++++++++++++++++++++++ src/with-btrfs-seed | 98 ------------------------------------- 5 files changed, 256 insertions(+), 203 deletions(-) delete mode 100755 src/btarfs create mode 100755 src/btrfs-utils/btarfs create mode 100755 src/btrfs-utils/btrfs-shrink create mode 100755 src/btrfs-utils/with-btrfs-seed delete mode 100755 src/with-btrfs-seed (limited to 'src') diff --git a/src/btarfs b/src/btarfs deleted file mode 100755 index a51b2ef..0000000 --- a/src/btarfs +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/sh - -die() { printf "%s: Error: %s\n" "$0" "$*" >&2; exit 1; } - -[ "$(id -u)" = 0 ] || die 'you are not root' - -TEMP="$(getopt -o 'f:vcxz' --long size:,file:,create,extract,gzip,gunzip,ungzip -n "$0" -- "$@")" || - die 'getopt error' -eval set -- "$TEMP" - -MIN_BYTES=$((128 * 1024 * 1024)) - -FILE= -MODE= -ZIP=y -BYTES=$((256 * 1024 * 1024)) -while [ $# -gt 0 ]; do - case "$1" in - --size) - BYTES=$(( $2 * 1024 * 1024)) - [ "$BYTES" -ge "$MIN_BYTES" ] || die "invalid size (too small or not a number)" - SIZE="$2" - shift 2 ;; - -f|--file) - [ "$FILE" ] && die "only one archive file can be specified" - FILE="$2" - shift 2 ;; - -c|--create) - [ "$MODE" ] && die "incompatible modes" - MODE=create - shift ;; - -x|--extract) - [ "$MODE" ] && die "incompatible modes" - MODE=extract - shift ;; - -v) - VERBOSE=y - shift ;; - -z|--gzip|--gunzip|--ungzip) - ZIP=y - shift ;; - --) - shift; break;; - *) die 'getopt error';; - esac -done -[ "$FILE" ] || die "you must specify a file (this is not tar, there is no stdout)" - -create() -{ - TMPFILE=$(dirname "$FILE")/.~.$(basename "$FILE") -# [ ! -e "$FILE" ] || die "refusing to overwrite '$FILE'" -# [ ! -e "$TMPFILE" ] || die "refusing to overwrite '.~.$FILE'" - rm -f "$TMPFILE" - fallocate -l "$BYTES" "$TMPFILE" - mountpoint=$(mktemp -d) || die - trap 'umount "$mountpoint"; rmdir "$mountpoint"; rm "$TMPFILE"' EXIT - mkfs.btrfs "$TMPFILE" || die - mount -o ${ZIP:+compress,}loop "$TMPFILE" "$mountpoint" || die - rsync -a ${VERBOSE:+ -i} "$@" "$mountpoint" || die - - shrink "$mountpoint" - umount "$mountpoint" || die - btrfs_truncate "$TMPFILE" - - rmdir "$mountpoint" - btrfstune -S1 "$TMPFILE" || die - mv "$TMPFILE" "$FILE" - trap '' EXIT -} - -btrfs_truncate() -{ - local img="$1" bytes - bytes=$(file "$img" | sed -ne 's?.*/\([0-9]*\) bytes used.*?\1?p') - if [ "$bytes" ]; then - truncate -s "$bytes" "$img" - fi -} - - -get_k() -{ - local mountpoint="$1" kilos - kilos=$(btrfs fi usage -k "$mountpoint"|sed -ne 's/[\t ]*Device size:[\t ]*//p') - case "$kilos" in - *.00KiB) echo "${kilos%.00KiB}";; - *) return 1;; - esac -} - -shrink() -{ - shrinkmegs=100 - while true; do - while ! btrfs filesystem resize -${shrinkmegs}M "$mountpoint"/; do - shrinkmegs=$((shrinkmegs - 10 )) - if [ $shrinkmegs -lt 10 ]; then - return - fi - done - done -} - -$MODE "$@" 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 @@ +#!/bin/sh + +die() { printf "%s: Error: %s\n" "$0" "$*" >&2; exit 1; } + +[ "$(id -u)" = 0 ] || die 'you are not root' + +TEMP="$(getopt -o 'f:vcxz' --long size:,file:,create,extract,gzip,gunzip,ungzip -n "$0" -- "$@")" || + die 'getopt error' +eval set -- "$TEMP" + +MIN_BYTES=$((128 * 1024 * 1024)) + +FILE= +MODE= +ZIP=y +BYTES=$((256 * 1024 * 1024)) +while [ $# -gt 0 ]; do + case "$1" in + --size) + BYTES=$(( $2 * 1024 * 1024)) + [ "$BYTES" -ge "$MIN_BYTES" ] || die "invalid size (too small or not a number)" + SIZE="$2" + shift 2 ;; + -f|--file) + [ "$FILE" ] && die "only one archive file can be specified" + FILE="$2" + shift 2 ;; + -c|--create) + [ "$MODE" ] && die "incompatible modes" + MODE=create + shift ;; + -x|--extract) + [ "$MODE" ] && die "incompatible modes" + MODE=extract + shift ;; + -v) + VERBOSE=y + shift ;; + -z|--gzip|--gunzip|--ungzip) + ZIP=y + shift ;; + --) + shift; break;; + *) die 'getopt error';; + esac +done +[ "$FILE" ] || die "you must specify a file (this is not tar, there is no stdout)" + +create() +{ + TMPFILE=$(dirname "$FILE")/.~.$(basename "$FILE") +# [ ! -e "$FILE" ] || die "refusing to overwrite '$FILE'" +# [ ! -e "$TMPFILE" ] || die "refusing to overwrite '.~.$FILE'" + rm -f "$TMPFILE" + fallocate -l "$BYTES" "$TMPFILE" + mountpoint=$(mktemp -d) || die + trap 'umount "$mountpoint"; rmdir "$mountpoint"; rm "$TMPFILE"' EXIT + mkfs.btrfs "$TMPFILE" || die + mount -o ${ZIP:+compress,}loop "$TMPFILE" "$mountpoint" || die + rsync -a ${VERBOSE:+ -i} "$@" "$mountpoint" || die + + shrink "$mountpoint" + umount "$mountpoint" || die + btrfs_truncate "$TMPFILE" + + rmdir "$mountpoint" + btrfstune -S1 "$TMPFILE" || die + mv "$TMPFILE" "$FILE" + trap '' EXIT +} + +btrfs_truncate() +{ + local img="$1" bytes + bytes=$(file "$img" | sed -ne 's?.*/\([0-9]*\) bytes used.*?\1?p') + if [ "$bytes" ]; then + truncate -s "$bytes" "$img" + fi +} + + +get_k() +{ + local mountpoint="$1" kilos + kilos=$(btrfs fi usage -k "$mountpoint"|sed -ne 's/[\t ]*Device size:[\t ]*//p') + case "$kilos" in + *.00KiB) echo "${kilos%.00KiB}";; + *) return 1;; + esac +} + +shrink() +{ + shrinkmegs=100 + while true; do + while ! btrfs filesystem resize -${shrinkmegs}M "$mountpoint"/; do + shrinkmegs=$((shrinkmegs - 10 )) + if [ $shrinkmegs -lt 10 ]; then + return + fi + done + done +} + +$MODE "$@" diff --git a/src/btrfs-utils/btrfs-shrink b/src/btrfs-utils/btrfs-shrink new file mode 100755 index 0000000..f3dbbb0 --- /dev/null +++ b/src/btrfs-utils/btrfs-shrink @@ -0,0 +1,52 @@ +#!/bin/sh + +die() { printf "%s: Error: %s\n" "$0" "$*" >&2; exit 1; } + +[ "$(id -u)" = 0 ] || die 'you are not root' + +shrink() +{ + shrinkmegs=100 + while true; do + while ! btrfs filesystem resize -${shrinkmegs}M "$mountpoint"/; do + shrinkmegs=$((shrinkmegs - 10 )) + if [ $shrinkmegs -lt 10 ]; then + return + fi + done + done +} + +btrfs_truncate() +{ + local img="$1" bytes + bytes=$(file "$img" | sed -ne 's?.*/\([0-9]*\)/[0-9]* bytes used.*?\1?p') +# 548044800/1176715264 bytes used + if [ "$bytes" ]; then + truncate -s "$bytes" "$img" + fi +} + +main() +{ + if [ -d "$1" ]; then + mountpoint -q "$1" || die "not a mountpoint: $1" + shrink "$1" + elif [ -f "$1" ]; then + mkdir "$1".mnt.tmp + mount -t btrfs "$1" "$1".mnt.tmp + result=$? + if [ $result = 0 ]; then + shrink "$1".mnt.tmp + result=$? + fi + umount "$1".mnt.tmp + rmdir "$1".mnt.tmp + btrfs_truncate "$1" + return $result + else + die "not a file or directory: $1" + fi +} + +main "$@" diff --git a/src/btrfs-utils/with-btrfs-seed b/src/btrfs-utils/with-btrfs-seed new file mode 100755 index 0000000..637af5a --- /dev/null +++ b/src/btrfs-utils/with-btrfs-seed @@ -0,0 +1,99 @@ +#!/bin/sh + +usage() +{ + cat >&2 < [command] [args ...] + + options: + --resize + --btrfs-options (default: compress) + --no-chroot +EOF + exit $1 +} + +error() +{ + printf '%s: Error: %s\n' "$0" "$*" >&2 + exit 1 +} + +warning() +{ + printf '%s: Warning: %s\n' "$0" "$*" >&2 +} + +have_root() +{ + [ "$(id -u)" = 0 ] +} + +main() +{ + have_root || error "you are not root" + + iso_file=$1 + shift + + iso_file_clone=${iso_file}.clone.tmp + mountpoint=${iso_file%.iso}.mnt.tmp + + [ -f "$iso_file" ] || error "not a file: $iso_file" + [ ! -f "$iso_file_clone" ] || error "refusing to clobber existing file: $iso_file_clone" + [ -d "$mountpoint" ] || mkdir "$mountpoint" || error "could not create directory $mountpoint" + ! mountpoint -q "$mountpoint" || error "directory is already a mountpoint: $mountpoint" + + cp --reflink=always "$iso_file" "$iso_file_clone" || error "cp failed" + trap 'rm -f "$iso_file_clone"' EXIT + + if [ "$RESIZE" ]; then + truncate --size="$RESIZE" "$iso_file_clone" || error "failed to resize image with truncate" + fi + + btrfstune -f -S 0 "$iso_file_clone" 2>/dev/null || error "btrfstune failed" + mount_options=rw,loop${BTRFS_OPTIONS:+,$BTRFS_OPTIONS} + mount -o "$mount_options" "$iso_file_clone" "$mountpoint" || error "failed to mount $iso_file" + + if [ "$RESIZE" ]; then + btrfs filesystem resize max "$mountpoint" || error "btrfs filesystem resize" + fi + + if [ "$CHROOT" ]; then + chroot "$mountpoint" "$@" + else + "$@" "$mountpoint" + fi + result=$? + umount "$mountpoint" || warning "umount $mountpoint failed! You had better do something about it" + rmdir "$mountpoint" + if [ "$result" = 0 ]; then + btrfstune -S 1 "$iso_file_clone" || error "btrfstune failed. The original ISO is unmodified." + mv "$iso_file_clone" "$iso_file" + else + warning "The command executed within the chroot failed. The original ISO is unmodified." + rm "$iso_file_clone" + fi +} + +[ $# = 0 ] && usage 0 + +CHROOT=y +eval set -- "$(getopt -o '' --long shrink,no-chroot,resize:,fork:,btrfs-options: -n "$0" -- "$@")" || error 'getopt error' +while [ $# -gt 0 ]; do + case "$1" in + --) shift; break;; + --resize) RESIZE=$2; shift 2;; + --fork) FORK=$2; shift 2;; + --btrfs-options) BTRFS_OPTIONS=$2; shift 2;; + --no-chroot) CHROOT=; shift;; + --shrink) SHRINK=y; shift;; + *) error "unrecognized option: $1" + esac +done + +: ${BTRFS_OPTIONS:=compress} + +[ "$FORK" ] && error "unimplemented option: --fork" + +main "$@" diff --git a/src/with-btrfs-seed b/src/with-btrfs-seed deleted file mode 100755 index f78417b..0000000 --- a/src/with-btrfs-seed +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/sh - -usage() -{ - cat >&2 < [command] [args ...] - - options: - --resize - --btrfs-options (default: compress) - --no-chroot -EOF - exit $1 -} - -error() -{ - printf '%s: Error: %s\n' "$0" "$*" >&2 - exit 1 -} - -warning() -{ - printf '%s: Warning: %s\n' "$0" "$*" >&2 -} - -have_root() -{ - [ "$(id -u)" = 0 ] -} - -main() -{ - have_root || error "you are not root" - - iso_file=$1 - shift - - iso_file_clone=${iso_file}.clone.tmp - mountpoint=${iso_file%.iso}.mnt.tmp - - [ -f "$iso_file" ] || error "not a file: $iso_file" - [ ! -f "$iso_file_clone" ] || error "refusing to clobber existing file: $iso_file_clone" - [ -d "$mountpoint" ] || mkdir "$mountpoint" || error "could not create directory $mountpoint" - ! mountpoint -q "$mountpoint" || error "directory is already a mountpoint: $mountpoint" - - cp --reflink=always "$iso_file" "$iso_file_clone" || error "cp failed" - trap 'rm -f "$iso_file_clone"' EXIT - - if [ "$RESIZE" ]; then - truncate --size="$RESIZE" "$iso_file_clone" || error "failed to resize image with truncate" - fi - - btrfstune -f -S 0 "$iso_file_clone" 2>/dev/null || error "btrfstune failed" - mount_options=rw,loop${BTRFS_OPTIONS:+,$BTRFS_OPTIONS} - mount -o "$mount_options" "$iso_file_clone" "$mountpoint" || error "failed to mount $iso_file" - - if [ "$RESIZE" ]; then - btrfs filesystem resize max "$mountpoint" || error "btrfs filesystem resize" - fi - - if [ "$CHROOT" ]; then - chroot "$mountpoint" "$@" - else - "$@" "$mountpoint" - fi - result=$? - umount "$mountpoint" || warning "umount $mountpoint failed! You had better do something about it" - rmdir "$mountpoint" - if [ "$result" = 0 ]; then - btrfstune -S 1 "$iso_file_clone" || error "btrfstune failed. The original ISO is unmodified." - mv "$iso_file_clone" "$iso_file" - else - warning "The command executed within the chroot failed. The original ISO is unmodified." - rm "$iso_file_clone" - fi -} - -[ $# = 0 ] && usage 0 - -CHROOT=y -eval set -- "$(getopt -o '' --long no-chroot,resize:,fork:,btrfs-options: -n "$0" -- "$@")" || error 'getopt error' -while [ $# -gt 0 ]; do - case "$1" in - --) shift; break;; - --resize) RESIZE=$2; shift 2;; - --fork) FORK=$2; shift 2;; - --btrfs-options) BTRFS_OPTIONS=$2; shift 2;; - --no-chroot) CHROOT=; shift;; - *) error "unrecognized option: $1" - esac -done - -: ${BTRFS_OPTIONS:=compress} - -[ "$FORK" ] && error "unimplemented option: --fork" - -main "$@" -- cgit v1.2.3