LCOV - code coverage report
Current view: top level - spdk/test/nvme/simple_copy - simple_copy.c (source / functions) Hit Total Coverage
Test: Combined Lines: 157 244 64.3 %
Date: 2024-07-13 21:41:39 Functions: 12 13 92.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 83 217 38.2 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (c) Samsung Electronics Co., Ltd.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/stdinc.h"
       7                 :            : #include "spdk/nvme.h"
       8                 :            : #include "spdk/env.h"
       9                 :            : 
      10                 :            : #define NUM_LBAS 64
      11                 :            : #define DEST_LBA 256
      12                 :            : 
      13                 :            : struct ns_entry {
      14                 :            :         struct spdk_nvme_ctrlr  *ctrlr;
      15                 :            :         struct spdk_nvme_ns     *ns;
      16                 :            :         struct ns_entry         *next;
      17                 :            :         struct spdk_nvme_qpair  *qpair;
      18                 :            : };
      19                 :            : 
      20                 :            : struct simple_copy_context {
      21                 :            :         struct ns_entry *ns_entry;
      22                 :            :         char            **write_bufs;
      23                 :            :         char            **read_bufs;
      24                 :            :         int             writes_completed;
      25                 :            :         int             reads_completed;
      26                 :            :         int             simple_copy_completed;
      27                 :            :         int             matches_written_data;
      28                 :            :         int             error;
      29                 :            : };
      30                 :            : 
      31                 :            : static struct ns_entry *g_namespaces = NULL;
      32                 :            : static struct spdk_nvme_transport_id g_trid;
      33                 :            : static bool g_use_trid = false;
      34                 :            : 
      35                 :            : static void cleanup(struct simple_copy_context *context);
      36                 :            : 
      37                 :            : static void
      38                 :        320 : fill_random(char *buf, size_t num_bytes)
      39                 :            : {
      40                 :            :         size_t  i;
      41                 :            : 
      42                 :        320 :         srand((unsigned) time(NULL));
      43         [ +  + ]:    1311040 :         for (i = 0; i < num_bytes; i++) {
      44                 :    1310720 :                 buf[i] = rand() % 0x100;
      45                 :            :         }
      46                 :        320 : }
      47                 :            : 
      48                 :            : static void
      49                 :          5 : register_ns(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns)
      50                 :            : {
      51                 :            :         struct ns_entry                         *entry;
      52                 :            :         const struct spdk_nvme_ctrlr_data       *cdata;
      53                 :            : 
      54                 :          5 :         cdata = spdk_nvme_ctrlr_get_data(ctrlr);
      55                 :            : 
      56         [ -  + ]:          5 :         if (!spdk_nvme_ns_is_active(ns)) {
      57                 :          0 :                 printf("Controller %-20.20s (%-20.20s): Skipping inactive NS %u\n",
      58         [ #  # ]:          0 :                        cdata->mn, cdata->sn,
      59                 :            :                        spdk_nvme_ns_get_id(ns));
      60                 :          0 :                 return;
      61                 :            :         }
      62                 :            : 
      63                 :          5 :         entry = malloc(sizeof(struct ns_entry));
      64         [ -  + ]:          5 :         if (entry == NULL) {
      65                 :          0 :                 perror("ns_entry malloc");
      66                 :          0 :                 exit(1);
      67                 :            :         }
      68                 :            : 
      69                 :          5 :         entry->ctrlr = ctrlr;
      70                 :          5 :         entry->ns = ns;
      71                 :          5 :         entry->next = g_namespaces;
      72                 :          5 :         g_namespaces = entry;
      73                 :            : 
      74         [ -  + ]:          5 :         printf("  Namespace ID: %d size: %juGB\n", spdk_nvme_ns_get_id(ns),
      75                 :          5 :                spdk_nvme_ns_get_size(ns) / 1000000000);
      76                 :            : }
      77                 :            : 
      78                 :            : static uint32_t
      79                 :          5 : get_max_block_size(void)
      80                 :            : {
      81                 :            :         struct ns_entry *ns;
      82                 :            :         uint32_t        max_block_size, temp_block_size;
      83                 :            : 
      84                 :          5 :         ns = g_namespaces;
      85                 :          5 :         max_block_size = 0;
      86                 :            : 
      87         [ +  + ]:         10 :         while (ns != NULL) {
      88                 :          5 :                 temp_block_size = spdk_nvme_ns_get_sector_size(ns->ns);
      89                 :          5 :                 max_block_size = temp_block_size > max_block_size ? temp_block_size : max_block_size;
      90                 :          5 :                 ns = ns->next;
      91                 :            :         }
      92                 :            : 
      93                 :          5 :         return max_block_size;
      94                 :            : }
      95                 :            : 
      96                 :            : static void
      97                 :        320 : write_complete(void *arg, const struct spdk_nvme_cpl *cpl)
      98                 :            : {
      99                 :        320 :         struct simple_copy_context      *context = arg;
     100                 :            : 
     101                 :        320 :         context->writes_completed++;
     102                 :            : 
     103   [ +  -  -  + ]:        320 :         if (spdk_nvme_cpl_is_error(cpl)) {
     104         [ #  # ]:          0 :                 printf("write cpl error. SC 0x%x SCT 0x%x\n", cpl->status.sc, cpl->status.sct);
     105                 :          0 :                 context->error++;
     106                 :          0 :                 return;
     107                 :            :         }
     108                 :            : }
     109                 :            : 
     110                 :            : static void
     111                 :        320 : read_complete(void *arg, const struct spdk_nvme_cpl *cpl)
     112                 :            : {
     113                 :        320 :         struct simple_copy_context      *context = arg;
     114                 :        320 :         struct ns_entry                 *ns_entry = context->ns_entry;
     115                 :            :         int                             rc;
     116                 :            : 
     117   [ +  -  -  + ]:        320 :         if (spdk_nvme_cpl_is_error(cpl)) {
     118                 :          0 :                 printf("read cpl error. SC 0x%x SCT 0x%x\n", cpl->status.sc, cpl->status.sct);
     119                 :          0 :                 context->reads_completed++;
     120                 :          0 :                 context->error++;
     121                 :          0 :                 return;
     122                 :            :         }
     123                 :            : 
     124   [ -  +  -  + ]:        320 :         rc = memcmp(context->write_bufs[context->reads_completed],
     125                 :        320 :                     context->read_bufs[context->reads_completed], spdk_nvme_ns_get_sector_size(ns_entry->ns));
     126         [ +  - ]:        320 :         if (rc == 0) {
     127                 :        320 :                 context->matches_written_data++;
     128                 :            :         }
     129                 :            : 
     130                 :        320 :         context->reads_completed++;
     131                 :            : }
     132                 :            : 
     133                 :            : static void
     134                 :          5 : simple_copy_complete(void *arg, const struct spdk_nvme_cpl *cpl)
     135                 :            : {
     136                 :          5 :         struct simple_copy_context      *context = arg;
     137                 :            : 
     138                 :          5 :         context->simple_copy_completed = 1;
     139                 :            : 
     140   [ +  -  -  + ]:          5 :         if (spdk_nvme_cpl_is_error(cpl)) {
     141         [ #  # ]:          0 :                 printf("scc cpl error. SC 0x%x SCT 0x%x\n", cpl->status.sc, cpl->status.sct);
     142                 :          0 :                 context->error++;
     143                 :          0 :                 return;
     144                 :            :         }
     145                 :            : 
     146         [ -  + ]:          5 :         printf("Copied LBAs from 0 - %d to the Destination LBA %d\n", NUM_LBAS - 1, DEST_LBA);
     147                 :          5 :         context->reads_completed = 0;
     148                 :          5 :         context->matches_written_data = 0;
     149                 :            : }
     150                 :            : 
     151                 :            : static void
     152                 :          5 : simple_copy_test(void)
     153                 :            : {
     154                 :            :         struct ns_entry                         *ns_entry;
     155                 :            :         struct spdk_nvme_ctrlr                  *ctrlr;
     156                 :            :         const struct spdk_nvme_ctrlr_data       *data;
     157                 :          3 :         struct simple_copy_context              context;
     158                 :          5 :         struct spdk_nvme_scc_source_range       range = {};
     159                 :            :         uint32_t                                max_block_size;
     160                 :            :         int                                     rc, i;
     161                 :            : 
     162         [ -  + ]:          5 :         memset(&context, 0, sizeof(struct simple_copy_context));
     163                 :          5 :         max_block_size = get_max_block_size();
     164                 :          5 :         ns_entry = g_namespaces;
     165                 :            : 
     166                 :          5 :         context.write_bufs = calloc(NUM_LBAS, sizeof(char *));
     167         [ -  + ]:          5 :         if (context.write_bufs == NULL) {
     168         [ #  # ]:          0 :                 printf("could not allocate write buffer pointers for test\n");
     169                 :          0 :                 cleanup(&context);
     170                 :          0 :                 return;
     171                 :            :         }
     172                 :            : 
     173                 :          5 :         context.read_bufs = calloc(NUM_LBAS, sizeof(char *));
     174         [ -  + ]:          5 :         if (context.read_bufs == NULL) {
     175         [ #  # ]:          0 :                 printf("could not allocate read buffer pointers for test\n");
     176                 :          0 :                 cleanup(&context);
     177                 :          0 :                 return;
     178                 :            :         }
     179                 :            : 
     180         [ +  + ]:        325 :         for (i = 0; i < NUM_LBAS; i++) {
     181                 :        320 :                 context.write_bufs[i] = spdk_zmalloc(0x1000, max_block_size, NULL, SPDK_ENV_LCORE_ID_ANY,
     182                 :            :                                                      SPDK_MALLOC_DMA);
     183         [ -  + ]:        320 :                 if (context.write_bufs[i] == NULL) {
     184         [ #  # ]:          0 :                         printf("could not allocate write buffer %d for test\n", i);
     185                 :          0 :                         cleanup(&context);
     186                 :          0 :                         return;
     187                 :            :                 }
     188                 :            : 
     189                 :        320 :                 fill_random(context.write_bufs[i], 0x1000);
     190                 :        320 :                 context.read_bufs[i] = spdk_zmalloc(0x1000, max_block_size, NULL, SPDK_ENV_LCORE_ID_ANY,
     191                 :            :                                                     SPDK_MALLOC_DMA);
     192         [ -  + ]:        320 :                 if (context.read_bufs[i] == NULL) {
     193         [ #  # ]:          0 :                         printf("could not allocate read buffer %d for test\n", i);
     194                 :          0 :                         cleanup(&context);
     195                 :          0 :                         return;
     196                 :            :                 }
     197                 :            :         }
     198                 :            : 
     199         [ +  + ]:         10 :         while (ns_entry != NULL) {
     200                 :            : 
     201                 :          5 :                 ns_entry->qpair = spdk_nvme_ctrlr_alloc_io_qpair(ns_entry->ctrlr, NULL, 0);
     202         [ -  + ]:          5 :                 if (ns_entry->qpair == NULL) {
     203         [ #  # ]:          0 :                         printf("ERROR: spdk_nvme_ctrlr_alloc_io_qpair() failed\n");
     204                 :          0 :                         cleanup(&context);
     205                 :          0 :                         return;
     206                 :            :                 }
     207                 :            : 
     208                 :          5 :                 ctrlr = spdk_nvme_ns_get_ctrlr(ns_entry->ns);
     209                 :          5 :                 data = spdk_nvme_ctrlr_get_data(ctrlr);
     210                 :            : 
     211         [ -  + ]:          5 :                 printf("\nController %-20.20s (%-20.20s)\n", data->mn, data->sn);
     212         [ -  + ]:          5 :                 printf("Controller PCI vendor:%u PCI subsystem vendor:%u\n", data->vid, data->ssvid);
     213         [ -  + ]:          5 :                 printf("Namespace Block Size:%u\n", spdk_nvme_ns_get_sector_size(ns_entry->ns));
     214         [ -  + ]:          5 :                 printf("Writing LBAs 0 to %d with Random Data\n", NUM_LBAS - 1);
     215                 :            : 
     216                 :          5 :                 context.ns_entry = ns_entry;
     217                 :            : 
     218         [ +  + ]:        325 :                 for (i = 0; i < NUM_LBAS; i++) {
     219                 :        320 :                         rc = spdk_nvme_ns_cmd_write(ns_entry->ns, ns_entry->qpair, context.write_bufs[i],
     220                 :            :                                                     i,
     221                 :            :                                                     1,
     222                 :            :                                                     write_complete, &context, 0);
     223         [ -  + ]:        320 :                         if (rc) {
     224         [ #  # ]:          0 :                                 printf("submission of write I/O failed\n");
     225                 :            :                         }
     226                 :            :                 }
     227         [ +  + ]:       9614 :                 while (context.writes_completed < NUM_LBAS) {
     228                 :       9609 :                         rc = spdk_nvme_qpair_process_completions(ns_entry->qpair, 0);
     229         [ -  + ]:       9609 :                         if (rc < 0) {
     230         [ #  # ]:          0 :                                 printf("Error processing write completions, rc: %d\n", rc);
     231                 :          0 :                                 break;
     232                 :            :                         }
     233                 :            :                 }
     234                 :            : 
     235         [ -  + ]:          5 :                 if (context.error) {
     236         [ #  # ]:          0 :                         printf("Error : %d Write completions failed\n",
     237                 :            :                                context.error);
     238                 :          0 :                         spdk_nvme_ctrlr_free_io_qpair(ns_entry->qpair);
     239                 :          0 :                         cleanup(&context);
     240                 :          0 :                         exit(1);
     241                 :            :                 }
     242                 :            : 
     243                 :          5 :                 range.nlb = NUM_LBAS - 1;
     244                 :          5 :                 range.slba = 0;
     245                 :            : 
     246                 :          5 :                 rc = spdk_nvme_ns_cmd_copy(ns_entry->ns, ns_entry->qpair,
     247                 :            :                                            &range, 1, DEST_LBA, simple_copy_complete, &context);
     248                 :            : 
     249         [ -  + ]:          5 :                 if (rc) {
     250         [ #  # ]:          0 :                         printf("submission of copy I/O failed\n");
     251                 :            :                 }
     252                 :            : 
     253         [ +  + ]:       5028 :                 while (!context.simple_copy_completed) {
     254                 :       5023 :                         rc = spdk_nvme_qpair_process_completions(ns_entry->qpair, 0);
     255         [ -  + ]:       5023 :                         if (rc < 0) {
     256         [ #  # ]:          0 :                                 printf("Error processing copy completions, rc: %d\n", rc);
     257                 :          0 :                                 break;
     258                 :            :                         }
     259                 :            :                 }
     260                 :            : 
     261         [ -  + ]:          5 :                 if (context.error) {
     262         [ #  # ]:          0 :                         printf("Error : Copy completion failed\n");
     263                 :          0 :                         spdk_nvme_ctrlr_free_io_qpair(ns_entry->qpair);
     264                 :          0 :                         cleanup(&context);
     265                 :          0 :                         exit(1);
     266                 :            :                 }
     267                 :            : 
     268         [ +  + ]:        325 :                 for (i = 0; i < NUM_LBAS; i++) {
     269                 :        320 :                         rc = spdk_nvme_ns_cmd_read(ns_entry->ns, ns_entry->qpair, context.read_bufs[i],
     270                 :        320 :                                                    DEST_LBA + i, /* LBA start */
     271                 :            :                                                    1, /* number of LBAs */
     272                 :            :                                                    read_complete, &context, 0);
     273         [ -  + ]:        320 :                         if (rc) {
     274         [ #  # ]:          0 :                                 printf("submission of read I/O failed\n");
     275                 :            :                         }
     276                 :            :                         /* block after each read command so that we can match the block to the write buffer. */
     277         [ +  + ]:      55155 :                         while (context.reads_completed <= i) {
     278                 :      54835 :                                 rc = spdk_nvme_qpair_process_completions(ns_entry->qpair, 0);
     279         [ -  + ]:      54835 :                                 if (rc < 0) {
     280         [ #  # ]:          0 :                                         printf("Error processing read completions, rc: %d\n", rc);
     281                 :          0 :                                         break;
     282                 :            :                                 }
     283                 :            :                         }
     284                 :            :                 }
     285                 :            : 
     286         [ -  + ]:          5 :                 if (context.error) {
     287         [ #  # ]:          0 :                         printf("Error : %d Read completions failed\n",
     288                 :            :                                context.error);
     289                 :          0 :                         spdk_nvme_ctrlr_free_io_qpair(ns_entry->qpair);
     290                 :          0 :                         cleanup(&context);
     291                 :          0 :                         exit(1);
     292                 :            :                 }
     293                 :            : 
     294         [ -  + ]:          5 :                 printf("LBAs matching Written Data: %d\n", context.matches_written_data);
     295                 :            : 
     296         [ -  + ]:          5 :                 if (context.matches_written_data != NUM_LBAS) {
     297         [ #  # ]:          0 :                         printf("Error : %d LBAs are copied correctly out of %d LBAs\n",
     298                 :            :                                context.matches_written_data, NUM_LBAS);
     299                 :          0 :                         spdk_nvme_ctrlr_free_io_qpair(ns_entry->qpair);
     300                 :          0 :                         cleanup(&context);
     301                 :          0 :                         exit(1);
     302                 :            :                 }
     303                 :            : 
     304                 :            :                 /* reset counters in between each namespace. */
     305                 :          5 :                 context.matches_written_data = 0;
     306                 :          5 :                 context.writes_completed = 0;
     307                 :          5 :                 context.reads_completed = 0;
     308                 :          5 :                 context.simple_copy_completed = 0;
     309                 :            : 
     310                 :          5 :                 spdk_nvme_ctrlr_free_io_qpair(ns_entry->qpair);
     311                 :          5 :                 ns_entry = ns_entry->next;
     312                 :            :         }
     313                 :          5 :         cleanup(&context);
     314                 :            : }
     315                 :            : 
     316                 :            : static bool
     317                 :          5 : probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
     318                 :            :          struct spdk_nvme_ctrlr_opts *opts)
     319                 :            : {
     320         [ -  + ]:          5 :         printf("Attaching to %s\n", trid->traddr);
     321                 :            : 
     322                 :          5 :         return true;
     323                 :            : }
     324                 :            : 
     325                 :            : static void
     326                 :          5 : attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
     327                 :            :           struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
     328                 :            : {
     329                 :            :         int                     num_ns;
     330                 :            :         struct spdk_nvme_ns     *ns;
     331                 :            :         const struct spdk_nvme_ctrlr_data       *cdata;
     332                 :            : 
     333                 :          5 :         cdata = spdk_nvme_ctrlr_get_data(ctrlr);
     334                 :            : 
     335         [ +  - ]:          5 :         if (cdata->oncs.copy) {
     336         [ -  + ]:          5 :                 printf("Controller supports SCC. Attached to %s\n", trid->traddr);
     337                 :            :                 /*
     338                 :            :                  * Use only the first namespace from each controller since we are testing controller level functionality.
     339                 :            :                  */
     340                 :          5 :                 num_ns = spdk_nvme_ctrlr_get_num_ns(ctrlr);
     341         [ -  + ]:          5 :                 if (num_ns < 1) {
     342         [ #  # ]:          0 :                         printf("No valid namespaces in controller\n");
     343                 :            :                 } else {
     344                 :          5 :                         ns = spdk_nvme_ctrlr_get_ns(ctrlr, 1);
     345                 :          5 :                         register_ns(ctrlr, ns);
     346                 :            :                 }
     347                 :            :         } else {
     348         [ #  # ]:          0 :                 printf("Controller doesn't support SCC. Not Attached to %s\n", trid->traddr);
     349                 :            :         }
     350                 :          5 : }
     351                 :            : 
     352                 :            : static void
     353                 :          5 : cleanup(struct simple_copy_context *context)
     354                 :            : {
     355                 :          5 :         struct ns_entry *ns_entry = g_namespaces;
     356                 :          5 :         struct spdk_nvme_detach_ctx *detach_ctx = NULL;
     357                 :            :         int             i;
     358                 :            : 
     359         [ +  + ]:         10 :         while (ns_entry) {
     360                 :          5 :                 struct ns_entry *next = ns_entry->next;
     361                 :            : 
     362                 :          5 :                 spdk_nvme_detach_async(ns_entry->ctrlr, &detach_ctx);
     363                 :            : 
     364                 :          5 :                 free(ns_entry);
     365                 :          5 :                 ns_entry = next;
     366                 :            :         }
     367                 :            : 
     368         [ +  - ]:          5 :         if (detach_ctx) {
     369                 :          5 :                 spdk_nvme_detach_poll(detach_ctx);
     370                 :            :         }
     371                 :            : 
     372         [ +  + ]:        325 :         for (i = 0; i < NUM_LBAS; i++) {
     373   [ +  -  +  - ]:        320 :                 if (context->write_bufs && context->write_bufs[i]) {
     374                 :        320 :                         spdk_free(context->write_bufs[i]);
     375                 :            :                 } else {
     376                 :            :                         break;
     377                 :            :                 }
     378   [ +  -  +  - ]:        320 :                 if (context->read_bufs && context->read_bufs[i]) {
     379                 :        320 :                         spdk_free(context->read_bufs[i]);
     380                 :            :                 } else {
     381                 :            :                         break;
     382                 :            :                 }
     383                 :            :         }
     384                 :            : 
     385                 :          5 :         free(context->write_bufs);
     386                 :          5 :         free(context->read_bufs);
     387                 :          5 : }
     388                 :            : 
     389                 :            : static void
     390                 :          0 : usage(const char *program_name)
     391                 :            : {
     392         [ #  # ]:          0 :         printf("%s [options]", program_name);
     393                 :          0 :         printf("\n");
     394         [ #  # ]:          0 :         printf("options:\n");
     395         [ #  # ]:          0 :         printf(" -r trid    remote NVMe over Fabrics target address\n");
     396         [ #  # ]:          0 :         printf("    Format: 'key:value [key:value] ...'\n");
     397         [ #  # ]:          0 :         printf("    Keys:\n");
     398         [ #  # ]:          0 :         printf("     trtype      Transport type (e.g. RDMA)\n");
     399         [ #  # ]:          0 :         printf("     adrfam      Address family (e.g. IPv4, IPv6)\n");
     400         [ #  # ]:          0 :         printf("     traddr      Transport address (e.g. 192.168.100.8)\n");
     401         [ #  # ]:          0 :         printf("     trsvcid     Transport service identifier (e.g. 4420)\n");
     402         [ #  # ]:          0 :         printf("     subnqn      Subsystem NQN (default: %s)\n", SPDK_NVMF_DISCOVERY_NQN);
     403         [ #  # ]:          0 :         printf("    Example: -r 'trtype:RDMA adrfam:IPv4 traddr:192.168.100.8 trsvcid:4420'\n");
     404         [ #  # ]:          0 :         printf(" -h         show this usage\n");
     405                 :          0 : }
     406                 :            : 
     407                 :            : static int
     408                 :          5 : parse_args(int argc, char **argv, struct spdk_env_opts *env_opts)
     409                 :            : {
     410                 :            :         int op;
     411                 :            : 
     412                 :          5 :         spdk_nvme_trid_populate_transport(&g_trid, SPDK_NVME_TRANSPORT_PCIE);
     413         [ -  + ]:          5 :         snprintf(g_trid.subnqn, sizeof(g_trid.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
     414                 :            : 
     415   [ +  +  +  +  :         10 :         while ((op = getopt(argc, argv, "r:h")) != -1) {
                   +  + ]
     416      [ +  -  - ]:          5 :                 switch (op) {
     417                 :          5 :                 case 'r':
     418         [ -  + ]:          5 :                         if (spdk_nvme_transport_id_parse(&g_trid, optarg) != 0) {
     419   [ #  #  #  # ]:          0 :                                 fprintf(stderr, "Error parsing transport address\n");
     420                 :          0 :                                 return 1;
     421                 :            :                         }
     422                 :            : 
     423                 :          5 :                         g_use_trid = true;
     424                 :          5 :                         break;
     425                 :          0 :                 case 'h':
     426                 :          0 :                         usage(argv[0]);
     427                 :          0 :                         exit(EXIT_SUCCESS);
     428                 :          0 :                 default:
     429                 :          0 :                         usage(argv[0]);
     430                 :          0 :                         return 1;
     431                 :            :                 }
     432                 :            :         }
     433                 :            : 
     434                 :          5 :         return 0;
     435                 :            : }
     436                 :            : 
     437                 :            : int
     438                 :          5 : main(int argc, char **argv)
     439                 :            : {
     440                 :            :         int                     rc;
     441                 :          3 :         struct spdk_env_opts    opts;
     442                 :            : 
     443                 :          5 :         spdk_env_opts_init(&opts);
     444                 :          5 :         rc = parse_args(argc, argv, &opts);
     445         [ -  + ]:          5 :         if (rc != 0) {
     446                 :          0 :                 return rc;
     447                 :            :         }
     448                 :            : 
     449                 :          5 :         opts.name = "simple_copy";
     450                 :          5 :         opts.shm_id = 0;
     451         [ -  + ]:          5 :         if (spdk_env_init(&opts) < 0) {
     452   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Unable to initialize SPDK env\n");
     453                 :          0 :                 return 1;
     454                 :            :         }
     455                 :            : 
     456         [ -  + ]:          5 :         printf("Initializing NVMe Controllers\n");
     457                 :            : 
     458   [ +  +  +  - ]:          5 :         rc = spdk_nvme_probe(g_use_trid ? &g_trid : NULL, NULL, probe_cb, attach_cb, NULL);
     459         [ -  + ]:          5 :         if (rc != 0) {
     460   [ #  #  #  # ]:          0 :                 fprintf(stderr, "spdk_nvme_probe() failed\n");
     461                 :          0 :                 return 1;
     462                 :            :         }
     463                 :            : 
     464         [ -  + ]:          5 :         if (g_namespaces == NULL) {
     465   [ #  #  #  # ]:          0 :                 fprintf(stderr, "no NVMe controllers found\n");
     466                 :          0 :                 return 1;
     467                 :            :         }
     468                 :            : 
     469         [ -  + ]:          5 :         printf("Initialization complete.\n");
     470                 :          5 :         simple_copy_test();
     471                 :          5 :         return 0;
     472                 :            : }

Generated by: LCOV version 1.14