Назад | Перейти на главную страницу

Ошибка NFSv4 «Слишком много уровней символических ссылок»

Обе машины работают под управлением Ubuntu 12.04.

Удаленный клиент NFSv4

$ ls /mnt/storage/aaaaaaa_aaa/bbbb/cccc_ccccc gives this error:
ls: reading directory .: Too many levels of symbolic links

Как я могу это исправить?

При возникновении ошибки я начинаю перечислять файлы, однако PHP тормозит.

На сервере NFSv4

В /etc/fstab:

/mnt/storage    /srv/storage    none    bind    0 0

В /etc/exports

/srv         192.168.1.0/24(rw,async,insecure,no_subtree_check,crossmnt,fsid=0,no_root_squash)
/srv/storage   192.168.1.0/24(rw,async,nohide,insecure,no_subtree_check,no_root_squash)

ОШИБКА

root@ds:root@ds:/mnt/storage/foreign_dbs/imdb/imdb_htmls# ls -l | head
ls: reading directory .: Too many levels of symbolic links
total 10302840
-rw-r--r-- 1 root root  10484 Jul  5 13:56 0019038.gz
-rw-r--r-- 1 root root  16264 Mar 30 00:31 0259701.gz
-rw-r--r-- 1 root root  13784 Mar 30 14:20 1000000.gz
-rw-r--r-- 1 root root  12741 Mar 30 13:04 1000003.gz
-rw-r--r-- 1 root root  12794 Mar 30 12:40 1000004.gz
-rw-r--r-- 1 root root  13123 Mar 30 12:07 1000005.gz
-rw-r--r-- 1 root root  13183 Mar 30 12:04 1000006.gz
-rw-r--r-- 1 root root  13443 Jul  4 01:16 1000007.gz
-rw-r--r-- 1 root root  12968 Mar 30 11:05 1000008.gz

Я столкнулся с этим в PHP. scandir вернет 1612577.gz & 1612579.gz, но пропустит 1612578.gz, но все же типы файлов и свойства для них идентичны

и это происходит только на клиенте nfs, работает на 100% на сервере

О проблеме

У вас может возникнуть проблема, когда два или более файлов имеют одинаковый файл cookie readdir.

Эта проблема чаще встречается при использовании файловой системы NFS (v3 или v4) поверх серверной части EXT4 и с большим количеством файлов в одном каталоге (более 50000). Эта проблема также может возникнуть при использовании GlusterFS вместо NFS.

PS: Эта проблема может возникать также с несколькими файлами в одном каталоге, но этот последний случай очень маловероятен.

В этом случае вы увидите Too many levels of symbolic links ошибки, даже если у вас нет символических ссылок внутри вашего каталога. Вы можете доказать это, убедившись, что следующая команда не возвращает никаких результатов:

find /mnt/storage/aaaaaaa_aaa/bbbb/cccc_ccccc -type l

Чтобы проверить, возникает ли у вас эта конкретная проблема, выполните указанную выше команду:

$ ls /mnt/storage/aaaaaaa_aaa/bbbb/cccc_ccccc >/dev/null
ls: reading directory .: Too many levels of symbolic links

После этого проверьте свой системный журнал (/var/log/syslog) для таких записей:

[400000.200000] NFS: directory /mnt/storage/aaaaaaa_aaa/bbbb/cccc_ccccc
contains a readdir loop. Please contact your server vendor.
The file: DDDDDDDDDD has duplicate cookie COOKIE_NUMBER.

Проблема связана с readdir функция API readdir, которая использует cookie readdir для быстрого поиска файла внутри каталога. Сервер NFS использует этот API при взаимодействии с серверными модулями EXT4.

Полное и отличное объяснение проблемы дублирования файлов cookie (на самом деле проблема коллизии хэшей) можно найти по адресу Расширение файла cookie readdir () ext4.

Соответствующий отчет об ошибке можно найти на Клиент NFS сообщает о цикле readdir с поврежденным именем.

Если вы можете перезагрузить свою систему, хорошая новость в том, что по словам Дэвида Хедберга, эта проблема уже решена в более новых версиях ядра Ubuntu (> = 3.2.0-60-generic). Возможно, вам также потребуется обновить ваш сервер NFS (решение работает, только если обновлены и сервер NFS, и ядро).

PS: Если вы действительно любите операционные системы, вы можете проверить исправления ядра / nfs на http://comments.gmane.org - 32/64 битные хэши llseek.

Решение

Обновите ядро ​​и сервер ядра NFS и перезагрузите систему:

apt-get -y dist-upgrade
reboot

Если вы не можете перезагрузить систему, вы также можете обнаружить файл с дублированным файлом cookie readdir (проверьте свой системный журнал) и переместить его в другой каталог (или переименовать, чтобы изменить его cookie / хэш).

Где-то у вас есть символическая ссылка, указывающая на своего родителя. Используйте это, чтобы найти это:

find /mnt/storage -type l -exec ls -l {} \;

Как только вы это сделаете, возможно, вы сможете понять, как это исправить.