Задача: увеличить размер виртуального диска формата RAW ("сырой", полностью соответствующий формату отображения данных на физическом дисковом носителе) до требуемого произвольного.
Представим, что прониклись мы идеями виртуализации и перевели массу мелких сервисов, потребляющих не более 10-15% ресурса гудящих и греющих выделенных железок, на рвущие и мечущие по первому времени сервера виртуализации. Лепота - куча служб, пользы невпроворот, и счета за потреблённую электроэнергию резко меньше стали. Прошёл год, как-то плавно количество клиентов увеличилось на порядок-другой, базы данных приложений разрастаются пусть ещё и не в геометрической, но уже отнюдь и не в арифметической прогрессии. В общем, вопрос расширения размеров виртуальных дисков (вслед за увеличением объёма дискового "пула") встаёт в полный рост и не терпит промедления. Сделаем это просто и наиболее эффективно, в среде Linux.
Инсталлируем приложение, манипулирующее разметкой дисков:
# aptitude install parted
Сразу обозначу момент немаловажный: к сожалению, используя UNIX-way, расширить виртуальный диск не останавливая работающей с ним виртуальной машины невозможно. Ясное дело, что разного рода "корпоративным" системам управления это вполне по плечу, но вот так запросто, "в консоли" в три команды этого пока не сделать. Потому - останавливаем целевую виртуальную машину.
Запускаем утилиту разметки дисков, натравливая её на RAW-файл:
# parted ./target.raw
....
# Первым делом выбираем в качестве единицы измерения "сектор" (прикинуть реальный объём, в байтах, занимаемый диском и разделами нетрудно - ниже приводится размер логических и физических секторов целевого блочного устройства в байтах)
(parted) unit s
(parted) print
Model: (file)
Disk ./target.raw: 251706420s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 63s 251674289s 251674227s primary ntfs boot
....
# Первым делом выбираем в качестве единицы измерения "сектор" (прикинуть реальный объём, в байтах, занимаемый диском и разделами нетрудно - ниже приводится размер логических и физических секторов целевого блочного устройства в байтах)
(parted) unit s
(parted) print
Model: (file)
Disk ./target.raw: 251706420s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 63s 251674289s 251674227s primary ntfs boot
....
В данном случае весь диск занимает один раздел, занимающий всё доступное пространство. В нашей задаче неважно, сколько разделов содержит виртуальный диск и какого типа файловые системы на них размещены - мы увеличиваем размер диска как такового.
Из вывода утилиты выше видно, что текущий размер диска составляет 251706420 сектора (это: ( 251706420B * 512 ) / 1024 / 1024 / 1024 = 120GB ). Предположим, нам нужно расширить диск на 100GB.
Прикидываем, сколько нам нужно докинуть секторов в конец диска:
( 100GB * 1024 * 1024 * 1024 ) / 512 = 209715200
Элементарно с помощью утилиты "dd" дописываем в конец целевого RAW-файла требуемое количество "нулей":
# dd if=/dev/zero of=./target.raw bs=512 seek=251706420 count=209715200
Где:
"if" - файл, источник данных;
"of" - файл, цель записи;
"bs" - объём блока данных (в байтах), которым оперирует утилита, последовательно читая и записывая таковые (указываем 512 байт для упрощённого манипулирования объёмами данных, равными размеру сектора на целевом устройстве);
"seek" - количество пропускаемых (от начала целевого файла) тактов чтения/записи (чтобы не затрагивать уже существующие данные виртуального диска);
"count" - количество отрабатываемх тактов чтения/записи (после пропуска тактов обозначенных опцией "seek"), идущих на собственно приращение объёма.
"of" - файл, цель записи;
"bs" - объём блока данных (в байтах), которым оперирует утилита, последовательно читая и записывая таковые (указываем 512 байт для упрощённого манипулирования объёмами данных, равными размеру сектора на целевом устройстве);
"seek" - количество пропускаемых (от начала целевого файла) тактов чтения/записи (чтобы не затрагивать уже существующие данные виртуального диска);
"count" - количество отрабатываемх тактов чтения/записи (после пропуска тактов обозначенных опцией "seek"), идущих на собственно приращение объёма.
Подождём минут двадцать-тридцать и утилита покажет нам, с какой скоростью и сколько данных было отработано:
209715200+0 records in
209715200+0 records out
107374182400 bytes (107 GB) copied, 1038.19 s, 103 MB/s
209715200+0 records out
107374182400 bytes (107 GB) copied, 1038.19 s, 103 MB/s
Особое внимание обращаю на то, что мы не "проскочили" весь необходимый добавочный объём и не поставили метку конца файла (секундное дело), создавая "spare"-диск ("разрежённый" файл, отображающий только реально существующие данные виртуального диска на носитель, пропуская неиспользованные до поры куски), а заполнили всё добавочное пространство нулями, создавая "preallocated"-диск ("монолитный" файл, отображающий данные виртуального диска на носитель "как есть", со всеми пропусками, готовыми к немедленному использованию).
Перед тем, как запускать виртуальную машину, удостоверимся, что диск действительно расширен на требуемый объём:
# parted ./target.raw
....
# Для наглядности выбираем в качестве единицы измерения объёма проценты
(parted) unit %
(parted) print
....
Number Start End Size Type File system Flags
1 0.00% 54.5% 54.5% primary ntfs boot
....
# Для наглядности выбираем в качестве единицы измерения объёма проценты
(parted) unit %
(parted) print
....
Number Start End Size Type File system Flags
1 0.00% 54.5% 54.5% primary ntfs boot
....
Видно, что ранее на 100% задействованный диск теперь занят единственным разделом лишь на 54%. Теперь у нас имеется возможность добавить новый раздел или растянуть существующий до нужного размера. Вопросы методики манипулирования разметкой разделов и размещённых на таковых файловых системам будут освещены чуть позже, в отдельной заметке.