Jika saya melakukannya (dalam shell seperti Bourne):
exec 3> file 4>&3 5> file 6>> file
File deskriptor 3 dan 4, karena 4 adalah dup()
ed dari 3, berbagi deskripsi file terbuka yang sama (properti yang sama, offset yang sama dalam file ...). Sementara deskriptor file 5 dan 6 dari proses tersebut berada pada deskripsi file terbuka yang berbeda (misalnya, mereka masing-masing memiliki pointer sendiri dalam file).
Sekarang, dalam lsof
output, yang kita lihat adalah:
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
Ini sedikit lebih baik dengan 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
(di sini di Linux 3.16) di mana kita melihat fd 6 memiliki flag yang berbeda, jadi itu harus menjadi deskripsi file terbuka yang berbeda dari yang ada di fd 3, 4 atau 5, tetapi dari situ kita tidak bisa mengatakan fd 5 ada di deskripsi file terbuka berbeda . Dengan -o
, kita juga bisa melihat offset, tetapi offset yang sama tidak menjamin itu adalah deskripsi file terbuka yang sama .
Apakah ada non-intrusif 1 cara untuk mengetahui bahwa? Secara eksternal, atau untuk deskriptor file proses sendiri?
1 . Salah satu pendekatan heuristik bisa dengan mengubah bendera satu fd dengan fcntl()
dan melihat apa file deskriptor lain memiliki bendera mereka diperbarui sebagai hasilnya, tapi itu jelas tidak ideal atau bukti bodoh
sumber
Jawaban:
Untuk Linux 3.5 dan selanjutnya, ini dapat dilakukan dengan kcmp (3) :
Halaman manual memberikan contoh khusus untuk use case yang diminta OP. Perhatikan bahwa syscall ini mengharuskan kernel dikompilasi dengan
CONFIG_CHECKPOINT_RESTORE
set.sumber
struct file *
pointer.Yang ingin Anda bandingkan adalah
struct file
pointer yang ditunjuk oleh deskriptor file. (Di dalam kernel adalah salah satutask_struct
struktur data untuk setiap thread. Ini berisi pointer ke struktur lain yang disebutfiles_struct
. Dan yang struktur berisi sebuah array dari pointer, masing-masing untukstruct file
. Inistruct file
yang memegang mencari offset, bendera terbuka, dan beberapa bidang lainnya.)Saya tidak tahu cara yang terlihat oleh pengguna untuk melihat petunjuk di
files_struct
lain selain penggunaan beberapa alat yang mengganggu. Sebagai contoh, SystemTap dapat diberi PID dan itu bisa menemukan yang sesuaitask_struct
dan mengikuti petunjuknya. Jika Anda mencari pasif, saya kira itu saja. Dell merilis alat sejak lama yang disebut KME (Kernel Memory Editor) yang memberikan antarmuka seperti spreadsheet untuk menghidupkan memori kernel dan bisa melakukan apa yang Anda inginkan, tetapi tidak pernah porting ke 64-bit. (Saya mencoba dan tidak pernah berhasil sepenuhnya, dan tidak yakin mengapa.)Salah satu alasan Anda merasa tidak
lsof
membantu adalah karena ia tidak melihat petunjuk itu juga (tetapi lihat+f
opsi untuk sistem non-Linux). Secara teoritis Anda dapat membandingkan semua bidang dalamstruct file
dan berpikir kedua struktur itu sama, namun keduanya masih dapat berasal dariopen(2)
panggilan terpisah .Lihatlah skrip SystemTap pfiles untuk ide-ide. Jika Anda memodifikasinya untuk mencetak alamat
struct file
, Anda akan mendapatkan solusinya. Anda mungkin juga memeriksa opens_file_by_pid.stp karena ada fungsi di dalamnya yang berjalanfiles_struct
yaitu,. tabel deskriptor file, melihatstruct file
objek ...Bisakah saya bertanya apa yang ingin Anda capai?
sumber
probe begin
blok dan gunakanfor_each_process
makro dalam blok kode C yang tertanam dalam skrip (Anda harus menggunakan mode "guru" SystemTap untuk menanamkan kode C). Bahkan, untuk membuat ini menarik (!), Anda bisa menggunakan salah satu array asosiatif SystemTap; gunakanfiles_struct
alamat sebagai kunci, dan daftar PID / TIDs sebagai nilai. Anda sekarang memiliki daftar setiap file yang dibuka dan tugas mana yang dibagikan (mereka dapat dibagi antara orang tua / anak). Balas lagi jika Anda ingin mendiskusikan SystemTap.Berikut ini adalah solusi spesifik linux: / proc / self / fd adalah direktori tautan simbolik untuk pegangan file terbuka dalam proses saat ini. Anda bisa membandingkan nilai tautan. Semakin rumit ketika menggunakan proses anak, karena anak akan memiliki yang berbeda / proc / self karena itu adalah link simbolik ketergantungan pid. Anda dapat mengatasi masalah ini dengan menggunakan / proc / $$ / fd di mana $$ adalah pid yang diinginkan.
sumber