LCOV - code coverage report
Current view: top level - spdk/test/app/stub - stub.c (source / functions) Hit Total Coverage
Test: Combined Lines: 64 106 60.4 %
Date: 2024-07-13 08:44:29 Functions: 7 8 87.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 30 93 32.3 %

           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                 :            : static uint32_t g_io_queue_size;
      18                 :            : 
      19                 :            : struct ctrlr_entry {
      20                 :            :         struct spdk_nvme_ctrlr *ctrlr;
      21                 :            :         TAILQ_ENTRY(ctrlr_entry) link;
      22                 :            : };
      23                 :            : 
      24                 :            : static TAILQ_HEAD(, ctrlr_entry) g_controllers = TAILQ_HEAD_INITIALIZER(g_controllers);
      25                 :            : 
      26                 :            : static void
      27                 :          6 : cleanup(void)
      28                 :            : {
      29                 :            :         struct ctrlr_entry *ctrlr_entry, *tmp;
      30                 :          6 :         struct spdk_nvme_detach_ctx *detach_ctx = NULL;
      31                 :            : 
      32         [ +  + ]:         16 :         TAILQ_FOREACH_SAFE(ctrlr_entry, &g_controllers, link, tmp) {
      33         [ +  + ]:         10 :                 TAILQ_REMOVE(&g_controllers, ctrlr_entry, link);
      34                 :         10 :                 spdk_nvme_cuse_unregister(ctrlr_entry->ctrlr);
      35                 :         10 :                 spdk_nvme_detach_async(ctrlr_entry->ctrlr, &detach_ctx);
      36                 :         10 :                 free(ctrlr_entry);
      37                 :            :         }
      38                 :            : 
      39         [ +  - ]:          6 :         if (detach_ctx) {
      40                 :          6 :                 spdk_nvme_detach_poll(detach_ctx);
      41                 :            :         }
      42                 :          6 : }
      43                 :            : 
      44                 :            : static void
      45                 :          0 : usage(char *executable_name)
      46                 :            : {
      47         [ #  # ]:          0 :         printf("%s [options]\n", executable_name);
      48         [ #  # ]:          0 :         printf("options:\n");
      49         [ #  # ]:          0 :         printf(" -i shared memory ID [required]\n");
      50         [ #  # ]:          0 :         printf(" -m mask    core mask for DPDK\n");
      51         [ #  # ]:          0 :         printf(" -n channel number of memory channels used for DPDK\n");
      52         [ #  # ]:          0 :         printf(" -p core    main (primary) core for DPDK\n");
      53         [ #  # ]:          0 :         printf(" -s size    memory size in MB for DPDK\n");
      54         [ #  # ]:          0 :         printf(" -t msec    sleep time (ms) between checking for admin completions\n");
      55         [ #  # ]:          0 :         printf(" -q size    override default io_queue_size when attaching controllers\n");
      56         [ #  # ]:          0 :         printf(" -H         show this usage\n");
      57                 :          0 : }
      58                 :            : 
      59                 :            : static bool
      60                 :         10 : probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
      61                 :            :          struct spdk_nvme_ctrlr_opts *opts)
      62                 :            : {
      63         [ -  + ]:         10 :         if (g_io_queue_size > 0) {
      64                 :          0 :                 opts->io_queue_size = g_io_queue_size;
      65                 :            :         }
      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                 :        257 : stub_sleep(void *arg)
      90                 :            : {
      91                 :            :         struct ctrlr_entry *ctrlr_entry, *tmp;
      92                 :            : 
      93                 :        257 :         usleep(g_sleep_time * 1000);
      94         [ +  + ]:        748 :         TAILQ_FOREACH_SAFE(ctrlr_entry, &g_controllers, link, tmp) {
      95                 :        491 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr_entry->ctrlr);
      96                 :            :         }
      97                 :        257 :         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 :         snprintf(g_path, sizeof(g_path), "/var/run/spdk_stub%d", shm_id);
     106                 :            : 
     107                 :            :         /* If sentinel file already exists from earlier crashed stub, delete
     108                 :            :          * it now to avoid mknod() failure after spdk_nvme_probe() completes.
     109                 :            :          */
     110         [ -  + ]:          6 :         unlink(g_path);
     111                 :            : 
     112                 :          6 :         spdk_unaffinitize_thread();
     113                 :            : 
     114         [ -  + ]:          6 :         if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
     115   [ #  #  #  # ]:          0 :                 fprintf(stderr, "spdk_nvme_probe() failed\n");
     116                 :          0 :                 exit(1);
     117                 :            :         }
     118                 :            : 
     119   [ -  +  -  + ]:          6 :         if (mknod(g_path, S_IFREG, 0) != 0) {
     120   [ #  #  #  # ]:          0 :                 fprintf(stderr, "could not create sentinel file %s\n", g_path);
     121                 :          0 :                 exit(1);
     122                 :            :         }
     123                 :            : 
     124                 :          6 :         g_poller = SPDK_POLLER_REGISTER(stub_sleep, NULL, 0);
     125                 :          6 : }
     126                 :            : 
     127                 :            : static void
     128                 :          6 : stub_shutdown(void)
     129                 :            : {
     130                 :          6 :         spdk_poller_unregister(&g_poller);
     131         [ -  + ]:          6 :         unlink(g_path);
     132                 :          6 :         spdk_app_stop(0);
     133                 :          6 : }
     134                 :            : 
     135                 :            : int
     136                 :          6 : main(int argc, char **argv)
     137                 :            : {
     138                 :            :         int ch;
     139                 :          6 :         struct spdk_app_opts opts = {};
     140                 :            :         long int val;
     141                 :            : 
     142                 :            :         /* default value in opts structure */
     143                 :          6 :         spdk_app_opts_init(&opts, sizeof(opts));
     144                 :            : 
     145                 :          6 :         opts.name = "stub";
     146                 :          6 :         opts.rpc_addr = NULL;
     147                 :          6 :         opts.env_context = "--proc-type=primary";
     148                 :            : 
     149   [ +  +  +  +  :         24 :         while ((ch = getopt(argc, argv, "i:m:n:p:q:s:t:H")) != -1) {
                   +  + ]
     150         [ +  + ]:         18 :                 if (ch == 'm') {
     151                 :          6 :                         opts.reactor_mask = optarg;
     152   [ +  -  -  + ]:         12 :                 } else if (ch == '?' || ch == 'H') {
     153                 :          0 :                         usage(argv[0]);
     154                 :          0 :                         exit(EXIT_SUCCESS);
     155                 :            :                 } else {
     156                 :         12 :                         val = spdk_strtol(optarg, 10);
     157         [ -  + ]:         12 :                         if (val < 0) {
     158   [ #  #  #  # ]:          0 :                                 fprintf(stderr, "Converting a string to integer failed\n");
     159                 :          0 :                                 exit(1);
     160                 :            :                         }
     161   [ +  -  -  +  :         12 :                         switch (ch) {
                -  -  - ]
     162                 :          6 :                         case 'i':
     163                 :          6 :                                 opts.shm_id = val;
     164                 :          6 :                                 break;
     165                 :          0 :                         case 'n':
     166                 :          0 :                                 opts.mem_channel = val;
     167                 :          0 :                                 break;
     168                 :          0 :                         case 'p':
     169                 :          0 :                                 opts.main_core = val;
     170                 :          0 :                                 break;
     171                 :          6 :                         case 's':
     172                 :          6 :                                 opts.mem_size = val;
     173                 :          6 :                                 break;
     174                 :          0 :                         case 't':
     175                 :          0 :                                 g_sleep_time = val;
     176                 :          0 :                                 break;
     177                 :          0 :                         case 'q':
     178                 :          0 :                                 g_io_queue_size = val;
     179                 :          0 :                                 break;
     180                 :          0 :                         default:
     181                 :          0 :                                 usage(argv[0]);
     182                 :          0 :                                 exit(EXIT_FAILURE);
     183                 :            :                         }
     184                 :            :                 }
     185                 :            :         }
     186                 :            : 
     187         [ -  + ]:          6 :         if (opts.shm_id < 0) {
     188   [ #  #  #  # ]:          0 :                 fprintf(stderr, "%s: -i shared memory ID must be specified\n", argv[0]);
     189                 :          0 :                 usage(argv[0]);
     190                 :          0 :                 exit(1);
     191                 :            :         }
     192                 :            : 
     193                 :          6 :         opts.shutdown_cb = stub_shutdown;
     194                 :            : 
     195                 :          6 :         ch = spdk_app_start(&opts, stub_start, (void *)(intptr_t)opts.shm_id);
     196                 :            : 
     197                 :          6 :         cleanup();
     198                 :          6 :         spdk_app_fini();
     199                 :            : 
     200                 :          6 :         return ch;
     201                 :            : }

Generated by: LCOV version 1.14