null

Добавляем поддержку NTFS/exFAT в Solaris 11

Недавно к нам обратился один заказчик с маленькой проблемой: на его SunRay-сервере, установленном на сервере SPARC Enterprise T5120 не работали флешки с файловыми системами NTFS и exFAT. Вопрос с переносом все x86-железку с Linux на борту не рассматривался, так что пришлось импровизировать.

    prepare

Как известно, в Linux существует подсистема FUSE (Filesystem in USErspace), позволяющая писать драйвера файловых систем как обычные пользовательские программы, которые просто форкаются от mount. При разработке OpenSolaris она была худо-бедно портирована (на Solaris 10 из-за некоторых изменений в VFS не собирается), а в Solaris 11 превратилась в UVFS, сильно урезанный вариант FUSE, из-за чего не позволяющий использовать NTFS и exFAT. Поэтому пришлось вытаскивать исходники с hg.opensolaris.org, и собирать руками FUSE, что как оказалось не очень сложно. Единственная проблема, возникшая состояла в том, что FUSE использует символ ',' для разделения опций файловой системы, тогда как в Solaris имена устройств могут содержать запятые, и поэтому следующая строка:
    ...,fsname=/tmp/SUNWut/units/IEEE802.002128f8888b/devices/usb@1/hub@1/USB2.0,USB_FLASH_DRIVE@1:1
приведет к тому, что имя устройства окажется /tmp/SUNWut/units/IEEE802.002128f8888b/devices/usb@1/hub@1/USB2.0 и дезориентирует SunRay Software. Я по-началу думал, что проблему может решить экранирование запятых. Однако, как оказалось SunRay Software требует вообще символических ссылок вида /tmp/SUNWut/units/IEEE802.002128f8888b/dev/dsk/disk1s2 .

    Сказано - сделано:

@@ -523,7 +563,7 @@ char *parse_mount_options(ntfs_fuse_context_t *ctx,
        
        if (ntfs_strappend(&ret, "fsname="))
                goto err_exit;
-       if (ntfs_strappend(&ret, popts->device))
+       if (ntfs_strappend_escaped(&ret, popts->arg_device))
                goto err_exit;
        if (permissions && !acl)
                ctx->secure_flags |= (1 << SECURITY_DEFAULT);



Еще одна проблема состоит в том, что Solaris на SPARC не умеет разделы и MBR-метку - поддерживается только типичная для SPARC VTOC. К счастью, и в ntfs-3g и в fuse-exfat предусмотрены обертки над функциями pread, pwrite и lseek и не составляет труда в этих функциях-обертках прибавлять смещение, соответствующее разделу, а при монтировании устройства эти самые разделы опеределять (так собственно делает драйвер файловой системы FAT pcfs, правда он через специальный синтаксис указания раздела в имени устройства). Однако если кто-то придет с внешним жестким диском с разделами NTFS и exFAT, смонтируется только одна ФС.

    configure && make

    Теперь можно собирать исходники. Для этого нам потребуется:

  • Solaris Studio 12.3 и пакет developer/build/onbld, чтобы собрать FUSE
  • GCC (в Solaris он живет в пакете developer/gcc-45) , чтобы собрать ntfs-3g и fuse-exfat
  • Систему сборки SCons для fuse-exfat


    Сборка и установка пакетов FUSE выглядит так:
# export PATH=$PATH:/opt/solarisstudio12.3/bin:/opt/onbld/bin/sparc/

# dmake
# dmake install
# dmake pkg

# pkgrm <pkg-name>
# pkgadd -d packages/ <pkg-name>


    ntfs-3g собирается следующим образом:
# ./configure --with-fuse=external --prefix=/opt/ntfs/
# make
# make install


    Еще проще (если не считать время на установку SCons smiley ) собрать fuse-exfat:
# scons install

    patch && fix

Для того, чтобы идентифицировать файловую систему Solaris использует утилиту fstyp и набор плагинов с именами fstyp.so.1, лежащими в директориях /usr/lib/fs/<имя ФС>. Можно конечно, положить в указанную директорию свой fstyp, и тогда именно он будет вызываться, а его например сделать скриптом-оберткой над ntfs-3g.probe. Но я узнал про этот метод уже после того, как реализовал указанные плагины - они расположены в дереве исходников в директории tools/ и собираются так:
    Для ntfs-3g:
# gcc -o fstyp.so.1 fstyp.c -fpic -lntfs-3g -shared

    Для fuse-exfat:
# gcc -o fstyp.so.1 fstyp.c -D_FILE_OFFSET_BITS=64 -O2 -fPIC -lexfat -shared

Кроме этого, надо создать жесткие ссылки на утилиту fstyp в директориях /usr/lib/fs/ntfs и /usr/lib/fs/exfat и добавить setuid-бит на утилиты /bin/ntfs-3g, /sbin/mount.exfat-fuse и /usr/lib/fs/fuse/fusermount.bin

Теперь можно полезть своими руками в недра SunRay Software, для того, чтобы рассказать ему про эти файловые системы. Во-первых надо изменить в файлах /opt/SUNWut/bin/utdiskadm и /opt/SUNWut/lib/utprepmount значения переменных FST_LIST и FSM_LIST. А вот утилита /opt/SUNWut/lib/utdomount является бинарником, так что ее придется обернуть в shell-скрипт - он располагается в файле tools/utdomount.sh Саму утилиту соответственно мы переименовываем в /opt/SUNWut/lib/utdomount.bin а на ее место кладем shell-скрипт. В качестве небольшого бонуса он создает для kiosk-пользователей ярлыки на рабочем столе, открывающие/отмонтирующие файловую систему.

Последний фикс который мне пришлось внести связан с интересной логикой разработчика fuse-exfat. На любой внутренний сбой он вместо того, чтобы вернуть EIO ядровому драйверу fuse, он вызывает exfat_bug(), а она в свою очередь abort(), от чего процесс, отвечающий за файловую систему аварийно завершается. Solaris от такой радости падает в панику, унося за собой всю систему. Так что пришлось потратить день на перелопачивание кода fuse-exfat angry

    wget && tar x

Свежий ntfs-3g лежит тут: http://www.tuxera.com/community/ntfs-3g-download/
Драйвер fuse-exfat тут: http://code.google.com/p/exfat/downloads/list
Все исходники есть в GitHub-репозитории: https://github.com/myaut/solaris-sparc-fuse
Ленивые могут скачать бинарную сборку для T5120/Solaris 11.1:  fuse-exfat-ntfs-1.0.1.tar

К списку статей

 

Интересуюсь по большей части системным анализом программного обеспечения: поиском багов и анализом неисправностей, а также системным программированием (и не оставляю надежд запилить свою операционку, хотя нехватка времени сказывается :) ). Программированием увлекаюсь с 12 лет, но так уж получилось, что стал я инженером.

Основная сфера моей деятельности связана с поддержкой Solaris и оборудования Sun/Oracle, хотя в последнее время к ним прибавились технологии виртуализации (линейка Citrix Xen) и всякое разное от IBM - от xSeries до Power. Учусь на кафедре Вычислительной Техники НИУ ИТМО.

See you...out there!

http://www.facebook.com/profile.php?id=100001947776045
https://twitter.com/AnnoyingBugs