1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright (c) Intel Corporation. 4 * All rights reserved. 5 */ 6 7 #include "spdk_cunit.h" 8 9 #include "common/lib/test_env.c" 10 #include "nvme/nvme_cuse.c" 11 12 DEFINE_STUB(nvme_io_msg_send, int, (struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, 13 spdk_nvme_io_msg_fn fn, void *arg), 0); 14 15 DEFINE_STUB(spdk_nvme_ctrlr_alloc_cmb_io_buffer, void *, (struct spdk_nvme_ctrlr *ctrlr, 16 size_t size), NULL); 17 18 DEFINE_STUB(spdk_nvme_ctrlr_cmd_admin_raw, int, (struct spdk_nvme_ctrlr *ctrlr, 19 struct spdk_nvme_cmd *cmd, void *buf, uint32_t len, 20 spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0); 21 22 DEFINE_STUB(spdk_nvme_ctrlr_cmd_io_raw_with_md, int, (struct spdk_nvme_ctrlr *ctrlr, 23 struct spdk_nvme_qpair *qpair, struct spdk_nvme_cmd *cmd, void *buf, uint32_t len, void *md_buf, 24 spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0); 25 26 DEFINE_STUB(spdk_nvme_ctrlr_get_num_ns, uint32_t, (struct spdk_nvme_ctrlr *ctrlr), 128); 27 28 static uint32_t g_active_num_ns = 4; 29 static uint32_t g_active_nsid_min = 1; 30 31 bool 32 spdk_nvme_ctrlr_is_active_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid) 33 { 34 return nsid >= g_active_nsid_min && nsid < g_active_num_ns + g_active_nsid_min; 35 } 36 37 uint32_t 38 spdk_nvme_ctrlr_get_first_active_ns(struct spdk_nvme_ctrlr *ctrlr) 39 { 40 return g_active_nsid_min; 41 } 42 43 uint32_t 44 spdk_nvme_ctrlr_get_next_active_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid) 45 { 46 nsid = nsid + 1; 47 48 if (spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { 49 return nsid; 50 } 51 52 return 0; 53 } 54 55 DEFINE_STUB(spdk_nvme_ctrlr_reset, int, (struct spdk_nvme_ctrlr *ctrlr), 0); 56 57 DEFINE_STUB(spdk_nvme_ctrlr_reset_subsystem, int, (struct spdk_nvme_ctrlr *ctrlr), 0); 58 59 DEFINE_STUB(spdk_nvme_ns_cmd_read_with_md, int, (struct spdk_nvme_ns *ns, 60 struct spdk_nvme_qpair *qpair, 61 void *payload, void *metadata, 62 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, 63 uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag), 0); 64 65 DEFINE_STUB(spdk_nvme_ns_cmd_write_with_md, int, (struct spdk_nvme_ns *ns, 66 struct spdk_nvme_qpair *qpair, 67 void *payload, void *metadata, 68 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, 69 uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag), 0); 70 71 DEFINE_STUB(spdk_nvme_ns_get_num_sectors, uint64_t, (struct spdk_nvme_ns *ns), 0); 72 73 DEFINE_STUB(spdk_nvme_ns_get_sector_size, uint32_t, (struct spdk_nvme_ns *ns), 0); 74 75 DEFINE_STUB(spdk_nvme_ns_get_md_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 DEFINE_STUB_V(nvme_ctrlr_update_namespaces, (struct spdk_nvme_ctrlr *ctrlr)); 89 90 static bool 91 wait_for_file(char *filename, bool exists) 92 { 93 int i; 94 95 for (i = 0; i < 1000; i++) { 96 if ((access(filename, F_OK) != -1) ^ (!exists)) { 97 return true; 98 } 99 usleep(100); 100 } 101 return false; 102 } 103 104 static void 105 verify_devices(struct spdk_nvme_ctrlr *ctrlr) 106 { 107 char ctrlr_name[256]; 108 size_t ctrlr_name_size; 109 char ctrlr_dev[256]; 110 char ns_dev[256 + 1 + 10]; /* sizeof ctrl_dev + 'n' + string size of UINT32_MAX */ 111 uint32_t nsid, num_ns; 112 int rv; 113 114 ctrlr_name_size = sizeof(ctrlr_name); 115 rv = spdk_nvme_cuse_get_ctrlr_name(ctrlr, ctrlr_name, &ctrlr_name_size); 116 SPDK_CU_ASSERT_FATAL(rv == 0); 117 118 rv = snprintf(ctrlr_dev, sizeof(ctrlr_dev), "/dev/%s", ctrlr_name); 119 CU_ASSERT(rv > 0); 120 CU_ASSERT(wait_for_file(ctrlr_dev, true)); 121 122 num_ns = spdk_nvme_ctrlr_get_num_ns(ctrlr); 123 124 for (nsid = 1; nsid <= num_ns; nsid++) { 125 snprintf(ns_dev, sizeof(ns_dev), "%sn%" PRIu32, ctrlr_dev, nsid); 126 if (spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { 127 CU_ASSERT(wait_for_file(ns_dev, true)); 128 } else { 129 CU_ASSERT(wait_for_file(ns_dev, false)); 130 } 131 } 132 133 /* Next one should never exist */ 134 snprintf(ns_dev, sizeof(ns_dev), "%sn%" PRIu32, ctrlr_dev, nsid); 135 CU_ASSERT(wait_for_file(ns_dev, false)); 136 } 137 138 static void 139 test_cuse_update(void) 140 { 141 int rc; 142 struct spdk_nvme_ctrlr ctrlr = {}; 143 144 rc = nvme_cuse_start(&ctrlr); 145 CU_ASSERT(rc == 0); 146 147 g_active_num_ns = 4; 148 g_active_nsid_min = 1; 149 nvme_cuse_update(&ctrlr); 150 verify_devices(&ctrlr); 151 152 g_active_num_ns = 0; 153 nvme_cuse_update(&ctrlr); 154 verify_devices(&ctrlr); 155 156 g_active_num_ns = 4; 157 g_active_nsid_min = spdk_nvme_ctrlr_get_num_ns(&ctrlr) - g_active_num_ns; 158 nvme_cuse_update(&ctrlr); 159 verify_devices(&ctrlr); 160 161 g_active_num_ns = 2; 162 g_active_nsid_min = 2; 163 nvme_cuse_update(&ctrlr); 164 verify_devices(&ctrlr); 165 166 g_active_num_ns = 10; 167 g_active_nsid_min = 5; 168 nvme_cuse_update(&ctrlr); 169 verify_devices(&ctrlr); 170 171 g_active_num_ns = 5; 172 g_active_nsid_min = 3; 173 nvme_cuse_update(&ctrlr); 174 verify_devices(&ctrlr); 175 176 g_active_num_ns = 6; 177 g_active_nsid_min = 1; 178 nvme_cuse_update(&ctrlr); 179 verify_devices(&ctrlr); 180 181 nvme_cuse_stop(&ctrlr); 182 } 183 184 int 185 main(int argc, char **argv) 186 { 187 CU_pSuite suite = NULL; 188 unsigned int num_failures; 189 190 CU_set_error_action(CUEA_ABORT); 191 CU_initialize_registry(); 192 suite = CU_add_suite("nvme_cuse", NULL, NULL); 193 CU_ADD_TEST(suite, test_cuse_update); 194 CU_basic_set_mode(CU_BRM_VERBOSE); 195 CU_basic_run_tests(); 196 num_failures = CU_get_number_of_failures(); 197 CU_cleanup_registry(); 198 return num_failures; 199 } 200