Bagaimana cara meningkatkan perpustakaan bersama tanpa kerusakan?

18

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?

Sam
sumber
Anda dapat memeriksa .sofile menggunakan ldd filename.sountuk memeriksa dependensi
Rahul Patil
Saya tahu ketergantungannya. Saya ingin cara mengganti file-file itu tanpa mempengaruhi proses yang sedang berjalan. Seperti yang disiratkan oleh pertanyaan terkait
Sam
diperlukan downtime .. atau Anda dapat melakukan seperti stop app && create symlink of .so && start app
Rahul Patil

Jawaban:

21

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(). Meskipun MAP_DENYWRITEdapat 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:

  1. 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) ;

  2. 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.

peterph
sumber
6

Pemutakhiran rpm melakukan hal yang sama - dengan menjalankan binari dan pustaka sementara tidak ada yang macet.

Jadi apa bedanya:

  1. batalkan tautan file
  2. tulis file baru dengan nama yang sama

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 scpatau cpakan mencoba mengganti file inplace - yang akan mengubah konten yang dimaksud inode. Ini tidak berfungsi - seperti yang Anda gambarkan.

Nils
sumber