Я скопировал USB-накопитель в файл .img используя dd:

dd if=/dev/sdc of=myimage.img

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

  • Как мне изменить myimage.img чтобы иметь меньший раздел после монтирования по петле ?

  • Нужно ли копировать нули в пустую часть раздела перед этим?

  • Нужно ли выполнять дефрагментацию, чтобы при уменьшении размера изображения я удалял пустые байты? (Из того, что я прочитал, Linux распространяется на весь раздел, поэтому я не ожидаю, что все данные в конце образа будут нулевыми байтами. Даже запись всех нулей будет просто потреблять пустые байты, где бы они ни лежали.)

ПРИМЕЧАНИЕ. Я не пытаюсь сэкономить место на диске, поэтому архивирование мне не поможет.

ФОН

У меня Linux установлен на USB-накопитель с использованием ext4 . Я намерен продублировать установку для нескольких устройств. Я сделал это успешно, но хотел бы создать на том же USB-накопителе раздел только для чтения с системой и небольшой раздел, обеспечивающий постоянное хранение. Вместо того, чтобы сломать мой USB, я пытаюсь изменить копию USB. Я надеюсь, что мы не отвлекаемся на этот фон.

Короче говоря, я сделал следующее:

# Create mount point in current directory
sudo mkdir mnt
# Loopback mount the image
fdisk -l myimage.img
sudo mount -o offset=<partion_block_start * block_size> myimage.img mnt
# Copy all zeros to remaining space of the image
cd mnt
sudo dd if=/dev/zero of=filler conv=fsync bs=1M
rm filler
cd ..

Во- первых, я пытался использовать parted , как описано в этом доступа привилегированного ответа и qemu-img , как описано в этом другом доступа привилегированного ответ.

sudo umount mnt
parted myimage.img
# At parted command prompt
(parted) resizepart 1
# Entered my end <target size>. Note that parted uses zero-based 
# indexing. This could be your final image size. In my case, the way the
# Linux installer worked, the partition started at 1M.
(parted) print
# I see that the partition is now sized as I expect
(parted) exit
# Just another sanity check
sudo parted -m esp3_007.img unit B print
# I see that the partition is now sized as I expect

Когда я пытаюсь снова смонтировать образ, он работает нормально, но df прежнему показывает раздел в том же размере. Итак, я попытался

qemu-img resize myimage.img <target_size>

И теперь, когда я пытаюсь смонтировать образ, я получаю сообщение об ошибке «mount: неправильный тип fs, неверный параметр, плохой суперблок ...».

Затем я попытался использовать gparted как описано в этом посте за пределами сайта. GUI показывал полный раздел, если я не запускал parted в первую очередь. Даже тогда графический интерфейс не позволил бы мне изменить размер раздела.

Чтобы попытаться уменьшить размер раздела и начать с новой копии myimage.img я попытался использовать fdisk описанный в этом ответе AskUbuntu.

sudo fdisk myimage.img
Command (m for help): d
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4, default 1): 1
# defaults on the rest seemed to be correct in my case.

Когда я смонтировал раздел, он все еще показывал тот же размер.

1 ответ1

4

На изображениях петли

Прежде всего, забудьте offset= , используйте losetup --partscan и просто смонтируйте раздел через /dev/loop0p1 .

# losetup --partscan /dev/loop0 myimage.img
# lsblk
# mount /dev/loop0p1 /mnt

Чтобы эффективно очистить пустое пространство внутри раздела, запустите fstrim в файловой системе, смонтированной в цикле, так же, как в SSD. (Это на самом деле сделает файл изображения разреженным.)

# fstrim -v /mnt

При изменении размера разделов

Но сейчас вам не нужно очищать пустое пространство или делать что-то подобное. Заполнена ли область, которую нужно урезать, нулями или порциями старых данных, совершенно не имеет значения.

Вместо этого вам нужно сделать то же самое, что и с ext4 на реальном диске - вам нужно сжать каждый слой изнутри. Вы не можете пропустить шаги только потому, что это изображение.

Чтобы сжать раздел, содержащий файловую систему, вы должны сначала указать файловой системе сжать себя. Для ext2/3/4 это делается с помощью resize2fs . Это переместит данные, которые могут находиться в области, которую вы собираетесь отрубить, и сохранит новые границы как часть метаданных файловой системы. (Я полагаю, это то, что вы подразумевали под "дефрагментацией".)

Только после того, как файловая система была сокращена, вы также можете сжать раздел, содержащий ее. Это можно сделать с помощью parted или fdisk, просто изменив конечный адрес раздела.

Примечание: у вас должна быть возможность использовать GParted для изменения размера файловой системы и раздела за один шаг - если он поддерживает работу на петлевых устройствах, то есть. Это может зависеть от версии GParted. (Однако CLI parted не может сжать файловые системы, он просто усекает раздел.)

Наконец, после изменения размера файловой системы и раздела вы можете обрезать весь образ, содержащий их. Для этого сначала отсоедините устройство цикла и используйте truncate --size=... в вашем файле изображения.

(Чтобы сделать это безопасно, без необходимости делать тщательные вычисления, я бы сжал файловую систему немного больше, чем нужно для создания некоторого «буферного» пространства; например, если бы я хотел образ 4 ГБ, я бы сжал файловую систему до 3 ГБ, раздел до 3,5 ГБ, а затем обрежьте изображение до 4 ГБ. Затем увеличьте все в обратном порядке, чтобы заполнить пространство «буфера».)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .