2016-12-09 4 views
1

쉘에서 파일이 비어 있는지 테스트합니다. test -s /sys/fs/cgroup/systemd/docker/d4e311735706485e748513bad611070e223cba76fdf4c72a1102d14b653da750/tasks 거짓을 반환하고 ls -lh을 사용할 때 크기가 0이지만, cat을 사용할 때이 파일에서 4071을 얻을 수 있습니다. 이는 파일이 비어 있지 않다는 것을 의미합니다. 아마이 파일이 너무 작아서 홈 디렉토리에 파일을 만들고 4071을 반향합니다. 크기가 0이 아니라는 것을 알았습니다./sys/fs/cgroup의 파일이 특별합니까?리눅스에서 파일은 비어 있지 않지만 크기는 0입니다.

+0

이 반드시 "동시에"라는 의미는 아닙니다. 파일이 쓰여지고 연속적으로 잘 리게됩니까? 정규 파일인가? ls -l 출력을 표시 할 수 있습니까? –

+0

@Stefan Hegny 답변을 주셔서 감사합니다. 여기에 ls -l 출력이 있습니다. '-rw-r-r-- 1 root root 0 12 월 15:47 tasks' 나는 당신이 옳다고 생각합니다. 아마도이 파일이 작성되었을 것입니다. to 및 nottruncated,이 파일은 컨테이너의 프로세스를 기록하며 항상 업데이트됩니다. – cheon

+0

@ cheon 적어도 나는 그것이 너무 작지는 않다는 것을 확신합니다. 0보다 큰 컴퓨터 언어는 0보다 크고 다른 "너무 작은"층이 없음을 의미합니다 ... –

답변

1

처리중인 파일은 cgroup 파일 시스템의 일부인 특수 파일입니다.

왜 그런지 이해하려면 test -e $filename 할 때 어떤 일이 발생하는지 봅시다.

strace 명령을 사용하여 시스템 호출을 인쇄하는 명령을 사용합니다.

stat("$filename", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 

는 파일의 크기 st_size = 0을 반환이 경우 : 당신이 strace test -e $filename을 할 경우

, 당신은 결과에이 줄을 찾을 수 있습니다.

그러나 문제는 실제로 커널 내에서, 다른 측면에서 발생하는 것입니다 :

당신이 파일을 처리 할 때, 당신은 가상라는 커널의 중간 계층으로가는 시스템 호출을 파일 시스템은 필요한 정보를 담당하는 부분을 호출합니다. stat 시스템 호출은 파일에 해당하는 아이 노드의 상태를 얻으려고 시도합니다. 파일 시스템은 원하는대로 아이 노드를 생성하고 조작 할 수 있습니다. 이 파일을 (kernel/cgroup.c에 정의 된 cgroup_add_file 기능을 사용하여) 항상 __kernfs_create_file에 크기가 0을 전달하는 이유 cgroup에의 FS에 의해 만들어진 내부의 모든 파일 /에서 sys/FS를/cgroup에 (그래서 즉 추가 할 때

cgroup에는 특수 파일 시스템입니다)는 파일의 실제 내용과 관련하여 항상 크기가 0입니다.

다른 부분은 cat 파일입니다. 당신이 strace cat $filename을한다면, 그건 당신이 얻을 것이다 무엇 :

open("$filename", O_RDONLY)      = 3 
read(3, "...", 131072)       = ### 

읽기 시스템 호출은 파일과 관련된 파일 작업을 사용하여 커널 파일 시스템에 가상 파일 시스템을 통해 갈 것이다, 그것은 당신에게 얻을 것이다 필요한 데이터.

Cgroup fs에는 파일에 데이터를 생성하는 기능이 있습니다. 이 tasks 파일이

{ 
     .name = "tasks", 
     .seq_start = cgroup_pidlist_start, 
     .seq_next = cgroup_pidlist_next, 
     .seq_stop = cgroup_pidlist_stop, 
     .seq_show = cgroup_pidlist_show, 
     .private = CGROUP_FILE_TASKS, 
     .write = cgroup_tasks_write, 
}, 

kernel/cgroup.c에 정의 그래서 seq_start, seq_next, seq_stop 및 seq_show 파일에 필요한 정보를 생성을 담당하는 기능이되는 방법이다. kernel/cgroups.c으로 가서 그들이하는 일을 확인하십시오.

cgroup에 작업이 있는지 여부를 확인하려는 경우 릴리스 할 때 알림을 사용하는 것이 더 쉽습니다.Documentation/cgroup-v1/cgroups.txt

에서

notify_on_release 플래그는 cgroup에 (1)을 사용하는 경우는, 다음 때마다 cgroup에 잎의 마지막 작업 (종료 또는 다른 cgroup에 부착)와 그의 마지막 자식 cgroup에 cgroup이 제거되면 커널은 해당 계층의 루트 디렉토리에있는 "release_agent"파일의 내용에 지정된 명령을 실행하여 버려진 cgroup의 경로 이름 (cgroup 파일 시스템의 마운트 지점에 대한 상대 경로)을 제공합니다. 이렇게하면 버려진 cgroup을 자동으로 제거 할 수 있습니다. 시스템 부트시 루트 cgroup의 notify_on_release의 기본값은 비활성화됩니다 (0). 생성시 다른 cgroup의 기본값은 부모의 notify_on_release 설정의 현재 값입니다. cgroup 계층의 release_agent 경로의 기본값은 비어 있습니다.