Tomas Bzatek fdcd46
From 06597099906be55b106c234b3bf0c87ec7d90a07 Mon Sep 17 00:00:00 2001
Tomas Bzatek fdcd46
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek fdcd46
Date: Thu, 17 Aug 2023 14:45:18 +0200
Tomas Bzatek fdcd46
Subject: [PATCH] nvme: Align HostNQN and HostID format to TP4126
Tomas Bzatek fdcd46
Tomas Bzatek fdcd46
Also don't overwrite existing files during startup() since they
Tomas Bzatek fdcd46
might have been supplied by early boot stages.
Tomas Bzatek fdcd46
---
Tomas Bzatek fdcd46
 blivet/nvme.py | 62 +++++++++++++++++++++++++++++++-------------------
Tomas Bzatek fdcd46
 1 file changed, 39 insertions(+), 23 deletions(-)
Tomas Bzatek fdcd46
Tomas Bzatek fdcd46
diff --git a/blivet/nvme.py b/blivet/nvme.py
Tomas Bzatek fdcd46
index 17bead15e..5ac41cffa 100644
Tomas Bzatek fdcd46
--- a/blivet/nvme.py
Tomas Bzatek fdcd46
+++ b/blivet/nvme.py
Tomas Bzatek fdcd46
@@ -18,16 +18,20 @@
Tomas Bzatek fdcd46
 #
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
 import os
Tomas Bzatek fdcd46
-import shutil
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
 from . import errors
Tomas Bzatek fdcd46
-from . import util
Tomas Bzatek fdcd46
+
Tomas Bzatek fdcd46
+import gi
Tomas Bzatek 1618b0
+gi.require_version("BlockDev", "2.0")
Tomas Bzatek fdcd46
+
Tomas Bzatek fdcd46
+from gi.repository import BlockDev as blockdev
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
 import logging
Tomas Bzatek fdcd46
 log = logging.getLogger("blivet")
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
-HOSTNQN_FILE = "/etc/nvme/hostnqn"
Tomas Bzatek fdcd46
-HOSTID_FILE = "/etc/nvme/hostid"
Tomas Bzatek fdcd46
+ETC_NVME_PATH = "/etc/nvme/"
Tomas Bzatek fdcd46
+HOSTNQN_FILE = ETC_NVME_PATH + "hostnqn"
Tomas Bzatek fdcd46
+HOSTID_FILE = ETC_NVME_PATH + "hostid"
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
 class NVMe(object):
Tomas Bzatek fdcd46
@@ -40,6 +44,8 @@ class NVMe(object):
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
     def __init__(self):
Tomas Bzatek fdcd46
         self.started = False
Tomas Bzatek fdcd46
+        self._hostnqn = None
Tomas Bzatek fdcd46
+        self._hostid = None
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
     # So that users can write nvme() to get the singleton instance
Tomas Bzatek fdcd46
     def __call__(self):
Tomas Bzatek fdcd46
@@ -52,28 +58,38 @@ def startup(self):
Tomas Bzatek fdcd46
         if self.started:
Tomas Bzatek fdcd46
             return
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
-        rc, nqn = util.run_program_and_capture_output(["nvme", "gen-hostnqn"])
Tomas Bzatek fdcd46
-        if rc != 0:
Tomas Bzatek fdcd46
-            raise errors.NVMeError("Failed to generate hostnqn")
Tomas Bzatek fdcd46
-
Tomas Bzatek fdcd46
-        with open(HOSTNQN_FILE, "w") as f:
Tomas Bzatek fdcd46
-            f.write(nqn)
Tomas Bzatek fdcd46
-
Tomas Bzatek fdcd46
-        rc, hid = util.run_program_and_capture_output(["dmidecode", "-s", "system-uuid"])
Tomas Bzatek fdcd46
-        if rc != 0:
Tomas Bzatek fdcd46
-            raise errors.NVMeError("Failed to generate host ID")
Tomas Bzatek fdcd46
-
Tomas Bzatek fdcd46
-        with open(HOSTID_FILE, "w") as f:
Tomas Bzatek fdcd46
-            f.write(hid)
Tomas Bzatek fdcd46
+        self._hostnqn = blockdev.nvme_get_host_nqn()
Tomas Bzatek fdcd46
+        self._hostid = blockdev.nvme_get_host_id()
Tomas Bzatek fdcd46
+        if not self._hostnqn:
Tomas Bzatek fdcd46
+            self._hostnqn = blockdev.nvme_generate_host_nqn()
Tomas Bzatek fdcd46
+        if not self._hostnqn:
Tomas Bzatek fdcd46
+            raise errors.NVMeError("Failed to generate HostNQN")
Tomas Bzatek fdcd46
+        if not self._hostid:
Tomas Bzatek fdcd46
+            if 'uuid:' not in self._hostnqn:
Tomas Bzatek fdcd46
+                raise errors.NVMeError("Missing UUID part in the HostNQN string '%s'" % self._hostnqn)
Tomas Bzatek fdcd46
+            # derive HostID from HostNQN's UUID part
Tomas Bzatek fdcd46
+            self._hostid = self._hostnqn.split('uuid:')[1]
Tomas Bzatek fdcd46
+
Tomas Bzatek fdcd46
+        # do not overwrite existing files, taken e.g. from initramfs
Tomas Bzatek fdcd46
+        self.write("/", overwrite=False)
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
         self.started = True
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
-    def write(self, root):  # pylint: disable=unused-argument
Tomas Bzatek fdcd46
-        # copy the hostnqn and hostid files
Tomas Bzatek fdcd46
-        if not os.path.isdir(root + "/etc/nvme"):
Tomas Bzatek fdcd46
-            os.makedirs(root + "/etc/nvme", 0o755)
Tomas Bzatek fdcd46
-        shutil.copyfile(HOSTNQN_FILE, root + HOSTNQN_FILE)
Tomas Bzatek fdcd46
-        shutil.copyfile(HOSTID_FILE, root + HOSTID_FILE)
Tomas Bzatek fdcd46
+    def write(self, root, overwrite=True):  # pylint: disable=unused-argument
Tomas Bzatek fdcd46
+        # write down the hostnqn and hostid files
Tomas Bzatek fdcd46
+        p = root + ETC_NVME_PATH
Tomas Bzatek fdcd46
+        if not os.path.isdir(p):
Tomas Bzatek fdcd46
+            os.makedirs(p, 0o755)
Tomas Bzatek fdcd46
+        p = root + HOSTNQN_FILE
Tomas Bzatek fdcd46
+        if overwrite or not os.path.isfile(p):
Tomas Bzatek fdcd46
+            with open(p, "w") as f:
Tomas Bzatek fdcd46
+                f.write(self._hostnqn)
Tomas Bzatek fdcd46
+                f.write("\n")
Tomas Bzatek fdcd46
+        p = root + HOSTID_FILE
Tomas Bzatek fdcd46
+        if overwrite or not os.path.isfile(p):
Tomas Bzatek fdcd46
+            with open(p, "w") as f:
Tomas Bzatek fdcd46
+                f.write(self._hostid)
Tomas Bzatek fdcd46
+                f.write("\n")
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
 
Tomas Bzatek fdcd46
 # Create nvme singleton