2010-12-14 18 views
7

Tôi đang cố gắng tìm chỗ trong hạt nhân Linux, nơi nó dọn dẹp sau khi quá trình chết. Cụ thể, tôi muốn xem liệu nó có xử lý các kết nối TCP mở sau khi quá trình bị giết với tín hiệu -9 hay không. Tôi khá chắc chắn nó đóng tất cả các kết nối, nhưng tôi muốn xem chi tiết, và nếu có bất kỳ cơ hội mà các kết nối không được đóng đúng cách.Nhân Linux đang xử lý và làm sạch các kết nối TCP sau khi quá trình chết ở đâu?

Con trỏ tới nguồn hạt nhân Linux được chào đón.

+0

Tôi rất tò mò nếu bạn thích câu trả lời và nếu đó là sự cố hạt nhân hoặc sự cố mạng. Ngoài ra, việc cập nhật câu hỏi của bạn sẽ giúp những người khác vấp ngã sau này. – JimB

+0

@JimB, Nếu bạn quan tâm đến vấn đề mạng của chúng tôi, thì không, tôi không biết vấn đề là gì. Chúng tôi đã thêm những kết nối nhàn rỗi này kiểm tra và sử dụng so_keepalive ngay bây giờ, nhưng có rất nhiều lưu lượng truy cập, rất khó để thực hiện lưu lượng truy cập và xác minh xem các gói nhất định có bị mất hay không. Về việc đóng cửa, tôi đã kiểm tra các nguồn mà quán cà phê được đề cập trong câu trả lời của anh ta, và tôi tin rằng hạt nhân Linux ít nhất * cố gắng * để đóng các ổ cắm khi quá trình bị giết. Nếu nó thành công hay không là một câu hỏi khác. –

Trả lời

10

Thịt chấm dứt quá trình được xử lý bởi exit.c:do_exit(). Hàm này gọi exit_files(), mà lần lượt gọi put_files_struct(), gọi close_files().

close_files() vòng qua tất cả các file descriptor quá trình này có mở (bao gồm tất cả ổ cắm), gọi filp_close() trên mỗi người, trong đó kêu gọi fput() trên đối tượng struct file. Khi tham chiếu cuối cùng cho số struct file đã được đặt, fput() gọi phương thức .release() của đối tượng tệp, đối với ổ cắm, là chức năng sock_close() trong net/socket.c.

6

Tôi khá chắc chắn rằng việc dọn dẹp ổ cắm là một tác dụng phụ của việc giải phóng tất cả các bộ mô tả tệp sau khi quá trình chết và không được thực hiện trực tiếp bởi quá trình dọn dẹp.

Tôi sẽ đi ra ngoài trên một chi, và giả sử bạn đang đánh một điểm chung với lập trình mạng. Nếu tôi đúng khi đoán rằng vấn đề của bạn là bạn nhận được lỗi "Địa chỉ đang sử dụng" (EADDRINUSE) khi cố gắng liên kết với một địa chỉ sau khi quá trình bị giết, thì bạn đang chạy vào TIME_WAIT của socket.

Nếu trường hợp này xảy ra, bạn có thể chờ thời gian chờ, thường là 60 giây hoặc bạn có thể sửa đổi ổ cắm để cho phép sử dụng lại ngay lập tức như vậy.

int sock, ret, on; 
struct sockaddr_in servaddr; 

sock = socket(AF_INET, SOCK_STREAM, 0): 

/* Enable address reuse */ 
on = 1; 
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 

[EDIT]

Từ ý kiến ​​của bạn, Có vẻ như bạn đang gặp vấn đề với các kết nối half-open, và không hoàn toàn hiểu TCP hoạt động. TCP không có cách nào để biết liệu một khách hàng đã chết hay chỉ là nhàn rỗi. Nếu bạn kill -9 một quá trình khách hàng, việc bắt tay đóng bốn chiều không bao giờ hoàn thành. Tuy nhiên, điều này không nên để các kết nối mở trên máy chủ của bạn, vì vậy bạn vẫn có thể cần phải có một bãi chứa mạng để chắc chắn về những gì đang xảy ra.

Tôi không thể chắc chắn cách bạn nên xử lý việc này mà không biết chính xác bạn đang làm gì, nhưng bạn có thể đọc khoảng TCP Keepalive here. Một vài tùy chọn khác sẽ gửi các thông báo rỗng hoặc null định kỳ tới máy khách (có thể yêu cầu sửa đổi giao thức của bạn), hoặc đặt các bộ định thời cứng trên các kết nối không hoạt động (có thể dẫn đến các kết nối không hợp lệ).

+0

Cảm ơn bạn ... dọn dẹp các mô tả tập tin thực sự sẽ dẫn đến việc đóng kết nối. Btw, tôi đang chạy vào vấn đề khác nhau ;-) Máy chủ của chúng tôi thấy các kết nối cũ từ khách hàng đã bị giết với -9 và chúng tôi đang cố gắng tìm hiểu lý do.Bây giờ, giải pháp của chúng tôi là tự động đóng các kết nối nhàn rỗi từ máy chủ và cũng có thể sử dụng SO_KEEPALIVE, nhưng chúng tôi đang cố gắng hiểu vấn đề. –

+0

Sau đó, có vẻ như bạn đang gặp vấn đề với các kết nối nửa mở. Tôi sẽ cập nhật câu trả lời của mình. – JimB

+0

Cảm ơn bạn đã cập nhật. Tôi đọc Tcp faq keepalive chỉ ngày hôm qua. Chúng tôi cũng đã thêm các kết nối không hoạt động vào máy chủ. Việc sửa đổi giao thức để gửi "ping" từ máy chủ không phải là một tùy chọn, nhưng chúng ta sẽ kết hợp SO_KEEPALIVE với việc bỏ các kết nối nhàn rỗi, và điều đó sẽ làm cho chúng ta. Điều làm tôi bối rối là khi tôi chơi với kill -9 cục bộ, kernel cố gắng đóng kết nối này tốt. Btw, máy khách và máy chủ đều nằm trong quyền kiểm soát của chúng tôi trên cùng một mạng, chúng tôi chỉ gặp sự cố này trên một lần triển khai. –

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