Di sini dikatakan bahwa Anda dapat menulis ulang file yang dapat dieksekusi dan prosesnya akan berjalan dengan baik - ini akan dibaca kembali ketika suatu proses dimulai ulang.
Namun, ketika saya mencoba untuk mengganti file biner saat proses sedang berjalan (dengan scp, dari dev ke server uji) ia mengatakan 'file busy'. Dan jika saya mengganti file perpustakaan bersama (* .so), semua proses yang menghubungkannya macet.
Kenapa begitu? Apakah saya melewatkan sesuatu? Bagaimana saya bisa mengganti file biner tanpa menghentikan proses?
.so
file menggunakanldd filename.so
untuk memeriksa dependensistop app && create symlink of .so && start app
Jawaban:
Seperti disebutkan dalam Mengapa paket perangkat lunak berjalan dengan baik bahkan ketika sedang ditingkatkan? , kunci ditempatkan pada inode bukan pada nama file. Ketika Anda memuat dan menjalankan biner, file ditandai sebagai sibuk - itulah sebabnya Anda mendapatkan kesalahan ETXTBSY (file sibuk) ketika Anda mencoba menulisnya.
Sekarang, untuk pustaka bersama sedikit berbeda: pustaka mendapatkan memori yang dipetakan ke dalam ruang alamat proses
mmap()
. MeskipunMAP_DENYWRITE
dapat ditentukan, setidaknya Glibc di Linux diam-diam mengabaikannya (menurut halaman manual, jangan ragu untuk memeriksa sumbernya) - periksa utas ini . Oleh karena itu Anda benar-benar diperbolehkan untuk menulis file dan, karena memori dipetakan, perubahan terlihat segera - yang berarti bahwa jika Anda mencoba cukup keras Anda dapat mengatur untuk batu bata mesin Anda dengan Timpa perpustakaan.Karena itu cara yang benar untuk memperbarui adalah:
menghapus file, yang menghilangkan referensi ke data dari sistem file, sehingga tidak dapat diakses untuk aplikasi yang baru lahir yang mungkin ingin menggunakannya, sambil menjaga data dapat diakses oleh siapa saja yang sudah membuka (atau memetakan) ;
membuat file baru dengan konten yang diperbarui.
Proses yang baru dibuat akan menggunakan konten yang diperbarui, aplikasi yang berjalan akan mengakses versi lama. Inilah yang dilakukan utilitas manajemen paket yang waras. Perhatikan bahwa ini tidak sepenuhnya tanpa bahaya - misalnya aplikasi yang memuat kode secara dinamis (menggunakan
dlsym()
dan teman-teman) akan mengalami masalah jika API perpustakaan berubah secara diam-diam.Jika Anda ingin berada di sisi yang benar- benar aman, matikan sistem, pasang sistem file dari instance sistem operasi lain, perbarui dan tampilkan kembali sistem yang diperbarui.
sumber
Pemutakhiran rpm melakukan hal yang sama - dengan menjalankan binari dan pustaka sementara tidak ada yang macet.
Jadi apa bedanya:
Ini TIDAK akan mengganti file inplace: Inode yang merujuk ke biner yang digunakan masih "sibuk" sampai objek terakhir yang menahannya terbuka selesai. File baru akan dibuat dengan nomor inode baru.
Sekarang
scp
ataucp
akan mencoba mengganti file inplace - yang akan mengubah konten yang dimaksud inode. Ini tidak berfungsi - seperti yang Anda gambarkan.sumber