-
Notifications
You must be signed in to change notification settings - Fork 14
/
image-shrink
133 lines (121 loc) · 2.41 KB
/
image-shrink
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/bash
mkloop()
{
INFO="$(sfdisk -d "${IMGFILE}")"
START=$(grep type=83 <<< "${INFO}" | sed -n 's|^.*start=\s\+\([0-9]\+\).*$|\1|p')
SIZE=$(grep type=83 <<< "${INFO}" | sed -n 's|^.*size=\s\+\([0-9]\+\).*$|\1|p')
LOOP="$(losetup -f --show -o $((${START} * 512)) --sizelimit $((${SIZE} * 512)) "${IMGFILE}")"
if [ $? -ne 0 ]; then
errexit "Unable to create ROOT loop device"
fi
}
rmloop()
{
losetup -d "${LOOP}"
}
fsckerr()
{
rmloop
errexit "Filesystem appears corrupted "$1" resize2fs"
}
errexit()
{
echo ""
echo "$1"
echo ""
exit 1
}
if [ $(id -u) -ne 0 ]; then
errexit "$0 must be run as root user"
fi
IMGFILE="$1"
if [ "${IMGFILE}" = "" ]; then
errexit "Usage: $0 imagefile [Additional MB]"
fi
if [ ! -f "${IMGFILE}" ] || [ ! -s "${IMGFILE}" ]; then
errexit "${IMGFILE} is missing or empty"
fi
mkloop
FS_TYPE=$(blkid "${LOOP}" | sed -n 's|^.*TYPE="\(\S\+\)".*|\1|p')
rmloop
if [ "${FS_TYPE}" = "f2fs" ]; then
errexit "Cannot shrink F2FS filesystem"
fi
answer="$2"
if [[ ! "${answer}" =~ ^[0-9]+$ ]]; then
echo ""
while :
do
read -r -e -i "${answer}" -p "Additional MB? " answer
if [[ "${answer}" =~ ^[0-9]*$ ]]; then
break
fi
done
fi
while [ "${answer:0:1}" = "0" ]; do
answer="${answer:1}"
done
if [ ${#answer} -eq 0 ]; then
answer=0
fi
ADDMB=${answer}
echo ""
echo -n "Shrink ${IMGFILE} [Additional MB = ${ADDMB}] (y/n)? "
while read -r -n 1 -s answer; do
if [[ "${answer}" = [yYnN] ]]; then
echo "${answer}"
if [[ "${answer}" = [yY] ]]; then
break
else
errexit "Aborted"
fi
fi
done
echo ""
mkloop
e2fsck -f "${LOOP}"
if [ $? -ne 0 ]; then
fsckerr "before"
fi
echo ""
resize2fs -M "${LOOP}"
resize2fs -M "${LOOP}"
resize2fs -M "${LOOP}"
e2fsck -f "${LOOP}"
if [ $? -ne 0 ]; then
fsckerr "after"
fi
INFO="$(tune2fs -l "${LOOP}" 2>/dev/null)"
rmloop
NEWSIZE=$(grep '^Block count:' <<< "${INFO}" | awk '{print $3}')
BLKSIZE=$(grep '^Block size:' <<< "${INFO}" | awk '{print $3}')
NEWEND=$((${START} + (${NEWSIZE} * (${BLKSIZE} / 512)) + ((${ADDMB} * 1024 * 1024) / 512) - 1))
truncate -s $(((${NEWEND} + 1) * 512)) "${IMGFILE}"
fdisk "${IMGFILE}" <<EOF > /dev/null
p
d
2
n
p
2
${START}
${NEWEND}
p
w
EOF
if [ ${ADDMB} -ne 0 ]; then
echo ""
mkloop
e2fsck -f "${LOOP}"
if [ $? -ne 0 ]; then
fsckerr "before"
fi
echo ""
resize2fs "${LOOP}"
e2fsck -f "${LOOP}"
if [ $? -ne 0 ]; then
fsckerr "after"
fi
rmloop
fi
echo ""