1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2025 Oxide Computer Company 14 */ 15 16 /* 17 * Verify that we generate the appropriate missing field error for destructive 18 * tests. 19 */ 20 21 #include <err.h> 22 #include <string.h> 23 24 #include "libnvme_test_common.h" 25 26 static bool 27 missing_field_err(nvme_ctrl_t *ctrl, const char *desc, nvme_err_t exp_err) 28 { 29 nvme_err_t err = nvme_ctrl_err(ctrl); 30 31 if (err == exp_err) { 32 return (true); 33 } 34 35 warnx("TEST FAILED: %s returned wrong error %s (0x%x), not %s (0x%x)", 36 desc, nvme_ctrl_errtostr(ctrl, err), err, 37 nvme_ctrl_errtostr(ctrl, exp_err), exp_err); 38 return (false); 39 } 40 41 int 42 main(void) 43 { 44 int ret = EXIT_SUCCESS; 45 nvme_t *nvme; 46 nvme_ctrl_t *ctrl; 47 nvme_fw_commit_req_t *fw_commit_req = NULL; 48 nvme_format_req_t *format_req = NULL; 49 nvme_ns_create_req_t *create_req = NULL; 50 nvme_ns_delete_req_t *delete_req = NULL; 51 nvme_ns_attach_req_t *attach_req = NULL; 52 53 libnvme_test_init(&nvme, &ctrl); 54 55 if (!nvme_fw_commit_req_init(ctrl, &fw_commit_req)) { 56 if (nvme_ctrl_err(ctrl) == NVME_ERR_FW_UNSUP_BY_DEV) { 57 warnx("TEST SKIPPED: device does not support firmware " 58 "requests"); 59 } else { 60 libnvme_test_ctrl_warn(ctrl, "failed to initialize fw " 61 "commit request"); 62 ret = EXIT_FAILURE; 63 } 64 } else if (nvme_fw_commit_req_exec(fw_commit_req)) { 65 warnx("TEST FAILED: fw commit request succeeded despite " 66 "missing fields"); 67 ret = EXIT_FAILURE; 68 } else if (!missing_field_err(ctrl, "fw commit request", 69 NVME_ERR_FW_COMMIT_REQ_MISSING_FIELDS)) { 70 ret = EXIT_FAILURE; 71 } else { 72 (void) printf("TEST PASSED: fw commit request generated " 73 "missing fields error\n"); 74 } 75 nvme_fw_commit_req_fini(fw_commit_req); 76 77 if (!nvme_format_req_init(ctrl, &format_req)) { 78 if (nvme_ctrl_err(ctrl) == NVME_ERR_FORMAT_UNSUP_BY_DEV) { 79 warnx("TEST SKIPPED: device does not support format " 80 "requests"); 81 } else { 82 libnvme_test_ctrl_warn(ctrl, "failed to initialize " 83 "format request"); 84 ret = EXIT_FAILURE; 85 } 86 } else if (nvme_format_req_exec(format_req)) { 87 warnx("TEST FAILED: format request succeeded despite missing " 88 "fields"); 89 ret = EXIT_FAILURE; 90 } else if (!missing_field_err(ctrl, "format request", 91 NVME_ERR_FORMAT_REQ_MISSING_FIELDS)) { 92 ret = EXIT_FAILURE; 93 } else { 94 (void) printf("TEST PASSED: format request generated missing " 95 "fields error\n"); 96 } 97 nvme_format_req_fini(format_req); 98 99 if (!nvme_ns_create_req_init_by_csi(ctrl, NVME_CSI_NVM, &create_req)) { 100 libnvme_test_ctrl_warn(ctrl, "failed to initialize namespace " 101 "create request"); 102 ret = EXIT_FAILURE; 103 } else if (nvme_ns_create_req_exec(create_req)) { 104 warnx("TEST FAILED: namespace create request succeeded despite " 105 "missing fields"); 106 ret = EXIT_FAILURE; 107 } else if (!missing_field_err(ctrl, "namespace create", 108 NVME_ERR_NS_CREATE_REQ_MISSING_FIELDS)) { 109 ret = EXIT_FAILURE; 110 } else { 111 (void) printf("TEST PASSED: namespace create generated missing " 112 "fields error\n"); 113 } 114 nvme_ns_create_req_fini(create_req); 115 116 if (!nvme_ns_delete_req_init(ctrl, &delete_req)) { 117 libnvme_test_ctrl_warn(ctrl, "failed to initialize namespace " 118 "delete request"); 119 ret = EXIT_FAILURE; 120 } else if (nvme_ns_delete_req_exec(delete_req)) { 121 warnx("TEST FAILED: namespace delete request succeeded despite " 122 "missing fields"); 123 ret = EXIT_FAILURE; 124 } else if (!missing_field_err(ctrl, "namespace delete", 125 NVME_ERR_NS_DELETE_REQ_MISSING_FIELDS)) { 126 ret = EXIT_FAILURE; 127 } else { 128 (void) printf("TEST PASSED: namespace delete generated missing " 129 "fields error\n"); 130 } 131 nvme_ns_delete_req_fini(delete_req); 132 133 if (!nvme_ns_attach_req_init_by_sel(ctrl, NVME_NS_ATTACH_CTRL_ATTACH, 134 &attach_req)) { 135 libnvme_test_ctrl_warn(ctrl, "failed to initialize namespace " 136 "attach request"); 137 ret = EXIT_FAILURE; 138 } else if (nvme_ns_attach_req_exec(attach_req)) { 139 warnx("TEST FAILED: namespace attach request succeeded despite " 140 "missing fields"); 141 ret = EXIT_FAILURE; 142 } else if (!missing_field_err(ctrl, "namespace attach", 143 NVME_ERR_NS_ATTACH_REQ_MISSING_FIELDS)) { 144 ret = EXIT_FAILURE; 145 } else { 146 (void) printf("TEST PASSED: namespace attach generated missing " 147 "fields error\n"); 148 } 149 nvme_ns_attach_req_fini(attach_req); 150 151 if (!nvme_ns_attach_req_init_by_sel(ctrl, NVME_NS_ATTACH_CTRL_DETACH, 152 &attach_req)) { 153 libnvme_test_ctrl_warn(ctrl, "failed to initialize namespace " 154 "detach request"); 155 ret = EXIT_FAILURE; 156 } else if (nvme_ns_attach_req_exec(attach_req)) { 157 warnx("TEST FAILED: namespace detach request succeeded despite " 158 "missing fields"); 159 ret = EXIT_FAILURE; 160 } else if (!missing_field_err(ctrl, "namespace detach", 161 NVME_ERR_NS_ATTACH_REQ_MISSING_FIELDS)) { 162 ret = EXIT_FAILURE; 163 } else { 164 (void) printf("TEST PASSED: namespace detach generated missing " 165 "fields error\n"); 166 } 167 nvme_ns_attach_req_fini(attach_req); 168 169 170 171 nvme_ctrl_fini(ctrl); 172 nvme_fini(nvme); 173 174 if (ret == EXIT_SUCCESS) { 175 (void) printf("All tests passed successfully\n"); 176 } 177 178 return (ret); 179 } 180