GNU/Linux >> Belajar Linux >  >> Linux

Apa yang terjadi jika file yang 100% dimasukkan ke dalam cache halaman diubah oleh proses lain

Rilis berkelanjutan kemudian menggantikan /apps/EXE dengan executable baru.

Ini adalah bagian yang penting.

Cara rilis file baru adalah dengan membuat file baru (misalnya /apps/EXE.tmp.20190907080000 ), menulis konten, menyetel izin dan kepemilikan, dan terakhir rename(2) dengan nama akhir /apps/EXE , menggantikan file lama.

Hasilnya adalah file baru memiliki nomor inode baru (yang berarti, pada dasarnya, ini adalah file yang berbeda.)

Dan file lama memiliki nomor inode sendiri, yang sebenarnya masih ada meskipun nama file tidak menunjuk ke sana lagi (atau tidak ada lagi nama file yang menunjuk ke inode itu.)

Jadi, kuncinya di sini adalah ketika kita berbicara tentang "file" di Linux, kita paling sering benar-benar berbicara tentang "inodes" karena setelah file dibuka, inode adalah referensi yang kita simpan ke file tersebut.

Asumsi 1 :Saya berasumsi bahwa proses P (dan siapa pun dengan deskriptor file yang merujuk pada executable lama) akan terus menggunakan yang lama, di memori /apps/EXE tanpa masalah, dan setiap proses baru yang mencoba menjalankan jalur itu akan mendapatkan yang baru dapat dieksekusi.

Benar.

Asumsi 2 :Saya berasumsi bahwa jika tidak semua halaman file dipetakan ke dalam memori, semuanya akan baik-baik saja sampai ada kesalahan halaman yang memerlukan halaman dari file yang telah diganti, dan mungkin akan terjadi segfault?

Salah. Inode lama masih ada, jadi kesalahan halaman dari proses yang menggunakan biner lama masih dapat menemukan halaman tersebut di disk.

Anda dapat melihat beberapa efek dari ini dengan melihat /proc/${pid}/exe symlink (atau, ekuivalennya, lsof output) untuk proses yang menjalankan biner lama, yang akan menampilkan /app/EXE (deleted) untuk menunjukkan nama sudah tidak ada tapi inode masih ada.

Anda juga dapat melihat bahwa ruang disk yang digunakan oleh biner hanya akan dirilis setelah proses mati (dengan asumsi itu satu-satunya proses dengan inode yang terbuka.) Periksa output dari df sebelum dan sesudah menghentikan proses, Anda akan melihatnya turun sebesar biner lama yang menurut Anda sudah tidak ada lagi.

BTW, ini tidak hanya dengan binari, tetapi dengan file yang terbuka. Jika Anda membuka file dalam suatu proses dan menghapus file tersebut, file tersebut akan disimpan di disk sampai proses tersebut menutup file (atau mati). Demikian pula dengan cara hardlink menyimpan penghitung berapa banyak nama yang menunjuk ke inode di disk, driver sistem file (di kernel Linux) menyimpan penghitung berapa banyak referensi yang ada untuk inode tersebut di memori , dan hanya akan merilis inode dari disk setelah semua referensi dari sistem yang sedang berjalan juga dirilis.

Pertanyaan 1 :Jika Anda mengunci semua halaman file dengan sesuatu seperti vmtouch apakah itu mengubah skenario

Pertanyaan ini didasarkan pada asumsi 2 yang salah bahwa tidak mengunci halaman akan menyebabkan segfault. Tidak akan.

Pertanyaan 2 :Jika /apps/EXE menggunakan NFS jarak jauh, apakah itu akan membuat perbedaan? (Saya kira tidak)

Itu berarti untuk bekerja dengan cara yang sama dan sering kali berhasil, tetapi ada beberapa "gotcha" dengan NFS.

Terkadang Anda dapat melihat artefak penghapusan file yang masih terbuka di NFS (ditampilkan sebagai file tersembunyi di direktori tersebut.)

Anda juga memiliki beberapa cara untuk menetapkan nomor perangkat ke ekspor NFS, untuk memastikan nomor tersebut tidak akan "diubah ulang" saat server NFS dimulai ulang.

Tapi ide utamanya sama. Driver klien NFS masih menggunakan inode dan akan mencoba menyimpan file (di server) sementara inode masih direferensikan.


Asumsi 2:Saya berasumsi bahwa jika tidak semua halaman file dipetakan ke dalam memori, semuanya akan baik-baik saja sampai ada kesalahan halaman yang memerlukan halaman dari file yang telah diganti, dan mungkin akan terjadi segfault?

Tidak, itu tidak akan terjadi, karena kernel tidak akan membiarkan Anda membuka untuk menulis dan mengganti apapun di dalam file yang sedang dieksekusi. Tindakan seperti itu akan gagal dengan ETXTBSY [1] :

cp /bin/sleep sleep; ./sleep 3600 & echo none > ./sleep
[9] 5332
bash: ./sleep: Text file busy

Saat dpkg, dll memperbarui biner, itu tidak menimpanya, tetapi menggunakan rename(2) yang hanya mengarahkan entri direktori ke file yang sama sekali berbeda, dan setiap proses yang masih memiliki pemetaan atau pegangan terbuka ke file lama akan terus menggunakannya tanpa masalah.

[1][strong> ETXBUSY perlindungan tidak diperluas ke file lain yang juga dapat dianggap sebagai "teks" (=kode langsung / dapat dieksekusi):pustaka bersama, kelas java, dll; memodifikasi file seperti itu saat dipetakan oleh proses lain akan menyebabkan proses crash. Di linux, linker dinamis dengan patuh meneruskan MAP_DENYWRITE tandai ke mmap(2) , tapi jangan salah -- tidak berpengaruh apa-apa. Contoh:

$ cc -xc - <<<'void lib(){}' -shared -o lib.so
$ cc -Wl,-rpath=. lib.so -include unistd.h -xc - <<<'
   extern void lib();
   int main(){ truncate("lib.so", 0); lib(); }
'
./a.out
Bus error

jawaban filbranden benar dengan asumsi proses rilis berkelanjutan melakukan penggantian file atom yang tepat melalui rename . Jika tidak, tetapi memodifikasi file di tempat, semuanya berbeda. Namun model mental Anda masih salah.

Tidak ada kemungkinan hal-hal diubah pada disk dan menjadi tidak konsisten dengan cache halaman, karena cache halaman adalah versi kanonis dan yang dimodifikasi. Setiap penulisan ke file dilakukan melalui cache halaman. Jika sudah ada di sana, halaman yang ada diubah. Jika belum ada, upaya untuk mengubah sebagian halaman akan menyebabkan seluruh halaman di-cache, diikuti dengan modifikasi seolah-olah sudah di-cache. Menulis yang menjangkau seluruh halaman atau lebih dapat (dan hampir pasti melakukannya) mengoptimalkan langkah baca paging mereka. Bagaimanapun, hanya ada satu versi kanonis yang dapat dimodifikasi dari file yang pernah (*) ada, yang ada di cache halaman .

(*) Saya sedikit berbohong. Untuk NFS dan sistem file jarak jauh lainnya, mungkin ada lebih dari satu, dan mereka biasanya (tergantung pada yang mana dan opsi mount dan sisi server apa yang digunakan) tidak mengimplementasikan atomisitas dan memesan semantik dengan benar untuk penulisan. Itu sebabnya banyak dari kita menganggapnya rusak secara mendasar dan menolak menggunakannya untuk situasi di mana akan ada penulisan bersamaan dengan penggunaan.


Linux
  1. Apa nomor inode di Linux?

  2. Apa itu anon_inode dalam keluaran ls -l /proc/[PID]/fd?

  3. Apa unit waktu yang digunakan strace saat menampilkan waktu yang dihabiskan di syscalls?

  1. Alat Untuk Mendapatkan Garis Dalam Satu File Yang Tidak Di File Lain?

  2. Proses Induk Baru Ketika Proses Induk Meninggal?

  3. Apa Yang Terjadi Dengan Keluaran Dari Proses Yang Telah Diabaikan Dan Kehilangan Terminalnya?

  1. Linux – Apa Yang Terjadi Saat Anda Rsync Tanpa Jalur Tujuan??

  2. Apa Yang Terjadi Jika Batas Bandwidth Dilampaui?

  3. Bagaimana cara memulihkan semaphore ketika proses yang menurunkannya menjadi nol macet?