Fórum Root.cz
Hlavní témata => Software => Téma založeno: RDa 14. 09. 2025, 12:02:56
-
Asi skrvny na slunci, nebo jako fakt nechápu co se děje. Rozbilo se mi du na straně, kde je NFS klient. Na straně serveru jsou výsledky vždy ok - tak jak je předpokládám.
Mám aktualizovaný Gentoo,
$ du --version
du (GNU coreutils) 9.7
Packaged by Gentoo (9.7 (p0))
Ve složce je 30 položek (adresářů ~ subvolumes), ale zobrazí se jenom první:
$ sudo du --si -sh *
1.7T xxx
Tak zkusím pustit du jen na dvoje - taky zobrazuje jenom první:
$ sudo du --si -sh xxx yyy
43G xxx
$ sudo du --si -sh yyy xxx
13G yyy
Přidám podsložku v prvním argumentu - druhý se zobrazuje nulový:
$ sudo du --si -sh yyy/zzz xxx
13G yyy/zzz
0 xxx
Přidám dvě podsložky v prvním argumentu - druhý se zobrazuje správně:
$ sudo du --si -sh yyy/zzz/www xxx
78M yyy/zzz/www
43G xxx
Ty složky jsou každá jako individuální btrfs subvolume, ale nevolám du s --one-file-system, že by měl vůbec řešit zda jede v jenom nebo ne. Volání s --apparent-size se chová sejně. Strace nezobrazuje chybu.. načte adresář a pak se to rozhodne traversing ukončit ať už s výpisem nebo bez.
Je možné, že se něco ztratilo v překladu při té kombinaci NFS + BTRFS subvolumes?
Lze tohle nějak ladit a odkrokovat např. v kombinaci VScode + gdb, abych viděl co si to tedy myslí, že to nechce chodit?
-
Takže problém je, že NFS maskuje informaci o subvolumes v kombinaci že btrfs má neunikátní inode numbers mezi subvolumes.
Lokálně btrfs idenfikuje subvolume skrze jiný device minor, viz:
Server:
# stat xxx yyy | grep -E 'Device|Inode'
Device: 0,198 Inode: 256 Links: 1
Device: 0,201 Inode: 256 Links: 1
Klient:
# stat xxx yyy | grep -E 'Device|Inode'
Device: 0,46 Inode: 256 Links: 1
Device: 0,46 Inode: 256 Links: 1
A pak příkaz du obsahuje unique redukci skrze hash a netuší, že tyhle dvě věci jsou rozdílné (na lokálu to pozná, potože tam vstupuje i device do hashu).
Taky neexistuje žádný přepínač v du, který by hashování vyplo nebo započetlo všechny výskyty souborů. Podle zdrojáku se hash zapíná, když je uvedeno více než dva argumenty, takže pro můj příklad je funkční řešení tohle (za podmínky, že už tyto argumenty nebudou obsahovat další subvolumes):
ls | xargs -n 1 sudo du --si -sh
REF:
The Btrfs inode-number epic (part 1: the problem)
https://lwn.net/Articles/866582/
+
The Btrfs inode-number epic (part 2: solutions)
https://lwn.net/Articles/866709/
z těchto návrhů ale není v jádru akceptované nic jestli dobře vidím.
Současný stav věci je, že si mám jako ručně v /etc/exports vypsat všechny subvolumes (LOL fakt):
https://btrfs.readthedocs.io/en/latest/Interoperability.html#nfs
ale to dělat nebudu.. protože pak při použití df bude ta stovka subvolumes prasit výstup identickým výpisem o užitém/volném místu. Nevím zda má NFS auto-umount těch sub-mountů po nějaké době nečinnosti.
-
Ahoj. To je podle mě kvůli tomu, že ty btrfs subvolumy v NFS mountu mají vždycky stejný inode a společný device.
Porovnej si to přes výstup ze stat lokálně a přes NFS.
Takže to du nerozliší a ty položky, co mají stejný dev i inode, při procházení vyhazuje. Neznám teď konkrétní mechanismus, musel bych to někde hledat ve zdrojáku coreutils.. ale typicky se to dělá kvůli tomu, abys nezpracovával/nepočítal vícekrát položky, co jsou hardlinkované.
Myslím, že i proto je tam obecné doporučení ty subvolumy sdílet přes NFS zvlášť a přidat jim unikátní ID.
https://btrfs.readthedocs.io/en/latest/Interoperability.html#nfs
Ještě jinak ty du výstupy přes NFS bude chtít brát trochu s rezervou, pokud jsou v té struktuře třeba reflinky (soubory sdílí extenty), což se podle mě projeví tak, že to spočítá víckrát.
-
Aha, už sis odpověděl sám mezitím :)
-
Kralovstvi a pul princezny za patch, kde NFS bude prenaset device-minor pro subvolumes na druhej breh! :)