Skip to content

Commit

Permalink
nvme: run nvme connect-all --nbft before running the actual probes
Browse files Browse the repository at this point in the history
When running in an environment where a NBFT is available, we want
probert to collect information about the remote NVMe drives too.

This can be done by calling the `nvme connect-all --nbft` command. That
said, running the command in the NVMe probe code itself will be too late
for other probes (e.g., blockdev, filesystem, ...) to pick-up
information about the remote NVMe drives.

Instead, we run the command before dispatching the probes ; in a
function called "activate_devices". In the long run, I would like to
move some code that is currently in the probes (e.g., vgchange
--activate=y) to the activate_devices function ; to avoid side effects
in the probe code.

Signed-off-by: Olivier Gayot <[email protected]>
  • Loading branch information
ogayot committed Sep 12, 2024
1 parent 83d25c8 commit e0d71c3
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
2 changes: 2 additions & 0 deletions probert/lvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ async def probe(context=None, **kw):
older LVM2 stacks, the LVM probe may be incomplete.
"""
# scan and activate lvm vgs/lvs
# TODO it feels like the activation code should be moved to
# Storage.activate_devices.
lvm_scan()
activate_volgroups()

Expand Down
11 changes: 10 additions & 1 deletion probert/nvme.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import logging
import subprocess

import pyudev

from probert.utils import udev_get_attributes
from probert.utils import arun, udev_get_attributes

log = logging.getLogger('probert.nvme')

Expand All @@ -32,3 +33,11 @@ async def probe(context=None, **kw):
nvme_controllers[controller.sys_name] = props

return nvme_controllers


async def connect_nbft() -> None:
cmd = ['nvme', 'connect-all', '--nbft']
try:
await arun(cmd)
except (subprocess.CalledProcessError, FileNotFoundError):
log.error('Failed to run cmd: %s', cmd)
21 changes: 21 additions & 0 deletions probert/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ async def probe(self, probe_types=None, *, parallelize=False):
print('Unavilable probe types: %s' % not_avail)
return self.results

# Run operations that have side-effects, before we start reading udev
# cache.
await activate_devices()

probed_data = {}

async def run_probe(ptype):
Expand All @@ -250,3 +254,20 @@ async def run_probe(ptype):

self.results = probed_data
return probed_data

async def activate_devices(probe_types: list[str]) -> None:
"""Before querying udev, we want to let it know of the existence of
some block devices (which may not be currently visible). This includes
connecting to NVMe drives using the NVMe/TCP protocol, but also
activating LVM VGs to make LVM LVs visible.
Typically, commands must be run in a specific order to make all the
devices visible; so running the commands in the code of the probes
themselves (which run in an undefined order) feels wrong.
Ideally, the code of the probes should have no side effect, and we
should move operations that have side effect here."""
if "nvme" in probe_types:
await nvme.connect_nbft()

# TODO we should probably move the LVM VG activation code here ; so
# that blockdev, filesystem_sizing, OS detection and other probes
# include information about LVs.

0 comments on commit e0d71c3

Please sign in to comment.