Merge 860a128b4a
into aa14313d04
This commit is contained in:
commit
980d4bdec3
30
README.md
30
README.md
|
@ -8,7 +8,7 @@ using multiple cores is supported.
|
||||||
## Usage ##
|
## Usage ##
|
||||||
|
|
||||||
```
|
```
|
||||||
Usage: $0 [-adhrsvzZ] imagefile.img [newimagefile.img]
|
Usage: $0 [-adhrsvzZn] imagefile.img [newimagefile.img]
|
||||||
|
|
||||||
-s Don't expand filesystem when image is booted the first time
|
-s Don't expand filesystem when image is booted the first time
|
||||||
-v Be verbose
|
-v Be verbose
|
||||||
|
@ -17,6 +17,7 @@ Usage: $0 [-adhrsvzZ] imagefile.img [newimagefile.img]
|
||||||
-Z Compress image after shrinking with xz
|
-Z Compress image after shrinking with xz
|
||||||
-a Compress image in parallel using multiple cores
|
-a Compress image in parallel using multiple cores
|
||||||
-d Write debug messages in a debug log file
|
-d Write debug messages in a debug log file
|
||||||
|
-n Accept an input that is not a file (e.g. a tf card)
|
||||||
```
|
```
|
||||||
|
|
||||||
If you specify the `newimagefile.img` parameter, the script will make a copy of `imagefile.img` and work off that. You will need enough space to make a full copy of the image to use that option.
|
If you specify the `newimagefile.img` parameter, the script will make a copy of `imagefile.img` and work off that. You will need enough space to make a full copy of the image to use that option.
|
||||||
|
@ -28,6 +29,7 @@ If you specify the `newimagefile.img` parameter, the script will make a copy of
|
||||||
* `-Z` will compress the image after shrinking using xz. `.xz` extension will be added to the filename.
|
* `-Z` will compress the image after shrinking using xz. `.xz` extension will be added to the filename.
|
||||||
* `-a` will use option -f9 for pigz and option -T0 for xz and compress in parallel.
|
* `-a` will use option -f9 for pigz and option -T0 for xz and compress in parallel.
|
||||||
* `-d` will create a logfile `pishrink.log` which may help for problem analysis.
|
* `-d` will create a logfile `pishrink.log` which may help for problem analysis.
|
||||||
|
* `-n` will shrink the file system of a tfcard, and create an image file from that if `newimagefile.img` is specified.
|
||||||
|
|
||||||
Default options for compressors can be overwritten by defining PISHRINK_GZIP or PSHRINK_XZ environment variables for gzip and xz.
|
Default options for compressors can be overwritten by defining PISHRINK_GZIP or PSHRINK_XZ environment variables for gzip and xz.
|
||||||
|
|
||||||
|
@ -48,10 +50,10 @@ chmod +x pishrink.sh
|
||||||
sudo mv pishrink.sh /usr/local/bin
|
sudo mv pishrink.sh /usr/local/bin
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example ##
|
## Example 1 ##
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[user@localhost PiShrink]$ sudo pishrink.sh pi.img
|
sudo pishrink.sh pi.img
|
||||||
e2fsck 1.42.9 (28-Dec-2013)
|
e2fsck 1.42.9 (28-Dec-2013)
|
||||||
Pass 1: Checking inodes, blocks, and sizes
|
Pass 1: Checking inodes, blocks, and sizes
|
||||||
Pass 2: Checking directory structure
|
Pass 2: Checking directory structure
|
||||||
|
@ -73,6 +75,28 @@ The filesystem on /dev/loop1 is now 773603 blocks long.
|
||||||
Shrunk pi.img from 30G to 3.1G
|
Shrunk pi.img from 30G to 3.1G
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Example 2 ##
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pishrink.sh -n /dev/sdb pi.img
|
||||||
|
pishrink.sh v0.1.3
|
||||||
|
pishrink.sh: Gathering data ...
|
||||||
|
|
||||||
|
pishrink.sh: Checking filesystem ...
|
||||||
|
rootfs: 69602/155648 files (0.4% non-contiguous), 457517/599771 blocks
|
||||||
|
resize2fs 1.46.5 (30-Dec-2021)
|
||||||
|
pishrink.sh: Shrinking filesystem ...
|
||||||
|
resize2fs 1.46.5 (30-Dec-2021)
|
||||||
|
Resizing the filesystem on /dev/sdb2 to 597213 (4k) blocks.
|
||||||
|
The filesystem on /dev/sdb2 is now 597213 (4k) blocks long.
|
||||||
|
|
||||||
|
pishrink.sh: Creating image ...
|
||||||
|
5310185+0 records in
|
||||||
|
5310185+0 records out
|
||||||
|
2718814720 bytes (2.7 GB, 2.5 GiB) copied, 294.339 s, 9.2 MB/s
|
||||||
|
pishrink.sh: Shrunk pi.img from 8, to 2.6G ...
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing ##
|
## Contributing ##
|
||||||
|
|
||||||
If you find a bug please create an issue for it. If you would like a new feature added, you can create an issue for it but I can't promise that I will get to it.
|
If you find a bug please create an issue for it. If you would like a new feature added, you can create an issue for it but I can't promise that I will get to it.
|
||||||
|
|
103
pishrink.sh
103
pishrink.sh
|
@ -165,7 +165,7 @@ EOF1
|
||||||
help() {
|
help() {
|
||||||
local help
|
local help
|
||||||
read -r -d '' help << EOM
|
read -r -d '' help << EOM
|
||||||
Usage: $0 [-adhrsvzZ] imagefile.img [newimagefile.img]
|
Usage: $0 [-adhrsvzZn] imagefile.img [newimagefile.img]
|
||||||
|
|
||||||
-s Don't expand filesystem when image is booted the first time
|
-s Don't expand filesystem when image is booted the first time
|
||||||
-v Be verbose
|
-v Be verbose
|
||||||
|
@ -174,6 +174,7 @@ Usage: $0 [-adhrsvzZ] imagefile.img [newimagefile.img]
|
||||||
-Z Compress image after shrinking with xz
|
-Z Compress image after shrinking with xz
|
||||||
-a Compress image in parallel using multiple cores
|
-a Compress image in parallel using multiple cores
|
||||||
-d Write debug messages in a debug log file
|
-d Write debug messages in a debug log file
|
||||||
|
-n Accept an input that is not a file (e.g. a tf card)
|
||||||
EOM
|
EOM
|
||||||
echo "$help"
|
echo "$help"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -185,8 +186,9 @@ repair=false
|
||||||
parallel=false
|
parallel=false
|
||||||
verbose=false
|
verbose=false
|
||||||
ziptool=""
|
ziptool=""
|
||||||
|
notfile=false
|
||||||
|
|
||||||
while getopts ":adhrsvzZ" opt; do
|
while getopts ":adhrsvzZn" opt; do
|
||||||
case "${opt}" in
|
case "${opt}" in
|
||||||
a) parallel=true;;
|
a) parallel=true;;
|
||||||
d) debug=true;;
|
d) debug=true;;
|
||||||
|
@ -196,6 +198,7 @@ while getopts ":adhrsvzZ" opt; do
|
||||||
v) verbose=true;;
|
v) verbose=true;;
|
||||||
z) ziptool="gzip";;
|
z) ziptool="gzip";;
|
||||||
Z) ziptool="xz";;
|
Z) ziptool="xz";;
|
||||||
|
n) notfile=true;;
|
||||||
*) help;;
|
*) help;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
@ -219,10 +222,14 @@ if [[ -z "$img" ]]; then
|
||||||
help
|
help
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -f "$img" ]]; then
|
if [ "$notfile" = false ]; then
|
||||||
error $LINENO "$img is not a file..."
|
echo "$notfile"
|
||||||
exit 2
|
if [[ ! -f "$img" ]]; then
|
||||||
|
error $LINENO "$img is not a file..."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if (( EUID != 0 )); then
|
if (( EUID != 0 )); then
|
||||||
error $LINENO "You need to be running as root."
|
error $LINENO "You need to be running as root."
|
||||||
exit 3
|
exit 3
|
||||||
|
@ -261,19 +268,21 @@ done
|
||||||
|
|
||||||
#Copy to new file if requested
|
#Copy to new file if requested
|
||||||
if [ -n "$2" ]; then
|
if [ -n "$2" ]; then
|
||||||
f="$2"
|
if [ "$notfile" = false ]; then #Skip copy if input is device
|
||||||
if [[ -n $ziptool && "${f##*.}" == "${ZIPEXTENSIONS[$ziptool]}" ]]; then # remove zip extension if zip requested because zip tool will complain about extension
|
f="$2"
|
||||||
f="${f%.*}"
|
if [[ -n $ziptool && "${f##*.}" == "${ZIPEXTENSIONS[$ziptool]}" ]]; then # remove zip extension if zip requested because zip tool will complain about extension
|
||||||
|
f="${f%.*}"
|
||||||
|
fi
|
||||||
|
info "Copying $1 to $f..."
|
||||||
|
cp --reflink=auto --sparse=always "$1" "$f"
|
||||||
|
if (( $? != 0 )); then
|
||||||
|
error $LINENO "Could not copy file..."
|
||||||
|
exit 5
|
||||||
|
fi
|
||||||
|
old_owner=$(stat -c %u:%g "$1")
|
||||||
|
chown "$old_owner" "$f"
|
||||||
|
img="$f"
|
||||||
fi
|
fi
|
||||||
info "Copying $1 to $f..."
|
|
||||||
cp --reflink=auto --sparse=always "$1" "$f"
|
|
||||||
if (( $? != 0 )); then
|
|
||||||
error $LINENO "Could not copy file..."
|
|
||||||
exit 5
|
|
||||||
fi
|
|
||||||
old_owner=$(stat -c %u:%g "$1")
|
|
||||||
chown "$old_owner" "$f"
|
|
||||||
img="$f"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# cleanup at script exit
|
# cleanup at script exit
|
||||||
|
@ -292,17 +301,21 @@ fi
|
||||||
partnum="$(echo "$parted_output" | tail -n 1 | cut -d ':' -f 1)"
|
partnum="$(echo "$parted_output" | tail -n 1 | cut -d ':' -f 1)"
|
||||||
partstart="$(echo "$parted_output" | tail -n 1 | cut -d ':' -f 2 | tr -d 'B')"
|
partstart="$(echo "$parted_output" | tail -n 1 | cut -d ':' -f 2 | tr -d 'B')"
|
||||||
if [ -z "$(parted -s "$img" unit B print | grep "$partstart" | grep logical)" ]; then
|
if [ -z "$(parted -s "$img" unit B print | grep "$partstart" | grep logical)" ]; then
|
||||||
parttype="primary"
|
parttype="primary"
|
||||||
else
|
else
|
||||||
parttype="logical"
|
parttype="logical"
|
||||||
|
fi
|
||||||
|
if [ "$notfile" = false ]; then
|
||||||
|
loopback="$(losetup -f --show -o "$partstart" "$img")"
|
||||||
|
else
|
||||||
|
loopback=""$img""2""
|
||||||
fi
|
fi
|
||||||
loopback="$(losetup -f --show -o "$partstart" "$img")"
|
|
||||||
tune2fs_output="$(tune2fs -l "$loopback")"
|
tune2fs_output="$(tune2fs -l "$loopback")"
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc )); then
|
if (( $rc )); then
|
||||||
echo "$tune2fs_output"
|
echo "$tune2fs_output"
|
||||||
error $LINENO "tune2fs failed. Unable to shrink this type of image"
|
error $LINENO "tune2fs failed. Unable to shrink this type of image"
|
||||||
exit 7
|
exit 7
|
||||||
fi
|
fi
|
||||||
|
|
||||||
currentsize="$(echo "$tune2fs_output" | grep '^Block count:' | tr -d ' ' | cut -d ':' -f 2)"
|
currentsize="$(echo "$tune2fs_output" | grep '^Block count:' | tr -d ' ' | cut -d ':' -f 2)"
|
||||||
|
@ -378,21 +391,37 @@ if (( $rc )); then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#Truncate the file
|
#Truncate the file
|
||||||
info "Shrinking image"
|
if [ "$notfile" = false ]; then
|
||||||
endresult=$(parted -ms "$img" unit B print free)
|
info "Shrinking image"
|
||||||
rc=$?
|
endresult=$(parted -ms "$img" unit B print free)
|
||||||
if (( $rc )); then
|
rc=$?
|
||||||
error $LINENO "parted failed with rc $rc"
|
if (( $rc )); then
|
||||||
exit 15
|
error $LINENO "parted failed with rc $rc"
|
||||||
fi
|
exit 15
|
||||||
|
fi
|
||||||
|
|
||||||
endresult=$(tail -1 <<< "$endresult" | cut -d ':' -f 2 | tr -d 'B')
|
endresult=$(tail -1 <<< "$endresult" | cut -d ':' -f 2 | tr -d 'B')
|
||||||
logVariables $LINENO endresult
|
logVariables $LINENO endresult
|
||||||
truncate -s "$endresult" "$img"
|
truncate -s "$endresult" "$img"
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc )); then
|
if (( $rc )); then
|
||||||
error $LINENO "trunate failed with rc $rc"
|
error $LINENO "trunate failed with rc $rc"
|
||||||
exit 16
|
exit 16
|
||||||
|
fi
|
||||||
|
else #Skip truncate if input is device
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
target="$2"
|
||||||
|
info "Creating image"
|
||||||
|
fdiskresult=$(fdisk -l "$img")
|
||||||
|
count=$(tail -1 <<< "$fdiskresult" | tr -s ' ' | cut -d ' ' -f 3)
|
||||||
|
bs=$(head -3 <<< "$fdiskresult" | tail -1 | tr -s ' ' | rev | cut -d ' ' -f 2 | rev)
|
||||||
|
count=$(expr "$count" + 1)
|
||||||
|
dd if="$img" of="$target" bs="$bs" count="$count"
|
||||||
|
img="$target"
|
||||||
|
else
|
||||||
|
info "File system shrinked from $beforesize to $aftersize, no image created"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# handle compression
|
# handle compression
|
||||||
|
|
Loading…
Reference in New Issue