2009-03-27 20 views
55

Tôi có thể tìm thấy tài liệu được tôn trọng tốt chi tiết cách xử lý đúng các tệp PID trên Unix?Tham chiếu để xử lý đúng cách tệp PID trên Unix

Trên hệ điều hành Unix, thực tế phổ biến là “khóa” chương trình (thường là một daemon) bằng cách sử dụng tệp khóa đặc biệt: tệp PID.

Đây là tệp ở vị trí có thể dự đoán được, thường là ‘/var/run/foo.pid’. Chương trình được yêu cầu kiểm tra khi nó khởi động cho dù tệp PID tồn tại và, nếu tệp tồn tại, hãy thoát với một lỗi. Vì vậy, nó là một loại tư vấn, cơ chế khóa hợp tác.

Tệp có chứa một dòng văn bản duy nhất, là ID quá trình số (do đó có tên là "tệp PID") của quy trình hiện đang giữ khóa; điều này cho phép một cách dễ dàng để tự động gửi tín hiệu đến quá trình giữ khóa.

Điều tôi không thể tìm thấy là tham khảo tốt về hành vi được mong đợi hoặc "thực hành tốt nhất" để xử lý tệp PID. Có nhiều sắc thái khác nhau: làm thế nào để khóa tập tin (đừng bận tâm? Sử dụng hạt nhân? Điều gì về sự không tương thích của nền tảng?), Xử lý khóa cũ (âm thầm xóa chúng? Khi nào cần kiểm tra?), Khi chính xác lấy và nhả khóa , và kể từ đó trở đi.

Tôi có thể tìm thấy tài liệu tham khảo được tôn trọng, có thẩm quyền nhất (lý tưởng ở cấp độ nào của W. Richard Stevens) cho chủ đề nhỏ này?

+0

$ XDG_RUNTIME_DIR là nơi bạn nên đặt tệp pid nếu chạy với tư cách người dùng có 1000+ uid. – Behrooz

Trả lời

16

Theo như tôi biết, các tệp PID là một quy ước chứ không phải thứ gì đó mà bạn có thể tìm thấy nguồn được tôn trọng, chủ yếu là có thẩm quyền. Gần nhất tôi có thể tìm thấy là this section của tiêu chuẩn phân cấp hệ thống tập tin.

This Perl library có thể hữu ích, vì có vẻ như tác giả ít nhất đã nghĩ về một số vấn đề có thể phát sinh.

Tôi tin rằng các tập tin trong/var/run thường được xử lý bởi các nhà bảo trì distro chứ không phải là tác giả daemon, vì đó là trách nhiệm của người bảo trì distro để đảm bảo rằng tất cả các init script chơi đẹp với nhau. Tôi đã kiểm tra tài liệu của nhà phát triển Debian và Fedora và không thể tìm thấy bất kỳ hướng dẫn chi tiết nào, nhưng bạn có thể có thêm thông tin về danh sách gửi thư của nhà phát triển của họ.

+0

Cảm ơn. Sự đồng thuận trong các diễn đàn khác cũng có vẻ là không có tham chiếu kinh điển cho việc này. (FHS đề cập đến vị trí tệp và nội dung ngắn gọn và không nói gì về hành vi.) – bignose

21

Trước hết, trên tất cả UNIX hiện đại /var/run không tồn tại trong quá trình khởi động lại.

Phương pháp chung để xử lý tệp PID là tạo ra nó trong khi khởi tạo và xóa nó khỏi bất kỳ lối thoát nào, hoặc là trình xử lý thông thường hoặc tín hiệu.

Có hai cách hợp lý để tạo/kiểm tra tệp nguyên tử. Một trong những chính những ngày này là để mở nó với cờ O_EXCL: nếu tập tin đã tồn tại, cuộc gọi không thành công. Cách cũ (bắt buộc trên các hệ thống không có O_EXCL) là tạo nó bằng một tên ngẫu nhiên và liên kết đến nó. Liên kết sẽ thất bại nếu mục tiêu tồn tại.

+3

“Có hai cách kinh điển để tạo/kiểm tra nguyên tắc cho tệp.” Đó chính xác là điều mà câu hỏi của tôi là: canon này được ghi lại theo cách kinh điển, và điều gì làm cho nó có thẩm quyền so với lời khuyên mâu thuẫn của người khác? – bignose

+0

Thật không may là nhiều phương thức hoạt động UNIX được lưu truyền trong văn hóa. Đọc các trang hướng dẫn sử dụng cho các cuộc gọi hệ thống được mô tả trong POSIX.1 (những điều này, đủ gây nhầm lẫn, trong phần 2) chỉ cho thấy một vài điều phù hợp để khóa. Vì flock() không đáng tin cậy nên lá này chỉ có hai cái và một liên quan đến mkdir. – Joshua

+2

Câu hỏi công bằng là "Tại sao không phải là đàn chiên() đáng tin cậy." Câu trả lời là đã có quá nhiều hệ thống bị hỏng trong những năm qua, và nó không bao giờ hoạt động chính xác trên nfs anyway (giao thức nfslock chính nó là tùy thuộc vào vấn đề tâm phân chia). – Joshua

7

Tùy thuộc vào phân phối, thực tế tập lệnh init xử lý tệp pidfile. Nó kiểm tra sự tồn tại lúc bắt đầu, loại bỏ khi dừng, vv Tôi không thích làm theo cách đó. Tôi viết các init script của riêng mình và thường không sử dụng các hàm init stanard.

Một chương trình được viết bằng văn bản (daemon) sẽ có một số loại tệp cấu hình cho biết vị trí của tệp pidfile (nếu có) này. Nó cũng sẽ cẩn thận để thiết lập xử lý tín hiệu để các tập tin PID được làm sạch trên bình thường, hoặc thoát bất thường, bất cứ khi nào một tín hiệu có thể được xử lý. Tệp PID sau đó cung cấp cho init script đúng PID để nó có thể được dừng lại.

Vì vậy, nếu pidfile đã tồn tại khi bắt đầu, nó là một chỉ báo rất tốt cho chương trình mà trước đó nó đã bị rơi và nên làm một số loại nỗ lực phục hồi (nếu có). Bạn loại bắn logic đó trong bàn chân nếu bạn có init script chính nó kiểm tra sự tồn tại của PID, hoặc hủy liên kết nó.

Theo như không gian tên, tên phải tuân theo tên chương trình. Nếu bạn đang bắt đầu 'foo-daemon', nó sẽ là foo-daemon.pid

Bạn cũng nên khám phá/var/lock/subsys, tuy nhiên, phần lớn được sử dụng cho các hương vị của Red Hat.

11

Xem sốcủa Kerrisk, phần 55.6 "Running Just One Instance of a Program" dựa trên việc triển khai thực hiện pidfile trong Lập trình mạng UNIX của Stevens, v2. Lưu ý rằng vị trí của pidfile thường là một cái gì đó được xử lý bởi distro (thông qua init script), do đó, một daemon được viết tốt sẽ lấy một đối số dòng lệnh để chỉ định pidfile và không cho phép điều này vô tình bị ghi đè bởi tệp cấu hình. Nó cũng nên xử lý một cách dễ dàng một tệp pid cũ (O_EXCL không nên được sử dụng). fcntl() tập tin khóa nên được sử dụng - bạn có thể giả định rằng một pidfile daemon nằm trên một hệ thống tập tin địa phương (không NFS).

+0

Nếu có thông tin trực tuyến về điều này, vui lòng chuyển "Giao diện lập trình Linux" và/hoặc "phần 55.6" thành văn bản liên kết đến nơi chúng tôi có thể đọc hơn. – bignose

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