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
missing_field_err(nvme_ctrl_t * ctrl,const char * desc,nvme_err_t exp_err)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
main(void)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