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 the
18 * non-vendor-specific request types. Destructive requests are in
19 * missing-field-destruct.c.
20 */
21
22 #include <err.h>
23 #include <string.h>
24
25 #include "libnvme_test_common.h"
26
27 static bool
missing_field_err(nvme_ctrl_t * ctrl,const char * desc,nvme_err_t exp_err)28 missing_field_err(nvme_ctrl_t *ctrl, const char *desc, nvme_err_t exp_err)
29 {
30 nvme_err_t err = nvme_ctrl_err(ctrl);
31
32 if (err == exp_err) {
33 return (true);
34 }
35
36 warnx("TEST FAILED: %s returned wrong error %s (0x%x), not %s (0x%x)",
37 desc, nvme_ctrl_errtostr(ctrl, err), err,
38 nvme_ctrl_errtostr(ctrl, exp_err), exp_err);
39 return (false);
40 }
41
42 int
main(void)43 main(void)
44 {
45 int ret = EXIT_SUCCESS;
46 nvme_t *nvme;
47 nvme_ctrl_t *ctrl;
48 nvme_id_req_t *id_req = NULL;
49 nvme_log_req_t *log_req = NULL;
50 nvme_get_feat_req_t *get_feat_req = NULL;
51 nvme_vuc_req_t *vuc_req = NULL;
52
53 libnvme_test_init(&nvme, &ctrl);
54
55 if (!nvme_id_req_init_by_cns(ctrl, NVME_CSI_NVM, NVME_IDENTIFY_CTRL,
56 &id_req)) {
57 libnvme_test_ctrl_warn(ctrl, "failed to initialize identify "
58 "request");
59 ret = EXIT_FAILURE;
60 } else if (nvme_id_req_exec(id_req)) {
61 warnx("TEST FAILED: identify request succeeded despite missing "
62 "fields");
63 ret = EXIT_FAILURE;
64 } else if (!missing_field_err(ctrl, "identify request",
65 NVME_ERR_IDENTIFY_REQ_MISSING_FIELDS)) {
66 ret = EXIT_FAILURE;
67 } else {
68 (void) printf("TEST PASSED: identify request generated missing "
69 "fields error\n");
70 }
71 nvme_id_req_fini(id_req);
72
73 if (!nvme_log_req_init(ctrl, &log_req)) {
74 libnvme_test_ctrl_warn(ctrl, "failed to initialize log "
75 "request");
76 ret = EXIT_FAILURE;
77 } else if (nvme_log_req_exec(log_req)) {
78 warnx("TEST FAILED: log request succeeded despite missing "
79 "fields");
80 ret = EXIT_FAILURE;
81 } else if (!missing_field_err(ctrl, "log request",
82 NVME_ERR_LOG_REQ_MISSING_FIELDS)) {
83 ret = EXIT_FAILURE;
84 } else {
85 (void) printf("TEST PASSED: log request generated missing "
86 "fields error\n");
87 }
88 nvme_log_req_fini(log_req);
89
90 if (!nvme_get_feat_req_init(ctrl, &get_feat_req)) {
91 libnvme_test_ctrl_warn(ctrl, "failed to initialize get feature "
92 "request");
93 ret = EXIT_FAILURE;
94 } else if (nvme_get_feat_req_exec(get_feat_req)) {
95 warnx("TEST FAILED: get feature request succeeded despite "
96 "missing fields");
97 ret = EXIT_FAILURE;
98 } else if (!missing_field_err(ctrl, "get feature request",
99 NVME_ERR_GET_FEAT_REQ_MISSING_FIELDS)) {
100 ret = EXIT_FAILURE;
101 } else {
102 (void) printf("TEST PASSED: get feature request generated "
103 "missing fields error\n");
104 }
105 nvme_get_feat_req_fini(get_feat_req);
106
107 if (!nvme_vuc_req_init(ctrl, &vuc_req)) {
108 if (nvme_ctrl_err(ctrl) == NVME_ERR_VUC_UNSUP_BY_DEV) {
109 warnx("TEST SKIPPED: device does not support VUC "
110 "requests");
111 } else {
112 libnvme_test_ctrl_warn(ctrl, "failed to initialize vuc "
113 "request");
114 ret = EXIT_FAILURE;
115 }
116 } else if (nvme_vuc_req_exec(vuc_req)) {
117 warnx("TEST FAILED: vuc request succeeded despite missing "
118 "fields");
119 ret = EXIT_FAILURE;
120 } else if (!missing_field_err(ctrl, "vuc request",
121 NVME_ERR_VUC_REQ_MISSING_FIELDS)) {
122 ret = EXIT_FAILURE;
123 } else {
124 (void) printf("TEST PASSED: vuc request generated missing "
125 "fields error\n");
126 }
127 nvme_vuc_req_fini(vuc_req);
128
129 if (ret == EXIT_SUCCESS) {
130 (void) printf("All tests passed successfully\n");
131 }
132
133 nvme_ctrl_fini(ctrl);
134 nvme_fini(nvme);
135 return (ret);
136 }
137