Еще информация к размышлению. strace кроме EFBIG выдает еще и SIGXFSZ:
с одной стороны подозрение вызывает lseek. Единственное место где он вызывается --- файл CFile.cpp, причем в форме lseek, которая может оказаться 32 и 64 битной. Однако, в Makefile определяется -D_FILE_OFFSET_BITS=64 в результате чего lseek превращается в корректный уже 64-битный _llseek , к тому же он возвращает успех. Так что похоже lseek не виноват.Code:_llseek(11, 1108992000, [1108992000], SEEK_SET) = 0 write(11, "d\363\303\32\355\263x\261\327\2447\271\350\336\332\302"..., 10240) = -1 EFBIG (File too large) --- SIGXFSZ (File size limit exceeded) @ 0 (0) ---
Далее цитата из man 2 write:
Итак EFBIG могут вызвать 3 причины, а именно, попытки:Code:EFBIG An attempt was made to write a file that exceeds the implementation-defined maximum file size or the process' file size limit, or to write at a position past the maximum allowed offset.
1) write a file that exceeds the implementation-defined maximum file size;
2) write a file that exceeds the process' file size limit;
3) write at a position past the maximum allowed offset.
Причем SIGXFSZ (File size limit exceeded), похоже, указывает на вариант №2.
Далее, существует такое понятие как лимиты ресурсов или RLIMIT, причем они используются в файле amule.cpp
, правда их там пытаются выставить в максимум.
Цитата из man 2 getrlimits , касаемо лимита размера файла, который может создать процесс:
Очень похоже на нашу ситуацию, по крайней мере оба ключевых слова (SIGXFSZ и EFBIG) присутствуют.Code:RLIMIT_FSIZE The maximum size of files that the process may create. Attempts to extend a file beyond this limit result in delivery of a SIGXFSZ signal. By default, this signal terminates a process, but a process can catch this signal instead, in which case the relevant system call (e.g., write() truncate()) fails with the error EFBIG.
Чему же равен RLIMIT_FSIZE
возвращает 2147483647 2147483647 4 2147483647Code:#include <sys/time.h> #include <sys/resource.h> #include <stdio.h> int main() { struct rlimit rl; int res = getrlimit(RLIMIT_FSIZE, &rl); printf("%ld %ld %d %ld\n", rl.rlim_cur, rl.rlim_max, sizeof(rlim_t), RLIM_INFINITY); }
Это величина в байтах. Первое число т.н. soft rlimit , второе hard rlimit . Соответственно, при желании можем их установить, причем soft <= hard . Величины эти имеют тим rlim_t и являются 32-битными. Необходимо отметить, что у свежей suse они тоже четырехбитные (-1 -1 4 -1, что по сути есть то же самое). В результате непонятно как вообще в линухе можно работать с файлами более 2 Гб если лимит размера файла четырехбайтный.![]()
Дополнение. А вот, кстати, где сидит 1 Гигабайт. Если запустить strace amuled -f, т.е. прописать его с самого начала, а не атачить к pid-у, то как раз и наблюдается то о чем я писал выше. Этот код выполняется в файле amule.cpp . А вот изменить то эти цифры что-то ни хрена не получается.
Дополнение 2. Короче дело в следующем. Как и предполагалось в начале виноваты искривления uclibc . Максимальное значение RLIMIT_FSIZE равное RLIM_INFINITY определяется в ней для части архитектур как (~0UL), а для второй части, в т.ч. mipsel как (~0UL>>1) . А setrlimit для перестраховки делает еще раз >>1 Отсюда и берется 1Гб. Если закомментировать одну строчку (избавиться от setrlimit, который в общем то на хрен не нужен), то проблема исчезает:Code:getrlimit(RLIMIT_DATA, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0 setrlimit(RLIMIT_DATA, {rlim_cur=1073741823, rlim_max=1073741823}) = 0 getrlimit(RLIMIT_FSIZE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0 setrlimit(RLIMIT_FSIZE, {rlim_cur=1073741823, rlim_max=1073741823}) = 0 getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0 setrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0 getrlimit(RLIMIT_RSS, {rlim_cur=7401488, rlim_max=4735824}) = 0 setrlimit(RLIMIT_RSS, {rlim_cur=720283552, rlim_max=2147449912}) = 0
strace после операции (getrlimit оставлен чисто для контроля):
Причем, как ни странно, вместо ожидаемого увеличения объема от 1 до 2 Гб, похоже проблема снялась совсем и, наконец, заработал LFS (aMule, кстати, не дает поставить на загрузку ссылку больше 4Гб ни под mipsel ни под виндой):Code:getrlimit(RLIMIT_DATA, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0 getrlimit(RLIMIT_FSIZE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0 getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0 getrlimit(RLIMIT_RSS, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
Code:_llseek(13, 4205578240, [4205578240], SEEK_SET) = 0 write(13, "\210\302\2568\10\25\322\16\225\350!\372\200OQ\6x\326\362"..., 10240) = 10240 _llseek(13, 4205598720, [4205578240], SEEK_SET) = 0 write(13, "\216\35{\312\347\305\271\247\243{\206\202\357\254\311`"..., 10240) = 10240 _llseek(13, 4205608960, [4205608960], SEEK_SET) = 0 write(13, "\36\250\2732;\354C!\356\232\376\352\365\202\177,~h\233"..., 10240) = 10240


Reply With Quote
Чем отличаются наши системы компиляции я не понимаю. Единственное что бросается в глаза сразу --- мой amuled имеет размер 3.6Мб, а у oleo 3.2Мб ... Я делал кросс-компиляция согласно первой половине этой инструкции 
