LCOV - code coverage report
Current view: top level - spdk/test/app/stub - stub.c (source / functions) Hit Total Coverage
Test: Combined Lines: 62 99 62.6 %
Date: 2024-07-15 19:04:35 Functions: 7 8 87.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 28 86 32.6 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2017 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/stdinc.h"
       7                 :            : 
       8                 :            : #include "spdk/event.h"
       9                 :            : #include "spdk/nvme.h"
      10                 :            : #include "spdk/string.h"
      11                 :            : #include "spdk/thread.h"
      12                 :            : 
      13                 :            : static char g_path[256];
      14                 :            : static struct spdk_poller *g_poller;
      15                 :            : /* default sleep time in ms */
      16                 :            : static uint32_t g_sleep_time = 1000;
      17                 :            : 
      18                 :            : struct ctrlr_entry {
      19                 :            :         struct spdk_nvme_ctrlr *ctrlr;
      20                 :            :         TAILQ_ENTRY(ctrlr_entry) link;
      21                 :            : };
      22                 :            : 
      23                 :            : static TAILQ_HEAD(, ctrlr_entry) g_controllers = TAILQ_HEAD_INITIALIZER(g_controllers);
      24                 :            : 
      25                 :            : static void
      26                 :          6 : cleanup(void)
      27                 :            : {
      28                 :            :         struct ctrlr_entry *ctrlr_entry, *tmp;
      29                 :          6 :         struct spdk_nvme_detach_ctx *detach_ctx = NULL;
      30                 :            : 
      31         [ +  + ]:         16 :         TAILQ_FOREACH_SAFE(ctrlr_entry, &g_controllers, link, tmp) {
      32         [ +  + ]:         10 :                 TAILQ_REMOVE(&g_controllers, ctrlr_entry, link);
      33                 :         10 :                 spdk_nvme_cuse_unregister(ctrlr_entry->ctrlr);
      34                 :         10 :                 spdk_nvme_detach_async(ctrlr_entry->ctrlr, &detach_ctx);
      35                 :         10 :                 free(ctrlr_entry);
      36                 :            :         }
      37                 :            : 
      38         [ +  - ]:          6 :         if (detach_ctx) {
      39                 :          6 :                 spdk_nvme_detach_poll(detach_ctx);
      40                 :            :         }
      41                 :          6 : }
      42                 :            : 
      43                 :            : static void
      44                 :          0 : usage(char *executable_name)
      45                 :            : {
      46         [ #  # ]:          0 :         printf("%s [options]\n", executable_name);
      47         [ #  # ]:          0 :         printf("options:\n");
      48         [ #  # ]:          0 :         printf(" -i shared memory ID [required]\n");
      49         [ #  # ]:          0 :         printf(" -m mask    core mask for DPDK\n");
      50         [ #  # ]:          0 :         printf(" -n channel number of memory channels used for DPDK\n");
      51         [ #  # ]:          0 :         printf(" -p core    main (primary) core for DPDK\n");
      52         [ #  # ]:          0 :         printf(" -s size    memory size in MB for DPDK\n");
      53         [ #  # ]:          0 :         printf(" -t msec    sleep time (ms) between checking for admin completions\n");
      54         [ #  # ]:          0 :         printf(" -H         show this usage\n");
      55                 :          0 : }
      56                 :            : 
      57                 :            : static bool
      58                 :         10 : probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
      59                 :            :          struct spdk_nvme_ctrlr_opts *opts)
      60                 :            : {
      61                 :            :         /*
      62                 :            :          * Set the io_queue_size to UINT16_MAX to initialize
      63                 :            :          * the controller with the possible largest queue size.
      64                 :            :          */
      65                 :         10 :         opts->io_queue_size = UINT16_MAX;
      66                 :         10 :         return true;
      67                 :            : }
      68                 :            : 
      69                 :            : static void
      70                 :         10 : attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
      71                 :            :           struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
      72                 :            : {
      73                 :            :         struct ctrlr_entry *entry;
      74                 :            : 
      75                 :         10 :         entry = malloc(sizeof(struct ctrlr_entry));
      76         [ -  + ]:         10 :         if (entry == NULL) {
      77   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Malloc error\n");
      78                 :          0 :                 exit(1);
      79                 :            :         }
      80                 :            : 
      81                 :         10 :         entry->ctrlr = ctrlr;
      82                 :         10 :         TAILQ_INSERT_TAIL(&g_controllers, entry, link);
      83         [ -  + ]:         10 :         if (spdk_nvme_cuse_register(ctrlr) != 0) {
      84   [ #  #  #  # ]:          0 :                 fprintf(stderr, "could not register ctrlr with cuse\n");
      85                 :            :         }
      86                 :         10 : }
      87                 :            : 
      88                 :            : static int
      89                 :        265 : stub_sleep(void *arg)
      90                 :            : {
      91                 :            :         struct ctrlr_entry *ctrlr_entry, *tmp;
      92                 :            : 
      93                 :        265 :         usleep(g_sleep_time * 1000);
      94         [ +  + ]:        770 :         TAILQ_FOREACH_SAFE(ctrlr_entry, &g_controllers, link, tmp) {
      95                 :        505 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr_entry->ctrlr);
      96                 :            :         }
      97                 :        265 :         return 0;
      98                 :            : }
      99                 :            : 
     100                 :            : static void
     101                 :          6 : stub_start(void *arg1)
     102                 :            : {
     103                 :          6 :         int shm_id = (intptr_t)arg1;
     104                 :            : 
     105                 :          6 :         spdk_unaffinitize_thread();
     106                 :            : 
     107         [ -  + ]:          6 :         if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
     108   [ #  #  #  # ]:          0 :                 fprintf(stderr, "spdk_nvme_probe() failed\n");
     109                 :          0 :                 exit(1);
     110                 :            :         }
     111                 :            : 
     112         [ -  + ]:          6 :         snprintf(g_path, sizeof(g_path), "/var/run/spdk_stub%d", shm_id);
     113   [ -  +  -  + ]:          6 :         if (mknod(g_path, S_IFREG, 0) != 0) {
     114   [ #  #  #  # ]:          0 :                 fprintf(stderr, "could not create sentinel file %s\n", g_path);
     115                 :          0 :                 exit(1);
     116                 :            :         }
     117                 :            : 
     118                 :          6 :         g_poller = SPDK_POLLER_REGISTER(stub_sleep, NULL, 0);
     119                 :          6 : }
     120                 :            : 
     121                 :            : static void
     122                 :          6 : stub_shutdown(void)
     123                 :            : {
     124                 :          6 :         spdk_poller_unregister(&g_poller);
     125         [ -  + ]:          6 :         unlink(g_path);
     126                 :          6 :         spdk_app_stop(0);
     127                 :          6 : }
     128                 :            : 
     129                 :            : int
     130                 :          6 : main(int argc, char **argv)
     131                 :            : {
     132                 :            :         int ch;
     133                 :          6 :         struct spdk_app_opts opts = {};
     134                 :            :         long int val;
     135                 :            : 
     136                 :            :         /* default value in opts structure */
     137                 :          6 :         spdk_app_opts_init(&opts, sizeof(opts));
     138                 :            : 
     139                 :          6 :         opts.name = "stub";
     140                 :          6 :         opts.rpc_addr = NULL;
     141                 :            : 
     142   [ +  +  +  +  :         24 :         while ((ch = getopt(argc, argv, "i:m:n:p:s:t:H")) != -1) {
                   +  + ]
     143         [ +  + ]:         18 :                 if (ch == 'm') {
     144                 :          6 :                         opts.reactor_mask = optarg;
     145   [ +  -  -  + ]:         12 :                 } else if (ch == '?' || ch == 'H') {
     146                 :          0 :                         usage(argv[0]);
     147                 :          0 :                         exit(EXIT_SUCCESS);
     148                 :            :                 } else {
     149                 :         12 :                         val = spdk_strtol(optarg, 10);
     150         [ -  + ]:         12 :                         if (val < 0) {
     151   [ #  #  #  # ]:          0 :                                 fprintf(stderr, "Converting a string to integer failed\n");
     152                 :          0 :                                 exit(1);
     153                 :            :                         }
     154   [ +  -  -  +  :         12 :                         switch (ch) {
                   -  - ]
     155                 :          6 :                         case 'i':
     156                 :          6 :                                 opts.shm_id = val;
     157                 :          6 :                                 break;
     158                 :          0 :                         case 'n':
     159                 :          0 :                                 opts.mem_channel = val;
     160                 :          0 :                                 break;
     161                 :          0 :                         case 'p':
     162                 :          0 :                                 opts.main_core = val;
     163                 :          0 :                                 break;
     164                 :          6 :                         case 's':
     165                 :          6 :                                 opts.mem_size = val;
     166                 :          6 :                                 break;
     167                 :          0 :                         case 't':
     168                 :          0 :                                 g_sleep_time = val;
     169                 :          0 :                                 break;
     170                 :          0 :                         default:
     171                 :          0 :                                 usage(argv[0]);
     172                 :          0 :                                 exit(EXIT_FAILURE);
     173                 :            :                         }
     174                 :            :                 }
     175                 :            :         }
     176                 :            : 
     177         [ -  + ]:          6 :         if (opts.shm_id < 0) {
     178   [ #  #  #  # ]:          0 :                 fprintf(stderr, "%s: -i shared memory ID must be specified\n", argv[0]);
     179                 :          0 :                 usage(argv[0]);
     180                 :          0 :                 exit(1);
     181                 :            :         }
     182                 :            : 
     183                 :          6 :         opts.shutdown_cb = stub_shutdown;
     184                 :            : 
     185                 :          6 :         ch = spdk_app_start(&opts, stub_start, (void *)(intptr_t)opts.shm_id);
     186                 :            : 
     187                 :          6 :         cleanup();
     188                 :          6 :         spdk_app_fini();
     189                 :            : 
     190                 :          6 :         return ch;
     191                 :            : }

Generated by: LCOV version 1.14