У меня есть тест приложения C ++, который создает 10000 файлов в смонтированном каталоге NFS, но недавно мой тест не прошел один раз из-за того, что один файл дважды появлялся в этом каталоге с тем же именем вместе со всеми остальными 10000 файлами. Это можно увидеть в Linux Centos v4 или v5, где каталог смонтирован по NFS, но не на хост-компьютере, где находится диск.
Как вообще возможно иметь два файла с одинаковым именем в одном каталоге?
[centos4x32 destination] ls -al ./testfile03373
-rwx------ 1 user root 3373 Sep 3 03:23 ./testfile03373*
[centos4x32 destination] ls -al ./testfile03373*
-rwx------ 1 user root 3373 Sep 3 03:23 ./testfile03373*
-rwx------ 1 user root 3373 Sep 3 03:23 ./testfile03373*
[centos4x32 destination] ls -al *testfile03373
-rwx------ 1 user root 3373 Sep 3 03:23 testfile03373*
-rwx------ 1 user root 3373 Sep 3 03:23 testfile03373*
[centos4x32 destination] ls -alb test*file03373
-rwx------ 1 user root 3373 Sep 3 03:23 testfile03373*
-rwx------ 1 user root 3373 Sep 3 03:23 testfile03373*
Запуск сценария Perl, предложенного в одном из ответов ниже:
ls -la *03373* | perl -e 'while(<>){chomp();while(/(.)/g){$c=$1;if($c=~/[!-~]/){print("$c");}else{printf("\\x%.2x",ord($c));}}print("\n");}'
дает:
-rwx------\x20\x201\x20user\x20root\x203373\x20Sep\x20\x203\x2003:23\x20testfile03373*
-rwx------\x20\x201\x20user\x20root\x203373\x20Sep\x20\x203\x2003:23\x20testfile03373*
Печать со значениями inode (-i) показывает, что две копии имеют одинаковую запись inode (36733444):
[h3-centos4x32 destination] ls -alib te*stfile03373
36733444 -rwx------ 1 user root 3373 Sep 3 03:23 testfile03373*
36733444 -rwx------ 1 user root 3373 Sep 3 03:23 testfile03373*
Казалось бы, запись каталога как-то повреждена.
Могло ли мое приложение законно создать такую ситуацию, или это ошибка в операционной системе? Могу ли я что-нибудь сделать для защиты от этого в моей программе, которая создает файлы?
Я думаю, что есть какая-то ошибка в программе монтирования NFS. Также «umount» и затем «mount» диска NFS, в котором возникла проблема, не устраняет ее, повторная запись остается после перемонтирования.
Обновление 1: теперь я столкнулся с этой проблемой второй раз, несколько часов спустя, и действительно странно, что это произошло с точно таким же файлом testfile03373
, хотя на этот раз он получил другой инод, 213352984, для дублированных файлов. Я также добавлю, что файл создается на компьютере Centos 5, где размещается диск, поэтому он создается локально и показывает правильное локально, но все остальные машины, которые его монтируют в NFS, видят двойную запись.
Обновление 2: я смонтировал диск на машине Centos v6 и /var/log/messages
после перечисления обнаружил следующее :
[root@c6x64 double3373file]# ls -laiB testfile03373* ; tail -3 /var/log/messages
36733444 -rwx------. 1 user root 3373 Sep 3 03:23 testfile03373
36733444 -rwx------. 1 user root 3373 Sep 3 03:23 testfile03373
...
Sep 4 14:59:46 c6x64 kernel: NFS: directory user/double3373file contains a readdir loop.Please contact your server vendor. The file: testfile03373 has duplicate cookie 7675190874049154909
Sep 4 14:59:46 c6x64 kernel: NFS: directory user/double3373file contains a readdir loop.Please contact your server vendor. The file: testfile03373 has duplicate cookie 7675190874049154909
Кроме того, я обнаружил, что переименование файла приводит к исчезновению двойной записи, но переименование его обратно приводит к повторному появлению в два раза, или, наоборот, простое касание нового файла с именем testfile03373
приводит к появлению двойной записи, но это происходит только в две директории, где эта двойная запись была замечена.
источник
Ответы:
Друг помог мне отследить это и обнаружил, что это ошибка, записанная в Bugzilla 38572 для ядра Linux здесь . Ошибка предположительно исправлена в версии 3.0.0 ядра, но присутствует по крайней мере в версии 2.6.38.
Проблема заключается в том, что RPC-вызов сервера ReadDIR () возвращает неверные результаты. Это происходит из-за следующего:
Когда клиент читает каталог, он указывает максимальный размер буфера и обнуляет cookie. Если каталог слишком большой, ответ указывает, что ответ является только частичным, и обновляет cookie. Затем клиент может повторно выполнить RPC с обновленным файлом cookie, чтобы получить следующий фрагмент данных. (Данные представляют собой наборы дескрипторов файлов и имен. В случае ReadDirPlus () также есть данные stat / inode / vnode.) В документации не указывается, что это ошибка в ReadDirPlus (), но, вероятно, она есть также.
Фактическая проблема заключается в том, что последний файл в каждом чанке (имя, дескриптор кортежа) иногда возвращается как первый файл в следующем чанке.
Плохое взаимодействие с основными файловыми системами. Ext4 показывает это, XFS нет.
Вот почему проблема возникает в некоторых ситуациях, но не в других, и редко возникает в небольших каталогах. Как видно из описания вопроса, файлы показывают одинаковый номер инода, а имена идентичны (не повреждены). Поскольку ядро Linux вызывает операции vnode для базовых операций, таких как open () и т. Д., Базовые процедуры файловой системы решают, что произойдет. В этом случае клиент NFS3 просто переводит операцию vnode в RPC, если требуемая информация отсутствует в его кэше атрибутов. Это приводит к путанице, так как клиент считает, что сервер не может этого сделать.
источник
Вероятно, ошибка, проблема или состояние гонки с NFS.
Возможно иметь два файла с одинаковым именем, если вы напрямую редактируете структуры файловой системы с помощью шестнадцатеричного редактора. Однако я не уверен, что произойдет, если вы попытаетесь удалить или открыть файлы. Я не уверен, какие инструменты существуют в Linux для доступа к файлу по номеру инода (который не может быть дублирован), но это может сработать.
Дублирующиеся имена файлов - это то,
fsck
что скорее всего поймает и попытается исправить.Удостоверьтесь, что ни один из файлов не имеет разные конечные пробелы.
источник
fsck
нашел проблем. Перезагружал и хост и клиентские машины, проблема все еще показывает.fsck
вероятно, будет работать только на локальной файловой системе, а не на смонтированной NFS. Возможно, вам нужно обновить / исправить ваши пакеты nfs и, возможно, ваше ядро. Как упоминает @somequixotic, ваш CentOS устарел, и проблемы, с которыми вы столкнулись, могли быть решены в будущих обновлениях.Существует вероятность того, что у вас есть скрытый непечатный символ или пробел в одном из имен файлов. Вы можете проверить с помощью
-b
опцииls
, например:Обратите внимание на
\
обозначение пробела в конце этого имени файла.В качестве альтернативы (хотя вышеприведенное должно работать), вы можете передать вывод через этот сценарий perl, чтобы заменить все, что не является печатным символом ASCII, его шестнадцатеричным кодом. Например, пробел становится
\x20
.Применение:
источник