GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/iscsid/task.c Lines: 0 42 0.0 %
Date: 2017-11-13 Branches: 0 35 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: task.c,v 1.10 2014/05/10 11:28:02 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
#include <sys/types.h>
19
#include <sys/queue.h>
20
#include <sys/socket.h>
21
#include <sys/uio.h>
22
23
#include <scsi/iscsi.h>
24
25
#include <errno.h>
26
#include <event.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <strings.h>
30
#include <unistd.h>
31
32
#include "iscsid.h"
33
#include "log.h"
34
35
/*
36
 * Task handling, PDU are attached to tasks and task are scheduled across
37
 * all connections of a session.
38
 */
39
40
void
41
task_init(struct task *t, struct session *s, int immediate, void *carg,
42
    void (*c)(struct connection *, void *, struct pdu *),
43
    void (*f)(void *))
44
{
45
	TAILQ_INIT(&t->sendq);
46
	TAILQ_INIT(&t->recvq);
47
	t->callback = c;
48
	t->failback = f;
49
	t->callarg = carg;
50
	/* skip reserved and maybe bad ITT values */
51
	if (s->itt == 0xffffffff || s->itt == 0)
52
		s->itt = 1;
53
	t->itt = s->itt++; /* XXX we could do better here */
54
	t->cmdseqnum = s->cmdseqnum;
55
	if (!immediate)
56
		s->cmdseqnum++;
57
}
58
59
void
60
taskq_cleanup(struct taskq *tq)
61
{
62
	struct task *t;
63
64
	while ((t = TAILQ_FIRST(tq))) {
65
		TAILQ_REMOVE(tq, t, entry);
66
		if (t->failback)
67
			t->failback(t->callarg);
68
		conn_task_cleanup(NULL, t);
69
		free(t);
70
	}
71
}
72
73
void
74
task_pdu_add(struct task *t, struct pdu *p)
75
{
76
	struct iscsi_pdu *ipdu;
77
78
	/* fixup the pdu by setting the itt and seqnum if needed */
79
	ipdu = pdu_getbuf(p, NULL, PDU_HEADER);
80
	ipdu->itt = ntohl(t->itt);
81
	switch (ISCSI_PDU_OPCODE(ipdu->opcode)) {
82
	case ISCSI_OP_I_NOP:
83
	case ISCSI_OP_SCSI_REQUEST:
84
	case ISCSI_OP_TASK_REQUEST:
85
	case ISCSI_OP_LOGIN_REQUEST:
86
	case ISCSI_OP_TEXT_REQUEST:
87
	case ISCSI_OP_LOGOUT_REQUEST:
88
		ipdu->cmdsn = ntohl(t->cmdseqnum);
89
		break;
90
	}
91
92
	TAILQ_INSERT_TAIL(&t->sendq, p, entry);
93
}
94
95
void
96
task_pdu_cb(struct connection *c, struct pdu *p)
97
{
98
	struct task *t;
99
	struct iscsi_pdu *ipdu;
100
	u_int32_t itt;
101
102
	ipdu = pdu_getbuf(p, NULL, PDU_HEADER);
103
	switch (ISCSI_PDU_OPCODE(ipdu->opcode)) {
104
	case ISCSI_OP_T_NOP:
105
		itt = ntohl(ipdu->itt);
106
		if (itt == 0xffffffff) {
107
			/* target issued a ping, must answer back immediately */
108
			c->expstatsn = ntohl(ipdu->cmdsn) + 1;
109
			initiator_nop_in_imm(c, p);
110
			break;
111
		}
112
		/* FALLTHROUGH */
113
	case ISCSI_OP_LOGIN_RESPONSE:
114
	case ISCSI_OP_TEXT_RESPONSE:
115
	case ISCSI_OP_LOGOUT_RESPONSE:
116
	case ISCSI_OP_SCSI_RESPONSE:
117
	case ISCSI_OP_R2T:
118
	case ISCSI_OP_DATA_IN:
119
		itt = ntohl(ipdu->itt);
120
		c->expstatsn = ntohl(ipdu->cmdsn) + 1;
121
122
		/* XXX for now search the task on the connection queue
123
		   later on this should be moved to a per session RB tree but
124
		   now I do the quick ugly thing. */
125
		TAILQ_FOREACH(t, &c->tasks, entry) {
126
			if (itt == t->itt)
127
				break;
128
		}
129
		if (t)
130
			t->callback(c, t->callarg, p);
131
		else {
132
			log_debug("no task for PDU found");
133
			log_pdu(p, 1);
134
			pdu_free(p);
135
		}
136
		break;
137
	default:
138
		log_warnx("not handled yet. fix me");
139
		log_pdu(p, 1);
140
		pdu_free(p);
141
	}
142
}