2012-04-03 29 views
5

Nếu quá trình của tôi đang tải thư viện .so và nếu có phiên bản mới của thư viện, bạn có thể chuyển sang thư viện mới mà không cần khởi động lại quá trình không? Hoặc câu trả lời phụ thuộc vào những thứ như liệu có thay đổi tham số cho một trong các hàm hiện có trong thư viện không?Cập nhật các thư viện được chia sẻ mà không cần khởi động lại quy trình

Tôi đang làm việc trong một hệ thống khá lớn chạy 100 quy trình và mỗi lần tải 10 thư viện. Các thư viện cung cấp chức năng cụ thể và được cung cấp bởi các nhóm riêng biệt. Vì vậy, khi một trong những thư viện thay đổi (cho một sửa lỗi cho phép nói) điều lý tưởng sẽ được xuất bản nó dưới mui xe mà không ảnh hưởng đến quá trình chạy. Có thể không?

EDIT Cảm ơn! Trong trường hợp của tôi khi một thư viện mới có sẵn, tất cả các tiến trình đang chạy phải bắt đầu sử dụng nó. Tùy chọn không phải của nó để cho phép chúng chạy với phiên bản cũ và chọn phiên bản mới sau này. Vì vậy, có vẻ như các tùy chọn an toàn hơn là chỉ cần tải lại các quy trình.

+1

Trừ khi bạn kiểm soát tất cả các tệp thực thi, cập nhật nóng để không thể thực hiện được các tệp mà không có các hacks xấu xí như quy trình ptracing. Ngoài ra, Linux không sử dụng dll. – BatchyX

Trả lời

5

Bạn không thể nâng cấp thư viện được liên kết khi đang chạy với quy trình đang chạy. Bạn thậm chí có thể thử, nhưng nếu bạn succed (và bạn sẽ không thất bại với một "văn bản tập tin đang sử dụng" thông báo lỗi), bạn sẽ phải khởi động lại quá trình để làm cho nó ánh xạ thư viện mới vào bộ nhớ.

Bạn có thể sử dụng lsof lệnh để kiểm tra thư viện được liên kết trong (runtime hoặc linktime):

lsof -p <process_pid> | grep ' mem ' 
+0

Thay vì 'lsof -p ', bạn cũng có thể sử dụng 'pldd '. – Mikel

+0

pldd: không tìm thấy lệnh. apt-cache search pldd: không tìm thấy ... – dAm2K

+0

Nó chỉ được thêm vào glibc vào tháng 3 năm nay. Phân phối của bạn có thể chưa bao gồm nó. – Mikel

0

ldd nhị phân của quá trình của bạn là một cách để tìm hiểu. mặc dù về mặt lý thuyết có thể, nó không được khuyến khích để tinker với quá trình chạy, mặc dù tôi chắc chắn các tiện ích tồn tại như ksplice mà tinker với nhân linux đang chạy.

bạn chỉ cần nâng cấp và quá trình chạy sẽ tiếp tục với phiên bản cũ và chọn phiên bản mới khi khởi động lại, giả sử hệ thống quản lý gói của bạn tốt và biết cài đặt nào là comptible.

0

Bạn có thể muốn tìm hiểu về phiên bản thư viện được chia sẻ và tùy chọn ld -h.

Một cách để sử dụng nó như sau:

Bạn duy trì bộ đếm phiên bản trong hệ thống xây dựng của mình. Bạn xây dựng thư viện được chia sẻ với:

ld ..... -h mylibrary.so.$VERSION 

tuy nhiên, bạn đặt thư viện đó vào lib cây của bạn chỉ đơn giản là mylibrary.so. (Cũng có một hack liên quan đến việc đưa toàn bộ .so vào một tập tin .a).

Hiện tại, khi chạy, các quá trình sử dụng thư viện sẽ tìm tên được phiên bản đầy đủ. Để triển khai phiên bản mới, bạn chỉ cần thêm phiên bản mới vào hình ảnh. Chạy các chương trình liên kết với phiên bản cũ tiếp tục sử dụng nó. Khi các chương trình được relinked và thử nghiệm với cái mới, bạn tung ra các file thực thi mới.

0

Đôi khi bạn có thể nâng cấp một trong sử dụng .so, và đôi khi bạn không thể. Điều này phụ thuộc chủ yếu vào cách bạn cố gắng làm điều đó, mà còn về sự đảm bảo an toàn của hạt nhân bạn đang chạy.

Đừng làm điều này: mèo mới.so> cũ.so ... bởi vì cuối cùng, quá trình của bạn có thể cố gắng yêu cầu trang gì đó và thấy rằng nó không ở vị trí chính xác nữa. Đó là một vấn đề bởi vì các địa chỉ của sự vật có thể thay đổi, và nó vẫn là inode tương tự; bạn chỉ ghi đè các byte trong tệp.

Tuy nhiên, nếu bạn: mv mới.so cũ.so Bạn sẽ OK trên hầu hết các hệ thống, bởi vì các quy trình đang chạy của bạn có thể giữ được inode chưa đặt tên cho thư viện cũ, trong khi các yêu cầu mới của quy trình của bạn lấy tập tin mới. NHƯNG, một số hạt nhân không thích để bạn mv một trong sử dụng .so, có lẽ hết thận trọng, có lẽ cho sự đơn giản của riêng mình.

+1

Tôi không nghĩ rằng "cat new.so> old.so" có bất kỳ ảnh hưởng nào đến chương trình đang chạy. Kể từ khi hạt nhân biết rằng đoạn mã trong bộ nhớ được ánh xạ tới lưu trữ nơi old.so là, nó sẽ hoặc là từ chối viết ("văn bản bận") hoặc thậm chí đi trước và đặt các lĩnh vực sang một bên cho đến khi chương trình kết thúc. – SquareRootOfTwentyThree

0

Nếu bạn mong đợi libaries thay đổi trên một cách khá thường xuyên, và bạn mong đợi để duy trì tăng thời gian, tôi nghĩ rằng hệ thống của bạn nên được tái thiết kế sao cho các thư viện như vậy thực sự trở thành thành phần lỏng (ví dụ như dịch vụ).

Có nói rằng, câu trả lời của tôi cho câu hỏi là có: dưới nhất định trường hợp, nó có thể để cập nhật thư viện chia sẻ mà không quá trình khởi động lại. Trong hầu hết các trường hợp, tôi cho rằng điều đó là không thể, ví dụ: khi API của thư viện thay đổi, khi sắp xếp thay đổi phân đoạn dữ liệu của bạn, khi thư viện duy trì các chuỗi nội bộ. Danh sách này khá dài.

Đối với sửa lỗi rất nhỏ đối với mã, bạn vẫn có thể tận dụng của ptrace ghi vào không gian bộ nhớ quá trình, và từ có làm lại những gì /lib/ld-linux.so làm về động liên kết. Thành thật mà nói, nó là một hoạt động cực kỳ phức tạp.

3

Một kỹ thuật thú vị, mặc dù nó có phần dễ bị lỗi trong bước khôi phục điểm kiểm tra, là thực hiện khởi động lại vô hình.

Quy trình máy chủ của bạn hoặc bất kể nó là gì, lưu tất cả thông tin cần thiết của nó vào tệp đĩa. Bao gồm các số mô tả tập tin và các trạng thái hiện tại. Sau đó, quá trình máy chủ thực hiện cuộc gọi hệ thống exec để thực thi chính nó, thay thế phiên bản hiện tại của chính nó. Sau đó, nó đọc trạng thái của nó từ các tệp đĩa và tiếp tục phục vụ các bộ mô tả tệp của nó như thể không có gì xảy ra.

Nếu mọi việc suôn sẻ, khởi động lại là vô hình và quy trình mới đang sử dụng tất cả các thư viện được cập nhật.

+1

Một ví dụ tuyệt vời là lệnh «irssi' và'/upgrade'. –

2

Ít nhất, bạn phải đảm bảo rằng giao diện của thư viện không thay đổi giữa các phiên bản. Nếu đó là đảm bảo, sau đó tôi sẽ cố gắng tìm kiếm vào tự động tải các thư viện với dlopen/dlsym và xem nếu dlclose cho phép bạn tải lại.

Tôi chưa bao giờ tự mình làm điều này, nhưng đó là con đường tôi muốn theo đuổi trước tiên. Nếu bạn đi theo cách này, bạn có thể xuất bản kết quả không?

2

Linux cung cấp một số giao diện trình tải động và quy trình có thể tải thư viện động khi chạy. dlopen và dlsysm được cung cấp bởi linux có thể giải quyết vấn đề của bạn.

Các vấn đề liên quan