Процесс открыл inode, которого нет ни в одной файловой системе?

Процесс открыл inode, которого нет ни в одной файловой системе?

Поэтому я пытаюсь выяснить, не stderrбыл ли процесс перенаправлен куда-то необычным образом (это процесс Java, и мне нужен дамп потока, но он запускается через набор стартовых скриптов).

Я нахожу свой процесс с помощью pgrepи использую, pfilesчтобы посмотреть, что там:

4366: /foo/bar/platform/solaris2/jre_1.5.0/bin/java -Xmx2048m -Xms10
Текущий лимит: 65536 файловых дескрипторов
 0: S_IFCHR режим:0666 dev:302,0 ino:6815752 uid:0 gid:3 rdev:13,2
    O_RDONLY|O_LARGEFILE
    /devices/pseudo/mm@0:null
 1: S_IFREG режим:0640 dev:85,56 ino:26471 uid:0 gid:0 размер:10485812
    O_WRONLY|O_LARGEFILE
 2: S_IFREG режим:0640 dev:85,56 ino:26471 uid:0 gid:0 размер:10485812
    O_WRONLY|O_LARGEFILE
 3: S_IFCHR режим:0666 dev:302,0 ino:6815772 uid:0 gid:3 rdev:13,12

Итак, я вижу, что stdoutи stderr(файловые дескрипторы 1 и 2) указывают на одно и то же место; я думаю, что они перенаправлены на один и тот же файл в скриптах запуска, так что это совпадает.

Но когда я ищу файл с номером инода 26471, я вижу это:

# найти / -inum 26471
/usr/share/man/man3mlib/mlib_MatrixScale_S16_U8_Sat.3mlib
/proc/4366/fd/1
/проц/4366/фд/2
/проц/4366/фд/83

Первое попадание (я уверен) — файл на другой файловой системе. Три записи — /procэто fds, которые открыл мой процесс.

Заглянув туда /proc/4366, я не вижу больше информации, чем получаю от pfiles.

# ls -li 0 1 2 3
   6815752 c--------- 1 root sys 13, 2 янв. 20 14:10 0
     26471 --w------- 0 root root 10485812 20 января 13:42 1
     26471 --w------- 0 root root 10485812 20 января 13:42 2
   6815772 c--------- 1 root sys 13, 12 7 июня 2009 3
# файл 0 1 2 3
0: специальный символ (13/2)
1: текст ascii
2: текст ascii
3: особый персонаж (13/12)

(Я могу отследить один из этих fds и по нему определить, какой это файл. Я спрашиваю, потому что явно не понимаю достаточно глубоко взаимосвязь между fds и inode).

Итак, мой процесс заключается в том, чтобы писатьчто-нибудь(на каком-то устройстве с инодом 26471) и данные затем попадают в файл с другим номером инода. Может ли кто-нибудь дать мне представление о том, что это может быть (или даже дать мне знать, если мои рассуждения до сих пор полностью сломаны)?

решение1

AFAIK, findищет в каталогах файловой системы. Если этот файл был удален, но все еще существует, потому что он открыт (обычный трюк в unix), он не будет найден find.

Я не пробовал в Solaris, ноздесьесть заметка об использовании lsofдля идентификации таких «удаленных, но открытых» файлов и восстановлении с помощьюcat /proc/<procid>/fd/<fdid> > /tmp/xxxx

Редактировать:

кажется, вы уже определили, что это так, но все еще задаетесь вопросом, как это возможно. Вот краткое объяснение:

В файловых системах POSIX файлы обрабатываются его inode, а каталоги представляют собой не более чем сопоставление "путь => inode". У вас может быть более одного пути, "указывающего" на один и тот же inode (это называется жесткой ссылкой), и inode ведет подсчет количества ссылок, которые у него есть. Команда rmпросто вызывает unlink()этот путь, что уменьшает количество ссылок и "возможно" удаляет сам файл.

Но путь в дереве каталогов — это не единственная возможная ссылка на inode, открытие fdв запущенном процессе также учитывается, а «удаленный» файл не будет по-настоящему удален, пока его значение не достигнет 0.

Как я уже упоминал выше, это распространенный трюк: если у вас есть временный файл, который вы не хотите сохранять после завершения процесса, просто откройте его и немедленно «удалите». Открытый дескриптор будет работать надежно, и когда ваш процесс завершится (нормально, убит или аварийно), система удалит дескриптор и аккуратно удалит временный файл.

Файл журнала вряд ли является подходящим кандидатом на роль такого «скрытого автоудаляемого» файла, но это несложно сделать случайно.

Поскольку ваш удаленный файл журнала все еще активен и собирает данные, похоже, простое копирование содержимого не поможет. поэтому попробуйте создать новую жесткую ссылку на файл /proc//fd/, что-то вроде ln /proc/4366/fd/1 /tmp/xxxx. Обратите внимание, что флага нет -s, поэтому lnследует создать новую жесткую ссылку с тем же inode, что и у оригинала, а не символическую ссылку (которая представляет собой не более чем указатель на существующий путь, а не то, что вам нужно).

Редактировать:

Команда ln /proc/... /tmp/...не может работать, поскольку /proc и /tmp находятся в разных файловых системах. К сожалению, я не знаю способа создать имя пути для существующего inode. Можно было бы захотеть, чтобы link()системный вызов принимал номер inode и путь, но он принимает исходный и целевой пути.

Связанный контент