git: ad9dc97e4dce - main - nvmecontrol devlist: Handle disconnected Fabrics hosts
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 31 Jan 2025 20:49:41 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=ad9dc97e4dce478452edc4877020adf37ff5790c
commit ad9dc97e4dce478452edc4877020adf37ff5790c
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2025-01-31 20:48:21 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-01-31 20:48:21 +0000
nvmecontrol devlist: Handle disconnected Fabrics hosts
If a Fabrics host is disconnected, use the cached controller data
instead of reading the cdata via a pass-through command. In addition,
annotate disconnected hosts including the amount of time since the
connection was lost.
Reviewed by: chuck
Sponsored by: Chelsio Communications
Differential Revision: https://reviews.freebsd.org/D48220
---
sbin/nvmecontrol/devlist.c | 63 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 57 insertions(+), 6 deletions(-)
diff --git a/sbin/nvmecontrol/devlist.c b/sbin/nvmecontrol/devlist.c
index d2386e7ea800..31445a2ef920 100644
--- a/sbin/nvmecontrol/devlist.c
+++ b/sbin/nvmecontrol/devlist.c
@@ -27,11 +27,14 @@
*/
#include <sys/param.h>
+#include <sys/nv.h>
+#include <sys/time.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
+#include <libnvmf.h>
#include <libutil.h>
#include <paths.h>
#include <stddef.h>
@@ -39,6 +42,7 @@
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
+#include <time.h>
#include <unistd.h>
#include "nvmecontrol.h"
@@ -113,12 +117,62 @@ scan_namespace(int fd, int ctrlr, uint32_t nsid)
}
static bool
-scan_controller(int ctrlr)
+print_controller_info(const char *name, int fd)
{
+ static struct timespec now;
struct nvme_controller_data cdata;
+ struct timespec last_disconnect, delta;
+ uint8_t mn[64];
+ nvlist_t *nvl;
+ const nvlist_t *nvl_ts;
+ bool connected;
+
+ /*
+ * If the controller doesn't support connection status, assume
+ * it is connected.
+ */
+ if (nvmf_connection_status(fd, &nvl) != 0) {
+ connected = true;
+ nvl = NULL;
+ } else {
+ connected = nvlist_get_bool(nvl, "connected");
+ }
+
+ if (connected) {
+ if (read_controller_data(fd, &cdata) != 0) {
+ nvlist_destroy(nvl);
+ return (false);
+ }
+ } else {
+ if (ioctl(fd, NVME_GET_CONTROLLER_DATA, &cdata) == -1) {
+ nvlist_destroy(nvl);
+ return (false);
+ }
+ }
+
+ nvme_strvis(mn, cdata.mn, sizeof(mn), NVME_MODEL_NUMBER_LENGTH);
+ printf("%6s: %s", name, mn);
+ if (!connected) {
+ if (now.tv_sec == 0)
+ clock_gettime(CLOCK_REALTIME, &now);
+
+ nvl_ts = nvlist_get_nvlist(nvl, "last_disconnect");
+ last_disconnect.tv_sec = nvlist_get_number(nvl_ts, "tv_sec");
+ last_disconnect.tv_nsec = nvlist_get_number(nvl_ts, "tv_nsec");
+ timespecsub(&now, &last_disconnect, &delta);
+ printf(" (disconnected for %ju seconds)",
+ (uintmax_t)delta.tv_sec);
+ }
+ printf("\n");
+ nvlist_destroy(nvl);
+ return (connected);
+}
+
+static bool
+scan_controller(int ctrlr)
+{
struct nvme_ns_list nslist;
char name[64];
- uint8_t mn[64];
uint32_t nsid;
int fd, ret;
@@ -132,14 +186,11 @@ scan_controller(int ctrlr)
} else if (ret != 0)
return (false);
- if (read_controller_data(fd, &cdata) != 0) {
+ if (!print_controller_info(name, fd)) {
close(fd);
return (true);
}
- nvme_strvis(mn, cdata.mn, sizeof(mn), NVME_MODEL_NUMBER_LENGTH);
- printf("%6s: %s\n", name, mn);
-
nsid = 0;
for (;;) {
if (read_active_namespaces(fd, nsid, &nslist) != 0)