編輯

編輯

當我統計 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,並且/home是 的 btrfs 子卷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_*)

請注意,檔案名稱被截斷,這是因為 util-linux 使用的loop_info64結構在欄位上有 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

(這段程式碼是偽 bash,所有條件和循環都是手動完成的。它只是為了證明這個概念。我將把程式設計和翻譯留給 python 作為讀者的練習。)

相關內容