我的测试环境

我的测试环境

LVM 是一款非常有用的工具,但它似乎仍然不支持对已经是快照的驱动器进行快照。我编写了一个脚本来自动处理这个问题,但遇到了一些麻烦。

我的测试环境

我正在一个干净的 Xen-box 上测试该脚本(从现在开始:测试箱)。创建框后,我创建了一个新的 LVM 卷并将其添加到测试箱的驱动器。在测试箱本身,它显示为普通块设备,所以我不认为 Dom0 的 LVM 应该干扰测试过程。

原装驱动器

测试箱,我使用以下命令创建了一个新的分区:

# Using the data in the other tables i determined 
# where i could begin my new device sectors
dmsetup table

# Create the new device without a table
dmsetup create base --notable
# Put the table into the device...
echo '0 4194304 linear 202:2 0' | dmsetup load base
dmsetup resume base

mkfs.ext2 /dev/mapper/base

需要明确的是,第二个目标参数“202:2”是我添加到测试箱机器的第二个设备,我像这样仔细检查了它:

ls /dev -l | grep 'xvda2'

返回:

brw-rw---- 1 根磁盘 202,2 月 3 日 17:01 xvda2

剧本

我编写了这个函数来制作快照:

function create_dm_snapshot {
  banner "0: Checking if block devices don't allready exist, original device should exist...";
  device_exists $base_path$original;
  [ $? -eq 0 ] || error 'The source (original) device should exist';
  device_exists $base_path$snapshot_origin $base_path$snapshot $base_path$cow;
  [ $? -eq 0 ] && error "They allready exist pls use the 'remove' function";
  echo "Done checking.";  

  banner "1: Suspending the original device.";
  suspend_dev $original || error "Failed suspending original device";

  banner "2: Creating snapshot-origin.";
  create_dev $snapshot_origin || error "Failed creating snapshot-origin";

  banner "3: Read original table into snapshot-origin.";
  dmsetup table $original | dmsetup load $snapshot_origin ||
    error 'Failed loading original table into snapshot-origin';
  echo "Done reading.";

  banner "4: Resume snapshot-origin.";
  resume_dev $snapshot_origin || error 'Could not resume snapshot-origin';

  banner "5: Create snapshot device.";
  create_dev $snapshot || error 'Failed to create snapshot device';

  banner "6: Create COW-device.";
  #TODO: check total sector count device
  create_dev $cow ;
  target_device=$( dmsetup table $original | awk '{print $4}' );
  last_table=$( dmsetup table | grep "$target_device" | awk '{print $6}' | sort -g | tail -n 1 );
  begin_sector_args=( $( dmsetup table | grep -E $target_device".*"$last_table"|"$last_table".*"$target_device | awk '{print $2 " " $3 " " $6}' ) );
  begin_sector=$( expr ${begin_sector_args[1]} - ${begin_sector_args[0]} + ${begin_sector_args[2]} );
  table="0 $size linear $target_device $begin_sector";
  echo $table | dmsetup load $cow;
  resume_dev $cow;

  banner "7: Calculate rowcount in snapshot-origin";
  snapshot_origin_size=$( blockdev --getsz $base_path$snapshot_origin ) ||
    error 'Could not determine rowcount';
  echo "Snapshot size: $snapshot_origin_size";

  banner "8: Load snapshot table.";
  table="0 $snapshot_origin_size snapshot $base_path$snapshot_origin $base_path$cow p 64";
  [ $verbose ] && echo "Table: $table";
  echo $table | dmsetup load $snapshot || error 'Failed loading snapshot table';
  echo "Done loading.";

  banner "9: Reload original device table.";
  table="0 $snapshot_origin_size snapshot-origin $base_path$snapshot_origin";
  [ $verbose ] && echo "Table: $table";
  echo $table | dmsetup load $original || error 'Failed reloading original table';
  echo "Done reloading.";

  banner "10: Resume frozen tables.";
  resume_dev $snapshot $original || error 'Could not resume devices';
  echo "Done resuming.";
}

错误

在步骤 8(横幅“8:...)时,脚本失败并出现以下错误:

设备映射器:重新加载 ioctl 失败:没有此设备或地址

命令失败

dmsetup table

结果如下表数据:

dm.base.snapshot_origin:0 4194304 线性 202:2 0

基数:0 4194304 线性 202:2 0

dm.base.快照:

dm.base.cow:0 4096 线性 202:2 4194304

由于我无法确定错误的原因,所以我做的最后一步是查看我的 dmesg……

dmesg | tail

Giving me:

PM:0.080 毫秒后设备冻结完成

暂停 xenstore...

下午:设备延迟冻结在 0.019 毫秒后完成

PM:设备早期恢复在 0.035 毫秒后完成

PM:设备恢复在 32.367 毫秒后完成

将容量设置为 10485760

将容量设置为 104857600

设备映射器:持久快照:快照无效或损坏

设备映射器:表:254:2:快照:无法读取快照元数据

设备映射器:ioctl:将目标添加到表时出错

我无法找出导致快照损坏的原因。

答案1

在干净的 Xen-box 上测试脚本

这并不能保证导出的磁盘在未写入区域中只包含零。因此,内核可能会检测到实际上不存在的东西。您应该覆盖 COW 卷的第一部分(我不知道需要多少,但前 4 MiB 应该足够了。哦,您的 COW 卷大小甚至不到 4 MiB:

dd if=/dev/zero of=/dev/mapper/dm.base.cow bs=4K count=1024

也许 COW 卷有一个最小尺寸,而您的卷太小了?

相关内容