среда, 7 декабря 2005 г.

Безопасное использование VMWare 5.0 (или о том как сделать бесконечный винт)

На моем ноутбуке установлены две операционные системы - Linux и Windows XP. До не давнего времени меня это вполне устраивало, загружался в винду я раз в месяц, чтобы поиграть в какую-нибудь игру. И вот вчера я поставил одну нужную мне программу, которая к сожалению есть только для Windows, а работать то всеже хочется в основном в linux вот и встал вопрос об одновременной работе обеих операционных систем на одном компьютере. На первый взгляд все очень просто: ставим VMWare настраиваем ее и вот все готово. Но на самом деле.... на самом деле не хочется делать полностью виртуальную машину, ставить новую windows и все программы, а хочется использовать уже установленную.. вот тут-то и начинается самое веселое.

А суть проблемы вот в чем. VMWare позволяет использовать существующие диски, но как выяснилось в процессе, доступ ей необходим ко ВСЕМУ винчестеру, а не только к той партиции которая реально с этого винчестера нужна. В моем случае windows установлена на /dev/hda1, linux swap на /dev/hda2, сам linux на /dev/hda3. Таким образом, чтобы использовать раздел /dev/hda1 в качестве раздела внутри vmware я должен добавить в конфигурацию виртуальной машины /dev/hda. А что тут такого, надо указать /dev/hda ну и укажем, подумаешь. На самом деле, указать мало, надо еще дать права чтения-записи /dev/hda пользователю который собирается работать в vmware с windows. А ведь /dev/hda это не только windows, но еще и swap и собственно сам раздел с linux. Это ж такая дырка не хилая получается, что уж почти тоже самое работать из под root все время.

I. Первый небезопасный способ.
Да можно просто дать права на /dev/hda и не страдать, если руки не шаловливые, если незнакомые программы не пускаем, если данные не жалко, если не параноик, то смело прописываем себя в /etc/groups в группу disks или делаем:
chmod 660 /dev/hda
chown akshaal:root /dev/hda
или даже более правильное:
cp -r /dev/hda /dev/hdw
chown akshaal:root /dev/hdw
chmod 600 /dev/hdw
Потом создаем виртуальную машину, выбираем для диска физический диск, говорим, использовать определенные партиции: помечаем hda1, а остальные не трогаем. Грузим виртуальную машину и видим LI 1919191919191919(19) или если у нас grub, то видим error 17. Это означает, что наши любимые загрузчики не смогли прочитать куски своих жирных туш находящихся в тех партициях которые мы не включили. В моем случае, это /dev/hda3. Если у кого-то grub/lilo лежат в /boot, то тут все немного проще становится, достаточно разрешить в vmware доступ к этой partition и все будет ок. Мне же получается надо открыть доступ гостевой системе к hda3, только тогда я увижу долгожданную менюшку. Но сделав это я открываю гостевой системе доступ к линуховому разделу, и могу вполне себе нечайно так загрузить linux еще раз, но уже внутри виртуальной машины тем самым испортить файловую системы в которую будут одновременно писать как гостевой linux так и хостовый.
Резюме:
решение простое, но это единственный его плюс, а из минусов видимость безопасности, отсутствие защиты от самого себя как в виртуальной машине, так и в реальной.

II. Способ второй, тоже не безопасный.
Вариация первого способа. Делать /dev/hda доступным для пользователя не обязательно, можно ведь еще пускать vmware через sudo. Но с одной стороны мы больше не даем пользователю доступа к /dev/hda, а с другой стороны кто его знает каких дел можно наворотить из suid'нутой vmware?! Там вроде даже скрипты можно запускать.. Да и выглядят приложения пущенные из под root не в общей визуальной теме.
Страшно в общем это все. К тому же это не решает проблему grub и lilo в гостевой машине.

III. Способ третий, все еще не безопасный.
Сам не пробовал, но в теории можно сделать sudo'ным вот такой вот скрипт:
cp -r /dev/hda /dev/hdw
chown akshaal:root /dev/hdw
nohup su -c vmware akshaal &
sleep 10
rm -f /dev/hdw
Или по-русски, мы делаем копию /dev/hda доступной для пользователя в течении 10 секунд за которые пользователь должен включить виртуальную машину в работу, после чего дырка закрывается (в unix'ах можно без проблем удалять открытые файлы, это никак не мешает программе которая с удаленным файлом работает). Если так сделать, то дырка в реальной машине будет существовать в течении только 10 секунд, за которые что-то можно сделать разве что специально. Но это опять не решает проблемы внутри гостевой машины.

IV. Способ четвертый.
Способ вообще не рабочий, даже рассматривать лень.
(основан на идее давать права не на /dev/hda, а на /dev/hda1, 2, 3. но из-за того, что vmware даже и не смотрит в сторону этих файлов, он не рабочий).

V. Безопасный способ решения проблемы.
А что если попробовать виртуально склеить /dev/hda1 с другими устройствами и получить совершенно новый диск частью которого бы являлся наш /dev/hda1 (fat32 раздел). Потом дать на этот диск права пользователю и использовать именно его из vmware. Развивая эту мысль вспоминаем о технологии LVM которая кажется чем-то таким занимается (почти software raid). Почитав подробнее про LVM понятно - она занимается не этим и не подходит, но есть одна деталь, LVM сама в свою очередь использует технологию device mapper появившуюся в ядрах 2.4 и 2.6. Идея device mapper: мы задаем из каких кусков состоит наше новое устройство, задавая интервалы секторов и соответствия этих интервалов данным других устройств (подробнее в документации).

Итак, для начала надо определиться, что мы хотим создать. Я создаю новое устройство - винчестер, по размеру аналогичный существующему винчестеру hda. Мой новый винчестер (назовем hdw) должен иметь такуюже разбивку как и реальный. И самое главное, новый винчестер должен использовать в качестве раздела hdw1 реальный раздел hda1 реального винчестера. Вот основное требование к новому винчестеру.

Теперь более детально обдумываем ситуацию. Вспоминаем, что жесткий диск имеет следующую структуру:
Сначала идут 512 байт принадлежащие master boot record'у. В этих же 512 байтах MBR'а лежит partition table (таблица разделов), в которой описано с какого сектора и по какой расположена каждая из четырех партиций. На каком-то расстоянии от MBR расположен первый раздел. За котором следующий и так далее (между разделами вполне вероятны промежутки).

Таким образом, в соответствии с задачей наш винчестер разделяется на три области:
1. То, что идет до hda1 (это MBR и все что за ней до начала раздела, назовем эту область PRE).
2. Раздел hda1 на котором лежит Windows XP.
3. Все, что после раздела hda1 (назовем эту область POST).
Для того, чтобы воссоздать аналогичную структуру на hdw, надо знать параметры этих частей, а именно их длинны в секторах.
Узнать смещение hda1 относительно начала диска, можно посмотрев в hex редакторе partition table. Для этого сделаем:
dd if=/dev/hda of=/tmp/hda count=1 bs=512

Откроем /tmp/hda на просмотр в mc и нажмем f4. 4 байта по смещению 0x000001c6 определяют начало первого раздела (в секторах). Мой раздел hda1 начинается с 63го сектора.
Теперь определим количество секторов в разделе hda1, это можно сделать так:
blockdev --getsize /dev/hda1

В моем разделе hda1 оказалось 20000862 сектора.
Теперь вычислим длинну оставшейся области винчестера в которой находятся hda2 и hda3, для этого получим общее количество секторов в hda:
blockdev --getsize /dev/hda

Мой hda имеет 78140160 секторов. Если из этого числа вычесть количество секторов занятых под hda1 и под область перед hda1, то выходит длинна области за hda1.

После всех вычислений имеем следующую информацию по hda:
1. Область PRE: Начинается в секторе 0 и имеет длину 63 сектора.
2. Область hda1: Начинается в секторе 63 и имеет длину 20000862.
3. Область POST: Начинается в секторе 20000925 и имеет длинну 58139235.
(это же самую информацию можно получить и через fdisk, нажав там u, а потом p :) )

У нас есть достаточно данных, чтобы написать конфигурацию для нового винчестера!
Итак вот она (/etc/hdw/dm.cfg)
0        63        linear /dev/loop3 0
63 20000862 linear /dev/hda1 0
20000925 58139235 zero

Первый столбец - номер сектора с которого начинается интервал.
Второй столбец - количество секторов в интервале.
Третий столбец - метод описывающий откуда проецировать сектора.
Четвертый столбец - параметры метода.
В моем конфигурационном файле написано, что новый винчестер состоит из трех областей, где первые 63 сектора проецируются из устройства /dev/loop3, следующие из устройства /dev/hda1 и наконец остаток забивается нулями ибо нам не интересен совсем.
Теперь надо создать облать PRE. Сделаем это так:
dd if=/dev/hda of=/etc/hdw/pre.img count=63 bs=512

- мы скопировали первые 63 сектора из винчестера в файл образа.
Теперь делаем:
losetup /dev/loop3 /etc/hdw/pre.img

- и область PRE для нового винчестера готова. Вот теперь у нас есть все, чтобы создать устройства нового винчестера.
Длеаем:
dmsetup create hdw /etc/hdw/dm.cfg
chmod 600 /dev/mapper/hdw
chown akshaal:akshaal /dev/mapper/hdw
ln /dev/mapper/hdw /dev/hdw


После всех этих шагов, в /dev должно появится устройство hdw, которое побайтно соответствует устройству hda на протяжении первых 20000925 секторов, после которых в hdw начинаются 0. Но если мы изменим сектор лежащий в интервал 0...62 (включительно) в устройстве hdw, то hda затронут не будет, а изменится файл /etc/hdw/pre.img. Если же мы изменим значение в секторах с 63 по 20000924 в hdw, то изменения отразятся и в hda1. Запись в сектора с номерами больше 20000924 в hdw смысла не имеет (она игнорируется, а при чтении всегда будет 0).

Хорошо, у нас есть изолированный винчестер доступ к которому вполне безопасно (разве что windows затрется) давать пользователю. Включим же его в работу! Пытаемся. А VMWare говорит, что bus error и она его использовать не будет! Предвкушая перспективу реализовывать эмуляцию ioctl'ов нужных vmware, но сохраняя надежду более простого решения, лезим в google и находим вот такую ссылку. Оказывается, совсем недавно (в ноябре этого года) кто-то столкнулся с аналогичной проблемой подключения loop устройств в vmware в качестве винтов, ну и в конце концов была написана вот такая программа обертка о которой можно прочитать тут или сразу скачать тут. Компиляция и установка программы происходит как обычно и без проблем. Работает программа тоже без нареканий. Для запуска vmware с обвязкой надо написать вот такой скрипт (~/bin/vmware-in-nutshell):
 #!/bin/sh LD_PRELOAD=libvmware-bdwrapper.so.0 VMWARE_BDWRAPPER_DEVICES=/dev/hdw vmware 

и запускать уже его.

Теперь vmware прекрасно запускается и нормально позволяет создать виртуальную машину с /dev/hdw в качестве физического диска.

Запускаем vmware и правильно... получаем совершенно ожидаемое li или error 17. Lilo и grub пытаются прочитать свои хвосты в hdw3 а там у нас полностью нулевая область. Пострадав и поискав около пары часов способ снести grub, находим в своем дистрибутиве пакет ms-sys и ставим:
apt-get install ms-sys 


Прочитав man на программу ms-sys, делаем:
ms-sys -f -m /dev/hdw

на что получаем "Windows 2000/XP/2003 master boot record successfully written to /dev/hdw".

Если в процессе поиска решения об удалении grub'а вы нечайно снесли еще и бутовую область раздела hda1 (как это сделал я), то делаем еще и (для XP):
ms-sys -2 -w /dev/hda1


Операции по созданию устройства следует вынести в отдельный файл и загружать его из rc.boot.

Вот и все. Теперь сразу после включения виртуальной машины у нас грузится Windows XP. Оно того стоило.

При загрузке реальной машины появляется обыкновенное меню выбора операционной системы (linux, windows).
При загрузке виртуальной машины Windows XP грузится сразу.
В обоих случаях для работы используется одна и та же область жесткого диска с одним тем же набором программ windows.
Оно того стоило.

В Vmware 5.0 появилась возможность вписать рабочий стол гостевой системы в окно vmware. Делается это одним нажатием хоткея. Так у меня сейчас Windows XP имеет разрешение 1016x610.
Еще появились какие-то Shared Folders... надо посмотреть, похоже это технология более простого доступа к содержимому хоста из гостевой машины.

PS. Чтобы не было мешанины из драйверов и настроек при работе то в виртуальной машине, то в реальной, следует использовать профили оборудования. Еще лучше выключить засыпание винды при долгом простое, а то после ее пробуждения настройки мыши как-то сбрасываются нехорошо...
И самое главное, не стоит использовать снапшоты! Не стоит делать саспенд в виртуальной машины, грузить винду с реальной, а потом делать ресаме в виртуальной. Такой бардак приведет к разрушению файловой системы.
В конце-концов эксплуатая dual booting системы в vmware не такая уж и сложная. Главное знать что делать и не делать лишнего.

Комментариев нет:

Отправить комментарий