Рейтинг:3

Извлечение смолы из многотомной ленты при вычислении шасумов

флаг cn

В рамках нашей системы резервного копирования мы реплицируем наборы данных zfs из системы TrueNAS на пару серверов резервного копирования, на одном из которых работает TrueNAS Scale и к которому подключен ленточный накопитель LTO-5. Иногда мы записываем на ленту одно из содержимого моментального снимка, доступного только для чтения. Поскольку некоторые из этих наборов данных большие, tar используется с флагом --multi-volume.

Перед резервным копированием sha256sums генерируются для каждого файла в каталоге моментальных снимков. Копия этого файла хранится на сервере и также записывается на ленту.

После этого все содержимое снимка записывается на ленту с помощью

  tar --acls --xattrs --spares --label="SomeLabel" --multi-volume -cvpf /dev/nst0 *

Это сослужило нам хорошую службу, однако я хочу проверить данные после того, как они будут записаны на ленту. Я хочу избежать необходимости извлекать весь набор файлов данных в пустое место, которое в противном случае позволило бы запустить «sha256sum -c», поскольку сервер масштабирования TrueNAS не имеет достаточного дополнительного пространства для извлечения некоторых наборов данных. Вместо этого я попытался: -

  tar --multi-volume -xf /dev/nst0 --to-command=tar-shasums.sh | тройник проверить-datasetname.sha25sum

Где tar-shasums.sh находится в следующих строках:

#!/бин/баш

sha1=`sha1sum`
эхо -n $sha1 | sed 's/ .*$//'
эхо "$TAR_FILENAME"

Однако я столкнулся с проблемой, если tar охватывает две ленты. Когда tar находится в процессе чтения файла, занимающего две ленты, он запросит вставку следующего тома и нажмет Enter. Однако это приведет к ошибке, поскольку устройство используется.

Похоже, что "--to-command" все еще активен для этого файла, так как он еще не получил все данные для создания шасума, но он также не может завершиться, пока лента не будет заменена, но лента не может быть изменена до тех пор, пока оно закончилось...

В настоящее время я убиваю процесс shasum, что позволяет tar продолжать работу со следующей лентой, но означает, что один файл, охватывающий два тома, не может быть проверен.Если этот файл не извлечен и не проверен вручную. Не идеально.

Я ожидаю, что нет, но есть ли способ обойти это? Есть ли способ генерировать шасумы, который не требует предварительного извлечения всего tar на диск? Или какой-либо способ снять блокировки на /dev/nst0, чтобы позволить tar продолжить чтение с только что вставленной ленты без необходимости убивать shas256sum?

Gerard H. Pille avatar
флаг in
Что, если tar-экстракт будет писать в именованный канал, а она будет читать из этого канала?
флаг cn
Вчера вечером я просмотрел исходный код tar, и похоже, что «--to-command» действительно создает канал, который затем использует fork для запуска сценария и передает ему данные файла. Эта вилка приводит к тому, что все родительские файловые дескрипторы, т.е. tar, передаются сценарию, включая /dev/nst0, а не только канал, из которого сценарий считывает данные. Имейте в виду, что причина использования --to-command заключается в том, что она выполняется для каждого файла, извлеченного из tar, поэтому вы можете генерировать контрольные суммы для каждого файла, а не для tar-архива в целом.
Рейтинг:1
флаг cn

Вчера вечером я просмотрел исходный код tar, и похоже, что «--to-command» действительно создает канал, который затем использует fork для запуска сценария и передает ему данные файла.

Итак, проблема в том, что fork приводит к тому, что разветвленный процесс наследует все файловые дескрипторы родителей, включая устройство /dev/nst0, открытое tar. Затем Tar закрывает /dev/nst0, готовый к смене носителя, но разветвленный процесс, ожидающий дополнительных передаваемых данных, все еще имеет его открытым, следовательно, тупик.

Я частично обошел это, изменив запускаемый скрипт, чтобы он всегда закрывал дескриптор /dev/nst0.

УСТРОЙСТВО=/dev/nst0
файл=`lsof -p $$ | grep ${УСТРОЙСТВО} | awk '{напечатать $4}'`
файл=${файл::-1}
eval "exec ${файл}<&-"

Тогда есть только один процесс «sh», который, кажется, все еще держится за дескриптор файла. «fuser -u /dev/nst0» показывает это, и в качестве временного обходного пути можно использовать gdb, чтобы закрыть его, после чего носитель изменится, а оставшиеся контрольные суммы сгенерируются правильно.

gdb -p PID
р близко (FD)

Я не уверен, можно ли использовать разветвление, но не передавать все дескрипторы файлов разветвленному процессу, но похоже, что это будет окончательное решение.

Я обновлю этот ответ, если выясню это.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.