nvmed: Expose LockdownMetric dynamically in static store

Expose the NVMe Command and Feature Lockdown Metric (Log Page 0x14) dynamically based on the controller's supported log page list.

Map standard NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN to LockdownMetric in logpageIdentifier.

Register and instantiate LockdownMetric in initializeMetricStore only if Log Page 0x14 is reported as supported by the controller.

Google-Bug-Id: 439949534
Tested: https://paste.googleplex.com/5125313488093184
Change-Id: I90646afa093d208185d9220833a154b372e3dfbd
Signed-off-by: Agrim Bharat <agrimbharat@google.com>
diff --git a/src/NVMeCacheImpl.hpp b/src/NVMeCacheImpl.hpp
index 51252f9..78c47ff 100644
--- a/src/NVMeCacheImpl.hpp
+++ b/src/NVMeCacheImpl.hpp
@@ -45,6 +45,10 @@
         {
             return "HostInitiatedMetric";
         }
+        else if constexpr (LID == NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN)
+        {
+            return "LockdownMetric";
+        }
         else
         {
             static_assert(false,
diff --git a/src/NVMeController.cpp b/src/NVMeController.cpp
index 11ac0d8..694b748 100644
--- a/src/NVMeController.cpp
+++ b/src/NVMeController.cpp
@@ -274,6 +274,9 @@
     using HostTelemetryMetric =
         ControllerLogPageMetric<NVME_LOG_LID_TELEMETRY_HOST,
                                 SchedulerClockType>;
+    using LockdownMetric =
+        ControllerLogPageMetric<NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN,
+                                SchedulerClockType>;
 
     auto defaultLogpageRefreshDuration =
         std::chrono::duration_cast<SchedulerClockType::duration>(
@@ -287,37 +290,32 @@
     std::list<std::shared_ptr<MetricBase<SchedulerClockType>>> metrics;
     metrics.push_back(identify);
 
-    if (isLogPageSupported(NVME_LOG_LID_ERROR))
-    {
-        metrics.push_back(std::make_shared<ErrorInfoMetric>(
-            this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
-    }
-    if (isLogPageSupported(NVME_LOG_LID_SMART))
-    {
-        metrics.push_back(std::make_shared<SMARTMetric>(
-            this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
-    }
-    if (isLogPageSupported(NVME_LOG_LID_FW_SLOT))
-    {
-        metrics.push_back(std::make_shared<FwSlotMetric>(
-            this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
-    }
-    if (isLogPageSupported(NVME_LOG_LID_DEVICE_SELF_TEST))
-    {
-        metrics.push_back(std::make_shared<SelfTestMetric>(
-            this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
-    }
+    // Standard core metrics are statically supported across all NVMe versions
+    metrics.push_back(std::make_shared<ErrorInfoMetric>(
+        this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
+    metrics.push_back(std::make_shared<SMARTMetric>(
+        this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
+    metrics.push_back(std::make_shared<FwSlotMetric>(
+        this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
+    metrics.push_back(std::make_shared<SelfTestMetric>(
+        this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
 
     auto pluginName = findPluginName(config);
     if (!pluginName || pluginName != "OCP")
     {
-        if (isLogPageSupported(NVME_LOG_LID_TELEMETRY_HOST))
-        {
-            metrics.push_back(std::make_shared<HostTelemetryMetric>(
-                this->weak_from_this(), scheduler,
-                std::chrono::duration_cast<SchedulerClockType::duration>(
-                    std::chrono::seconds(900))));
-        }
+        metrics.push_back(std::make_shared<HostTelemetryMetric>(
+            this->weak_from_this(), scheduler,
+            std::chrono::duration_cast<SchedulerClockType::duration>(
+                std::chrono::seconds(900))));
+    }
+
+    // Command Lockdown (Log Page 14h) is dynamically registered only on
+    // NVMe 2.0+ controllers that explicitly report support via Supported Log
+    // Pages (00h) check.
+    if (isLogPageSupported(NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN))
+    {
+        metrics.push_back(std::make_shared<LockdownMetric>(
+            this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
     }
 
     this->metricStore.emplace(
@@ -1145,7 +1143,7 @@
 {
     if (nvmeVersion < kMinNvmeVerLogLid00hSupport)
     {
-        return true;
+        return false;
     }
 
     if (lid == 0x00)
diff --git a/src/NVMeMiFake.hpp b/src/NVMeMiFake.hpp
index 091e16b..0871aa2 100644
--- a/src/NVMeMiFake.hpp
+++ b/src/NVMeMiFake.hpp
@@ -261,6 +261,12 @@
                             log.temperature[1] = 1;
                             break;
                         }
+                        case NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN:
+                        {
+                            data.resize(sizeof(nvme_lockdown_log));
+                            std::fill(data.begin(), data.end(), 0);
+                            break;
+                        }
 
                         default:
                         {