mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 10:52:22 +00:00
/api/storage now runs a single `zpool status -j --json-int -P` (OpenZFS 2.3+) for all pools and returns, per pool: - top-level vdevs with type, raidz/draid parity, class (data, special, dedup, log, cache, spare), state and read/write/checksum errors - member devices with path, resolved base disk, state, error counters, slow I/Os, and the spare-N/replacing-N they sit under while swapping - scrub/resilver status (progress only while running), the pool's status/action text and data-error count - fragmentation, capacity and dedup ratio from `zpool list` This replaces the per-pool `zpool status` text loop whose result (zfs_disks) was never used. Member paths (by-id, by-partlabel, wwn) are resolved to base disks via sysfs rather than an lsblk call per device. On ZFS without `-j`, pools report details_available: false and the UI falls back to the existing basic card. The ZFS pool card shows a layout summary (e.g. "RAIDZ2 | 5 disks | Scrub finished ...") and opens a details dialog with the vdev tree, per-device error counts, scrub/resilver progress, and links from each member disk to its disk details dialog. Tested against `zpool status -j` output from PVE 9 / OpenZFS 2.4.4: mirror, raidz2, striped mirrors, single-disk pool, and a file-backed degraded raidz1 with log, cache and spare devices. Tests cover the `zpool status -j` -> Storage view shape against real output from PVE 9 / OpenZFS 2.4.4 hosts (serials and WWNs replaced): mirror, raidz2, single-disk pool, slow I/Os, and a degraded raidz1 with log, cache and spare devices; plus a synthetic resilver with a spare swapping in. Member path -> base disk resolution is tested against a stubbed sysfs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
141 lines
3.5 KiB
JSON
141 lines
3.5 KiB
JSON
{
|
|
"output_version": {
|
|
"command": "zpool status",
|
|
"vers_major": 0,
|
|
"vers_minor": 1
|
|
},
|
|
"pools": {
|
|
"pmx-test": {
|
|
"name": "pmx-test",
|
|
"state": "DEGRADED",
|
|
"txg": 8,
|
|
"spa_version": 5000,
|
|
"zpl_version": 5,
|
|
"status": "One or more devices has been taken offline by the administrator.\n\tSufficient replicas exist for the pool to continue functioning in a\n\tdegraded state.\n",
|
|
"action": "Online the device using 'zpool online' or replace the device with\n\t'zpool replace'.\n",
|
|
"vdevs": {
|
|
"pmx-test": {
|
|
"name": "pmx-test",
|
|
"vdev_type": "root",
|
|
"class": "normal",
|
|
"state": "DEGRADED",
|
|
"alloc_space": 265216,
|
|
"total_space": 738197504,
|
|
"def_space": 491651072,
|
|
"read_errors": 0,
|
|
"write_errors": 0,
|
|
"checksum_errors": 0,
|
|
"vdevs": {
|
|
"raidz1-0": {
|
|
"name": "raidz1-0",
|
|
"vdev_type": "raidz",
|
|
"class": "normal",
|
|
"state": "DEGRADED",
|
|
"alloc_space": 265216,
|
|
"total_space": 738197504,
|
|
"def_space": 491651072,
|
|
"rep_dev_size": 738197504,
|
|
"read_errors": 0,
|
|
"write_errors": 0,
|
|
"checksum_errors": 0,
|
|
"vdevs": {
|
|
"/root/zfstest/d1.img": {
|
|
"name": "/root/zfstest/d1.img",
|
|
"vdev_type": "file",
|
|
"path": "/root/zfstest/d1.img",
|
|
"class": "normal",
|
|
"state": "ONLINE",
|
|
"rep_dev_size": 250784427,
|
|
"phys_space": 268435456,
|
|
"read_errors": 0,
|
|
"write_errors": 0,
|
|
"checksum_errors": 0,
|
|
"slow_ios": 0,
|
|
"guid": 1001
|
|
},
|
|
"/root/zfstest/d2.img": {
|
|
"name": "/root/zfstest/d2.img",
|
|
"vdev_type": "file",
|
|
"path": "/root/zfstest/d2.img",
|
|
"class": "normal",
|
|
"state": "OFFLINE",
|
|
"rep_dev_size": 250784427,
|
|
"phys_space": 268435456,
|
|
"read_errors": 0,
|
|
"write_errors": 0,
|
|
"checksum_errors": 0,
|
|
"slow_ios": 0,
|
|
"guid": 1001
|
|
},
|
|
"/root/zfstest/d3.img": {
|
|
"name": "/root/zfstest/d3.img",
|
|
"vdev_type": "file",
|
|
"path": "/root/zfstest/d3.img",
|
|
"class": "normal",
|
|
"state": "ONLINE",
|
|
"rep_dev_size": 250784427,
|
|
"phys_space": 268435456,
|
|
"read_errors": 0,
|
|
"write_errors": 0,
|
|
"checksum_errors": 0,
|
|
"slow_ios": 0,
|
|
"guid": 1001
|
|
}
|
|
},
|
|
"guid": 1001
|
|
}
|
|
},
|
|
"guid": 1001
|
|
}
|
|
},
|
|
"logs": {
|
|
"/root/zfstest/d4.img": {
|
|
"name": "/root/zfstest/d4.img",
|
|
"vdev_type": "file",
|
|
"path": "/root/zfstest/d4.img",
|
|
"class": "log",
|
|
"state": "ONLINE",
|
|
"total_space": 251658240,
|
|
"def_space": 251658240,
|
|
"rep_dev_size": 256376832,
|
|
"phys_space": 268435456,
|
|
"read_errors": 0,
|
|
"write_errors": 0,
|
|
"checksum_errors": 0,
|
|
"slow_ios": 0,
|
|
"guid": 1001
|
|
}
|
|
},
|
|
"l2cache": {
|
|
"/root/zfstest/d5.img": {
|
|
"name": "/root/zfstest/d5.img",
|
|
"vdev_type": "file",
|
|
"path": "/root/zfstest/d5.img",
|
|
"class": "l2cache",
|
|
"state": "ONLINE",
|
|
"total_space": 263716352,
|
|
"rep_dev_size": 268435456,
|
|
"phys_space": 268435456,
|
|
"read_errors": 0,
|
|
"write_errors": 0,
|
|
"checksum_errors": 0,
|
|
"slow_ios": 0,
|
|
"guid": 1001
|
|
}
|
|
},
|
|
"spares": {
|
|
"/root/zfstest/d6.img": {
|
|
"name": "/root/zfstest/d6.img",
|
|
"vdev_type": "file",
|
|
"path": "/root/zfstest/d6.img",
|
|
"class": "spare",
|
|
"state": "AVAIL",
|
|
"guid": 1001
|
|
}
|
|
},
|
|
"error_count": 0,
|
|
"pool_guid": 1000
|
|
}
|
|
}
|
|
}
|