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?


29

Giả sử tôi đang chạy một phần mềm và sau đó tôi chạy trình quản lý gói để nâng cấp phần mềm, tôi nhận thấy rằng Linux không làm giảm quá trình chạy để nâng cấp gói - nó vẫn chạy tốt. Linux làm điều này như thế nào?

Câu trả lời:


35

Lý do là Unix không khóa tệp thực thi trong khi nó được thực thi hoặc ngay cả khi nó giống như Linux, khóa này áp dụng cho inode, không phải tên tệp. Điều đó có nghĩa là một quá trình giữ cho nó mở đang truy cập cùng một dữ liệu (cũ) ngay cả sau khi tệp đã bị xóa (thực sự không được liên kết) và được thay thế bằng một cái mới có cùng tên mà về cơ bản là cập nhật gói.

Đó là một trong những khác biệt chính giữa Unix và Windows. Cái sau không thể cập nhật một tệp đang bị khóa vì nó thiếu một lớp giữa tên tệp và inodes gây rắc rối lớn để cập nhật hoặc thậm chí cài đặt một số gói vì nó thường yêu cầu khởi động lại đầy đủ.


10
Để làm rõ, trong Linux, bạn không thể sửa đổi tệp thực thi trong khi nó đang chạy. Nhưng bạn có thể hủy liên kết tệp và thay thế nó bằng một tệp mới cùng tên.
cjm

Trong Linux, bạn có thể sửa đổi một tệp thực thi trong khi nó đang chạy. Kết quả có thể sẽ không thể đoán trước mặc dù trừ khi bạn thực sự biết những gì bạn đang làm. Đã thêm điểm "cùng tên" không được nêu rõ ràng.
jlliagre

4
@jlliagre Trừ khi tôi hiểu lầm, bạn không thể hiểu được: spunge.us/egiR
Chris Down

2
Mặc dù vậy, có một điều thú vị về NFTS - nếu bạn thực hiện đổi tên từ dòng lệnh hoặc chương trình khác, thì bạn có thể đặt một tệp cùng tên ở đó và nó sẽ không ảnh hưởng đến các chương trình mở tệp gốc. (lệnh đổi tên trong explorer không hoạt động cho việc này)
Steffan Donal

1
@cjm Bạn đã đúng về bảo vệ "tệp văn bản bận" trong Linux, hãy trả lời cập nhật. Không có hạn chế nào như vậy dưới Solaris mà với tôi quen thuộc hơn. Bạn vẫn có thể sửa đổi các thư viện chia sẻ với cả hai hệ điều hành.
jlliagre

18

Các tệp thực thi thường được mở một lần, được đính kèm với một bộ mô tả tệp và không có một bộ mô tả tệp để nhị phân của chúng được mở lại trong một khoảng thời gian thực hiện. Ví dụ: nếu bạn thực thi bash, exec()thường chỉ tạo một bộ mô tả tệp cho nút được trỏ đến /bin/bashmột lần - khi gọi.

Điều này thường có nghĩa là đối với các nhị phân đơn giản không cố đọc lại chính chúng trong khi thực thi (bằng cách sử dụng đường dẫn mà chúng được gọi), nội dung được lưu trong bộ nhớ cache vẫn có hiệu lực như một nút inode. Điều này có nghĩa là về cơ bản có một bản sao của phiên bản thực thi trước đó.

Trong trường hợp phức tạp hơn, điều này có thể gây ra vấn đề. Ví dụ, một tệp cấu hình có thể được nâng cấp và sau đó đọc lại hoặc chương trình có thể tự thực hiện lại thông qua đường dẫn mà nó được thực thi. Cũng có thể có vấn đề nếu các chương trình được kết nối với nhau và một chương trình được thực thi trước khi nâng cấp và một sau đó (có thể bởi chương trình đầu tiên). Điều này cũng đúng với một số thư viện.

Tuy nhiên, đối với các trường hợp sử dụng đơn giản, việc nâng cấp mà không cần khởi động lại quá trình là an toàn.


1
Một mối nguy hiểm khác, ngay cả trong những trường hợp đơn giản, là bởi vì ứng dụng đang chạy đang sử dụng bản sao nhị phân được lưu trong bộ nhớ cache, cho đến khi bạn tự khởi động lại ứng dụng, nó vẫn chạy phiên bản mã cũ. Trong khi điều này không quan trọng hầu hết thời gian; nếu bản nâng cấp bao gồm các bản sửa lỗi bảo mật, mặc dù bản vá được cài đặt, hệ thống của bạn vẫn dễ bị tổn thương vì phiên bản cũ vẫn đang chạy.
Dan Neely

1
Tôi sợ đoạn đầu tiên của bạn không chính xác. Các hạt nhân Unix / Linux không tải các chương trình thực thi cùng một lúc mà bộ nhớ ánh xạ chúng. Điều đó có nghĩa là chỉ có các trang thực sự được sử dụng cuối cùng làm cho nó vào RAM. Đây là toàn bộ quan điểm của bảo vệ "Tệp văn bản bận" trong Linux. Không có gì đảm bảo một phần của một tệp thực thi sẽ không được đọc lâu sau khi nó được đưa ra. Hơn nữa, một số trang sẽ không bao giờ được tải cho các chương trình đủ lớn và điều này thậm chí còn đúng hơn đối với các thư viện được tải động. Ví dụ, bashnhị phân là khoảng 200 trang 4K, không chắc chắn tất cả chúng đều được sử dụng trong một phiên trung bình.
jlliagre

@jlliagre Tôi đã nói về ialloc()ing với cấu trúc kernel khi đọc, không phải là ánh xạ bộ nhớ của chính các trang. Tôi có đúng không khi nghĩ rằng trên các hệ thống tập tin ext * hiện đại, inode cuối cùng là in-kernel nhất quán (và bên trong hệ thống con VM)?
Chris Down

Không có phần đảm bảo nào của nội dung thực thi sẽ không được đọc trong một thời gian dài sau khi được chạy và không có gì đảm bảo rằng các trang tương tự sẽ không được đọc lại sau một thời gian trong thời gian thực hiện.
jlliagre

@jlliagre Đúng, nhưng đó không phải là ý tôi. Có lẽ tôi đã băm vằm lời nói của mình một chút trong câu trả lời của mình, tôi sẽ cố gắng làm cho những gì tôi muốn nói rõ ràng hơn.
Chris Xuống
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.