Bearbeiten

Bearbeiten

Wenn ich eine Datei auf einem BTRFS-Subvolume starte, erhalte ich die Hauptgerätenummer 0. Gibt es eine zuverlässige Möglichkeit, den Einhängepunkt dieses Geräts zu finden, ohne im Voraus zu wissen, dass es sich um ein BTRFS-Subvolume handelt?

zB möchte ich dies in Python tun können:

>>> 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'

(in meinem Fall ist sda1( /sys/dev/block/8:1) auf gemountet /bootund /homeist ein BTRFS-Untervolume von sda2).

Bearbeiten

Ich müsste dies tun können, ohne den Pfad der Datei zu kennen. Oben habe ich os.statals Beispiel verwendet, aber die Informationen werden tatsächlich aus einem ioctlAufruf eines Loop-Geräts abgerufen, das Folgendes zurückgibt:

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];
};

Das Feld ist vorhanden, lo_file_namehat jedoch eine maximale Länge von 63 Zeichen und kann daher nicht zuverlässig geöffnet werden. Ich weiß auch von /sys/block/loopX/loop/backing_file, dies ist jedoch nur unter Linux >= 2.6.37 verfügbar und mein Code muss unter CentOS 6 (2.6.32) ausgeführt werden.

Bearbeitung #2

Mein ultimatives Ziel hier ist es, die Sicherungsdatei für ein Loop-Gerät zuverlässig finden zu können. Sogar util-linux tut dies nicht auf Kerneln < 2.6.37, z. B.

> 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_*)

Beachten Sie, dass der Dateiname abgeschnitten ist. Dies liegt daran, dass Util-Linux die loop_info64Struktur verwendet, bei der das Feld auf 63 Zeichen begrenzt ist lo_file_name.

Was ich zuverlässig bekomme, ist die Geräte-ID und die Inode-Nummer der Sicherungsdatei. Hier stoße ich auf ein Problem, da die Sicherungsdatei auf einem Btrfs-Subvolume gespeichert ist.

Antwort1

Ich habe mir den Quellcode der GNU Core-Utils angesehen, insbesondere den dfBefehl.

Es durchläuft die Hierarchie rekursiv, bis sich die Geräte-IDs ändern. Der Punkt, an dem sich die IDs ändern, ist der Einhängepunkt.

Ich habe gerade versucht, den Einhängepunkt des Dateisystems zu finden, in dem ~/home/me/a-dir/another-dires sich befindet. Folgendes habe ich getan:

stat . #noting device IDs
while id not changes and root not hit
do
  cd ..
  stat .
done
if root not hit
then
  cd -
fi

(Dieser Code ist Pseudo-Bash, alle Bedingungen und Schleifen wurden manuell erstellt. Er dient nur dazu, das Konzept zu beweisen. Die Programmierung und Übersetzung in Python überlasse ich als Übung dem Leser.)

verwandte Informationen