Tại sao cập nhật hệ thống Linux đang chạy không có vấn đề?


25

Đã nhiều năm tôi sử dụng các hệ thống Linux hàng ngày và tôi chưa bao giờ gặp vấn đề lớn khi cập nhật một hệ thống khi nó đang chạy, nhưng tôi vẫn tự hỏi tại sao điều này lại có khả năng.

Hãy để tôi làm một ví dụ.

Giả sử một chương trình "A" từ một gói nhất định đang chạy trên một hệ thống. Chương trình này, tại một thời điểm nhất định, cần mở một tệp khác ("B") từ cùng một gói. Sau đó, chương trình "A" sẽ đóng "B" vì không cần nó nữa. Giả sử bây giờ tôi cập nhật gói "A" và "B" thuộc về. "A" không bị ảnh hưởng trực tiếp bởi các thao tác này, ít nhất là tại thời điểm này, vì nó đang chạy trong RAM và bản cập nhật chỉ thay thế "A" trên đĩa cứng. Giả sử "B" cũng đã được thay thế trên hệ thống tập tin. Bây giờ "A" cần đọc lại "B" vì một số lý do. Câu hỏi đặt ra là: "A" có thể tìm thấy phiên bản "B" không tương thích và sự cố hoặc trục trặc theo một cách khác không?

Tại sao không ai cập nhật hệ thống của họ bằng cách khởi động lại bằng đĩa CD trực tiếp hoặc một số quy trình tương tự?


Tôi có xu hướng thích tránh các cập nhật như vậy, không phải vì cơ chế cập nhật (điều này có thể được thực hiện tốt), mà là vì ưu tiên kiểm tra các ứng dụng và cấu hình của tôi trước các thay đổi. Sau đó, tôi sẽ có một hệ thống cập nhật riêng để chuyển sang. Nhưng bên cạnh đó, việc cập nhật trong vùng người dùng thường không phải là vấn đề và đối với các bản sửa lỗi nhỏ hoặc bảo mật, tôi chỉ cần làm điều đó.
Skaperen

Câu trả lời:


23

Cập nhật Userland hiếm khi là một vấn đề

Bạn thường có thể cập nhật các gói trên hệ thống trực tiếp vì:

  1. Các thư viện dùng chung được lưu trữ trong bộ nhớ, không đọc từ đĩa trên mỗi cuộc gọi, vì vậy các phiên bản cũ sẽ vẫn được sử dụng cho đến khi ứng dụng được khởi động lại.
  2. Các tệp đang mở thực sự được đọc từ các bộ mô tả tệp , không phải tên tệp, vì vậy nội dung tệp vẫn có sẵn cho các ứng dụng đang chạy ngay cả khi di chuyển / đổi tên / xóa cho đến khi các cung bị ghi đè hoặc mô tả tệp bị đóng.
  3. Các gói yêu cầu tải lại hoặc khởi động lại thường được xử lý đúng bởi người quản lý gói nếu gói được thiết kế tốt. Ví dụ, Debian sẽ khởi động lại một số dịch vụ bất cứ khi nào libc6 được nâng cấp.

Nói chung, trừ khi bạn đang cập nhật kernel và không sử dụng ksplice, thì các chương trình hoặc dịch vụ có thể cần được khởi động lại để tận dụng lợi thế của bản cập nhật. Tuy nhiên, hiếm khi cần phải khởi động lại hệ thống để cập nhật mọi thứ trong vùng người dùng, mặc dù trên máy tính để bàn đôi khi dễ dàng hơn so với khởi động lại các dịch vụ riêng lẻ.

Xem thêm

http://en.wikipedia.org/wiki/Ring_%28computer_security%29#Supervisor_mode


Nhưng điều gì sẽ xảy ra, nếu bạn cần tất cả bộ nhớ cache? Trong trường hợp đó, các thư viện chia sẻ sẽ phải được tải lại từ đĩa ...
Nils

3
Trên thực tế, mô tả của # 1 không quá rõ ràng. Nội dung tệp thư viện cũ vẫn nằm trong một nút riêng (gốc), ngay cả khi tất cả các tên liên kết đến nó đã bị mất, miễn là một số quy trình đã mở tệp hoặc nội dung của nó được ánh xạ, dữ liệu được giữ riêng biệt (và hệ thống tệp không thể được tính lại r / o cho đến khi việc hủy liên kết của tệp hoàn tất). Quá trình ánh xạ tệp gốc vẫn có ánh xạ bộ nhớ đến nội dung gốc.
Skaperen

@Nils Tôi không phải là chuyên gia, nhưng nếu bạn hết bộ nhớ cache, nó sẽ không được viết để trao đổi và đọc lại từ đó chứ? Nếu nó đã đầy thì một số tiến trình có thể sẽ bị chặn trước khi nó có thể lấy bộ nhớ ra khỏi một tiến trình khác đang sử dụng nó.
Joe

@Joe không - trao đổi là ram, quá. Skaperen mô tả những gì xảy ra: xử lý tệp đang được giữ nguyên. Vì vậy, về cơ bản, chương trình có một thư viện cũ (thư viện cũ), sẽ không bị xóa cho đến khi xử lý đó là miễn phí một lần nữa - tất cả chỉ ở cấp độ hệ thống tệp - không phải ở cấp RAM.
Nils

4

Có, những gì bạn mô tả là có thể, nhưng hầu hết thời gian nếu tệp được bao gồm trong gói, nó sẽ là một thư viện hoặc tệp khác được đọc một lần và chỉ một lần (vì nó không thay đổi, không có lý do gì để đọc nó nhiều lần). Ngoài ra, nếu tệp cần thiết trong thời gian dài, ứng dụng có thể sẽ để xử lý tệp mở, trong đó ngay cả khi nó được thay thế trên hệ thống tệp thực tế, xử lý tệp mở sẽ giữ phiên bản cũ mở.

Trong hầu hết các trường hợp, bất kỳ dữ liệu nào được đọc nhiều lần trong suốt quá trình là dữ liệu người dùng / biến và điều này sẽ không thay đổi trong quá trình nâng cấp gói. Thêm vào đó vì dữ liệu là biến, bất kỳ lập trình viên nào trong suy nghĩ đúng đắn của họ sẽ đảm bảo chương trình có thể xử lý nó thay đổi từ lần đọc này sang lần đọc tiếp theo.


Tệp vẫn có thể được đọc lại thành "kho lưu trữ dự phòng" nếu ánh xạ của tệp không có thay đổi trong bộ nhớ (điều này sẽ thay đổi cửa hàng sao lưu sang trao đổi nếu có) và bản sao trong bộ nhớ bị loại bỏ do áp lực nhu cầu khác sử dụng ký ức. Nhưng điều này không có vấn đề gì vì tệp gốc vẫn đang mở hoặc được ánh xạ. Thư viện thay thế là một tệp mới và khác mà quy trình cũ chưa được mở.
Skaperen

1
@Skaperen Tôi giả sử bạn đang nói về các tệp ánh xạ bộ nhớ. Đây không phải là vấn đề khi nâng cấp gói. Tất cả các trình quản lý gói tạo các tệp mới để thay thế các tệp cũ thay vì ghi đè lên chúng. Trong thực tế, đây là cách duy nhất để làm điều đó vì một tệp thực thi đang chạy không thể được sửa đổi, nó chỉ có thể được hủy liên kết.
Patrick

4

Giả sử "B" cũng đã được thay thế trên hệ thống tập tin. Bây giờ "A" cần đọc lại "B" vì một số lý do. Câu hỏi đặt ra là: "A" có thể tìm thấy phiên bản "B" không tương thích và sự cố hoặc trục trặc theo một cách khác không?

Điều này là có thể, nhưng không thể trong hầu hết các trường hợp. Nếu "B" là một thư viện mã, thì phiên bản gốc thường sẽ không bị đóng. "A" sẽ tiếp tục sử dụng phiên bản gốc của "B". Nếu bạn chạy "A" sau khi cập nhật, phiên bản "B" mới sẽ được sử dụng. Trong quá trình cập nhật, có một số rủi ro rằng các phiên bản không tương thích có thể được tải. Tuy nhiên, do cách các thư viện mã được tải, đây chỉ là vấn đề nếu "A" cần chức năng không có trong các phiên bản "B" mà nó đã tải.

Thực hành mã hóa tốt giữ cho giao diện hoạt động như nhau. Do đó, không có vấn đề gì với phiên bản được tải, ngoại trừ nếu có lỗi được sửa trong phiên bản mới hơn.

Các tập tin cấu hình là một vấn đề hơi khác nhau, nhưng thường được đọc trong khi khởi động. Trong trường hợp này, "A" sẽ không đọc "B" trừ khi tải lại cấu hình được thay đổi. Một lần nữa, nó sẽ là thực hành mã hóa xấu để thay đổi định dạng hoặc ý nghĩa của tệp cấu hình. Một phiên bản không tương thích của tệp cấu hình nên có một tên khác, vì vậy nó sẽ không gây ra vấn đề.

Tại sao không ai cập nhật hệ thống của họ bằng cách khởi động lại bằng đĩa CD trực tiếp hoặc một số quy trình tương tự?

Tắt và khởi động lại từ một phiên bản khác sẽ dẫn đến sự cố ngừng dịch vụ. Đối với máy chủ, điều này thường không mong muốn. Trong mọi trường hợp, trình quản lý gói trên hệ thống đang chạy đều biết phần mềm và phiên bản mà nó đã cài đặt. Các đĩa CD trực tiếp có danh sách các phần mềm được cài đặt riêng, có thể với các phiên bản khác nhau. Điều này gây khó khăn cho việc nâng cấp hệ thống đang chạy từ đĩa CD trực tiếp.

CD trực tiếp đôi khi được sử dụng khi bản phát hành mới của O / S đang được cài đặt. Trong trường hợp này, việc cài đặt sạch O / S thường được thực hiện. Điều này có thể giới hạn số lượng tệp không sử dụng từ phiên bản trước được giữ lại. Nó có thể là nỗ lực nhiều hơn là nâng cấp hệ thống trực tiếp. Tuy nhiên, nếu các phân vùng gốc khác nhau được sử dụng, nó có thể hạn chế nguy cơ bị mắc kẹt với một hệ thống được cập nhật một phần không thể khởi động.


0

Có một số trường hợp đây là một vấn đề:

  • Nâng cấp JDK khi java-VM đang chạy: Tôi đã hỏi myselv câu hỏi tương tự mà bạn nhận được - Tôi có một tomcat đang chạy sử dụng java. Bây giờ sau khi cập nhật bản vá của JDK, nó vẫn chạy mà không gặp vấn đề gì - vì vậy có vẻ như vậy.

Bây giờ giải thích là bộ nhớ cache. OK - Tôi đã bắt đầu một chương trình bộ nhớ để sử dụng hết RAM có sẵn - và sau đó tomcat bị hỏng (sau khi tôi truy cập ứng dụng chạy ở đó).

  • Nâng cấp kernel trên các hệ thống SuSE: Trên SuSE, kernel cũ và các mô-đun của nó bị xóa ngay sau khi nâng cấp bản vá của kernel. Nếu sau đó bạn muốn sử dụng một cái gì đó mới, đòi hỏi một mô-đun hạt nhân, mà không được tải lên cho đến bây giờ, dịch vụ sẽ thất bại.

2
Âm thanh như một số phần của Tomcat đã được khởi động lại hoặc các thư viện động được sử dụng dưới mức Java (ví dụ: dlopen () và như vậy) có thể kết thúc bằng hỗn hợp API trực tiếp.
Skaperen

@Skaperen ngay cả khi sử dụng các thư viện dùng chung - nếu chúng bị đóng sau khi sử dụng, bất kỳ chương trình nào cũng gặp sự cố nếu bộ nhớ cache ngày càng thưa thớt ...
Nils

1
Một bộ mô tả tệp mở có cùng khả năng giữ lại dữ liệu trên đĩa làm tên cho tệp trong một thư mục. Inode gốc sẽ không bị xóa miễn là có một liên kết cứng trên đĩa hoặc một mô tả tập tin mở. Cache không có gì để làm với nó. Bây giờ, một số chương trình đóng mô tả tệp của họ khi họ không sử dụng chúng và điều đó có thể khiến dữ liệu biến mất.
dmckee

@dmckee Đúng rồi. Chúng tôi đang tiến gần đến cốt lõi. Vì vậy, điều gì là bình thường đối với một chương trình "bình thường": mở thư viện và giữ cho nó mở, hoặc tải thư viện và đóng nó sau đó?
Nils
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.