* [LTP] [PATCH v2] testcases/nvme: Add NVMe device discovery and identification test
[not found] <20260428075302.7320ef7e3@imap1.dmz-prg2.suse.org>
@ 2026-04-30 15:52 ` priyama2
2026-04-29 7:33 ` [LTP] " linuxtestproject.agent
2026-05-01 15:14 ` [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test priyama2
1 sibling, 1 reply; 10+ messages in thread
From: priyama2 @ 2026-04-30 15:52 UTC (permalink / raw)
To: ltp
From: priyama2 <priyama2@linux.ibm.com>
This test verifies NVMe device discovery and identification by:
- Detecting NVMe controllers in /dev
- Enumerating namespaces for detected controllers
- Verifying PCI enumeration (class code 0x010802)
- Checking NVMe driver binding
Changes in v2:
- Use LTP buildsystem instead of standalone Makefile
- Remove README file (use doc comments instead)
- Fix author attribution
- Add proper LTP documentation comment format
- Use SAFE_OPENDIR() and SAFE_CLOSEDIR() macros
- Remove obvious and redundant comments
- Code cleanup and style improvements
Signed-off-by: priyama2 <priyama2@linux.ibm.com>
---
testcases/kernel/device-drivers/nvme/Makefile | 7 +
testcases/kernel/device-drivers/nvme/nvme01.c | 208 ++++++++++++++++++
2 files changed, 215 insertions(+)
create mode 100644 testcases/kernel/device-drivers/nvme/Makefile
create mode 100644 testcases/kernel/device-drivers/nvme/nvme01.c
diff --git a/testcases/kernel/device-drivers/nvme/Makefile b/testcases/kernel/device-drivers/nvme/Makefile
new file mode 100644
index 000000000..d47e99e6a
--- /dev/null
+++ b/testcases/kernel/device-drivers/nvme/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2024 IBM Corporation
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/kernel/device-drivers/nvme/nvme01.c b/testcases/kernel/device-drivers/nvme/nvme01.c
new file mode 100644
index 000000000..f448e7e5c
--- /dev/null
+++ b/testcases/kernel/device-drivers/nvme/nvme01.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2024 IBM Corporation
+ * Author: Priya Gopinath <priyama2@linux.ibm.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify NVMe device discovery and identification:
+ *
+ * - Detect NVMe controllers in /dev
+ * - Enumerate namespaces for detected controllers
+ * - Verify PCI enumeration (class code 0x010802)
+ * - Check NVMe driver binding
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include "tst_test.h"
+
+#define NVME_DEV_PATH "/dev"
+#define NVME_SYS_PATH "/sys/class/nvme"
+#define PCI_DEVICES_PATH "/sys/bus/pci/devices"
+
+static int nvme_device_found;
+static char nvme_dev_name[256];
+
+static void test_detect_nvme_controllers(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int found = 0;
+
+ dir = SAFE_OPENDIR(NVME_DEV_PATH);
+
+ tst_res(TINFO, "Scanning for NVMe devices in %s", NVME_DEV_PATH);
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (strncmp(entry->d_name, "nvme", 4) == 0 &&
+ strlen(entry->d_name) == 5) {
+ tst_res(TINFO, "Found NVMe controller: %s", entry->d_name);
+ strncpy(nvme_dev_name, entry->d_name, sizeof(nvme_dev_name) - 1);
+ found = 1;
+ nvme_device_found = 1;
+ }
+ }
+
+ SAFE_CLOSEDIR(dir);
+
+ if (found)
+ tst_res(TPASS, "NVMe controller(s) detected successfully");
+ else
+ tst_res(TCONF, "No NVMe controllers found in system");
+}
+
+static void test_enumerate_namespaces(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int ns_count = 0;
+ char search_pattern[32];
+
+ if (!nvme_device_found) {
+ tst_res(TCONF, "No NVMe device found, skipping namespace enumeration");
+ return;
+ }
+
+ snprintf(search_pattern, sizeof(search_pattern), "%sn", nvme_dev_name);
+
+ dir = SAFE_OPENDIR(NVME_DEV_PATH);
+
+ tst_res(TINFO, "Enumerating namespaces for %s", nvme_dev_name);
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (strncmp(entry->d_name, search_pattern, strlen(search_pattern)) == 0) {
+ tst_res(TINFO, "Found namespace: %s", entry->d_name);
+ ns_count++;
+ }
+ }
+
+ SAFE_CLOSEDIR(dir);
+
+ if (ns_count > 0)
+ tst_res(TPASS, "Enumerated %d namespace(s) successfully", ns_count);
+ else
+ tst_res(TPASS, "No namespaces found for %s (device may not have namespaces configured)", nvme_dev_name);
+}
+
+static void test_verify_pci_enumeration(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int found = 0;
+ char class_path[512];
+ FILE *fp;
+ char class_id[16];
+
+ if (!nvme_device_found) {
+ tst_res(TCONF, "No NVMe device found, skipping PCI enumeration check");
+ return;
+ }
+
+ dir = SAFE_OPENDIR(PCI_DEVICES_PATH);
+
+ tst_res(TINFO, "Checking PCI enumeration for NVMe devices");
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (entry->d_name[0] == '.')
+ continue;
+
+ snprintf(class_path, sizeof(class_path), "%s/%s/class",
+ PCI_DEVICES_PATH, entry->d_name);
+
+ fp = fopen(class_path, "r");
+ if (!fp)
+ continue;
+
+ if (fgets(class_id, sizeof(class_id), fp)) {
+ if (strncmp(class_id, "0x010802", 8) == 0) {
+ tst_res(TINFO, "Found NVMe PCI device: %s (class: %s)",
+ entry->d_name, class_id);
+ found = 1;
+ }
+ }
+ fclose(fp);
+ }
+
+ SAFE_CLOSEDIR(dir);
+
+ if (found)
+ tst_res(TPASS, "NVMe device properly enumerated on PCI bus");
+ else
+ tst_res(TFAIL, "NVMe device not found on PCI bus");
+}
+
+static void test_check_driver_binding(void)
+{
+ char driver_path[512];
+ char driver_link[512];
+ ssize_t len;
+
+ if (!nvme_device_found) {
+ tst_res(TCONF, "No NVMe device found, skipping driver binding check");
+ return;
+ }
+
+ snprintf(driver_path, sizeof(driver_path), "%s/%s/device/driver",
+ NVME_SYS_PATH, nvme_dev_name);
+
+ len = readlink(driver_path, driver_link, sizeof(driver_link) - 1);
+ if (len == -1) {
+ tst_res(TFAIL | TERRNO, "Failed to read driver symlink for %s", nvme_dev_name);
+ return;
+ }
+
+ driver_link[len] = '\0';
+
+ tst_res(TINFO, "Driver binding: %s", driver_link);
+
+ if (strstr(driver_link, "nvme") != NULL)
+ tst_res(TPASS, "NVMe driver properly bound to device");
+ else
+ tst_res(TFAIL, "Unexpected driver bound to NVMe device: %s", driver_link);
+}
+
+static void setup(void)
+{
+ /* Check if nvme module is loaded */
+ if (access("/sys/module/nvme", F_OK) != 0)
+ tst_brk(TCONF, "NVMe kernel module not loaded");
+
+ tst_res(TINFO, "NVMe Device Discovery & Identification Test");
+}
+
+static void run(unsigned int n)
+{
+ switch (n) {
+ case 0:
+ test_detect_nvme_controllers();
+ break;
+ case 1:
+ test_enumerate_namespaces();
+ break;
+ case 2:
+ test_verify_pci_enumeration();
+ break;
+ case 3:
+ test_check_driver_binding();
+ break;
+ }
+}
+
+static struct tst_test test = {
+ .test = run,
+ .tcnt = 4,
+ .setup = setup,
+ .needs_root = 1,
+};
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [LTP] testcases/nvme: Add NVMe device discovery and identification test
2026-04-30 15:52 ` [LTP] [PATCH v2] testcases/nvme: Add NVMe device discovery and identification test priyama2
@ 2026-04-29 7:33 ` linuxtestproject.agent
0 siblings, 0 replies; 10+ messages in thread
From: linuxtestproject.agent @ 2026-04-29 7:33 UTC (permalink / raw)
To: priyama2; +Cc: ltp
Hi Priya,
On 2026-04-30, priyama2 <priyama2@linux.ibm.com> wrote:
> [PATCH] testcases/nvme: Add NVMe device discovery and identification test
The subject prefix should match the actual directory path:
testcases/kernel/device-drivers/nvme:
The commit body only describes what the test does (restating the subject).
Please add a sentence explaining why the test is needed, e.g. what gap in
NVMe coverage this fills.
> +/*
> + * Copyright (c) 2024 IBM Corporation
New files added in 2026 must use 2026 as the copyright year.
[...]
> +SUBDIRS := acpi \
> + ...
testcases/kernel/device-drivers/Makefile has an explicit SUBDIRS list that
does not include nvme. The directory will not be built. Add nvme to the list.
[...]
> +static int nvme_device_found;
> +static char nvme_dev_name[256];
These statics are written in run() case 0 and read in cases 1-3 but are
never reset at the top of run(). With -i, stale values from a previous
iteration carry over. Reset them at the start of run().
[...]
> + .needs_root = 1,
All operations here (reading /dev, /sys) are world-readable. Remove
.needs_root = 1.
[...]
> + fp = fopen(class_path, "r");
> + if (!fp)
> + continue;
> + ...
> + fclose(fp);
Use SAFE_FOPEN/SAFE_FCLOSE (include/tst_safe_stdio.h), or document why
the raw call with continue-on-failure is intentional.
[...]
> + len = readlink(driver_path, driver_link, sizeof(driver_link) - 1);
Use SAFE_READLINK (include/tst_safe_macros.h).
Also missing:
- testcases/kernel/device-drivers/nvme/.gitignore entry for nvme01
- runtest/ entry for nvme01 (e.g. in runtest/drivers)
---
Note:
Our agent completed the review of the patch. The full review can be
found at: (not available)
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 10+ messages in thread
* [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test
[not found] <20260428075302.7320ef7e3@imap1.dmz-prg2.suse.org>
2026-04-30 15:52 ` [LTP] [PATCH v2] testcases/nvme: Add NVMe device discovery and identification test priyama2
@ 2026-05-01 15:14 ` priyama2
2026-04-30 6:35 ` [LTP] " linuxtestproject.agent
` (2 more replies)
1 sibling, 3 replies; 10+ messages in thread
From: priyama2 @ 2026-05-01 15:14 UTC (permalink / raw)
To: ltp
From: priyama2 <priyama2@linux.ibm.com>
This test fills a gap in NVMe test coverage by validating basic device
enumeration and driver binding, which are fundamental prerequisites for
any NVMe functionality testing.
The test verifies:
- Detection of NVMe controllers in /dev
- Enumeration of namespaces for detected controllers
- PCI enumeration (class code 0x010802)
- NVMe driver binding
Changes in v3:
- Fix subject prefix to match directory path
- Update copyright year to 2026
- Add nvme to SUBDIRS in testcases/kernel/device-drivers/Makefile
- Reset static variables at start of run() for -i support
- Remove .needs_root (all operations are world-readable)
- Use SAFE_FOPEN/SAFE_FCLOSE for PCI class file access
- Use SAFE_READLINK for driver symlink reading
- Add .gitignore entry for nvme01 binary
- Add runtest/device-drivers entry for nvme01
- Fix author field to use priyama2
Changes in v2:
- Use LTP buildsystem instead of standalone Makefile
- Remove README file (use doc comments instead)
- Add proper LTP documentation comment format
- Use SAFE_OPENDIR() and SAFE_CLOSEDIR() macros
- Remove obvious and redundant comments
- Code cleanup and style improvements
Signed-off-by: priyama2 <priyama2@linux.ibm.com>
---
runtest/device-drivers | 1 +
testcases/kernel/device-drivers/Makefile | 1 +
.../kernel/device-drivers/nvme/.gitignore | 1 +
testcases/kernel/device-drivers/nvme/Makefile | 7 +
testcases/kernel/device-drivers/nvme/nvme01.c | 205 ++++++++++++++++++
5 files changed, 215 insertions(+)
create mode 100644 runtest/device-drivers
create mode 100644 testcases/kernel/device-drivers/nvme/.gitignore
create mode 100644 testcases/kernel/device-drivers/nvme/Makefile
create mode 100644 testcases/kernel/device-drivers/nvme/nvme01.c
diff --git a/runtest/device-drivers b/runtest/device-drivers
new file mode 100644
index 000000000..a7295584e
--- /dev/null
+++ b/runtest/device-drivers
@@ -0,0 +1 @@
+nvme01 nvme01
diff --git a/testcases/kernel/device-drivers/Makefile b/testcases/kernel/device-drivers/Makefile
index 229a50683..664f4cd18 100644
--- a/testcases/kernel/device-drivers/Makefile
+++ b/testcases/kernel/device-drivers/Makefile
@@ -9,6 +9,7 @@ SUBDIRS := acpi \
block \
cpufreq \
locking \
+ nvme \
pci \
rcu \
rtc \
diff --git a/testcases/kernel/device-drivers/nvme/.gitignore b/testcases/kernel/device-drivers/nvme/.gitignore
new file mode 100644
index 000000000..c60bc210c
--- /dev/null
+++ b/testcases/kernel/device-drivers/nvme/.gitignore
@@ -0,0 +1 @@
+nvme01
diff --git a/testcases/kernel/device-drivers/nvme/Makefile b/testcases/kernel/device-drivers/nvme/Makefile
new file mode 100644
index 000000000..d47e99e6a
--- /dev/null
+++ b/testcases/kernel/device-drivers/nvme/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2024 IBM Corporation
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/kernel/device-drivers/nvme/nvme01.c b/testcases/kernel/device-drivers/nvme/nvme01.c
new file mode 100644
index 000000000..3c3cb92ce
--- /dev/null
+++ b/testcases/kernel/device-drivers/nvme/nvme01.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 IBM Corporation
+ * Author: priyama2 <priyama2@linux.ibm.com>
+ */
+
+/* * [Description]
+ *
+ * Verify NVMe device discovery and identification.
+ *
+ * This test fills a gap in NVMe test coverage by validating basic device
+ * enumeration and driver binding, which are fundamental prerequisites for
+ * any NVMe functionality testing.
+ *
+ * - Detect NVMe controllers in /dev
+ * - Enumerate namespaces for detected controllers
+ * - Verify PCI enumeration (class code 0x010802)
+ * - Check NVMe driver binding
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
+
+#define NVME_DEV_PATH "/dev"
+#define NVME_SYS_PATH "/sys/class/nvme"
+#define PCI_DEVICES_PATH "/sys/bus/pci/devices"
+
+static int nvme_device_found;
+static char nvme_dev_name[256];
+
+static void test_detect_nvme_controllers(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int found = 0;
+
+ dir = SAFE_OPENDIR(NVME_DEV_PATH);
+
+ tst_res(TINFO, "Scanning for NVMe devices in %s", NVME_DEV_PATH);
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (strncmp(entry->d_name, "nvme", 4) == 0 &&
+ strlen(entry->d_name) == 5) {
+ tst_res(TINFO, "Found NVMe controller: %s", entry->d_name);
+ strncpy(nvme_dev_name, entry->d_name, sizeof(nvme_dev_name) - 1);
+ found = 1;
+ nvme_device_found = 1;
+ }
+ }
+
+ SAFE_CLOSEDIR(dir);
+
+ if (found)
+ tst_res(TPASS, "NVMe controller(s) detected successfully");
+ else
+ tst_res(TCONF, "No NVMe controllers found in system");
+}
+
+static void test_enumerate_namespaces(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int ns_count = 0;
+ char search_pattern[32];
+
+ if (!nvme_device_found) {
+ tst_res(TCONF, "No NVMe device found, skipping namespace enumeration");
+ return;
+ }
+
+ snprintf(search_pattern, sizeof(search_pattern), "%sn", nvme_dev_name);
+
+ dir = SAFE_OPENDIR(NVME_DEV_PATH);
+
+ tst_res(TINFO, "Enumerating namespaces for %s", nvme_dev_name);
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (strncmp(entry->d_name, search_pattern, strlen(search_pattern)) == 0) {
+ tst_res(TINFO, "Found namespace: %s", entry->d_name);
+ ns_count++;
+ }
+ }
+
+ SAFE_CLOSEDIR(dir);
+
+ if (ns_count > 0)
+ tst_res(TPASS, "Enumerated %d namespace(s) successfully", ns_count);
+ else
+ tst_res(TPASS, "No namespaces found for %s (device may not have namespaces configured)", nvme_dev_name);
+}
+
+static void test_verify_pci_enumeration(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int found = 0;
+ char class_path[512];
+ FILE *fp;
+ char class_id[16];
+
+ if (!nvme_device_found) {
+ tst_res(TCONF, "No NVMe device found, skipping PCI enumeration check");
+ return;
+ }
+
+ dir = SAFE_OPENDIR(PCI_DEVICES_PATH);
+
+ tst_res(TINFO, "Checking PCI enumeration for NVMe devices");
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (entry->d_name[0] == '.')
+ continue;
+
+ snprintf(class_path, sizeof(class_path), "%s/%s/class",
+ PCI_DEVICES_PATH, entry->d_name);
+
+ fp = SAFE_FOPEN(class_path, "r");
+
+ if (fgets(class_id, sizeof(class_id), fp)) {
+ if (strncmp(class_id, "0x010802", 8) == 0) {
+ tst_res(TINFO, "Found NVMe PCI device: %s (class: %s)",
+ entry->d_name, class_id);
+ found = 1;
+ }
+ }
+ SAFE_FCLOSE(fp);
+ }
+
+ SAFE_CLOSEDIR(dir);
+
+ if (found)
+ tst_res(TPASS, "NVMe device properly enumerated on PCI bus");
+ else
+ tst_res(TFAIL, "NVMe device not found on PCI bus");
+}
+
+static void test_check_driver_binding(void)
+{
+ char driver_path[512];
+ char driver_link[512];
+
+ if (!nvme_device_found) {
+ tst_res(TCONF, "No NVMe device found, skipping driver binding check");
+ return;
+ }
+
+ snprintf(driver_path, sizeof(driver_path), "%s/%s/device/driver",
+ NVME_SYS_PATH, nvme_dev_name);
+
+ SAFE_READLINK(driver_path, driver_link, sizeof(driver_link));
+
+ tst_res(TINFO, "Driver binding: %s", driver_link);
+
+ if (strstr(driver_link, "nvme") != NULL)
+ tst_res(TPASS, "NVMe driver properly bound to device");
+ else
+ tst_res(TFAIL, "Unexpected driver bound to NVMe device: %s", driver_link);
+}
+
+static void setup(void)
+{
+ if (access("/sys/module/nvme", F_OK) != 0)
+ tst_brk(TCONF, "NVMe kernel module not loaded");
+
+ tst_res(TINFO, "NVMe Device Discovery & Identification Test");
+}
+
+static void run(unsigned int n)
+{
+ /* Reset state for each iteration */
+ nvme_device_found = 0;
+ memset(nvme_dev_name, 0, sizeof(nvme_dev_name));
+
+ switch (n) {
+ case 0:
+ test_detect_nvme_controllers();
+ break;
+ case 1:
+ test_enumerate_namespaces();
+ break;
+ case 2:
+ test_verify_pci_enumeration();
+ break;
+ case 3:
+ test_check_driver_binding();
+ break;
+ }
+}
+
+static struct tst_test test = {
+ .test = run,
+ .tcnt = 4,
+ .setup = setup,
+};
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [LTP] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test
2026-05-01 15:14 ` [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test priyama2
@ 2026-04-30 6:35 ` linuxtestproject.agent
2026-05-04 10:40 ` [LTP] [PATCH v3] " Andrea Cervesato via ltp
2026-05-05 3:46 ` Sebastian Chlad
2 siblings, 0 replies; 10+ messages in thread
From: linuxtestproject.agent @ 2026-04-30 6:35 UTC (permalink / raw)
To: priyama2; +Cc: ltp
Hi priyama2,
On Fri, 1 May 2026 15:14:20 +0000, priyama2 wrote:
> +++ b/testcases/kernel/device-drivers/nvme/Makefile
> +# Copyright (c) 2024 IBM Corporation
This file is new and added in 2026; the copyright year must match the
year of creation. Change 2024 -> 2026.
[...]
> +static int nvme_device_found;
> +static char nvme_dev_name[256];
[...]
> +static void run(unsigned int n)
> +{
> + /* Reset state for each iteration */
> + nvme_device_found = 0;
> + memset(nvme_dev_name, 0, sizeof(nvme_dev_name));
> +
> + switch (n) {
> + case 0:
> + test_detect_nvme_controllers();
> + break;
> + case 1:
> + test_enumerate_namespaces();
With .tcnt = 4, each run(n) is a separate call, so the reset at the top
zeroes out nvme_device_found before cases 1-3 can use the value set by
case 0. On a machine with NVMe hardware, cases 1-3 always TCONF. Move
the device discovery into setup() so the state persists across all run()
invocations.
---
Note:
Our agent completed the review of the patch. The full review can be
found at: https://github.com/linux-test-project/ltp-agent/actions/runs/25150858409
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test
2026-05-01 15:14 ` [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test priyama2
2026-04-30 6:35 ` [LTP] " linuxtestproject.agent
@ 2026-05-04 10:40 ` Andrea Cervesato via ltp
2026-05-05 3:46 ` Sebastian Chlad
2 siblings, 0 replies; 10+ messages in thread
From: Andrea Cervesato via ltp @ 2026-05-04 10:40 UTC (permalink / raw)
To: priyama2; +Cc: ltp
Hi Priyama,
The patch doesn't compile:
https://github.com/linux-test-project/ltp/actions/runs/25153014278
Kind regards,
--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test
2026-05-01 15:14 ` [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test priyama2
2026-04-30 6:35 ` [LTP] " linuxtestproject.agent
2026-05-04 10:40 ` [LTP] [PATCH v3] " Andrea Cervesato via ltp
@ 2026-05-05 3:46 ` Sebastian Chlad
2026-05-05 8:45 ` Daniel Wagner
2 siblings, 1 reply; 10+ messages in thread
From: Sebastian Chlad @ 2026-05-05 3:46 UTC (permalink / raw)
To: priyama2; +Cc: daniel.wagner, ltp
Hi Priyama,
Sorry for top-posting, but I have a broader question here.
First of all, thanks for working on this and for looking into NVMe coverage.
Before going further, could you please explain the intended LTP-specific
value of
this test? blktests already has a dedicated NVMe test group with much
broader
coverage, including controller/namespace discovery, NVMe commands, fabrics,
etc.:
https://github.com/linux-blktests/blktests/tree/master/tests/nvme
So I think we should be careful not to duplicate coverage unless there is a
clear
reason for having a small LTP-level smoke test as well. Maybe your
intention is
different? Could you please clarify?
Cheers,
Sebastian
On Thu, 30 Apr 2026 at 07:10, <priyama2@linux.ibm.com> wrote:
> From: priyama2 <priyama2@linux.ibm.com>
>
> This test fills a gap in NVMe test coverage by validating basic device
> enumeration and driver binding, which are fundamental prerequisites for
> any NVMe functionality testing.
>
> The test verifies:
> - Detection of NVMe controllers in /dev
> - Enumeration of namespaces for detected controllers
> - PCI enumeration (class code 0x010802)
> - NVMe driver binding
>
> Changes in v3:
> - Fix subject prefix to match directory path
> - Update copyright year to 2026
> - Add nvme to SUBDIRS in testcases/kernel/device-drivers/Makefile
> - Reset static variables at start of run() for -i support
> - Remove .needs_root (all operations are world-readable)
> - Use SAFE_FOPEN/SAFE_FCLOSE for PCI class file access
> - Use SAFE_READLINK for driver symlink reading
> - Add .gitignore entry for nvme01 binary
> - Add runtest/device-drivers entry for nvme01
> - Fix author field to use priyama2
>
> Changes in v2:
> - Use LTP buildsystem instead of standalone Makefile
> - Remove README file (use doc comments instead)
> - Add proper LTP documentation comment format
> - Use SAFE_OPENDIR() and SAFE_CLOSEDIR() macros
> - Remove obvious and redundant comments
> - Code cleanup and style improvements
>
> Signed-off-by: priyama2 <priyama2@linux.ibm.com>
> ---
> runtest/device-drivers | 1 +
> testcases/kernel/device-drivers/Makefile | 1 +
> .../kernel/device-drivers/nvme/.gitignore | 1 +
> testcases/kernel/device-drivers/nvme/Makefile | 7 +
> testcases/kernel/device-drivers/nvme/nvme01.c | 205 ++++++++++++++++++
> 5 files changed, 215 insertions(+)
> create mode 100644 runtest/device-drivers
> create mode 100644 testcases/kernel/device-drivers/nvme/.gitignore
> create mode 100644 testcases/kernel/device-drivers/nvme/Makefile
> create mode 100644 testcases/kernel/device-drivers/nvme/nvme01.c
>
> diff --git a/runtest/device-drivers b/runtest/device-drivers
> new file mode 100644
> index 000000000..a7295584e
> --- /dev/null
> +++ b/runtest/device-drivers
> @@ -0,0 +1 @@
> +nvme01 nvme01
> diff --git a/testcases/kernel/device-drivers/Makefile
> b/testcases/kernel/device-drivers/Makefile
> index 229a50683..664f4cd18 100644
> --- a/testcases/kernel/device-drivers/Makefile
> +++ b/testcases/kernel/device-drivers/Makefile
> @@ -9,6 +9,7 @@ SUBDIRS := acpi \
> block \
> cpufreq \
> locking \
> + nvme \
> pci \
> rcu \
> rtc \
> diff --git a/testcases/kernel/device-drivers/nvme/.gitignore
> b/testcases/kernel/device-drivers/nvme/.gitignore
> new file mode 100644
> index 000000000..c60bc210c
> --- /dev/null
> +++ b/testcases/kernel/device-drivers/nvme/.gitignore
> @@ -0,0 +1 @@
> +nvme01
> diff --git a/testcases/kernel/device-drivers/nvme/Makefile
> b/testcases/kernel/device-drivers/nvme/Makefile
> new file mode 100644
> index 000000000..d47e99e6a
> --- /dev/null
> +++ b/testcases/kernel/device-drivers/nvme/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (c) 2024 IBM Corporation
> +
> +top_srcdir ?= ../../../..
> +
> +include $(top_srcdir)/include/mk/env_pre.mk
> +include $(top_srcdir)/include/mk/generic_trunk_target.mk
> diff --git a/testcases/kernel/device-drivers/nvme/nvme01.c
> b/testcases/kernel/device-drivers/nvme/nvme01.c
> new file mode 100644
> index 000000000..3c3cb92ce
> --- /dev/null
> +++ b/testcases/kernel/device-drivers/nvme/nvme01.c
> @@ -0,0 +1,205 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2026 IBM Corporation
> + * Author: priyama2 <priyama2@linux.ibm.com>
> + */
> +
> +/* * [Description]
> + *
> + * Verify NVMe device discovery and identification.
> + *
> + * This test fills a gap in NVMe test coverage by validating basic device
> + * enumeration and driver binding, which are fundamental prerequisites for
> + * any NVMe functionality testing.
> + *
> + * - Detect NVMe controllers in /dev
> + * - Enumerate namespaces for detected controllers
> + * - Verify PCI enumeration (class code 0x010802)
> + * - Check NVMe driver binding
> + */
> +
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <dirent.h>
> +#include <errno.h>
> +
> +#include "tst_test.h"
> +#include "tst_safe_stdio.h"
> +
> +#define NVME_DEV_PATH "/dev"
> +#define NVME_SYS_PATH "/sys/class/nvme"
> +#define PCI_DEVICES_PATH "/sys/bus/pci/devices"
> +
> +static int nvme_device_found;
> +static char nvme_dev_name[256];
> +
> +static void test_detect_nvme_controllers(void)
> +{
> + DIR *dir;
> + struct dirent *entry;
> + int found = 0;
> +
> + dir = SAFE_OPENDIR(NVME_DEV_PATH);
> +
> + tst_res(TINFO, "Scanning for NVMe devices in %s", NVME_DEV_PATH);
> +
> + while ((entry = readdir(dir)) != NULL) {
> + if (strncmp(entry->d_name, "nvme", 4) == 0 &&
> + strlen(entry->d_name) == 5) {
> + tst_res(TINFO, "Found NVMe controller: %s",
> entry->d_name);
> + strncpy(nvme_dev_name, entry->d_name,
> sizeof(nvme_dev_name) - 1);
> + found = 1;
> + nvme_device_found = 1;
> + }
> + }
> +
> + SAFE_CLOSEDIR(dir);
> +
> + if (found)
> + tst_res(TPASS, "NVMe controller(s) detected successfully");
> + else
> + tst_res(TCONF, "No NVMe controllers found in system");
> +}
> +
> +static void test_enumerate_namespaces(void)
> +{
> + DIR *dir;
> + struct dirent *entry;
> + int ns_count = 0;
> + char search_pattern[32];
> +
> + if (!nvme_device_found) {
> + tst_res(TCONF, "No NVMe device found, skipping namespace
> enumeration");
> + return;
> + }
> +
> + snprintf(search_pattern, sizeof(search_pattern), "%sn",
> nvme_dev_name);
> +
> + dir = SAFE_OPENDIR(NVME_DEV_PATH);
> +
> + tst_res(TINFO, "Enumerating namespaces for %s", nvme_dev_name);
> +
> + while ((entry = readdir(dir)) != NULL) {
> + if (strncmp(entry->d_name, search_pattern,
> strlen(search_pattern)) == 0) {
> + tst_res(TINFO, "Found namespace: %s",
> entry->d_name);
> + ns_count++;
> + }
> + }
> +
> + SAFE_CLOSEDIR(dir);
> +
> + if (ns_count > 0)
> + tst_res(TPASS, "Enumerated %d namespace(s) successfully",
> ns_count);
> + else
> + tst_res(TPASS, "No namespaces found for %s (device may not
> have namespaces configured)", nvme_dev_name);
> +}
> +
> +static void test_verify_pci_enumeration(void)
> +{
> + DIR *dir;
> + struct dirent *entry;
> + int found = 0;
> + char class_path[512];
> + FILE *fp;
> + char class_id[16];
> +
> + if (!nvme_device_found) {
> + tst_res(TCONF, "No NVMe device found, skipping PCI
> enumeration check");
> + return;
> + }
> +
> + dir = SAFE_OPENDIR(PCI_DEVICES_PATH);
> +
> + tst_res(TINFO, "Checking PCI enumeration for NVMe devices");
> +
> + while ((entry = readdir(dir)) != NULL) {
> + if (entry->d_name[0] == '.')
> + continue;
> +
> + snprintf(class_path, sizeof(class_path), "%s/%s/class",
> + PCI_DEVICES_PATH, entry->d_name);
> +
> + fp = SAFE_FOPEN(class_path, "r");
> +
> + if (fgets(class_id, sizeof(class_id), fp)) {
> + if (strncmp(class_id, "0x010802", 8) == 0) {
> + tst_res(TINFO, "Found NVMe PCI device: %s
> (class: %s)",
> + entry->d_name, class_id);
> + found = 1;
> + }
> + }
> + SAFE_FCLOSE(fp);
> + }
> +
> + SAFE_CLOSEDIR(dir);
> +
> + if (found)
> + tst_res(TPASS, "NVMe device properly enumerated on PCI
> bus");
> + else
> + tst_res(TFAIL, "NVMe device not found on PCI bus");
> +}
> +
> +static void test_check_driver_binding(void)
> +{
> + char driver_path[512];
> + char driver_link[512];
> +
> + if (!nvme_device_found) {
> + tst_res(TCONF, "No NVMe device found, skipping driver
> binding check");
> + return;
> + }
> +
> + snprintf(driver_path, sizeof(driver_path), "%s/%s/device/driver",
> + NVME_SYS_PATH, nvme_dev_name);
> +
> + SAFE_READLINK(driver_path, driver_link, sizeof(driver_link));
> +
> + tst_res(TINFO, "Driver binding: %s", driver_link);
> +
> + if (strstr(driver_link, "nvme") != NULL)
> + tst_res(TPASS, "NVMe driver properly bound to device");
> + else
> + tst_res(TFAIL, "Unexpected driver bound to NVMe device:
> %s", driver_link);
> +}
> +
> +static void setup(void)
> +{
> + if (access("/sys/module/nvme", F_OK) != 0)
> + tst_brk(TCONF, "NVMe kernel module not loaded");
> +
> + tst_res(TINFO, "NVMe Device Discovery & Identification Test");
> +}
> +
> +static void run(unsigned int n)
> +{
> + /* Reset state for each iteration */
> + nvme_device_found = 0;
> + memset(nvme_dev_name, 0, sizeof(nvme_dev_name));
> +
> + switch (n) {
> + case 0:
> + test_detect_nvme_controllers();
> + break;
> + case 1:
> + test_enumerate_namespaces();
> + break;
> + case 2:
> + test_verify_pci_enumeration();
> + break;
> + case 3:
> + test_check_driver_binding();
> + break;
> + }
> +}
> +
> +static struct tst_test test = {
> + .test = run,
> + .tcnt = 4,
> + .setup = setup,
> +};
> --
> 2.52.0
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test
2026-05-05 3:46 ` Sebastian Chlad
@ 2026-05-05 8:45 ` Daniel Wagner
2026-05-05 13:26 ` Daniel Wagner
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Wagner @ 2026-05-05 8:45 UTC (permalink / raw)
To: Sebastian Chlad, priyama2; +Cc: Shin'ichiro Kawasaki, daniel.wagner, ltp
Adding Shin'ichiro
On 5/5/26 5:46 AM, Sebastian Chlad wrote:
> Hi Priyama,
>
> Sorry for top-posting, but I have a broader question here.
>
> First of all, thanks for working on this and for looking into NVMe coverage.
>
> Before going further, could you please explain the intended LTP-specific
> value of
> this test? blktests already has a dedicated NVMe test group with much
> broader
> coverage, including controller/namespace discovery, NVMe commands,
> fabrics, etc.:
>
> https://github.com/linux-blktests/blktests/tree/master/tests/nvme
> <https://github.com/linux-blktests/blktests/tree/master/tests/nvme>
>
> So I think we should be careful not to duplicate coverage unless there
> is a clear
> reason for having a small LTP-level smoke test as well. Maybe your
> intention is
> different? Could you please clarify?
>
> Cheers,
> Sebastian
>
> On Thu, 30 Apr 2026 at 07:10, <priyama2@linux.ibm.com
> <mailto:priyama2@linux.ibm.com>> wrote:
>
> From: priyama2 <priyama2@linux.ibm.com <mailto:priyama2@linux.ibm.com>>
>
> This test fills a gap in NVMe test coverage by validating basic device
> enumeration and driver binding, which are fundamental prerequisites for
> any NVMe functionality testing.
>
> The test verifies:
> - Detection of NVMe controllers in /dev
> - Enumeration of namespaces for detected controllers
> - PCI enumeration (class code 0x010802)
> - NVMe driver binding
>
> Changes in v3:
> - Fix subject prefix to match directory path
> - Update copyright year to 2026
> - Add nvme to SUBDIRS in testcases/kernel/device-drivers/Makefile
> - Reset static variables at start of run() for -i support
> - Remove .needs_root (all operations are world-readable)
> - Use SAFE_FOPEN/SAFE_FCLOSE for PCI class file access
> - Use SAFE_READLINK for driver symlink reading
> - Add .gitignore entry for nvme01 binary
> - Add runtest/device-drivers entry for nvme01
> - Fix author field to use priyama2
>
> Changes in v2:
> - Use LTP buildsystem instead of standalone Makefile
> - Remove README file (use doc comments instead)
> - Add proper LTP documentation comment format
> - Use SAFE_OPENDIR() and SAFE_CLOSEDIR() macros
> - Remove obvious and redundant comments
> - Code cleanup and style improvements
>
> Signed-off-by: priyama2 <priyama2@linux.ibm.com
> <mailto:priyama2@linux.ibm.com>>
> ---
> runtest/device-drivers | 1 +
> testcases/kernel/device-drivers/Makefile | 1 +
> .../kernel/device-drivers/nvme/.gitignore | 1 +
> testcases/kernel/device-drivers/nvme/Makefile | 7 +
> testcases/kernel/device-drivers/nvme/nvme01.c | 205 ++++++++++++++++++
> 5 files changed, 215 insertions(+)
> create mode 100644 runtest/device-drivers
> create mode 100644 testcases/kernel/device-drivers/nvme/.gitignore
> create mode 100644 testcases/kernel/device-drivers/nvme/Makefile
> create mode 100644 testcases/kernel/device-drivers/nvme/nvme01.c
>
> diff --git a/runtest/device-drivers b/runtest/device-drivers
> new file mode 100644
> index 000000000..a7295584e
> --- /dev/null
> +++ b/runtest/device-drivers
> @@ -0,0 +1 @@
> +nvme01 nvme01
> diff --git a/testcases/kernel/device-drivers/Makefile b/testcases/
> kernel/device-drivers/Makefile
> index 229a50683..664f4cd18 100644
> --- a/testcases/kernel/device-drivers/Makefile
> +++ b/testcases/kernel/device-drivers/Makefile
> @@ -9,6 +9,7 @@ SUBDIRS := acpi \
> block \
> cpufreq \
> locking \
> + nvme \
> pci \
> rcu \
> rtc \
> diff --git a/testcases/kernel/device-drivers/nvme/.gitignore b/
> testcases/kernel/device-drivers/nvme/.gitignore
> new file mode 100644
> index 000000000..c60bc210c
> --- /dev/null
> +++ b/testcases/kernel/device-drivers/nvme/.gitignore
> @@ -0,0 +1 @@
> +nvme01
> diff --git a/testcases/kernel/device-drivers/nvme/Makefile b/
> testcases/kernel/device-drivers/nvme/Makefile
> new file mode 100644
> index 000000000..d47e99e6a
> --- /dev/null
> +++ b/testcases/kernel/device-drivers/nvme/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (c) 2024 IBM Corporation
> +
> +top_srcdir ?= ../../../..
> +
> +include $(top_srcdir)/include/mk/env_pre.mk <http://env_pre.mk>
> +include $(top_srcdir)/include/mk/generic_trunk_target.mk <http://
> generic_trunk_target.mk>
> diff --git a/testcases/kernel/device-drivers/nvme/nvme01.c b/
> testcases/kernel/device-drivers/nvme/nvme01.c
> new file mode 100644
> index 000000000..3c3cb92ce
> --- /dev/null
> +++ b/testcases/kernel/device-drivers/nvme/nvme01.c
> @@ -0,0 +1,205 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2026 IBM Corporation
> + * Author: priyama2 <priyama2@linux.ibm.com
> <mailto:priyama2@linux.ibm.com>>
> + */
> +
> +/* * [Description]
> + *
> + * Verify NVMe device discovery and identification.
> + *
> + * This test fills a gap in NVMe test coverage by validating basic
> device
> + * enumeration and driver binding, which are fundamental
> prerequisites for
> + * any NVMe functionality testing.
> + *
> + * - Detect NVMe controllers in /dev
> + * - Enumerate namespaces for detected controllers
> + * - Verify PCI enumeration (class code 0x010802)
> + * - Check NVMe driver binding
> + */
> +
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <dirent.h>
> +#include <errno.h>
> +
> +#include "tst_test.h"
> +#include "tst_safe_stdio.h"
> +
> +#define NVME_DEV_PATH "/dev"
> +#define NVME_SYS_PATH "/sys/class/nvme"
> +#define PCI_DEVICES_PATH "/sys/bus/pci/devices"
> +
> +static int nvme_device_found;
> +static char nvme_dev_name[256];
> +
> +static void test_detect_nvme_controllers(void)
> +{
> + DIR *dir;
> + struct dirent *entry;
> + int found = 0;
> +
> + dir = SAFE_OPENDIR(NVME_DEV_PATH);
> +
> + tst_res(TINFO, "Scanning for NVMe devices in %s",
> NVME_DEV_PATH);
> +
> + while ((entry = readdir(dir)) != NULL) {
> + if (strncmp(entry->d_name, "nvme", 4) == 0 &&
> + strlen(entry->d_name) == 5) {
> + tst_res(TINFO, "Found NVMe controller: %s",
> entry->d_name);
> + strncpy(nvme_dev_name, entry->d_name,
> sizeof(nvme_dev_name) - 1);
> + found = 1;
> + nvme_device_found = 1;
> + }
> + }
> +
> + SAFE_CLOSEDIR(dir);
> +
> + if (found)
> + tst_res(TPASS, "NVMe controller(s) detected
> successfully");
> + else
> + tst_res(TCONF, "No NVMe controllers found in system");
> +}
> +
> +static void test_enumerate_namespaces(void)
> +{
> + DIR *dir;
> + struct dirent *entry;
> + int ns_count = 0;
> + char search_pattern[32];
> +
> + if (!nvme_device_found) {
> + tst_res(TCONF, "No NVMe device found, skipping
> namespace enumeration");
> + return;
> + }
> +
> + snprintf(search_pattern, sizeof(search_pattern), "%sn",
> nvme_dev_name);
> +
> + dir = SAFE_OPENDIR(NVME_DEV_PATH);
> +
> + tst_res(TINFO, "Enumerating namespaces for %s", nvme_dev_name);
> +
> + while ((entry = readdir(dir)) != NULL) {
> + if (strncmp(entry->d_name, search_pattern,
> strlen(search_pattern)) == 0) {
> + tst_res(TINFO, "Found namespace: %s", entry-
> >d_name);
> + ns_count++;
> + }
> + }
> +
> + SAFE_CLOSEDIR(dir);
> +
> + if (ns_count > 0)
> + tst_res(TPASS, "Enumerated %d namespace(s)
> successfully", ns_count);
> + else
> + tst_res(TPASS, "No namespaces found for %s (device
> may not have namespaces configured)", nvme_dev_name);
> +}
> +
> +static void test_verify_pci_enumeration(void)
> +{
> + DIR *dir;
> + struct dirent *entry;
> + int found = 0;
> + char class_path[512];
> + FILE *fp;
> + char class_id[16];
> +
> + if (!nvme_device_found) {
> + tst_res(TCONF, "No NVMe device found, skipping PCI
> enumeration check");
> + return;
> + }
> +
> + dir = SAFE_OPENDIR(PCI_DEVICES_PATH);
> +
> + tst_res(TINFO, "Checking PCI enumeration for NVMe devices");
> +
> + while ((entry = readdir(dir)) != NULL) {
> + if (entry->d_name[0] == '.')
> + continue;
> +
> + snprintf(class_path, sizeof(class_path), "%s/%s/class",
> + PCI_DEVICES_PATH, entry->d_name);
> +
> + fp = SAFE_FOPEN(class_path, "r");
> +
> + if (fgets(class_id, sizeof(class_id), fp)) {
> + if (strncmp(class_id, "0x010802", 8) == 0) {
> + tst_res(TINFO, "Found NVMe PCI
> device: %s (class: %s)",
> + entry->d_name, class_id);
> + found = 1;
> + }
> + }
> + SAFE_FCLOSE(fp);
> + }
> +
> + SAFE_CLOSEDIR(dir);
> +
> + if (found)
> + tst_res(TPASS, "NVMe device properly enumerated on
> PCI bus");
> + else
> + tst_res(TFAIL, "NVMe device not found on PCI bus");
> +}
> +
> +static void test_check_driver_binding(void)
> +{
> + char driver_path[512];
> + char driver_link[512];
> +
> + if (!nvme_device_found) {
> + tst_res(TCONF, "No NVMe device found, skipping
> driver binding check");
> + return;
> + }
> +
> + snprintf(driver_path, sizeof(driver_path), "%s/%s/device/
> driver",
> + NVME_SYS_PATH, nvme_dev_name);
> +
> + SAFE_READLINK(driver_path, driver_link, sizeof(driver_link));
> +
> + tst_res(TINFO, "Driver binding: %s", driver_link);
> +
> + if (strstr(driver_link, "nvme") != NULL)
> + tst_res(TPASS, "NVMe driver properly bound to device");
> + else
> + tst_res(TFAIL, "Unexpected driver bound to NVMe
> device: %s", driver_link);
> +}
> +
> +static void setup(void)
> +{
> + if (access("/sys/module/nvme", F_OK) != 0)
> + tst_brk(TCONF, "NVMe kernel module not loaded");
> +
> + tst_res(TINFO, "NVMe Device Discovery & Identification Test");
> +}
> +
> +static void run(unsigned int n)
> +{
> + /* Reset state for each iteration */
> + nvme_device_found = 0;
> + memset(nvme_dev_name, 0, sizeof(nvme_dev_name));
> +
> + switch (n) {
> + case 0:
> + test_detect_nvme_controllers();
> + break;
> + case 1:
> + test_enumerate_namespaces();
> + break;
> + case 2:
> + test_verify_pci_enumeration();
> + break;
> + case 3:
> + test_check_driver_binding();
> + break;
> + }
> +}
> +
> +static struct tst_test test = {
> + .test = run,
> + .tcnt = 4,
> + .setup = setup,
> +};
> --
> 2.52.0
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp <https://
> lists.linux.it/listinfo/ltp>
>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test
2026-05-05 8:45 ` Daniel Wagner
@ 2026-05-05 13:26 ` Daniel Wagner
0 siblings, 0 replies; 10+ messages in thread
From: Daniel Wagner @ 2026-05-05 13:26 UTC (permalink / raw)
To: Sebastian Chlad, priyama2; +Cc: Shin'ichiro Kawasaki, daniel.wagner, ltp
Hi,
On 5/5/26 10:45 AM, Daniel Wagner wrote:
>> Before going further, could you please explain the intended LTP-
>> specific value of
>> this test? blktests already has a dedicated NVMe test group with much
>> broader
>> coverage, including controller/namespace discovery, NVMe commands,
>> fabrics, etc.:
I’ve had a quick look at the test attached to this email and I
completely agree with Sebastian. This should go into blktests.
We already have a good collection of NVMe-specific tests there, so it
would be a perfect fit. Plus, the upstream developers run the blktests
suite regularly against both the mainline and 'nvme-next' branches.
Moving it there would help us catch any NVMe issues very early on.
Honestly, I’m not quite sure how often LTP is executed for NVMe, so this
feels like the safer bet!
Thanks,
Daniel
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 10+ messages in thread
* [LTP] [PATCH] testcases/nvme: Add NVMe device discovery and identification test
@ 2026-04-29 10:51 priyama2
2026-04-28 2:58 ` [LTP] " linuxtestproject.agent
0 siblings, 1 reply; 10+ messages in thread
From: priyama2 @ 2026-04-29 10:51 UTC (permalink / raw)
To: ltp
This patch introduces the first test case (nvme01) for NVMe device
testing in LTP. The test verifies:
- Detection of NVMe controllers in the system
- Enumeration of NVMe namespaces
- PCI bus enumeration verification
- Driver binding validation
The test uses the LTP test framework (tst_test.h) and follows LTP
coding standards. It provides comprehensive coverage for basic NVMe
device discovery functionality.
Tested on:
- System: ppc64le, RHEL 10.2
- Kernel: 6.12.0-210.el10.ppc64le
- Hardware: Samsung PM1735a NVMe devices
- Result: All 4 test cases passed
This is the first in a series of patches to add comprehensive NVMe
testing support to LTP.
Signed-off-by: priyama2 <priyama2@linux.ibm.com>
---
testcases/kernel/device-drivers/nvme/Makefile | 42 ++++
testcases/kernel/device-drivers/nvme/README | 155 ++++++++++++
testcases/kernel/device-drivers/nvme/nvme01.c | 236 ++++++++++++++++++
3 files changed, 433 insertions(+)
create mode 100644 testcases/kernel/device-drivers/nvme/Makefile
create mode 100644 testcases/kernel/device-drivers/nvme/README
create mode 100644 testcases/kernel/device-drivers/nvme/nvme01.c
diff --git a/testcases/kernel/device-drivers/nvme/Makefile b/testcases/kernel/device-drivers/nvme/Makefile
new file mode 100644
index 000000000..ace6696f6
--- /dev/null
+++ b/testcases/kernel/device-drivers/nvme/Makefile
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2024 IBM Corporation
+#
+# Standalone Makefile for NVMe LTP test suite
+
+# Compiler and flags
+CC = gcc
+CFLAGS = -Wall -O2 -I/opt/ltp/include
+LDFLAGS = -L/opt/ltp/lib
+LDLIBS = -lltp -lrt
+
+# Test binaries
+TARGETS = nvme01 nvme02 nvme03 nvme04
+
+# Build all tests
+all: $(TARGETS)
+
+nvme01: nvme01.c
+ $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDLIBS)
+
+nvme02: nvme02.c
+ $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDLIBS)
+
+nvme03: nvme03.c
+ $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDLIBS)
+
+nvme04: nvme04.c
+ $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDLIBS)
+
+# Install targets
+install: $(TARGETS)
+ @mkdir -p /opt/ltp/testcases/bin
+ @for target in $(TARGETS); do \
+ install -m 0755 $$target /opt/ltp/testcases/bin/; \
+ done
+ @echo "Tests installed to /opt/ltp/testcases/bin/"
+
+# Clean
+clean:
+ rm -f $(TARGETS) *.o
+
+.PHONY: all install clean
\ No newline at end of file
diff --git a/testcases/kernel/device-drivers/nvme/README b/testcases/kernel/device-drivers/nvme/README
new file mode 100644
index 000000000..6ee5796fe
--- /dev/null
+++ b/testcases/kernel/device-drivers/nvme/README
@@ -0,0 +1,155 @@
+NVMe Test Suite for Linux Test Project (LTP)
+==============================================
+
+This directory contains test cases for NVMe (Non-Volatile Memory Express)
+device functionality testing.
+
+Test Cases
+----------
+
+1. nvme01 - Device Discovery & Identification
+ Tests:
+ - Detect NVMe controllers
+ - Enumerate namespaces
+ - Verify PCI enumeration
+ - Check driver binding
+
+2. nvme02 - Namespace Management
+ Tests:
+ - Create namespaces (various sizes)
+ - Delete namespaces
+ - Attach/detach namespaces to controllers
+ - Resize namespaces
+ - Format namespaces (different block sizes: 512B, 4KB)
+ - Namespace sharing across controllers
+
+3. nvme03 - I/O Operations
+ Tests:
+ - Sequential read/write operations
+ - Random read/write operations
+ - Mixed workloads
+ - Different block sizes (512B, 4KB, 8KB)
+ - Queue depth variations
+ - Direct I/O vs buffered I/O
+
+4. nvme04 - Multipath & Redundancy
+ Tests:
+ - Path failover testing
+ - Load balancing across paths
+ - Path recovery
+ - ANA (Asymmetric Namespace Access) states
+ - Controller failover
+
+Requirements
+------------
+
+Hardware:
+- System with NVMe storage device(s)
+- For multipath tests: NVMe device with multiple paths configured
+
+Software:
+- Linux kernel with NVMe support (CONFIG_BLK_DEV_NVME=y)
+- nvme-cli tools (for namespace management tests)
+- Root/sudo privileges
+
+Building
+--------
+
+From the LTP root directory:
+ make -C testcases/kernel/device-drivers/nvme
+
+Or from this directory:
+ make
+
+Running Tests
+-------------
+
+Individual test execution:
+ ./nvme01
+ ./nvme02
+ ./nvme03
+ ./nvme04
+
+Using LTP runtest:
+ runltp -f nvme
+
+Using runtest file:
+ runltp -f /opt/ltp/runtest/nvme
+
+Test Results
+------------
+
+Tests use standard LTP result codes:
+- TPASS: Test passed
+- TFAIL: Test failed
+- TCONF: Test not configured (e.g., no NVMe device found)
+- TBROK: Test broken (setup failure)
+- TWARN: Test warning
+
+Notes
+-----
+
+1. Some tests require specific hardware configurations:
+ - nvme02: May require namespace management support
+ - nvme04: Requires multipath configuration for full testing
+
+2. Destructive tests:
+ - nvme02 includes namespace creation/deletion which may affect data
+ - Always run on test systems or with proper backups
+
+3. Performance tests (nvme03):
+ - Results vary based on hardware and system load
+ - Tests measure relative performance, not absolute benchmarks
+
+4. Root privileges:
+ - All tests require root access for device operations
+
+Test Coverage
+-------------
+
+The test suite covers:
+- Basic NVMe device detection and enumeration
+- Namespace lifecycle management
+- I/O performance characteristics
+- Multipath and redundancy features
+- Driver and controller state verification
+
+Known Limitations
+-----------------
+
+1. Namespace management tests may not work on all NVMe devices
+ (depends on controller capabilities)
+
+2. Multipath tests require specific hardware and kernel configuration
+
+3. Some tests are informational and may show TCONF on systems
+ without full NVMe feature support
+
+Contributing
+------------
+
+When adding new tests:
+1. Follow LTP coding standards
+2. Use tst_test.h framework
+3. Include proper error handling
+4. Document test purpose and requirements
+5. Test on multiple NVMe device types if possible
+
+References
+----------
+
+- NVMe Specification: https://nvmexpress.org/specifications/
+- Linux NVMe Driver: Documentation/block/nvme.rst
+- nvme-cli: https://github.com/linux-nvme/nvme-cli
+- LTP Documentation: https://linux-test-project.github.io/
+
+Authors
+-------
+
+Copyright (c) 2024 IBM Corporation
+LTP NVMe Test Suite
+
+License
+-------
+
+SPDX-License-Identifier: GPL-2.0-or-later
\ No newline at end of file
diff --git a/testcases/kernel/device-drivers/nvme/nvme01.c b/testcases/kernel/device-drivers/nvme/nvme01.c
new file mode 100644
index 000000000..82fbd315b
--- /dev/null
+++ b/testcases/kernel/device-drivers/nvme/nvme01.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2024 IBM Corporation
+ * Author: LTP NVMe Test Suite
+ *
+ * Test: NVMe Device Discovery & Identification
+ *
+ * This test verifies:
+ * - Detection of NVMe controllers
+ * - Enumeration of namespaces
+ * - PCI enumeration verification
+ * - Driver binding check
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include "tst_test.h"
+
+#define NVME_DEV_PATH "/dev"
+#define NVME_SYS_PATH "/sys/class/nvme"
+#define PCI_DEVICES_PATH "/sys/bus/pci/devices"
+
+static int nvme_device_found = 0;
+static char nvme_dev_name[256];
+
+/*
+ * Test Case 1: Detect NVMe Controllers
+ * Verifies that NVMe controllers are present in the system
+ */
+static void test_detect_nvme_controllers(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int found = 0;
+
+ dir = opendir(NVME_DEV_PATH);
+ if (!dir) {
+ tst_brk(TBROK | TERRNO, "Failed to open %s", NVME_DEV_PATH);
+ return;
+ }
+
+ tst_res(TINFO, "Scanning for NVMe devices in %s", NVME_DEV_PATH);
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (strncmp(entry->d_name, "nvme", 4) == 0 &&
+ strlen(entry->d_name) == 5) { /* nvme0, nvme1, etc. */
+ tst_res(TINFO, "Found NVMe controller: %s", entry->d_name);
+ strncpy(nvme_dev_name, entry->d_name, sizeof(nvme_dev_name) - 1);
+ found = 1;
+ nvme_device_found = 1;
+ }
+ }
+
+ closedir(dir);
+
+ if (found)
+ tst_res(TPASS, "NVMe controller(s) detected successfully");
+ else
+ tst_res(TCONF, "No NVMe controllers found in system");
+}
+
+/*
+ * Test Case 2: Enumerate Namespaces
+ * Verifies that NVMe namespaces can be enumerated
+ */
+static void test_enumerate_namespaces(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int ns_count = 0;
+ char search_pattern[32];
+
+ if (!nvme_device_found) {
+ tst_res(TCONF, "No NVMe device found, skipping namespace enumeration");
+ return;
+ }
+
+ snprintf(search_pattern, sizeof(search_pattern), "%sn", nvme_dev_name);
+
+ dir = opendir(NVME_DEV_PATH);
+ if (!dir) {
+ tst_brk(TBROK | TERRNO, "Failed to open %s", NVME_DEV_PATH);
+ return;
+ }
+
+ tst_res(TINFO, "Enumerating namespaces for %s", nvme_dev_name);
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (strncmp(entry->d_name, search_pattern, strlen(search_pattern)) == 0) {
+ tst_res(TINFO, "Found namespace: %s", entry->d_name);
+ ns_count++;
+ }
+ }
+
+ closedir(dir);
+
+ if (ns_count > 0)
+ tst_res(TPASS, "Enumerated %d namespace(s) successfully", ns_count);
+ else
+ tst_res(TPASS, "No namespaces found for %s (device may not have namespaces configured)", nvme_dev_name);
+}
+
+/*
+ * Test Case 3: Verify PCI Enumeration
+ * Checks if NVMe device is properly enumerated on PCI bus
+ */
+static void test_verify_pci_enumeration(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int found = 0;
+ char class_path[512];
+ FILE *fp;
+ char class_id[16];
+
+ if (!nvme_device_found) {
+ tst_res(TCONF, "No NVMe device found, skipping PCI enumeration check");
+ return;
+ }
+
+ dir = opendir(PCI_DEVICES_PATH);
+ if (!dir) {
+ tst_brk(TBROK | TERRNO, "Failed to open %s", PCI_DEVICES_PATH);
+ return;
+ }
+
+ tst_res(TINFO, "Checking PCI enumeration for NVMe devices");
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (entry->d_name[0] == '.')
+ continue;
+
+ snprintf(class_path, sizeof(class_path), "%s/%s/class",
+ PCI_DEVICES_PATH, entry->d_name);
+
+ fp = fopen(class_path, "r");
+ if (!fp)
+ continue;
+
+ if (fgets(class_id, sizeof(class_id), fp)) {
+ /* NVMe class code is 0x010802 (Mass storage controller: NVM Express) */
+ if (strncmp(class_id, "0x010802", 8) == 0) {
+ tst_res(TINFO, "Found NVMe PCI device: %s (class: %s)",
+ entry->d_name, class_id);
+ found = 1;
+ }
+ }
+ fclose(fp);
+ }
+
+ closedir(dir);
+
+ if (found)
+ tst_res(TPASS, "NVMe device properly enumerated on PCI bus");
+ else
+ tst_res(TFAIL, "NVMe device not found on PCI bus");
+}
+
+/*
+ * Test Case 4: Check Driver Binding
+ * Verifies that NVMe driver is properly bound to the device
+ */
+static void test_check_driver_binding(void)
+{
+ char driver_path[512];
+ char driver_link[512];
+ ssize_t len;
+
+ if (!nvme_device_found) {
+ tst_res(TCONF, "No NVMe device found, skipping driver binding check");
+ return;
+ }
+
+ snprintf(driver_path, sizeof(driver_path), "%s/%s/device/driver",
+ NVME_SYS_PATH, nvme_dev_name);
+
+ len = readlink(driver_path, driver_link, sizeof(driver_link) - 1);
+ if (len == -1) {
+ tst_res(TFAIL | TERRNO, "Failed to read driver symlink for %s", nvme_dev_name);
+ return;
+ }
+
+ driver_link[len] = '\0';
+
+ tst_res(TINFO, "Driver binding: %s", driver_link);
+
+ if (strstr(driver_link, "nvme") != NULL)
+ tst_res(TPASS, "NVMe driver properly bound to device");
+ else
+ tst_res(TFAIL, "Unexpected driver bound to NVMe device: %s", driver_link);
+}
+
+static void setup(void)
+{
+ /* Check if nvme module is loaded */
+ if (access("/sys/module/nvme", F_OK) != 0)
+ tst_brk(TCONF, "NVMe kernel module not loaded");
+
+ tst_res(TINFO, "NVMe Device Discovery & Identification Test");
+}
+
+static void run(unsigned int n)
+{
+ switch (n) {
+ case 0:
+ test_detect_nvme_controllers();
+ break;
+ case 1:
+ test_enumerate_namespaces();
+ break;
+ case 2:
+ test_verify_pci_enumeration();
+ break;
+ case 3:
+ test_check_driver_binding();
+ break;
+ }
+}
+
+static struct tst_test test = {
+ .test = run,
+ .tcnt = 4,
+ .setup = setup,
+ .needs_root = 1,
+};
+
+// Made with Bob
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [LTP] testcases/nvme: Add NVMe device discovery and identification test
2026-04-29 10:51 [LTP] [PATCH] testcases/nvme: Add NVMe device discovery and identification test priyama2
@ 2026-04-28 2:58 ` linuxtestproject.agent
0 siblings, 0 replies; 10+ messages in thread
From: linuxtestproject.agent @ 2026-04-28 2:58 UTC (permalink / raw)
To: priyama2; +Cc: ltp
Hi priyama2,
On Wed, 29 Apr 2026, priyama2 wrote:
> testcases/nvme: Add NVMe device discovery and identification test
> This patch introduces the first test case (nvme01) for NVMe device
> testing in LTP. The test verifies: [...]
The commit body describes what the test does and what hardware it was
run on, but doesn't explain *why* this test is being added to LTP —
what gap does it fill, or what problem prompted writing it?
> +TARGETS = nvme01 nvme02 nvme03 nvme04
nvme02.c, nvme03.c, nvme04.c are not present in this patch, so `make`
will fail. Remove the missing targets (and their explicit rules) from
this patch; add them when those tests land.
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2024 IBM Corporation
> + * Author: LTP NVMe Test Suite
Copyright year must be 2026 for a newly added file. "Author: LTP NVMe
Test Suite" is not a real author; use your name and email. Also, the
test description must be in a separate /*\ RST block (not merged into
the copyright block).
> + dir = opendir(NVME_DEV_PATH);
> + if (!dir) {
> + tst_brk(TBROK | TERRNO, "Failed to open %s", NVME_DEV_PATH);
Use SAFE_OPENDIR() here (and SAFE_FOPEN() / SAFE_CLOSEDIR() /
SAFE_FCLOSE() elsewhere). These are defined in tst_safe_macros.h and
tst_safe_stdio.h.
> +static int nvme_device_found = 0;
> +static char nvme_dev_name[256];
Both static vars are set in case 0 of run() but never reset. Under
`-i` (iteration), subsequent iterations inherit stale state. Reset
them at the top of run().
> + .needs_root = 1,
All operations in this test are unprivileged sysfs/devfs reads. Drop
.needs_root.
> +CC = gcc
> +CFLAGS = -Wall -O2 -I/opt/ltp/include
> +LDFLAGS = -L/opt/ltp/lib
This is a hand-rolled standalone Makefile with hardcoded paths. Replace
it with LTP's build system (env_pre.mk + generic_leaf_target.mk). Also
add `nvme` to SUBDIRS in testcases/kernel/device-drivers/Makefile, and
add a runtest entry and .gitignore entry for nvme01.
[...]
Pre-existing issues noticed in the surrounding code (not introduced by
this patch):
- nvme01.c:236 — Stray `// Made with Bob` comment at end of file.
- nvme01.c:58 — `strlen(entry->d_name) == 5` silently skips nvme10+.
---
Note:
Our agent completed the review of the patch. The full review can be
found at: https://github.com/linux-test-project/ltp-agent/actions/runs/25031212578
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <20260430154852.896072-1-priyama2@linux.ibm.com>]
* Re: [LTP] testcases/nvme: Add NVMe device discovery and identification test
[not found] <20260430154852.896072-1-priyama2@linux.ibm.com>
@ 2026-04-29 7:33 ` linuxtestproject.agent
0 siblings, 0 replies; 10+ messages in thread
From: linuxtestproject.agent @ 2026-04-29 7:33 UTC (permalink / raw)
To: priyama2; +Cc: ltp
Hi Priya,
On Thu, 30 Apr 2026 15:48:52 +0000, priyama2 wrote:
> testcases/nvme: Add NVMe device discovery and identification test
>
> This test verifies NVMe device discovery and identification by:
> - Detecting NVMe controllers in /dev
> [...]
The commit body describes what the test does but not why it is needed —
what coverage gap does this fill? Also, "Changes in v2:" belongs in the
cover letter, not the commit body; strip it before sending.
> +++ b/testcases/kernel/device-drivers/nvme/nvme01
> new file mode 100755
> Bin 0 -> 995536 bytes
Do not commit compiled binaries. Remove nvme01 from the patch and add a
.gitignore in the test directory listing it.
> + * Copyright (c) 2024 IBM Corporation
This file is new and added in 2026; use the current year.
> +static int nvme_device_found;
> +static char nvme_dev_name[256];
These statics are set in case 0 of run() but never cleared. With -i,
stale state from a prior iteration persists into subsequent ones. Reset
them at the top of run().
> + .needs_root = 1,
No operation in this test requires root. All reads from /dev and sysfs
are accessible to unprivileged users. Drop needs_root.
The patch is also missing a runtest entry (e.g. in runtest/drivers) and
a .gitignore entry for the nvme01 binary.
---
Note:
Our agent completed the review of the patch.
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-05-05 13:30 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260428075302.7320ef7e3@imap1.dmz-prg2.suse.org>
2026-04-30 15:52 ` [LTP] [PATCH v2] testcases/nvme: Add NVMe device discovery and identification test priyama2
2026-04-29 7:33 ` [LTP] " linuxtestproject.agent
2026-05-01 15:14 ` [LTP] [PATCH v3] testcases/kernel/device-drivers/nvme: Add NVMe device discovery test priyama2
2026-04-30 6:35 ` [LTP] " linuxtestproject.agent
2026-05-04 10:40 ` [LTP] [PATCH v3] " Andrea Cervesato via ltp
2026-05-05 3:46 ` Sebastian Chlad
2026-05-05 8:45 ` Daniel Wagner
2026-05-05 13:26 ` Daniel Wagner
2026-04-29 10:51 [LTP] [PATCH] testcases/nvme: Add NVMe device discovery and identification test priyama2
2026-04-28 2:58 ` [LTP] " linuxtestproject.agent
[not found] <20260430154852.896072-1-priyama2@linux.ibm.com>
2026-04-29 7:33 ` linuxtestproject.agent
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox