Снимки нескольких поколений с использованием Device Mapper (Linux)

LVM - удивительно полезный инструмент, однако, похоже, ему по-прежнему не хватает поддержки моментального снимка диска, который уже является моментальным снимком. Я сделал скрипт для автоматической обработки, но столкнулся с некоторыми проблемами.

Моя тестовая среда

Я тестирую скрипт на чистой Xen-коробке (с этого момента: testbox). После создания коробки я создал новый том LVM и добавил его на диски testbox. В самом testbox он отображается как обычное блочное устройство, поэтому я не думаю, что LVM Dom0 должен мешать процессу тестирования.

Оригинальный диск

На testbox я создал новый раздел, используя следующие команды:

# 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: 20

база: 0 4194304, линейная 202: 2 0

dm.base.snapshot:

dm.base.cow: 0 4096 линейный 202:2 4194304

Так как я не смог определить причину ошибки, последний шаг, который я сделал, - заглянул в мой dmesg...

dmesg | tail

Giving me:

PM: заморозка устройств завершена после 0,080 мсек

приостановка работы xenstore...

PM: поздняя заморозка устройств завершена после 0,019 мсек

PM: раннее восстановление устройств завершено после 0,035 мсек

PM: восстановление устройств завершено после 32,367 мсек

Установка емкости до 10485760

Установка емкости до 104857600

устройство-сопоставитель: постоянный снимок: неверный или поврежденный снимок

устройство-сопоставление: таблица: 254:2: снимок: не удалось прочитать метаданные снимка

device-mapper: ioctl: ошибка при добавлении цели в таблицу

Я не смог выяснить, что послужило причиной повреждения снимка.

1 ответ

Решение

тестирование скрипта на чистой Xen-коробке

Это не гарантирует, что экспортированные диски будут содержать только нули в неписанных областях. Таким образом, ядро ​​может обнаружить что-то, чего на самом деле нет. Вы должны перезаписать первую часть тома COW (я не знаю, сколько нужно, но первых 4 МБ должно хватить. О, ваш объем COW даже не равен 4 МБ:

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

Может быть, есть минимальный размер для объемов COW, а ваш просто слишком мал?

Другие вопросы по тегам