Bug 32805

Summary: i586: fts_read: Value too large for defined data type
Product: Sisyphus Reporter: Sergey Y. Afonin <asy>
Component: osecAssignee: Alexey Gladkov <legion>
Status: CLOSED FIXED QA Contact: qa-sisyphus
Severity: normal    
Priority: P3 CC: glebfm, legion
Version: unstable   
Hardware: all   
OS: Linux   

Description Sergey Y. Afonin 2016-11-24 22:00:20 MSK
При испытаниях 1.2.7 наткнулся на

osec: /foo/foo.zip: fts_read: Value too large for defined data type
Program (/usr/bin/osec) exited abnormally, exit code = 1

Объём файла, конечно, знатный: 2540425259.
Comment 1 Sergey Y. Afonin 2016-11-25 00:20:30 MSK
/foo/foo.zip в exclude.conf не спасает. Обработка файла раньше происходит, получается, чем exclude работает ?
Comment 2 Alexey Gladkov 2016-11-25 13:11:46 MSK
$ dd if=/dev/zero of=/tmp/5/foo bs=1024 count=5000000
5000000+0 записей получено
5000000+0 записей отправлено
 скопировано 5120000000 байт (5,1 GB), 95,1987 c, 53,8 MB/c

$ ./osec -D /tmp/osec -R /tmp/5/
Init database for /tmp/5 ...
/tmp/5	stat	new	 uid=legion gid=legion mode=40755 inode=14814011
/tmp/5/foo	checksum	new	 checksum=4f42574db865484f66b08f38c0ee3ed145f1d445
/tmp/5/foo	stat	new	 uid=legion gid=legion mode=100644 inode=14821585

И повторный

$ ./osec -D /tmp/osec -R /tmp/5/
Processing /tmp/5 ...
Comment 3 Alexey Gladkov 2016-11-25 13:12:27 MSK
У меня не воспроизводится. Как воспроизвести ?
Comment 4 Alexey Gladkov 2016-11-25 13:17:21 MSK
(В ответ на комментарий №1)
> /foo/foo.zip в exclude.conf не спасает. Обработка файла раньше происходит,
> получается, чем exclude работает ?

На каталоги первого уровня exclude до процесса создания базы. На файлы/каталоги которые попадают в определённую базу exclude действует после fts_read.

Вы собирали osec сами ?
Comment 5 Sergey Y. Afonin 2016-11-25 16:16:06 MSK
(In reply to comment #4)

> На каталоги первого уровня exclude до процесса создания базы.
> На файлы/каталоги которые попадают в определённую базу exclude
> действует после fts_read.

Понятно. Тогда я зря не указал точнее. Это второй уровень: /home/user/foo.zip. И, теоретически, такое может и глубже оказаться.

> Вы собирали osec сами ?

Да. А вот как воспроизвести... Попробую в разных вариантах. Кстати, вот что может быть существенно. Это в OpenVZ контейнере (но failcnt все по нулям правда) и i586.
Comment 6 Alexey Gladkov 2016-11-25 16:36:00 MSK
(В ответ на комментарий №5)
> Понятно. Тогда я зря не указал точнее. Это второй уровень: /home/user/foo.zip.
> И, теоретически, такое может и глубже оказаться.

Тогда exclude будет работать после fts_read.

> > Вы собирали osec сами ?
> 
> Да. А вот как воспроизвести... Попробую в разных вариантах. Кстати, вот что
> может быть существенно. Это в OpenVZ контейнере (но failcnt все по нулям
> правда) и i586.

Такое ощущение, что вам не хватает AC_SYS_LARGEFILE.
Comment 7 Sergey Y. Afonin 2016-11-25 17:02:47 MSK
(In reply to comment #6)

> > И, теоретически, такое может и глубже оказаться.
> 
> Тогда exclude будет работать после fts_read.

А на сколько сложно сделать, чтобы было до ? С этим архивом частный случай, но хотелось бы, чтобы работало с вариантом

/var/www/vhosts/*/log
/var/www/vhosts/*/log/*
Comment 8 Alexey Gladkov 2016-11-25 22:20:10 MSK
(В ответ на комментарий №7)
> А на сколько сложно сделать, чтобы было до ?

Так можно сделать только если реализовывать обход дерева руками. Это глобальное переписывание кода и скорее всего будет потеря в скорости.

> С этим архивом частный случай, но хотелось бы, чтобы работало с вариантом
> 
> /var/www/vhosts/*/log
> /var/www/vhosts/*/log/*

Я не очень понял.
Comment 9 Sergey Y. Afonin 2016-11-26 13:41:30 MSK
(In reply to comment #8)

> > С этим архивом частный случай, но хотелось бы, чтобы работало с вариантом
> > 
> > /var/www/vhosts/*/log
> > /var/www/vhosts/*/log/*
> 
> Я не очень понял.

В смысле, чтобы быстро работало, слово не дописал. Исходя из #4 я так понял, что логи обсчитываются, раз они глубже первого уровня, а это время. Ещё может быть вариант с кэшами, и т.п.
Comment 10 Alexey Gladkov 2016-11-26 15:14:31 MSK
(В ответ на комментарий №9)
> В смысле, чтобы быстро работало, слово не дописал. Исходя из #4 я так понял,
> что логи обсчитываются, раз они глубже первого уровня, а это время. Ещё может
> быть вариант с кэшами, и т.п.

Вы не знаете что такое fts(3). Это не чтение файлов, а обход дерева каталогов.
Comment 11 Sergey Y. Afonin 2016-11-28 18:46:21 MSK
(In reply to comment #2)

> $ dd if=/dev/zero of=/tmp/5/foo bs=1024 count=5000000
> 5000000+0 записей получено
> 5000000+0 записей отправлено
>  скопировано 5120000000 байт (5,1 GB), 95,1987 c, 53,8 MB/c
> 
> $ ./osec -D /tmp/osec -R /tmp/5/

Уменя на таком файле воспроизводится на i586. На x86_64 работает нормально.

(In reply to comment #6)

> Такое ощущение, что вам не хватает AC_SYS_LARGEFILE.

Вероятно. Просто добавление AC_SYS_LARGEFILE в configure.ac не помогает, хотя при сборке появляется:

checking for _FILE_OFFSET_BITS value needed for large files... 64

"#define _FILE_OFFSET_BITS 64" должен как-то в коде учитываться ?
Comment 12 Sergey Y. Afonin 2016-11-28 18:48:49 MSK
(In reply to comment #10)

> Вы не знаете что такое fts(3). Это не чтение файлов, а обход дерева каталогов.

Не знаю, но я не про это, наверное. На этот файл тратится время на обсчёт контрольной суммы при том, что он попадает в паттерн исключений. Кстати, может отдельный фичереквест повесить на эту тему ? А там уж как пойдёт.
Comment 13 Alexey Gladkov 2016-11-28 19:42:02 MSK
> Уменя на таком файле воспроизводится на i586. На x86_64 работает нормально.

Какая у вас версия glibc ? до 2.23 или после.

$ readelf -sW /lib64/libc.so.6 | grep fts64
   323: 00000000000df000   36 FUNC WEAK DEFAULT 13 fts64_set@@GLIBC_2.23
   343: 00000000000df030  321 FUNC WEAK DEFAULT 13 fts64_children@@GLIBC_2.23
   559: 00000000000de670  823 FUNC WEAK DEFAULT 13 fts64_open@@GLIBC_2.23
  2066: 00000000000deaa0 1368 FUNC WEAK DEFAULT 13 fts64_read@@GLIBC_2.23
  2248: 00000000000de9b0  237 FUNC WEAK DEFAULT 13 fts64_close@@GLIBC_2.23

> Не знаю, но я не про это, наверное. На этот файл тратится время на обсчёт
> контрольной суммы при том, что он попадает в паттерн исключений.

fts это рекурсивный обход дерева. В этот момент не происходит чтения самого
файла. Оно происходет позже, когда exclude уже применился. Так что единственные
лишние операции будут stat на исключённые файлы.
Comment 14 Sergey Y. Afonin 2016-11-29 00:25:24 MSK
(In reply to comment #13)

> > Уменя на таком файле воспроизводится на i586. На x86_64 работает нормально.
> 
> Какая у вас версия glibc ? до 2.23 или после.

glibc-core-2.23-alt3

Собственно, я могу доступ дать в OVZ-контейнер i586, где всё это воспроизводится, если i586 под руками нет.

> Так что единственные лишние операции будут stat на исключённые файлы.

Понятно.
Comment 15 Sergey Y. Afonin 2016-11-29 12:39:04 MSK
(In reply to comment #14)

> > Какая у вас версия glibc ? до 2.23 или после.
> 
> glibc-core-2.23-alt3

Это в p8 и текущем Сизифе сейчас. Пересборка в i586 p7 с glibc-2.17-alt8.M70P.1 даёт тот же самый эффект.

Я правильно понимаю, что проблема в строке "while ((p = fts_read(t)))" в osec.c ? А раз p определена как FTSENT из fts.h, то следы проблемы ведут в glibc, и, похоже, там и остаются, так как bits/stat.h (struct stat, используящаяся в FTSENT) тоже из glibc.

Глядя на (bits/stat.h)

#if defined __x86_64__ || !defined __USE_FILE_OFFSET64
    __off_t st_size;                    /* Size of file, in bytes.  */
#else

Создаётся впечатление, что AC_SYS_LARGEFILE должно быть достаточно. Ладно, но если проблемы в glibc, то как iso многогигабайтные на флешки и DVD пишутся ?.. Да и без AC_SYS_LARGEFILE предполагается off64_t. 

Непонятно, на чём должен баг висеть.
Comment 16 Sergey Y. Afonin 2016-11-29 14:13:49 MSK
В osec.c config.h инклудится после fts.h, потому AC_SYS_LARGEFILE на него не действует. Только лучше от понимания этого не стало. После переноса config.h до fts.h сборке вылезло:

/usr/include/fts.h:41:3: error: #error "<fts.h> cannot be used with -D_FILE_OFFSET_BITS==64"

bin/du то как работает тогда ? Пишут, что там тоже fts_read используется...
Comment 17 Sergey Y. Afonin 2016-11-29 14:46:42 MSK
(In reply to comment #16)

> bin/du то как работает тогда ? Пишут, что там тоже fts_read используется...

А du использует не fts.h из glibc, а fts_.h из gnulib. И там нет 

#ifdef __USE_FILE_OFFSET64
# error "<fts.h> cannot be used with -D_FILE_OFFSET_BITS==64"
#endif
Comment 18 Gleb F-Malinovskiy 2016-11-29 14:58:29 MSK
(В ответ на комментарий №14)
> glibc-core-2.23-alt3

(В ответ на комментарий №16)
> fts.h сборке вылезло:
> 
> /usr/include/fts.h:41:3: error: #error "<fts.h> cannot be used with
> -D_FILE_OFFSET_BITS==64"

$ grep 'cannot be used with' /usr/include/fts.h
$ rpm -qf /usr/include/fts.h
glibc-devel-2.23-alt3.x86_64

Не уверен, что так бывает.
Comment 19 Sergey Y. Afonin 2016-11-29 15:43:02 MSK
(In reply to comment #18)

> Не уверен, что так бывает.

Бывает в glibc-devel-2.17-alt8.M70P.1. На p7 разбор заканчивал...

И чудо случилось. :-) В Сизифе на i586 работает.

Правда, в Сизифе AC_SYS_LARGEFILE не сработал почему-то:
checking for _FILE_OFFSET_BITS value needed for large files... no

Зато сработал %add_optflags -D_FILE_OFFSET_BITS=64 в спеке.

В общем, если в p7 портировать, надо fts_.h из gnulib, а в p8 можно уже glibc обойтись.
Comment 20 Sergey Y. Afonin 2016-11-29 17:35:02 MSK
С AC_SYS_LARGEFILE что-то непонятное. Вчера же добавлялся _FILE_OFFSET_BITS в config.h. Сейчас ещё раз попробовал, добавился. Единственное предположение - консольки днём перепутал, где пробовал.

Но, всё равно, не сработало, хотя #include "config.h" на первом месте в osec.c, и #define _FILE_OFFSET_BITS 64 есть в config.h. Если из спека %add_optflags -D_FILE_OFFSET_BITS=64 убрать, то не работает. Но это же, по идее, одно и то же, что в config.h, что в параметре компилятора ?
Comment 21 Sergey Y. Afonin 2016-12-09 09:12:28 MSK
На свежеобновлённом сизифе i586:

osec: /home/test/foo: fts_read: Value too large for defined data type
Program (/usr/bin/osec) exited abnormally, exit code = 1

И /etc/osec/exclude.conf: Not found, parameter EXCLUDE will be ignored

-mv -- etc/dirs.conf .%_datadir/pipe.conf etc/osec/
+mv -- etc/dirs.conf etc/exclude.conf .%_datadir/pipe.conf etc/osec/
Comment 22 Alexey Gladkov 2016-12-10 19:27:18 MSK
(В ответ на комментарий №21)
> На свежеобновлённом сизифе i586:
> 
> osec: /home/test/foo: fts_read: Value too large for defined data type
> Program (/usr/bin/osec) exited abnormally, exit code = 1

В сизиф уехала сборка с _FILE_OFFSET_BITS=64

http://webery.altlinux.org/log/sisyphus/tested/174238/build/100/i586/log#L188
 
> И /etc/osec/exclude.conf: Not found, parameter EXCLUDE will be ignored

$ rpm2cpio osec-cronjob-1.2.7-alt2.i586.rpm |cpio -t |grep exclude
./etc/osec/exclude.conf
Comment 23 Sergey Y. Afonin 2016-12-10 22:17:35 MSK
(In reply to comment #22)

> > osec: /home/test/foo: fts_read: Value too large for defined data type
> > Program (/usr/bin/osec) exited abnormally, exit code = 1
> 
> В сизиф уехала сборка с _FILE_OFFSET_BITS=64

Взял из archive/done/_170/174238. Не работает. Вернул сборку с %add_optflags -D_FILE_OFFSET_BITS=64
Comment 24 Alexey Gladkov 2016-12-11 01:40:48 MSK
(В ответ на комментарий №23)
> Взял из archive/done/_170/174238. Не работает. Вернул сборку с %add_optflags
> -D_FILE_OFFSET_BITS=64

Попробуйте пожалуйста osec-1.2.7-alt3 из задания #174267
Comment 25 Repository Robot 2016-12-15 23:49:05 MSK
osec-1.2.7-alt3 -> sisyphus:

* Sat Dec 10 2016 Alexey Gladkov <legion@altlinux> 1.2.7-alt3
- Use _FILE_OFFSET_BITS=64 (ALT#32805).
- Add default value to identify parser error (ALT#28770).
Comment 26 Sergey Y. Afonin 2016-12-16 08:51:16 MSK
Теперь работает.
Comment 27 Sergey Y. Afonin 2017-11-08 08:28:25 MSK
(In reply to comment #18)

> > Не уверен, что так бывает.
> 
> Бывает в glibc-devel-2.17-alt8.M70P.1. На p7 разбор заканчивал...

На всякий случай ссылка: Bug #34093