/proc/self/mountinfo
마운트 지점 목록을 제공합니다. 가장 최근 순으로 정렬되어 있는 것 같아요만들어진마지막으로 설치되었습니다( mount --move
영향을 주지 않음).
그렇다면 최근에 이동했거나 생성된 설치로 인해 설치에 액세스할 수 없게 되었는지 확인할 수 있습니까?
man proc
표시되는 첫 번째 필드 /proc/self/mountinfo
는 "설치 ID"입니다. 그러나 주어진 경로에서 최상위 마운트 ID를 확인하는 방법은 설명하지 않습니다.
statvfs()
( /usr/bin/stat -f
)는 "파일 시스템 ID"라는 다른 것을 검색할 수 있습니다. 각 파일 시스템마다 고유한 값이 있는 것 같습니다... 여기서 질문한 내용에는 도움이 되지 않지만 원래 문제를 해결하는 데에도 충분할 것입니다... 파일 시스템 ID를 연관시키는 방법도 있다면 설치 경로와 모든 설치 옵션이 포함되어 있습니다. ( statvfs()
"마운트 플래그"를 반환하지만 와 달리 파일 시스템별 옵션은 반환하지 않습니다 /proc/self/mountinfo
.)
이에 대한 두 번째 관심은 불완전한 과부하 감지를 다음과 같이 보고했다는 것입니다.부족df
.
제 생각에는FSINFO_ATTR_MOUNT_INFO이 질문에 아주 잘 답할 것입니다. 그러나 이 패치는 현재 커널에서 아직 승인되지 않았습니다.
답변1
.txt 파일의 "상위 ID" 필드를 보면 설치 트리의 모든 세부 정보를 파악할 수 있을 것 같습니다 mountinfo
.
두 개의 마운트를 고려 /dir/sub
하고 /dir
. 상위 마운트 /dir/sub
가 아닌 /dir
경우 마스크해야 /
합니다 ./dir/sub
/dir
또는 경로에 두 개의 설치가 있는 경우 /
하나는 다른 하나의 상위가 되고 하위는 최상위(액세스 가능한) 설치가 됩니다.
둘이 있다면이상정확히 동일한 경로에 설치되면 이러한 설치의 최상위는 다른 설치의 상위가 아닙니다.
그러니 이것을 시도해 보세요:
마운트 경로 P를 확인하세요. 마운트 M의 자손인 마운트가 P에 있는 경우 마운트 M이 숨겨집니다(중지됨).
마운트 경로 P를 확인하세요. 마운트 M의 상위인 P에 마운트가 있는 경우 M을 해당 상위로 설정하고 2를 반복합니다.
하나 이상의 마운트 지점이 있는 경로 P의 가장 긴 하위 접두사 PRE를 확인합니다. 마운트 M의 상위 마운트 PAR을 찾으세요. 상위 마운트 PAR이 존재하지 않으면 마운트 M이 숨겨집니다(중지됨).
재귀적으로: 상위 마운트 PAR이 숨겨지면 원래 마운트도 숨겨집니다.
참고: 경로에는 /
더 작은 접두사가 없습니다. 2단계에 도달하고 경로 P가 와 같다면 /
마운트 M이 숨겨져 있지 않다는 것을 알 수 있습니다. 멈추다.
답변2
Sourcejedi의 알고리즘을 구현한 후 눈에 보이는 마운트 지점이 숨겨져 있다는 오탐지가 표시되어 큰 장애물에 부딪혔습니다. 경로, ID 및 상위 ID와 함께 이 마운트 지점 세트를 가져옵니다.
- 아이디: 2, "/"
- ID: 3, "/a/b", ParentID: 2
- ID: 4, "/a/b/c", ParentID: 3
- ID: 5, "/a/b/c/e/f", ParentID: 4
- ID: 40, "/a/b/c", ParentID: 4
- ID: 5, "/a", ParentID: 2
- ID: 50, "/a/b/c/e/f", ParentID: 5
ID: 2 "/", ID: 5, "/a" 및 ID: 50 "/a/b/c/e/f"를 가진 마운트 지점만 표시되어야 합니다. Sourcejedi 알고리즘 구현의 3단계에서 마운트 지점 ID: 50에 대해 잘못된 긍정을 얻었습니다. 이 경우 PRE와 PAR을 올바르게 가져오는 방법은 "VFS 뷰"에서 PRE가 계산된다는 점, 즉 PRE가 여러 마운트 지점과 관련될 수 있는 마운트 경로라는 가정하에 오랫동안 고민했습니다. 또한 하나의 PRE는 다른 계층의 마운트 지점만 참조할 수 있으며 이 조합으로 인해 3단계에서 오류가 발생할 수 있습니다.
Linux 커널의 VFS는 루트에서 시작하여 VFS 노드를 따라가는 경로를 inode로 확인한다는 점을 고려하세요."아래에"따라서 마운트 지점이 숨겨져 있는지 확인하기 위해 동일한 작업을 수행하는 것이 (알아내려고 시도하는 것보다) 더 안전한 옵션일 수 있습니다.위로문제가 있는 장착 지점부터 시작하여 계층 구조). 단점은 특정 마운트 지점이 실제로 오버마운트/숨겨졌는지 안전하게 결정하기 전에 전체 마운트 지점 트리에 대한 오버마운트를 결정해야 한다는 것입니다.
내 거구현(Golang)위의 테스트 사례는 다음과 같으며 기본적으로 다음과 같이 성공적으로 작동합니다.
- 마운트 경로 "/"의 마운트 지점에서 시작:
- 현재 마운트 지점의 하위 항목 중 하나의 경로 P(child(MP))가 현재 마운트 지점의 경로 P(MP)와 동일한 "내부" 오버마운트를 확인합니다.
- 예:현재 마운트 지점(하위 마운트 지점과 함께 반복적으로)의 모든 하위 마운트 지점을 숨김으로 표시합니다.현재 마운트 지점을 넘어서는 하위 마운트 지점은 제외. 그런 다음 다시 수행하기 전에 오버마운트의 하위 마운트 지점을 재귀적으로 확인하십시오.
- 아니요:계속하다
- 경로를 비교하여 하위 항목이 다른 하위 항목을 초과하는지 확인합니다. ISPREFIX(P(ith-child(MP)),P(jth-child(MP))):
- 예:jth-child(MP)와 그 모든 것(손자)을 숨김(오버로드)으로 재귀적으로 표시합니다.
- 아니요:계속하다.
- 숨겨지지 않은(오버로드된) 모든 하위 항목(MP)의 경우: 이 알고리즘을 사용하여 재귀적으로 확인합니다.
- 현재 마운트 지점의 하위 항목 중 하나의 경로 P(child(MP))가 현재 마운트 지점의 경로 P(MP)와 동일한 "내부" 오버마운트를 확인합니다.
연결 구현에는 마운트 지점 ID를 기반으로 마운트 지점의 링크 트리를 구축하고 마운트 경로 길이에 따라 하위 마운트 지점을 정렬하는 등 몇 가지 가벼운 최적화가 있습니다(!). 예를 들어, 첫 번째 자식 마운트 지점(있는 경우)만 살펴봄으로써 부모 이외의 자식 마운트 지점에 대한 확인을 단순화할 수 있습니다. 또한 서브마운트 지점 세트에서 O² 접두사 오버로드 검색을 절반으로 줄였습니다. 이는 O²가 수행하는 것에 비해 많은 이점을 얻지 못하는 것으로 인정됩니다.
답변3
액세스 권한이 있으면 chroot
해킹이 있는 것입니다.최신 커널에서 작동. 적어도 Linux v4.17에서는 작동합니다. 쉘 친화적이지 않다고 생각하지만 Python은 괜찮습니다.
chroot
(사용자 네임스페이스에 액세스할 수 있는 경우 또는 이에 상응하는 기능을 사용하여 다음 기능을 얻을 수 있습니다 unshare -rm --propagation slave
.)
# mount --bind / /mnt
# mount --make-slave /mnt # don't propagate submounts back to /
# mount --bind / /mnt
이제 과부하를 발견했으므로 조사해 보겠습니다.
# python3
...
>>> import os
>>> os.chdir("/")
>>> os.system("grep mnt proc/self/mountinfo")
231 73 253:0 / /mnt rw,relatime shared:1 - ext4 /dev/mapper/alan_dell_2016-fedora rw,seclabel
352 231 253:0 / /mnt rw,relatime shared:281 - ext4 /dev/mapper/alan_dell_2016-fedora rw,seclabel
0
>>> os.chroot("/mnt")
>>> os.system("cat proc/self/mountinfo")
352 231 253:0 / / rw,relatime shared:281 - ext4 /dev/mapper/alan_dell_2016-fedora rw,seclabel
0
/mnt
이 결과는 마운트된 액세스 가능한 파일 시스템 (마운트 ID 352 등의 파일 시스템)이 있음을 나타냅니다 .