如果我已经从“/dev/sdq1”备份了数据,如何将 ddrescue 从“/dev/sdq1”切换到“/dev/sdq”?

如果我已经从“/dev/sdq1”备份了数据,如何将 ddrescue 从“/dev/sdq1”切换到“/dev/sdq”?

当我对硬盘恢复还不熟悉的时候,我开始恢复硬盘/dev/sdq1。还好我足够小心,大约 500 次运行就恢复了 85%。

后来,我发现我需要/dev/sdq(没有1)内容实际上将它们转换为.vhd带有并且之后我可以在Windows中VBoxManage convertdd z:\fixed.vdi d:\disc.vhd --format VHD附加和读取它,因为不支持.vhdVBoxManage分割转换并需要硬盘已满原始数据作为输入。这意味着我应该使用/dev/sdq而不是 来启动 ddrescue /dev/sdq1

我用 fdisk发现 的内容/dev/sdq1从 的 32256 字节开始。我将这些字节放在开头以分离文件,现在运行以将它们添加到 的恢复数据前面。/dev/sdqddbegin.rawcat ./rescue/begin.raw ./rescue/fixed.vdi > ./sdq.raw/dev/sdq1

有没有更简单的方法可以使用旧的 rescuelog 继续运行ddrescue新的./sdq.raw?我不确定这--output-position是否适合这里。(它究竟是如何工作的?——从文档中不清楚这output-position将如何影响 rescuelog 的解释)。我不想每次想要获取./sdq.raw.

下面是我用来恢复数据的脚本。有时我不得不物理地卸下硬盘,因为我的 USB 集线器不支持端口上的完全关闭。

#!/bin/bash
function run {
    ddrescue -T 5s --max-error-rate=10MB --skip-size=512KiB,10MiB \
        --direct -vv -P /dev/sdq1 ./fixed.vdi ./rescue.log
}

while true; do
    run &
    JOBPID=$!
    while true; do
        dmesg | tail -1 | grep 'reset high-speed USB device number' > /dev/null
        CODE=$?
        if [ $CODE -eq 0 ]; then
            break
        fi
        kill -0 "$JOBPID" > /dev/null
        CODE=$?
        if [ $CODE -ne 0 ]; then
            break
        fi
        sleep 3
    done
    ./uhubctl -i -a 2 -p 1 -l 1
    wait $JOBPID
    echo "MSG: waiting for re-attach"
    until dmesg | tail -1 | grep 'Attached SCSI disk'; do sleep 1; done
    sleep 5
done

谢谢!

PS:我有 Logitech USB 2.0 集线器,但它也不支持端口完全关闭uhubctl。也许还有其他工具可以与它配合使用?

答案1

无论这是否--output-position是正确的ddrescue选择,我介绍了 Linux 中连接两个文件而不将结果写入磁盘的通用方法。

该工具是dmsetup。它在dmsetup我的 Kubuntu 包中,在 Debian 中也一样。

我们有begin.raw大小32256 Bfixed.vdi对应于大小的分区<X>(大约500 GB,我不知道确切的值)。我们需要用512 B单位表示大小;结果分别是63<Y>。在下面的代码中,您必须<Y>用计算值替换,所以不要盲目地复制粘贴。

# Creating loop devices and storing their names.
BEGIN_LOOP=$(sudo losetup -f --show begin.raw)
FIXED_LOOP=$(sudo losetup -f --show fixed.vdi)

# Creating a map to feed to `dmsetup` later.
# !!! REPLACE <Y> WITH THE PROPER VALUE !!!
echo "0 63 linear $BEGIN_LOOP 0" > whole.map
echo "63 <Y> linear $FIXED_LOOP 0" >> whole.map

# Creating a concatenated "file".
sudo dmsetup create whole.raw < whole.map
ln -s /dev/mapper/whole.raw

现在,您可以将 用作whole.raw整个磁盘的映像,同时ddrescue仍可使用fixed.vdi。 上的每个 I/O 操作whole.raw都将映射到begin.rawfixed.vdi

请注意,此映射不是持久的。重启后,您需要重复整个过程,但 除外ln -s

要清除此设置而不重新启动,请调用:

rm whole.raw                    # removes the symlink
sudo dmsetup remove whole.raw   # removes /dev/mapper/whole.raw
sudo losetup -d $FIXED_LOOP     # removes /dev/loop1 (or so)
sudo losetup -d $BEGIN_LOOP     # removes /dev/loop0 (or so)

如果您以某种方式丢失了变量(例如关闭终端仿真器),则检查输出losetup -a并执行sudo losetup -d /dev/loopX相应的操作。

相关内容