为什么 Linux“dd”在将单个分区复制到较小的设备时出现“设备上没有剩余空间”的错误?

为什么 Linux“dd”在将单个分区复制到较小的设备时出现“设备上没有剩余空间”的错误?

我正在尝试将单个分区 /dev/sda1 复制到 /dev/sdc1,但出现错误“设备上没有剩余空间”,老实说,我不明白为什么。

我正在使用 Oracle 云基础设施 (OCI) VM,其中 /dev/sda 是一个 768 GB 的卷,其 sda1 分区已缩小至仅 32 GB(该过程正常,没有数据丢失!我可以保证,因为该卷是 Oracle 数据库 ASM 磁盘组,缩小后一切正常)。

由于 OCI 仅允许增加卷大小,我创建了一个大小为 50 GB(这是允许的最小大小)的新卷 /dev/sdc,并创建了一个仅为 32 GB(大小与 /dev/sda1 相同)的分区 /dev/sdc1。

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdc      8:32   0    50G  0 disk
└─sdc1   8:33   0    32G  0 part
sda      8:0    0   768G  0 disk
└─sda1   8:1    0    32G  0 part

运行时出现错误

# dd if=/dev/sda1 of=/dev/sdc1 bs=512b conv=noerror,sync
dd: error writing ‘/dev/sdc1’: No space left on device
22567+0 records in
22566+0 records out
5915787264 bytes (5.9 GB) copied, 42.9384 s, 138 MB/s

两个分区的大小完全相同,如 fdisk 所示

# fdisk /dev/sda

Disk /dev/sda: 824.6 GB, 824633720832 bytes, 1610612736 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 1048576 bytes
Disk label type: dos
Disk identifier: 0x7c9bf84b

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1            2048    67108863    33553408   83  Linux


# fdisk /dev/sdc
Disk /dev/sdc: 53.7 GB, 53687091200 bytes, 104857600 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 1048576 bytes
Disk label type: dos
Disk identifier: 0x9b11add5

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1            2048    67108863    33553408   83  Linux

我究竟做错了什么?

答案1

前几天我刚遇到这个问题(不过是在 Ubuntu Server 上)。结果发现,内核没有重新读取分区表,因为一些旧的 LVM 挂载仍在使用中。要重新读取分区表:

partprobe /dev/X

如果此操作失败,则表示设备正忙,则表示挂载点处于活动状态,LVM 或设备映射器处于活动状态(在我的情况下,LVM 创建了一个设备映射器,我不确定是否总是如此)。运行:

dmsetup ls

可能接下来是:

dmsetup remove X

对于曾经位于目标磁盘上的任何设备。

答案2

我不知道问题出在哪里,但我只需克隆整个卷就可以了

# dd if=/dev/sda of=/dev/sdc bs=512b conv=noerror,sync

当然,操作在 /dev/sdc 总大小达到 50 GB 时停止,并出现相同的错误信息,但结果是正常的。

答案3

原始命令中分区号的表示法存在错误:

dd if=/dev/sda1 of=/dev/sdc1 bs=512b conv=noerror,sync

应该只指示设备值字母而不是数字以使 dd 正常工作:

dd if=/dev/sda of=/dev/sdc bs=512b conv=noerror,sync

我不确定 dd 是否是你实现目标所需要的。

相关内容