У меня есть куча образов дисков, созданных с помощью ddrescue, в разделе EXT, и я хочу уменьшить их размер без потери данных, оставаясь при этом монтируемым.
Как я могу заполнить пустое пространство в файловой системе изображения нулями, а затем преобразовать файл в разреженный файл, чтобы это пустое пространство фактически не сохранялось на диске?
Например:
> du -s --si --apparent-size Jimage.image
120G Jimage.image
> du -s --si Jimage.image
121G Jimage.image
Это на самом деле имеет только 50G реальных данных, поэтому второе измерение должно быть намного меньше.
Это предположительно заполнит пустое пространство нулями:
cat /dev/zero > zero.file
rm zero.file
Но если разреженные файлы обрабатываются прозрачно , он может фактически создать разреженный файл, ничего не записывая на виртуальный диск, иронически не давая мне превратить образ виртуального диска в сам разреженный файл. :) Является ли?
Примечание: по какой-то причине sudo dd if=/dev/zero of=./zero.file
работает, когда cat
нет на смонтированном образе диска.
источник
sudo cat /dev/zero > zero.file
не работает, потому что ваш bash (работает как вы, а не root) выполняет перенаправление перед выполнениемsudo
команды. См. Unix.stackexchange.com/questions/1416/…Ответы:
Прежде всего, разреженные файлы обрабатываются прозрачно только при поиске, а не при записи нулей.
Чтобы было понятнее, пример из Википедии
ничего не писать никаких нулей, он будет открыть выходной файл, искать (перепрыгнуть) 5МБЫ , а затем записать нулевые нули (т.е. вообще ничего). Эта команда ( не из Википедии)
напишет 5 МБ нулей и не создаст разреженный файл!
Как следствие, файл, который уже не является разреженным, волшебным образом не станет разреженным позже.
Во- вторых, чтобы сделать файл с большим количеством нулей разреженным, вы должны сП это
или вы можете использовать опцию tar или rsync --sparse.
источник
cat /dev/zero > zero.file
все в порядке, чтобы заполнить пустое пространство нулями?dd
для записи нулей или для поиска.cat
команда заполнит весь ваш диск (или хотя бы сумму, не зарезервированную для root или квотами) "реальными" нулями и не создаст разреженных файлов.Возможно, самый простой способ разбить файл на месте - использовать
fallocate
утилиту следующим образом:fallocate (1) предоставляется пакетом util-linux в Debian .
источник
fallocate --dig-holes
получил файл 103GiB из оригинала 299GiB, аcp --sparse=always
мне дали 93GiB - все с той же суммой SHA1 (размеры проверены черезdu -B1G
vsdu --apparent-size -B1G
). Так что,fallocate
похоже, дает худшие результаты.Редактирую мой ответ для полноты:
losetup --partscan --find --show disk.img
Предположим, что он дает / dev / loop1 в качестве диска и есть только один раздел, в противном случае нам нужно повторить это для каждого раздела с монтируемой FS в нем (игнорировать раздел подкачки и т. Д.).
mkdir -p /mnt/tmp mount /dev/loop1p1 /mnt/tmp dd if=/dev/zero of=/mnt/tmp/tempfile
Пусть это закончится неудачей с ENOSPC.
/bin/rm -f /mnt/tmp/tempfile umount /mnt/tmp losetup -d /dev/loop1
У 'dd' есть опция для преобразования файла с нулями в разреженный файл:
dd if=disk.img of=disk-sparse.img conv=sparse
источник
zerofree
может быть быстрее, чем монтировать и записывать нули в файловую систему, и уменьшать размер образа диска, если он уже содержит много нулей.Вы имеете в виду, что ваш образ, созданный ddrescue, скажем, 50 ГБ, и в действительности чего-то гораздо меньшего будет достаточно?
Если это так, не могли бы вы сначала создать новое изображение с помощью dd:
а затем создайте в нем файловую систему:
затем просто смонтировать образ и скопировать все со старого образа на новый? Будет ли это работать для вас?
источник
PartImage может создавать образы дисков, которые хранят только используемые блоки файловой системы, таким образом, значительно сокращая требуемое пространство, игнорируя неиспользуемые блоки. Я не думаю, что вы можете напрямую смонтировать полученные изображения, но собираюсь:
Должен производить то, что вы хотите (возможно, даже можно придерживаться последнего шага, не пытался).
источник
Теперь есть инструмент под названием virt-sparsify, который сделает это. Он заполняет пустое пространство нулями, а затем копирует изображение в разреженный файл. Это требует установки большого количества зависимостей, хотя.
источник
Я подозреваю, что вам потребуется специальная программа, написанная для этой спецификации, если это действительно то, что вы хотите сделать. Но так ли это ...?
Если у вас на самом деле много областей с нулевым заполнением, то любой хороший инструмент сжатия значительно его сломает. И попытка записи разреженных файлов не будет работать во всех случаях. Если я правильно помню, даже разреженные файлы занимают минимум 1 блок памяти вывода, где блок ввода содержит ЛЮБЫЕ биты, которые не равны нулю. Например - скажем, у вас был файл, который имел в среднем даже 1 ненулевой бит на блок 512 байт - его нельзя записать «редко». Кстати, вы не потеряете данные, если сжимаете файл с помощью zip, bzip, bzip2 или p7zip. Они не похожи на сжатие mpeg или jpeg с потерями.
С другой стороны, если вам нужно выполнить произвольное чтение в файл, тогда сжатие может оказаться более трудным, чем оно того стоит, и вы вернетесь к разреженной записи. Компетентный программист на C или C ++ должен уметь написать что-то подобное за час или меньше.
источник
cp --sparse=always
отлично работает