Если я это сделаю (в Bourne-подобной оболочке):
exec 3> file 4>&3 5> file 6>> file
Файловые дескрипторы 3 и 4, так как 4 был dup()
отредактирован от 3, имеют одинаковое описание открытого файла (те же свойства, то же смещение внутри файла ...). В то время как файловые дескрипторы 5 и 6 этого процесса находятся в разных описаниях открытого файла (например, каждый из них имеет свой собственный указатель в файле).
Теперь в lsof
результате мы видим только:
zsh 21519 stephane 3w REG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 4w REG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 5w REG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 6w REG 254,2 0 10505865 /home/stephane/file
Это немного лучше с lsof +fg
:
zsh 21519 stephane 3w REG W,LG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 4w REG W,LG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 5w REG W,LG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 6w REG W,AP,LG 254,2 0 10505865 /home/stephane/file
(здесь, в Linux 3.16), поскольку мы видим, что fd 6 имеет разные флаги, поэтому описание открытого файла должно отличаться от описания на fd 3, 4 или 5, но из этого нельзя сказать, что fd 5 находится на другое описание открытого файла . С помощью -o
мы также можем увидеть смещение, но опять же смещение не гарантирует того же описания открытого файла .
Есть ли ненавязчивые 1 способ это выяснить? Внешне или для собственных файловых дескрипторов процесса?
1 . Один эвристический подход может состоять в том, чтобы изменить флаги одного fd fcntl()
и посмотреть, как в результате у других файловых дескрипторов обновляются их флаги, но это, очевидно, не идеально и не дурак.
источник
Ответы:
Для Linux 3.5 и выше это можно сделать с помощью kcmp (3) :
Страница man предоставляет пример специально для запрашиваемого варианта использования OP. Обратите внимание, что этот системный вызов требует, чтобы ядро было скомпилировано с помощью
CONFIG_CHECKPOINT_RESTORE
set.источник
struct file *
указатели.То, что вы хотите сравнить, это
struct file
указатели, на которые указывают файловые дескрипторы. (Внутри ядра есть однаtask_struct
структура данных для каждого потока. Он содержит указатель на другую структуру, называемуюfiles_struct
. И эта структура содержит массив указателей, каждый из которых на astruct file
. Это то,struct file
что содержит смещение поиска, флаги открытия и несколько других полей.)Я не знаю ни одного видимого для пользователя способа увидеть указатели в
files_struct
другом, кроме как использовать некоторые навязчивые инструменты. Например, SystemTap может быть присвоен PID, и он может найти соответствующиеtask_struct
и следовать указателям. Если вы ищете пассивный, хотя, я думаю, что об этом. Dell давно выпустила инструмент под названием KME (Kernel Memory Editor), который предоставил интерфейс в виде электронных таблиц для оперативной памяти ядра, и он мог делать то, что вы хотите, но он никогда не был перенесен на 64-битную. (Я пытался, но так и не заработал, и не знал почему.)Одна из причин, по которой вы не находите
lsof
полезными, заключается в том, что он также не видит эти указатели (но посмотрите на+f
вариант для не-Linux систем). Вы можете теоретически сравнить все поля вstruct file
и думать, что эти две структуры одинаковы, но все же они могут быть из отдельныхopen(2)
вызовов.Посмотрите на сценарий pfiles SystemTap для идей. Если вы изменили его, чтобы распечатать адрес
struct file
, у вас будет решение. Вы также можете проверить open_file_by_pid.stp, так как в нем есть функция, которая проходитfiles_struct
, т.е. таблица дескрипторов файлов, глядя наstruct file
объекты ...Могу я спросить, чего ты пытаешься достичь?
источник
probe begin
блок и сделайте так, чтобы он использовалfor_each_process
макрос в блоке кода C, встроенного в скрипт (для встраивания кода C вам потребуется использовать SystemTap в режиме «гуру»). Фактически, чтобы сделать это интересным (!), Вы можете использовать один из ассоциативных массивов SystemTap; используйтеfiles_struct
адрес в качестве ключа, а список PID / TID в качестве значений. Теперь у вас есть список каждого открытого файла и какие задачи делятся ими (они могут быть разделены между родителем / ребенком). Ответьте еще раз, если хотите обсудить SystemTap.Вот решение для Linux: / proc / self / fd - это каталог символических ссылок для дескрипторов открытых файлов в текущем процессе. Вы можете просто сравнить значения ссылок. Это становится более сложным при использовании дочернего процесса, потому что у дочернего процесса будет другая / proc / self, потому что это символическая ссылка, зависящая от pid. Вы можете обойти эту проблему, используя / proc / $$ / fd, где $$ - желаемый pid.
источник