Làm thế nào để nâng cấp thư viện chia sẻ mà không gặp sự cố?


18

Ở đây nó nói rằng bạn có thể viết lại một tập tin thực thi và quá trình sẽ chạy tốt - nó sẽ được đọc lại khi một quá trình khởi động lại.

Tuy nhiên, khi tôi cố gắng thay thế một tệp nhị phân trong khi quá trình đang chạy (với scp, từ dev đến máy chủ thử nghiệm) thì nó báo 'tệp bận'. Và nếu tôi thay thế một tệp thư viện dùng chung (* .so), tất cả các quy trình liên kết nó bị sập.

Tại sao như vậy? Tui bỏ lỡ điều gì vậy? Làm thế nào tôi có thể thay thế các tệp nhị phân mà không dừng / sập một quy trình?


Bạn có thể kiểm tra .sotệp bằng cách sử dụng ldd filename.sođể kiểm tra các phụ thuộc
Rahul Patil

Tôi biết sự phụ thuộc. Tôi muốn một cách để thay thế các tệp đó mà không ảnh hưởng đến các quy trình đang chạy. Như câu hỏi được liên kết ngụ ý
Sam

thời gian chết là bắt buộc .. hoặc bạn có thể làm như thế stop app && create symlink of .so && start app
Rahul Patil

Câu trả lời:


21

Như đã đề cập trong Tại sao một gói phần mềm chỉ chạy tốt ngay cả khi nó đang được nâng cấp? , khóa được đặt trên inode không phải trên tên tệp. Khi bạn tải và thực thi nhị phân, tệp được đánh dấu là bận - đó là lý do tại sao bạn gặp lỗi ETXTBSY (tệp bận) khi bạn cố gắng ghi vào tệp.

Bây giờ, đối với các thư viện dùng chung, nó hơi khác một chút: các thư viện được ánh xạ bộ nhớ vào không gian địa chỉ của tiến trình mmap(). Mặc dù MAP_DENYWRITEcó thể được chỉ định, ít nhất Glibc trên Linux âm thầm bỏ qua nó (theo trang man, vui lòng kiểm tra các nguồn) - kiểm tra chủ đề này . Do đó, bạn thực sự được phép ghi tệp và, vì nó được ánh xạ bộ nhớ, mọi thay đổi sẽ hiển thị gần như ngay lập tức - điều đó có nghĩa là nếu bạn cố gắng hết sức, bạn có thể quản lý để gạch máy của mình bằng cách ghi đè lên thư viện.

Do đó, cách chính xác để cập nhật là:

  1. xóa tệp, loại bỏ tham chiếu đến dữ liệu khỏi hệ thống tệp, do đó không thể truy cập được đối với bất kỳ ứng dụng mới sinh nào có thể muốn sử dụng, trong khi vẫn giữ dữ liệu có thể truy cập được cho bất kỳ ai đã mở (hoặc ánh xạ) ;

  2. tạo một tập tin mới với nội dung được cập nhật.

Các quy trình mới được tạo sẽ sử dụng các nội dung được cập nhật, các ứng dụng đang chạy sẽ truy cập phiên bản cũ. Đây là những gì bất kỳ tiện ích quản lý gói sane làm. Lưu ý rằng nó không hoàn toàn không có bất kỳ nguy hiểm nào - ví dụ: các ứng dụng tải mã động (sử dụng dlsym()và bạn bè) sẽ gặp rắc rối nếu API của thư viện thay đổi âm thầm.

Nếu bạn muốn ở bên thực sự, thực sự an toàn, hãy tắt hệ thống, gắn hệ thống tệp từ một phiên bản hệ điều hành khác, cập nhật và đưa hệ thống cập nhật lại.


6

Nâng cấp vòng / phút thực hiện tương tự - với các nhị phân và thư viện đang chạy trong khi không có gì gặp sự cố.

Vì vậy, sự khác biệt là gì:

  1. hủy liên kết tập tin
  2. viết tập tin mới có cùng tên

Điều này sẽ KHÔNG thay thế tệp tại chỗ: Inode đề cập đến nhị phân đang sử dụng vẫn "bận" cho đến khi đối tượng cuối cùng giữ nó mở kết thúc. Các tập tin mới sẽ được tạo ra với một số inode mới.

Bây giờ scphoặc cpsẽ cố gắng thay thế tệp tại chỗ - sẽ thay đổi nội dung mà inode đang đề cập đến. Điều này không hoạt động - như bạn mô tả.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.