Jeśli to zrobię (w powłoce Bourne'a):
exec 3> file 4>&3 5> file 6>> file
Deskryptory plików 3 i 4, ponieważ 4 był dup()
edytowany z 3, dzielą ten sam otwarty opis pliku (te same właściwości, to samo przesunięcie w pliku ...). Chociaż deskryptory plików 5 i 6 tego procesu znajdują się w innym otwartym opisie pliku (na przykład każdy z nich ma własny wskaźnik w pliku).
Teraz w lsof
wyniku widzimy tylko:
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
Jest trochę lepiej z 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
(tutaj w Linuksie 3.16), ponieważ widzimy, że fd 6 ma inne flagi, więc musi to być inny opis otwartego pliku niż ten na fd 3, 4 lub 5, ale z tego nie wiemy, że fd 5 jest na inny opis otwartego pliku . Za pomocą -o
możemy również zobaczyć przesunięcie, ale ponownie to samo przesunięcie nie gwarantuje, że jest to ten sam opis otwartego pliku .
Czy jest jakiś nieinwazyjny 1 sposób, aby się tego dowiedzieć? Zewnętrznie, czy dla własnych deskryptorów plików procesu?
1 . Jednym heurystycznym podejściem może być zmiana flag jednego fd za pomocą fcntl()
i sprawdzenie, w jaki sposób inne deskryptory plików mają zaktualizowane flagi, ale to oczywiście nie jest idealny ani głupi dowód
źródło
Odpowiedzi:
W Linuksie 3.5 i nowszych można to zrobić za pomocą kcmp (3) :
Strona man zawiera przykład konkretnie dla przypadku użycia OP, o który pytano. Zauważ, że to wywołanie systemowe wymaga kompilacji jądra z
CONFIG_CHECKPOINT_RESTORE
setem.źródło
struct file *
wskaźniki.To, co chcesz porównać, to
struct file
wskaźniki, na które wskazują deskryptory plików. (Wewnątrz jądra znajduje się jednatask_struct
struktura danych dla każdego wątku. Zawiera on wskaźnik do innej struktury o nazwiefiles_struct
. I ta struktura zawiera tablicę wskaźników, każdy do astruct file
. To onstruct file
zawiera przesunięcie wyszukiwania, otwarte flagi i kilka innych pól.)Nie znam żadnego widocznego dla użytkownika sposobu, aby zobaczyć wskaźniki w
files_struct
inny sposób niż użycie niektórych natrętnych narzędzi. Na przykład SystemTap może otrzymać PID i może znaleźć odpowiednitask_struct
i postępować zgodnie ze wskazówkami. Jeśli jednak szukasz umiejętności pasywnej, myślę, że o to chodzi. Firma Dell wydała dawno narzędzie o nazwie KME (Kernel Memory Editor), które udostępnia interfejs podobny do arkusza kalkulacyjnego do żywej pamięci jądra i może robić to, co chcesz, ale nigdy nie zostało przeniesione do wersji 64-bitowej. (Próbowałem i nigdy nie działałem całkowicie, i nie byłem pewien, dlaczego).Jednym z powodów, dla których nie jesteś
lsof
pomocny, jest to, że nie widzi tych wskaźników (ale spójrz na+f
opcję dla systemów innych niż Linux). Można teoretycznie porównać wszystkie pola wstruct file
i pomyśleć, że obie struktury są takie same, ale wciąż mogą pochodzić z osobnychopen(2)
wywołań.Spójrz na pomysły pfiles SystemTap. Jeśli zmodyfikujesz go, aby wydrukować adres
struct file
, będziesz mieć swoje rozwiązanie. Możesz także sprawdzić plik open_file_by_pid.stp, ponieważ jest w nim funkcja, która chodzifiles_struct
, tj. tablica deskryptorów plików, patrząc nastruct file
obiekty ...Czy mogę zapytać, co próbujesz osiągnąć?
źródło
probe begin
blok ifor_each_process
niech użyje makra w bloku kodu C osadzonego w skrypcie (musisz użyć SystemTap w trybie „guru”, aby osadzić kod C). W rzeczywistości, aby uczynić to interesującym (!), Możesz użyć jednej z tablic asocjacyjnych SystemTap; użyjfiles_struct
adresu jako klucza oraz listy PID / TID jako wartości. Masz teraz listę każdego otwartego pliku i zadania, które je współużytkują (mogą być udostępniane między rodzicem / dzieckiem). Odpowiedz ponownie, jeśli chcesz omówić SystemTap.Oto rozwiązanie specyficzne dla systemu Linux: / proc / self / fd to katalog dowiązań symbolicznych dla otwartych uchwytów plików w bieżącym procesie. Możesz po prostu porównać wartości linków. Staje się bardziej skomplikowane, gdy używa się procesu potomnego, ponieważ dziecko będzie miało inne / proc / self, ponieważ jest to zależne od pid symboliczne łącze. Możesz obejść ten problem, używając / proc / $$ / fd, gdzie $$ jest pożądanym pid.
źródło