Samba (самба) под Linux. Этот удивительный софт подарил линуксоидам возможность связи с миром Windows.
Помню то дивное чувство, когда в локальной сети появился мой первый самба-сервер. Эх, было время!

Но пост не об этом. Не по наслышке знаю, что многих раздражает ограниченная поддержка спец.символов в Windows. Но ведь это не повод отказываться от них, не так ли?

image

Подробности моих злоключений и (почти) счастливый финал под катом. Приступим!

Я увлекаюсь коллекционированием фильмов. Вначале они помещались на один диск и это было просто. Потом дисков стало больше, помогали бумажки и Excel. Но всему хорошему приходит конец и пришлось задуматься о создании полноценной базы данных. Одним из следствий такой разработки появились виртуальные папки/списки фильмов.

Позволю себе лирическое отступление. У самбы есть одна прекрасная фишка — работа с симлинками. И если эти симлинки не ведут на доступный ресурс, то они не видны. Это позволяет иметь директорию (и не одну), в которой каждая позиция, это симлинк на конкретное хранилище. Если диск подключен, то симлинк отображается как доступная директория. Если нет — то директория не отображается вовсе. По этой причине (а также по иным, не имеющим отношения к теме) уже много лет используется самба и подобные папки (видны как в плеерах, Windows, так и на линукс клиентах).

Однако эту идиллию разрушает то, что наличие, например, двоеточия, превращает прекрасную папку вида (здесь я намеренно вставил двоеточие, позже объясню почему выбран именно этот фильм): 2008 — Вавилон Н.Э. — Babylon: A.D. в такую: 2NIQRO~7

Что же делать?


Вначале я ошибочно смотрел в сторону опции монтирования mapchars. Но она на самом деле ничего не решала, причем она дополнительно могла приводить к странным именам файлов.

Я понимал что нужно искать что-то, что сможет заменять названия файлов на лету. Значит нужна автоподстановка. Но таких модулей все никак не находилось, либо они работали не так, как хотелось бы. За время поисков третья версия самбы стала стабильной. А в ней появились т.н. Stackable VFS modules, т.е. модули виртуальной файловой системы. Это было то, что я искал!

Однако нужного мне модуля все не находилось. Версия самбы из третьей превратилась в четвертую и я был близок к тому чтобы попытаться написать модуль самому (хотя знаком с системным программированием только отдаленно). Но непрекращающиеся поиски привели меня к модулю vfs_catia, который был создан для решения проблем с Catia CAD, также создающей названия с запрещенными символами, но делал именно то, что и требовалось. Полная его функциональность раскрывается с версии самбы 3.5.0 и далее. Я тестировал на версиях 4.1.x довольно продолжительное время.

Дальнейшее было делом техники. Используемая мной система — Debian — уже имеет пакет samba-vfs-modules, содержащий данный плагин. Он был установлен и настроена замена нелегальных символов их аналогами (конфиг файл: /etc/samba/smb.conf, секция [global]):

# 002: maps illegal symbols
# vfs_catia, removed default translations: 0x20:0xb1
# vfs_catia, list of special characters:
# Unix & replacement chars:
# 0x22: "  0xa8: ?
# 0x2a: *  0xa4: ¤
# 0x2f: /  0xf8: o (forbidden range, should never exists in names)
# 0x3a: :  0xf7: ?
# 0x3c: <  0xab: «
# 0x3e: >  0xbb: »
# 0x3f: ?  0xbf: ?
# 0x5c: \  0xff: y (forbidden range)
# 0x7c: |  0xa6: ¦
# 0x20:    0xb1: ±
vfs objects = catia
catia:mappings = 0x22:0xa8,0x2a:0xa4,0x2f:0xf8,0x3a:0xf7,0x3c:0xab,0x3e:0xbb,0x3f:0xbf,0x5c:0xff,0x7c:0xa6


Я добавил комментарии для себя, чтобы понимать какие символы заменяются на их визуальные аналоги. Надеюсь, это будет полезным не только мне.

Счастливый финал


После добавления кода перегружаем демона самбы и магия в действии:
2015 — Терминатор? Генезис — Terminator Genisys

Стоит отметить что замены работают в обоих направлениях, т.е. работа с одним и тем же файлом идет прозрачно и без порчи оригинального имени в системе. Хотя если постараться, то можно, меняя, символ на один из обычных. Но в моем примере такого нет.

Теперь напомню почему в качестве первого примера я выбрал фильм Вавилон Н.Э… Дело в том, что точка в конце названия файла или директории в файловой системе Windows недопустима. Поэтому-то 2008 — Вавилон Н.Э. — Babylon A.D. все равно показывается как 2XJW59~H
Это и есть та самая ложка дёгтя, в большой бочке мёда. Пока я не знаю как заменить точку в конце, а не все точки подряд и буду благодарен всем, кто откликнется и поможет закрыть последний элемент мозаики.

Спасибо за внимание и да пребудет с вами Сила!

Комментарии (33)


  1. bakatrouble
    15.11.2015 11:27
    +5

    Если вам доступен юникод, как вариант, можно использовать CJK-пунктуацию
    Выглядит не очень похоже на окружающие символы, но они хотя бы останутся сами собой:

    ”*/:<>?\|


    1. alexkuzko
      15.11.2015 12:05
      +3

      Отличный комментарий.

      Сейчас пытаюсь вспомнить почему я от них отказался: у меня основными плеерами являются превосходные медиаплееры Dune HD, но в них символы из расширенного списка юникода отображаются знаком вопроса. Поэтому-то я и выбирал символы из базового набора, которые хотя бы видны. Согласитесь, лучше ?, чем ? вместо двоеточия (это самый используемый символ в названиях, остальные вроде того же знака вопроса или вертикального слеша, используются на порядок реже).

      Но данное уточнение я еще раз осмыслю и дополню статью.


  1. Beholder
    15.11.2015 12:39

    Только непонятно как вы заставите Windows создать файл с двоетоечием внутри (как, впрочем, и с другими символами).


    1. alexkuzko
      15.11.2015 12:49
      +2

      Для Windows нужено будет создать файл с таким именем:
      2015 — Терминатор? Генезис — Terminator Genisys
      А на Linux сервере (с самбой) он транслируется в такой:
      2015 — Терминатор: Генезис — Terminator Genisys
      Причем это происходит на лету! В чем и есть особая прелесть.

      Насчет непосредственно создания файла с двоеточием. Да, на Windows системе надо создавать файл с ? вместо двоеточия (если вам действительно нужно получить двоеточие в названии файла на диске Linux сервера).

      Само собой, что никакая замена не позволит научить летать, тех кто рожден ползать/ходить/подставить по вкусу. Но зато данный способ позволяет удобно (без приведения названий к маске 8.3) работать с любыми файлами из-под обеих систем. Для Windows ничего не изменится, как нельзя было использовать спец.символы, так и не будет можно. Это фундаментальное ограничение. Однако, его можно обойти заменой, как я показал выше.

      Надеюсь, объяснил доходчиво. Если будут еще вопросы — спрашивайте!


      1. ComodoHacker
        15.11.2015 17:37

        Полагаю, Beholder интересовался, откуда вообще берутся имена со спецсимволами.

        Мне тоже это интересно. Я могу предположить, что берутся они с раздач. Но неужели раздающие не думают о проблемах, возникающих у пользователей. Да и сами они на чем раздают?


        1. alexkuzko
          15.11.2015 20:59

          Нет. Спецсимволы возникают от того что я желаю видеть на дисках человекоподобные названия. И если в них есть двоеточия, значит там должны быть двоеточия. Вопрос, значит вопрос.

          Далее два варианта:
          1) Релиз просматривается через виртуальные папки (набор симлинков с названиями без лишних символов и т.п.) — тут все хорошо и так.
          2) Релиз просматривается напрямую через структуру папок (зачем? Потому что быстрее, потому что знаю что именно я хочу в данный момент открыть/скопировать/посмотреть) — тут спецсимволы вылазили во всей красе. До того как я решил эту проблему.

          Подмножество второго варианта: файлы с такими символами, не относящиеся к видео. Вот они такие. И опять же, проблема решается.

          Напомню что исправить названия можно и руками, но если что-то можно автоматизировать и облегчить себе жизнь — это нужно делать. Заодно и опыт, и удовлетворение от решения задачи.


      1. Speakus
        15.11.2015 19:32

        Для Windows нужено будет создать файл с таким именем:
        Хм… А если на винде сделать "o" внутри названия и скопировать на самбу с вашим плагином то самба рухнет?


        1. alexkuzko
          15.11.2015 21:08

          Во-первых, самба не рухнет.

          Во-вторых, если вы внимательно посмотрите на текст статьи и ссылку про vfs_catia, то вы поймете что данный символ "o" переведется в "/" и хоть он и запрещен, ничего не упадет, но файл такой не будет создан (из-за того что "/", он же 0x2f, запрещен в файловой системе т.к. это разделитель каталогов [не по теме, но интересно его вообще можно как-то создать и потом удалить? Напишите, кто эксперт по данной части, интересно!]).

          Специально попробовал создавать и одно и другое. Ожидаемо ничего страшного не произошло. Если смущает, эту замену можно и убрать. Она скорее для перестраховки. Создать имя со слешем у меня не получилось, создаются вложенные папки или ничего ;)


          1. leschenko
            16.11.2015 13:09

            Что будет если вы с помощью Windows создадите директорию "o"? Как она будет отображаться под Linux'ом? Можно ли зайти в такую директорию под Linux?


            1. alexkuzko
              16.11.2015 13:32

              А я уже писал что ничего плохого не будет. Вы не сможете создать такую директорию т.к. она подменится в слеш и уже самба сервер на Linux не создаст такую директорию с ошибкой «Файл с указанным именем уже существует». Если по любой причине вам нужен символ "o", то нужно убрать эту замену и подменяться не будет.

              P.S. Да, я это проверил из-под Windows XP / 7 и заодно из самого Linux с примонтированной шарой. Обратное преобразование сработает и ничего не сломает. Просто не создадите/скопируете такой файл/директорию.

              P.P.S. Вот ведь как всем интересно что будет с запрещенным слешем :)


              1. leschenko
                16.11.2015 13:59

                Я возможно слишком глуп, но в упор не понимаю при чем тут создание файлов самбой. Вас спрашивают о другом.
                Под виндой создается папка test1 внутри папка o внутри папка test2.
                Получаем пусть «что-то там\test1\o\test2\»,
                Так вот как такой это будет отображаться в самбе? можно ли зайти в test2 и прочитать список файлов?
                По сути у вас должен получиться путь «что-то там/test1///test2/», но это не корректный путь.

                Кстати, есть мнение что символ o вы так же не сможете использовать в начале и конце имени папки или файла.

                К PPS: Интересно только потому что вы обошли одну проблему, создав другую. А это не есть решение проблемы.


                1. alexkuzko
                  16.11.2015 14:31
                  +1

                  Мы говорим об одном и том же. Так вот, на сетевой смонтированной папке вы не сможете создать символ "o" ни в начале, ни в середине, ни в конце. Локально — сможете. Но как только попробуете его скопировать на сетевую самба-папку, то получите ошибку.

                  Напоминаю, что я говорю про Samba на Linux. Т.е. сервер работает на его стороне, а не на стороне Windows.

                  Если вас смущает (а вас смущает!) эта замена — то уберите ее. Тогда символ "o" будет спокойно создаваться в обоих случаях, а слеш ни при каких (да его и так не должно быть, может только если сможете напрямую в файловой системе поковыряться).

                  Любые замены можно использовать некорректно. По этой причине я и использовал символы, которые с большой вероятностью не нужно использовать. "o" один из них. Если же ваше окружение требует чтобы конкретные из этих символов были доступны и не автоподменялись, настройте свой конфиг. Он сам по себе весьма прост.

                  Вот пример на базе следующих символов: 0x3f: ? 0xbf: ?
                  Дано:
                  1) Директория на стороне линукс сервера:
                  1?1
                  2) Отображение данной директории на стороне клиентов (линукс и Windows):
                  1?1
                  3) Создаем директорию 2?2 на стороне линуксового клиента и директорию 3?3 на стороне Windows клиента.
                  4) Отображение данных директорий на стороне сервера:
                  2?2
                  3?3
                  Цель достигнута. Мы имеем директорию с запрещенным знаком вопроса, можем создавать и копировать такие директории/файлы.

                  Как «сломать» поведение? Создать директорию 4?4 на стороне линуксового клиента. Тогда данная директория будет отображаться как 4?4 для него самого (за счет трансляции), на диске сервера и для Windows клиента она будет отображаться как 4?4 (точка посередине).

                  Но это не является проблемой т.к. мы знаем что за клиенты у нас есть и т.д. Это просто нужно знать. Еще и еще раз напоминаю что любые подстановки можно «сломать» используя тот же символ, который заменяем, на системе, в которой он разрешен. Это нормальное и ожидаемое поведение.


                  1. Speakus
                    18.11.2015 22:40

                    Если вас смущает (а вас смущает!) эта замена — то уберите ее.
                    А вас эта замена не смущает? Вы предлагаете настроить конфиг самостоятельно вместо того чтобы сделать правильным этот конфиг для всех? В каком случае эта замена вообще может быть полезна и работать должным образом?


                    1. alexkuzko
                      18.11.2015 22:49

                      Я решил что ее стоит оставить на всякий случай. Комментарий в коде оставлен.
                      В любом случае, я планирую сделать небольшой апдейт в статье т.к. мне помогли решить проблему с точкой в конце. Но еще не решил проблему сборки правильного vfs_catia.c (в лоб сборка вроде бы некрасиво, бинарник выкладывать — мало ли побоятся). Для себя уже тестирую. Работает корректно (но в одну сторону!). Выбираю каким символом заменить эту точку в конце.


                      1. Speakus
                        19.11.2015 00:01

                        Простите за занудство, но я не понял: В каком случае эта замена вообще может быть полезна и работать должным образом? На какой именно случай Вы её оставили? Другими словами: приведите, пожалуйста, конкретный пример полезности этой замены — может я действительно чего-то не понимаю…


                        1. alexkuzko
                          19.11.2015 00:06

                          Никаких проблем, сам такой ;)

                          Две основные причины:
                          1) Для понимания что это один из запрещенных символов и его надо подменять (тут сделаю отсылку к тому что у меня в основном шары read only, т.е. мне обратная замена не грозит, а если каким-то образом запрещенный слеш окажется в имени файла, то он не пролезет).
                          2) Защита от дурака.


                          1. Speakus
                            19.11.2015 00:29

                            1. для понимания что его подменять? его НЕ надо подменять. Ну и если он нужен для какого-то понимания то ему место в комментах а не в catia:mappings
                            2. Что конкретно может сделать не так тот самый дурак, что ему поможет это правило замены?


  1. cagami
    15.11.2015 13:36

    а я хотел бы узнать как и куда вы ушли от списков и excel


    1. alexkuzko
      15.11.2015 14:08
      +4

      Это достойно отдельной статьи.

      Вкратце, для тех кому интересно...
      Есть иерархия папок по class, type, format (где class=video, type=animation/movies/music и т.п., format=bluray/hdremux/dvd и т.п.), внутри релиз с маской YYYY — NAME или YYYY-YYYY — NAME (для сериалов).

      Каждый релиз обрабатывается спец.скриптом, который собирает мини-базу по релизу (названия, годы, форматы, плейлисты, размеры и прочее) и создает локальный db файл. Также есть отдельные процессы, которые делают «слепок» с диска (на случай потери информации), копируют эти db файлы и, главное, добавляют в базу по диску.

      Финальным аккордом является другой процесс, который собирает информацию со всех дисков, сортирует, обрабатывает (например, вытягивает обновления с кинопоиска и imdb), и… складывает в SQL базу (на данный момент MySQL, но ничто не мешает перейти на PostgreSQL или что либо еще). Параллельно есть доп.процессы, которые генерируют списки для плееров, в Excel формате (через phpexcel) и т.п.

      Есть веб-сайт (для личного использования), через который я могу поискать все что мне нужно в своей же базе — фильмы, актеров, жанры, связи (очень приятно найти пропущенный при просмотре фильм или отсылку к другому).

      Для друзей и знакомых написан скрипт по копированию нужно по артикулу релиза (генерируется автоматически).

      В целом это такой большой велосипед, хотя архитектурно не самый худший. Все масштабируется (есть шероховатости с class/type/format — новые сущности требуют изменения более чем одного файла, хотя следующий этап будет для 4K, что само по себе будет увлекательным) кроме обработчика всех баз данных по дискам — он всю информацию вбирает в себя целиком и только потом генерирует базу данных. Но я для себя решил что пока что не стоит заниматься map/reduce (хотя как сказано выше, все распараллелено еще на уровне дисков и их баз), т.к. имеется десятикратный запас по количеству релизов. Сейчас их около 4 тысяч и занимают они более 100 Тб, упрусь же в потолок по памяти я на петабайте, что даже финансово уже слишком для хобби. И меньшей из проблем будет увеличение оперативной памяти до 32 или 64 Гб с сегодняшних 16-ти.

      Параллельно с разработкой софта улучшаю и железо — причем краеугольным камнем является философия оффлайнового хранения. Диски НЕ должны работать т.к. они нужны только считанные недели в году. Это также весьма занимательно и когда-нибудь я напишу большую статью о тех разных подходах, которые я проходил, принимал, отказывался и принимал снова, но уже на новом уровне (SATA PM, SAS, SAS Expander, DAS/iSCSI и т.п.).


      1. ComodoHacker
        15.11.2015 17:38

        Да, было бы интересно почитать и об этом.


      1. cagami
        15.11.2015 23:58
        -2

        жду отдельной статьи.


      1. ValdikSS
        16.11.2015 23:04

        Есть веб-сайт (для личного использования), через который я могу поискать все что мне нужно в своей же базе — фильмы, актеров, жанры, связи (очень приятно найти пропущенный при просмотре фильм или отсылку к другому).
        geektimes.ru/post/263302
        habrahabr.ru/post/184638
        Кроме tagsistant есть еще довольно большое количество теговых ФС под Linux, но все они не очень, по крайней мере, когда я года три назад на них смотрел. В моем случае, в анимешном, все решилось клиентом anidb, который сам сканирует папку с мультиками, вычисляет хеши, сверяет их с базой anidb и добавляет в мой лист.

        Диски НЕ должны работать т.к. они нужны только считанные недели в году.
        Вы не раздаете?


        1. alexkuzko
          16.11.2015 23:14

          Хе-хе! Про тагсистант я прочитал (и попробовал его) задолго до выхода этих статей. Принципиальной проблемой оказалось добавление ID при дублировании симлинков. Автор это считает фичей из-за дедупликации контента. А мне ну никак не интересно получать «1_2015 — ИМЯ» вместо «2015 — ИМЯ» в сложных запросах (в простых все нормально). Генерировать tagsistant структуру я тоже мог бы на лету, в процессе создания вирт. папок, но… пока не подходит.

          В общем, пока пришлось отказаться. И опять же, это все файловые вещи. Т.к. у меня есть веб-интерфейс, я смогу сделать любой сложный запрос. Но практика показала что нужно не так и много фильтров. Для Dune, например, есть каталогизаторы (не совсем совместимы с моей базой, у них все свое, на контакт не пошли — я хотел узнать можно ли подключать свою базу к их системе), тот что на флеше очень достойный и делает все что нужно и даже больше. Аналог его можно сделать скрестив веб с оболочкой. Другими словами, написав плагин. Я еще не решился на это. Балуюсь с dune_folder.txt для простых вещей. Для отображения готовых коллекций — хорошо.

          По раздачам — конечно раздаю, рейтинги везде выше единицы. Но активно только в самом начале. А потом — по требованию помогаю. Все держать включенным просто очень дорого.


  1. PastorGL
    15.11.2015 14:25
    +3

    Вообще-то, создать под Windows файлы/каталоги с именами, заканчивающимися на точку, можно. Как и на пробел. Можно даже файл с именем типа «файл…… ..» получить. NTFS технически поддерживает любые символы в именах, за исключением 0x00, а что касается двоеточия — оно служит разделителем имени файла и потока (гуглим alternative data streams).

    Другое дело, что штатный виндовый Explorer с такими файлами работает не очень (до Windows 8 даже отобразить толком не мог). Более правильно написанные программы (например, всем известный FAR Manager) их вполне переваривают. SMB сервер же по умолчанию будет пытаться их нормализовать для совместимости с более старыми версиями ОС, и это документированное поведение.


    1. alexkuzko
      15.11.2015 14:35
      +1

      Да, я прекрасно знаю что технически NTFS неплоха, изучал, надеялся что можно ее перекроить. Но фактически использовать ее на полную невозможно. А без двоеточий в фильмах никуда. По поводу точки — создать-то можно, но как использовать? Точку в конце нужно убирать. Маленький пунктик, который также хотелось бы решить.

      SMB сервер пытается «нормализовать», думаете я не знаю что это «документированное поведение»? Именно это поведение в горле у меня сидело многие годы (только для файлов, которые я не контролирую, там где возможно, для виртуальных списков, я просто заменял эти символы в процессе генерации, не трогая исходники), и насколько я был рад когда обошел его через vfs (тоже ведь документированные модули, правда для другого, но их надо было найти и применить). Своей радостью я и решил поделиться, т.к. на эту тему не нашел ничего на хабре. Справедливости ради, я давно пользуюсь своим решением и оно меня полностью устраивает, просто написал только сейчас.


      1. EvilFox
        19.11.2015 02:42

        После точки добавьте неразрывной пробел и дело с концом.
        Кстати если это файл, почему ему не дать расширение? С расширением проблем нет.


        1. alexkuzko
          19.11.2015 11:21

          Я не хочу ничего добавлять. Меня устраивает точка в конце. Это не устраивает только Windows и из-за нее тянется такой пучок проблем.
          Аналогично с расширением — какое еще расширение у директории? Нет, я лучше для совместимости при отображении заменю точку, но на диске останется как красивее и корректнее.


  1. mOlind
    15.11.2015 16:28
    +2

    А зачем нужно такое строгое соответствие между именем файла и названием фильма? Ведь имя файла это просто идентификатор для базы фильмов и именем может быть любой уникальный идентификатор, чтобы сделать связь один-к-одному.


    1. alexkuzko
      15.11.2015 17:40
      +2

      Для базы неважно. Но для самого себя важно.

      Позволю себе уточнение: в виртуальных папках нет спецсимволов. Но помимо обработанных, есть еще необработанные, которые лежат физически на дисках и ждут своего часа. И т.к. жизнь не черно-белая штука, по этим дискам иногда приходится «ходить». И в этот момент архиважно видеть настоящее название папки, а не кракозябры из-за совместимости с эпохой «палеолита» ;)

      В базе вообще все ID это sha1 хеши (соль тут ни к чему) + артикулы (это сокращенные хеши до 8 бит, экспериментально выбрал связку первых двух бит от sha1 + полный crc32 хеш, времени математически доказать этот выбор не было, не хватает таких глубоких знаний...).


  1. nagibat0r
    16.11.2015 07:54

    Статья понравилась, искал что-то подобное. Правда мне нужно немного для другого. В конторе конструкторы работают с чертежами, и им надо как раз имена чертежей со спец.символами


    1. alexkuzko
      16.11.2015 09:56
      +1

      Для этого и писал. Если это вам поможет и получится использовать такие символы в работе — я буду только рад!


  1. Plone
    16.11.2015 11:00

    Конкретно для случая с многоточием в конце — используйте символ многоточия (один), а не три точки (что, в общем-то, просто неверно).


    1. alexkuzko
      16.11.2015 11:11

      Проблемы не с многоточием в конце (они у меня изначально единым символом многоточия), а с единственной точкой. Решить это может только regexp в vfs_catia, но, как я понял, это пока не поддерживается.