Skip to content

Commit dc44617

Browse files
committed
Prevent shared FC/iSCSI LUNs from being used simultaneously across hosts
Use WWNs in the disk fixture to: - Mark a LUN unavailable on all hosts if it is already in use on any host (cross-host deduplication for shared FC/iSCSI LUNs). - Deprioritize LUNs listed in LVMOHBA_DEVICE_CONFIG or LVMOISCSI_DEVICE_CONFIG so they are only selected when no other disk is available. Signed-off-by: Gaëtan Lehmann <gaetan.lehmann@vates.tech>
1 parent 35bdbf4 commit dc44617

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

conftest.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pytest
44

55
import argparse
6+
import dataclasses
67
import itertools
78
import logging
89
import os
@@ -435,6 +436,42 @@ def _host_disks(host: Host, hosts_cli_disks: list[DiskDevName] | None) -> Iterab
435436
ret = {host: list(_host_disks(host, cli_disks.get(host.hostname_or_ip)))
436437
for host in pools_hosts_by_name_or_ip.values()
437438
}
439+
# Cross-host deduplication: a LUN in use on any host (same WWN) is unavailable on all hosts.
440+
# This matters for shared FC/iSCSI LUNs visible on multiple hosts simultaneously.
441+
used_wwns = {
442+
disk.wwn
443+
for host_disks in ret.values()
444+
for disk in host_disks
445+
if disk.wwn and not disk.available
446+
}
447+
if used_wwns:
448+
logging.debug("cross-host used WWNs: %s", used_wwns)
449+
ret = {
450+
host: [
451+
dataclasses.replace(disk, available=False) if (disk.wwn and disk.wwn in used_wwns) else disk
452+
for disk in host_disks
453+
]
454+
for host, host_disks in ret.items()
455+
}
456+
# LUNs reserved for lvmohba/lvmoiscsi: sort them to the end so they are
457+
# only picked if no other disk is available.
458+
reserved_wwns: set[str] = set()
459+
try:
460+
import data
461+
for key in ('LVMOHBA_DEVICE_CONFIG', 'LVMOISCSI_DEVICE_CONFIG'):
462+
cfg = getattr(data, key, None)
463+
if isinstance(cfg, dict):
464+
scsiid = cfg.get('SCSIid', '').lower().removeprefix('0x')
465+
if len(scsiid) >= 16:
466+
reserved_wwns.add(scsiid[:16])
467+
except ImportError:
468+
pass
469+
if reserved_wwns:
470+
logging.debug("reserved WWNs (lvmohba/lvmoiscsi): %s", reserved_wwns)
471+
ret = {
472+
host: sorted(host_disks, key=lambda d: d.wwn in reserved_wwns)
473+
for host, host_disks in ret.items()
474+
}
438475
logging.debug("disks collected: %s", {host.hostname_or_ip: value for host, value in ret.items()})
439476
return ret
440477

0 commit comments

Comments
 (0)