Spike (read-only probe, tools/physdisk_probe.py): the agent-side walk (partition -> disk, dm/LVM slaves, loop -> backing file) names the right physical disk for one-disk boxes, two disks, two partitions of one disk and a pass-through USB bridge; inside a VM (Tester 1) every disk is "unknown". Today's agent lists whole disks only and calls an empty partition table "data-bearing"; the controller's Tier-2 "different disk" is st_dev. sys_drive is a folder of mp0 (backup=1), so the design gives one-disk boxes a separate internal data place outside the whole-guest copy instead. Draft only; waits on the operator's rulings D1-D6 (16 section 12). 07 section 6.1's stale mp1 cell corrected. Register 163 -> 169. Scratch loop disk and Tester 1 scratch disk removed. Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
Spike — can the agent name the physical disk under every storage place? (2026-10-15)
For architecture/16-storage-physical-identity.md (draft). Method: tools/physdisk_probe.py — read-only, run as root
on each Proxmox host. It follows the block chain down to whole disks — partition → parent (/sys/class/block/<p>/partition,
the same as lsblk PKNAME), device-mapper / LVM thin → /sys/class/block/<dm>/slaves/* recursively, loop →
loop/backing_file → the filesystem that holds the file — and reads each disk's ID_WWN, ID_SERIAL_SHORT, ID_BUS,
vendor and model from udev, plus systemd-detect-virt. tools/summarize.py prints the tables. The agent already
has most of this chain (role.go walkSlaves/physicalDisksOf, hostread.go parentDisk); it lacks the loop step
and a per-place report.
Results
| # | Case | Where | The probe's answer | Truth | Right? | Evidence |
|---|---|---|---|---|---|---|
| 1 | One disk: host root, local, the thin pool, guest rootfs and mp0 (sys_drive is a folder of mp0) |
N100 | all → wwn:0x5000000123456f1f (AirDisk 512 GB SSD), proven |
one SATA SSD | yes | B-n100.txt |
| 1b | The same on demo-hp | demo-hp | all system places → wwn:0x5001b448b60a9d6e (SanDisk 128 GB) |
one SSD | yes | B-demo-hp.txt |
| 2 | Two disks: system + enrolled data drive | demo-hp, N100 | system → SanDisk / AirDisk; /mnt/felhom-drives/hdd_1 → Toshiba NVMe (eui…46c07b) / Toshiba MQ04 on USB (0x5000039ddb108568) |
two disks each | yes | B-demo-hp.txt, B-n100.txt |
| 3 | One disk, two partitions, two places | demo-hp, a 4 GB scratch file as a loop disk, p1 and p2 ext4, mounted |
both → the NVMe that holds the file, via loop2pN → loop2 → file on nvme0n1 |
the same disk | yes (after a probe fix: the partition step must run before the loop step) | B-case3-loop.* |
| 4a | A USB enclosure that passes the disk's identity | N100's backup drive | ID_BUS=ata, real model, serial 65NOP3HDT, WWN; ID_USB_DRIVER=usb-storage |
the real Toshiba disk | yes | B-n100.txt |
| 4b | A USB enclosure that hides or fakes the serial | — | not measured — no such device at hand, none in earlier evidence (searched documentation/, agent, controller) |
— | — | R-1077 |
| 4c | A cheap SSD with a generic WWN | N100 system SSD | ID_WWN=0x5000000123456f1f: NAA-5 with OUI 000000 (no registered vendor) — the serial QDF922W009654S30EX looks real |
unknown whether two units share the WWN | probably weak | R-1076 |
| 5 | Inside a VM: virtual disks on the same host disk | Tester 1 (VM 341): scsi0, scsi1, scsi2 |
inside: QEMU HARDDISK, serials drive-scsi0/1/2, systemd-detect-virt=kvm → unknown |
host: all three are files on demo-hp's NVMe (B-case56-host-truth.txt) |
yes — „unknown" | B-tester1.txt, B-case56-* |
| 6 | Inside a VM: a virtual disk on a different host disk | Tester 1, scratch scsi6 (4 GB on local-lvm = demo-hp's SanDisk), hot-added and removed |
inside: QEMU HARDDISK, ID_SERIAL_SHORT=drive-scsi6 (the set serial SCRATCHSID6 shows only as ID_SCSI_SERIAL) → unknown |
host: the SanDisk | yes — „unknown" | B-case56-* |
| 7 | A network share | — (no box has one mounted now; the OMV run mounted one at /mnt/felhom-drives/omv-filmek) |
the probe classes cifs/nfs sources as network → unknown, no disk |
a disk on another machine | yes by rule (not run on a live share) | ../omv-vm-2026-10-15/B6-omv-share.txt |
The VM cases in one sentence: from inside a VM, two virtual disks on the same host disk and two on different host disks look exactly alike (same vendor, same model, serial = the hypervisor's slot name), so the agent can only say „unknown"; only the hypervisor's host knows.
What today's agent does with a partitioned disk (Tester 1, scratch sdg, read-only GET /disks/candidates)
| Disk state | Agent answer | Evidence |
|---|---|---|
| blank | initialize: /dev/sdg, data_bearing:false, mountable:false |
B-case56-agent-blank.txt |
GPT, p1 empty (no fs), p2 empty ext4 |
attach and initialize: one row /dev/sdg, fstype ext4, mount_source /dev/sdg2, data_bearing:true; p1 is not offered at all |
B-case4b-partitions-empty.txt, B-case4b-partitions.txt |
| GPT, both partitions empty | initialize only: /dev/sdg, data_bearing:true, mountable:false — the only way to use it is to wipe the whole disk |
B-case4b-partitions.txt |
So today a place is always a whole disk (or the one partition the agent picks), an empty filesystem counts as data, and a partition table alone makes the whole disk „data-bearing".
Also found while reading (code, not run)
- The controller's „same disk" test is
stat().st_dev(felhom-controller/controller/internal/system/mounts_linux.go:225-245; its own comment: „two partitions on one physical disk look "different" here"). Tier-2 target choice (internal/backup/tier2.go:83-179) and the one-copy warning (internal/backup/backup.go:1387-1410) use it. - Tester 1 today makes Tier-2 copies between
media_a/adatlemez/ … — all files on one host NVMe — and counts them as off-drive copies (case 5). R-1074. hasOffDriveTarget(backup.go:1390-1402) does not skip network paths, and a NAS is registeredSchedulable:true(internal/web/netstorage_job.go:267-273), so adding a NAS would remove the „Csak egy másolat…" warning while Tier-2 refuses a NAS (tier2.go:141-143). Read in code, not run. R-1075.sys_driveis a folder ofmp0(/var/lib/felhom,backup=1), next to Docker — not a separatemp1(all three boxes,pct config 9201;07-backup-architecture.md§7.5.1). Anything stored there rides in every whole-guest copy.
Put back
- demo-hp: the 4 GB scratch file and its loop device removed (checked:
losetup -a0 lines, file absent). A first try left them for ~1 minute (a missingpartprobe); removed at once, nothing else touched. - Tester 1: scratch
scsi6partitioned, wiped (wipefs -a,sgdisk -Z— the scratch disk only, matched by its serial before every write), hot-removed, its LVvm-341-disk-0destroyed;sdggone; VM 341 still running. - Probe files deleted from all hosts. No disk that holds anything was written. DooPlex and ep0 not touched.