Где ядро ​​Linux выполняет процесс и очищает TCP-соединения после смерти процесса? - PullRequest
7 голосов
/ 14 декабря 2010

Я пытаюсь найти место в ядре Linux, где оно выполняет очистку после того, как процесс умирает. В частности, я хочу посмотреть, если / как он обрабатывает открытые TCP-соединения после того, как процесс завершен с сигналом -9. Я почти уверен, что он закрывает все соединения, но я хочу увидеть детали, и есть ли вероятность того, что соединения не закрыты должным образом.

Приветствуются указатели на источники ядра Linux.

Ответы [ 2 ]

11 голосов
/ 15 декабря 2010

Мясо завершения процесса обрабатывается exit.c:do_exit().Эта функция вызывает exit_files(), что, в свою очередь, вызывает put_files_struct(), что вызывает close_files().

close_files() зацикливается на всех файловых дескрипторах, открытых процессом (включая все сокеты)), вызывая filp_close() для каждого из них, что вызывает fput() для struct file объекта.Когда последняя ссылка на struct file установлена, fput() вызывает метод .release() объекта файла, который для сокетов является функцией sock_close() в net/socket.c.

6 голосов
/ 14 декабря 2010

Я почти уверен, что очистка сокета является побочным эффектом освобождения всех файловых дескрипторов после того, как процесс умирает, а не выполняется непосредственно очисткой процесса.

Я собираюсь выйти на конечность и предположить, что вы попали в общую ловушку сетевого программирования.Если я правильно предположил, что ваша проблема в том, что вы получаете сообщение об ошибке «Адрес используется» (EADDRINUSE) при попытке привязки к адресу после того, как процесс завершен, тогда вы работаете с сокетом TIME_WAIT.

В этом случае вы можете подождать тайм-аут, обычно 60 секунд, или вы можете изменить сокет, чтобы разрешить немедленное повторное использование, например, так.

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]

Из ваших комментариев кажется, что у вас проблемы с полуоткрытыми соединениями, и вы не до конца понимаете, как работает TCP.TCP не может узнать, мертв ли ​​клиент или просто простаивает.Если вы kill -9 клиентский процесс, четырехстороннее закрывающее рукопожатие никогда не завершается.Это не должно оставлять открытых соединений на вашем сервере, так что вам все еще может потребоваться сетевой дамп, чтобы быть уверенным в том, что происходит.

Я не могу точно сказать, как вы должны справиться с этим безточно зная, что вы делаете, но вы можете прочитать о TCP Keepalive здесь .Несколько других опций - отправка пустых или нулевых сообщений периодически клиенту (может потребоваться изменить ваш протокол) или установка жестких таймеров на незанятых соединениях (может привести к потере допустимых соединений).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...