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 return nsid >= g_active_nsid_min && nsid < g_active_num_ns + g_active_nsid_min; 32 } 33 34 uint32_t 35 spdk_nvme_ctrlr_get_first_active_ns(struct spdk_nvme_ctrlr *ctrlr) 36 { 37 return g_active_nsid_min; 38 } 39 40 uint32_t 41 spdk_nvme_ctrlr_get_next_active_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid) 42 { 43 nsid = nsid + 1; 44 45 if (spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { 46 return nsid; 47 } 48 49 return 0; 50 } 51 52 DEFINE_STUB(spdk_nvme_ctrlr_reset, int, (struct spdk_nvme_ctrlr *ctrlr), 0); 53 54 DEFINE_STUB(spdk_nvme_ctrlr_reset_subsystem, int, (struct spdk_nvme_ctrlr *ctrlr), 0); 55 56 DEFINE_STUB(spdk_nvme_ns_cmd_read_with_md, int, (struct spdk_nvme_ns *ns, 57 struct spdk_nvme_qpair *qpair, 58 void *payload, void *metadata, 59 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, 60 uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag), 0); 61 62 DEFINE_STUB(spdk_nvme_ns_cmd_write_with_md, int, (struct spdk_nvme_ns *ns, 63 struct spdk_nvme_qpair *qpair, 64 void *payload, void *metadata, 65 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, 66 uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag), 0); 67 68 DEFINE_STUB(spdk_nvme_ns_get_num_sectors, uint64_t, (struct spdk_nvme_ns *ns), 0); 69 70 DEFINE_STUB(spdk_nvme_ns_get_sector_size, uint32_t, (struct spdk_nvme_ns *ns), 0); 71 72 DEFINE_STUB(spdk_nvme_ns_get_md_size, uint32_t, (struct spdk_nvme_ns *ns), 0); 73 74 DEFINE_STUB_V(spdk_unaffinitize_thread, (void)); 75 76 DEFINE_STUB(spdk_nvme_ctrlr_get_ns, struct spdk_nvme_ns *, (struct spdk_nvme_ctrlr *ctrlr, 77 uint32_t nsid), NULL); 78 79 DEFINE_STUB(nvme_io_msg_ctrlr_register, int, 80 (struct spdk_nvme_ctrlr *ctrlr, struct nvme_io_msg_producer *io_msg_producer), 0); 81 82 DEFINE_STUB_V(nvme_io_msg_ctrlr_unregister, 83 (struct spdk_nvme_ctrlr *ctrlr, struct nvme_io_msg_producer *io_msg_producer)); 84 85 DEFINE_STUB_V(nvme_ctrlr_update_namespaces, (struct spdk_nvme_ctrlr *ctrlr)); 86 87 static bool 88 wait_for_file(char *filename, bool exists) 89 { 90 int i; 91 92 for (i = 0; i < 1000; i++) { 93 if ((access(filename, F_OK) != -1) ^ (!exists)) { 94 return true; 95 } 96 usleep(100); 97 } 98 return false; 99 } 100 101 static void 102 verify_devices(struct spdk_nvme_ctrlr *ctrlr) 103 { 104 char ctrlr_name[256]; 105 size_t ctrlr_name_size; 106 char ctrlr_dev[256]; 107 char ns_dev[256 + 1 + 10]; /* sizeof ctrl_dev + 'n' + string size of UINT32_MAX */ 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 = spdk_nvme_cuse_register(&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 g_active_nsid_min = 1; 151 nvme_cuse_update(&ctrlr); 152 verify_devices(&ctrlr); 153 154 g_active_num_ns = 4; 155 g_active_nsid_min = spdk_nvme_ctrlr_get_num_ns(&ctrlr) - g_active_num_ns; 156 nvme_cuse_update(&ctrlr); 157 verify_devices(&ctrlr); 158 159 g_active_num_ns = 2; 160 g_active_nsid_min = 2; 161 nvme_cuse_update(&ctrlr); 162 verify_devices(&ctrlr); 163 164 g_active_num_ns = 10; 165 g_active_nsid_min = 5; 166 nvme_cuse_update(&ctrlr); 167 verify_devices(&ctrlr); 168 169 g_active_num_ns = 5; 170 g_active_nsid_min = 3; 171 nvme_cuse_update(&ctrlr); 172 verify_devices(&ctrlr); 173 174 g_active_num_ns = 6; 175 g_active_nsid_min = 1; 176 nvme_cuse_update(&ctrlr); 177 verify_devices(&ctrlr); 178 179 nvme_cuse_stop(&ctrlr); 180 } 181 182 int 183 main(int argc, char **argv) 184 { 185 CU_pSuite suite = NULL; 186 unsigned int num_failures; 187 188 CU_initialize_registry(); 189 suite = CU_add_suite("nvme_cuse", NULL, NULL); 190 CU_ADD_TEST(suite, test_cuse_update); 191 192 num_failures = spdk_ut_run_tests(argc, argv, NULL); 193 CU_cleanup_registry(); 194 return num_failures; 195 } 196