通过 Ubuntu 服务器缩小 Raspberry Pi SD .img (cli)

通过 Ubuntu 服务器缩小 Raspberry Pi SD .img (cli)

我将 Raspbian 安装到 16 GB 卡上并扩展了文件系统。当我dd对卡进行备份时,.img 文件输出约为 16 GB。其中大部分是 ext4 分区中未使用的空间 — 我在该分区中仅使用了 2.5 GB 左右的空间。 (有两个分区 — 第一个是用于启动的 FAT,第二个是用于 rootfs 的 ext4。)我想缩小位于 Ubuntu 16.04 服务器安装(无 GUI)上的 backup.img 文件,以便我可以恢复图像到较小尺寸的卡(例如8GB)。

/dev/loop0到目前为止,我已经使用 提供给我的偏移值安装了 ext4 分区fdisk -l backup.img。然后我使用了e2fsck -f /dev/loop0thenresize2fs -M /dev/loop0这似乎缩小了 ext4 fs...我走在正确的轨道上吗?我觉得parted可能是下一个,但我已经与它的经验。

如何仅使用 cli 工具来完成此任务?


更新:

这是运行的输出fdisk -l backup.img

Disk backup.img: 14.9 GiB, 15931539456 bytes, 31116288 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x79d38e92

Device        Boot  Start      End  Sectors  Size Id Type
backup.img1 *      8192   124927   116736   57M  e W95 FAT16 (LBA)
backup.img2      124928 31116287 30991360 14.8G 83 Linux

答案1

我可以确认您缩小文件系统的方向是正确的;接下来是 fdisk/parted。棘手的部分是让它紧邻新文件系统的大小,计算一下,或者为了安全起见,再泄漏一百KB。如果需要,您可以稍后在新卡上进行调整。

命令通常是:umount、resize、fdisk/parted、partprobe、fsck,然后 mount 来检查一切是否正常。由于您要调整大小的分区小于 2T,您可以使用fdiskparted

调整大小过程必须首先进行,因为当文件系统仍然占用您需要回收的空间时,您将无法可靠地缩小分区。在您需要再次缩小分区以保持一致性之后,并且由于没有剩余空间,您需要摆脱“预订”以供使用。文件系统放在最后,以使文件系统结构与新大小一致。

我会留下这些RH文章。它缺少partprobe,因为新的分区大小并不总是立即被识别或被旧内核识别。

如何使用 resize2fs 缩小 ext2/3/4 文件系统

如何使用 fdisk 调整分区大小

您缺少的步骤是:

sudo fdisk /dev/loop
p     - to check for partition number (probably 2)
d     - to delete
2     - partition 2
n     - new partition
p     - primary
ENTER - default beginning
+new size -  smaller card size
w      - write it

sudo partprobe /dev/loop

要完成此操作,请卸载映像文件;由于额外的大小不再被标记为文件系统和文件映像中的分区大小所使用,因此操作系统不会尝试使用该空间。因此可以安全地将其截断为预期大小:

truncate -s 8GB fileName

为了使用适当的大小,因为我很懒,我会将文件系统粉碎到小于我需要的大小(即新分区的大小 - 400k,然后在缩小分区后再次扩展它),并使用以下命令创建分区所需的大小(可能的第一个分区填充的 8GB-2048(2K) 减去第一个分区的大小)。不涉及太多数学。

为了正确计算它,请看一下:

如何在不丢失数据的情况下调整 ext3 分区大小

答案2

怎么样使用自动 RPi 图像缩小器

您也可以查看代码以了解发生了什么。

if [[ ! $(whoami) =~ "root" ]]; then
echo ""
echo "**********************************"
echo "*** This should be run as root ***"
echo "**********************************"
echo ""
exit
fi

if [[ -z $1 ]]; then
echo "Usage: ./autosizer.sh "
exit
fi

if [[ ! -e $1 || ! $(file $1) =~ "x86" ]]; then
echo "Error : Not an image file, or file doesn't exist"
exit
fi

partinfo=`parted -m $1 unit B print`
partnumber=`echo "$partinfo" | grep ext4 | awk -F: ' { print $1 } '`
partstart=`echo "$partinfo" | grep ext4 | awk -F: ' { print substr($2,0,length($2)-1) } '`
loopback=`losetup -f --show -o $partstart $1`
e2fsck -f $loopback
minsize=`resize2fs -P $loopback | awk -F': ' ' { print $2 } '`
minsize=`echo $minsize+1000 | bc`
resize2fs -p $loopback $minsize
sleep 1
losetup -d $loopback
partnewsize=`echo "$minsize * 4096" | bc`
newpartend=`echo "$partstart + $partnewsize" | bc`
part1=`parted $1 rm 2`
part2=`parted $1 unit B mkpart primary $partstart $newpartend`
endresult=`parted -m $1 unit B print free | tail -1 | awk -F: ' { print substr($2,0,length($2)-1) } '`
truncate -s $endresult $1

相关内容