xref: /spdk/test/unit/lib/iscsi/common.c (revision 32999ab917f67af61872f868585fd3d78ad6fb8a)
1 #include "iscsi/task.h"
2 #include "iscsi/iscsi.h"
3 #include "iscsi/conn.h"
4 
5 #include "spdk/env.h"
6 #include "spdk/sock.h"
7 #include "spdk_cunit.h"
8 
9 #include "spdk/log.h"
10 #include "spdk_internal/mock.h"
11 
12 #include "scsi/scsi_internal.h"
13 
14 SPDK_LOG_REGISTER_COMPONENT(iscsi)
15 
16 struct spdk_trace_histories *g_trace_histories;
17 DEFINE_STUB_V(spdk_trace_add_register_fn, (struct spdk_trace_register_fn *reg_fn));
18 DEFINE_STUB_V(spdk_trace_register_owner, (uint8_t type, char id_prefix));
19 DEFINE_STUB_V(spdk_trace_register_object, (uint8_t type, char id_prefix));
20 DEFINE_STUB_V(spdk_trace_register_description, (const char *name,
21 		uint16_t tpoint_id, uint8_t owner_type, uint8_t object_type, uint8_t new_object,
22 		uint8_t arg1_type, const char *arg1_name));
23 DEFINE_STUB_V(_spdk_trace_record, (uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id,
24 				   uint32_t size, uint64_t object_id, uint64_t arg1));
25 
26 TAILQ_HEAD(, spdk_iscsi_pdu) g_write_pdu_list = TAILQ_HEAD_INITIALIZER(g_write_pdu_list);
27 
28 static bool g_task_pool_is_empty = false;
29 static bool g_pdu_pool_is_empty = false;
30 static uint32_t g_conn_read_len;
31 
32 struct spdk_iscsi_task *
33 iscsi_task_get(struct spdk_iscsi_conn *conn,
34 	       struct spdk_iscsi_task *parent,
35 	       spdk_scsi_task_cpl cpl_fn)
36 {
37 	struct spdk_iscsi_task *task;
38 
39 	if (g_task_pool_is_empty) {
40 		return NULL;
41 	}
42 
43 	task = calloc(1, sizeof(*task));
44 	if (!task) {
45 		return NULL;
46 	}
47 
48 	task->conn = conn;
49 	task->scsi.cpl_fn = cpl_fn;
50 	if (parent) {
51 		parent->scsi.ref++;
52 		task->parent = parent;
53 		task->tag = parent->tag;
54 		task->lun_id = parent->lun_id;
55 		task->scsi.dxfer_dir = parent->scsi.dxfer_dir;
56 		task->scsi.transfer_len = parent->scsi.transfer_len;
57 		task->scsi.lun = parent->scsi.lun;
58 		task->scsi.cdb = parent->scsi.cdb;
59 		task->scsi.target_port = parent->scsi.target_port;
60 		task->scsi.initiator_port = parent->scsi.initiator_port;
61 		if (conn && (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV)) {
62 			conn->data_in_cnt++;
63 		}
64 	}
65 
66 	task->scsi.iovs = &task->scsi.iov;
67 	return task;
68 }
69 
70 void
71 spdk_scsi_task_put(struct spdk_scsi_task *task)
72 {
73 	free(task);
74 }
75 
76 void
77 iscsi_put_pdu(struct spdk_iscsi_pdu *pdu)
78 {
79 	if (!pdu) {
80 		return;
81 	}
82 
83 	pdu->ref--;
84 	if (pdu->ref < 0) {
85 		CU_FAIL("negative ref count");
86 		pdu->ref = 0;
87 	}
88 
89 	if (pdu->ref == 0) {
90 		if (pdu->data && !pdu->data_from_mempool) {
91 			free(pdu->data);
92 		}
93 		free(pdu);
94 	}
95 }
96 
97 struct spdk_iscsi_pdu *
98 iscsi_get_pdu(struct spdk_iscsi_conn *conn)
99 {
100 	struct spdk_iscsi_pdu *pdu;
101 
102 	assert(conn != NULL);
103 	if (g_pdu_pool_is_empty) {
104 		return NULL;
105 	}
106 
107 	pdu = malloc(sizeof(*pdu));
108 	if (!pdu) {
109 		return NULL;
110 	}
111 
112 	memset(pdu, 0, offsetof(struct spdk_iscsi_pdu, ahs));
113 	pdu->ref = 1;
114 	pdu->conn = conn;
115 
116 	return pdu;
117 }
118 
119 DEFINE_STUB_V(spdk_scsi_task_process_null_lun, (struct spdk_scsi_task *task));
120 
121 DEFINE_STUB_V(spdk_scsi_task_process_abort, (struct spdk_scsi_task *task));
122 
123 void
124 spdk_scsi_dev_queue_task(struct spdk_scsi_dev *dev, struct spdk_scsi_task *task)
125 {
126 	assert(dev->lun[0] != NULL);
127 
128 	TAILQ_INSERT_TAIL(&dev->lun[0]->tasks, task, scsi_link);
129 }
130 
131 DEFINE_STUB(spdk_scsi_dev_find_port_by_id, struct spdk_scsi_port *,
132 	    (struct spdk_scsi_dev *dev, uint64_t id), NULL);
133 
134 DEFINE_STUB_V(spdk_scsi_dev_queue_mgmt_task,
135 	      (struct spdk_scsi_dev *dev, struct spdk_scsi_task *task));
136 
137 const char *
138 spdk_scsi_dev_get_name(const struct spdk_scsi_dev *dev)
139 {
140 	if (dev != NULL) {
141 		return dev->name;
142 	}
143 
144 	return NULL;
145 }
146 
147 DEFINE_STUB(spdk_scsi_dev_construct, struct spdk_scsi_dev *,
148 	    (const char *name, const char **bdev_name_list,
149 	     int *lun_id_list, int num_luns, uint8_t protocol_id,
150 	     void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
151 	     void *hotremove_ctx),
152 	    NULL);
153 
154 DEFINE_STUB_V(spdk_scsi_dev_destruct,
155 	      (struct spdk_scsi_dev *dev, spdk_scsi_dev_destruct_cb_t cb_fn, void *cb_arg));
156 
157 DEFINE_STUB(spdk_scsi_dev_add_port, int,
158 	    (struct spdk_scsi_dev *dev, uint64_t id, const char *name), 0);
159 
160 DEFINE_STUB(iscsi_drop_conns, int,
161 	    (struct spdk_iscsi_conn *conn, const char *conn_match, int drop_all),
162 	    0);
163 
164 DEFINE_STUB(spdk_scsi_dev_delete_port, int,
165 	    (struct spdk_scsi_dev *dev, uint64_t id), 0);
166 
167 DEFINE_STUB_V(shutdown_iscsi_conns, (void));
168 
169 DEFINE_STUB_V(iscsi_conns_request_logout, (struct spdk_iscsi_tgt_node *target, int pg_tag));
170 
171 DEFINE_STUB(iscsi_get_active_conns, int, (struct spdk_iscsi_tgt_node *target), 0);
172 
173 void
174 iscsi_task_cpl(struct spdk_scsi_task *scsi_task)
175 {
176 	struct spdk_iscsi_task *iscsi_task;
177 
178 	if (scsi_task != NULL) {
179 		iscsi_task = iscsi_task_from_scsi_task(scsi_task);
180 		if (iscsi_task->parent && (iscsi_task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV)) {
181 			assert(iscsi_task->conn->data_in_cnt > 0);
182 			iscsi_task->conn->data_in_cnt--;
183 		}
184 
185 		free(iscsi_task);
186 	}
187 }
188 
189 DEFINE_STUB_V(iscsi_task_mgmt_cpl, (struct spdk_scsi_task *scsi_task));
190 
191 int
192 iscsi_conn_read_data(struct spdk_iscsi_conn *conn, int bytes, void *buf)
193 {
194 	uint32_t *data = buf;
195 	int i;
196 
197 	/* Limit the length to 4 bytes multiples. */
198 	SPDK_CU_ASSERT_FATAL((bytes % 4) == 0);
199 
200 	for (i = 0; i < bytes; i += 4) {
201 		data[i / 4] = g_conn_read_len + i;
202 	}
203 
204 	g_conn_read_len += bytes;
205 
206 	return bytes;
207 }
208 
209 int
210 iscsi_conn_readv_data(struct spdk_iscsi_conn *conn, struct iovec *iov, int iovcnt)
211 {
212 	int i, len = 0;
213 
214 	for (i = 0; i < iovcnt; i++) {
215 		len += iov[i].iov_len;
216 	}
217 
218 	return len;
219 }
220 
221 void
222 iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu,
223 		     iscsi_conn_xfer_complete_cb cb_fn, void *cb_arg)
224 {
225 	TAILQ_INSERT_TAIL(&g_write_pdu_list, pdu, tailq);
226 }
227 
228 DEFINE_STUB_V(iscsi_conn_logout, (struct spdk_iscsi_conn *conn));
229 
230 DEFINE_STUB_V(spdk_scsi_task_set_status,
231 	      (struct spdk_scsi_task *task, int sc, int sk, int asc, int ascq));
232 
233 void
234 spdk_scsi_task_set_data(struct spdk_scsi_task *task, void *data, uint32_t len)
235 {
236 	SPDK_CU_ASSERT_FATAL(task->iovs != NULL);
237 	task->iovs[0].iov_base = data;
238 	task->iovs[0].iov_len = len;
239 }
240