суббота, 20 апреля 2019 г.

Совместный доступ к файлам для Windows и Linux в VirtualBox

Для обеспечения совместной работы с файлами для хост-системы на базе Windows и Linux, установленного в виртуальную машину VirtualBox, предлагается использовать shared folders. Чтобы обеспечить доступ к содержимому файлов этот способ подойдет, но если пытаться использовать shared folders как замену файловым системам Linux, то вас ждет набор проблем:
  • нужно отдельно настраивать VirtualBox для работы с symlinks
  • крайне ограниченная поддержка linux owner/group/permissions
  • сложности с удалением и переименованием отрытых файлов унаследованные от хост-системы
  • ограничения на имена файлов и директорий унаследованные от хост-системы
  • низкая скорость работы
Я пользовался shared folders почти два года и периодически пытался уйти на WSL, но последнее заслуживает отдельного повествования. Когда началась работа с проектом, где регрессионный тест занимал 15 минут, вместо положенных двух (если запускать его в виртуальной машине, но вне shared folders) я приступил к поиску альтернатив.

И первое что я попробовал - поменять направление передачи файлов. Теперь они хранятся в VirtualBox, а Linux их предоставляет хостовой системе посредством NFS.

Host-only network


Чтобы случайно не расшарить свои файлы в общую сеть я создал host-only сеть в VirtualBox (192.168.123.0/24). IP адрес Windows будет 192.168.123.1, а Linux - 192.168.123.100. Чтобы Linux начал использовать новую сеть добавляю ее настройки

$ cat >/tmp/eth1-net <<_EOF_
allow-hotplug eth1
iface eth1 inet static
    address 192.168.123.100
    netmask 255.255.255.0
_EOF_
$ cat /tmp/eth1-net | sudo tee -a /etc/network/interfaces
$ sudo ifup eth1

Linux


Перенес свои файлы внутрь виртуальной машины через SSH

$ tar -cf- -C /cygdrive/c/Work . | ssh andrey@192.168.123.100 tar -xf- -C /work

Возможно было бы быстрее создать архив в Windows, а потом распаковать его в Linux через shared folders, но я не делал такой тест. Устанавливаю сервер NFS в Linux (я использую Debian Stretch)

$ sudo apt-get update
$ sudo apt-get install -y nfs-kernel-server
$ echo '/work  192.168.123.1(rw,sync,no_subtree_check,all_squash,anonuid=1000,anongid=1000)' | sudo tee /etc/exports
$ sudo exportfs -av
exporting 192.168.123.1:/work

Я использую опции all_squash,anonuid=1000,anongid=1000 чтобы мой пользователь внутри виртуальной машины с uid 1000 и gid 1000 (первый созданный пользователь в Debian) мог редактировать загруженные файлы как свои собственные.

Windows


Не помню с какой версии Windows поставляется NFS клиент, но в Windows 7 он уже был. Для включения его в Windows 10 нужно перейти в "Control Panel / Programs / Turn Windows features on or off / Services for NFS" и включить "Client for NFS"


Теперь нужно сказать клиенту NFS чтобы использовал uid/gid 1000 как идентификатор анонимного пользователя. Иначе только что созданный файл будет считаться принадлежащим другому пользователю. Для этого в ветке реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ClientForNFS\CurrentVersion\Default создать ключи AnonymousUid и AnonymousGid с типом DWORD 32bit и присвоить им значение 000003e8 (НЕХ) или 1000 (DEC). Для удобства я подготовил registry файл

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ClientForNFS\CurrentVersion\Default]
"AnonymousUid"=dword:000003e8
"AnonymousGid"=dword:000003e8

Теперь нужно перезагрузиться, запустить виртуальную машину и можно монтировать NFS шару

WIndows
> mount -o anon 192.168.123.100:/work z:
> mount

Local    Remote                                 Properties
-----------------------------------------------------------------------------
z:       \\192.168.123.100\work                 UID=1000, GID=1000
                                                rsize=524288, wsize=524288
                                                mount=soft, timeout=0.8
                                                retry=1, locking=yes
                                                fileaccess=755, lang=ANSI
                                                casesensitive=no
                                                sec=sys

Осталось решить две проблемы: "неправильная кодировка имени файлов, содержащих кириллицу, в Linux" и "непонятно как задать раздельные пермишены для файлов и директорий по-умолчанию"

Проблема с неправильной кодировкой выглядит так:

Windows
> mkdir z:\test
> echo test > "z:\test\тестовый файл.txt"
> dir w:\test

 Directory of w:\test

2019-04-20  10:45 AM                 7 тестовый файл.txt
2019-04-20  10:45 AM    <DIR>          .
2019-04-20  10:44 AM    <DIR>          ..
               1 File(s)          8,199 bytes
               2 Dir(s)   6,432,579,584 bytes free

Linux
$ ls -l /work/test
total 4
-rwxr-xr-x 1 andrey andrey 7 Apr 20 10:45 ???????? ????.txt

А проблема с правами по-умолчанию так:

Linux
$ ls -ld /work/test
drwxr-xr-x 2 andrey andrey 4096 Apr 20 10:45 /work/test

$ ls -l /work/test
-rwxr-xr-x 1 andrey andrey 7 Apr 20 10:45 ???????? ????.txt

Т.е. для файлов и директорий по-умолчанию назначаются права 0755, которые задаются в параметре fileaccess=755 параметров монтирования. Если при монтировании шары указать -o fileaccess=644, то это будет выглядеть так:

Windows
> mount -o anon -o fileaccess=644 192.168.123.100:/work y:

y: is now successfully connected to 192.168.123.100:/work

The command completed successfully.

> mkdir y:\test2

> echo test > y:\test2\test.txt
Access is denied.

Linux
$ ls -ld /work/test2
drw-r--r-- 2 andrey andrey 4096 Apr 20 11:04 /work/test2

Из-за того что на новую директорию были назначены права 644 в ней не дает создать новый файл.

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

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