Как можно обмануть программы, заставив их думать, что они не передаются по конвейеру?

TL;DR:Использование параметра -c, как описано выше, в целом работает. Когда снимки содержат жесткие ссылки, в ядре Linux возникает ошибка, которая вызывает ошибку при отправке снимков — подробности см. в заключении в конце ответа.


Я экспериментирую с параметром -c, и он выглядит многообещающе:

# for i in {0..3}; do btrfs send testvol_$i $(ls -d testvol_* | head -n$i | sed 's/^/-c /'); done | wc -c
### btrfs send testvol_0
### btrfs send testvol_1 -c testvol_0
### btrfs send testvol_2 -c testvol_0 -c testvol_1
### btrfs send testvol_3 -c testvol_0 -c testvol_1 -c testvol_2
At subvol testvol_0
At subvol testvol_1
At subvol testvol_2
At subvol testvol_3
838778546    # also 800MiB

Я до сих пор не уверен, что это то, что мне нужно. Есть комментарии к этому решению?

Обновление:Чтобы проверить это на моей реальной файловой системе, я написал сценарий Perl для удобной отправки набора подтомов (, создание списков для -cбыстро стало утомительным )и отправил некоторые данные в/dev/null:

#!/usr/bin/env perl

use strict;
use warnings;

my @subvols = @ARGV
  or die "Usage: $0 SUBVOLUME...\n";

for(@subvols) {
    -d $_
      or die "Not a directory: $_\n";
}

for my $i (0.. $#subvols) {
    my $subvol = $subvols[$i];
    my @clones = map { ('-c', $_) } @subvols[ 0.. $i-1 ];
    print "btrfs send $subvol @clones\n";
}

Результаты:

  • btrfs send some-subvolme_* | pv > /dev/null:24 ГБ 0 :04 :17 [95,2 МБ/с]
  • perl btrfs-send-all.pl some-subvolume_* | bash | pv > /dev/null:12,7 ГБ 0 :03 :58 [54,7 МБ/с]

Это незначительное увеличение производительности, но почти 50-процентное уменьшение объема памяти ! Сейчас я пытаюсь запустить это в реале…

Обновление:Я успешно перенес 2 снимка, но для третьего btrfs receiveпроизошел сбой со следующим сообщением об ошибке:

ERROR: unlink path/to/some/file/in/the/snapshot failed. No such file or directory

Именованный файл присутствует в subvol_2и subvol_3, но еще не в subvol_1.

Я пытался сравнить отправленные и полученные снимки:

# ### sender
# du -s subvol_{1,2,3}
132472304       subvol_1
117069504       subvol_2
126015636       subvol_3

# ### receiver
# du -s subvol_*
132472304       subvol_1
117069504       subvol_2
132472304       subvol_3

Первые два снимка передаются правильно, но subvol_3является клоном subvol_1. Это определенно клон, потому что используемое пространство на резервном диске составляет всего 39% от совокупного размера моментальных снимков — чуть больше 1/3, поскольку они совместно используют большинство файлов.

Почему btrfs send subvol_3 -c subvol_1 -c subvol_2 | btrfs receiveнеправильно передает снимок, а клонирует subvol_1, а затем не может удалить файл, который должен храниться в subvol_3и присутствует только в subvol_2??

Обновление:Может ли это быть ошибкой?https://patchwork.kernel.org/patch/10073969/

Я использую Debian 9 Stretch с ядром 4.9, которое кажется более старым, чем патч.

Обновление:Поскольку я не смог найти никакого решения, я просто скопировал самый последний моментальный снимок каждого подтома. Затем у меня было примерно 500 ГБ свободного места, и я попытался добавить предыдущий снимок с параметром уже скопированный снимок как -p. Затем я получил то же сообщение об ошибке для того же снимка, что и выше.

Заключение:Я пришел к выводу, что столкнулся с ошибкой, указанной выше.Мне пришлось перезагрузить эту машину с более новым ядром Linux или получить доступ к файловой системе с другого компьютера, но это невозможно, потому что это производственная система.

До сих пор у меня не было проблем с btrfs, но запуск rsnapshot, который создает много жестких ссылок, и отправка снимков btrfs все еще могут вызывать проблемы в текущей стабильной версии Debian.

0
26.02.2021, 01:09
1 ответ

Не уверен, что это хорошее решение, но на основанииhttps://stackoverflow.com/questions/4233808/piping-data-to-linux-program-which-expects-a-tty-terminalкажется, что unbufferвыполняет это.

unbuffer exa | lessпокажет цвета.

1
18.03.2021, 22:28

Теги

Похожие вопросы