1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright (C) 2020 Intel Corporation. 4 * All rights reserved. 5 */ 6 7 #include "spdk_internal/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_cmd_admin_raw, int, (struct spdk_nvme_ctrlr *ctrlr, 16 struct spdk_nvme_cmd *cmd, void *buf, uint32_t len, 17 spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0); 18 19 DEFINE_STUB(spdk_nvme_ctrlr_cmd_io_raw_with_md, int, (struct spdk_nvme_ctrlr *ctrlr, 20 struct spdk_nvme_qpair *qpair, struct spdk_nvme_cmd *cmd, void *buf, uint32_t len, void *md_buf, 21 spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0); 22 23 DEFINE_STUB(spdk_nvme_ctrlr_get_num_ns, uint32_t, (struct spdk_nvme_ctrlr *ctrlr), 128); 24 25 static uint32_t g_active_num_ns = 4; 26 static uint32_t g_active_nsid_min = 1; 27 28 bool 29 spdk_nvme_ctrlr_is_active_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid) 30 { 31 if (g_active_num_ns == 0) { 32 return false; 33 } 34 return nsid && 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 if (g_active_num_ns > 0) { 41 return g_active_nsid_min; 42 } else { 43 return 0; 44 } 45 } 46 47 uint32_t 48 spdk_nvme_ctrlr_get_next_active_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid) 49 { 50 nsid = nsid + 1; 51 52 if (spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { 53 return nsid; 54 } 55 56 return 0; 57 } 58 59 DEFINE_STUB(spdk_nvme_ctrlr_reset, int, (struct spdk_nvme_ctrlr *ctrlr), 0); 60 61 DEFINE_STUB(spdk_nvme_ctrlr_reset_subsystem, int, (struct spdk_nvme_ctrlr *ctrlr), 0); 62 63 DEFINE_STUB(spdk_nvme_ns_cmd_read_with_md, int, (struct spdk_nvme_ns *ns, 64 struct spdk_nvme_qpair *qpair, 65 void *payload, void *metadata, 66 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, 67 uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag), 0); 68 69 DEFINE_STUB(spdk_nvme_ns_cmd_write_with_md, int, (struct spdk_nvme_ns *ns, 70 struct spdk_nvme_qpair *qpair, 71 void *payload, void *metadata, 72 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, 73 uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag), 0); 74 75 DEFINE_STUB(spdk_nvme_ns_get_num_sectors, uint64_t, (struct spdk_nvme_ns *ns), 0); 76 77 DEFINE_STUB(spdk_nvme_ns_get_sector_size, uint32_t, (struct spdk_nvme_ns *ns), 0); 78 79 DEFINE_STUB(spdk_nvme_ns_get_md_size, uint32_t, (struct spdk_nvme_ns *ns), 0); 80 81 DEFINE_STUB_V(spdk_unaffinitize_thread, (void)); 82 83 DEFINE_STUB(spdk_nvme_ctrlr_get_ns, struct spdk_nvme_ns *, (struct spdk_nvme_ctrlr *ctrlr, 84 uint32_t nsid), NULL); 85 86 DEFINE_STUB(nvme_io_msg_ctrlr_register, int, 87 (struct spdk_nvme_ctrlr *ctrlr, struct nvme_io_msg_producer *io_msg_producer), 0); 88 89 DEFINE_STUB_V(nvme_io_msg_ctrlr_unregister, 90 (struct spdk_nvme_ctrlr *ctrlr, struct nvme_io_msg_producer *io_msg_producer)); 91 92 DEFINE_STUB_V(nvme_ctrlr_update_namespaces, (struct spdk_nvme_ctrlr *ctrlr)); 93 94 static bool 95 wait_for_file(char *filename, bool exists) 96 { 97 int i; 98 99 for (i = 0; i < 10000; i++) { 100 if ((access(filename, F_OK) != -1) ^ (!exists)) { 101 return true; 102 } 103 usleep(100); 104 } 105 return false; 106 } 107 108 static bool 109 verify_devices(struct spdk_nvme_ctrlr *ctrlr) 110 { 111 char ctrlr_name[256]; 112 size_t ctrlr_name_size; 113 char ctrlr_dev[256]; 114 char ns_dev[256 + 1 + 10]; /* sizeof ctrl_dev + 'n' + string size of UINT32_MAX */ 115 uint32_t nsid, num_ns; 116 int rv; 117 118 ctrlr_name_size = sizeof(ctrlr_name); 119 rv = spdk_nvme_cuse_get_ctrlr_name(ctrlr, ctrlr_name, &ctrlr_name_size); 120 SPDK_CU_ASSERT_FATAL(rv == 0); 121 122 rv = snprintf(ctrlr_dev, sizeof(ctrlr_dev), "/dev/%s", ctrlr_name); 123 SPDK_CU_ASSERT_FATAL(rv > 0); 124 if (!wait_for_file(ctrlr_dev, true)) { 125 SPDK_ERRLOG("Couldn't find controller device: %s\n", ctrlr_dev); 126 return false; 127 } 128 129 num_ns = spdk_nvme_ctrlr_get_num_ns(ctrlr); 130 131 for (nsid = 1; nsid <= num_ns; nsid++) { 132 snprintf(ns_dev, sizeof(ns_dev), "%sn%" PRIu32, ctrlr_dev, nsid); 133 if (spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { 134 if (!wait_for_file(ns_dev, true)) { 135 SPDK_ERRLOG("Couldn't find namespace device: %s\n", ns_dev); 136 return false; 137 } 138 } else { 139 if (!wait_for_file(ns_dev, false)) { 140 SPDK_ERRLOG("Found unexpected namespace device: %s\n", ns_dev); 141 return false; 142 } 143 } 144 } 145 146 /* Next one should never exist */ 147 snprintf(ns_dev, sizeof(ns_dev), "%sn%" PRIu32, ctrlr_dev, nsid); 148 if (!wait_for_file(ns_dev, false)) { 149 SPDK_ERRLOG("Found unexpected namespace device beyond max NSID value: %s\n", ns_dev); 150 return false; 151 } 152 return true; 153 } 154 155 static void 156 test_cuse_update(void) 157 { 158 int rc; 159 struct spdk_nvme_ctrlr ctrlr = {}; 160 161 rc = spdk_nvme_cuse_register(&ctrlr); 162 CU_ASSERT(rc == 0); 163 164 g_active_num_ns = 4; 165 g_active_nsid_min = 1; 166 nvme_cuse_update(&ctrlr); 167 CU_ASSERT(verify_devices(&ctrlr)); 168 169 g_active_num_ns = 0; 170 g_active_nsid_min = 1; 171 nvme_cuse_update(&ctrlr); 172 CU_ASSERT(verify_devices(&ctrlr)); 173 174 g_active_num_ns = 4; 175 g_active_nsid_min = spdk_nvme_ctrlr_get_num_ns(&ctrlr) - g_active_num_ns; 176 nvme_cuse_update(&ctrlr); 177 CU_ASSERT(verify_devices(&ctrlr)); 178 179 g_active_num_ns = 2; 180 g_active_nsid_min = 2; 181 nvme_cuse_update(&ctrlr); 182 CU_ASSERT(verify_devices(&ctrlr)); 183 184 g_active_num_ns = 10; 185 g_active_nsid_min = 5; 186 nvme_cuse_update(&ctrlr); 187 CU_ASSERT(verify_devices(&ctrlr)); 188 189 g_active_num_ns = 5; 190 g_active_nsid_min = 3; 191 nvme_cuse_update(&ctrlr); 192 CU_ASSERT(verify_devices(&ctrlr)); 193 194 g_active_num_ns = 6; 195 g_active_nsid_min = 1; 196 nvme_cuse_update(&ctrlr); 197 CU_ASSERT(verify_devices(&ctrlr)); 198 199 g_active_num_ns = 10; 200 g_active_nsid_min = 10; 201 nvme_cuse_update(&ctrlr); 202 verify_devices(&ctrlr); 203 204 g_active_num_ns = 3; 205 g_active_nsid_min = 13; 206 nvme_cuse_update(&ctrlr); 207 verify_devices(&ctrlr); 208 209 g_active_num_ns = 10; 210 g_active_nsid_min = 10; 211 nvme_cuse_update(&ctrlr); 212 verify_devices(&ctrlr); 213 214 nvme_cuse_stop(&ctrlr); 215 } 216 217 int 218 main(int argc, char **argv) 219 { 220 CU_pSuite suite = NULL; 221 unsigned int num_failures; 222 223 CU_initialize_registry(); 224 suite = CU_add_suite("nvme_cuse", NULL, NULL); 225 CU_ADD_TEST(suite, test_cuse_update); 226 227 num_failures = spdk_ut_run_tests(argc, argv, NULL); 228 CU_cleanup_registry(); 229 return num_failures; 230 } 231