-
Notifications
You must be signed in to change notification settings - Fork 0
Fix error for non slot devices. #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -73,6 +73,17 @@ function zfs_drivemap_lookup() | |
| $lookup[$value] = $bay_id; | ||
| $lookup[basename($value)] = $bay_id; | ||
| } | ||
|
|
||
| $storage_label = $slot['storage-label'] ?? ''; | ||
| if (is_string($storage_label) && preg_match('/^disk([0-9]+)$/', $storage_label, $match)) { | ||
| $lookup[$storage_label] = $bay_id; | ||
| $lookup['md' . $match[1]] = $bay_id; | ||
| $lookup['md' . $match[1] . 'p1'] = $bay_id; | ||
| $lookup['/dev/md' . $match[1]] = $bay_id; | ||
| $lookup['/dev/md' . $match[1] . 'p1'] = $bay_id; | ||
| $lookup['/dev/mapper/md' . $match[1]] = $bay_id; | ||
| $lookup['/dev/mapper/md' . $match[1] . 'p1'] = $bay_id; | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -401,54 +412,10 @@ function zpool_status_parse($status_obj, $key, $pool_name, $disk_lookup = []) | |
|
|
||
| function verify_zfs_device_format($status_obj, $pool_name, $disk_lookup = []) | ||
| { | ||
| // Frontend drive-to-bay mapping relies on "card-drive" aliases (e.g. 1-1). | ||
| // Emit warnings when pool members do not follow that convention. | ||
| // Non-bay devices such as boot, flash, and standalone NVMe pools are valid | ||
| // ZFS members, but there is no slot to annotate in the drivemap UI. | ||
| // Keep them in the pool list and skip user-facing warnings. | ||
| $alert = []; | ||
| if (!isset($status_obj[$pool_name])) { | ||
| return $alert; | ||
| } | ||
|
|
||
| $default_pattern = '/^\t (\d+-\d+)(?:-part[0-9])?\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*/m'; | ||
| $unsupported_pattern = '/^\t (\S+)(?:-part[0-9])?\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*/m'; | ||
|
|
||
| preg_match_all($default_pattern, $status_obj[$pool_name], $default_matches, PREG_SET_ORDER); | ||
| preg_match_all($unsupported_pattern, $status_obj[$pool_name], $unsupported_matches, PREG_SET_ORDER); | ||
|
|
||
| $default_disks = []; | ||
| foreach ($default_matches as $match) { | ||
| $default_disks[] = $match[1]; | ||
| } | ||
|
|
||
| $unsupported_disks = []; | ||
| foreach ($unsupported_matches as $match) { | ||
| $unsupported_disks[] = $match[1]; | ||
| } | ||
|
|
||
| if (count($unsupported_disks) > count($default_disks)) { | ||
| $filtered = array_values(array_diff($unsupported_disks, $default_disks)); | ||
| $filtered = array_values(array_filter($filtered, function ($name) { | ||
| return !preg_match('/^(\d+-\d+)(?:-part[0-9])/', $name); | ||
| })); | ||
| $filtered = array_values(array_filter($filtered, function ($name) use ($disk_lookup) { | ||
| return !preg_match('/^\d+-\d+$/', canonical_zfs_disk_name($name, $disk_lookup)); | ||
| })); | ||
|
|
||
| if (!$filtered) { | ||
| return $alert; | ||
| } | ||
|
|
||
| $alert[] = "ZFS status displayed by this module for zpool '$pool_name' may be incomplete.\n\n"; | ||
| $alert[] = "This module can only display zfs status information for devices that are created using a device alias.\n\n"; | ||
| $alert[] = "This can be done using the 45Drives cockpit-zfs-manager package:\nhttps://github.com/45Drives/cockpit-zfs-manager/releases/\n\n"; | ||
| if ($filtered) { | ||
| $alert[] = "The following zfs devices do not conform:\n"; | ||
| foreach ($filtered as $disk) { | ||
| $alert[] = "\t $disk\n"; | ||
| } | ||
| } | ||
| $alert[] = "\n"; | ||
| } | ||
|
|
||
| return $alert; | ||
|
Comment on lines
+415
to
419
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Line 415-419 returns an empty array unconditionally, so genuinely malformed or unexpectedly mapped members also lose diagnostics. That widens behavior beyond the stated non-slot suppression and weakens the API’s warning signal. 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
|
|
@@ -624,6 +591,9 @@ function generate_zfs_info() | |
| } | ||
| foreach ($pool['vdevs'] as $vdev) { | ||
| foreach ($vdev['disks'] as $disk) { | ||
| if (!isset($disk['name']) || !preg_match('/^\d+-\d+$/', $disk['name'])) { | ||
| continue; | ||
| } | ||
| $disk_entries[$disk['name']] = [ | ||
| 'zpool_name' => $pool['name'], | ||
| 'zpool_used' => $pool['used'] ?? '-', | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| disk1 10G 90G 10G /mnt/disk1 | ||
| zmirror 20G 180G 20G /mnt/zmirror |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| capacity operations bandwidth | ||
| pool alloc free read write read write | ||
| ------------------------------------- ----- ----- ----- ----- ----- ----- | ||
| disk1 10G 90G 1 2 10M 20M | ||
| /dev/mapper/md1p1 10G 90G 1 2 10M 20M |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| capacity operations bandwidth | ||
| pool alloc free read write read write | ||
| ------------------------------------- ----- ----- ----- ----- ----- ----- | ||
| disk1 10G 90G 1 2 10M 20M | ||
| /dev/mapper/md1p1 10G 90G 1 2 10M 20M |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| capacity operations bandwidth | ||
| pool alloc free read write read write | ||
| ------------------------------------- ----- ----- ----- ----- ----- ----- | ||
| zmirror 20G 180G 1 2 10M 20M | ||
| mirror-0 20G 180G 1 2 10M 20M | ||
| /dev/nvme1n1p1 10G 90G 1 2 5M 10M | ||
| /dev/nvme2n1p1 10G 90G 1 2 5M 10M |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| capacity operations bandwidth | ||
| pool alloc free read write read write | ||
| ------------------------------------- ----- ----- ----- ----- ----- ----- | ||
| zmirror 20G 180G 1 2 10M 20M | ||
| mirror-0 20G 180G 1 2 10M 20M | ||
| nvme1n1p1 10G 90G 1 2 5M 10M | ||
| nvme2n1p1 10G 90G 1 2 5M 10M |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| disk1 100G 10G 90G - - 10% 10% 1.00x ONLINE - | ||
| zmirror 200G 20G 180G - - 10% 10% 1.00x ONLINE - |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| pool: disk1 | ||
| state: ONLINE | ||
| config: | ||
|
|
||
| NAME STATE READ WRITE CKSUM | ||
| disk1 ONLINE 0 0 0 | ||
| /dev/mapper/md1p1 ONLINE 0 0 0 | ||
|
|
||
| errors: No known data errors |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| pool: disk1 | ||
| state: ONLINE | ||
| config: | ||
|
|
||
| NAME STATE READ WRITE CKSUM | ||
| disk1 ONLINE 0 0 0 | ||
| /dev/mapper/md1p1 ONLINE 0 0 0 | ||
|
|
||
| errors: No known data errors |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| pool: zmirror | ||
| state: ONLINE | ||
| config: | ||
|
|
||
| NAME STATE READ WRITE CKSUM | ||
| zmirror ONLINE 0 0 0 | ||
| mirror-0 ONLINE 0 0 0 | ||
| /dev/nvme1n1p1 ONLINE 0 0 0 | ||
| /dev/nvme2n1p1 ONLINE 0 0 0 | ||
|
|
||
| errors: No known data errors |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| pool: zmirror | ||
| state: ONLINE | ||
| config: | ||
|
|
||
| NAME STATE READ WRITE CKSUM | ||
| zmirror ONLINE 0 0 0 | ||
| mirror-0 ONLINE 0 0 0 | ||
| nvme1n1p1 ONLINE 0 0 0 | ||
| nvme2n1p1 ONLINE 0 0 0 | ||
|
|
||
| errors: No known data errors |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -553,7 +553,34 @@ function run_ported_dmap_alias_lines($root, $ctx, $case_name) | |||||||||||||
| assert_true(!isset($zfs_raw_info['zfs_disks']['sda1']), 'raw-device zfs_info does not expose raw sda1 key'); | ||||||||||||||
| assert_true(empty($zfs_raw_info['warnings']), 'raw-device zfs_info suppresses alias warning when drivemap can resolve devices'); | ||||||||||||||
|
|
||||||||||||||
| $original_zfs_fixture_dir = getenv('DRIVEMAP_ZFS_FIXTURE_DIR'); | ||||||||||||||
| putenv('DRIVEMAP_ZFS_FIXTURE_DIR=' . $fixtures . '/zfs_array'); | ||||||||||||||
| try { | ||||||||||||||
| [$zfs_array_code, $zfs_array_body] = run_api_action($root, 'zfs_info'); | ||||||||||||||
| assert_equal($zfs_array_code, 0, 'zfs_info array-device endpoint exits successfully'); | ||||||||||||||
| $zfs_array_info = json_decode($zfs_array_body, true); | ||||||||||||||
| assert_true(is_array($zfs_array_info), 'zfs_info array-device endpoint returns JSON'); | ||||||||||||||
| assert_true(isset($zfs_array_info['zfs_disks']['1-1']), 'array-device zfs_info maps md1p1 pool to disk1 bay'); | ||||||||||||||
| assert_equal($zfs_array_info['zfs_disks']['1-1']['zpool_name'] ?? '', 'disk1', 'array-device zfs_info reports disk1 pool on bay 1-1'); | ||||||||||||||
| assert_true(!isset($zfs_array_info['zfs_disks']['/dev/mapper/md1p1']), 'array-device zfs_info does not expose md mapper key'); | ||||||||||||||
| assert_true(!isset($zfs_array_info['zfs_disks']['nvme1n1p1']), 'array-device zfs_info ignores unmapped nvme pool members'); | ||||||||||||||
| assert_true(!isset($zfs_array_info['zfs_disks']['nvme2n1p1']), 'array-device zfs_info ignores second unmapped nvme pool member'); | ||||||||||||||
| assert_true(empty($zfs_array_info['warnings']), 'array-device zfs_info suppresses warning for non-slot zfs devices'); | ||||||||||||||
| } finally { | ||||||||||||||
| if ($original_zfs_fixture_dir === false) { | ||||||||||||||
| putenv('DRIVEMAP_ZFS_FIXTURE_DIR'); | ||||||||||||||
| } else { | ||||||||||||||
| putenv('DRIVEMAP_ZFS_FIXTURE_DIR=' . $original_zfs_fixture_dir); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| require_once $root . '/php/zfs_info.php'; | ||||||||||||||
| $malformed_alerts = verify_zfs_device_format([ | ||||||||||||||
| 'tank' => "\ttank ONLINE 0 0 0\n\t mirror-0 ONLINE 0 0 0\n\t bad-disk ONLINE 0 0 0\n", | ||||||||||||||
| ], 'tank', []); | ||||||||||||||
| assert_true(!empty($malformed_alerts), 'zfs device format warns for unresolved malformed members'); | ||||||||||||||
| assert_true(strpos(implode('', $malformed_alerts), 'bad-disk') !== false, 'zfs device format warning names malformed member'); | ||||||||||||||
|
Comment on lines
+581
to
+582
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Update stale warning assertions to match current These expectations now conflict with the implementation that returns no warnings, so this test will fail after the warning-removal change. Proposed fix-$malformed_alerts = verify_zfs_device_format([
- 'tank' => "\ttank ONLINE 0 0 0\n\t mirror-0 ONLINE 0 0 0\n\t bad-disk ONLINE 0 0 0\n",
-], 'tank', []);
-assert_true(!empty($malformed_alerts), 'zfs device format warns for unresolved malformed members');
-assert_true(strpos(implode('', $malformed_alerts), 'bad-disk') !== false, 'zfs device format warning names malformed member');
+$malformed_alerts = verify_zfs_device_format([
+ 'tank' => "\ttank ONLINE 0 0 0\n\t mirror-0 ONLINE 0 0 0\n\t bad-disk ONLINE 0 0 0\n",
+], 'tank', []);
+assert_true(empty($malformed_alerts), 'zfs device format suppresses warnings for unresolved malformed members');📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| $lookup_refresh_path = $ctx['out_dir'] . '/zfs_lookup_refresh.json'; | ||||||||||||||
| file_put_contents($lookup_refresh_path, json_encode([ | ||||||||||||||
| 'rows' => [[ | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exclude the current disk from peer-group animation.
showStorageGroupPeerscurrently animates all group members, includingcd. For peer-only highlighting, skip the current disk in this loop.Suggested fix
group.forEach((dsk) => { + if (dsk.name === cd) + return; const dsk_idx = diskLocations2.findIndex((loc) => loc.BAY === dsk.name); if (dsk_idx < 0 || !diskLocations2[dsk_idx]?.image) return; const loc = diskLocations2[dsk_idx]; p5.animateZpools(loc.x, loc.y, loc.image.width, loc.image.height + y_offset, p5.zfsAnimationSteps, p5.zfsAnimationIndex, p5.zfsAnimationColors.storage_group.start, p5.zfsAnimationColors.storage_group.end, p5.zfsAnimationDir); });📝 Committable suggestion
🤖 Prompt for AI Agents