btrfs 하위 볼륨의 파일 수를 계산하면 주요 장치 번호가 로 표시됩니다 0
. 장치가 btrfs 하위 볼륨인지 미리 알지 않고도 장치의 마운트 지점을 찾을 수 있는 안정적인 방법이 있습니까?
예를 들어, 저는 Python에서 다음과 같은 작업을 수행하고 싶습니다.
>>> st = os.stat('a file')
>>> os.major(st.st_dev)
0
>>> os.minor(st.st_dev)
38
>>> os.path.exists('/sys/dev/block/0:38')
False
>>> magic_method_that_gets_mount_point(0, 38)
'/home'
>>> magic_method_that_gets_mount_point(8, 1)
'/boot'
(제 경우에는 sda1
( /sys/dev/block/8:1
)가 에 마운트되어 있고 /boot
btrfs /home
하위 볼륨입니다 sda2
.)
편집하다
파일 경로를 몰라도 이 작업을 수행할 수 있어야 합니다. 위의 예를 사용했지만 os.stat
정보는 실제로 ioctl
다음을 반환하는 루프 장치를 호출하여 검색됩니다.
struct loop_info64 {
uint64_t lo_device;
uint64_t lo_inode;
uint64_t lo_rdevice;
uint64_t lo_offset;
uint64_t lo_sizelimit;
uint32_t lo_number;
uint32_t lo_encrypt_type;
uint32_t lo_encrypt_key_size;
uint32_t lo_flags;
uint8_t lo_file_name[64];
uint8_t lo_crypt_name[64];
uint8_t lo_encrypt_key[32];
uint64_t lo_init[2];
};
이 필드가 있지만 lo_file_name
최대 길이가 63자이므로 안정적으로 열 수 없습니다. 나도 그것을 알고 있지만 /sys/block/loopX/loop/backing_file
이것은 Linux >= 2.6.37에서만 사용할 수 있으며 내 코드는 CentOS 6(2.6.32)에서 실행되어야 합니다.
편집 #2
나의 최종 목표는 루프 장치에 대한 지원 파일을 안정적으로 찾는 것입니다. 심지어 util-linux도 2.6.37 미만의 커널에서는 이 작업을 수행하지 않습니다.
> dd if=/dev/urandom bs=4096 count=256 of=/root/a_really_really_really_really_really_really_really_long_file_name.img
256+0 records in
256+0 records out
1048576 bytes (1.0 MB) copied, 0.137397 s, 7.6 MB/s
> LD=`losetup -f --show /root/a_really_really_really_really_really_really_really_long_file_name.img`
> losetup $LD
/dev/loop1: [fd00]:922372 (/root/a_really_really_really_really_really_really_really_long_*)
loop_info64
util-linux에서 사용하는 구조에는 필드에 63자 제한이 있으므로 파일 이름이 잘립니다 lo_file_name
.
내가 확실하게 얻을 수 있는 것은 장치 ID와 백업 파일의 inode 번호입니다. 백업 파일이 btrfs 하위 볼륨에 저장되기 때문에 이것이 제가 벽에 부딪힌 부분입니다.
답변1
나는 Gnu core-utils 소스 코드, 특히 df
명령을 살펴보았습니다.
장치 ID가 변경될 때까지 계층 구조를 반복적으로 아래로 이동합니다. ID가 변경되는 지점이 마운트 지점입니다.
나는 그것이 있는 파일 시스템의 마운트 지점을 찾으려고 노력하고 있습니다 ~/home/me/a-dir/another-dir
. 나는 그랬다:
stat . #noting device IDs
while id not changes and root not hit
do
cd ..
stat .
done
if root not hit
then
cd -
fi
(이 코드는 의사 배시(pseudo-bash)이며, 모든 조건과 루프는 수동으로 수행됩니다. 개념을 보여주기 위한 것일 뿐입니다. 프로그래밍과 번역은 독자의 연습으로 Python에 맡기겠습니다.)