Резервное копирование на флеш-накопитель с помощью rsync

На первый взгляд, это простая dd:

dd if=sparsefile of=sparsefile conv=notrunc bs=1M

Которая считывает весь файл и записывает в него все содержимое обратно.

Чтобы записать только саму дыру, сначала нужно определить, где находятся эти дыры. Вы можете сделать это, используя либо filefrag, либо hdparm:

filefrag:

# filefrag -e sparsefile
Filesystem type is: 58465342
File size of sparsefile is 10737418240 (2621440 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0.. 1048575:  187357696.. 188406271: 1048576:            
   1:  1572864.. 2621439:  200704128.. 201752703: 1048576:  188406272: last,eof
sparsefile: 2 extents found

hdparm:

# hdparm --fibmap sparsefile

sparsefile:
 filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0 1498861568 1507250175    8388608
  6442450944 1605633024 1614021631    8388608

Этот файл примера, как вы говорите, имеет размер 10G с отверстием 2G. Он имеет два экстенциала, первый охватывает 0-1048575, второй 1572864-2621439, что означает, что отверстие имеет размер 1048576-1572864 (в блоках размером 4 кб, как показано в filefrag). Информация, показанная в hdparm, та же самая, просто отображается по-другому (первая степень охватывает 8388608 512-байтовые сектора, начиная с 0, так что это 0-4294967295 байты, так что отверстие находится в 4294967296-6442450944 в байтах.

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

Заполнение этого отверстия 1048576-1572864 dd, как показано выше, может быть сделано путем добавления соответствующих (идентичных) значений seek/skip и счета count. Обратите внимание, что bs= был адаптирован для использования секторов 4k, как это использовалось в filefrag выше. (Для bs=1M необходимо было бы адаптировать значения поиска/пропуска/счета для отражения блоков размера 1M).

dd if=sparsefile of=sparsefile conv=notrunc \
   bs=4k seek=1048576 skip=1048576 count=$((-1048576+1572864))

Хотя вы можете заполнить дыры с помощью /dev/zero вместо чтения дыры в самом файле (что также даст только нули), в любом случае безопаснее читать из разреженного файла /dev/zero, чтобы не повредить данные в случае, если вы получили неправильное смещение.

В новых версиях GNU dd вы можете придерживаться большего размера блока и указывать все значения в байтах:

dd if=sparsefile of=sparsefile conv=notrunc bs=1M \
   iflag=skip_bytes,count_bytes oflag=seek_bytes \
   seek=4294967296 skip=4294967296 count=$((-4294967296+6442450944))

filefrag после выполнения этого:

# sync
# filefrag -e sparsefile 
Filesystem type is: 58465342
File size of sparsefile is 10737418240 (2621440 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0.. 1572863:  187357696.. 188930559: 1572864:            
   1:  1572864.. 2621439:  200704128.. 201752703: 1048576:  188930560: last,eof
sparsefile: 2 extents found

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

Естественно, это решение dd является очень ручным подходом к вещам. Если вам это нужно регулярно, то будет легко написать небольшую программу, которая заполнит такие пробелы. Если она уже существует как стандартный инструмент, то я о ней еще не слышал.


В конце концов, инструмент все-таки есть, fallocate, кажется, работает, в каком-то смысле:

fallocate -l $(stat --format="%s" sparsefile) sparsefile

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

   2:        3..      15:    7628851..   7628863:     13:    7629020: unwritten

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

0
14.12.2014, 23:08
1 ответ

Это уже делает полную резервную копию. Содержимое каталогов, которые исключаются (например, dev, run, etc), создаются во время выполнения и не должны быть созданы резервными копиями.

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

Использование rsync вот правильный метод, так как rsync может работать в одной и той же системе или удаленно, и он также будет только обновлять изменения файлов, не буду держать копирование все каждый раз. Если вы регулярно выполняете эту команду, вы также можете добавить «--delete» до конца команды, чтобы она удалила удаленные файлы из пункта назначения.

Кроме того, вы, возможно, захотите добавить опции rsync для него для предопределения жестких ссылок.

1
28.01.2020, 02:51

Теги

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