Wednesday, May 6, 2009

FreeBSD 7.2 and VMWare Workstation

(For newcomers: есть предыдущие серии.)

Иногда мне кажется, что FreeBSD порт open-vm-tools больше всего похож на стационарный двигатель слесаря-интеллигента Полесова -- все выглядит как настоящее, но не работает.

Файловая система hgfs, для которой хотя написаны и ядерный модуль и монтировщик, все еще являет собой work in progress. Шаг вперед по сравнению с прошлой версией по величине своей таков, что если раньше при попытке монтирования shared folder вы тот час же могли любоваться паникой ядра, то теперь mount_vmhgfs вместе с vmhgfs.ko тщательно стараются соблюдать приличия, в которые вы верите до тех самых пор, пока не пытаетесь что-то прочесть из mount point. Не самый худший вариант, беря во внимание вспоминания о том, что именно раньше в припадке истерии вытворял vmhgfs.ko.

Потери

vmblock.ko, который счастливо перезагружал FreeBSD в прошлом, продолжает радостно делать это в настоящем. Хорошая новость тут состоит в том, что об этом модуле можно забыть, т.к. теперь реализация файловой системы VMBlock переписана с помощью FUSE library. Это означает, что мы сможем, наконец, получить сомнительно долгожданный host<->guest Drag & Drop. Если проявим терпение.

vmware-guestd, который верой и правдой честно служил нам все эти годы, уходит на пенсию. Вместо него мы получаем демон vmtoolsd, который с помощью plugins может в том числе и, синхронизировать время.

В путь

Розсуваєш чіпке гілля чагарників -- і перед тобою несподівано виблискує вода.
-- Михайло Коцюбинський.

(Всяческие предварительные вещи, такие как выбор типа виртуальной сетевой карты или общие места о настройке Xorg -- см. в 1-м эпизоде.)

Последней вещью на свете, которой нужно доверять в нашем случаи -- это подсказке порта, что куда прописать, чтобы якобы получить. На самом деле, после установки open-vm-tools, сделайте следующее:

  1. Убедитесь, что sysctl переменная vfs.usermount имеет значение 1 и пользователь под которым вы работаете состоит в группе operator.

  2. Добавьте в /etc/rc.conf:

    fusefs_enable=YES
    vmware_guestd_enable=NO
    vmware_guest_vmmemctl_enable=YES
    

    и напечатайте:

    # /usr/local/etc/rc.d/vmware-kmod start
    # /usr/local/etc/rc.d/fusefs start
    
  3. Теперь, для запуска vmtoolsd, нахмурьте лоб посерьезнее и наберите:

    # vmtoolsd -n vmsvc -p /usr/local/lib/open-vm-tools/plugins/vmsvc \
        -b /var/run/vmtoolsd.pid
    

    Так вы запустите его с сервисом vmsvc, в котором есть такой полезный plugin, как timeSync. Разумеется, ручное добавление в .vmx файл строчки tools.syncTime = "TRUE" для корректной работы никто не отменял, хотя аналогичного можно добиться запустив:

    % vmware-toolbox-cmd timesync enable

    Если вас беспокоит насколько новый способ синхронизации времени более прожорлив (или наоборот), то удалите ненужные (впрочем, пока этого не делайте) plugins из /usr/local/lib/open-vm-tools/plugins/vmsvc, оставьте только libtimeSync.so вместе c libguestInfo.so и посмотрите что вышло:

    33805 root          1  44    0 20660K  3820K select   0:00  0.00% vmtoolsd

    против старого доброго vmware-guestd:

    33854 root          1  49    0 18124K  2480K select   0:00  0.00% vmware-guestd

    Руками, конечно, запускать каждый раз vmtoolsd довольно скучно, поэтому возьмите себе rc.subr скрипт, положите его в /usr/local/etc/rc.d и добавьте строчку vmtoolsd_enable=YES в /etc/rc.conf.

  4. Если вы установили порт open-vm-tools-nox11 вместо open-vm-tools, можете дальше не читать, иначе продолжайте движение. Помните, что vmblock.ko наконец-то considered harmful? Вместо его кривых рук, нам нужно самим подмонтировать VMBlock file system в некотором укромном месте:

    % mkdir /tmp/vmblock-fuse
    % chmod 777 /tmp/vmblock-fuse
    % vmware-vmblock-fuse /tmp/vmblock-fuse
    

    Эти команды нужно выполнять от regular user, не root, иначе пропадает смысл. Недостаток такого монтирования конкретным пользователем проявится как только другой пользователь попытается посмотреть содержимое /tmp/vmblock-fuse и очень огорчится, потому что у него не окажется на это никаких прав. Это значит, что либо каждому пользователю придется вызывать vmware-vmblock-fuse с каким-нибудь другим каталогом в качестве параметра, либо сделать монтирование 1 раз root'ом с опцией allow_other. Кто помнит, в отличие от Linux, во FreeLSD указывать allow_other для всех FUSE file systems может только root. С /etc/fstab тут у вас ничего не получится, поэтому возьмите rc.subr скрипт, пропишите в /etc/rc.conf vmblock_enable=YES и, немного погодя, убедитесь что regular user может читать /tmp/vmblock-fuse.

  5. Пускайте иксы. (Для Xorg 7.4+ обязательно просмотрите раздел об X11 в Handbook.)

  6. В теории, демон vmtoolsd с сервисом vmusr, должен на вечные времена заменить собою vmware-user и обеспечивать copy/paste между host и guest, управлять Drag & Drop, дружить с VIX API и проч. Одновременно пускать vmware-user и vmtoolsd-с-сервисом-vmusr строжайше запрещено, так что между ими двумя придется выбирать себе только одного компаньона. Если вас не интересует Drag & Drop -- берите vmtoolsd, но этот путь вы прошагаете без меня, поэтому заранее желаю удачи.

    Раньше, в темные времена vmblock.ko, то что мы проделали в п.4 мог исполнять только root, поэтому существовала suid'ная утилита vmware-user-suid-wrapper, которая загружала ядерный модуль vmblock, монтировала vmblock file system, открывала некоторый (о нем ниже) файловый дескриптор для создание/удаления блоков (файлов), делала drop privileges и стартовала vmware-user от обычного пользователя.

    Весь ужасный magic в доставании файлового дескриптора VMBlock file system, заключается в знании на каком файле сделать open(2) с O_WRONLY mode. Если мы назначили точку монтирования в п.4 как /tmp/vmblock-fuse, то искомый файл (при успешном монтировании) будет /tmp/vmblock-fuse/dev. Число полученное при успешном вызове open(2) мы должны передать программе vmware-user в параметре --blockFd. Собственно говоря, именно так мы точно сэмулируем работу vmware-user-suid-wrapper:

    % vmware-user --blockFd `vmware-getblockid /tmp/vmblock-fuse/dev`

    vmware-getblockid -- это простейшая программка, которую вы забираете вот отсюда, компилируете у себя посредством "cc -o vmware-getblockid.c vmware-getblockid" и ложите результат куда-нибудь в PATH.

    Btw, vmtoolsd тоже имеет опцию --blockFd, но как бы вам не хотелось изобразить улыбку чеширского кота, посмотрите сначала в файл services/vmtoolsd/cmdLine.c (из tarball'а с исходным кодом open-vm-tools):

    GOptionEntry clOptions[] = {
    ...
          { "blockFd", '\0', 0, G_OPTION_ARG_INT, &state->ctx.blockFD,
             N_("File descriptor for the VMware blocking fs."), N_("fd") },
    ...
    }
    
    #if !defined(G_PLATFORM_WIN32)
       state->ctx.blockFD = -1;
    #endif
    

    Короче говоря, с vmtoolsd тут каши не сваришь.

  7. Самое время попробовать Drag & Drop and copy/paste. Со вторым у меня проблем не оказалось, а DnD почему-то заработал только из guest в host, обратное перетаскивание сопровождалось вот таким возмущением:

    DnD_RemoveBlock: Cannot delete block on /tmp/VMwareDnD/4cc8fb08/ \
        (Operation not supported)
    DnDRpcInDataFinishCB: could not remove block on /tmp/VMwareDnD/4cc8fb08/
    

    То есть, файл из host оставался лежать в /tmp/VMwareDnD/4cc8fb08, а host в лице Vista на несколько минут запрещал сам себе DnD с VMWare, делая соответствующие внушения тихим голосом.

    Может это было потому, что на тестовой виртуальной машине с FreeBSD 7.2-RC2 с Xorg 7.4 стартовал только twm, а Gnome или KDE отсутствовали. Перетягивание из FreeBSD в Vista файлов я тестировал каким-то x11-fm/emelfm2 -- больше ни для чего мне этот файловый менеджер не нужен.

  8. vmware-user делает одну нехорошую вещь и портит всю курицу в горшке: пытается отвечать VMWare на изменение размеров окна виртуальной машины. Такое поведение напоминает эпитет Geminus у римского Януса. Побороть это нравственное двуличие инструмента как помощника, можно только выкусыванием из vmware-user вызовов Resolution_foobar() в исходном коде.

Urbi et orbi

Каким бы безупречно правдивым не казался человек,
ему можно верить лишь в том, что касается дел человеческих.
-- Мишель Монтень.

Если вам совсем нечем заняться, сделайте grep в tarball'е c open-vm-tools на функцию RpcOut_sendOne и посмотрите на утилиту vmware-rpctool. Например:

% vmware-rpctool vmx.capability.dnd_version
2

Терпения внимательно рассматривать plugins для vmtoolsd у меня на сегодня закончилось, хотя VIX -- это, вероятно, самое интересное, ради чего стоит вообще так страдать с open-vm-tools. Правда, для самых простых операций, таких как start/suspend никакие VMWare tools внутри виртуальной машины не требуются, а запуск в guest программ посредством VIX API из host есть не более чем детская игрушка, при наличии работающего expect. На этой апофегме, мы, пожалуй, и закончим.

No comments:

Post a Comment