/proc/ 파일을 해석해도 안전한가요?
하고 /proc/net/tcp/
지만만안?안 전??
「 」의 , 「 」의 파일을 읽으면 요./proc/
다른 프로세스(또는 OS 자체)가 동시에 변경되는 것을 두려워하지 마십시오.
일반적으로 그렇지 않습니다. (그래서 여기 있는 대부분의 답은 틀렸습니다.어떤 물건을 원하느냐에 따라 안전할 수도 있어요.그러나 파일의 일관성에 대해 너무 많이 가정하면 코드에 버그가 생기기 쉽습니다./proc
예를 들어, 일관된 스냅샷이라고 가정한 이 버그를 참조해 주세요.
예를 들어 다음과 같습니다.
/proc/uptime
다른 답변에서도 언급했듯이 완전히 원자적인 것입니다.그러나 Linux 2.6.30 이후로는 2년이 채 되지 않았습니다.따라서 이 작고 사소한 파일도 그때까지 경쟁 조건의 대상이었고, 지금도 대부분의 엔터프라이즈 커널에 존재합니다.현재의 송신원 또는 그것을 아토믹하게 한 커밋에 대해서는, 을 참조해 주세요.2.6.30 이전 커널에서는 다음 작업을 수행할 수 있습니다.open
★★★★★★★★★★★★★★★★★.read
read
제가 해 .「 」를 참조해 주세요)./proc/mounts
는 단일 시스템콜 내의 atomic입니다그래서 만약 당신이read
전체 파일을 한 번에 처리할 수 있으므로 시스템의 마운트 지점에 대한 일관된 단일 스냅샷을 얻을 수 있습니다.단, 여러 개의 「」를 는, 「」를 합니다.read
시스템 콜 - 파일이 큰 경우 일반 I/O 라이브러리를 사용하고 이 문제에 특별한 주의를 기울이지 않으면 경합 상태가 됩니다.일관된 스냅샷이 생성되지 않을 뿐만 아니라 시작 전에 존재했던 마운트 지점이 표시되지 않을 수 있습니다.가 되는read()
를 보고 마운트 포인트 목록을 보호하는 세마포어를 잡습니다.이 세마포는 다음 시간까지 유지됩니다.m_stop()
「」가 때에 됩니다.read()
완료했습니다.무엇이 잘못될 수 있는지 알아보려면 지난해 이 버그(위에서 링크한 버그와 동일)를 참조하십시오.그 이외의 고품질 소프트웨어는 쉽게 읽을 수 있습니다./proc/mounts
.당신이 실제로 묻고 있는 것은 그것보다도 더 일관성이 떨어진다는 것입니다
/proc/net/tcp
.그것은 테이블의 각 열 안에만 원자입니다.이것을 보려면 , 를 참조해 주세요.established_get_next()
각 엔트리의 잠금을 차례로 확인합니다.각 행의 일관성이 결여되어 있는 것을 나타내는 리프로코드에는 없지만, 일관성을 유지할 수 있는 잠금 장치(또는 그 외의 것)는 없습니다.생각해 보면, 네트워킹은 많은 경우 매우 바쁜 시스템이기 때문에, 이 진단 툴에 일관된 뷰를 표시하는 것은 오버헤드의 가치가 없습니다.
또 다른 한 조각은/proc/net/tcp
각 행 내의 atomic은 버퍼링입니다.seq_read()
(을 참조해 주세요.이를 통해 한 번만 더 많은read()
한 행의 일부, 전체 행의 텍스트는 버퍼에 저장되므로 다음 행은read()
새 행을 시작하기 전에 나머지 행을 가져옵니다.에서는 같은 메커니즘이 사용됩니다./proc/mounts
각 행을 원자적으로 유지하다read()
전화, 그리고 그 메커니즘이/proc/uptime
를 사용하여 원자성을 유지합니다.커널은 메모리 사용에 주의하기 때문에 이 메커니즘은 파일 전체를 버퍼링하지 않습니다.
의 대부분의 파일/proc
적어도 와 같은 정도의 일관성이 있을 것이다/proc/net/tcp
각 행은 제공하는 정보에 관계없이1개의 엔트리를 일관되게 나타내고 있습니다.대부분의 엔트리는 같은 것을 사용하기 때문입니다.seq_file
추상화처럼/proc/uptime
예를 들어 일부 파일이 아직 이행되어 있는 것을 알 수 있습니다.seq_file
나는 아직도 오래된 메커니즘을 사용하고 있고 심지어 그 수준의 원자성조차 가지고 있지 않다고 확신한다.이러한 경고는 거의 문서화되어 있지 않습니다.특정 파일에 대해 유일한 보증은 소스를 읽는 것입니다.
의 경우/proc/net/tcp
, 그것을 읽고, 각 행을 안심하고 해석할 수 있습니다.그러나 여러 줄에서 동시에 결론을 내리려고 하면 다른 프로세스와 커널이 읽을 때 변경되어 버그가 발생할 수 있습니다.
의 파일이지만/proc
사용자 공간에서 일반 파일로 나타납니다.실제 파일은 아니고 사용자 공간에서 표준 파일 조작을 지원하는 엔티티입니다.(open
,read
,close
이는 커널에 의해 변경되는 일반 파일을 디스크에 저장하는 것과는 상당히 다르다는 점에 유의하십시오.
커널이 하는 일은 내부 상태를 자신의 메모리에 인쇄하는 것뿐입니다.sprintf
-like 함수입니다.이 메모리는 사용자가 명령어를 발행할 때마다 사용자 공간에 복사됩니다.read(2)
시스템 콜을 실행합니다.
커널은 이러한 콜을 일반 파일과는 전혀 다른 방법으로 처리합니다.이것은, 판독하는 데이터의 스냅샷 전체가, 그 시점에서 준비되는 것을 의미합니다.open(2)
한편, 커널은 동시 콜의 일관성과 원자성을 보증합니다.어디선가 읽어본 적은 없지만, 그렇지 않으면 말이 안 돼요.
사용자 고유의 Unix 플레이버에 proc 파일이 구현되어 있는지 살펴보시기 바랍니다.이것은 실제로 구현상의 문제이며(출력 형식 및 내용도 마찬가지) 표준에 의해 관리되지 않습니다.
가장 간단한 예는 Linux에서 proc 파일을 구현하는 것입니다.에 제공되는 콜백 함수에서 버퍼 전체가 어떻게 생성되는지 주의해 주십시오.single_open
.
/displays는 가상 파일 시스템입니다.사실 커널 내부만 쉽게 표시할 수 있습니다.읽어보는 것은 확실히 안전하지만(그래서 여기에 있습니다), 장기적으로 보면 이러한 가상 파일의 내부가 새로운 버전의 커널과 함께 발전하는 경우가 있기 때문에 위험합니다.
편집
자세한 내용은 Linux 커널 문서의 proc 매뉴얼 1.4장 네트워킹에서 확인할 수 있습니다.정보가 시간이 지남에 따라 어떻게 진화하는지 알 수 없습니다.열려있는 채로 멈춰있는 줄 알았는데 확답을 할 수가 없어요.
편집 2
Sco doc에 따르면 (Linux는 아니지만 *nix의 모든 맛이 그렇게 동작한다고 확신합니다)
프로세스 상태와 그에 따라 /proc 파일의 내용이 순간마다 변경될 수 있지만, /proc 파일의 단일 읽기(2)는 "sane" 상태 표현을 반환하도록 보장됩니다. 즉, 읽기 내용은 프로세스 상태의 원자 스냅샷이 됩니다.실행 중인 프로세스의 /proc 파일에 적용되는 연속 읽기에는 이러한 보증이 적용되지 않습니다.또한 원자성은 as(주소 공간) 파일에 적용되는 I/O에 대해 특별히 보장되지 않습니다. 프로세스의 주소 공간의 내용은 해당 프로세스의 LWP 또는 시스템 내의 다른 프로세스에 의해 동시에 수정될 수 있습니다.
Linux 커널의 procfs API는 읽기가 일관된 데이터를 반환하도록 하는 인터페이스를 제공합니다.의 코멘트를 읽어 주세요.빅 코멘트 블록의 항목 1)에서 이 인터페이스에 대해 설명합니다.
즉, 이 인터페이스를 올바르게 사용하여 반환된 데이터의 일관성을 확인하는 것은 물론 특정 proc 파일의 구현에 달려 있습니다.따라서 질문에 답하려면: 아니요, 커널은 읽기 중에 proc 파일의 일관성을 보장하지는 않지만 이러한 파일의 구현이 일관성을 제공하는 수단을 제공합니다.
현재 임베디드 ARM 타깃으로 드라이버 개발을 하고 있기 때문에 Linux 2.6.27.8 소스를 가지고 있습니다.
파일...linux-2.6.27.8-lpc32xx/net/ipv4/raw.c
예를 들어, 934행에는 다음이 포함됩니다.
seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
i, src, srcp, dest, destp, sp->sk_state,
atomic_read(&sp->sk_wmem_alloc),
atomic_read(&sp->sk_rmem_alloc),
0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
출력되는 것
[wally@zenetfedora ~]$ cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 017AA8C0:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 15160 1 f552de00 299
1: 00000000:C775 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 13237 1 f552ca00 299
...
기능하여raw_sock_seq_show()
procfs 처리 함수 계층의 일부입니다.텍스트는 다음 시간까지 생성되지 않습니다.read()
에 대한 요구가 이루어짐/proc/net/tcp
procfs 읽기는 정보를 업데이트하는 것보다 훨씬 덜 일반적이기 때문에 합리적인 메커니즘인 file.
일부 드라이버(예: 내 드라이버)는 싱글로 proc_read 함수를 구현합니다.sprintf()
코어 드라이버의 실장에 있어서, 한층 더 복잡해지는 것은, 1회의 판독시에 중간 커널 스페이스 버퍼에 들어가지 않는, 매우 긴 출력을 처리하는 것입니다.
64K 읽기 버퍼를 사용하는 프로그램으로 테스트했지만 proc_read가 데이터를 반환하기 위해 시스템에서 커널 공간 버퍼가 3072바이트가 됩니다.그 이상의 텍스트를 반환하려면 어드밴스 포인터를 가진 여러 콜이 필요합니다.여러 I/O가 필요할 때 반환된 데이터의 일관성을 유지하는 올바른 방법을 모르겠습니다.에서의 각 엔트리/proc/net/tcp
자기일관성이 있습니다.나란히 있는 선이 서로 다른 시간에 스냅샷일 수 있습니다.
알 수 없는 버그를 제외하고 에는 레이스 조건이 없습니다./proc
손상된 데이터를 읽거나 이전 데이터와 새 데이터가 혼합될 수 있습니다.그런 의미에서 안전합니다.하지만 여전히 인종적 조건이 있습니다 당신이 읽은 데이터의 많은 부분이/proc
는 생성되자마자 수정될 수 있으며, 읽기/처리를 시작할 때쯤에는 더욱 그렇습니다.예를 들어 프로세스는 언제든지 정지할 수 있으며 새로운 프로세스는 동일한 pid를 할당할 수 있습니다. 레이스 조건 없이 사용할 수 있는 유일한 프로세스 ID는 자신의 자식 프로세스입니다.네트워크 정보(오픈 포트 등) 및 실제로 에 있는 대부분의 정보에 대해서도 마찬가지입니다./proc
에 있는 모든 데이터에 의존하는 것은 나쁘고 위험한 관행이라고 생각합니다./proc
자신의 프로세스와 잠재적으로 하위 프로세스에 대한 데이터를 제외하고 정확해야 합니다.물론 다른 정보를 제공하는 것은 여전히 유용할 수 있습니다./proc
사용자/관리자에게 정보를 제공합니다.
/proc 파일에서 읽을 때 커널은 미리 등록된 함수를 호출하여 해당 proc 파일의 "읽기" 함수로 만듭니다.를 참조해 주세요.__proc_file_read
fs/syslog/syslog.c로 기능합니다.
따라서 proc read의 안전성은 읽기 요구를 만족시키기 위해 커널이 호출하는 함수만큼 안전합니다.이 함수가 만지는 모든 데이터를 적절히 잠그고 버퍼에 저장하여 사용자에게 반환할 경우 해당 함수를 사용하여 읽는 것이 완전히 안전합니다./proc/net/tcp에 대한 읽기 요구를 충족시키기 위해 사용되는 proc 파일과 같은 파일은 오랫동안 존재해 왔고 꼼꼼한 검토를 거쳤기 때문에 당신이 요구하는 만큼 안전합니다.실제로 많은 일반적인 Linux 유틸리티는 proc 파일 시스템에서 읽고 출력 포맷을 다르게 하는 데 의존하고 있습니다(머릿속으로는 'ps'와 'netstat'가 이를 수행하는 것 같습니다).
항상 그렇듯이, 당신은 내 말을 믿을 필요가 없다. 당신은 두려움을 가라앉히기 위해 근원을 볼 수 있다.proc_net_tcp로부터의 다음 문서.txt는 /syslog/net/syslog의 "읽기" 기능이 어디에 있는지 알려주기 때문에 해당 proc 파일에서 읽을 때 실행되는 실제 코드를 보고 잠금 위험이 없는지 직접 확인할 수 있습니다.
이 문서에서는 /proc/net/tcp 및 /proc/net/tcp6 인터페이스에 대해 설명합니다.
이러한 인터페이스는 tcp_diag를 위해 권장되지 않습니다.이러한 /proc 인터페이스는 현재 액티브한 TCP 연결에 대한 정보를 제공하며, 각각 net/ipv4/tcp_ipv4.c의 tcp4_seq_show()와 net/ipv6/tcp_ipv6.c의 tcp6_seq_show()에 의해 구현됩니다.
언급URL : https://stackoverflow.com/questions/5713451/is-it-safe-to-parse-a-proc-file
'source' 카테고리의 다른 글
CMake에서의 디버깅과 릴리스 (0) | 2022.08.14 |
---|---|
Vue.js를 사용하여 단일 파일 구성 요소의 메서드에서 계산된 속성에 액세스하는 방법 (0) | 2022.08.14 |
C 어레이를 반복합니다. (0) | 2022.08.14 |
Enter 키를 누르면 vuejs의 버튼을 클릭합니다. (0) | 2022.08.14 |
vue2의 별칭 URL에서 ID 가져오기 (0) | 2022.08.14 |