LCOV - code coverage report
Current view: top level - spdk/app/spdk_nvme_discover - discovery_aer.c (source / functions) Hit Total Coverage
Test: Combined Lines: 0 162 0.0 %
Date: 2024-07-15 16:00:50 Functions: 0 10 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 159 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2021 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/stdinc.h"
       7                 :            : 
       8                 :            : #include "spdk/env.h"
       9                 :            : #include "spdk/nvme.h"
      10                 :            : #include "spdk/queue.h"
      11                 :            : #include "spdk/string.h"
      12                 :            : #include "spdk/util.h"
      13                 :            : #include "spdk/log.h"
      14                 :            : #include "spdk/likely.h"
      15                 :            : #include "spdk/endian.h"
      16                 :            : 
      17                 :            : /* The flag is used to exit the program while keep alive fails on the transport */
      18                 :            : static bool g_exit;
      19                 :            : static struct spdk_nvme_ctrlr *g_ctrlr;
      20                 :            : static struct spdk_nvme_transport_id g_trid;
      21                 :            : static const char *g_hostnqn;
      22                 :            : static bool g_discovery_in_progress;
      23                 :            : static bool g_pending_discovery;
      24                 :            : 
      25                 :            : static void get_discovery_log_page(struct spdk_nvme_ctrlr *ctrlr);
      26                 :            : 
      27                 :            : static void
      28                 :          0 : print_discovery_log(struct spdk_nvmf_discovery_log_page *log_page)
      29                 :            : {
      30                 :            :         uint64_t numrec;
      31                 :          0 :         char str[512];
      32                 :            :         uint32_t i;
      33                 :            : 
      34         [ #  # ]:          0 :         printf("Discovery Log Page\n");
      35         [ #  # ]:          0 :         printf("==================\n");
      36                 :            : 
      37                 :          0 :         numrec = from_le64(&log_page->numrec);
      38                 :            : 
      39         [ #  # ]:          0 :         printf("Generation Counter: %" PRIu64 "\n", from_le64(&log_page->genctr));
      40         [ #  # ]:          0 :         printf("Number of Records:  %" PRIu64 "\n", numrec);
      41         [ #  # ]:          0 :         printf("Record Format:      %" PRIu16 "\n", from_le16(&log_page->recfmt));
      42                 :          0 :         printf("\n");
      43                 :            : 
      44         [ #  # ]:          0 :         for (i = 0; i < numrec; i++) {
      45                 :          0 :                 struct spdk_nvmf_discovery_log_page_entry *entry = &log_page->entries[i];
      46                 :            : 
      47         [ #  # ]:          0 :                 printf("Discovery Log Entry %u\n", i);
      48         [ #  # ]:          0 :                 printf("----------------------\n");
      49                 :          0 :                 printf("Transport Type:                        %u (%s)\n",
      50         [ #  # ]:          0 :                        entry->trtype, spdk_nvme_transport_id_trtype_str(entry->trtype));
      51                 :          0 :                 printf("Address Family:                        %u (%s)\n",
      52         [ #  # ]:          0 :                        entry->adrfam, spdk_nvme_transport_id_adrfam_str(entry->adrfam));
      53                 :          0 :                 printf("Subsystem Type:                        %u (%s)\n",
      54         [ #  # ]:          0 :                        entry->subtype,
      55         [ #  # ]:          0 :                        entry->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY ? "Referral to a discovery service" :
      56         [ #  # ]:          0 :                        entry->subtype == SPDK_NVMF_SUBTYPE_NVME ? "NVM Subsystem" :
      57         [ #  # ]:          0 :                        entry->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY_CURRENT ? "Current Discovery Subsystem" :
      58                 :            :                        "Unknown");
      59         [ #  # ]:          0 :                 printf("Port ID:                               %" PRIu16 " (0x%04" PRIx16 ")\n",
      60                 :          0 :                        from_le16(&entry->portid), from_le16(&entry->portid));
      61         [ #  # ]:          0 :                 printf("Controller ID:                         %" PRIu16 " (0x%04" PRIx16 ")\n",
      62                 :          0 :                        from_le16(&entry->cntlid), from_le16(&entry->cntlid));
      63         [ #  # ]:          0 :                 snprintf(str, sizeof(entry->trsvcid) + 1, "%s", entry->trsvcid);
      64         [ #  # ]:          0 :                 printf("Transport Service Identifier:          %s\n", str);
      65         [ #  # ]:          0 :                 snprintf(str, sizeof(entry->subnqn) + 1, "%s", entry->subnqn);
      66         [ #  # ]:          0 :                 printf("NVM Subsystem Qualified Name:          %s\n", str);
      67         [ #  # ]:          0 :                 snprintf(str, sizeof(entry->traddr) + 1, "%s", entry->traddr);
      68         [ #  # ]:          0 :                 printf("Transport Address:                     %s\n", str);
      69                 :            :         }
      70                 :          0 : }
      71                 :            : 
      72                 :            : static void
      73                 :          0 : get_log_page_completion(void *cb_arg, int rc, const struct spdk_nvme_cpl *cpl,
      74                 :            :                         struct spdk_nvmf_discovery_log_page *log_page)
      75                 :            : {
      76   [ #  #  #  #  :          0 :         if (rc || spdk_nvme_cpl_is_error(cpl)) {
                   #  # ]
      77   [ #  #  #  # ]:          0 :                 fprintf(stderr, "get discovery log page failed\n");
      78                 :          0 :                 exit(1);
      79                 :            :         }
      80                 :            : 
      81                 :          0 :         print_discovery_log(log_page);
      82                 :          0 :         free(log_page);
      83                 :            : 
      84                 :          0 :         g_discovery_in_progress = false;
      85   [ #  #  #  # ]:          0 :         if (g_pending_discovery) {
      86                 :          0 :                 get_discovery_log_page(g_ctrlr);
      87                 :          0 :                 g_pending_discovery = false;
      88                 :            :         }
      89                 :          0 : }
      90                 :            : 
      91                 :            : static void
      92                 :          0 : get_discovery_log_page(struct spdk_nvme_ctrlr *ctrlr)
      93                 :            : {
      94   [ #  #  #  # ]:          0 :         if (g_discovery_in_progress) {
      95                 :          0 :                 g_pending_discovery = true;
      96                 :            :         }
      97                 :            : 
      98                 :          0 :         g_discovery_in_progress = true;
      99                 :            : 
     100         [ #  # ]:          0 :         if (spdk_nvme_ctrlr_get_discovery_log_page(ctrlr, get_log_page_completion, NULL)) {
     101   [ #  #  #  # ]:          0 :                 fprintf(stderr, "spdk_nvme_ctrlr_get_discovery_log_page() failed\n");
     102                 :          0 :                 exit(1);
     103                 :            :         }
     104                 :          0 : }
     105                 :            : 
     106                 :            : static void
     107                 :          0 : usage(char *program_name)
     108                 :            : {
     109         [ #  # ]:          0 :         printf("%s options", program_name);
     110                 :          0 :         printf("\n");
     111         [ #  # ]:          0 :         printf("\t[-r, --transport <fmt> Transport ID for NVMeoF discovery subsystem]\n");
     112         [ #  # ]:          0 :         printf("\t Format: 'key:value [key:value] ...'\n");
     113         [ #  # ]:          0 :         printf("\t Keys:\n");
     114         [ #  # ]:          0 :         printf("\t  trtype      Transport type (e.g. TCP, RDMA)\n");
     115         [ #  # ]:          0 :         printf("\t  adrfam      Address family (e.g. IPv4, IPv6)\n");
     116         [ #  # ]:          0 :         printf("\t  traddr      Transport address (e.g. 192.168.100.8)\n");
     117         [ #  # ]:          0 :         printf("\t  trsvcid     Transport service identifier (e.g. 4420)\n");
     118         [ #  # ]:          0 :         printf("\t Example: -r 'trtype:TCP adrfam:IPv4 traddr:192.168.100.8 trsvcid:4420'\n");
     119                 :          0 :         printf("\t");
     120                 :          0 :         spdk_log_usage(stdout, "-T");
     121                 :            : #ifdef DEBUG
     122         [ #  # ]:          0 :         printf("\t[-G, --enable-debug enable debug logging]\n");
     123                 :            : #else
     124                 :            :         printf("\t[-G, --enable-debug enable debug logging (flag disabled, must reconfigure with --enable-debug)]\n");
     125                 :            : #endif
     126         [ #  # ]:          0 :         printf("\t[-H, --hostnqn Host NQN]\n");
     127                 :          0 : }
     128                 :            : 
     129                 :            : static void
     130                 :          0 : set_trid(const char *trid_str)
     131                 :            : {
     132                 :            :         struct spdk_nvme_transport_id *trid;
     133                 :            : 
     134                 :          0 :         trid = &g_trid;
     135                 :          0 :         trid->trtype = SPDK_NVME_TRANSPORT_PCIE;
     136         [ #  # ]:          0 :         snprintf(trid->subnqn, sizeof(trid->subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
     137                 :            : 
     138         [ #  # ]:          0 :         if (spdk_nvme_transport_id_parse(trid, trid_str) != 0) {
     139   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Invalid transport ID format '%s'\n", trid_str);
     140                 :          0 :                 exit(1);
     141                 :            :         }
     142                 :            : 
     143                 :          0 :         spdk_nvme_transport_id_populate_trstring(trid,
     144                 :            :                         spdk_nvme_transport_id_trtype_str(trid->trtype));
     145                 :          0 : }
     146                 :            : 
     147                 :            : #define AER_GETOPT_SHORT "r:GH:T:"
     148                 :            : 
     149                 :            : static const struct option g_aer_cmdline_opts[] = {
     150                 :            : #define AER_TRANSPORT           'r'
     151                 :            :         {"transport",         required_argument,      NULL, AER_TRANSPORT},
     152                 :            : #define AER_ENABLE_DEBUG        'G'
     153                 :            :         {"enable-debug",      no_argument,            NULL, AER_ENABLE_DEBUG},
     154                 :            : #define AER_HOSTNQN             'H'
     155                 :            :         {"hostnqn",           required_argument,      NULL, AER_HOSTNQN},
     156                 :            : #define AER_LOG_FLAG            'T'
     157                 :            :         {"logflag",           required_argument,      NULL, AER_LOG_FLAG},
     158                 :            :         /* Should be the last element */
     159                 :            :         {0, 0, 0, 0}
     160                 :            : };
     161                 :            : 
     162                 :            : static int
     163                 :          0 : parse_args(int argc, char **argv, struct spdk_env_opts *env_opts)
     164                 :            : {
     165                 :          0 :         int op, long_idx;
     166                 :            :         int rc;
     167                 :            : 
     168   [ #  #  #  #  :          0 :         while ((op = getopt_long(argc, argv, AER_GETOPT_SHORT, g_aer_cmdline_opts, &long_idx)) != -1) {
                   #  # ]
     169   [ #  #  #  #  :          0 :                 switch (op) {
                      # ]
     170                 :          0 :                 case AER_TRANSPORT:
     171                 :          0 :                         set_trid(optarg);
     172                 :          0 :                         break;
     173                 :          0 :                 case AER_ENABLE_DEBUG:
     174                 :            : #ifndef DEBUG
     175                 :            :                         fprintf(stderr, "%s must be configured with --enable-debug for -G flag\n",
     176                 :            :                                 argv[0]);
     177                 :            :                         usage(argv[0]);
     178                 :            :                         return 1;
     179                 :            : #else
     180                 :          0 :                         spdk_log_set_flag("nvme");
     181                 :          0 :                         spdk_log_set_print_level(SPDK_LOG_DEBUG);
     182                 :          0 :                         break;
     183                 :            : #endif
     184                 :          0 :                 case AER_HOSTNQN:
     185                 :          0 :                         g_hostnqn = optarg;
     186                 :          0 :                         break;
     187                 :          0 :                 case AER_LOG_FLAG:
     188                 :          0 :                         rc = spdk_log_set_flag(optarg);
     189         [ #  # ]:          0 :                         if (rc < 0) {
     190   [ #  #  #  # ]:          0 :                                 fprintf(stderr, "unknown flag\n");
     191                 :          0 :                                 usage(argv[0]);
     192                 :          0 :                                 exit(EXIT_FAILURE);
     193                 :            :                         }
     194                 :            : #ifdef DEBUG
     195                 :          0 :                         spdk_log_set_print_level(SPDK_LOG_DEBUG);
     196                 :            : #endif
     197                 :          0 :                         break;
     198                 :          0 :                 default:
     199                 :          0 :                         usage(argv[0]);
     200                 :          0 :                         return 1;
     201                 :            :                 }
     202                 :            :         }
     203                 :            : 
     204                 :          0 :         return 0;
     205                 :            : }
     206                 :            : 
     207                 :            : static void
     208                 :          0 : aer_cb(void *arg, const struct spdk_nvme_cpl *cpl)
     209                 :            : {
     210                 :          0 :         uint32_t log_page_id = (cpl->cdw0 & 0xFF0000) >> 16;
     211                 :            : 
     212   [ #  #  #  # ]:          0 :         if (spdk_nvme_cpl_is_error(cpl)) {
     213   [ #  #  #  # ]:          0 :                 fprintf(stderr, "aer failed\n");
     214                 :          0 :                 exit(1);
     215                 :            :         }
     216                 :            : 
     217         [ #  # ]:          0 :         if (log_page_id != SPDK_NVME_LOG_DISCOVERY) {
     218   [ #  #  #  # ]:          0 :                 fprintf(stderr, "unexpected log page 0x%x\n", log_page_id);
     219                 :          0 :                 exit(1);
     220                 :            :         }
     221                 :            : 
     222                 :          0 :         get_discovery_log_page(g_ctrlr);
     223                 :          0 : }
     224                 :            : 
     225                 :            : static void
     226                 :          0 : sig_handler(int signo)
     227                 :            : {
     228                 :          0 :         g_exit = true;
     229                 :          0 : }
     230                 :            : 
     231                 :            : static void
     232                 :          0 : setup_sig_handlers(void)
     233                 :            : {
     234                 :          0 :         struct sigaction sigact = {};
     235                 :            :         int rc;
     236                 :            : 
     237                 :          0 :         sigemptyset(&sigact.sa_mask);
     238                 :          0 :         sigact.sa_handler = sig_handler;
     239                 :          0 :         rc = sigaction(SIGINT, &sigact, NULL);
     240         [ #  # ]:          0 :         if (rc < 0) {
     241         [ #  # ]:          0 :                 fprintf(stderr, "sigaction(SIGINT) failed, errno %d (%s)\n", errno, strerror(errno));
     242                 :          0 :                 exit(1);
     243                 :            :         }
     244                 :            : 
     245                 :          0 :         rc = sigaction(SIGTERM, &sigact, NULL);
     246         [ #  # ]:          0 :         if (rc < 0) {
     247         [ #  # ]:          0 :                 fprintf(stderr, "sigaction(SIGTERM) failed, errno %d (%s)\n", errno, strerror(errno));
     248                 :          0 :                 exit(1);
     249                 :            :         }
     250                 :          0 : }
     251                 :            : 
     252                 :            : int
     253                 :          0 : main(int argc, char **argv)
     254                 :            : {
     255                 :            :         int rc;
     256                 :          0 :         struct spdk_env_opts opts;
     257                 :          0 :         struct spdk_nvme_ctrlr_opts ctrlr_opts;
     258                 :          0 :         struct spdk_nvme_detach_ctx *detach_ctx = NULL;
     259                 :            : 
     260                 :          0 :         spdk_env_opts_init(&opts);
     261                 :          0 :         opts.name = "discovery_aer";
     262                 :          0 :         rc = parse_args(argc, argv, &opts);
     263         [ #  # ]:          0 :         if (rc != 0) {
     264                 :          0 :                 exit(1);
     265                 :            :         }
     266                 :            : 
     267         [ #  # ]:          0 :         if (g_trid.subnqn[0] == '\0') {
     268         [ #  # ]:          0 :                 fprintf(stderr, "Discovery subsystem transport ID not specified\n");
     269                 :          0 :                 usage(argv[0]);
     270                 :          0 :                 exit(1);
     271                 :            :         }
     272                 :            : 
     273         [ #  # ]:          0 :         if (spdk_env_init(&opts) < 0) {
     274         [ #  # ]:          0 :                 fprintf(stderr, "Unable to initialize SPDK env\n");
     275                 :          0 :                 exit(1);
     276                 :            :         }
     277                 :            : 
     278                 :          0 :         setup_sig_handlers();
     279                 :            : 
     280                 :          0 :         spdk_nvme_ctrlr_get_default_ctrlr_opts(&ctrlr_opts, sizeof(ctrlr_opts));
     281         [ #  # ]:          0 :         if (g_hostnqn) {
     282                 :          0 :                 snprintf(ctrlr_opts.hostnqn, sizeof(ctrlr_opts.hostnqn), "%s", g_hostnqn);
     283                 :            :         }
     284                 :            : 
     285                 :          0 :         g_ctrlr = spdk_nvme_connect(&g_trid, &ctrlr_opts, sizeof(ctrlr_opts));
     286         [ #  # ]:          0 :         if (g_ctrlr == NULL) {
     287         [ #  # ]:          0 :                 fprintf(stderr, "spdk_nvme_connect() failed for transport address '%s'\n", g_trid.traddr);
     288                 :          0 :                 exit(1);
     289                 :            :         }
     290                 :            : 
     291                 :          0 :         spdk_nvme_ctrlr_register_aer_callback(g_ctrlr, aer_cb, NULL);
     292                 :            : 
     293                 :          0 :         get_discovery_log_page(g_ctrlr);
     294                 :            : 
     295   [ #  #  #  # ]:          0 :         while (spdk_likely(!g_exit)) {
     296                 :          0 :                 spdk_nvme_ctrlr_process_admin_completions(g_ctrlr);
     297                 :            :         }
     298                 :            : 
     299                 :          0 :         spdk_nvme_detach_async(g_ctrlr, &detach_ctx);
     300                 :            : 
     301         [ #  # ]:          0 :         if (detach_ctx) {
     302                 :          0 :                 spdk_nvme_detach_poll(detach_ctx);
     303                 :            :         }
     304                 :            : 
     305                 :          0 :         spdk_env_fini();
     306                 :            : 
     307                 :          0 :         return 0;
     308                 :            : }

Generated by: LCOV version 1.14