Bug 28214 - Системный вызов stat() для проверки файлов
: Системный вызов stat() для проверки файлов
Status: CLOSED FIXED
: Sisyphus
(All bugs in Sisyphus/apt)
: unstable
: all Linux
: P3 normal
Assigned To:
:
: http://bugs.etersoft.ru/show_bug.cgi?...
:
:
:
  Show dependency tree
 
Reported: 2012-12-11 21:35 by
Modified: 2013-01-30 07:00 (History)


Attachments


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2012-12-11 21:35:17
Недавно столкнулся с проблемой некорректной работы 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.
------- Comment #1 From 2012-12-18 15:27:41 -------
Может быть надо рассмотреть принудительную сборку всего с
-D_FILE_OFFSET_BITS=64? Получается, что ни одна программа без этого,
использующая stat, работать толком не будет.
Хотя я и не понимаю, какое дело проверке доступности файла с помощью stat до
номера inode. Мне всё же кажется, что это больше проблема функций, или ядра.
NFS вот отлично умеет сворачивать номера inode в 32-битные, как я понял.

На самом деле основная наша задача по проблеме 64 inode у нас здесь:
http://bugs.etersoft.ru/show_bug.cgi?id=8420
------- Comment #2 From 2012-12-18 16:44:58 -------
Надо просто добавить AC_SYS_LARGEFILE.
------- Comment #3 From 2012-12-20 18:26:53 -------
(В ответ на комментарий №2)
> Надо просто добавить AC_SYS_LARGEFILE.
Но я так понимаю, что для 32-битных систем всё более вероятная ситуация иметь
сервер на 64-битной платформе.

Возможно, должно быть принято более широкое решение, как обеспечить
совместимость. то ли сжимать inode в файловых системах в ядре, то ли
использовать 
FILE_OFFSET_BITS (stat64), то ли что-то ещё.

Кстати, на тему:
http://sandeen.net/wordpress/computers/the-world-wants-32-bit-inodes/
------- Comment #4 From 2012-12-20 18:37:37 -------
(In reply to comment #3)
> (В ответ на комментарий №2)
> > Надо просто добавить AC_SYS_LARGEFILE.
> Но я так понимаю, что для 32-битных систем всё более вероятная ситуация иметь
> сервер на 64-битной платформе.
> 
> Возможно, должно быть принято более широкое решение, как обеспечить
> совместимость. то ли сжимать inode в файловых системах в ядре, то ли
> использовать 
> FILE_OFFSET_BITS (stat64), то ли что-то ещё.

Достаточно просто добавить AC_SYS_LARGEFILE, который does the right thing.
------- Comment #5 From 2012-12-22 02:45:30 -------
(В ответ на комментарий №4)
...
> Достаточно просто добавить AC_SYS_LARGEFILE, который does the right thing.
А мы будем добавлять в sisyphus_check проверку на то, что 32-битный бинарник не
использует 32-битный stat или будем ловить случайные глюки с разнообразными
программами, при использовании 64-битного файлового сервера?
------- Comment #6 From 2012-12-22 04:18:33 -------
(In reply to comment #5)
> (В ответ на комментарий №4)
> ...
> > Достаточно просто добавить AC_SYS_LARGEFILE, который does the right thing.
> А мы будем добавлять в sisyphus_check проверку на то, что 32-битный бинарник не
> использует 32-битный stat или будем ловить случайные глюки с разнообразными
> программами, при использовании 64-битного файлового сервера?

Мы не будем добавлять в sisyphus_check такую проверку, ей там не место.
Практичнее добавить диагностику куда-нибудь в verify-elf.
------- Comment #7 From 2012-12-28 13:11:43 -------
(В ответ на комментарий №6)
> > А мы будем добавлять в sisyphus_check проверку на то, что 32-битный бинарник не
> > использует 32-битный stat или будем ловить случайные глюки с разнообразными
> > программами, при использовании 64-битного файлового сервера?
> 
> Мы не будем добавлять в sisyphus_check такую проверку, ей там не место.
> Практичнее добавить диагностику куда-нибудь в verify-elf.
Действительно. Тогда завёл на это отдельную задачу
https://bugzilla.altlinux.org/show_bug.cgi?id=28290
------- Comment #8 From 2013-01-11 04:54:23 -------
-D_FILE_OFFSET_BITS=64 это ABI change на x86 (затрагивающее как минимум
/usr/include/apt-pkg/clean.h), придется менять soname.
------- Comment #9 From 2013-01-11 13:06:30 -------
Мужчины, на мой взгляд, вы пидорасы.  Какой смысол делать "проверку" на
использование функций, которые используются по умолчанию?  Такая "проверка"
накроет половину пакетов, и что тогда, вы их вручную будете исправлять?
------- Comment #10 From 2013-01-12 03:03:50 -------
(In reply to comment #9)
> Какой смысол делать "проверку" на
> использование функций, которые используются по умолчанию?  Такая "проверка"
> накроет половину пакетов, и что тогда, вы их вручную будете исправлять?

Напрашивается прямая аналогия:

Какой смысл добавлять -Wall в %optflags?  Такая "проверка" накроет больше
половины пакетов, и что тогда, их тоже вручную исправлять?
------- Comment #11 From 2013-01-12 05:00:23 -------
Мужчины, получается, что у вас _все_ программы по умолчанию дефектные, т.к. они
используют дефолтный ABI.  Довольно абсурдная ситуация.  Может тогда не
использовать по умолчанию дефолтный ABI? :-)  Напишите тогда в апстрим glibc:
"hey queers, нам пришла в голову fascinating idea!..."

И не понятно, почему программы падают. Если 64-битный i-node урезать до
32-битного, то упасть еще никто не должен.  Ядро отдает номера i-нодов, чтобы
юзеру проще было идентифицировать файлы, но назад их не берёт.
------- Comment #12 From 2013-01-12 06:06:26 -------
(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 недостаточного размера.
------- Comment #13 From 2013-01-12 11:10:58 -------
Точно, linux/fs/stat.c отказывается урезать длинные номера i-нодов.  Но
классическая реализация фс предполагает, что i-ноды выделяются заранее и
нумеруются последовательно (и потом повторно используются), в частности,
корневой каталог фс имеет i-нод примерно равный два (какой точно забыл) и т.д. 
Так что в классической реализации номера i-нодов имеют право переполинться,
только если файлов на диске больше 4 млрд.  Если каждый i-нод занимает на диске
128 байтов, то в сумме i-ноды на такой фс займут 0.5Тб.  Поэтому идея
32-битного ABI по умолчанию выглядит в общем-то жизнеспособной.  А почему
нельзя переключиться на 64-битный ABI по умолчанию?
------- Comment #14 From 2013-01-12 17:07:31 -------
Действительно, для классической реализации (например, 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 для создаваемых после
переключения файлов).
------- Comment #15 From 2013-01-12 21:09:14 -------
(In reply to comment #13)
> А почему нельзя переключиться на 64-битный ABI по умолчанию?

64-битный ABI - это не столько ino_t, сколько off_t.  Когда ты включаешь этот
64-битный ABI, меняются не только объекты типа ino_t, которых относительно
немного, но и объекты типа off_t, которые встречаются на каждом шагу.  В каждом
случае нужно убедиться, что 64-битный тип не преобразуется к 32-битному типу,
что нигде указатели на 32-битные типы не обрабатываются как указатели на
64-битные типы, и наоборот.  В общем, такие изменения нельзя делать неявно.
------- Comment #16 From 2013-01-30 07:00:52 -------
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).