Я создал Ubuntu 12.04 32-битную виртуальную машину в VirtualBox с диском .vdi. Затем я монтирую этот диск с помощью qemu-nbd и перемещаю все файлы с него; затем обратно на него. Когда я снова загружаю виртуальную машину, я получаю разные результаты:
- Ubuntu сообщает мне, что произошла ошибка, и спрашивает, хочу ли я исправить/пропустить/игнорировать/исправить вручную. Если я исправлю, он перезагрузится и загрузится на tty. Если я проигнорирую, он загрузится на tty. Я еще не пробовал пропускать/исправлять вручную.
- Загрузка с пустым фиолетовым экраном. Зависание. При последующих сбросах загрузка с мигающим текстовым курсором.
- Загрузка до заставки Ubuntu, зависание. При сбросе см. номер 1 в этом списке.
Мой вопрос:: почему это происходит? Есть ли какой-то адрес оборудования диска в Grub, ссылающийся на /boot/? Есть ли способ удалить и заменить файлы в VHD без этой проблемы?
Как воспроизвести этот результат (я надеюсь):
- Создайте виртуальную машину в VirtualBox, используя виртуальный диск .vdi объемом 8 ГБ (называемый ub.vdi, для целей оставшейся части вопроса)
- Загрузите установочный ISO-образ Ubuntu 12.04.3 32-бит
- «Попробуйте Ubuntu».
- Создайте таблицу разделов MSDOS и два основных раздела, пространство подкачки размером 2048 МБ, остальное — раздел ext4. (Использовал gparted).
- Установить Ubuntu на раздел ext4
- Выключите виртуальную машину.
- Перейдите в каталог вашей виртуальной машины и запустите следующий скрипт:
#!bin/bash
# load the nbd module
sudo modprobe nbd
# make a folder for our virtual disk files
mkdir os_files
# load the virtual disk as a device (nbd0)
sudo qemu-nbd -c /dev/nbd0 ub.vdi
sleep 1
# create a directory and mount the os partition to it
MNT_DIR=$(mktemp -d)
sudo mount /dev/nbd0p2 $MNT_DIR
# move the os files off, then back onto the virtual disk
find $MNT_DIR -maxdepth 1 -mindepth 1 | xargs -I{} sudo mv {} os_files/
find os_files/ -maxdepth 1 -mindepth 1 | xargs -I{} sudo mv {} $MNT_DIR
# clean up
sudo umount $MNT_DIR
sudo qemu-nbd -d /dev/nbd0
rm os_files/ $MNT_DIR -r
unset MNT_DIR
Зачем ты это делаешь?
В рамках контрактного требования мне нужно хранить виртуальный диск в системе контроля версий. Наличие огромного двоичного блоба (виртуального диска) в системе контроля версий — это боль, в основном для клонирования (git)/выписки (svn), но также и для diff. Я рассматривал возможность разделения на несколько файлов, но мне нужно иметь возможность манипулировать ОС/данными, извлеченными в (5) выше. Обратите внимание, что моему репозиторию VCS по-прежнему нужна вся информация, необходимая для построения полной виртуальной машины.
Смотрите также:https://superuser.com/questions/641971/manual-clone-recreate-virtual-disk. Извините, если повторная публикация покажется вам неуместной/неблагодарной/неидиоматической/грубой; ответы, которые я получил в SU, хотя и были полезными, просто не имели достаточной квалификации, чтобы решить мою проблему. Пожалуйста, обратите внимание, что вопрос, который я задал здесь, немного более конкретен, чем тот, по ссылке, но любые идеи, которые полностью обходят проблему, более чем приветствуются.
решение1
Загрузчику нужно найти какой-то файл в определенном месте. Ubuntu использует Grub в качестве загрузчика по умолчанию, а Grub содержит драйвер файловой системы, который он использует для загрузки ядра Linux, но Grub нужно найти свой драйвер файловой системы. Более того,
Если вы попытаетесь воссоздать виртуальную машину с нуля, создав пустой диск и разбив его на разделы, все будет еще хуже: на диске не будет загрузчика.
В качестве дополнительного шага восстановления вам нужно переустановить загрузчик. Я думаю, что следующая команда должна это сделать (вам может понадобиться несколько других опций, чтобы убедиться, что Grub включает необходимые драйверы устройств):
/usr/sbin/grub-install --root-directory="$MNT_DIR" /dev/nbd
и убедитесь, что /boot/grub/device.map
содержит
(hd0) /dev/nbd
Обратите внимание, что это device.map
не сработает, если вы запустите grub-install
в виртуальной машине. Если это имеет значение, либо сохраните и восстановите device.map
около grub-install
вызова, либо вручную вызовите низкоуровневую команду, которая grub-install
в конечном итоге запустится.
Альтернативным подходом будет настройка вашей виртуальной машины с помощью небольшого загрузочного диска, содержащего только загрузчик, который вы не будете возражать против создания с нуля каждый раз (или вы можете кэшировать созданную копию каждый раз, когда меняется загрузчик, что должно происходить редко).