xref: /spdk/test/unit/lib/iscsi/common.c (revision 19d5c3ed8e87dbd240c77ae0ddb5eda25ae99b5f)
1 #include "iscsi/task.h"
2 #include "iscsi/iscsi.h"
3 #include "iscsi/conn.h"
4 
5 #include "spdk/env.h"
6 #include "spdk/event.h"
7 #include "spdk/sock.h"
8 #include "spdk_cunit.h"
9 
10 #include "spdk_internal/log.h"
11 #include "spdk_internal/mock.h"
12 
13 #include "scsi/scsi_internal.h"
14 
15 SPDK_LOG_REGISTER_COMPONENT("iscsi", SPDK_LOG_ISCSI)
16 
17 struct spdk_trace_histories *g_trace_histories;
18 DEFINE_STUB_V(spdk_trace_add_register_fn, (struct spdk_trace_register_fn *reg_fn));
19 DEFINE_STUB_V(spdk_trace_register_owner, (uint8_t type, char id_prefix));
20 DEFINE_STUB_V(spdk_trace_register_object, (uint8_t type, char id_prefix));
21 DEFINE_STUB_V(spdk_trace_register_description, (const char *name,
22 		uint16_t tpoint_id, uint8_t owner_type, uint8_t object_type, uint8_t new_object,
23 		uint8_t arg1_type, const char *arg1_name));
24 DEFINE_STUB_V(_spdk_trace_record, (uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id,
25 				   uint32_t size, uint64_t object_id, uint64_t arg1));
26 
27 TAILQ_HEAD(, spdk_iscsi_pdu) g_write_pdu_list = TAILQ_HEAD_INITIALIZER(g_write_pdu_list);
28 
29 static bool g_task_pool_is_empty = false;
30 static bool g_pdu_pool_is_empty = false;
31 
32 struct spdk_iscsi_task *
33 spdk_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 spdk_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 spdk_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 DEFINE_STUB_V(spdk_scsi_dev_queue_task,
124 	      (struct spdk_scsi_dev *dev, struct spdk_scsi_task *task));
125 
126 DEFINE_STUB(spdk_scsi_dev_find_port_by_id, struct spdk_scsi_port *,
127 	    (struct spdk_scsi_dev *dev, uint64_t id), NULL);
128 
129 DEFINE_STUB_V(spdk_scsi_dev_queue_mgmt_task,
130 	      (struct spdk_scsi_dev *dev, struct spdk_scsi_task *task));
131 
132 const char *
133 spdk_scsi_dev_get_name(const struct spdk_scsi_dev *dev)
134 {
135 	if (dev != NULL) {
136 		return dev->name;
137 	}
138 
139 	return NULL;
140 }
141 
142 DEFINE_STUB(spdk_scsi_dev_construct, struct spdk_scsi_dev *,
143 	    (const char *name, const char **bdev_name_list,
144 	     int *lun_id_list, int num_luns, uint8_t protocol_id,
145 	     void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
146 	     void *hotremove_ctx),
147 	    NULL);
148 
149 DEFINE_STUB_V(spdk_scsi_dev_destruct,
150 	      (struct spdk_scsi_dev *dev, spdk_scsi_dev_destruct_cb_t cb_fn, void *cb_arg));
151 
152 DEFINE_STUB(spdk_scsi_dev_add_port, int,
153 	    (struct spdk_scsi_dev *dev, uint64_t id, const char *name), 0);
154 
155 DEFINE_STUB(spdk_iscsi_drop_conns, int,
156 	    (struct spdk_iscsi_conn *conn, const char *conn_match, int drop_all),
157 	    0);
158 
159 DEFINE_STUB(spdk_scsi_dev_delete_port, int,
160 	    (struct spdk_scsi_dev *dev, uint64_t id), 0);
161 
162 DEFINE_STUB_V(spdk_shutdown_iscsi_conns, (void));
163 
164 DEFINE_STUB_V(spdk_iscsi_conns_request_logout, (struct spdk_iscsi_tgt_node *target));
165 
166 DEFINE_STUB(spdk_iscsi_get_active_conns, int, (struct spdk_iscsi_tgt_node *target), 0);
167 
168 void
169 spdk_iscsi_task_cpl(struct spdk_scsi_task *scsi_task)
170 {
171 	struct spdk_iscsi_task *iscsi_task;
172 
173 	if (scsi_task != NULL) {
174 		iscsi_task = spdk_iscsi_task_from_scsi_task(scsi_task);
175 		if (iscsi_task->parent && (iscsi_task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV)) {
176 			assert(iscsi_task->conn->data_in_cnt > 0);
177 			iscsi_task->conn->data_in_cnt--;
178 		}
179 
180 		free(iscsi_task);
181 	}
182 }
183 
184 DEFINE_STUB_V(spdk_iscsi_task_mgmt_cpl, (struct spdk_scsi_task *scsi_task));
185 
186 DEFINE_STUB(spdk_iscsi_conn_read_data, int,
187 	    (struct spdk_iscsi_conn *conn, int bytes, void *buf), 0);
188 
189 DEFINE_STUB(spdk_iscsi_conn_readv_data, int,
190 	    (struct spdk_iscsi_conn *conn, struct iovec *iov, int iovcnt), 0);
191 
192 void
193 spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu,
194 			  iscsi_conn_xfer_complete_cb cb_fn, void *cb_arg)
195 {
196 	TAILQ_INSERT_TAIL(&g_write_pdu_list, pdu, tailq);
197 }
198 
199 DEFINE_STUB_V(spdk_iscsi_conn_logout, (struct spdk_iscsi_conn *conn));
200 
201 DEFINE_STUB_V(spdk_scsi_task_set_status,
202 	      (struct spdk_scsi_task *task, int sc, int sk, int asc, int ascq));
203 
204 void
205 spdk_scsi_task_set_data(struct spdk_scsi_task *task, void *data, uint32_t len)
206 {
207 	SPDK_CU_ASSERT_FATAL(task->iovs != NULL);
208 	task->iovs[0].iov_base = data;
209 	task->iovs[0].iov_len = len;
210 }
211