AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 667877
Accepted
GypsyCosmonaut
GypsyCosmonaut
Asked: 2021-09-07 04:50:30 +0800 CST2021-09-07 04:50:30 +0800 CST 2021-09-07 04:50:30 +0800 CST

向左扩展分区后将文件系统向左移动

  • 772

TL;博士

我有一个具有多个分区的dd图像。disk.dd最终目标是减小此dd图像文件的大小。

在删除并重新创建一个编号start sector offset比以前低的分区后(即向左扩展分区)我有一个分区,其中有一个文件系统,它primary superblock位于该分区内的某个位置,我知道哪个扇区这primary superblock住。

我怎样才能让e2fsck这个文件系统移动到分区的开头?

这样之后我就可以缩小这个文件系统,resize2fs然后从右边缩小这个分区,即(用较低的重新创建这个分区end sector offset)

然后我将在之后的分区上重复这个过程,直到最后一个分区,有效地缩小所有分区,从而减小dd图像的大小

请不要建议gparted。我正在寻找命令行解决方案

另外,我知道使用LVM. 但是这个遗留系统


长版


我有一个disk.dd使用以下内容拍摄的 dd 图像

dd if=/dev/sda of=/path/to/disk.dd

具有以下布局的系统

Disk /dev/loop15: 465.78 GiB, 500107862016 bytes, 976773168 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: 0x54093dd5

Device        Boot     Start       End   Sectors   Size Id Type
/dev/loop15p1 *         2048  81922047  81920000  39.1G 83 Linux
/dev/loop15p2       81922048 143362047  61440000  29.3G 82 Linux swap / Solaris
/dev/loop15p3      143362048 163842047  20480000   9.8G 83 Linux
/dev/loop15p4      163842048 976773167 812931120 387.7G  5 Extended
/dev/loop15p5      163844096 976773119 812929024 387.7G 83 Linux

现在,在不同的系统上,我disk.dd通过循环设备使用

losetup --find --partscan disk.dd

我调整了所有ext4文件系统的大小

resize2fs -M /dev/loopNpartX
resize2fs /dev/loopNpartX FSsize

即分区p1,p3和p5

有了dumpe2fs,我可以看到logical block size文件系统,它是4096所有文件系统的字节ext4,在我上面显示的情况下,这些文件系统托管在 3 个分区上

现在,如果我在口头上正确阅读此内容(如果我在这里错了,请纠正我)

文件系统的主超级块“通常预期”位于0分区的块中

所以,我可以转储超级块信息

dumpe2fs -h -o superblock=0 -o blocksize=4096 /dev/loopNpartX

现在是时候缩小分区以减小disk.dd文件大小了


我block count再次使用每个文件系统dumpe2fs

fdisk适用于设备的physical block sizeOR sectors,在我的情况下是512字节

因此,为了找到sectors足以容纳文件系统的数量,我使用了以下公式

Required Sectors = ( ( Block Count + 100 ) * Logical Block Size ) / Physical Block Size

100充当缓冲区,以防万一我遗漏了有关文件系统组织的一些内容,这应该足够了

我对每个文件系统都这样做了


现在


有了lsblk -f,我得到了现有文件系统的 UUID

使用fdisk -l,我得到要保持打开的boot flag分区

现在要缩小分区,我将使用删除并重新创建它们fdisk

-- 第一个分区

start sector offset = 2048
last sector offset  = 2048 + "Required Sectors" for this filesystem

-- 第二分区

现有磁盘上的第二个分区是swap,所以我不会缩小它,只是将它向左移动

start sector offset = "last sector offset" of first partition + 1
last sector offset  = "start sector offset" + Total sectors as as on existing partition

然后我将其类型更改为Swap 然后tune2fs -U将 UUID 更改回dd图像上的内容

-- 第三分区

start sector offset = "last sector offset" of second partition + 1
last sector offset  = "start sector offset" + "Required Sectors" for this filesystem

这是我卡住的地方


将第三个分区向左扩展后,该分区有一个文件系统,我知道它的起始扇区(即具有 的扇区primary superblock)

但我不知道如何让e2fsck这个文件系统在分区上更正它,以便文件系统向左移动到分区的开头

partition filesystems
  • 1 1 个回答
  • 535 Views

1 个回答

  • Voted
  1. Best Answer
    frostschutz
    2021-09-07T06:09:13+08:002021-09-07T06:09:13+08:00

    fsck 是不可能的。在文件系统中,所有东西都有偏移量,如果你改变起始扇区,所有这些偏移量都会改变。fsck 根本无法重写所有内容(超级块、日志、目录、文件段等)的所有偏移量。即使你能做到这一点,它也只有在新的起始扇区与内部文件系统结构一致的情况下才会起作用。

    所以这没有完成。

    相反,您必须使用 dd 将所有数据向左移动(本质上是 gparted 所做的)。只有完全移动文件系统,其中的偏移量才能保持不变。

    原则上 dd 命令可以像这样工作。它以不同的偏移量读取和写入同一设备。这仅适用于向左移动,因此 seek(写入)必须小于skip(读取)。512b 扇区中的所有单元(如果您指定bs=1M,则您的分区必须是 MiB 对齐的,并且所有单元都在 MiB 中)

    dd if=/dev/sdx of=/dev/sdx \
       seek=newpartitionstart \
       skip=oldpartitionstart \
       count=filesystemsize
    

    但是,这是非常危险的。需要您自担风险使用它。请务必花时间先备份您的数据。

    向右移动会更复杂。您必须向后工作,否则您会覆盖尚未读取的数据,并破坏过程中的所有内容。


    我所知道的(或多或少)不移动数据的唯一工具是blocks --lvmify,它通过将现有文件系统分区转换为 LVM 来实现。使用 LVM,您可以在逻辑上向右扩展,而它在物理上存储在左侧。如果没有 LVM,您也可以手动设置线性设备映射,但您会遇到非标准解决方案。


    解决此类问题(如果您不想使用 gparted)最明智的方法是备份所有数据,然后以您喜欢的任何布局创建新的分区和文件系统,然后恢复您的数据。

    如果此 dd 映像是您的备份解决方案,请考虑改为备份文件。磁盘映像可能很难处理,特别是如果您想在之后转换它们。


    如果您的主要目标是减少映像文件的存储需求,您可以做的是fstrim(对于循环安装的文件系统 - 丢失所有可用空间),或blkdiscard(对于循环交换分区 - 丢失所有数据)。

    如果存储图像的文件系统支持稀疏文件和打孔,它将使 dd 图像使用更少的存储空间而无需更改任何布局,因为图像中的任何可用空间也将被释放用于支持文件系统。

    同样,这是危险的,如果您丢弃图像文件的错误部分,图像文件将受到不可恢复的损坏。为图像文件创建循环设备并安装它的简单行为已经修改/损坏了图像文件。

    如果源磁盘是 SSD,并且它已经定期使用 fstrim,并且将修剪区域读取为二进制零,那么您可以首先使用dd conv=sparse if=/dev/ssd of=ssd.img. 这样,任何二进制零区域都不会占用 ssd.img 文件中的空间。请注意,conv=sparse在还原到非零目标驱动器时,在其他方向使用时可能会导致损坏的结果。

    • 1

相关问题

  • 如何正确分区 SSD 以进行双启动设置

  • 并行安装多个 linux 发行版

  • fdisk 没有看到 resize2fs 缩小未挂载的分区

  • du/df 和 ls 报告不同的磁盘使用情况

  • Linux 内核开发人员如何处理数百万行代码的工作?他们是一种方法吗?[关闭]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve