1 2 /*- 3 * BSD LICENSE 4 * 5 * Copyright (c) Intel Corporation. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * * Neither the name of Intel Corporation nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "spdk_cunit.h" 36 37 #include "common/lib/test_env.c" 38 #include "nvme/nvme_cuse.c" 39 40 DEFINE_STUB(nvme_io_msg_send, int, (struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, 41 spdk_nvme_io_msg_fn fn, void *arg), 0); 42 43 DEFINE_STUB(spdk_nvme_ctrlr_alloc_cmb_io_buffer, void *, (struct spdk_nvme_ctrlr *ctrlr, 44 size_t size), NULL); 45 46 DEFINE_STUB(spdk_nvme_ctrlr_cmd_admin_raw, int, (struct spdk_nvme_ctrlr *ctrlr, 47 struct spdk_nvme_cmd *cmd, void *buf, uint32_t len, 48 spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0); 49 50 DEFINE_STUB(spdk_nvme_ctrlr_get_num_ns, uint32_t, (struct spdk_nvme_ctrlr *ctrlr), 128); 51 52 static uint32_t g_active_num_ns = 4; 53 static uint32_t g_active_nsid_min = 1; 54 55 bool 56 spdk_nvme_ctrlr_is_active_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid) 57 { 58 return nsid >= g_active_nsid_min && nsid < g_active_num_ns + g_active_nsid_min; 59 } 60 61 DEFINE_STUB(spdk_nvme_ctrlr_reset, int, (struct spdk_nvme_ctrlr *ctrlr), 0); 62 63 DEFINE_STUB(spdk_nvme_ns_cmd_read, int, (struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, 64 void *payload, 65 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, 66 uint32_t io_flags), 0); 67 68 DEFINE_STUB(spdk_nvme_ns_cmd_write, int, (struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, 69 void *payload, 70 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, 71 uint32_t io_flags), 0); 72 73 DEFINE_STUB(spdk_nvme_ns_get_num_sectors, uint64_t, (struct spdk_nvme_ns *ns), 0); 74 75 DEFINE_STUB(spdk_nvme_ns_get_sector_size, uint32_t, (struct spdk_nvme_ns *ns), 0); 76 77 DEFINE_STUB_V(spdk_unaffinitize_thread, (void)); 78 79 DEFINE_STUB(spdk_nvme_ctrlr_get_ns, struct spdk_nvme_ns *, (struct spdk_nvme_ctrlr *ctrlr, 80 uint32_t nsid), NULL); 81 82 DEFINE_STUB(nvme_io_msg_ctrlr_register, int, 83 (struct spdk_nvme_ctrlr *ctrlr, struct nvme_io_msg_producer *io_msg_producer), 0); 84 85 DEFINE_STUB_V(nvme_io_msg_ctrlr_unregister, 86 (struct spdk_nvme_ctrlr *ctrlr, struct nvme_io_msg_producer *io_msg_producer)); 87 88 static bool 89 wait_for_file(char *filename, bool exists) 90 { 91 int i; 92 93 for (i = 0; i < 1000; i++) { 94 if ((access(filename, F_OK) != -1) ^ (!exists)) { 95 return true; 96 } 97 usleep(100); 98 } 99 return false; 100 } 101 102 static void 103 verify_devices(struct spdk_nvme_ctrlr *ctrlr) 104 { 105 char ctrlr_name[256]; 106 size_t ctrlr_name_size; 107 char ctrlr_dev[256], ns_dev[256 + 10]; 108 uint32_t nsid, num_ns; 109 int rv; 110 111 ctrlr_name_size = sizeof(ctrlr_name); 112 rv = spdk_nvme_cuse_get_ctrlr_name(ctrlr, ctrlr_name, &ctrlr_name_size); 113 SPDK_CU_ASSERT_FATAL(rv == 0); 114 115 rv = snprintf(ctrlr_dev, sizeof(ctrlr_dev), "/dev/%s", ctrlr_name); 116 CU_ASSERT(rv > 0); 117 CU_ASSERT(wait_for_file(ctrlr_dev, true)); 118 119 num_ns = spdk_nvme_ctrlr_get_num_ns(ctrlr); 120 121 for (nsid = 1; nsid <= num_ns; nsid++) { 122 snprintf(ns_dev, sizeof(ns_dev), "%sn%" PRIu32, ctrlr_dev, nsid); 123 if (spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { 124 CU_ASSERT(wait_for_file(ns_dev, true)); 125 } else { 126 CU_ASSERT(wait_for_file(ns_dev, false)); 127 } 128 } 129 130 /* Next one should never exist */ 131 snprintf(ns_dev, sizeof(ns_dev), "%sn%" PRIu32, ctrlr_dev, nsid); 132 CU_ASSERT(wait_for_file(ns_dev, false)); 133 } 134 135 static void 136 test_cuse_update(void) 137 { 138 int rc; 139 struct spdk_nvme_ctrlr ctrlr = {}; 140 141 rc = nvme_cuse_start(&ctrlr); 142 CU_ASSERT(rc == 0); 143 144 g_active_num_ns = 4; 145 g_active_nsid_min = 1; 146 nvme_cuse_update(&ctrlr); 147 verify_devices(&ctrlr); 148 149 g_active_num_ns = 0; 150 nvme_cuse_update(&ctrlr); 151 verify_devices(&ctrlr); 152 153 g_active_num_ns = 4; 154 g_active_nsid_min = spdk_nvme_ctrlr_get_num_ns(&ctrlr) - g_active_num_ns; 155 nvme_cuse_update(&ctrlr); 156 verify_devices(&ctrlr); 157 158 g_active_num_ns = 2; 159 g_active_nsid_min = 2; 160 nvme_cuse_update(&ctrlr); 161 verify_devices(&ctrlr); 162 163 g_active_num_ns = 10; 164 g_active_nsid_min = 5; 165 nvme_cuse_update(&ctrlr); 166 verify_devices(&ctrlr); 167 168 g_active_num_ns = 5; 169 g_active_nsid_min = 3; 170 nvme_cuse_update(&ctrlr); 171 verify_devices(&ctrlr); 172 173 g_active_num_ns = 6; 174 g_active_nsid_min = 1; 175 nvme_cuse_update(&ctrlr); 176 verify_devices(&ctrlr); 177 178 nvme_cuse_stop(&ctrlr); 179 } 180 181 int main(int argc, char **argv) 182 { 183 CU_pSuite suite = NULL; 184 unsigned int num_failures; 185 186 CU_set_error_action(CUEA_ABORT); 187 CU_initialize_registry(); 188 suite = CU_add_suite("nvme_cuse", NULL, NULL); 189 CU_ADD_TEST(suite, test_cuse_update); 190 CU_basic_set_mode(CU_BRM_VERBOSE); 191 CU_basic_run_tests(); 192 num_failures = CU_get_number_of_failures(); 193 CU_cleanup_registry(); 194 return num_failures; 195 } 196