APUE 라고
각 프로세스에는 절대 경로 이름을 확인하기 위한 루트 디렉터리도 있습니다. 이 루트 디렉터리는 chroot 함수를 사용하여 변경할 수 있습니다.
상대 경로명만 해결하면 된다고 생각합니다. 그래서 나는 알고 싶다
절대 경로 이름 확인은 무엇을 의미합니까?
chroot
루트 디렉토리를 사용하여 절대 경로 이름을 확인하는 방법은 무엇입니까 ? 감사해요.
답변1
모든 경로 이름을 확인해야 합니다. 분명히 프로세스는 경로 이름을 시스템 호출에 대한 인수로 커널에 전달합니다. 예를 들면 다음과 같습니다.
creat
또는open
,link
또는rename
,unlink
또는rmdir
,chmod
또는chown
,chdir
또는chroot
,execve
,
등. 다음과 같은 경로 이름을 고려해보세요.
…
a
/
b
/
c
커널이 이를 해석하는 방식은 다음과 같습니다.
(파일 시스템 어딘가에서) 시작하여 1 이라는
디렉토리를 찾으십시오 . 찾을 수 없으면 오류가 반환됩니다. 발견되면 디렉토리에서 이름이 지정된 하위 디렉토리를 검색합니다 . 찾을 수 없으면 오류가 반환됩니다. 발견되면 디렉토리에서 2 라는 디렉토리 항목을 검색합니다 . 찾을 수 없으면 오류 3 이 반환됩니다 . 발견되면 인덱스 노드가 반환됩니다.a
b
c
경로 이름의 시작 부분과 알고리즘의 첫 번째 줄에 혼동이 있다는 점에 유의하십시오. 간단합니다. 경로 이름이 슬래시로 시작하는 경우(예: "절대 경로 이름", 예: /a/b/c
), 경로 이름이 다른 것으로 시작하는 경우(예: 상대 경로 이름) 검색은 프로세스의 루트에서 시작됩니다. 예 a/b/c
), 프로세스의 현재 작업 디렉터리부터 검색이 시작됩니다.
"이것이 어떻게 이루어지나요?"라고 물을 수도 있습니다. 물론 커널은 다음을 포함하여 각 프로세스에 대한 많은 정보를 유지합니다.
- PID, PPID 및 다양한 프로세스 그룹 식별자,
- 실제적이고 유효한 저장된 UID 및 GID와 보충 GID 목록,
- 파일을 열고,
- 신호 구성,
그리고 더. 이 질문과 관련이 없기 때문에 많은 내용을 생략하겠습니다. 환경 변수는 커널에 의해 유지되지 않기 때문에 생략했습니다. 사용자 공간 프로그램에 의해 유지됩니다. 커널이 하는 일은 .NET을 통해 한 프로그램에서 다른 프로그램으로 환경 변수를 전달하는 메커니즘을 지원하는 것뿐입니다 execve
.
드라마를 위해 위 목록에서 두 가지를 생략했습니다.
- 프로세스의 루트 디렉터리
- 현재 작업 디렉토리
이는 inode에 대한 포인터입니다. 지금까지 이 과정을 마친 모든 사람이 프로세스의 현재 작업 디렉터리를 설정하는 방법을 이해하기를 바랍니다. 프로세스는 chdir
경로 이름을 인수로 전달하여 위 프로세스에 따라 경로 이름을 해석합니다(inode로 해석). 성공하면 현재 디렉터리 포인터가 인덱스 노드를 가리키도록 설정됩니다.
프로세스의 루트 디렉터리는 chroot
시스템 호출을 제외하고 동일한 방식으로 설정됩니다.
(두 경우 모두 경로 이름 인수가 다음으로 시작 /
하면 경로 이름 확인은 프로세스의 루트에서 시작됩니다.
시스템 호출 호출 시 적용. )
몇 가지 예:
- 현재 디렉터리가 다음
/home/tim
이고 프로세스 루트가 파일 시스템 루트인 경우- 방문하시면
/etc/services
받으실 수 있으며/etc/services
, - 방문하시면
.bashrc
받으실 수 있습니다/home/tim/.bashrc
.
- 방문하시면
- 이렇게 하면
chroot /filesystem/tim
(같은 이름의 디렉터리가 있고 해당 디렉터리에 액세스할 수 있으며 필요한 권한이 있다고 가정chroot
)- 방문하시면
/etc/services
받으실 수 있으며/filesystem/tim/etc/services
, - 방문하시면
/
을 받으실 수/filesystem/tim
있으니 - 만약 당신이
chroot /
, 아무것도 변하지 않을 것입니다; - 그렇게 하면 , 그렇게 하려고
chroot /filesystem/john
노력할 것입 니다 .chroot
/filesystem/tim/filesystem/john
- 방문하시면
루트 디렉토리와 현재 디렉토리는 inode에 대한 포인터로 저장되므로 시스템은 이를 "찾을" 필요가 없습니다.
__________
1 즉, 해당 모드가 디렉토리임을 나타내는 inode를 가리키는 디렉토리 항목, 즉 를 찾습니다 (i_mode & IFMT) == IFDIR
.
creat(file, mode)
open(file, O_CREAT, mode)
답변2
예를 들어, 커널이 /usr/share/man/man1/cat.1.gz
inode로 확인되면 루트에서 시작하여 /
아래로 진행 되어야 합니다 cat.1.gz
. 상대 경로 이름인 경우 현재 디렉터리에서 파일을 찾으세요.
어쩌면 현재 작업 디렉토리의 절대 경로를 얻는 방법을 생각하고 계십니까? 경로를 결정하려면 현재 디렉터리에서 시작하여 루트 디렉터리까지 모든 중간 디렉터리를 거쳐야 합니다. (그러나 파일에 대한 상대 경로(예: 시스템 호출에 대한 인수)가 주어지면 커널은 이 작업을 수행하지 않습니다 open
.)