MrM*_*Mas 1 linux gparted partitioning dd parted
我已.img使用dd以下命令将 USB 驱动器复制到文件中:
dd if=/dev/sdc of=myimage.img
Run Code Online (Sandbox Code Playgroud)
我想减小图像中分区的大小。我尝试了几种方法,但最终总是得到一个环回安装的映像,其分区仍然是 USB 的完整大小。
myimage.img安装回环后如何修改为具有较小的分区?
在这样做之前,我是否需要将零复制到分区的空白部分?
我是否需要进行碎片整理,以便在减小图像大小时删除空字节?(从我读到的内容来看,Linux 扩展到整个分区,所以我不期望图像末尾的所有数据都是零字节。即使写入全零也只会消耗它们所在的空字节。)
注意:我不是想节省磁盘空间,所以压缩对我没有帮助。
背景
我在 USB 驱动器上安装了 Linux,使用ext4. 我打算为多个设备复制安装。我已经成功做到了,但想在同一个 USB 驱动器上创建一个包含系统的只读分区和一个允许持久存储的小分区。我没有破坏我的 USB,而是尝试修改 USB 的副本。我希望我们不要被这个背景分心。
简而言之,我做了以下工作:
# Create mount point in current directory
sudo mkdir mnt
# Loopback mount the image
fdisk -l myimage.img
sudo mount -o offset=<partion_block_start * block_size> myimage.img mnt
# Copy all zeros to remaining space of the image
cd mnt
sudo dd if=/dev/zero of=filler conv=fsync bs=1M
rm filler
cd ..
Run Code Online (Sandbox Code Playgroud)
首先,我尝试parted按照此 SuperUser answerqemu-img中的描述和其他 SuperUser answer 中的描述使用。
sudo umount mnt
parted myimage.img
# At parted command prompt
(parted) resizepart 1
# Entered my end <target size>. Note that parted uses zero-based
# indexing. This could be your final image size. In my case, the way the
# Linux installer worked, the partition started at 1M.
(parted) print
# I see that the partition is now sized as I expect
(parted) exit
# Just another sanity check
sudo parted -m esp3_007.img unit B print
# I see that the partition is now sized as I expect
Run Code Online (Sandbox Code Playgroud)
当我再次尝试挂载映像时,它工作正常,但df仍将分区显示为相同大小。所以我尝试了
qemu-img resize myimage.img <target_size>
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试挂载映像时,我收到“挂载:错误的 fs 类型、错误的选项、错误的超级块...”错误消息。
然后我尝试gparted按照这个场外帖子中的描述使用。除非我parted首先运行,否则 GUI 会显示一个完整的分区。即便如此,GUI 也不会让我调整分区大小。
试图强制分区大小更小,并从myimage.img我尝试fdisk在此 AskUbuntu 回答中描述的新副本开始
sudo fdisk myimage.img
Command (m for help): d
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4, default 1): 1
# defaults on the rest seemed to be correct in my case.
Run Code Online (Sandbox Code Playgroud)
当我安装分区时,它仍然显示为相同的大小。
首先,忘记offset=,使用losetup --partscan并通过/dev/loop0p1.
# losetup --partscan /dev/loop0 myimage.img
# lsblk
# mount /dev/loop0p1 /mnt
Run Code Online (Sandbox Code Playgroud)
要有效地清除分区内的空白空间,请fstrim在循环安装的文件系统上运行,就像在 SSD 上一样。(这实际上会使图像文件变得稀疏。)
# fstrim -v /mnt
Run Code Online (Sandbox Code Playgroud)
但是现在,您不需要清除空白区域或执行类似操作。即将被截断的区域是用零填充还是用旧数据块完全无关紧要。
相反,您需要执行与在真实磁盘上使用 ext4 完全相同的操作——您需要从内向外缩小每一层。您不能仅仅因为它是图像而跳过步骤。
要收缩包含文件系统的分区,您必须首先告诉文件系统收缩自身。对于 ext2/3/4,这是使用resize2fs. 这将重新定位可能存在于您将要砍掉的区域中的数据,并将新边界存储为文件系统元数据的一部分。(我想这就是您所说的“对其进行碎片整理”的意思。)
只有在文件系统缩小后,您还可以缩小包含它的分区。这可以通过 parted 或 fdisk 通过更改分区的结束地址来完成。
旁注:您应该能够使用 GParted 一步调整文件系统和分区的大小——如果它支持在循环设备上工作,那就是。它可能取决于 GParted 的版本。(但是,CLI parted不能缩小文件系统,它只会截断分区。)
最后,一旦调整了文件系统和分区的大小,您就可以截断包含它们的整个映像。为此,首先分离循环设备并truncate --size=...在您的图像文件上使用。
(为了安全地做到这一点而不必仔细计算,我会将文件系统缩小到比创建一些“缓冲区”空间所需的略多一些;例如,如果我想要一个 4 GB 的图像,我会将文件系统缩小到 3 GB,即分区到 3.5 GB,然后将图像截断到 4 GB。然后以相反的顺序增长所有内容以填充“缓冲区”空间。)
| 归档时间: |
|
| 查看次数: |
7502 次 |
| 最近记录: |