Недавно столкнулся с проблемой некорректной работы apt по протоколу file:// на каталогах подключенных через CIFS. Выяснилось, что проблема проявляется на 32-битных системах, подключающих CIFS-каталоги с 64-битного сервера. Проблема исследована в задаче ETER#8869: http://bugs.etersoft.ru/show_bug.cgi?id=8869 "apt использует stat вызов для проверки доступности файла, что на 32 битной машине падает, если номера айнодов 64 битные. Поэтому нужно либо использовать stat64, либо компилировать с опцией -D_FILE_OFFSET_BITS=64. Так же есть вариант использовать опцию монтирования noserverino. Проблема повторяет то, что у нас было с WINE тут: http://bugs.etersoft.ru/show_bug.cgi?id=7302#c3." Стоит отметить, что подобной проблеме подвержен, видимо, не только apt. Но и, например bash, у которого некорректно работает автодополнение по именам каталогов в цепочке каталогов, подключенных через CIFS.
Может быть надо рассмотреть принудительную сборку всего с -D_FILE_OFFSET_BITS=64? Получается, что ни одна программа без этого, использующая stat, работать толком не будет. Хотя я и не понимаю, какое дело проверке доступности файла с помощью stat до номера inode. Мне всё же кажется, что это больше проблема функций, или ядра. NFS вот отлично умеет сворачивать номера inode в 32-битные, как я понял. На самом деле основная наша задача по проблеме 64 inode у нас здесь: http://bugs.etersoft.ru/show_bug.cgi?id=8420
Надо просто добавить AC_SYS_LARGEFILE.
(В ответ на комментарий №2) > Надо просто добавить AC_SYS_LARGEFILE. Но я так понимаю, что для 32-битных систем всё более вероятная ситуация иметь сервер на 64-битной платформе. Возможно, должно быть принято более широкое решение, как обеспечить совместимость. то ли сжимать inode в файловых системах в ядре, то ли использовать FILE_OFFSET_BITS (stat64), то ли что-то ещё. Кстати, на тему: http://sandeen.net/wordpress/computers/the-world-wants-32-bit-inodes/
(In reply to comment #3) > (В ответ на комментарий №2) > > Надо просто добавить AC_SYS_LARGEFILE. > Но я так понимаю, что для 32-битных систем всё более вероятная ситуация иметь > сервер на 64-битной платформе. > > Возможно, должно быть принято более широкое решение, как обеспечить > совместимость. то ли сжимать inode в файловых системах в ядре, то ли > использовать > FILE_OFFSET_BITS (stat64), то ли что-то ещё. Достаточно просто добавить AC_SYS_LARGEFILE, который does the right thing.
(В ответ на комментарий №4) ... > Достаточно просто добавить AC_SYS_LARGEFILE, который does the right thing. А мы будем добавлять в sisyphus_check проверку на то, что 32-битный бинарник не использует 32-битный stat или будем ловить случайные глюки с разнообразными программами, при использовании 64-битного файлового сервера?
(In reply to comment #5) > (В ответ на комментарий №4) > ... > > Достаточно просто добавить AC_SYS_LARGEFILE, который does the right thing. > А мы будем добавлять в sisyphus_check проверку на то, что 32-битный бинарник не > использует 32-битный stat или будем ловить случайные глюки с разнообразными > программами, при использовании 64-битного файлового сервера? Мы не будем добавлять в sisyphus_check такую проверку, ей там не место. Практичнее добавить диагностику куда-нибудь в verify-elf.
(В ответ на комментарий №6) > > А мы будем добавлять в sisyphus_check проверку на то, что 32-битный бинарник не > > использует 32-битный stat или будем ловить случайные глюки с разнообразными > > программами, при использовании 64-битного файлового сервера? > > Мы не будем добавлять в sisyphus_check такую проверку, ей там не место. > Практичнее добавить диагностику куда-нибудь в verify-elf. Действительно. Тогда завёл на это отдельную задачу https://bugzilla.altlinux.org/show_bug.cgi?id=28290
-D_FILE_OFFSET_BITS=64 это ABI change на x86 (затрагивающее как минимум /usr/include/apt-pkg/clean.h), придется менять soname.
Мужчины, на мой взгляд, вы пидорасы. Какой смысол делать "проверку" на использование функций, которые используются по умолчанию? Такая "проверка" накроет половину пакетов, и что тогда, вы их вручную будете исправлять?
(In reply to comment #9) > Какой смысол делать "проверку" на > использование функций, которые используются по умолчанию? Такая "проверка" > накроет половину пакетов, и что тогда, вы их вручную будете исправлять? Напрашивается прямая аналогия: Какой смысл добавлять -Wall в %optflags? Такая "проверка" накроет больше половины пакетов, и что тогда, их тоже вручную исправлять?
Мужчины, получается, что у вас _все_ программы по умолчанию дефектные, т.к. они используют дефолтный ABI. Довольно абсурдная ситуация. Может тогда не использовать по умолчанию дефолтный ABI? :-) Напишите тогда в апстрим glibc: "hey queers, нам пришла в голову fascinating idea!..." И не понятно, почему программы падают. Если 64-битный i-node урезать до 32-битного, то упасть еще никто не должен. Ядро отдает номера i-нодов, чтобы юзеру проще было идентифицировать файлы, но назад их не берёт.
(In reply to comment #11) > Мужчины, получается, что у вас _все_ программы по умолчанию дефектные, т.к. они > используют дефолтный ABI. Довольно абсурдная ситуация. Да, так исторически сложилось. Впрочем, большинство GNU'шных и некоторое множество остальных программ используют AC_SYS_LARGEFILE корректно. Так что сейчас уже далеко не все дефектные. > Может тогда не > использовать по умолчанию дефолтный ABI? :-) Думаю, никому не надо объяснять, почему нельзя менять это умолчание. > Напишите тогда в апстрим glibc: > "hey queers, нам пришла в голову fascinating idea!..." Самому себе предлагаешь написать? Нет, это развлечение не по мне. > И не понятно, почему программы падают. В данном случае не падают, а просто работают неправильно - файлов не видят. > Если 64-битный i-node урезать до > 32-битного, то упасть еще никто не должен. Ядро отдает номера i-нодов, чтобы > юзеру проще было идентифицировать файлы, но назад их не берёт. Чего гадать, когда можно просто в linux/fs/stat.c исходный код посмотреть. Например, там написано, что stat(2) возвращает EOVERFLOW, когда st_ino, st_nlink или st_size недостаточного размера.
Точно, linux/fs/stat.c отказывается урезать длинные номера i-нодов. Но классическая реализация фс предполагает, что i-ноды выделяются заранее и нумеруются последовательно (и потом повторно используются), в частности, корневой каталог фс имеет i-нод примерно равный два (какой точно забыл) и т.д. Так что в классической реализации номера i-нодов имеют право переполинться, только если файлов на диске больше 4 млрд. Если каждый i-нод занимает на диске 128 байтов, то в сумме i-ноды на такой фс займут 0.5Тб. Поэтому идея 32-битного ABI по умолчанию выглядит в общем-то жизнеспособной. А почему нельзя переключиться на 64-битный ABI по умолчанию?
Действительно, для классической реализации (например, ext4 в текущем состоянии) особых проблем нет (при значении по умолчанию inode_ratio = 16384 32-битных номеров inode хватит для ФС размером до 64 ТБ). Однако далеко не все ФС имеют подобную структуру, позволяющую легко вписываться в ограничения на номера inode. Например, в btrfs в качестве номера inode используется внутренний идентификатор объекта ФС, при этом идентификаторы назначаются последовательно по возрастанию и не используются повторно, так что переполнение 32-битного номера inode произойдёт после выполнения около 2^32 операций создания файлов. Наиболее проблемная в этом плане ФС из популярных, видимо, xfs, где используется следующий формат номера inode: /* * Inode number format: * low inopblog bits - offset in block * next agblklog bits - block number in ag * next agno_log bits - ag number * high agno_log-agblklog-inopblog bits - 0 */ При этом по умолчанию inopblog = 4 (в блок размером 4К помещается 16 записей inode размером 256 байт), а agblklog + agno_log — это примерно число битов, необходимое для адресации всех блоков ФС; в результате получается, что 32-битного номера inode в случае произвольного размещения inode достаточно лишь при размере ФС не более 1 ТБ. Для совместимости в xfs в ядрах до 3.7 по умолчанию не разрешалось размещение inode за пределами области, в которой номера inode помещаются в 32 бита, однако такой режим, во-первых, может снижать производительность (поскольку не удаётся разместить inode рядом с данными файла), во-вторых, мог приводить к невозможности создания файлов при видимом наличии свободного места, если вся область ниже 1 ТБ оказывалась заполненной. Начиная с ядра 3.7 опция inode64 для xfs используется по умолчанию, а для включения режима совместимости добавлена опция монтирования inode32 (также можно переключать эти режимы на смонтированной ФС, что повлияет на размещение inode для создаваемых после переключения файлов).
(In reply to comment #13) > А почему нельзя переключиться на 64-битный ABI по умолчанию? 64-битный ABI - это не столько ino_t, сколько off_t. Когда ты включаешь этот 64-битный ABI, меняются не только объекты типа ino_t, которых относительно немного, но и объекты типа off_t, которые встречаются на каждом шагу. В каждом случае нужно убедиться, что 64-битный тип не преобразуется к 32-битному типу, что нигде указатели на 32-битные типы не обрабатываются как указатели на 64-битные типы, и наоборот. В общем, такие изменения нельзя делать неявно.
apt-0.5.15lorg2-alt42 -> sisyphus: * Thu Jan 10 2013 Dmitry V. Levin <ldv@altlinux> 0.5.15lorg2-alt42 - Fixed and enabled LFS support (closes: #28214).