nvme/identify: print discovery log contents
Now that we can connect directly to a discovery service via spdk_nvme_connect(), it is useful to have the ability to dump its discovery log page in the identify example. Change-Id: Ie32f7ae2f0725874fed56258aa3c07d619fce0dd Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-on: https://review.gerrithub.io/382208 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: GangCao <gang.cao@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
415dcbf8cd
commit
0722434074
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "spdk/stdinc.h"
|
#include "spdk/stdinc.h"
|
||||||
|
|
||||||
|
#include "spdk/endian.h"
|
||||||
#include "spdk/log.h"
|
#include "spdk/log.h"
|
||||||
#include "spdk/nvme.h"
|
#include "spdk/nvme.h"
|
||||||
#include "spdk/env.h"
|
#include "spdk/env.h"
|
||||||
@ -41,6 +42,8 @@
|
|||||||
#include "spdk/pci_ids.h"
|
#include "spdk/pci_ids.h"
|
||||||
#include "spdk/util.h"
|
#include "spdk/util.h"
|
||||||
|
|
||||||
|
#define MAX_DISCOVERY_LOG_ENTRIES ((uint64_t)1000)
|
||||||
|
|
||||||
static int outstanding_commands;
|
static int outstanding_commands;
|
||||||
|
|
||||||
struct feature {
|
struct feature {
|
||||||
@ -60,6 +63,10 @@ static struct spdk_nvme_intel_temperature_page intel_temperature_page;
|
|||||||
|
|
||||||
static struct spdk_nvme_intel_marketing_description_page intel_md_page;
|
static struct spdk_nvme_intel_marketing_description_page intel_md_page;
|
||||||
|
|
||||||
|
static struct spdk_nvmf_discovery_log_page *g_discovery_page;
|
||||||
|
static size_t g_discovery_page_size;
|
||||||
|
static uint64_t g_discovery_page_numrec;
|
||||||
|
|
||||||
static bool g_hex_dump = false;
|
static bool g_hex_dump = false;
|
||||||
|
|
||||||
static int g_shm_id = -1;
|
static int g_shm_id = -1;
|
||||||
@ -249,6 +256,98 @@ get_intel_md_log_page(struct spdk_nvme_ctrlr *ctrlr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_discovery_log_page_header_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl)
|
||||||
|
{
|
||||||
|
struct spdk_nvmf_discovery_log_page *new_discovery_page;
|
||||||
|
struct spdk_nvme_ctrlr *ctrlr = cb_arg;
|
||||||
|
uint16_t recfmt;
|
||||||
|
uint64_t remaining;
|
||||||
|
uint64_t offset;
|
||||||
|
|
||||||
|
outstanding_commands--;
|
||||||
|
if (spdk_nvme_cpl_is_error(cpl)) {
|
||||||
|
/* Return without printing anything - this may not be a discovery controller */
|
||||||
|
free(g_discovery_page);
|
||||||
|
g_discovery_page = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Got the first 4K of the discovery log page */
|
||||||
|
recfmt = from_le16(&g_discovery_page->recfmt);
|
||||||
|
if (recfmt != 0) {
|
||||||
|
printf("Unrecognized discovery log record format %" PRIu16 "\n", recfmt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_discovery_page_numrec = from_le64(&g_discovery_page->numrec);
|
||||||
|
|
||||||
|
/* Pick an arbitrary limit to avoid ridiculously large buffer size. */
|
||||||
|
if (g_discovery_page_numrec > MAX_DISCOVERY_LOG_ENTRIES) {
|
||||||
|
printf("Discovery log has %" PRIu64 " entries - limiting to %" PRIu64 ".\n",
|
||||||
|
g_discovery_page_numrec, MAX_DISCOVERY_LOG_ENTRIES);
|
||||||
|
g_discovery_page_numrec = MAX_DISCOVERY_LOG_ENTRIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now that we now how many entries should be in the log page, we can allocate
|
||||||
|
* the full log page buffer.
|
||||||
|
*/
|
||||||
|
g_discovery_page_size += g_discovery_page_numrec * sizeof(struct
|
||||||
|
spdk_nvmf_discovery_log_page_entry);
|
||||||
|
new_discovery_page = realloc(g_discovery_page, g_discovery_page_size);
|
||||||
|
if (new_discovery_page == NULL) {
|
||||||
|
free(g_discovery_page);
|
||||||
|
printf("Discovery page allocation failed!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_discovery_page = new_discovery_page;
|
||||||
|
|
||||||
|
/* Retrieve the rest of the discovery log page */
|
||||||
|
offset = offsetof(struct spdk_nvmf_discovery_log_page, entries);
|
||||||
|
remaining = g_discovery_page_size - offset;
|
||||||
|
while (remaining) {
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
/* Retrieve up to 4 KB at a time */
|
||||||
|
size = spdk_min(remaining, 4096);
|
||||||
|
|
||||||
|
if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_DISCOVERY,
|
||||||
|
0, (char *)g_discovery_page + offset, size, offset,
|
||||||
|
get_log_page_completion, NULL)) {
|
||||||
|
printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += size;
|
||||||
|
remaining -= size;
|
||||||
|
outstanding_commands++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_discovery_log_page(struct spdk_nvme_ctrlr *ctrlr)
|
||||||
|
{
|
||||||
|
/* Allocate the initial discovery log page buffer - this will be resized later. */
|
||||||
|
g_discovery_page_size = sizeof(*g_discovery_page);
|
||||||
|
g_discovery_page = calloc(1, g_discovery_page_size);
|
||||||
|
if (g_discovery_page == NULL) {
|
||||||
|
printf("Discovery log page allocation failed!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_DISCOVERY,
|
||||||
|
0, g_discovery_page, g_discovery_page_size, 0,
|
||||||
|
get_discovery_log_page_header_completion, ctrlr)) {
|
||||||
|
printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_log_pages(struct spdk_nvme_ctrlr *ctrlr)
|
get_log_pages(struct spdk_nvme_ctrlr *ctrlr)
|
||||||
{
|
{
|
||||||
@ -293,6 +392,11 @@ get_log_pages(struct spdk_nvme_ctrlr *ctrlr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_discovery_log_page(ctrlr) == 0) {
|
||||||
|
outstanding_commands++;
|
||||||
|
}
|
||||||
|
|
||||||
while (outstanding_commands) {
|
while (outstanding_commands) {
|
||||||
spdk_nvme_ctrlr_process_admin_completions(ctrlr);
|
spdk_nvme_ctrlr_process_admin_completions(ctrlr);
|
||||||
}
|
}
|
||||||
@ -964,6 +1068,85 @@ print_controller(struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_transport
|
|||||||
for (i = 1; i <= spdk_nvme_ctrlr_get_num_ns(ctrlr); i++) {
|
for (i = 1; i <= spdk_nvme_ctrlr_get_num_ns(ctrlr); i++) {
|
||||||
print_namespace(spdk_nvme_ctrlr_get_ns(ctrlr, i));
|
print_namespace(spdk_nvme_ctrlr_get_ns(ctrlr, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_discovery_page) {
|
||||||
|
printf("Discovery Log Page\n");
|
||||||
|
printf("==================\n");
|
||||||
|
|
||||||
|
if (g_hex_dump) {
|
||||||
|
hex_dump(g_discovery_page, g_discovery_page_size);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Generation Counter: %" PRIu64 "\n",
|
||||||
|
from_le64(&g_discovery_page->genctr));
|
||||||
|
printf("Number of Records: %" PRIu64 "\n",
|
||||||
|
from_le64(&g_discovery_page->numrec));
|
||||||
|
printf("Record Format: %" PRIu16 "\n",
|
||||||
|
from_le16(&g_discovery_page->recfmt));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
for (i = 0; i < g_discovery_page_numrec; i++) {
|
||||||
|
struct spdk_nvmf_discovery_log_page_entry *entry = &g_discovery_page->entries[i];
|
||||||
|
|
||||||
|
printf("Discovery Log Entry %u\n", i);
|
||||||
|
printf("----------------------\n");
|
||||||
|
printf("Transport Type: %u (%s)\n",
|
||||||
|
entry->trtype, spdk_nvme_transport_id_trtype_str(entry->trtype));
|
||||||
|
printf("Address Family: %u (%s)\n",
|
||||||
|
entry->adrfam, spdk_nvme_transport_id_adrfam_str(entry->adrfam));
|
||||||
|
printf("Subsystem Type: %u (%s)\n",
|
||||||
|
entry->subtype,
|
||||||
|
entry->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY ? "Discovery Service" :
|
||||||
|
entry->subtype == SPDK_NVMF_SUBTYPE_NVME ? "NVM Subsystem" :
|
||||||
|
"Unknown");
|
||||||
|
printf("Transport Requirements:\n");
|
||||||
|
printf(" Secure Channel: %s\n",
|
||||||
|
entry->treq.secure_channel == SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_SPECIFIED ? "Not Specified" :
|
||||||
|
entry->treq.secure_channel == SPDK_NVMF_TREQ_SECURE_CHANNEL_REQUIRED ? "Required" :
|
||||||
|
entry->treq.secure_channel == SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED ? "Not Required" :
|
||||||
|
"Reserved");
|
||||||
|
printf("Port ID: %" PRIu16 " (0x%04" PRIx16 ")\n",
|
||||||
|
from_le16(&entry->portid), from_le16(&entry->portid));
|
||||||
|
printf("Controller ID: %" PRIu16 " (0x%04" PRIx16 ")\n",
|
||||||
|
from_le16(&entry->cntlid), from_le16(&entry->cntlid));
|
||||||
|
printf("Admin Max SQ Size: %" PRIu16 "\n",
|
||||||
|
from_le16(&entry->asqsz));
|
||||||
|
snprintf(str, sizeof(entry->trsvcid) + 1, "%s", entry->trsvcid);
|
||||||
|
printf("Transport Service Identifier: %s\n", str);
|
||||||
|
snprintf(str, sizeof(entry->subnqn) + 1, "%s", entry->subnqn);
|
||||||
|
printf("NVM Subsystem Qualified Name: %s\n", str);
|
||||||
|
snprintf(str, sizeof(entry->traddr) + 1, "%s", entry->traddr);
|
||||||
|
printf("Transport Address: %s\n", str);
|
||||||
|
|
||||||
|
if (entry->trtype == SPDK_NVMF_TRTYPE_RDMA) {
|
||||||
|
printf("Transport Specific Address Subtype - RDMA\n");
|
||||||
|
printf(" RDMA QP Service Type: %u (%s)\n",
|
||||||
|
entry->tsas.rdma.rdma_qptype,
|
||||||
|
entry->tsas.rdma.rdma_qptype == SPDK_NVMF_RDMA_QPTYPE_RELIABLE_CONNECTED ? "Reliable Connected" :
|
||||||
|
entry->tsas.rdma.rdma_qptype == SPDK_NVMF_RDMA_QPTYPE_RELIABLE_DATAGRAM ? "Reliable Datagram" :
|
||||||
|
"Unknown");
|
||||||
|
printf(" RDMA Provider Type: %u (%s)\n",
|
||||||
|
entry->tsas.rdma.rdma_prtype,
|
||||||
|
entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_NONE ? "No provider specified" :
|
||||||
|
entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_IB ? "InfiniBand" :
|
||||||
|
entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_ROCE ? "InfiniBand RoCE" :
|
||||||
|
entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_ROCE2 ? "InfiniBand RoCE v2" :
|
||||||
|
entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_IWARP ? "iWARP" :
|
||||||
|
"Unknown");
|
||||||
|
printf(" RDMA CM Service: %u (%s)\n",
|
||||||
|
entry->tsas.rdma.rdma_cms,
|
||||||
|
entry->tsas.rdma.rdma_cms == SPDK_NVMF_RDMA_CMS_RDMA_CM ? "RDMA_CM" :
|
||||||
|
"Unknown");
|
||||||
|
if (entry->adrfam == SPDK_NVMF_ADRFAM_IB) {
|
||||||
|
printf(" RDMA Partition Key: %" PRIu32 "\n",
|
||||||
|
from_le32(&entry->tsas.rdma.rdma_pkey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(g_discovery_page);
|
||||||
|
g_discovery_page = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user