리눅스는 자동으로 추상 도메인 소켓을 정리합니까?


15

데몬 에 대한 일반적인 PID 파일 잠금 메커니즘에 의존하지 않는 데몬에 대한 더 나은 잠금 기능 ( Eduardo Fleury 에서 합성 됨)을 제공하는 것에 대한 StackOverflow에 대한 훌륭한 답변이 있습니다 . PID 잠금 파일이 때때로 문제를 일으킬 수있는 이유에 대한 좋은 설명이 많이 있으므로 여기서 다시 해시하지는 않습니다.

요컨대, 솔루션은 Linux 추상 네임 스페이스 도메인 소켓에 의존하는데, 이는 데몬이 SIGKILL 된 후에 고집 될 수있는 파일에 의존하지 않고 이름을 기준으로 소켓을 추적합니다. 이 예제는 프로세스가 종료되면 Linux가 소켓을 비우는 것으로 보입니다.

그러나 바운드 프로세스가 SIGKILL 될 때 추상 소켓으로 Linux가 정확히 무엇을하는지 말하는 Linux에서 결정적인 문서를 찾을 수 없습니다. 아는 사람 있나요?

다시 말해 추상 소켓을 다시 사용할 수있게되면 언제입니까?

PID 파일 메커니즘을 문제를 해결하지 않으면 추상적 소켓으로 바꾸고 싶지 않습니다.


3
나는 이것에 직접 대답하는 것을 찾을 수 없습니다. 그러나 추상 소켓을 제거하는 API가 없으므로 커널에서 자동으로 관리 해야하는 것처럼 보입니다. 소켓이 열린 상태에서 프로세스가 없으면 사라집니다.
Barmar

@Barmar Fair로 충분합니다. 답변으로 추가 하시겠습니까?
CivFan

더 명확한 정보를 원합니다.
Barmar

답변:


5

그렇다. 리눅스는 정리하는 것이 의미가있는 한 추상 소켓을 자동으로 "정리"한다. 다음은이를 확인할 수있는 최소 작업 예입니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>

int
main(int argc, char **argv)
{
  int s;
  struct sockaddr_un sun;

  if (argc != 2 || strlen(argv[1]) + 1 > sizeof(sun.sun_path)) {
    fprintf(stderr, "usage: %s abstract-path\n", argv[0]);
    exit(1);
  }

  s = socket(AF_UNIX, SOCK_STREAM, 0);
  if (s < 0) {
    perror("socket");
    exit(1);
  }
  memset(&sun, 0, sizeof(sun));
  sun.sun_family = AF_UNIX;
  strcpy(sun.sun_path + 1, argv[1]);
  if (bind(s, (struct sockaddr *) &sun, sizeof(sun))) {
    perror("bind");
    exit(1);
  }
  pause();
}

이 프로그램을으로 실행 ./a.out /test-socket &한 다음을 실행 ss -ax | grep test-socket하면 사용중인 소켓이 표시됩니다. 그런 다음 kill %./a.out, 및 ss -ax소켓가 없어 표시됩니다.

그러나 모든 문서 에서이 정리를 찾을 수없는 이유는 비 추상 unix-domain 소켓을 정리 해야하는 것과 같은 의미로 실제로 정리하지 않기 때문입니다. 비추 상 소켓은 실제로 inode를 할당하고 기본 파일 시스템에서 정리해야하는 디렉토리에 항목을 작성합니다. 대조적으로 추상 소켓은 TCP 또는 UDP 포트 번호와 비슷합니다. 물론, TCP 포트를 바인드 한 후 종료하면 해당 TCP 포트가 다시 사용 가능해집니다. 그러나 사용했던 16 비트 숫자는 여전히 추상적이며 항상 존재합니다. 포트 번호의 네임 스페이스는 1-65535이며 변경하거나 정리할 필요가 없습니다.

따라서 추상 소켓 이름을 TCP 또는 UDP 포트 번호와 같이 생각하십시오. 경로 이름처럼 보이지만 그렇지 않은 훨씬 더 많은 가능한 포트 번호 세트에서 선택했습니다. 동일한 포트 번호를 두 번 (바인드 SO_REUSEADDR또는 SO_REUSEPORT) 바인딩 할 수 없습니다 . 그러나 소켓을 닫으면 (명시 적으로 또는 암시 적으로 종료하여) 포트를 비울 수 있으며 정리할 항목이 없습니다.


이미 오리 테스트를 통과했습니다. 파이썬과 같은 것들에는 문제가 없지만 Linux 커널 기능에 대해서는 더 많이 기대합니다. TCP / UDP 포트의 예를 보자. 언제 포트를 재사용 할 수 있는지 정확하게 설명하는 많은 문서가있다.
CivFan

2
그리고 왜 그 문서가 추상 소켓에도 똑같이 적용되지 않습니까? 당신은 참조가 있습니까? 비 유닉스 Unix 도메인 소켓에 대한 추가 정리 문제가 문서화되어있는 것이 더 좋은 질문 일 수 있습니다. 내 시스템에서 그것은 유닉스 (7) 에있다. "리눅스는 또한 파일 시스템과 독립적 인 추상 네임 스페이스를 지원한다"고 말한다. 따라서 "파일 시스템과 무관"하다는 것은 파일 시스템 별 정리를 의미하지 않습니다.
user3188445

5

나는 1 년 전에이 질문을 게시했으며 명확한 문서가 부족하다고 결코 만족하지 못했습니다. Linux 문서를 다시 확인하여 업데이트가 있는지 확인하고 행복했습니다. 습니다 .

추상 소켓

소켓 권한은 추상 소켓에 의미가 없습니다. 프로세스 umask (2)는 추상 소켓을 바인딩 할 때 영향을 미치지 않으며 객체의 소유권과 권한을 변경해도 (fchown (2) 및 fchmod (2)를 통해) 소켓의 접근성.

소켓에 대한 모든 열린 참조가 닫히면 추상 소켓이 자동으로 사라집니다.

또한, 인터페이스 프로그래밍 리눅스 에 의해 마이클 케 리스크는 (에서 크로스 - 게시 문제를 다루고 이 다른 답 ) :

57.6 리눅스 추상 소켓 네임 스페이스

소위 추상 네임 스페이스는 파일 시스템에서 해당 이름을 작성하지 않고 UNIX 도메인 소켓을 이름에 바인딩 할 수있는 Linux 고유 기능입니다. 이것은 몇 가지 잠재적 인 이점을 제공합니다.

  • 파일 시스템의 기존 이름과의 충돌 가능성에 대해 걱정할 필요가 없습니다.
  • 소켓 사용을 마치면 소켓 경로 이름을 연결 해제 할 필요가 없습니다. 소켓이 닫히면 추상 이름이 자동으로 제거됩니다.
  • 소켓의 파일 시스템 경로 이름을 만들 필요가 없습니다. 이것은 chroot 환경에서 또는 파일 시스템에 대한 쓰기 액세스 권한이없는 경우에 유용 할 수 있습니다.

추상 바인딩을 만들려면 sun_path 의 첫 번째 바이트를 지정합니다 필드 null 바이트 (\ 0)로 지정합니다. [...]

@ user3188445의 답변과 함께 질문을 매우 정확하게 정리한다고 생각합니다.

즉, 여전히 여기에는 SIGKILL 's 프로세스가 모든 열린 소켓을 닫을 것이라는 가정이 있습니다. 그것은 합리적인 가정으로 보이지만 그 행동을 정의하는 문서는 없습니다.


1
마지막 단락 : 소켓은 파일 설명자이며 프로세스가 종료되면 열려있는 모든 파일 설명자가 닫힙니다. 아이 쉬 보다 구체적으로, 소켓은 열린 파일이며 열린 파일은 자식 프로세스에 의해 상속 된 것처럼 전달 될 수 있습니다. 따라서 SOCK_CLOEXEC라이브러리를 포함한 모든 코드가 fork () + exec ()를 수행하는 경우 소켓을 호출해야합니다 . exec ()없이 fork ()를 사용하여 추가 자식 프로세스를 만드는 것은 일반적이지 않습니다. 당신이 그렇게하고 있다면 이미 알고있을 것입니다.
sourcejedi 2016 년

연결을 해제 할 필요는 없습니다 .-음, 경로 이름이 없기 때문에 연결을 끊을 수 없으며 불필요합니다.
domen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.