File-Restore: Mount eines 9-TB-NTFS-Volumes schlägt fehl (ntfs3, ENOENT ohne Kernel-Meldung) – kleineres NTFS derselben VM funktioniert

ProlyX

Renowned Member
Sep 19, 2011
11
0
66
Hallo zusammen,

beim File-Restore eines Windows-Server-2019-Fileservers lässt sich das große Datenvolume nicht mounten, das Systemlaufwerk derselben VM dagegen schon.

Umgebung
  • PVE 9.2.4, proxmox-backup-file-restore 4.2.3-1, proxmox-backup-restore-image 1.0.0
  • Host-Kernel: 7.0.14-5-pve
  • Restore-Kernel 6.14.6-pbs-restore
  • Gast: Windows Server 2019, UEFI, virtio-scsi

Symptom

Code:
proxmox-file-restore list vm/<VMID>/<SNAPSHOT> drive-scsi1.img.fidx/part/2 ...
Error: mounting 'drive-scsi1.img.fidx/part/2' failed: all mounts failed or no supported file system

Dasselbe Kommando auf drive-scsi0.img.fidx/part/4 (C:, 100 GB NTFS) liefert korrekt den Verzeichnisinhalt.

Vergleich beider Volumes

Code:
                     C: (geht)      D: (geht nicht)
Größe                100 GB         9 TB
NTFS-Version         3.1            3.1
Bytes/Cluster        4096           4096
Bytes/Sektor         512            512
MFT                  476 MB         9,8 GB

Bereits ausgeschlossen
  • Kein Dirty Flag (fsutil dirty query D: meldet sauber)
  • Windows-Deduplizierung nicht installiert
  • 15 Snapshots aus verschiedenen Zeiträumen geprüft, alle identisch fehlschlagend
  • Partitionstabelle wird korrekt gelesen: list auf drive-scsi1.img.fidx/part zeigt 1 (16 MB MSR) und 2 (9663657541632 Bytes), letzteres stimmt exakt mit der Windows-Datenträgerverwaltung überein
  • PBS_FILE_RESTORE_MEM_HOTPLUG_ALLOW und PBS_FILE_RESTORE_MEM_HOTPLUG_SIZE_MB zeigen keine Wirkung, die Restore-VM startet unverändert mit -m 256M,slots=1,maxmem=768M

Reproduktion außerhalb von proxmox-file-restore

Um an die Kernel-Meldungen zu kommen, habe ich die Restore-VM manuell gestartet. Damit meine ich: QEMU direkt aufgerufen, mit demselben Kernel und demselben pbs-Blockdev wie proxmox-file-restore es tut, aber mit einem eigenen initramfs, das in eine Busybox-Shell bootet statt in den Restore-Daemon. So lässt sich der Mount von Hand absetzen und dmesg auslesen.

initramfs bauen:

Code:
mkdir -p /tmp/shim && cd /tmp/shim
cpio -idmv < /usr/lib/x86_64-linux-gnu/proxmox-backup/file-restore/initramfs.img
cp /usr/lib/x86_64-linux-gnu/proxmox-backup/file-restore/proxmox-restore-daemon .
ln -sf busybox bin/sh
mv init init.orig
find . | cpio -o -H newc > /tmp/initramfs-manual.img

VM starten – /init ist entfernt, der Kernel fällt auf /bin/sh zurück, das ist hier gewollt:

Code:
export PBS_PASSWORD='...'
export PBS_FINGERPRINT='...'

qemu-system-x86_64 \
  -serial mon:stdio -vnc none -enable-kvm \
  -kernel /usr/lib/x86_64-linux-gnu/proxmox-backup/file-restore/bzImage \
  -initrd /tmp/initramfs-manual.img \
  -append 'console=ttyS0 loglevel=7' \
  -m 4096M \
  -blockdev driver=pbs,repository=<USER>@<REALM>@<PBS-IP>:8007:<DATASTORE>,namespace=<NS>,snapshot=vm/<VMID>/<SNAPSHOT>,archive=drive-scsi1.img.fidx,read-only=on,node-name=drive1 \
  -device pci-bridge,id=bridge2,chassis_nr=2 \
  -device virtio-blk-pci,drive=drive1,serial=drive-scsi1,bus=bridge2 \
  -nographic

In der Shell:

Code:
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
/bin/busybox --install -s /bin
mkdir -p /proc /dev /sys /tmp/m
mount -t proc proc /proc
mount -t devtmpfs dev /dev
mount -t sysfs sys /sys
mount -t ntfs3 -o ro /dev/vda2 /tmp/m ; echo "exit=$?"

Ergebnis

Code:
mount: mounting /dev/vda2 on /tmp/m failed: No such file or directory
exit=255

dmesg enthält dazu keinerlei Eintrag. Dasselbe mit -o ro,nohidden und -o ro,prealloc.

Der Treiber wird aber erreicht – mit einer ungültigen Option antwortet er:

Code:
ntfs3: Unknown parameter 'nols'

Gegenprobe im selben Aufbau

Identischer Start, nur archive=drive-scsi0.img.fidx, dann mount -t ntfs3 -o ro /dev/vda4 /tmp/m: funktioniert, Verzeichnisinhalt von C: wird angezeigt. Die Testumgebung ist also tauglich.

Geometrie und Datenintegrität geprüft

Code:
# cat /sys/block/vda/vda2/start /sys/block/vda/vda2/size
32768
18874331136

Code:
# dd if=/dev/vda2 bs=512 count=1 | hexdump -C | head -6
00000000  eb 52 90 4e 54 46 53 20  20 20 20 00 02 08 00 00  |.R.NTFS    .....|
00000010  00 00 00 00 00 f8 00 00  3f 00 ff 00 00 80 00 00  |........?.......|
00000020  00 00 00 00 80 00 80 00  ff 6f ff 64 04 00 00 00  |.........o.d....|
00000030  00 00 0c 00 00 00 00 00  02 00 00 00 00 00 00 00  |................|
00000040  f6 00 00 00 01 00 00 00  3f a3 a3 8c f2 a3 8c 3e  |........?......>|
00000050  00 00 00 00 fa 33 c0 8e  d0 bc 00 7c fb 68 c0 07  |.....3.....|.h..|

Bytes/Sektor 512, Sektoren/Cluster 8, hidden_sectors 32768 (passt zum Partitionsstart), Gesamtsektoren 18874331135, MFT-Start-LCN 0xC0000, Volume-Seriennummer 3e8ca3f28ca3a33f – identisch mit fsutil fsinfo ntfsinfo D: unter Windows.

Code:
# dd if=/dev/vda2 bs=4096 skip=786432 count=1 | hexdump -C | head -3
00000000  46 49 4c 45 30 00 03 00  17 fe 6e d8 04 00 00 00  |FILE0.....n.....|

MFT liegt an der erwarteten Position. Lesezugriffe über die gesamte Volumelänge funktionieren: bei 2 TiB liegen Daten, bei 8 TB Nullen (unbelegter Bereich).

Speicher scheidet als Ursache aus, der Mount scheitert auch mit 4 GB RAM.

Frage

Gibt es eine bekannte Grenze von ntfs3 bei großen Volumes bzw. großer MFT? Und ist der stille ENOENT-Pfad im Treiber bekannt? Über Hinweise zur weiteren Eingrenzung würde ich mich freuen.
 
Saubere Vorarbeit, mehr Eingrenzung geht kaum. Bei deinen Zahlen: 18874331135 Sektoren bei 8 Sektoren/Cluster sind ~2,36 Mrd. Cluster, also knapp über 2^31. Mit 4k-Clustern liegt diese Grenze genau bei 8 TiB, und dein C: ist mit ~26 Mio. Clustern meilenweit drunter. Spontan würde ich da auf ein signed int im Cluster-Handling tippen, der ENOENT ohne dmesg-Ausgabe spricht eher für einen frühen Bail-out beim Aufbau der Bitmap/MFT-Runlist. Sicher bin ich mir nicht, aber dass du genau über der Schwelle liegst, ist verdächtig.

Das kannst du billig gegentesten, komplett ohne PBS: Sparse-File anlegen, mkntfs -Q -F -c 4096 drauf, per losetup mounten. Einmal mit 7,9 TiB, einmal mit 8,5 TiB. Wenn nur das große scheitert, hast du einen minimalen Reproducer für die ntfs3-Leute, und mit deinem Backup hat das nichts zu tun. Da du den manuellen Aufbau eh schon stehen hast: tausch in dem QEMU-Aufruf mal das bzImage gegen einen aktuellen Kernel (virtio-blk und ntfs3 builtin oder als Modul ins initramfs), am ntfs3 wurde seit 6.14 einiges gefixt. Wäre gut zu wissen, ob es mit 6.17+ läuft.

Zum Rankommen an die Daten in der Zwischenzeit: proxmox-backup-client map auf das fidx-Archiv gibt dir ein Blockdevice auf dem Host, da kannst du die Partition mit ntfs-3g statt ntfs3 mounten. Der FUSE-Treiber ist langsamer, hat aber diese 32-Bit-Probleme nicht, und in der Restore-VM ist er halt nicht drin.
 
  • Like
Reactions: UdoB
Saubere Vorarbeit, mehr Eingrenzung geht kaum. Bei deinen Zahlen: 18874331135 Sektoren bei 8 Sektoren/Cluster sind ~2,36 Mrd. Cluster, also knapp über 2^31. Mit 4k-Clustern liegt diese Grenze genau bei 8 TiB, und dein C: ist mit ~26 Mio. Clustern meilenweit drunter. Spontan würde ich da auf ein signed int im Cluster-Handling tippen, der ENOENT ohne dmesg-Ausgabe spricht eher für einen frühen Bail-out beim Aufbau der Bitmap/MFT-Runlist. Sicher bin ich mir nicht, aber dass du genau über der Schwelle liegst, ist verdächtig.

Das kannst du billig gegentesten, komplett ohne PBS: Sparse-File anlegen, mkntfs -Q -F -c 4096 drauf, per losetup mounten. Einmal mit 7,9 TiB, einmal mit 8,5 TiB. Wenn nur das große scheitert, hast du einen minimalen Reproducer für die ntfs3-Leute, und mit deinem Backup hat das nichts zu tun. Da du den manuellen Aufbau eh schon stehen hast: tausch in dem QEMU-Aufruf mal das bzImage gegen einen aktuellen Kernel (virtio-blk und ntfs3 builtin oder als Modul ins initramfs), am ntfs3 wurde seit 6.14 einiges gefixt. Wäre gut zu wissen, ob es mit 6.17+ läuft.

Zum Rankommen an die Daten in der Zwischenzeit: proxmox-backup-client map auf das fidx-Archiv gibt dir ein Blockdevice auf dem Host, da kannst du die Partition mit ntfs-3g statt ntfs3 mounten. Der FUSE-Treiber ist langsamer, hat aber diese 32-Bit-Probleme nicht, und in der Restore-VM ist er halt nicht drin.

Danke, den map-Weg kannte ich nicht. Funktioniert bei mir auf Anhieb, Mount mit ntfs-3g auf dem Host klappt – damit komme ich an die Daten. Das löst mein akutes Problem, vielen Dank dafür.

Reproducer-Test
Deinen Vorschlag habe ich umgesetzt: zwei Sparse-Images, 7900G und 8500G, jeweils mkntfs -Q -F -c 4096, im selben manuellen QEMU-Aufbau mit dem 6.14.6-Restore-Kernel und -drive file=...,format=raw,if=virtio.

Code:
mount -t ntfs3 -o ro /dev/vda /tmp/m ; echo "exit=$?"exit=0

Beide mounten sauber, also auch das Image mit ~2,23 Mrd. Clustern, das über 2^31 liegt. Zumindest bei einem frisch angelegten, leeren Volume scheint die reine Größe damit nicht der Auslöser zu sein. Ob das auf ein gefülltes Volume übertragbar ist, kann ich daraus natürlich nicht ableiten.

Was als Unterschied übrig bleibt

Ein leeres mkntfs-Volume hat eine sehr kleine MFT, unser produktives Volume liegt bei 9,8 GB. Insofern würde ich vermuten, dass eher die MFT-Struktur eine Rolle spielt als die Volumegröße – sicher bin ich mir nicht.

In die Richtung geht auch der Upstream-Fix "ntfs3: fix mount failure on volumes with fragmented MFT bitmap" (Ruslan Elishev, März 2026, in den ntfs3-Änderungen für Linux 7.1): Dort scheitert ntfs_fill_super() mit -ENOENT in wnd_init(), weil wnd_init() vor ni_load_all_mi() läuft und die Runlist der MFT-Bitmap dann noch unvollständig ist, sobald sie in Extent-Records überläuft. Das Fehlerbild passt, insbesondere auch das Fehlen jeder dmesg-Ausgabe. Belegen kann ich es aber nicht – ob die MFT auf unserem Volume tatsächlich fragmentiert ist, konnte ich nicht verifizieren, defrag /A bricht auf dem SAN-Volume ab.

https://lkml.org/lkml/2026/3/28/405

Test mit neuerem Kernel

Deinen zweiten Vorschlag habe ich ebenfalls probiert. Ein 6.17+ steht mir nicht zur Verfügung, in den Repos ist proxmox-kernel-7.0.14-16-pve die aktuellste Version. Damit gebootet (virtio-blk ist builtin, ntfs3.ko habe ich ins initramfs gelegt und mit insmod geladen):

Code:
insmod /ntfs3.ko
cat /proc/filesystems | grep ntfs
        ntfs
        ntfs3
mount -t ntfs3 -o ro /dev/vda2 /tmp/m ; echo "exit=$?"
exit=255
mount -t ntfs -o ro /dev/vda2 /tmp/m ; echo "exit=$?"
exit=255

Gleiches Ergebnis, unter beiden Treibernamen. Gegenprobe mit C: (drive-scsi0.img.fidx, /dev/vda4) im selben Aufbau: mountet, Verzeichnisinhalt erscheint. Der Aufbau taugt also.
 
Dann zieh ich meinen 2^31-Verdacht zurück, dein Reproducer widerlegt das sauber. Der Bitmap-Bug passt besser zum stillen ENOENT.

Bei deinem Kerneltest ist nur der Haken: der 7.0.14-16 hat den Fix gar nicht drin, der hängt ja an 7.1 und in die 7.0er-Reihe wird sowas nicht zurückportiert. Dein Test sagt also nur "ohne Patch kaputt", was zu erwarten war. Wenn du es wirklich belegen willst, bleibt nur den einen Commit draufzupatchen und nur das ntfs3-Modul gegen die Header zu bauen, das ist überschaubar. Ich hätte da auch Lust drauf, ehrlich gesagt.

MFT-Fragmentierung kannst du übrigens ohne Windows und ohne defrag prüfen, du hast das Device per map ja eh schon liegen: ntfsinfo -i 0 -v /dev/mapper/... aus den ntfsprogs. Taucht bei $MFT eine $ATTRIBUTE_LIST auf bzw. siehst du mehrere Extent-Records, ist die Bedingung aus dem Patch erfüllt. Bei 9,8 GB MFT auf nem Fileserver würde mich das null wundern. Wär interessant ob das zusammenpasst.
 
Danke, den map-Weg kannte ich nicht. Funktioniert bei mir auf Anhieb, Mount mit ntfs-3g auf dem Host klappt – damit komme ich an die Daten. Das löst mein akutes Problem, vielen Dank dafür.

Reproducer-Test
Deinen Vorschlag habe ich umgesetzt: zwei Sparse-Images, 7900G und 8500G, jeweils mkntfs -Q -F -c 4096, im selben manuellen QEMU-Aufbau mit dem 6.14.6-Restore-Kernel und -drive file=...,format=raw,if=virtio.

Code:
mount -t ntfs3 -o ro /dev/vda /tmp/m ; echo "exit=$?"exit=0

Beide mounten sauber, also auch das Image mit ~2,23 Mrd. Clustern, das über 2^31 liegt. Zumindest bei einem frisch angelegten, leeren Volume scheint die reine Größe damit nicht der Auslöser zu sein. Ob das auf ein gefülltes Volume übertragbar ist, kann ich daraus natürlich nicht ableiten.

Was als Unterschied übrig bleibt

Ein leeres mkntfs-Volume hat eine sehr kleine MFT, unser produktives Volume liegt bei 9,8 GB. Insofern würde ich vermuten, dass eher die MFT-Struktur eine Rolle spielt als die Volumegröße – sicher bin ich mir nicht.

In die Richtung geht auch der Upstream-Fix "ntfs3: fix mount failure on volumes with fragmented MFT bitmap" (Ruslan Elishev, März 2026, in den ntfs3-Änderungen für Linux 7.1): Dort scheitert ntfs_fill_super() mit -ENOENT in wnd_init(), weil wnd_init() vor ni_load_all_mi() läuft und die Runlist der MFT-Bitmap dann noch unvollständig ist, sobald sie in Extent-Records überläuft. Das Fehlerbild passt, insbesondere auch das Fehlen jeder dmesg-Ausgabe. Belegen kann ich es aber nicht – ob die MFT auf unserem Volume tatsächlich fragmentiert ist, konnte ich nicht verifizieren, defrag /A bricht auf dem SAN-Volume ab.

https://lkml.org/lkml/2026/3/28/405

Test mit neuerem Kernel

Deinen zweiten Vorschlag habe ich ebenfalls probiert. Ein 6.17+ steht mir nicht zur Verfügung, in den Repos ist proxmox-kernel-7.0.14-16-pve die aktuellste Version. Damit gebootet (virtio-blk ist builtin, ntfs3.ko habe ich ins initramfs gelegt und mit insmod geladen):

Code:
insmod /ntfs3.ko
cat /proc/filesystems | grep ntfs
        ntfs
        ntfs3
mount -t ntfs3 -o ro /dev/vda2 /tmp/m ; echo "exit=$?"
exit=255
mount -t ntfs -o ro /dev/vda2 /tmp/m ; echo "exit=$?"
exit=255

Gleiches Ergebnis, unter beiden Treibernamen. Gegenprobe mit C: (drive-scsi0.img.fidx, /dev/vda4) im selben Aufbau: mountet, Verzeichnisinhalt erscheint. Der Aufbau taugt also.


Danke. Damit ließ sich beides klären.

1. Die Bedingung aus dem Patch ist bei uns erfüllt

ntfsinfo -i 0 -v auf dem gemappten Device zeigt bei der $MFT eine $ATTRIBUTE_LIST mit zwei $BITMAP-Einträgen:

Code:
Attribute type: 0xb0   Starting VCN: 0     MFT reference: 16
Attribute type: 0xb0   Starting VCN: 175   MFT reference: 17

Record 16 endet bei VCN 174 mit <RL_NOT_MAPPED>, Record 17 setzt bei 175 fort. Die Runlist der MFT-Bitmap läuft also in einen Extent-Record über – genau die Konstellation aus der Patch-Beschreibung. Die MFT ist insgesamt stark fragmentiert (Total runs: 358).

Interessant dabei: Das Volume stammt von Juli 2026, ist also kein "long-used Windows system".

2. Mit Kernel 7.1 mountet es

Zum Gegenbeweis einen Vanilla-7.1 gebaut (make defconfig plus NTFS3_FS, BLK_DEV_VIRTIO_BLK und VIRTIO_PCI builtin, MODULES aus) und im selben manuellen Aufbau anstelle des Restore-Kernels gebootet – gleiches initramfs, gleiches pbs-Blockdev, gleicher Snapshot, nur rdinit=/bin/sh zusätzlich im append:

Code:
mount -t ntfs3 -o ro /dev/vda2 /tmp/m ; echo "exit=$?"
exit=0
...


Fazit

File-Restore ist auf Windows-Fileservern mit großer, fragmentierter MFT derzeit nicht nutzbar – also ausgerechnet dort, wo das Zurückholen einzelner Dateien am häufigsten gebraucht wird.

Bis dahin ist der map-Weg mit ntfs-3g auf dem Host der Workaround.
 
Last edited:
Das ist ein lupenreiner Reproducer mit Gegenbeweis, schade wenn das im Thread untergeht. Mach dafür einen Bug auf https://bugzilla.proxmox.com auf. Der Kernel im proxmox-backup-restore-image hängt an einer eigenen, gepinnten Version und wandert nicht automatisch mit, wenn 7.1 irgendwann im Host-Repo landet. Selbst wenn der Fix upstream drin ist, bleibt der File-Restore kaputt, bis jemand das Restore-Image nachzieht. Häng die Bug-Nummer hier rein wenn du ihn aufmachst, dann häng ich mich dran.
 
Das ist ein lupenreiner Reproducer mit Gegenbeweis, schade wenn das im Thread untergeht. Mach dafür einen Bug auf https://bugzilla.proxmox.com auf. Der Kernel im proxmox-backup-restore-image hängt an einer eigenen, gepinnten Version und wandert nicht automatisch mit, wenn 7.1 irgendwann im Host-Repo landet. Selbst wenn der Fix upstream drin ist, bleibt der File-Restore kaputt, bis jemand das Restore-Image nachzieht. Häng die Bug-Nummer hier rein wenn du ihn aufmachst, dann häng ich mich dran.

Auf deinen Vorschlag hin hab ich es im Bugzilla eingetragen, mit allen Daten aus diesem Thread:

https://bugzilla.proxmox.com/show_bug.cgi?id=8058

Danke nochmal für die Hinweise.