LCOV - code coverage report
Current view: top level - spdk/test/app/stub - stub.c (source / functions) Hit Total Coverage
Test: Combined Lines: 65 118 55.1 %
Date: 2024-11-20 19:15:45 Functions: 7 8 87.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 31 237 13.1 %

           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                 :          0 :         }
      38                 :            : 
      39         [ +  - ]:          6 :         if (detach_ctx) {
      40                 :          6 :                 spdk_nvme_detach_poll(detach_ctx);
      41                 :          0 :         }
      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(" -L flag    enable log flag\n");
      53         [ #  # ]:          0 :         printf(" -p core    main (primary) core for DPDK\n");
      54         [ #  # ]:          0 :         printf(" -s size    memory size in MB for DPDK\n");
      55         [ #  # ]:          0 :         printf(" -t msec    sleep time (ms) between checking for admin completions\n");
      56         [ #  # ]:          0 :         printf(" -q size    override default io_queue_size when attaching controllers\n");
      57         [ #  # ]:          0 :         printf(" -H         show this usage\n");
      58                 :          0 : }
      59                 :            : 
      60                 :            : static bool
      61                 :         10 : probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
      62                 :            :          struct spdk_nvme_ctrlr_opts *opts)
      63                 :            : {
      64         [ -  + ]:         10 :         if (g_io_queue_size > 0) {
      65   [ #  #  #  # ]:          0 :                 opts->io_queue_size = g_io_queue_size;
      66                 :          0 :         }
      67                 :         10 :         return true;
      68                 :            : }
      69                 :            : 
      70                 :            : static void
      71                 :         10 : attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
      72                 :            :           struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
      73                 :            : {
      74                 :            :         struct ctrlr_entry *entry;
      75                 :            : 
      76                 :         10 :         entry = malloc(sizeof(struct ctrlr_entry));
      77         [ -  + ]:         10 :         if (entry == NULL) {
      78   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Malloc error\n");
      79         [ #  # ]:          0 :                 exit(1);
      80                 :            :         }
      81                 :            : 
      82   [ #  #  #  # ]:         10 :         entry->ctrlr = ctrlr;
      83   [ #  #  #  #  :         10 :         TAILQ_INSERT_TAIL(&g_controllers, entry, link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
      84         [ -  + ]:         10 :         if (spdk_nvme_cuse_register(ctrlr) != 0) {
      85   [ #  #  #  # ]:          0 :                 fprintf(stderr, "could not register ctrlr with cuse\n");
      86                 :          0 :         }
      87                 :         10 : }
      88                 :            : 
      89                 :            : static int
      90                 :        263 : stub_sleep(void *arg)
      91                 :            : {
      92                 :            :         struct ctrlr_entry *ctrlr_entry, *tmp;
      93                 :            : 
      94                 :        263 :         usleep(g_sleep_time * 1000);
      95   [ +  +  #  #  :        768 :         TAILQ_FOREACH_SAFE(ctrlr_entry, &g_controllers, link, tmp) {
          #  #  #  #  #  
                      # ]
      96   [ #  #  #  # ]:        505 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr_entry->ctrlr);
      97                 :          0 :         }
      98                 :        263 :         return 0;
      99                 :            : }
     100                 :            : 
     101                 :            : static void
     102                 :          6 : stub_start(void *arg1)
     103                 :            : {
     104                 :          6 :         int shm_id = (intptr_t)arg1;
     105                 :            : 
     106         [ -  + ]:          6 :         snprintf(g_path, sizeof(g_path), "/var/run/spdk_stub%d", shm_id);
     107                 :            : 
     108                 :            :         /* If sentinel file already exists from earlier crashed stub, delete
     109                 :            :          * it now to avoid mknod() failure after spdk_nvme_probe() completes.
     110                 :            :          */
     111         [ -  + ]:          6 :         unlink(g_path);
     112                 :            : 
     113                 :          6 :         spdk_unaffinitize_thread();
     114                 :            : 
     115         [ -  + ]:          6 :         if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
     116   [ #  #  #  # ]:          0 :                 fprintf(stderr, "spdk_nvme_probe() failed\n");
     117         [ #  # ]:          0 :                 exit(1);
     118                 :            :         }
     119                 :            : 
     120   [ -  +  -  + ]:          6 :         if (mknod(g_path, S_IFREG, 0) != 0) {
     121   [ #  #  #  # ]:          0 :                 fprintf(stderr, "could not create sentinel file %s\n", g_path);
     122         [ #  # ]:          0 :                 exit(1);
     123                 :            :         }
     124                 :            : 
     125                 :          6 :         g_poller = SPDK_POLLER_REGISTER(stub_sleep, NULL, 0);
     126                 :          6 : }
     127                 :            : 
     128                 :            : static void
     129                 :          6 : stub_shutdown(void)
     130                 :            : {
     131                 :          6 :         spdk_poller_unregister(&g_poller);
     132         [ -  + ]:          6 :         unlink(g_path);
     133                 :          6 :         spdk_app_stop(0);
     134                 :          6 : }
     135                 :            : 
     136                 :            : int
     137                 :          6 : main(int argc, char **argv)
     138                 :            : {
     139                 :            :         int ch;
     140                 :          6 :         struct spdk_app_opts opts = {};
     141                 :            :         long int val;
     142                 :            : 
     143                 :            :         /* default value in opts structure */
     144                 :          6 :         spdk_app_opts_init(&opts, sizeof(opts));
     145                 :            : 
     146                 :          6 :         opts.name = "stub";
     147                 :          6 :         opts.rpc_addr = NULL;
     148                 :          6 :         opts.env_context = "--proc-type=primary";
     149                 :            : 
     150   [ +  +  +  +  :         24 :         while ((ch = getopt(argc, argv, "i:m:n:p:q:s:t:HL:")) != -1) {
                   +  + ]
     151         [ +  + ]:         18 :                 if (ch == 'm') {
     152                 :          6 :                         opts.reactor_mask = optarg;
     153         [ -  + ]:         12 :                 } else if (ch == 'L') {
     154         [ #  # ]:          0 :                         if (spdk_log_set_flag(optarg) != 0) {
     155                 :          0 :                                 SPDK_ERRLOG("unknown flag: %s\n", optarg);
     156   [ #  #  #  # ]:          0 :                                 usage(argv[0]);
     157         [ #  # ]:          0 :                                 exit(EXIT_FAILURE);
     158                 :            :                         }
     159                 :            : #ifdef DEBUG
     160                 :          0 :                         opts.print_level = SPDK_LOG_DEBUG;
     161                 :            : #endif
     162   [ +  -  -  + ]:         12 :                 } else if (ch == '?' || ch == 'H') {
     163   [ #  #  #  # ]:          0 :                         usage(argv[0]);
     164         [ #  # ]:          0 :                         exit(EXIT_SUCCESS);
     165                 :            :                 } else {
     166                 :         12 :                         val = spdk_strtol(optarg, 10);
     167         [ -  + ]:         12 :                         if (val < 0) {
     168   [ #  #  #  # ]:          0 :                                 fprintf(stderr, "Converting a string to integer failed\n");
     169         [ #  # ]:          0 :                                 exit(1);
     170                 :            :                         }
     171   [ +  -  -  +  :         12 :                         switch (ch) {
                -  -  - ]
     172                 :          6 :                         case 'i':
     173                 :          6 :                                 opts.shm_id = val;
     174                 :          6 :                                 break;
     175                 :          0 :                         case 'n':
     176                 :          0 :                                 opts.mem_channel = val;
     177                 :          0 :                                 break;
     178                 :          0 :                         case 'p':
     179                 :          0 :                                 opts.main_core = val;
     180                 :          0 :                                 break;
     181                 :          6 :                         case 's':
     182                 :          6 :                                 opts.mem_size = val;
     183                 :          6 :                                 break;
     184                 :          0 :                         case 't':
     185                 :          0 :                                 g_sleep_time = val;
     186                 :          0 :                                 break;
     187                 :          0 :                         case 'q':
     188                 :          0 :                                 g_io_queue_size = val;
     189                 :          0 :                                 break;
     190                 :          0 :                         default:
     191   [ #  #  #  # ]:          0 :                                 usage(argv[0]);
     192         [ #  # ]:          0 :                                 exit(EXIT_FAILURE);
     193                 :            :                         }
     194                 :            :                 }
     195                 :            :         }
     196                 :            : 
     197         [ -  + ]:          6 :         if (opts.shm_id < 0) {
     198   [ #  #  #  # ]:          0 :                 fprintf(stderr, "%s: -i shared memory ID must be specified\n", argv[0]);
     199   [ #  #  #  # ]:          0 :                 usage(argv[0]);
     200         [ #  # ]:          0 :                 exit(1);
     201                 :            :         }
     202                 :            : 
     203                 :          6 :         opts.shutdown_cb = stub_shutdown;
     204                 :            : 
     205                 :          6 :         ch = spdk_app_start(&opts, stub_start, (void *)(intptr_t)opts.shm_id);
     206                 :            : 
     207                 :          6 :         cleanup();
     208                 :          6 :         spdk_app_fini();
     209                 :            : 
     210                 :          6 :         return ch;
     211                 :            : }

Generated by: LCOV version 1.15