Summary: | Увеличить ограничение на длину имени файлов в BTRFS | ||
---|---|---|---|
Product: | LINUX@Etersoft | Reporter: | Денис Обрезков <reprofy> |
Component: | Общее | Assignee: | Денис Обрезков <reprofy> |
Status: | DEFERRED --- | QA Contact: | |
Severity: | minor | ||
Priority: | P4 | CC: | lav |
Version: | не указана | ||
Target Milestone: | выпуск 1.0 | ||
Hardware: | PC | ||
OS: | Linux | ||
Whiteboard: | |||
Заявки RT: | Связано с: | ||
Дата напоминания: |
Description
Денис Обрезков
2013-11-16 17:19:54 MSK
Планируется итеративно рассматривать bftrs и bftrs-progs, пока не будет получено решение. в в btrfs-progs была изменена аналогичная константа BTRFS_NAME_LEN. Был отформатирован раздел btrfs программой mkfs-btrfs, но это не дало результата - файл все так же создается, но отображается, как неправильный. При этом параметры файла тоже не отображаются: [root@host-35 btrfs]# ls -l итого 20 -r----xr-- 1 root root 0 ноя 16 20:42 a12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 Исправления btrfs-progs: btrfs_progs git.eter:/people/reprofy/public/btrfs_progs.git Неясно, почему так, и есть ли файловые данные на самом деле, или они просто не отображаются. В mc файл не получается удалить, но stat, похоже что, верно отображает информацию: [root@host-35 btrfs]# stat a12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 Файл: «a12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789» Размер: 0 Блоков: 0 Блок В/В: 4096 пустой обычный файл Устройство: 22h/34d Inode: 258 Ссылки: 1 Доступ: (0414/-r----xr--) Uid: ( 0/ root) Gid: ( 0/ root) Доступ: 2013-11-16 20:42:55.297011710 +0400 Модифицирован: 2013-11-16 20:42:55.297011710 +0400 Изменён: 2013-11-16 20:42:55.297011710 +0400 Создан: - (В ответ на comment #1) ... > - файл все так же создается, но отображается, как неправильный. В чём это заключается? Где отображается? > При этом параметры файла тоже не отображаются: > [root@host-35 btrfs]# ls -l > итого 20 > -r----xr-- 1 root root 0 ноя 16 20:42 > a1234567890123456789012345678901234567890123456789012345678901234567890123456 > 78901234567890123456789012345678901234567890123456789012345678901234567890123 > 45678901234567890123456789012345678901234567890123456789012345678901234567890 > 123456789012345678901234567890123456789 Какие именно параметры здесь не отобразились? Вроде всё есть. > В mc файл не получается удалить, но stat, похоже что, верно отображает Для удаления есть команда rm. > информацию: Так что не так-то? Ошибся, параметры файла неправильно отображаются в mc. К примеру, время создания "1 января 1970 года", все файлы с длинным именем отображаются красным цветом, перед именем стоит знак вопроса. При попытке произвести операцию выводится окно: "Невозможно получить свойства "/mnt/btrfs/...". Нет такого файла или каталога (2)". В ls же только имя файла с длинным русским именем выводится красным цветом. Оказывается, в файле был установлен SUID бит, поэтому он подсвечивался красным в ls. (В ответ на comment #3) > Ошибся, параметры файла неправильно отображаются в mc. К примеру, время > создания "1 января 1970 года", все файлы с длинным именем отображаются Мы не изучаем работу программ. Проверять корректность должен написанный тобой тест. Есть ли он, что он проверяет? Надо ли заводить багу по его созданию? тест есть, все функции работают корректно, то есть, ошибок не возвращают. Проверяет основные функции с файлом с названием из 150 русских символов: [root@host-35 btrfs]# ./glibc_vlfn_test creat_test: working access_test: working chmod_test: working open_test: working stat_test: working read_open_dir_test: working unlink_test: working creat_test: working symlink_test: working chmod_test: working fopen_test: working truncate_test: working link_test: working remove_test: working mkdir_test: working read_open_dir_test: working rmdir_test: working Errors: 0 Команда btrfsck, отвечающая за проверку файловой системы, ошибок на выявила: [root@host-35 ~]# btrfsck /dev/sdd1 found 65536 bytes used err is 0 total csum bytes: 36 total tree bytes: 28672 total fs tree bytes: 8192 btree space waste bytes: 20453 file data blocks allocated: 36864 referenced 36864 Btrfs Btrfs v0.19 Создана wiki, добавлен раздел для btrfs: http://wiki.etersoft.ru/Linux/VLFN#BTRFS Есть ошибка, которая проявляется в шелле, но не проявляется в тесте: [root@host-35 btrfs]# rm оченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимякомунужнытакиеименаоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяидлиннаяконцовкас тремя пробелами .И заглавной буквой. rm: невозможно удалить «оченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимякомунужнытакиеименаоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяидлиннаяконцовкас»: Нет такого файла или каталога rm: невозможно удалить «тремя»: Нет такого файла или каталога rm: невозможно удалить «пробелами»: Нет такого файла или каталога rm: невозможно удалить «.И»: Нет такого файла или каталога rm: невозможно удалить «заглавной»: Нет такого файла или каталога rm: невозможно удалить «буквой.»: Нет такого файла или каталога В тесте имя файла так же содержит пробелы, но ошибок не выводится. (В ответ на comment #9) > Есть ошибка, которая проявляется в шелле, но не проявляется в тесте: ..... > > В тесте имя файла так же содержит пробелы, но ошибок не выводится. Ошибся - забыл экранировать пробелы. Изменен предел длины имени до 1023 (байт). Ручной тест: File is found filename = оченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимякомунужнытакиеименаоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяидлиннаяконцовкас тремя пробелами .И заглавной буквой.Сделаем имя очень длинным. Вряд ли кому-то в голову придет называть файл таким длинным именем. Даже чуть длиннее,проверим символы: АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ и нижние буквы абвгдеёжзийклмнопрстуфхцчшщъыьэюя. Возможно, я ошибся с порядком, поэтому проверю знаки: !№;%:?*()_-+=. Я точно не знаю, сколько они занимают байт, думаю, чтонемного. И....конец., filename length = 1022 File is found filename = оченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимякомунужнытакиеименаоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяидлиннаяконцовкас тремя пробелами .И заглавной буквой.Сделаем имя очень длинным. Вряд ли кому-то в голову придет называть файл таким длинным именем. Даже чуть длиннее,проверим символы: АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ и нижние буквы абвгдеёжзийклмнопрстуфхцчшщъыьэюя. Возможно, я ошибся с порядком, поэтому проверю знаки: !№;%:?*()_-+=. Я точно не знаю, сколько они занимают байт, думаю, чтонемного. И...конец!!!, filename length = 1023 File with Russian name isn't created, it's length 1024 bytes File isn't found Было изменен предел в ядре: File with Russian name isn't created, it's length 1024 bytes File isn't found Точно так же изменен предел в том же файле в btrfs-progs. В планах - провести тесты glibc Проверить работу тестом, приведенным выше* Проведение тестов программой показало, при длине в 1024 байта(буквы, цифры и символы) файл не создается: [root@host-35 btrfs]# ./glibc_vlfn_test crear_test: creat() error: File name too long access_test: access() error: File name too long chmod_test: chmod() error: File name too long open_test: open() error: File name too long stat_test: stat() error: File name too long lstat_test: lstat() error: File name too long read_open_dir_test: File isn't found unlink_test: unlink() error: File name too long crear_test: creat() error: File name too long symlink_test: working chmod_test: chmod() error: File name too long fopen_test: fopen() error: File name too long truncate_test: truncate() error: File name too long link_test: link() error: File name too long remove_test: remove() error: File name too long mkdir_test: mkdir() error: File name too long read_open_dir_test: File isn't found rmdir_test: rmdir() error: File name too long Errors: 20 При длине в 1023 байта, создается: [root@host-35 btrfs]# ./glibc_vlfn_test creat_test: working access_test: working chmod_test: working open_test: working stat_test: working lstat_test: working read_open_dir_test: working unlink_test: working creat_test: working symlink_test: working chmod_test: working fopen_test: working truncate_test: working link_test: working remove_test: working mkdir_test: working read_open_dir_test: working rmdir_test: working Errors: 0 Было замечено, что зависли терминалы, подключенные к этой виртуальной машине по ssh. Но, через некоторое время вернулись в рабочее состояние. Ошибка с терминалами, скорее всего не связана с данной проблемой. На wiki были добавлены резильтутаты теста. В программах glibc_vlfn_test и testfilenames убраны предупреждения времени компиляции. На данный момент для увеличения лимита в btrfs необходимо: Установить измененный mkfs.btrfs: git.eter:/people/reprofy/public/btrfs_progs.git Установить ядро с исправленный btrfs: git.eter:/people/reprofy/packages/kernel_sis.git Результаты тестирования функций glibc: Testing glibc functions with 1023-byte filename FAILED: 0, PASSED: 20 Testing glibc functions with 1024-byte filename FAILED: 0, PASSED: 20 В таком случае можно будет использовать базовую функциональность. Сторонние программы могут использовать предел длины из файла limits.h. Для изменения его содержимого необходимо: 1. Установить исправленную версию kernel-source. 2. Переустановить пакет glibc-kernheaders. Осталось установить корректную последовательность изменений в последнем пункте. (В ответ на comment #15) > На данный момент для увеличения лимита в btrfs необходимо: > > Установить измененный mkfs.btrfs: > git.eter:/people/reprofy/public/btrfs_progs.git > Из ветви filename_bound. Именно с его помощью необходимо создать новый раздел с btrfs. > > Установить ядро с исправленный btrfs: > git.eter:/people/reprofy/packages/kernel_sis.git > Ветвь btrfs_new_bound. Необходимо внести изменения в ядра std-def. Разобраться со сборкой ядер в пакетыю(В ответ на comment #15) > > Сторонние программы могут использовать предел длины из файла limits.h. > Для изменения его содержимого необходимо: > 1. Установить исправленную версию kernel-source. > 2. Переустановить пакет glibc-kernheaders. > > Осталось установить корректную последовательность изменений в последнем > пункте. Пока не удалось. Исправленная версия kernel-source доступна здесь: /people/reprofy/public/kernel_source_3.9.git namelength_increased Для изменения в файле limits.h необходимо собрать пакет kernel-source-3.9 командой rpmbb, далее установить его и установить пакет glibc-kernheaders. Исправлена статья на wiki - добавлено описание случаев тестирования различных комбинаций исправленных и неисправленных ядра и программ форматирования mkfs.btrfs. В планах сделать возможным выбор предела длины имени файла для программы форматирования. Сделать проверку в ядре доступной длины имени файла файловой системы и добавить функциональность связанных с различными результатами(длины в ядре и файловой системе совпадают-не совпадают) действий. Пока не получается сделать так, чтобы в программе mkfs.btrfs параметр максимальной длины файла задавался аргументом командной строки. Основная проблема в областях видимости: ctree.h: int max_name_length = 255; #define BTRFS_NAME_LEN max_name_length ... mkfs.c: static void parse_namelength(char *input) { extern int max_name_length; int length_buf; length_buf = 0; errno = 0; if (input) { length_buf = strtol(input, NULL, 10); } if (errno != 0 || length_buf <= 255 || length_buf >= 2047) { exit(1); } else max_name_length = length_buf; } Компилятор ругается на многократное определение переменной max_name_length. git.eter:/people/reprofy/public/btrfs_progs.git simple_btrfs (В ответ на comment #20) > Пока не получается сделать так, чтобы в программе mkfs.btrfs параметр > максимальной длины файла задавался аргументом командной строки. > Основная проблема в областях видимости: > > ctree.h: > int max_name_length = 255; ... > Компилятор ругается на многократное определение переменной max_name_length. Ну ты пиши больше кода, слушайся компилятора, посмотри как другие параметры обрабатываются. Также неплохо прочитать книжку про язык, на котором пишешь. В заголовочных файлах можно только описывать что-то, определять там ничего не стоит. Сам кода разбора параметра тоже странноват, без диагностики. Оказалось, что в btrfs-progs, несмотря на старые ограничения длины файлы(255 байт), утилита mkfs.btrfs создает файловую систему, в которой можно создавать длинные файлы. Видимо, я ранее ошибся и запустил проверку не в той директории. В итоге, при оригинальной программе форматирования и измененном ядре могут создаваться файлы с длинными именами, тест функций glibc проходится: [root@host-35 btrfs]# /home/guest/glibc_vlfn_test Testing glibc functions with 1023-byte filename FAILED: 0, PASSED: 20 Testing glibc functions with 1024-byte filename FAILED: 0, PASSED: 20 При беглом просмотре кода btrfs-progs я не заметил использования ограничения на имя файла при создании ФС. (В ответ на comment #22) > Оказалось, что в btrfs-progs, несмотря на старые ограничения длины файлы(255 > байт), утилита mkfs.btrfs создает файловую систему, в которой можно > создавать длинные файлы. Видимо, я ранее ошибся и запустил проверку не в той > директории. Тогда зачем в ней константа, задающая это ограничение? > В итоге, при оригинальной программе форматирования и измененном ядре могут > создаваться файлы с длинными именами, тест функций glibc проходится: > [root@host-35 btrfs]# /home/guest/glibc_vlfn_test > Testing glibc functions with 1023-byte filename > FAILED: 0, PASSED: 20 > > Testing glibc functions with 1024-byte filename > FAILED: 0, PASSED: 20 Что-то у меня совершенно не такой вывод этого теста: $ ./glibc_vlfn_test crear_test: creat() error: File name too long access_test: access() error: File name too long chmod_test: chmod() error: File name too long open_test: open() error: File name too long ... Errors: 18 (В ответ на comment #23) > (В ответ на comment #22) ... > Тогда зачем в ней константа, задающая это ограничение? > В том файле много других констант, которые нужны для создания файловой системы > > В итоге, при оригинальной программе форматирования и измененном ядре могут > > создаваться файлы с длинными именами, тест функций glibc проходится: > > [root@host-35 btrfs]# /home/guest/glibc_vlfn_test > > Testing glibc functions with 1023-byte filename > > FAILED: 0, PASSED: 20 > > > > Testing glibc functions with 1024-byte filename > > FAILED: 0, PASSED: 20 > Что-то у меня совершенно не такой вывод этого теста: > $ ./glibc_vlfn_test > crear_test: creat() error: File name too long > access_test: access() error: File name too long > chmod_test: chmod() error: File name too long > open_test: open() error: File name too long > ... > Errors: 18 Это вывод старой версии. Странно я зашел на builder64, пересобрал, запустил - такой же результат, посмотрел git log - там логи новой версии, посмотрел git status - там нет отслеживаемых изменений, сменил ветку, потом обратно, пересобрал - все заработало нормально. Видимо, я ошибся при публикации репозитория и самой его структуре, поэтому вот новый репозиторий с тестом: git.eter:/people/reprofy/public/glibc_vlfn_test.git Репозиторий реорганизован. Была исправлена утечка памяти убраны некоторые предупреждения. Откладываем задачи, к которым не обращались более 100 дней. |