1*c2e7ae76Sdholland /* $NetBSD: isns_thread.c,v 1.2 2019/07/03 18:40:33 dholland Exp $ */
2dc2ecebeSagc
3dc2ecebeSagc /*-
4dc2ecebeSagc * Copyright (c) 2004,2009 The NetBSD Foundation, Inc.
5dc2ecebeSagc * All rights reserved.
6dc2ecebeSagc *
7dc2ecebeSagc * This code is derived from software contributed to The NetBSD Foundation
8dc2ecebeSagc * by Wasabi Systems, Inc.
9dc2ecebeSagc *
10dc2ecebeSagc * Redistribution and use in source and binary forms, with or without
11dc2ecebeSagc * modification, are permitted provided that the following conditions
12dc2ecebeSagc * are met:
13dc2ecebeSagc * 1. Redistributions of source code must retain the above copyright
14dc2ecebeSagc * notice, this list of conditions and the following disclaimer.
15dc2ecebeSagc * 2. Redistributions in binary form must reproduce the above copyright
16dc2ecebeSagc * notice, this list of conditions and the following disclaimer in the
17dc2ecebeSagc * documentation and/or other materials provided with the distribution.
18dc2ecebeSagc *
19dc2ecebeSagc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20dc2ecebeSagc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21dc2ecebeSagc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22dc2ecebeSagc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23dc2ecebeSagc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24dc2ecebeSagc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25dc2ecebeSagc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26dc2ecebeSagc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27dc2ecebeSagc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28dc2ecebeSagc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29dc2ecebeSagc * POSSIBILITY OF SUCH DAMAGE.
30dc2ecebeSagc */
31dc2ecebeSagc
32dc2ecebeSagc #include <sys/cdefs.h>
33*c2e7ae76Sdholland __RCSID("$NetBSD: isns_thread.c,v 1.2 2019/07/03 18:40:33 dholland Exp $");
34dc2ecebeSagc
35dc2ecebeSagc
36dc2ecebeSagc /*
37dc2ecebeSagc * isns_thread.c
38dc2ecebeSagc */
39dc2ecebeSagc
40dc2ecebeSagc #include <sys/types.h>
41dc2ecebeSagc
42dc2ecebeSagc #include <unistd.h>
43dc2ecebeSagc
44dc2ecebeSagc #include "isns.h"
45dc2ecebeSagc #include "isns_config.h"
46dc2ecebeSagc #include "isns_defs.h"
47dc2ecebeSagc
48dc2ecebeSagc static struct iovec read_buf[2 + (ISNS_MAX_PDU_PAYLOAD / ISNS_BUF_SIZE) +
49dc2ecebeSagc ((ISNS_MAX_PDU_PAYLOAD % ISNS_BUF_SIZE) != 0)];
50dc2ecebeSagc
51dc2ecebeSagc static struct isns_task_s *isns_get_next_task(struct isns_config_s *);
52dc2ecebeSagc
53dc2ecebeSagc /*
54dc2ecebeSagc * isns_control_thread()
55dc2ecebeSagc */
56dc2ecebeSagc void *
isns_control_thread(void * arg)57dc2ecebeSagc isns_control_thread(void *arg)
58dc2ecebeSagc {
59dc2ecebeSagc struct isns_config_s *cfg_p = (struct isns_config_s *)arg;
60dc2ecebeSagc struct kevent evt_chgs[5], *evt_p;
61dc2ecebeSagc
62dc2ecebeSagc int n, nevents;
63dc2ecebeSagc isns_kevent_handler *evt_handler_p;
64dc2ecebeSagc int run_thread;
65dc2ecebeSagc
66dc2ecebeSagc run_thread = 1;
67dc2ecebeSagc
68dc2ecebeSagc while (run_thread) {
69dc2ecebeSagc /* if no task outstanding, check queue here and send PDU */
70dc2ecebeSagc while ((cfg_p->curtask_p == NULL)
71dc2ecebeSagc && ((cfg_p->curtask_p = isns_get_next_task(cfg_p)) != NULL))
72dc2ecebeSagc isns_run_task(cfg_p->curtask_p);
73dc2ecebeSagc
74dc2ecebeSagc nevents = kevent(cfg_p->kq, NULL, 0, evt_chgs,
75dc2ecebeSagc ARRAY_ELEMS(evt_chgs), NULL);
76dc2ecebeSagc
77dc2ecebeSagc DBG("isns_control_thread: kevent() nevents=%d\n", nevents);
78dc2ecebeSagc
79dc2ecebeSagc for (n = 0, evt_p = evt_chgs; n < nevents; n++, evt_p++) {
80dc2ecebeSagc DBG("event[%d] - data=%d\n", n, (int)evt_p->data);
81dc2ecebeSagc evt_handler_p = (void *)evt_p->udata;
82dc2ecebeSagc run_thread = (evt_handler_p(evt_p, cfg_p) == 0);
83dc2ecebeSagc }
84dc2ecebeSagc }
85dc2ecebeSagc
86dc2ecebeSagc return 0;
87dc2ecebeSagc }
88dc2ecebeSagc
89dc2ecebeSagc /*
90dc2ecebeSagc * isns_get_next_task()
91dc2ecebeSagc */
92dc2ecebeSagc static struct isns_task_s *
isns_get_next_task(struct isns_config_s * cfg_p)93dc2ecebeSagc isns_get_next_task(struct isns_config_s *cfg_p)
94dc2ecebeSagc {
95dc2ecebeSagc struct isns_task_s *task_p = NULL;
96dc2ecebeSagc
97dc2ecebeSagc
98dc2ecebeSagc DBG("isns_get_next_task: entered\n");
99dc2ecebeSagc
100dc2ecebeSagc task_p = isns_taskq_remove(cfg_p);
101dc2ecebeSagc
102dc2ecebeSagc if (cfg_p->sd_connected)
103dc2ecebeSagc return task_p;
104dc2ecebeSagc else {
105dc2ecebeSagc if (task_p == NULL)
106dc2ecebeSagc return NULL;
107dc2ecebeSagc else {
108dc2ecebeSagc if (task_p->task_type != ISNS_TASK_INIT_SOCKET_IO) {
109dc2ecebeSagc isns_taskq_insert_head(cfg_p, task_p);
110dc2ecebeSagc
111dc2ecebeSagc task_p = isns_new_task(cfg_p,
112dc2ecebeSagc ISNS_TASK_RECONNECT_SERVER, 0);
113dc2ecebeSagc task_p->var.reconnect_server.ai_p = cfg_p->ai_p;
114dc2ecebeSagc }
115dc2ecebeSagc
116dc2ecebeSagc return task_p;
117dc2ecebeSagc }
118dc2ecebeSagc }
119dc2ecebeSagc }
120dc2ecebeSagc
121dc2ecebeSagc /*
122dc2ecebeSagc * isns_kevent_pipe()
123dc2ecebeSagc */
124dc2ecebeSagc int
isns_kevent_pipe(struct kevent * evt_p,struct isns_config_s * cfg_p)125dc2ecebeSagc isns_kevent_pipe(struct kevent* evt_p, struct isns_config_s *cfg_p)
126dc2ecebeSagc {
127dc2ecebeSagc uint8_t cmd_type;
128dc2ecebeSagc int force_isns_stop;
129dc2ecebeSagc uint16_t trans_id;
130dc2ecebeSagc ssize_t rbytes;
131dc2ecebeSagc int pipe_nbytes;
132dc2ecebeSagc
133dc2ecebeSagc force_isns_stop = 0;
134dc2ecebeSagc pipe_nbytes = (int)evt_p->data;
135dc2ecebeSagc
136dc2ecebeSagc while (pipe_nbytes > 0) {
137dc2ecebeSagc rbytes = read(cfg_p->pipe_fds[0], &cmd_type,
138dc2ecebeSagc sizeof(cmd_type));
139dc2ecebeSagc if (rbytes < 0) {
140dc2ecebeSagc DBG("isns_kevent_pipe: error on wepe_sys_read\n");
141dc2ecebeSagc /*?? should we break here? */
142dc2ecebeSagc continue;
143dc2ecebeSagc }
144dc2ecebeSagc
145dc2ecebeSagc pipe_nbytes -= (int)rbytes;
146dc2ecebeSagc switch (cmd_type) {
147dc2ecebeSagc case ISNS_CMD_PROCESS_TASKQ:
148dc2ecebeSagc DBG("isns_kevent_pipe: ISNS_CMD_PROCESS_TASKQ\n");
149dc2ecebeSagc break;
150dc2ecebeSagc
151dc2ecebeSagc case ISNS_CMD_ABORT_TRANS:
152dc2ecebeSagc DBG("isns_kevent_pipe: ISNS_CMD_ABORT_TRANS\n");
153dc2ecebeSagc rbytes = read(cfg_p->pipe_fds[0], &trans_id,
154dc2ecebeSagc sizeof(trans_id));
155*c2e7ae76Sdholland if (rbytes < 0)
156dc2ecebeSagc DBG("isns_kevent_pipe: "
157dc2ecebeSagc "error reading trans id\n");
158*c2e7ae76Sdholland else if (rbytes != sizeof(trans_id))
159*c2e7ae76Sdholland DBG("isns_kevent_pipe: "
160*c2e7ae76Sdholland "short read reading trans id\n");
161*c2e7ae76Sdholland else {
162*c2e7ae76Sdholland isns_abort_trans(cfg_p, trans_id);
163dc2ecebeSagc pipe_nbytes -= (int)rbytes;
164*c2e7ae76Sdholland }
165dc2ecebeSagc break;
166dc2ecebeSagc
167dc2ecebeSagc case ISNS_CMD_STOP:
168dc2ecebeSagc DBG("isns_kevent_pipe: ISNS_CMD_STOP\n");
169dc2ecebeSagc force_isns_stop = 1;
170dc2ecebeSagc pipe_nbytes = 0;
171dc2ecebeSagc break;
172dc2ecebeSagc
173dc2ecebeSagc default:
174dc2ecebeSagc DBG("isns_kevent_pipe: unknown command (cmd=%d)\n",
175dc2ecebeSagc cmd_type);
176dc2ecebeSagc break;
177dc2ecebeSagc }
178dc2ecebeSagc }
179dc2ecebeSagc
180dc2ecebeSagc return (force_isns_stop ? 1 : 0);
181dc2ecebeSagc }
182dc2ecebeSagc
183dc2ecebeSagc /*
184dc2ecebeSagc * isns_is_trans_complete()
185dc2ecebeSagc */
186dc2ecebeSagc static int
isns_is_trans_complete(struct isns_trans_s * trans_p)187dc2ecebeSagc isns_is_trans_complete(struct isns_trans_s *trans_p)
188dc2ecebeSagc {
189dc2ecebeSagc struct isns_pdu_s *pdu_p;
190dc2ecebeSagc uint16_t count;
191dc2ecebeSagc
192dc2ecebeSagc pdu_p = trans_p->pdu_rsp_list;
193dc2ecebeSagc count = 0;
194dc2ecebeSagc while (pdu_p->next != NULL) {
195dc2ecebeSagc if (pdu_p->hdr.seq_id != count++) return 0;
196dc2ecebeSagc pdu_p = pdu_p->next;
197dc2ecebeSagc }
198dc2ecebeSagc if ((pdu_p->hdr.seq_id != count) ||
199dc2ecebeSagc !(pdu_p->hdr.flags & ISNS_FLAG_LAST_PDU))
200dc2ecebeSagc return 0;
201dc2ecebeSagc
202dc2ecebeSagc return 1;
203dc2ecebeSagc }
204dc2ecebeSagc
205dc2ecebeSagc /*
206dc2ecebeSagc * isns_is_valid_resp()
207dc2ecebeSagc */
208dc2ecebeSagc static int
isns_is_valid_resp(struct isns_trans_s * trans_p,struct isns_pdu_s * pdu_p)209dc2ecebeSagc isns_is_valid_resp(struct isns_trans_s *trans_p, struct isns_pdu_s *pdu_p)
210dc2ecebeSagc {
211dc2ecebeSagc struct isns_pdu_s *curpdu_p;
212dc2ecebeSagc
213dc2ecebeSagc if (pdu_p->hdr.trans_id != trans_p->id)
214dc2ecebeSagc return 0;
215dc2ecebeSagc if (pdu_p->hdr.func_id != (trans_p->func_id | 0x8000))
216dc2ecebeSagc return 0;
217dc2ecebeSagc curpdu_p = trans_p->pdu_rsp_list;
218dc2ecebeSagc while (curpdu_p != NULL) {
219dc2ecebeSagc if (curpdu_p->hdr.seq_id == pdu_p->hdr.seq_id) return 0;
220dc2ecebeSagc curpdu_p = curpdu_p->next;
221dc2ecebeSagc }
222dc2ecebeSagc
223dc2ecebeSagc return 1;
224dc2ecebeSagc }
225dc2ecebeSagc
226dc2ecebeSagc /*
227dc2ecebeSagc * isns_process_in_pdu()
228dc2ecebeSagc */
229dc2ecebeSagc static void
isns_process_in_pdu(struct isns_config_s * cfg_p)230dc2ecebeSagc isns_process_in_pdu(struct isns_config_s *cfg_p)
231dc2ecebeSagc {
232dc2ecebeSagc struct isns_task_s *curtask_p;
233dc2ecebeSagc struct isns_trans_s *trans_p;
234dc2ecebeSagc
235dc2ecebeSagc DBG("isns_process_in_pdu: entered\n");
236dc2ecebeSagc
237dc2ecebeSagc if ((curtask_p = cfg_p->curtask_p) == NULL)
238dc2ecebeSagc isns_free_pdu(cfg_p->pdu_in_p);
239dc2ecebeSagc else if ((trans_p = curtask_p->var.send_pdu.trans_p) == NULL)
240dc2ecebeSagc isns_free_pdu(cfg_p->pdu_in_p);
241dc2ecebeSagc else if (!isns_is_valid_resp(trans_p, cfg_p->pdu_in_p))
242dc2ecebeSagc isns_free_pdu(cfg_p->pdu_in_p);
243dc2ecebeSagc else {
244dc2ecebeSagc isns_add_pdu_response(trans_p, cfg_p->pdu_in_p);
245dc2ecebeSagc
246dc2ecebeSagc if (isns_is_trans_complete(trans_p)) {
247dc2ecebeSagc isns_complete_trans(trans_p);
248dc2ecebeSagc isns_end_task(curtask_p);
249dc2ecebeSagc }
250dc2ecebeSagc }
251dc2ecebeSagc
252dc2ecebeSagc cfg_p->pdu_in_p = NULL;
253dc2ecebeSagc }
254dc2ecebeSagc
255dc2ecebeSagc /*
256dc2ecebeSagc * isns_kevent_socket()
257dc2ecebeSagc */
258dc2ecebeSagc int
isns_kevent_socket(struct kevent * evt_p,struct isns_config_s * cfg_p)259dc2ecebeSagc isns_kevent_socket(struct kevent *evt_p, struct isns_config_s *cfg_p)
260dc2ecebeSagc {
261dc2ecebeSagc struct iovec *iovp;
262dc2ecebeSagc struct isns_buffer_s *curbuf_p, *newbuf_p;
263dc2ecebeSagc struct isns_pdu_s *pdu_p;
264dc2ecebeSagc int64_t bavail; /* bytes available in socket buffer */
265dc2ecebeSagc uint32_t cur_len, buf_len, unread_len, rd_len, b_len;
266dc2ecebeSagc ssize_t rv;
267dc2ecebeSagc uint16_t payload_len;
268dc2ecebeSagc int iovcnt, more, transport_evt;
269dc2ecebeSagc
270dc2ecebeSagc
271dc2ecebeSagc DBG("isns_kevent_socket: entered\n");
272dc2ecebeSagc
273dc2ecebeSagc transport_evt = 0;
274dc2ecebeSagc bavail = evt_p->data;
275dc2ecebeSagc iovp = read_buf;
276dc2ecebeSagc
277dc2ecebeSagc more = (bavail > 0);
278dc2ecebeSagc while (more) {
279dc2ecebeSagc if (cfg_p->pdu_in_p == NULL) {
280dc2ecebeSagc /*
281dc2ecebeSagc * Try to form a valid pdu by starting with the hdr.
282dc2ecebeSagc * If there isn't enough data in the socket buffer
283dc2ecebeSagc * to form a full hdr, just return.
284dc2ecebeSagc *
285dc2ecebeSagc * Once we have read in our hdr, allocate all buffers
286dc2ecebeSagc * needed.
287dc2ecebeSagc */
288dc2ecebeSagc
289dc2ecebeSagc if (bavail < (int64_t)sizeof(struct isns_pdu_hdr_s))
290dc2ecebeSagc return 0;
291dc2ecebeSagc
292dc2ecebeSagc /* Form a placeholder pdu */
293dc2ecebeSagc pdu_p = isns_new_pdu(cfg_p, 0, 0, 0);
294dc2ecebeSagc
295dc2ecebeSagc /* Read the header into our placeholder pdu */
296dc2ecebeSagc read_buf[0].iov_base = &(pdu_p->hdr);
297dc2ecebeSagc read_buf[0].iov_len = sizeof(struct isns_pdu_hdr_s);
298dc2ecebeSagc iovcnt = 1;
299dc2ecebeSagc
300dc2ecebeSagc iovp = read_buf;
301dc2ecebeSagc rv = isns_socket_readv(cfg_p->sd, iovp, iovcnt);
302dc2ecebeSagc if ((rv == 0) || (rv == -1)) {
303dc2ecebeSagc DBG("isns_kevent_socket: isns_socket_readv(1) "
304dc2ecebeSagc "returned %d\n", rv);
305dc2ecebeSagc transport_evt = 1;
306dc2ecebeSagc break;
307dc2ecebeSagc }
308dc2ecebeSagc
309dc2ecebeSagc bavail -= sizeof(struct isns_pdu_hdr_s);
310dc2ecebeSagc /*
311dc2ecebeSagc * ToDo: read until sizeof(struct isns_pdu_hdr_s) has
312dc2ecebeSagc * been read in. This statement should be
313dc2ecebeSagc *
314dc2ecebeSagc * bavail -= rv;
315dc2ecebeSagc */
316dc2ecebeSagc
317dc2ecebeSagc /* adjust byte order */
318dc2ecebeSagc pdu_p->hdr.isnsp_version = isns_ntohs(pdu_p->hdr.
319dc2ecebeSagc isnsp_version);
320dc2ecebeSagc pdu_p->hdr.func_id = isns_ntohs(pdu_p->hdr.func_id);
321dc2ecebeSagc pdu_p->hdr.payload_len = isns_ntohs(pdu_p->hdr.
322dc2ecebeSagc payload_len);
323dc2ecebeSagc pdu_p->hdr.flags = isns_ntohs(pdu_p->hdr.flags);
324dc2ecebeSagc pdu_p->hdr.trans_id = isns_ntohs(pdu_p->hdr.trans_id);
325dc2ecebeSagc pdu_p->hdr.seq_id = isns_ntohs(pdu_p->hdr.seq_id);
326dc2ecebeSagc pdu_p->byteorder_host = 1;
327dc2ecebeSagc
328dc2ecebeSagc /* Try to sense early whether we might have garbage */
329dc2ecebeSagc if (pdu_p->hdr.isnsp_version != ISNSP_VERSION) {
330dc2ecebeSagc DBG("isns_kevent_socket: pdu_p->hdr."
331dc2ecebeSagc "isnsp_version != ISNSP_VERSION\n");
332dc2ecebeSagc isns_free_pdu(pdu_p);
333dc2ecebeSagc
334dc2ecebeSagc transport_evt = 1;
335dc2ecebeSagc break;
336dc2ecebeSagc }
337dc2ecebeSagc
338dc2ecebeSagc /* Allocate all the necessary payload buffers */
339dc2ecebeSagc payload_len = pdu_p->hdr.payload_len;
340dc2ecebeSagc curbuf_p = pdu_p->payload_p;
341dc2ecebeSagc buf_len = 0;
342dc2ecebeSagc while (buf_len + curbuf_p->alloc_len < payload_len) {
343dc2ecebeSagc buf_len += curbuf_p->alloc_len;
344dc2ecebeSagc newbuf_p = isns_new_buffer(0);
345dc2ecebeSagc curbuf_p->next = newbuf_p;
346dc2ecebeSagc curbuf_p = newbuf_p;
347dc2ecebeSagc }
348dc2ecebeSagc curbuf_p->next = NULL;
349dc2ecebeSagc
350dc2ecebeSagc /* Hold on to our placeholder pdu */
351dc2ecebeSagc cfg_p->pdu_in_p = pdu_p;
352dc2ecebeSagc more = (bavail > 0) ? 1 : 0;
353dc2ecebeSagc } else if (bavail > 0) {
354dc2ecebeSagc /*
355dc2ecebeSagc * Fill in the pdu payload data.
356dc2ecebeSagc *
357dc2ecebeSagc * If we can fill it all in now
358dc2ecebeSagc * -AND- it corresponds to the active transaction
359dc2ecebeSagc * then add the pdu to the transaction's
360dc2ecebeSagc * pdu_rsp_list
361dc2ecebeSagc * -AND- it does not correspond to the active
362dc2ecebeSagc * transaction (or there is no active
363dc2ecebeSagc * transaction) then drop it on the floor.
364dc2ecebeSagc * We may not be able to fill it all in now.
365dc2ecebeSagc * -EITHER WAY- fill in as much payload data now
366dc2ecebeSagc * as we can.
367dc2ecebeSagc */
368dc2ecebeSagc
369dc2ecebeSagc /* Refer to our placeholder pdu */
370dc2ecebeSagc pdu_p = cfg_p->pdu_in_p;
371dc2ecebeSagc
372dc2ecebeSagc /* How much payload data has been filled in? */
373dc2ecebeSagc cur_len = 0;
374dc2ecebeSagc curbuf_p = pdu_p->payload_p;
375dc2ecebeSagc while (curbuf_p->cur_len == curbuf_p->alloc_len) {
376dc2ecebeSagc cur_len += curbuf_p->cur_len;
377dc2ecebeSagc curbuf_p = curbuf_p->next;
378dc2ecebeSagc }
379dc2ecebeSagc cur_len += curbuf_p->cur_len;
380dc2ecebeSagc
381dc2ecebeSagc /* How much payload data is left to be filled in? */
382dc2ecebeSagc unread_len = pdu_p->hdr.payload_len - cur_len;
383dc2ecebeSagc
384dc2ecebeSagc /* Read as much remaining payload data as possible */
385dc2ecebeSagc iovcnt = 0;
386dc2ecebeSagc while (curbuf_p->next != NULL) {
387dc2ecebeSagc read_buf[iovcnt].iov_base = isns_buffer_data(
388dc2ecebeSagc curbuf_p, curbuf_p->cur_len);
389dc2ecebeSagc read_buf[iovcnt].iov_len = curbuf_p->alloc_len -
390dc2ecebeSagc curbuf_p->cur_len;
391dc2ecebeSagc iovcnt++;
392dc2ecebeSagc
393dc2ecebeSagc curbuf_p = curbuf_p->next;
394dc2ecebeSagc }
395dc2ecebeSagc read_buf[iovcnt].iov_base = isns_buffer_data(curbuf_p,
396dc2ecebeSagc curbuf_p->cur_len);
397dc2ecebeSagc read_buf[iovcnt].iov_len = unread_len;
398dc2ecebeSagc iovcnt++;
399dc2ecebeSagc
400dc2ecebeSagc rv = isns_socket_readv(cfg_p->sd, iovp, iovcnt);
401dc2ecebeSagc if ((rv == 0) || (rv == -1)) {
402dc2ecebeSagc DBG("isns_kevent_socket: isns_socket_readv(2) "
403dc2ecebeSagc "returned %d\n",rv);
404dc2ecebeSagc isns_free_pdu(cfg_p->pdu_in_p);
405dc2ecebeSagc cfg_p->pdu_in_p = NULL;
406dc2ecebeSagc
407dc2ecebeSagc transport_evt = 1;
408dc2ecebeSagc break;
409dc2ecebeSagc }
410dc2ecebeSagc
411dc2ecebeSagc /* Update cur_len in buffers that newly have data */
412dc2ecebeSagc curbuf_p = pdu_p->payload_p;
413dc2ecebeSagc while (curbuf_p->cur_len == curbuf_p->alloc_len)
414dc2ecebeSagc curbuf_p = curbuf_p->next;
415dc2ecebeSagc
416dc2ecebeSagc rd_len = (uint32_t)rv;
417dc2ecebeSagc do {
418dc2ecebeSagc b_len = curbuf_p->alloc_len - curbuf_p->cur_len;
419dc2ecebeSagc if (rd_len > b_len) {
420dc2ecebeSagc curbuf_p->cur_len = curbuf_p->alloc_len;
421dc2ecebeSagc rd_len -= b_len;
422dc2ecebeSagc } else {
423dc2ecebeSagc curbuf_p->cur_len += rd_len;
424dc2ecebeSagc break;
425dc2ecebeSagc }
426dc2ecebeSagc
427dc2ecebeSagc curbuf_p = curbuf_p->next;
428dc2ecebeSagc } while (curbuf_p != NULL);
429dc2ecebeSagc
430dc2ecebeSagc bavail -= rv;
431dc2ecebeSagc
432dc2ecebeSagc if (rv == (int)unread_len)
433dc2ecebeSagc isns_process_in_pdu(cfg_p);
434dc2ecebeSagc
435dc2ecebeSagc more = (bavail > (int64_t)sizeof(struct isns_pdu_hdr_s)) ? 1 : 0;
436dc2ecebeSagc }
437dc2ecebeSagc }
438dc2ecebeSagc
439dc2ecebeSagc transport_evt |= (evt_p->flags & EV_EOF);
440dc2ecebeSagc if (transport_evt) {
441dc2ecebeSagc DBG("isns_kevent_socket: processing transport event\n");
442dc2ecebeSagc
443dc2ecebeSagc isns_socket_close(cfg_p->sd);
444dc2ecebeSagc cfg_p->sd_connected = 0;
445dc2ecebeSagc
446dc2ecebeSagc if (cfg_p->curtask_p != NULL)
447dc2ecebeSagc isns_process_connection_loss(cfg_p);
448dc2ecebeSagc
449dc2ecebeSagc if (cfg_p->pdu_in_p != NULL) {
450dc2ecebeSagc isns_free_pdu(cfg_p->pdu_in_p);
451dc2ecebeSagc cfg_p->pdu_in_p = NULL;
452dc2ecebeSagc }
453dc2ecebeSagc }
454dc2ecebeSagc
455dc2ecebeSagc return 0;
456dc2ecebeSagc }
457dc2ecebeSagc
458dc2ecebeSagc /* ARGSUSED */
459dc2ecebeSagc /*
460dc2ecebeSagc * isns_kevent_timer_recon()
461dc2ecebeSagc */
462dc2ecebeSagc int
isns_kevent_timer_recon(struct kevent * evt_p,struct isns_config_s * cfg_p)463dc2ecebeSagc isns_kevent_timer_recon(struct kevent *evt_p, struct isns_config_s *cfg_p)
464dc2ecebeSagc {
465dc2ecebeSagc int rv;
466dc2ecebeSagc
467dc2ecebeSagc
468dc2ecebeSagc DBG("isns_kevent_timer_recon: entered\n");
469dc2ecebeSagc
470dc2ecebeSagc rv = isns_socket_create(&(cfg_p->sd), cfg_p->ai_p->ai_family,
471dc2ecebeSagc cfg_p->ai_p->ai_socktype);
472dc2ecebeSagc if (rv != 0)
473dc2ecebeSagc return 0;
474dc2ecebeSagc
475dc2ecebeSagc rv = isns_socket_connect(cfg_p->sd, cfg_p->ai_p->ai_addr,
476dc2ecebeSagc cfg_p->ai_p->ai_addrlen);
477dc2ecebeSagc if (rv == 0) {
478dc2ecebeSagc /* Remove ISNS_EVT_TIMER_RECON from kqueue */
479dc2ecebeSagc rv = isns_change_kevent_list(cfg_p,
480dc2ecebeSagc (uintptr_t)ISNS_EVT_TIMER_RECON, EVFILT_TIMER, EV_DELETE,
481dc2ecebeSagc (int64_t)0, (intptr_t)0);
482dc2ecebeSagc if (rv == -1)
483dc2ecebeSagc DBG("isns_kevent_timer_recon: error on "
484dc2ecebeSagc "isns_change_kevent_list(1)\n");
485dc2ecebeSagc
486dc2ecebeSagc cfg_p->sd_connected = 1;
487dc2ecebeSagc
488dc2ecebeSagc /* Add cfg_p->sd to kqueue */
489dc2ecebeSagc rv = isns_change_kevent_list(cfg_p, (uintptr_t)cfg_p->sd,
490dc2ecebeSagc EVFILT_READ, EV_ADD | EV_CLEAR, (int64_t)0,
491dc2ecebeSagc (intptr_t)isns_kevent_socket);
492dc2ecebeSagc if (rv == -1)
493dc2ecebeSagc DBG("isns_kevent_timer_recon: error on "
494dc2ecebeSagc "isns_change_kevent_list(2)\n");
495dc2ecebeSagc
496dc2ecebeSagc isns_end_task(cfg_p->curtask_p);
497dc2ecebeSagc }
498dc2ecebeSagc
499dc2ecebeSagc return 0;
500dc2ecebeSagc }
501dc2ecebeSagc
502dc2ecebeSagc
503dc2ecebeSagc /* ARGSUSED */
504dc2ecebeSagc /*
505dc2ecebeSagc * isns_kevent_timer_refresh
506dc2ecebeSagc */
507dc2ecebeSagc int
isns_kevent_timer_refresh(struct kevent * evt_p,struct isns_config_s * cfg_p)508dc2ecebeSagc isns_kevent_timer_refresh(struct kevent* evt_p, struct isns_config_s *cfg_p)
509dc2ecebeSagc {
510dc2ecebeSagc struct isns_refresh_s *ref_p;
511dc2ecebeSagc ISNS_TRANS trans;
512dc2ecebeSagc uint32_t status;
513dc2ecebeSagc int rval;
514dc2ecebeSagc
515dc2ecebeSagc DBG("isns_kevent_timer_refresh: entered\n");
516dc2ecebeSagc
517dc2ecebeSagc /* If refresh info pointer NULL, or no name assigned, just return. */
518dc2ecebeSagc ref_p = cfg_p->refresh_p;
519dc2ecebeSagc if ((ref_p == NULL) || (ref_p->node[0] == '\0'))
520dc2ecebeSagc return 0;
521dc2ecebeSagc
522dc2ecebeSagc if (ref_p->trans_p != NULL) {
523dc2ecebeSagc /* If the previous refresh trans is not complete, return. */
524dc2ecebeSagc rval = isns_get_pdu_response_status(ref_p->trans_p, &status);
525dc2ecebeSagc if (rval == EPERM) {
526dc2ecebeSagc DBG("isns_kevent_timer_refresh: "
527dc2ecebeSagc "prev refresh trans not complete\n");
528dc2ecebeSagc return 0;
529dc2ecebeSagc }
530dc2ecebeSagc /* Free previous refresh trans. */
531dc2ecebeSagc isns_free_trans(ref_p->trans_p);
532dc2ecebeSagc ref_p->trans_p = NULL;
533dc2ecebeSagc }
534dc2ecebeSagc
535dc2ecebeSagc /* Build new refresh transaction and send it. */
536dc2ecebeSagc trans = isns_new_trans((ISNS_HANDLE)cfg_p, isnsp_DevAttrQry, 0);
537dc2ecebeSagc if (trans == ISNS_INVALID_TRANS) {
538dc2ecebeSagc DBG("isns_kevent_timer_refresh: error on isns_new_trans()\n");
539dc2ecebeSagc return 0;
540dc2ecebeSagc }
541dc2ecebeSagc
542dc2ecebeSagc ref_p->trans_p = (struct isns_trans_s *)trans;
543dc2ecebeSagc /* First we add our source attribute */
544dc2ecebeSagc isns_add_string(trans, isnst_iSCSIName, ref_p->node);
545dc2ecebeSagc /* Now add our message attribute */
546dc2ecebeSagc isns_add_string(trans, isnst_iSCSIName, ref_p->node);
547dc2ecebeSagc isns_add_tlv(trans, isnst_Delimiter, 0, NULL);
548dc2ecebeSagc /* and finally the operating attributes */
549dc2ecebeSagc isns_add_tlv(trans, isnst_EID, 0, NULL);
550dc2ecebeSagc isns_send_trans(trans, NULL, NULL);
551dc2ecebeSagc
552dc2ecebeSagc return 0;
553dc2ecebeSagc }
554