Saya tahu bahwa ketika halaman cache halaman diubah, itu ditandai kotor dan memerlukan penulisan kembali, tetapi apa yang terjadi ketika:
Skenario: File / apps / EXE, yang merupakan file yang dapat dieksekusi, di-paging ke halaman cache sepenuhnya (semua halamannya ada di cache / memori) dan dijalankan oleh proses P
Rilis berkelanjutan kemudian menggantikan / apps / EXE dengan executable baru.
Asumsi 1: Saya berasumsi bahwa proses P (dan siapa pun dengan deskriptor file yang mereferensikan yang dapat dieksekusi) akan terus menggunakan yang lama, di memori / apps / EXE tanpa masalah, dan setiap proses baru yang mencoba mengeksekusi jalur itu akan mendapatkan executable baru.
Asumsi 2: Saya berasumsi bahwa jika tidak semua halaman file dipetakan ke dalam memori, semuanya akan baik-baik saja sampai ada kesalahan halaman yang membutuhkan halaman dari file yang telah diganti, dan mungkin akan terjadi segfault?
Pertanyaan 1: Jika Anda meng-mlock semua halaman file dengan sesuatu seperti vmtouch apakah itu mengubah skenario sama sekali?
Pertanyaan 2: Jika / apps / EXE berada pada NFS jarak jauh, apakah itu akan membuat perbedaan? (Saya kira tidak)
Harap perbaiki atau validasikan 2 asumsi saya dan jawab 2 pertanyaan saya.
Mari kita asumsikan ini adalah kotak CentOS 7.6 dengan semacam kernel 3.10.0-957.el7
Pembaruan: Memikirkan lebih jauh, saya ingin tahu apakah skenario ini tidak berbeda dengan skenario halaman kotor lainnya ..
Saya kira proses yang menulis biner baru akan membaca dan mendapatkan semua halaman cache karena semuanya dipetakan, dan kemudian semua halaman itu akan ditandai kotor. Jika mereka di-mlock, mereka hanya akan menjadi halaman tidak berguna yang menempati memori inti setelah hitungan ref menjadi nol.
Saya curiga ketika program yang saat ini dijalankan berakhir, apa pun akan menggunakan biner baru. Dengan asumsi itu semua benar, saya kira itu hanya menarik ketika hanya beberapa file yang di-paging.
sumber
Jawaban:
Ini bagian yang penting.
Cara file baru dirilis adalah dengan membuat file baru (misalnya
/apps/EXE.tmp.20190907080000
), menulis konten, mengatur izin dan kepemilikan dan akhirnya mengubah nama (2) menjadi nama akhir/apps/EXE
, menggantikan file lama.Hasilnya adalah bahwa file baru memiliki nomor inode baru (yang berarti, pada dasarnya, ini 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 nama file yang menunjuk ke inode itu lagi.)
Jadi, kuncinya di sini adalah ketika kita berbicara tentang "file" di Linux, kita paling sering benar-benar berbicara tentang "inode" karena begitu file telah dibuka, inode adalah referensi yang kita simpan ke file tersebut.
Benar.
Salah. Inode lama masih ada, jadi kesalahan halaman dari proses menggunakan biner lama masih akan dapat menemukan halaman-halaman itu di disk.
Anda dapat melihat beberapa efek dari ini dengan melihat
/proc/${pid}/exe
symlink (atau, ekuivalen,lsof
output) untuk proses yang menjalankan biner lama, yang akan menunjukkan/app/EXE (deleted)
untuk menunjukkan nama tidak lagi ada tetapi inode masih ada.Anda juga dapat melihat bahwa ruang disk yang digunakan oleh biner hanya akan dirilis setelah proses mati (dengan asumsi itu adalah satu-satunya proses dengan inode yang terbuka.) Periksa output
df
sebelum dan setelah membunuh proses, Anda akan melihatnya turun sesuai ukuran biner tua yang Anda pikir tidak ada lagi.BTW, ini tidak hanya dengan binari, tetapi dengan file yang terbuka. Jika Anda membuka file dalam suatu proses dan menghapus file, file tersebut akan disimpan pada disk hingga proses itu menutup file (atau mati.) Demikian pula dengan bagaimana hardlink menyimpan penghitung berapa banyak nama yang menunjuk ke inode dalam disk, driver filesystem (di kernel Linux) menyimpan konter dari berapa banyak referensi yang ada pada inode dalam memori , dan hanya akan melepaskan inode dari disk setelah semua referensi dari sistem yang berjalan telah dirilis juga.
Pertanyaan ini didasarkan pada asumsi 2 yang salah bahwa tidak mengunci halaman akan menyebabkan segfault. Tidak akan.
Ini dimaksudkan untuk bekerja dengan cara yang sama dan sebagian besar tidak, tetapi ada beberapa "gotcha" dengan NFS.
Kadang-kadang Anda dapat melihat artefak menghapus file yang masih terbuka di NFS (muncul sebagai file tersembunyi di direktori itu.)
Anda juga memiliki beberapa cara untuk menetapkan nomor perangkat ke ekspor NFS, untuk memastikan mereka tidak akan "diacak ulang" ketika server NFS reboot.
Tapi ide utamanya sama. Driver klien NFS masih menggunakan inode dan akan mencoba untuk menyimpan file (di server) saat inode masih dirujuk.
sumber
rename
cukup banyak satu-satunya file dan filesystem operasi yang dijamin akan atom (dengan asumsi kita tidak lintas filesystem atau perangkat batas), jadi "membuat file temp dan kemudianrename
" adalah yang pola standar untuk memperbarui file. Itu juga yang digunakan oleh setiap editor teks di Unix, misalnya.rename
adalah bagian dari POSIX. Memang, ini dimasukkan dengan mengacu pada ISO C (bagian 7.21.4.2 dalam konsep saat ini), tetapi ada di sana.Tidak, itu tidak akan terjadi, karena kernel tidak akan membiarkan Anda membuka untuk menulis ganti apa pun di dalam file yang sedang dijalankan. Tindakan seperti itu akan gagal dengan
ETXTBSY
[1]:Ketika dpkg, dll memperbarui biner, ia 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] perlindungan tersebut tidak diperluas ke file lain yang juga dapat dianggap "teks" (kode langsung / dapat dieksekusi): shared library, kelas java, dll; memodifikasi file seperti itu sementara dipetakan oleh proses lain akan menyebabkannya macet. Di linux, dynamic linker dengan patuh meneruskan
MAP_DENYWRITE
flagmmap(2)
, tetapi jangan salah - tidak ada efek apa pun.sumber
rename(2)
adalah atom; segera setelah selesai, entri dir merujuk ke file baru. Proses yang masih menggunakan file lama pada saat itu hanya akan dapat mengaksesnya melalui pemetaan yang ada, atau melalui pegangan terbuka untuk itu (yang mungkin merujuk ke sebuah yatim piatu gigi, tidak lagi dapat diakses selain melalui/proc/PID/fd
).jawaban filbranden benar dengan asumsi proses rilis kontinu melakukan penggantian atom file yang tepat via
rename
. Jika tidak, tetapi memodifikasi file di tempat, semuanya berbeda. Namun model mental Anda masih salah.Tidak ada kemungkinan hal-hal yang dimodifikasi pada disk dan tidak konsisten dengan cache halaman, karena cache halaman adalah versi kanonik 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 memodifikasi sebagian halaman akan menyebabkan seluruh halaman di-cache, diikuti oleh modifikasi seolah-olah itu sudah di-cache. Menulis bahwa span seluruh halaman atau lebih dapat (dan hampir pasti melakukan) mengoptimalkan langkah baca paging mereka. Dalam hal apapun, hanya ada satu versi yang dapat dimodifikasi kanonik 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 biasanya (tergantung yang mana dan opsi mount dan sisi-server mana yang digunakan) tidak menerapkan atomicity dan memesan semantik untuk penulisan dengan benar. Itu sebabnya banyak dari kita menganggap mereka rusak secara fundamental dan menolak menggunakannya untuk situasi di mana akan ada tulisan bersamaan dengan penggunaan.
sumber