240 lines
8.2 KiB
Diff
240 lines
8.2 KiB
Diff
|
From ab841e9a58688e64c5ce50e6159f34fc1a414c48 Mon Sep 17 00:00:00 2001
|
||
|
From: Martin George <marting@netapp.com>
|
||
|
Date: Mon, 11 Nov 2024 22:08:39 +0530
|
||
|
Subject: [PATCH] netapp-ontapdev: add verbose output
|
||
|
|
||
|
Add a vebose output option to display additional information of
|
||
|
ONTAP devices on the host.
|
||
|
|
||
|
Signed-off-by: Martin George <marting@netapp.com>
|
||
|
---
|
||
|
plugins/netapp/netapp-nvme.c | 141 +++++++++++++++++++++++++++++++----
|
||
|
1 file changed, 126 insertions(+), 15 deletions(-)
|
||
|
|
||
|
diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c
|
||
|
index 9f05ffc5..cebd019e 100644
|
||
|
--- a/plugins/netapp/netapp-nvme.c
|
||
|
+++ b/plugins/netapp/netapp-nvme.c
|
||
|
@@ -119,6 +119,42 @@ static void netapp_get_ns_size(char *size, unsigned long long *lba,
|
||
|
sprintf(size, "%.2f%sB", nsze, s_suffix);
|
||
|
}
|
||
|
|
||
|
+static void netapp_get_ns_attrs(char *size, char *used, char *blk_size,
|
||
|
+ char *version, unsigned long long *lba,
|
||
|
+ struct nvme_id_ctrl *ctrl, struct nvme_id_ns *ns)
|
||
|
+{
|
||
|
+ __u8 lba_index;
|
||
|
+
|
||
|
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
|
||
|
+ *lba = 1ULL << ns->lbaf[lba_index].ds;
|
||
|
+
|
||
|
+ /* get the namespace size */
|
||
|
+ double nsze = le64_to_cpu(ns->nsze) * (*lba);
|
||
|
+ const char *s_suffix = suffix_si_get(&nsze);
|
||
|
+
|
||
|
+ sprintf(size, "%.2f%sB", nsze, s_suffix);
|
||
|
+
|
||
|
+ /* get the namespace utilization */
|
||
|
+ double nuse = le64_to_cpu(ns->nuse) * (*lba);
|
||
|
+ const char *u_suffix = suffix_si_get(&nuse);
|
||
|
+
|
||
|
+ sprintf(used, "%.2f%sB", nuse, u_suffix);
|
||
|
+
|
||
|
+ /* get the namespace block size */
|
||
|
+ long long addr = 1LL << ns->lbaf[lba_index].ds;
|
||
|
+ const char *l_suffix = suffix_binary_get(&addr);
|
||
|
+
|
||
|
+ sprintf(blk_size, "%u%sB", (unsigned int)addr, l_suffix);
|
||
|
+
|
||
|
+ /* get the ontap version */
|
||
|
+ int i, max = sizeof(ctrl->fr);
|
||
|
+
|
||
|
+ memcpy(version, ctrl->fr, sizeof(ctrl->fr));
|
||
|
+ /* strip trailing whitespaces */
|
||
|
+ for (i = max - 1; i >= 0 && version[i] == ' '; i--)
|
||
|
+ version[i] = '\0';
|
||
|
+}
|
||
|
+
|
||
|
static void ontap_labels_to_str(char *dst, char *src, int count)
|
||
|
{
|
||
|
int i;
|
||
|
@@ -235,7 +271,8 @@ static void netapp_smdevice_json(struct json_object *devices, char *devname,
|
||
|
|
||
|
static void netapp_ontapdevice_json(struct json_object *devices, char *devname,
|
||
|
char *vsname, char *nspath, int nsid, char *uuid,
|
||
|
- char *size, long long lba, long long nsze)
|
||
|
+ unsigned long long lba, char *version,
|
||
|
+ unsigned long long nsze, unsigned long long nuse)
|
||
|
{
|
||
|
struct json_object *device_attrs;
|
||
|
|
||
|
@@ -245,9 +282,10 @@ static void netapp_ontapdevice_json(struct json_object *devices, char *devname,
|
||
|
json_object_add_value_string(device_attrs, "Namespace_Path", nspath);
|
||
|
json_object_add_value_int(device_attrs, "NSID", nsid);
|
||
|
json_object_add_value_string(device_attrs, "UUID", uuid);
|
||
|
- json_object_add_value_string(device_attrs, "Size", size);
|
||
|
- json_object_add_value_int(device_attrs, "LBA_Data_Size", lba);
|
||
|
- json_object_add_value_int(device_attrs, "Namespace_Size", nsze);
|
||
|
+ json_object_add_value_uint64(device_attrs, "LBA_Data_Size", lba);
|
||
|
+ json_object_add_value_uint64(device_attrs, "Namespace_Size", nsze);
|
||
|
+ json_object_add_value_uint64(device_attrs, "UsedBytes", nuse);
|
||
|
+ json_object_add_value_string(device_attrs, "Version", version);
|
||
|
|
||
|
json_array_add_value_object(devices, device_attrs);
|
||
|
}
|
||
|
@@ -410,6 +448,66 @@ out:
|
||
|
json_free_object(root);
|
||
|
}
|
||
|
|
||
|
+static void netapp_ontapdevices_print_verbose(struct ontapdevice_info *devices,
|
||
|
+ int count, int format, const char *devname)
|
||
|
+{
|
||
|
+ char vsname[ONTAP_LABEL_LEN] = " ";
|
||
|
+ char nspath[ONTAP_NS_PATHLEN] = " ";
|
||
|
+ unsigned long long lba;
|
||
|
+ char size[128], used[128];
|
||
|
+ char blk_size[128], version[8];
|
||
|
+ char uuid_str[37] = " ";
|
||
|
+ int i;
|
||
|
+
|
||
|
+ char *formatstr = NULL;
|
||
|
+ char basestr[] =
|
||
|
+ "%s, Vserver %s, Path %s, NSID %d, UUID %s, %s, %s, %s, %s\n";
|
||
|
+ char columnstr[] = "%-16s %-25s %-50s %-4d %-38s %-9s %-9s %-9s %-9s\n";
|
||
|
+
|
||
|
+ if (format == NNORMAL)
|
||
|
+ formatstr = basestr;
|
||
|
+ else if (format == NCOLUMN) {
|
||
|
+ printf("%-16s %-25s %-50s %-4s %-38s %-9s %-9s %-9s %-9s\n",
|
||
|
+ "Device", "Vserver", "Namespace Path",
|
||
|
+ "NSID", "UUID", "Size", "Used",
|
||
|
+ "Format", "Version");
|
||
|
+ printf("%-16s %-25s %-50s %-4s %-38s %-9s %-9s %-9s %-9s\n",
|
||
|
+ "----------------", "-------------------------",
|
||
|
+ "--------------------------------------------------",
|
||
|
+ "----", "--------------------------------------",
|
||
|
+ "---------", "---------", "---------", "---------");
|
||
|
+ formatstr = columnstr;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < count; i++) {
|
||
|
+ if (devname && !strcmp(devname, basename(devices[i].dev))) {
|
||
|
+ /* found the device, fetch and print for that alone */
|
||
|
+ netapp_get_ns_attrs(size, used, blk_size, version,
|
||
|
+ &lba, &devices[i].ctrl, &devices[i].ns);
|
||
|
+ nvme_uuid_to_string(devices[i].uuid, uuid_str);
|
||
|
+ netapp_get_ontap_labels(vsname, nspath,
|
||
|
+ devices[i].log_data);
|
||
|
+
|
||
|
+ printf(formatstr, devices[i].dev, vsname, nspath,
|
||
|
+ devices[i].nsid, uuid_str, size, used,
|
||
|
+ blk_size, version);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < count; i++) {
|
||
|
+ /* fetch info and print for all devices */
|
||
|
+ netapp_get_ns_attrs(size, used, blk_size, version,
|
||
|
+ &lba, &devices[i].ctrl, &devices[i].ns);
|
||
|
+ nvme_uuid_to_string(devices[i].uuid, uuid_str);
|
||
|
+ netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
|
||
|
+
|
||
|
+ printf(formatstr, devices[i].dev, vsname, nspath,
|
||
|
+ devices[i].nsid, uuid_str, size, used,
|
||
|
+ blk_size, version);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
static void netapp_ontapdevices_print_regular(struct ontapdevice_info *devices,
|
||
|
int count, int format, const char *devname)
|
||
|
{
|
||
|
@@ -472,7 +570,8 @@ static void netapp_ontapdevices_print_json(struct ontapdevice_info *devices,
|
||
|
char vsname[ONTAP_LABEL_LEN] = " ";
|
||
|
char nspath[ONTAP_NS_PATHLEN] = " ";
|
||
|
unsigned long long lba;
|
||
|
- char size[128];
|
||
|
+ char size[128], used[128];
|
||
|
+ char blk_size[128], version[8];
|
||
|
char uuid_str[37] = " ";
|
||
|
int i;
|
||
|
|
||
|
@@ -483,28 +582,33 @@ static void netapp_ontapdevices_print_json(struct ontapdevice_info *devices,
|
||
|
for (i = 0; i < count; i++) {
|
||
|
if (devname && !strcmp(devname, basename(devices[i].dev))) {
|
||
|
/* found the device, fetch info for that alone */
|
||
|
- netapp_get_ns_size(size, &lba, &devices[i].ns);
|
||
|
+ netapp_get_ns_attrs(size, used, blk_size, version,
|
||
|
+ &lba, &devices[i].ctrl, &devices[i].ns);
|
||
|
nvme_uuid_to_string(devices[i].uuid, uuid_str);
|
||
|
- netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
|
||
|
+ netapp_get_ontap_labels(vsname, nspath,
|
||
|
+ devices[i].log_data);
|
||
|
|
||
|
netapp_ontapdevice_json(json_devices, devices[i].dev,
|
||
|
vsname, nspath, devices[i].nsid,
|
||
|
- uuid_str, size, lba,
|
||
|
- le64_to_cpu(devices[i].ns.nsze));
|
||
|
+ uuid_str, lba, version,
|
||
|
+ le64_to_cpu(devices[i].ns.nsze),
|
||
|
+ le64_to_cpu(devices[i].ns.nuse));
|
||
|
goto out;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < count; i++) {
|
||
|
/* fetch info for all devices */
|
||
|
- netapp_get_ns_size(size, &lba, &devices[i].ns);
|
||
|
+ netapp_get_ns_attrs(size, used, blk_size, version,
|
||
|
+ &lba, &devices[i].ctrl, &devices[i].ns);
|
||
|
nvme_uuid_to_string(devices[i].uuid, uuid_str);
|
||
|
netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
|
||
|
|
||
|
netapp_ontapdevice_json(json_devices, devices[i].dev,
|
||
|
vsname, nspath, devices[i].nsid,
|
||
|
- uuid_str, size, lba,
|
||
|
- le64_to_cpu(devices[i].ns.nsze));
|
||
|
+ uuid_str, lba, version,
|
||
|
+ le64_to_cpu(devices[i].ns.nsze),
|
||
|
+ le64_to_cpu(devices[i].ns.nuse));
|
||
|
}
|
||
|
|
||
|
out:
|
||
|
@@ -776,6 +880,7 @@ static int netapp_ontapdevices(int argc, char **argv, struct command *command,
|
||
|
int num_ontapdevices = 0;
|
||
|
|
||
|
struct config {
|
||
|
+ bool verbose;
|
||
|
char *output_format;
|
||
|
};
|
||
|
|
||
|
@@ -784,6 +889,7 @@ static int netapp_ontapdevices(int argc, char **argv, struct command *command,
|
||
|
};
|
||
|
|
||
|
OPT_ARGS(opts) = {
|
||
|
+ OPT_FLAG("verbose", 'v', &cfg.verbose, "Increase output verbosity"),
|
||
|
OPT_FMT("output-format", 'o', &cfg.output_format, "Output Format: normal|json|column"),
|
||
|
OPT_END()
|
||
|
};
|
||
|
@@ -839,9 +945,14 @@ static int netapp_ontapdevices(int argc, char **argv, struct command *command,
|
||
|
}
|
||
|
|
||
|
if (num_ontapdevices) {
|
||
|
- if (fmt == NNORMAL || fmt == NCOLUMN)
|
||
|
- netapp_ontapdevices_print_regular(ontapdevices,
|
||
|
- num_ontapdevices, fmt, devname);
|
||
|
+ if (fmt == NNORMAL || fmt == NCOLUMN) {
|
||
|
+ if (argconfig_parse_seen(opts, "verbose"))
|
||
|
+ netapp_ontapdevices_print_verbose(ontapdevices,
|
||
|
+ num_ontapdevices, fmt, devname);
|
||
|
+ else
|
||
|
+ netapp_ontapdevices_print_regular(ontapdevices,
|
||
|
+ num_ontapdevices, fmt, devname);
|
||
|
+ }
|
||
|
else if (fmt == NJSON)
|
||
|
netapp_ontapdevices_print_json(ontapdevices,
|
||
|
num_ontapdevices, devname);
|
||
|
--
|
||
|
2.43.5
|
||
|
|