xref: /freebsd-src/usr.bin/iscsictl/iscsictl.c (revision dd3603749cb7f20a628f04d595b105962b21a3d2)
1009ea47eSEdward Tomasz Napierala /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
4009ea47eSEdward Tomasz Napierala  * Copyright (c) 2012 The FreeBSD Foundation
5009ea47eSEdward Tomasz Napierala  *
6009ea47eSEdward Tomasz Napierala  * This software was developed by Edward Tomasz Napierala under sponsorship
7009ea47eSEdward Tomasz Napierala  * from the FreeBSD Foundation.
8009ea47eSEdward Tomasz Napierala  *
9009ea47eSEdward Tomasz Napierala  * Redistribution and use in source and binary forms, with or without
10009ea47eSEdward Tomasz Napierala  * modification, are permitted provided that the following conditions
11009ea47eSEdward Tomasz Napierala  * are met:
12009ea47eSEdward Tomasz Napierala  * 1. Redistributions of source code must retain the above copyright
13009ea47eSEdward Tomasz Napierala  *    notice, this list of conditions and the following disclaimer.
14009ea47eSEdward Tomasz Napierala  * 2. Redistributions in binary form must reproduce the above copyright
15009ea47eSEdward Tomasz Napierala  *    notice, this list of conditions and the following disclaimer in the
16009ea47eSEdward Tomasz Napierala  *    documentation and/or other materials provided with the distribution.
17009ea47eSEdward Tomasz Napierala  *
18009ea47eSEdward Tomasz Napierala  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19009ea47eSEdward Tomasz Napierala  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20009ea47eSEdward Tomasz Napierala  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21009ea47eSEdward Tomasz Napierala  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22009ea47eSEdward Tomasz Napierala  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23009ea47eSEdward Tomasz Napierala  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24009ea47eSEdward Tomasz Napierala  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25009ea47eSEdward Tomasz Napierala  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26009ea47eSEdward Tomasz Napierala  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27009ea47eSEdward Tomasz Napierala  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28009ea47eSEdward Tomasz Napierala  * SUCH DAMAGE.
29009ea47eSEdward Tomasz Napierala  *
30009ea47eSEdward Tomasz Napierala  */
31009ea47eSEdward Tomasz Napierala 
32b7a65e39SEdward Tomasz Napierala #include <sys/cdefs.h>
33009ea47eSEdward Tomasz Napierala #include <sys/ioctl.h>
34c76e8a9aSEdward Tomasz Napierala #include <sys/param.h>
35c76e8a9aSEdward Tomasz Napierala #include <sys/linker.h>
36009ea47eSEdward Tomasz Napierala #include <assert.h>
37009ea47eSEdward Tomasz Napierala #include <ctype.h>
38009ea47eSEdward Tomasz Napierala #include <errno.h>
39009ea47eSEdward Tomasz Napierala #include <fcntl.h>
40009ea47eSEdward Tomasz Napierala #include <limits.h>
41009ea47eSEdward Tomasz Napierala #include <stdio.h>
42009ea47eSEdward Tomasz Napierala #include <stdlib.h>
43009ea47eSEdward Tomasz Napierala #include <string.h>
44009ea47eSEdward Tomasz Napierala #include <unistd.h>
45*dd360374SJohn Baldwin #include <libiscsiutil.h>
4601d54ad2SEdward Tomasz Napierala #include <libxo/xo.h>
47009ea47eSEdward Tomasz Napierala 
48009ea47eSEdward Tomasz Napierala #include <iscsi_ioctl.h>
49009ea47eSEdward Tomasz Napierala #include "iscsictl.h"
50009ea47eSEdward Tomasz Napierala 
51009ea47eSEdward Tomasz Napierala struct conf *
52009ea47eSEdward Tomasz Napierala conf_new(void)
53009ea47eSEdward Tomasz Napierala {
54009ea47eSEdward Tomasz Napierala 	struct conf *conf;
55009ea47eSEdward Tomasz Napierala 
56009ea47eSEdward Tomasz Napierala 	conf = calloc(1, sizeof(*conf));
57009ea47eSEdward Tomasz Napierala 	if (conf == NULL)
5801d54ad2SEdward Tomasz Napierala 		xo_err(1, "calloc");
59009ea47eSEdward Tomasz Napierala 
60009ea47eSEdward Tomasz Napierala 	TAILQ_INIT(&conf->conf_targets);
61009ea47eSEdward Tomasz Napierala 
62009ea47eSEdward Tomasz Napierala 	return (conf);
63009ea47eSEdward Tomasz Napierala }
64009ea47eSEdward Tomasz Napierala 
65009ea47eSEdward Tomasz Napierala struct target *
66009ea47eSEdward Tomasz Napierala target_find(struct conf *conf, const char *nickname)
67009ea47eSEdward Tomasz Napierala {
68009ea47eSEdward Tomasz Napierala 	struct target *targ;
69009ea47eSEdward Tomasz Napierala 
70009ea47eSEdward Tomasz Napierala 	TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
71009ea47eSEdward Tomasz Napierala 		if (targ->t_nickname != NULL &&
72009ea47eSEdward Tomasz Napierala 		    strcasecmp(targ->t_nickname, nickname) == 0)
73009ea47eSEdward Tomasz Napierala 			return (targ);
74009ea47eSEdward Tomasz Napierala 	}
75009ea47eSEdward Tomasz Napierala 
76009ea47eSEdward Tomasz Napierala 	return (NULL);
77009ea47eSEdward Tomasz Napierala }
78009ea47eSEdward Tomasz Napierala 
79009ea47eSEdward Tomasz Napierala struct target *
80009ea47eSEdward Tomasz Napierala target_new(struct conf *conf)
81009ea47eSEdward Tomasz Napierala {
82009ea47eSEdward Tomasz Napierala 	struct target *targ;
83009ea47eSEdward Tomasz Napierala 
84009ea47eSEdward Tomasz Napierala 	targ = calloc(1, sizeof(*targ));
85009ea47eSEdward Tomasz Napierala 	if (targ == NULL)
8601d54ad2SEdward Tomasz Napierala 		xo_err(1, "calloc");
87009ea47eSEdward Tomasz Napierala 	targ->t_conf = conf;
88bfabdadeSRichard Scheffenegger 	targ->t_dscp = -1;
894dfbcffbSRichard Scheffenegger 	targ->t_pcp = -1;
90bd6bb493SRichard Scheffenegger 	targ->t_pingtimeout = -1;
91bd6bb493SRichard Scheffenegger 	targ->t_logintimeout = -1;
92009ea47eSEdward Tomasz Napierala 	TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next);
93009ea47eSEdward Tomasz Napierala 
94009ea47eSEdward Tomasz Napierala 	return (targ);
95009ea47eSEdward Tomasz Napierala }
96009ea47eSEdward Tomasz Napierala 
97009ea47eSEdward Tomasz Napierala void
98009ea47eSEdward Tomasz Napierala target_delete(struct target *targ)
99009ea47eSEdward Tomasz Napierala {
100009ea47eSEdward Tomasz Napierala 
101009ea47eSEdward Tomasz Napierala 	TAILQ_REMOVE(&targ->t_conf->conf_targets, targ, t_next);
102009ea47eSEdward Tomasz Napierala 	free(targ);
103009ea47eSEdward Tomasz Napierala }
104009ea47eSEdward Tomasz Napierala 
105009ea47eSEdward Tomasz Napierala static char *
106009ea47eSEdward Tomasz Napierala default_initiator_name(void)
107009ea47eSEdward Tomasz Napierala {
108009ea47eSEdward Tomasz Napierala 	char *name;
109009ea47eSEdward Tomasz Napierala 	size_t namelen;
110009ea47eSEdward Tomasz Napierala 	int error;
111009ea47eSEdward Tomasz Napierala 
112009ea47eSEdward Tomasz Napierala 	namelen = _POSIX_HOST_NAME_MAX + strlen(DEFAULT_IQN);
113009ea47eSEdward Tomasz Napierala 
114009ea47eSEdward Tomasz Napierala 	name = calloc(1, namelen + 1);
115009ea47eSEdward Tomasz Napierala 	if (name == NULL)
11601d54ad2SEdward Tomasz Napierala 		xo_err(1, "calloc");
117009ea47eSEdward Tomasz Napierala 	strcpy(name, DEFAULT_IQN);
118009ea47eSEdward Tomasz Napierala 	error = gethostname(name + strlen(DEFAULT_IQN),
119009ea47eSEdward Tomasz Napierala 	    namelen - strlen(DEFAULT_IQN));
120009ea47eSEdward Tomasz Napierala 	if (error != 0)
12101d54ad2SEdward Tomasz Napierala 		xo_err(1, "gethostname");
122009ea47eSEdward Tomasz Napierala 
123009ea47eSEdward Tomasz Napierala 	return (name);
124009ea47eSEdward Tomasz Napierala }
125009ea47eSEdward Tomasz Napierala 
126ba165a31SEdward Tomasz Napierala int
127ba165a31SEdward Tomasz Napierala parse_enable(const char *enable)
128ba165a31SEdward Tomasz Napierala {
129ba165a31SEdward Tomasz Napierala 	if (enable == NULL)
130ba165a31SEdward Tomasz Napierala 		return (ENABLE_UNSPECIFIED);
131ba165a31SEdward Tomasz Napierala 
132ba165a31SEdward Tomasz Napierala 	if (strcasecmp(enable, "on") == 0 ||
133ba165a31SEdward Tomasz Napierala 	    strcasecmp(enable, "yes") == 0)
134ba165a31SEdward Tomasz Napierala 		return (ENABLE_ON);
135ba165a31SEdward Tomasz Napierala 
136ba165a31SEdward Tomasz Napierala 	if (strcasecmp(enable, "off") == 0 ||
137ba165a31SEdward Tomasz Napierala 	    strcasecmp(enable, "no") == 0)
138ba165a31SEdward Tomasz Napierala 		return (ENABLE_OFF);
139ba165a31SEdward Tomasz Napierala 
140ba165a31SEdward Tomasz Napierala 	return (ENABLE_UNSPECIFIED);
141ba165a31SEdward Tomasz Napierala }
142ba165a31SEdward Tomasz Napierala 
143009ea47eSEdward Tomasz Napierala void
144009ea47eSEdward Tomasz Napierala conf_verify(struct conf *conf)
145009ea47eSEdward Tomasz Napierala {
146009ea47eSEdward Tomasz Napierala 	struct target *targ;
147009ea47eSEdward Tomasz Napierala 
148009ea47eSEdward Tomasz Napierala 	TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
149009ea47eSEdward Tomasz Napierala 		assert(targ->t_nickname != NULL);
150009ea47eSEdward Tomasz Napierala 		if (targ->t_session_type == SESSION_TYPE_UNSPECIFIED)
151009ea47eSEdward Tomasz Napierala 			targ->t_session_type = SESSION_TYPE_NORMAL;
152009ea47eSEdward Tomasz Napierala 		if (targ->t_session_type == SESSION_TYPE_NORMAL &&
153009ea47eSEdward Tomasz Napierala 		    targ->t_name == NULL)
15401d54ad2SEdward Tomasz Napierala 			xo_errx(1, "missing TargetName for target \"%s\"",
155009ea47eSEdward Tomasz Napierala 			    targ->t_nickname);
156009ea47eSEdward Tomasz Napierala 		if (targ->t_session_type == SESSION_TYPE_DISCOVERY &&
157009ea47eSEdward Tomasz Napierala 		    targ->t_name != NULL)
15801d54ad2SEdward Tomasz Napierala 			xo_errx(1, "cannot specify TargetName for discovery "
159009ea47eSEdward Tomasz Napierala 			    "sessions for target \"%s\"", targ->t_nickname);
160009ea47eSEdward Tomasz Napierala 		if (targ->t_name != NULL) {
161*dd360374SJohn Baldwin 			if (valid_iscsi_name(targ->t_name, xo_warnx) == false)
16201d54ad2SEdward Tomasz Napierala 				xo_errx(1, "invalid target name \"%s\"",
163009ea47eSEdward Tomasz Napierala 				    targ->t_name);
164009ea47eSEdward Tomasz Napierala 		}
165009ea47eSEdward Tomasz Napierala 		if (targ->t_protocol == PROTOCOL_UNSPECIFIED)
166009ea47eSEdward Tomasz Napierala 			targ->t_protocol = PROTOCOL_ISCSI;
167009ea47eSEdward Tomasz Napierala 		if (targ->t_address == NULL)
16801d54ad2SEdward Tomasz Napierala 			xo_errx(1, "missing TargetAddress for target \"%s\"",
169009ea47eSEdward Tomasz Napierala 			    targ->t_nickname);
170009ea47eSEdward Tomasz Napierala 		if (targ->t_initiator_name == NULL)
171009ea47eSEdward Tomasz Napierala 			targ->t_initiator_name = default_initiator_name();
172*dd360374SJohn Baldwin 		if (valid_iscsi_name(targ->t_initiator_name, xo_warnx) == false)
17301d54ad2SEdward Tomasz Napierala 			xo_errx(1, "invalid initiator name \"%s\"",
174009ea47eSEdward Tomasz Napierala 			    targ->t_initiator_name);
175009ea47eSEdward Tomasz Napierala 		if (targ->t_header_digest == DIGEST_UNSPECIFIED)
176009ea47eSEdward Tomasz Napierala 			targ->t_header_digest = DIGEST_NONE;
177009ea47eSEdward Tomasz Napierala 		if (targ->t_data_digest == DIGEST_UNSPECIFIED)
178009ea47eSEdward Tomasz Napierala 			targ->t_data_digest = DIGEST_NONE;
179009ea47eSEdward Tomasz Napierala 		if (targ->t_auth_method == AUTH_METHOD_UNSPECIFIED) {
180009ea47eSEdward Tomasz Napierala 			if (targ->t_user != NULL || targ->t_secret != NULL ||
181009ea47eSEdward Tomasz Napierala 			    targ->t_mutual_user != NULL ||
182009ea47eSEdward Tomasz Napierala 			    targ->t_mutual_secret != NULL)
183009ea47eSEdward Tomasz Napierala 				targ->t_auth_method =
184009ea47eSEdward Tomasz Napierala 				    AUTH_METHOD_CHAP;
185009ea47eSEdward Tomasz Napierala 			else
186009ea47eSEdward Tomasz Napierala 				targ->t_auth_method =
187009ea47eSEdward Tomasz Napierala 				    AUTH_METHOD_NONE;
188009ea47eSEdward Tomasz Napierala 		}
189009ea47eSEdward Tomasz Napierala 		if (targ->t_auth_method == AUTH_METHOD_CHAP) {
190009ea47eSEdward Tomasz Napierala 			if (targ->t_user == NULL) {
19101d54ad2SEdward Tomasz Napierala 				xo_errx(1, "missing chapIName for target \"%s\"",
192009ea47eSEdward Tomasz Napierala 				    targ->t_nickname);
193009ea47eSEdward Tomasz Napierala 			}
194009ea47eSEdward Tomasz Napierala 			if (targ->t_secret == NULL)
19501d54ad2SEdward Tomasz Napierala 				xo_errx(1, "missing chapSecret for target \"%s\"",
196009ea47eSEdward Tomasz Napierala 				    targ->t_nickname);
197009ea47eSEdward Tomasz Napierala 			if (targ->t_mutual_user != NULL ||
198009ea47eSEdward Tomasz Napierala 			    targ->t_mutual_secret != NULL) {
199009ea47eSEdward Tomasz Napierala 				if (targ->t_mutual_user == NULL)
20001d54ad2SEdward Tomasz Napierala 					xo_errx(1, "missing tgtChapName for "
201009ea47eSEdward Tomasz Napierala 					    "target \"%s\"", targ->t_nickname);
202009ea47eSEdward Tomasz Napierala 				if (targ->t_mutual_secret == NULL)
20301d54ad2SEdward Tomasz Napierala 					xo_errx(1, "missing tgtChapSecret for "
204009ea47eSEdward Tomasz Napierala 					    "target \"%s\"", targ->t_nickname);
205009ea47eSEdward Tomasz Napierala 			}
206009ea47eSEdward Tomasz Napierala 		}
207009ea47eSEdward Tomasz Napierala 	}
208009ea47eSEdward Tomasz Napierala }
209009ea47eSEdward Tomasz Napierala 
210009ea47eSEdward Tomasz Napierala static void
211009ea47eSEdward Tomasz Napierala conf_from_target(struct iscsi_session_conf *conf,
212009ea47eSEdward Tomasz Napierala     const struct target *targ)
213009ea47eSEdward Tomasz Napierala {
214009ea47eSEdward Tomasz Napierala 	memset(conf, 0, sizeof(*conf));
215009ea47eSEdward Tomasz Napierala 
216009ea47eSEdward Tomasz Napierala 	/*
217009ea47eSEdward Tomasz Napierala 	 * XXX: Check bounds and return error instead of silently truncating.
218009ea47eSEdward Tomasz Napierala 	 */
219009ea47eSEdward Tomasz Napierala 	if (targ->t_initiator_name != NULL)
220009ea47eSEdward Tomasz Napierala 		strlcpy(conf->isc_initiator, targ->t_initiator_name,
221009ea47eSEdward Tomasz Napierala 		    sizeof(conf->isc_initiator));
222009ea47eSEdward Tomasz Napierala 	if (targ->t_initiator_address != NULL)
223009ea47eSEdward Tomasz Napierala 		strlcpy(conf->isc_initiator_addr, targ->t_initiator_address,
224009ea47eSEdward Tomasz Napierala 		    sizeof(conf->isc_initiator_addr));
225009ea47eSEdward Tomasz Napierala 	if (targ->t_initiator_alias != NULL)
226009ea47eSEdward Tomasz Napierala 		strlcpy(conf->isc_initiator_alias, targ->t_initiator_alias,
227009ea47eSEdward Tomasz Napierala 		    sizeof(conf->isc_initiator_alias));
228009ea47eSEdward Tomasz Napierala 	if (targ->t_name != NULL)
229009ea47eSEdward Tomasz Napierala 		strlcpy(conf->isc_target, targ->t_name,
230009ea47eSEdward Tomasz Napierala 		    sizeof(conf->isc_target));
231009ea47eSEdward Tomasz Napierala 	if (targ->t_address != NULL)
232009ea47eSEdward Tomasz Napierala 		strlcpy(conf->isc_target_addr, targ->t_address,
233009ea47eSEdward Tomasz Napierala 		    sizeof(conf->isc_target_addr));
234009ea47eSEdward Tomasz Napierala 	if (targ->t_user != NULL)
235009ea47eSEdward Tomasz Napierala 		strlcpy(conf->isc_user, targ->t_user,
236009ea47eSEdward Tomasz Napierala 		    sizeof(conf->isc_user));
237009ea47eSEdward Tomasz Napierala 	if (targ->t_secret != NULL)
238009ea47eSEdward Tomasz Napierala 		strlcpy(conf->isc_secret, targ->t_secret,
239009ea47eSEdward Tomasz Napierala 		    sizeof(conf->isc_secret));
240009ea47eSEdward Tomasz Napierala 	if (targ->t_mutual_user != NULL)
241009ea47eSEdward Tomasz Napierala 		strlcpy(conf->isc_mutual_user, targ->t_mutual_user,
242009ea47eSEdward Tomasz Napierala 		    sizeof(conf->isc_mutual_user));
243009ea47eSEdward Tomasz Napierala 	if (targ->t_mutual_secret != NULL)
244009ea47eSEdward Tomasz Napierala 		strlcpy(conf->isc_mutual_secret, targ->t_mutual_secret,
245009ea47eSEdward Tomasz Napierala 		    sizeof(conf->isc_mutual_secret));
246009ea47eSEdward Tomasz Napierala 	if (targ->t_session_type == SESSION_TYPE_DISCOVERY)
247009ea47eSEdward Tomasz Napierala 		conf->isc_discovery = 1;
248ba165a31SEdward Tomasz Napierala 	if (targ->t_enable != ENABLE_OFF)
249ba165a31SEdward Tomasz Napierala 		conf->isc_enable = 1;
250009ea47eSEdward Tomasz Napierala 	if (targ->t_protocol == PROTOCOL_ISER)
251009ea47eSEdward Tomasz Napierala 		conf->isc_iser = 1;
25282babffbSEdward Tomasz Napierala 	if (targ->t_offload != NULL)
25382babffbSEdward Tomasz Napierala 		strlcpy(conf->isc_offload, targ->t_offload,
25482babffbSEdward Tomasz Napierala 		    sizeof(conf->isc_offload));
255009ea47eSEdward Tomasz Napierala 	if (targ->t_header_digest == DIGEST_CRC32C)
256009ea47eSEdward Tomasz Napierala 		conf->isc_header_digest = ISCSI_DIGEST_CRC32C;
257009ea47eSEdward Tomasz Napierala 	else
258009ea47eSEdward Tomasz Napierala 		conf->isc_header_digest = ISCSI_DIGEST_NONE;
259009ea47eSEdward Tomasz Napierala 	if (targ->t_data_digest == DIGEST_CRC32C)
260009ea47eSEdward Tomasz Napierala 		conf->isc_data_digest = ISCSI_DIGEST_CRC32C;
261009ea47eSEdward Tomasz Napierala 	else
262009ea47eSEdward Tomasz Napierala 		conf->isc_data_digest = ISCSI_DIGEST_NONE;
263bfabdadeSRichard Scheffenegger 	conf->isc_dscp = targ->t_dscp;
2644dfbcffbSRichard Scheffenegger 	conf->isc_pcp = targ->t_pcp;
265bd6bb493SRichard Scheffenegger 	conf->isc_ping_timeout = targ->t_pingtimeout;
266bd6bb493SRichard Scheffenegger 	conf->isc_login_timeout = targ->t_logintimeout;
267009ea47eSEdward Tomasz Napierala }
268009ea47eSEdward Tomasz Napierala 
269009ea47eSEdward Tomasz Napierala static int
270009ea47eSEdward Tomasz Napierala kernel_add(int iscsi_fd, const struct target *targ)
271009ea47eSEdward Tomasz Napierala {
272009ea47eSEdward Tomasz Napierala 	struct iscsi_session_add isa;
273009ea47eSEdward Tomasz Napierala 	int error;
274009ea47eSEdward Tomasz Napierala 
275009ea47eSEdward Tomasz Napierala 	memset(&isa, 0, sizeof(isa));
276009ea47eSEdward Tomasz Napierala 	conf_from_target(&isa.isa_conf, targ);
277009ea47eSEdward Tomasz Napierala 	error = ioctl(iscsi_fd, ISCSISADD, &isa);
278009ea47eSEdward Tomasz Napierala 	if (error != 0)
27901d54ad2SEdward Tomasz Napierala 		xo_warn("ISCSISADD");
280009ea47eSEdward Tomasz Napierala 	return (error);
281009ea47eSEdward Tomasz Napierala }
282009ea47eSEdward Tomasz Napierala 
283009ea47eSEdward Tomasz Napierala static int
2840262f2e0SEdward Tomasz Napierala kernel_modify(int iscsi_fd, unsigned int session_id, const struct target *targ)
2850262f2e0SEdward Tomasz Napierala {
2860262f2e0SEdward Tomasz Napierala 	struct iscsi_session_modify ism;
2870262f2e0SEdward Tomasz Napierala 	int error;
2880262f2e0SEdward Tomasz Napierala 
2890262f2e0SEdward Tomasz Napierala 	memset(&ism, 0, sizeof(ism));
2900262f2e0SEdward Tomasz Napierala 	ism.ism_session_id = session_id;
2910262f2e0SEdward Tomasz Napierala 	conf_from_target(&ism.ism_conf, targ);
2920262f2e0SEdward Tomasz Napierala 	error = ioctl(iscsi_fd, ISCSISMODIFY, &ism);
2930262f2e0SEdward Tomasz Napierala 	if (error != 0)
29401d54ad2SEdward Tomasz Napierala 		xo_warn("ISCSISMODIFY");
2950262f2e0SEdward Tomasz Napierala 	return (error);
2960262f2e0SEdward Tomasz Napierala }
2970262f2e0SEdward Tomasz Napierala 
2980262f2e0SEdward Tomasz Napierala static void
2990262f2e0SEdward Tomasz Napierala kernel_modify_some(int iscsi_fd, unsigned int session_id, const char *target,
300ba165a31SEdward Tomasz Napierala   const char *target_addr, const char *user, const char *secret, int enable)
3010262f2e0SEdward Tomasz Napierala {
3020262f2e0SEdward Tomasz Napierala 	struct iscsi_session_state *states = NULL;
3030262f2e0SEdward Tomasz Napierala 	struct iscsi_session_state *state;
3040262f2e0SEdward Tomasz Napierala 	struct iscsi_session_conf *conf;
3050262f2e0SEdward Tomasz Napierala 	struct iscsi_session_list isl;
3060262f2e0SEdward Tomasz Napierala 	struct iscsi_session_modify ism;
3070262f2e0SEdward Tomasz Napierala 	unsigned int i, nentries = 1;
3080262f2e0SEdward Tomasz Napierala 	int error;
3090262f2e0SEdward Tomasz Napierala 
3100262f2e0SEdward Tomasz Napierala 	for (;;) {
3110262f2e0SEdward Tomasz Napierala 		states = realloc(states,
3120262f2e0SEdward Tomasz Napierala 		    nentries * sizeof(struct iscsi_session_state));
3130262f2e0SEdward Tomasz Napierala 		if (states == NULL)
31401d54ad2SEdward Tomasz Napierala 			xo_err(1, "realloc");
3150262f2e0SEdward Tomasz Napierala 
3160262f2e0SEdward Tomasz Napierala 		memset(&isl, 0, sizeof(isl));
3170262f2e0SEdward Tomasz Napierala 		isl.isl_nentries = nentries;
3180262f2e0SEdward Tomasz Napierala 		isl.isl_pstates = states;
3190262f2e0SEdward Tomasz Napierala 
3200262f2e0SEdward Tomasz Napierala 		error = ioctl(iscsi_fd, ISCSISLIST, &isl);
3210262f2e0SEdward Tomasz Napierala 		if (error != 0 && errno == EMSGSIZE) {
3220262f2e0SEdward Tomasz Napierala 			nentries *= 4;
3230262f2e0SEdward Tomasz Napierala 			continue;
3240262f2e0SEdward Tomasz Napierala 		}
3250262f2e0SEdward Tomasz Napierala 		break;
3260262f2e0SEdward Tomasz Napierala 	}
3270262f2e0SEdward Tomasz Napierala 	if (error != 0)
32801d54ad2SEdward Tomasz Napierala 		xo_errx(1, "ISCSISLIST");
3290262f2e0SEdward Tomasz Napierala 
3300262f2e0SEdward Tomasz Napierala 	for (i = 0; i < isl.isl_nentries; i++) {
3310262f2e0SEdward Tomasz Napierala 		state = &states[i];
3320262f2e0SEdward Tomasz Napierala 
3330262f2e0SEdward Tomasz Napierala 		if (state->iss_id == session_id)
3340262f2e0SEdward Tomasz Napierala 			break;
3350262f2e0SEdward Tomasz Napierala 	}
3360262f2e0SEdward Tomasz Napierala 	if (i == isl.isl_nentries)
33701d54ad2SEdward Tomasz Napierala 		xo_errx(1, "session-id %u not found", session_id);
3380262f2e0SEdward Tomasz Napierala 
3390262f2e0SEdward Tomasz Napierala 	conf = &state->iss_conf;
3400262f2e0SEdward Tomasz Napierala 
3410262f2e0SEdward Tomasz Napierala 	if (target != NULL)
3420262f2e0SEdward Tomasz Napierala 		strlcpy(conf->isc_target, target, sizeof(conf->isc_target));
3430262f2e0SEdward Tomasz Napierala 	if (target_addr != NULL)
3440262f2e0SEdward Tomasz Napierala 		strlcpy(conf->isc_target_addr, target_addr,
3450262f2e0SEdward Tomasz Napierala 		    sizeof(conf->isc_target_addr));
3460262f2e0SEdward Tomasz Napierala 	if (user != NULL)
3470262f2e0SEdward Tomasz Napierala 		strlcpy(conf->isc_user, user, sizeof(conf->isc_user));
3480262f2e0SEdward Tomasz Napierala 	if (secret != NULL)
3490262f2e0SEdward Tomasz Napierala 		strlcpy(conf->isc_secret, secret, sizeof(conf->isc_secret));
350ba165a31SEdward Tomasz Napierala 	if (enable == ENABLE_ON)
351ba165a31SEdward Tomasz Napierala 		conf->isc_enable = 1;
352ba165a31SEdward Tomasz Napierala 	else if (enable == ENABLE_OFF)
353ba165a31SEdward Tomasz Napierala 		conf->isc_enable = 0;
3540262f2e0SEdward Tomasz Napierala 
3550262f2e0SEdward Tomasz Napierala 	memset(&ism, 0, sizeof(ism));
3560262f2e0SEdward Tomasz Napierala 	ism.ism_session_id = session_id;
3570262f2e0SEdward Tomasz Napierala 	memcpy(&ism.ism_conf, conf, sizeof(ism.ism_conf));
3580262f2e0SEdward Tomasz Napierala 	error = ioctl(iscsi_fd, ISCSISMODIFY, &ism);
3590262f2e0SEdward Tomasz Napierala 	if (error != 0)
36001d54ad2SEdward Tomasz Napierala 		xo_warn("ISCSISMODIFY");
3610262f2e0SEdward Tomasz Napierala }
3620262f2e0SEdward Tomasz Napierala 
3630262f2e0SEdward Tomasz Napierala static int
364009ea47eSEdward Tomasz Napierala kernel_remove(int iscsi_fd, const struct target *targ)
365009ea47eSEdward Tomasz Napierala {
366009ea47eSEdward Tomasz Napierala 	struct iscsi_session_remove isr;
367009ea47eSEdward Tomasz Napierala 	int error;
368009ea47eSEdward Tomasz Napierala 
369009ea47eSEdward Tomasz Napierala 	memset(&isr, 0, sizeof(isr));
370009ea47eSEdward Tomasz Napierala 	conf_from_target(&isr.isr_conf, targ);
371009ea47eSEdward Tomasz Napierala 	error = ioctl(iscsi_fd, ISCSISREMOVE, &isr);
372009ea47eSEdward Tomasz Napierala 	if (error != 0)
37301d54ad2SEdward Tomasz Napierala 		xo_warn("ISCSISREMOVE");
374009ea47eSEdward Tomasz Napierala 	return (error);
375009ea47eSEdward Tomasz Napierala }
376009ea47eSEdward Tomasz Napierala 
377009ea47eSEdward Tomasz Napierala /*
378009ea47eSEdward Tomasz Napierala  * XXX: Add filtering.
379009ea47eSEdward Tomasz Napierala  */
380009ea47eSEdward Tomasz Napierala static int
381009ea47eSEdward Tomasz Napierala kernel_list(int iscsi_fd, const struct target *targ __unused,
382009ea47eSEdward Tomasz Napierala     int verbose)
383009ea47eSEdward Tomasz Napierala {
384009ea47eSEdward Tomasz Napierala 	struct iscsi_session_state *states = NULL;
385009ea47eSEdward Tomasz Napierala 	const struct iscsi_session_state *state;
386009ea47eSEdward Tomasz Napierala 	const struct iscsi_session_conf *conf;
387009ea47eSEdward Tomasz Napierala 	struct iscsi_session_list isl;
388009ea47eSEdward Tomasz Napierala 	unsigned int i, nentries = 1;
389009ea47eSEdward Tomasz Napierala 	int error;
390009ea47eSEdward Tomasz Napierala 
391009ea47eSEdward Tomasz Napierala 	for (;;) {
392009ea47eSEdward Tomasz Napierala 		states = realloc(states,
393009ea47eSEdward Tomasz Napierala 		    nentries * sizeof(struct iscsi_session_state));
394009ea47eSEdward Tomasz Napierala 		if (states == NULL)
39501d54ad2SEdward Tomasz Napierala 			xo_err(1, "realloc");
396009ea47eSEdward Tomasz Napierala 
397009ea47eSEdward Tomasz Napierala 		memset(&isl, 0, sizeof(isl));
398009ea47eSEdward Tomasz Napierala 		isl.isl_nentries = nentries;
399009ea47eSEdward Tomasz Napierala 		isl.isl_pstates = states;
400009ea47eSEdward Tomasz Napierala 
401009ea47eSEdward Tomasz Napierala 		error = ioctl(iscsi_fd, ISCSISLIST, &isl);
402009ea47eSEdward Tomasz Napierala 		if (error != 0 && errno == EMSGSIZE) {
403009ea47eSEdward Tomasz Napierala 			nentries *= 4;
404009ea47eSEdward Tomasz Napierala 			continue;
405009ea47eSEdward Tomasz Napierala 		}
406009ea47eSEdward Tomasz Napierala 		break;
407009ea47eSEdward Tomasz Napierala 	}
408009ea47eSEdward Tomasz Napierala 	if (error != 0) {
40901d54ad2SEdward Tomasz Napierala 		xo_warn("ISCSISLIST");
410009ea47eSEdward Tomasz Napierala 		return (error);
411009ea47eSEdward Tomasz Napierala 	}
412009ea47eSEdward Tomasz Napierala 
413009ea47eSEdward Tomasz Napierala 	if (verbose != 0) {
41401d54ad2SEdward Tomasz Napierala 		xo_open_list("session");
415009ea47eSEdward Tomasz Napierala 		for (i = 0; i < isl.isl_nentries; i++) {
416009ea47eSEdward Tomasz Napierala 			state = &states[i];
417009ea47eSEdward Tomasz Napierala 			conf = &state->iss_conf;
418009ea47eSEdward Tomasz Napierala 
41901d54ad2SEdward Tomasz Napierala 			xo_open_instance("session");
42001d54ad2SEdward Tomasz Napierala 
42101d54ad2SEdward Tomasz Napierala 			/*
42201d54ad2SEdward Tomasz Napierala 			 * Display-only modifier as this information
42301d54ad2SEdward Tomasz Napierala 			 * is also present within the 'session' container
42401d54ad2SEdward Tomasz Napierala 			 */
42525b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:sessionId/%u}\n",
42601d54ad2SEdward Tomasz Napierala 			    "Session ID:", state->iss_id);
42701d54ad2SEdward Tomasz Napierala 
42801d54ad2SEdward Tomasz Napierala 			xo_open_container("initiator");
42925b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:name/%s}\n",
43001d54ad2SEdward Tomasz Napierala 			    "Initiator name:", conf->isc_initiator);
43125b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:portal/%s}\n",
43201d54ad2SEdward Tomasz Napierala 			    "Initiator portal:", conf->isc_initiator_addr);
43325b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:alias/%s}\n",
43401d54ad2SEdward Tomasz Napierala 			    "Initiator alias:", conf->isc_initiator_alias);
43501d54ad2SEdward Tomasz Napierala 			xo_close_container("initiator");
43601d54ad2SEdward Tomasz Napierala 
43701d54ad2SEdward Tomasz Napierala 			xo_open_container("target");
43825b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:name/%s}\n",
43901d54ad2SEdward Tomasz Napierala 			    "Target name:", conf->isc_target);
44025b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:portal/%s}\n",
44101d54ad2SEdward Tomasz Napierala 			    "Target portal:", conf->isc_target_addr);
44225b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:alias/%s}\n",
44301d54ad2SEdward Tomasz Napierala 			    "Target alias:", state->iss_target_alias);
444bfabdadeSRichard Scheffenegger 			if (conf->isc_dscp != -1)
445bfabdadeSRichard Scheffenegger 				xo_emit("{L:/%-26s}{V:dscp/0x%02x}\n",
446bfabdadeSRichard Scheffenegger 				    "Target DSCP:", conf->isc_dscp);
4474dfbcffbSRichard Scheffenegger 			if (conf->isc_pcp != -1)
4484dfbcffbSRichard Scheffenegger 				xo_emit("{L:/%-26s}{V:pcp/0x%02x}\n",
4494dfbcffbSRichard Scheffenegger 				    "Target PCP:", conf->isc_pcp);
450bd6bb493SRichard Scheffenegger 			if (conf->isc_ping_timeout != -1)
451bd6bb493SRichard Scheffenegger 				xo_emit("{L:/%-26s}{V:PingTimeout/%d}\n",
452bd6bb493SRichard Scheffenegger 				    "Target PingTimeout:",
453bd6bb493SRichard Scheffenegger 				    conf->isc_ping_timeout);
454bd6bb493SRichard Scheffenegger 			if (conf->isc_login_timeout != -1)
455bd6bb493SRichard Scheffenegger 				xo_emit("{L:/%-26s}{V:LoginTimeout/%d}\n",
456bd6bb493SRichard Scheffenegger 				    "Target LoginTimeout:",
457bd6bb493SRichard Scheffenegger 				    conf->isc_login_timeout);
45801d54ad2SEdward Tomasz Napierala 			xo_close_container("target");
45901d54ad2SEdward Tomasz Napierala 
46001d54ad2SEdward Tomasz Napierala 			xo_open_container("auth");
46125b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:user/%s}\n",
46201d54ad2SEdward Tomasz Napierala 			    "User:", conf->isc_user);
46325b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:secret/%s}\n",
46401d54ad2SEdward Tomasz Napierala 			    "Secret:", conf->isc_secret);
46525b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:mutualUser/%s}\n",
46601d54ad2SEdward Tomasz Napierala 			    "Mutual user:", conf->isc_mutual_user);
46725b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:mutualSecret/%s}\n",
46801d54ad2SEdward Tomasz Napierala 			    "Mutual secret:", conf->isc_mutual_secret);
46901d54ad2SEdward Tomasz Napierala 			xo_close_container("auth");
47001d54ad2SEdward Tomasz Napierala 
47125b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:type/%s}\n",
47201d54ad2SEdward Tomasz Napierala 			    "Session type:",
473009ea47eSEdward Tomasz Napierala 			    conf->isc_discovery ? "Discovery" : "Normal");
47425b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:enable/%s}\n",
475ba165a31SEdward Tomasz Napierala 			    "Enable:",
476ba165a31SEdward Tomasz Napierala 			    conf->isc_enable ? "Yes" : "No");
47725b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:state/%s}\n",
47801d54ad2SEdward Tomasz Napierala 			    "Session state:",
47901d54ad2SEdward Tomasz Napierala 			    state->iss_connected ? "Connected" : "Disconnected");
48025b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:failureReason/%s}\n",
48101d54ad2SEdward Tomasz Napierala 			    "Failure reason:", state->iss_reason);
48225b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:headerDigest/%s}\n",
48301d54ad2SEdward Tomasz Napierala 			    "Header digest:",
484009ea47eSEdward Tomasz Napierala 			    state->iss_header_digest == ISCSI_DIGEST_CRC32C ?
485009ea47eSEdward Tomasz Napierala 			    "CRC32C" : "None");
48625b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:dataDigest/%s}\n",
48701d54ad2SEdward Tomasz Napierala 			    "Data digest:",
488009ea47eSEdward Tomasz Napierala 			    state->iss_data_digest == ISCSI_DIGEST_CRC32C ?
489009ea47eSEdward Tomasz Napierala 			    "CRC32C" : "None");
49025b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:recvDataSegmentLen/%d}\n",
49197b84d34SNavdeep Parhar 			    "MaxRecvDataSegmentLength:",
49297b84d34SNavdeep Parhar 			    state->iss_max_recv_data_segment_length);
49325b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:sendDataSegmentLen/%d}\n",
49497b84d34SNavdeep Parhar 			    "MaxSendDataSegmentLength:",
49597b84d34SNavdeep Parhar 			    state->iss_max_send_data_segment_length);
49625b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:maxBurstLen/%d}\n",
4974e5408f1SEdward Tomasz Napierala 			    "MaxBurstLen:", state->iss_max_burst_length);
49825b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:firstBurstLen/%d}\n",
4994e5408f1SEdward Tomasz Napierala 			    "FirstBurstLen:", state->iss_first_burst_length);
50025b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:immediateData/%s}\n",
50101d54ad2SEdward Tomasz Napierala 			    "ImmediateData:", state->iss_immediate_data ? "Yes" : "No");
50225b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:iSER/%s}\n",
50301d54ad2SEdward Tomasz Napierala 			    "iSER (RDMA):", conf->isc_iser ? "Yes" : "No");
50425b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}{V:offloadDriver/%s}\n",
50501d54ad2SEdward Tomasz Napierala 			    "Offload driver:", state->iss_offload);
50625b20d78SEdward Tomasz Napierala 			xo_emit("{L:/%-26s}",
50701d54ad2SEdward Tomasz Napierala 			    "Device nodes:");
508009ea47eSEdward Tomasz Napierala 			print_periphs(state->iss_id);
50901d54ad2SEdward Tomasz Napierala 			xo_emit("\n\n");
51001d54ad2SEdward Tomasz Napierala 			xo_close_instance("session");
511009ea47eSEdward Tomasz Napierala 		}
51201d54ad2SEdward Tomasz Napierala 		xo_close_list("session");
513009ea47eSEdward Tomasz Napierala 	} else {
51401d54ad2SEdward Tomasz Napierala 		xo_emit("{T:/%-36s} {T:/%-16s} {T:/%s}\n",
515abec6193SEdward Tomasz Napierala 		    "Target name", "Target portal", "State");
51601d54ad2SEdward Tomasz Napierala 
51701d54ad2SEdward Tomasz Napierala 		if (isl.isl_nentries != 0)
51801d54ad2SEdward Tomasz Napierala 			xo_open_list("session");
519009ea47eSEdward Tomasz Napierala 		for (i = 0; i < isl.isl_nentries; i++) {
52001d54ad2SEdward Tomasz Napierala 
521009ea47eSEdward Tomasz Napierala 			state = &states[i];
522009ea47eSEdward Tomasz Napierala 			conf = &state->iss_conf;
523009ea47eSEdward Tomasz Napierala 
52401d54ad2SEdward Tomasz Napierala 			xo_open_instance("session");
52501d54ad2SEdward Tomasz Napierala 			xo_emit("{V:name/%-36s/%s} {V:portal/%-16s/%s} ",
526009ea47eSEdward Tomasz Napierala 			    conf->isc_target, conf->isc_target_addr);
527009ea47eSEdward Tomasz Napierala 
528be3d357eSEdward Tomasz Napierala 			if (state->iss_reason[0] != '\0' &&
529be3d357eSEdward Tomasz Napierala 			    conf->isc_enable != 0) {
53001d54ad2SEdward Tomasz Napierala 				xo_emit("{V:state/%s}\n", state->iss_reason);
531009ea47eSEdward Tomasz Napierala 			} else {
532009ea47eSEdward Tomasz Napierala 				if (conf->isc_discovery) {
53301d54ad2SEdward Tomasz Napierala 					xo_emit("{V:state}\n", "Discovery");
534ba165a31SEdward Tomasz Napierala 				} else if (conf->isc_enable == 0) {
535ba165a31SEdward Tomasz Napierala 					xo_emit("{V:state}\n", "Disabled");
536009ea47eSEdward Tomasz Napierala 				} else if (state->iss_connected) {
53701d54ad2SEdward Tomasz Napierala 					xo_emit("{V:state}: ", "Connected");
538009ea47eSEdward Tomasz Napierala 					print_periphs(state->iss_id);
53901d54ad2SEdward Tomasz Napierala 					xo_emit("\n");
540009ea47eSEdward Tomasz Napierala 				} else {
54101d54ad2SEdward Tomasz Napierala 					xo_emit("{V:state}\n", "Disconnected");
542009ea47eSEdward Tomasz Napierala 				}
543009ea47eSEdward Tomasz Napierala 			}
54401d54ad2SEdward Tomasz Napierala 			xo_close_instance("session");
545009ea47eSEdward Tomasz Napierala 		}
54601d54ad2SEdward Tomasz Napierala 		if (isl.isl_nentries != 0)
54701d54ad2SEdward Tomasz Napierala 			xo_close_list("session");
548009ea47eSEdward Tomasz Napierala 	}
549009ea47eSEdward Tomasz Napierala 
550009ea47eSEdward Tomasz Napierala 	return (0);
551009ea47eSEdward Tomasz Napierala }
552009ea47eSEdward Tomasz Napierala 
5531dba27c1SEdward Tomasz Napierala static int
5541dba27c1SEdward Tomasz Napierala kernel_wait(int iscsi_fd, int timeout)
5551dba27c1SEdward Tomasz Napierala {
5561dba27c1SEdward Tomasz Napierala 	struct iscsi_session_state *states = NULL;
5571dba27c1SEdward Tomasz Napierala 	const struct iscsi_session_state *state;
5581dba27c1SEdward Tomasz Napierala 	struct iscsi_session_list isl;
5591dba27c1SEdward Tomasz Napierala 	unsigned int i, nentries = 1;
5601dba27c1SEdward Tomasz Napierala 	bool all_connected;
5611dba27c1SEdward Tomasz Napierala 	int error;
5621dba27c1SEdward Tomasz Napierala 
5631dba27c1SEdward Tomasz Napierala 	for (;;) {
5641dba27c1SEdward Tomasz Napierala 		for (;;) {
5651dba27c1SEdward Tomasz Napierala 			states = realloc(states,
5661dba27c1SEdward Tomasz Napierala 			    nentries * sizeof(struct iscsi_session_state));
5671dba27c1SEdward Tomasz Napierala 			if (states == NULL)
5681dba27c1SEdward Tomasz Napierala 				xo_err(1, "realloc");
5691dba27c1SEdward Tomasz Napierala 
5701dba27c1SEdward Tomasz Napierala 			memset(&isl, 0, sizeof(isl));
5711dba27c1SEdward Tomasz Napierala 			isl.isl_nentries = nentries;
5721dba27c1SEdward Tomasz Napierala 			isl.isl_pstates = states;
5731dba27c1SEdward Tomasz Napierala 
5741dba27c1SEdward Tomasz Napierala 			error = ioctl(iscsi_fd, ISCSISLIST, &isl);
5751dba27c1SEdward Tomasz Napierala 			if (error != 0 && errno == EMSGSIZE) {
5761dba27c1SEdward Tomasz Napierala 				nentries *= 4;
5771dba27c1SEdward Tomasz Napierala 				continue;
5781dba27c1SEdward Tomasz Napierala 			}
5791dba27c1SEdward Tomasz Napierala 			break;
5801dba27c1SEdward Tomasz Napierala 		}
5811dba27c1SEdward Tomasz Napierala 		if (error != 0) {
5821dba27c1SEdward Tomasz Napierala 			xo_warn("ISCSISLIST");
5831dba27c1SEdward Tomasz Napierala 			return (error);
5841dba27c1SEdward Tomasz Napierala 		}
5851dba27c1SEdward Tomasz Napierala 
5861dba27c1SEdward Tomasz Napierala 		all_connected = true;
5871dba27c1SEdward Tomasz Napierala 		for (i = 0; i < isl.isl_nentries; i++) {
5881dba27c1SEdward Tomasz Napierala 			state = &states[i];
5891dba27c1SEdward Tomasz Napierala 
5901dba27c1SEdward Tomasz Napierala 			if (!state->iss_connected) {
5911dba27c1SEdward Tomasz Napierala 				all_connected = false;
5921dba27c1SEdward Tomasz Napierala 				break;
5931dba27c1SEdward Tomasz Napierala 			}
5941dba27c1SEdward Tomasz Napierala 		}
5951dba27c1SEdward Tomasz Napierala 
5961dba27c1SEdward Tomasz Napierala 		if (all_connected)
5971dba27c1SEdward Tomasz Napierala 			return (0);
5981dba27c1SEdward Tomasz Napierala 
5991dba27c1SEdward Tomasz Napierala 		sleep(1);
6001dba27c1SEdward Tomasz Napierala 
6011dba27c1SEdward Tomasz Napierala 		if (timeout > 0) {
6021dba27c1SEdward Tomasz Napierala 			timeout--;
6031dba27c1SEdward Tomasz Napierala 			if (timeout == 0)
6041dba27c1SEdward Tomasz Napierala 				return (1);
6051dba27c1SEdward Tomasz Napierala 		}
6061dba27c1SEdward Tomasz Napierala 	}
6071dba27c1SEdward Tomasz Napierala }
6081dba27c1SEdward Tomasz Napierala 
609009ea47eSEdward Tomasz Napierala static void
610009ea47eSEdward Tomasz Napierala usage(void)
611009ea47eSEdward Tomasz Napierala {
612009ea47eSEdward Tomasz Napierala 
61300f003daSYan-Hao Wang 	xo_error("usage: iscsictl -A -p portal -t target "
614ba165a31SEdward Tomasz Napierala 	    "[-u user -s secret] [-w timeout] [-e on | off]\n");
61500f003daSYan-Hao Wang 	xo_error("       iscsictl -A -d discovery-host "
616ba165a31SEdward Tomasz Napierala 	    "[-u user -s secret] [-e on | off]\n");
61700f003daSYan-Hao Wang 	xo_error("       iscsictl -A -a [-c path]\n");
61800f003daSYan-Hao Wang 	xo_error("       iscsictl -A -n nickname [-c path]\n");
61900f003daSYan-Hao Wang 	xo_error("       iscsictl -M -i session-id [-p portal] "
620ba165a31SEdward Tomasz Napierala 	    "[-t target] [-u user] [-s secret] [-e on | off]\n");
62100f003daSYan-Hao Wang 	xo_error("       iscsictl -M -i session-id -n nickname "
6220262f2e0SEdward Tomasz Napierala 	    "[-c path]\n");
62300f003daSYan-Hao Wang 	xo_error("       iscsictl -R [-p portal] [-t target]\n");
62400f003daSYan-Hao Wang 	xo_error("       iscsictl -R -a\n");
62500f003daSYan-Hao Wang 	xo_error("       iscsictl -R -n nickname [-c path]\n");
62600f003daSYan-Hao Wang 	xo_error("       iscsictl -L [-v] [-w timeout]\n");
627009ea47eSEdward Tomasz Napierala 	exit(1);
628009ea47eSEdward Tomasz Napierala }
629009ea47eSEdward Tomasz Napierala 
630009ea47eSEdward Tomasz Napierala int
631009ea47eSEdward Tomasz Napierala main(int argc, char **argv)
632009ea47eSEdward Tomasz Napierala {
633b0b3f0e1SEdward Tomasz Napierala 	int Aflag = 0, Mflag = 0, Rflag = 0, Lflag = 0, aflag = 0,
634b0b3f0e1SEdward Tomasz Napierala 	    rflag = 0, vflag = 0;
635009ea47eSEdward Tomasz Napierala 	const char *conf_path = DEFAULT_CONFIG_PATH;
6364d478469SEdward Tomasz Napierala 	char *nickname = NULL, *discovery_host = NULL, *portal = NULL,
637009ea47eSEdward Tomasz Napierala 	    *target = NULL, *user = NULL, *secret = NULL;
638ba165a31SEdward Tomasz Napierala 	int timeout = -1, enable = ENABLE_UNSPECIFIED;
6390262f2e0SEdward Tomasz Napierala 	long long session_id = -1;
6400262f2e0SEdward Tomasz Napierala 	char *end;
641c76e8a9aSEdward Tomasz Napierala 	int ch, error, iscsi_fd, retval, saved_errno;
642009ea47eSEdward Tomasz Napierala 	int failed = 0;
643009ea47eSEdward Tomasz Napierala 	struct conf *conf;
644009ea47eSEdward Tomasz Napierala 	struct target *targ;
645009ea47eSEdward Tomasz Napierala 
64601d54ad2SEdward Tomasz Napierala 	argc = xo_parse_args(argc, argv);
647ef7d10fdSPhil Shafer 	if (argc < 0)
648ef7d10fdSPhil Shafer 		exit(1);
649ef7d10fdSPhil Shafer 
65031ac8806SBram 	xo_set_version(ISCSICTL_XO_VERSION);
65101d54ad2SEdward Tomasz Napierala 	xo_open_container("iscsictl");
65201d54ad2SEdward Tomasz Napierala 
653ba165a31SEdward Tomasz Napierala 	while ((ch = getopt(argc, argv, "AMRLac:d:e:i:n:p:rt:u:s:vw:")) != -1) {
654009ea47eSEdward Tomasz Napierala 		switch (ch) {
655009ea47eSEdward Tomasz Napierala 		case 'A':
656009ea47eSEdward Tomasz Napierala 			Aflag = 1;
657009ea47eSEdward Tomasz Napierala 			break;
6580262f2e0SEdward Tomasz Napierala 		case 'M':
6590262f2e0SEdward Tomasz Napierala 			Mflag = 1;
6600262f2e0SEdward Tomasz Napierala 			break;
661009ea47eSEdward Tomasz Napierala 		case 'R':
662009ea47eSEdward Tomasz Napierala 			Rflag = 1;
663009ea47eSEdward Tomasz Napierala 			break;
664009ea47eSEdward Tomasz Napierala 		case 'L':
665009ea47eSEdward Tomasz Napierala 			Lflag = 1;
666009ea47eSEdward Tomasz Napierala 			break;
667009ea47eSEdward Tomasz Napierala 		case 'a':
668009ea47eSEdward Tomasz Napierala 			aflag = 1;
669009ea47eSEdward Tomasz Napierala 			break;
670009ea47eSEdward Tomasz Napierala 		case 'c':
671009ea47eSEdward Tomasz Napierala 			conf_path = optarg;
672009ea47eSEdward Tomasz Napierala 			break;
673009ea47eSEdward Tomasz Napierala 		case 'd':
674009ea47eSEdward Tomasz Napierala 			discovery_host = optarg;
675009ea47eSEdward Tomasz Napierala 			break;
676ba165a31SEdward Tomasz Napierala 		case 'e':
677ba165a31SEdward Tomasz Napierala 			enable = parse_enable(optarg);
678ba165a31SEdward Tomasz Napierala 			if (enable == ENABLE_UNSPECIFIED) {
679ba165a31SEdward Tomasz Napierala 				xo_errx(1, "invalid argument to -e, "
680ba165a31SEdward Tomasz Napierala 				    "must be either \"on\" or \"off\"");
681ba165a31SEdward Tomasz Napierala 			}
682ba165a31SEdward Tomasz Napierala 			break;
6830262f2e0SEdward Tomasz Napierala 		case 'i':
6840262f2e0SEdward Tomasz Napierala 			session_id = strtol(optarg, &end, 10);
6850262f2e0SEdward Tomasz Napierala 			if ((size_t)(end - optarg) != strlen(optarg))
68601d54ad2SEdward Tomasz Napierala 				xo_errx(1, "trailing characters after session-id");
6870262f2e0SEdward Tomasz Napierala 			if (session_id < 0)
68801d54ad2SEdward Tomasz Napierala 				xo_errx(1, "session-id cannot be negative");
6890262f2e0SEdward Tomasz Napierala 			if (session_id > UINT_MAX)
69001d54ad2SEdward Tomasz Napierala 				xo_errx(1, "session-id cannot be greater than %u",
6910262f2e0SEdward Tomasz Napierala 				    UINT_MAX);
6920262f2e0SEdward Tomasz Napierala 			break;
693009ea47eSEdward Tomasz Napierala 		case 'n':
694009ea47eSEdward Tomasz Napierala 			nickname = optarg;
695009ea47eSEdward Tomasz Napierala 			break;
696abec6193SEdward Tomasz Napierala 		case 'p':
6974d478469SEdward Tomasz Napierala 			portal = optarg;
698009ea47eSEdward Tomasz Napierala 			break;
699b0b3f0e1SEdward Tomasz Napierala 		case 'r':
700b0b3f0e1SEdward Tomasz Napierala 			rflag = 1;
701b0b3f0e1SEdward Tomasz Napierala 			break;
702009ea47eSEdward Tomasz Napierala 		case 't':
703009ea47eSEdward Tomasz Napierala 			target = optarg;
704009ea47eSEdward Tomasz Napierala 			break;
705009ea47eSEdward Tomasz Napierala 		case 'u':
706009ea47eSEdward Tomasz Napierala 			user = optarg;
707009ea47eSEdward Tomasz Napierala 			break;
708009ea47eSEdward Tomasz Napierala 		case 's':
709009ea47eSEdward Tomasz Napierala 			secret = optarg;
710009ea47eSEdward Tomasz Napierala 			break;
711009ea47eSEdward Tomasz Napierala 		case 'v':
712009ea47eSEdward Tomasz Napierala 			vflag = 1;
713009ea47eSEdward Tomasz Napierala 			break;
7141dba27c1SEdward Tomasz Napierala 		case 'w':
7151dba27c1SEdward Tomasz Napierala 			timeout = strtol(optarg, &end, 10);
7161dba27c1SEdward Tomasz Napierala 			if ((size_t)(end - optarg) != strlen(optarg))
7171dba27c1SEdward Tomasz Napierala 				xo_errx(1, "trailing characters after timeout");
7181dba27c1SEdward Tomasz Napierala 			if (timeout < 0)
7191dba27c1SEdward Tomasz Napierala 				xo_errx(1, "timeout cannot be negative");
7201dba27c1SEdward Tomasz Napierala 			break;
721009ea47eSEdward Tomasz Napierala 		case '?':
722009ea47eSEdward Tomasz Napierala 		default:
723009ea47eSEdward Tomasz Napierala 			usage();
724009ea47eSEdward Tomasz Napierala 		}
725009ea47eSEdward Tomasz Napierala 	}
726009ea47eSEdward Tomasz Napierala 	argc -= optind;
727009ea47eSEdward Tomasz Napierala 	if (argc != 0)
728009ea47eSEdward Tomasz Napierala 		usage();
729009ea47eSEdward Tomasz Napierala 
7300262f2e0SEdward Tomasz Napierala 	if (Aflag + Mflag + Rflag + Lflag == 0)
731009ea47eSEdward Tomasz Napierala 		Lflag = 1;
7320262f2e0SEdward Tomasz Napierala 	if (Aflag + Mflag + Rflag + Lflag > 1)
73301d54ad2SEdward Tomasz Napierala 		xo_errx(1, "at most one of -A, -M, -R, or -L may be specified");
734009ea47eSEdward Tomasz Napierala 
735009ea47eSEdward Tomasz Napierala 	/*
736af7ca7c8SPedro F. Giffuni 	 * Note that we ignore unnecessary/inapplicable "-c" flag; so that
737009ea47eSEdward Tomasz Napierala 	 * people can do something like "alias ISCSICTL="iscsictl -c path"
738009ea47eSEdward Tomasz Napierala 	 * in shell scripts.
739009ea47eSEdward Tomasz Napierala 	 */
740009ea47eSEdward Tomasz Napierala 	if (Aflag != 0) {
741009ea47eSEdward Tomasz Napierala 		if (aflag != 0) {
742ba165a31SEdward Tomasz Napierala 			if (enable != ENABLE_UNSPECIFIED)
74337ab1314SNiclas Zeising 				xo_errx(1, "-a and -e are mutually exclusive");
7444d478469SEdward Tomasz Napierala 			if (portal != NULL)
74537ab1314SNiclas Zeising 				xo_errx(1, "-a and -p are mutually exclusive");
746009ea47eSEdward Tomasz Napierala 			if (target != NULL)
74737ab1314SNiclas Zeising 				xo_errx(1, "-a and -t are mutually exclusive");
748009ea47eSEdward Tomasz Napierala 			if (user != NULL)
74937ab1314SNiclas Zeising 				xo_errx(1, "-a and -u are mutually exclusive");
750009ea47eSEdward Tomasz Napierala 			if (secret != NULL)
75137ab1314SNiclas Zeising 				xo_errx(1, "-a and -s are mutually exclusive");
752009ea47eSEdward Tomasz Napierala 			if (nickname != NULL)
75337ab1314SNiclas Zeising 				xo_errx(1, "-a and -n are mutually exclusive");
754009ea47eSEdward Tomasz Napierala 			if (discovery_host != NULL)
75537ab1314SNiclas Zeising 				xo_errx(1, "-a and -d are mutually exclusive");
756b0b3f0e1SEdward Tomasz Napierala 			if (rflag != 0)
75737ab1314SNiclas Zeising 				xo_errx(1, "-a and -r are mutually exclusive");
758009ea47eSEdward Tomasz Napierala 		} else if (nickname != NULL) {
759ba165a31SEdward Tomasz Napierala 			if (enable != ENABLE_UNSPECIFIED)
76037ab1314SNiclas Zeising 				xo_errx(1, "-n and -e are mutually exclusive");
7614d478469SEdward Tomasz Napierala 			if (portal != NULL)
76237ab1314SNiclas Zeising 				xo_errx(1, "-n and -p are mutually exclusive");
763009ea47eSEdward Tomasz Napierala 			if (target != NULL)
76437ab1314SNiclas Zeising 				xo_errx(1, "-n and -t are mutually exclusive");
765009ea47eSEdward Tomasz Napierala 			if (user != NULL)
76637ab1314SNiclas Zeising 				xo_errx(1, "-n and -u are mutually exclusive");
767009ea47eSEdward Tomasz Napierala 			if (secret != NULL)
76837ab1314SNiclas Zeising 				xo_errx(1, "-n and -s are mutually exclusive");
769009ea47eSEdward Tomasz Napierala 			if (discovery_host != NULL)
77037ab1314SNiclas Zeising 				xo_errx(1, "-n and -d are mutually exclusive");
771b0b3f0e1SEdward Tomasz Napierala 			if (rflag != 0)
77237ab1314SNiclas Zeising 				xo_errx(1, "-n and -r are mutually exclusive");
773009ea47eSEdward Tomasz Napierala 		} else if (discovery_host != NULL) {
7744d478469SEdward Tomasz Napierala 			if (portal != NULL)
77537ab1314SNiclas Zeising 				xo_errx(1, "-d and -p are mutually exclusive");
776009ea47eSEdward Tomasz Napierala 			if (target != NULL)
77737ab1314SNiclas Zeising 				xo_errx(1, "-d and -t are mutually exclusive");
778009ea47eSEdward Tomasz Napierala 		} else {
7794d478469SEdward Tomasz Napierala 			if (target == NULL && portal == NULL)
78001d54ad2SEdward Tomasz Napierala 				xo_errx(1, "must specify -a, -n or -t/-p");
781009ea47eSEdward Tomasz Napierala 
7824d478469SEdward Tomasz Napierala 			if (target != NULL && portal == NULL)
78301d54ad2SEdward Tomasz Napierala 				xo_errx(1, "-t must always be used with -p");
7844d478469SEdward Tomasz Napierala 			if (portal != NULL && target == NULL)
78501d54ad2SEdward Tomasz Napierala 				xo_errx(1, "-p must always be used with -t");
786009ea47eSEdward Tomasz Napierala 		}
787009ea47eSEdward Tomasz Napierala 
788009ea47eSEdward Tomasz Napierala 		if (user != NULL && secret == NULL)
78901d54ad2SEdward Tomasz Napierala 			xo_errx(1, "-u must always be used with -s");
790009ea47eSEdward Tomasz Napierala 		if (secret != NULL && user == NULL)
79101d54ad2SEdward Tomasz Napierala 			xo_errx(1, "-s must always be used with -u");
792009ea47eSEdward Tomasz Napierala 
7930262f2e0SEdward Tomasz Napierala 		if (session_id != -1)
79401d54ad2SEdward Tomasz Napierala 			xo_errx(1, "-i cannot be used with -A");
795009ea47eSEdward Tomasz Napierala 		if (vflag != 0)
79601d54ad2SEdward Tomasz Napierala 			xo_errx(1, "-v cannot be used with -A");
797009ea47eSEdward Tomasz Napierala 
7980262f2e0SEdward Tomasz Napierala 	} else if (Mflag != 0) {
7990262f2e0SEdward Tomasz Napierala 		if (session_id == -1)
80001d54ad2SEdward Tomasz Napierala 			xo_errx(1, "-M requires -i");
8010262f2e0SEdward Tomasz Napierala 
8020262f2e0SEdward Tomasz Napierala 		if (nickname != NULL) {
803ba165a31SEdward Tomasz Napierala 			if (enable != ENABLE_UNSPECIFIED)
80437ab1314SNiclas Zeising 				xo_errx(1, "-n and -e are mutually exclusive");
8054d478469SEdward Tomasz Napierala 			if (portal != NULL)
80637ab1314SNiclas Zeising 				xo_errx(1, "-n and -p are mutually exclusive");
8070262f2e0SEdward Tomasz Napierala 			if (target != NULL)
80837ab1314SNiclas Zeising 				xo_errx(1, "-n and -t are mutually exclusive");
8090262f2e0SEdward Tomasz Napierala 			if (user != NULL)
81037ab1314SNiclas Zeising 				xo_errx(1, "-n and -u are mutually exclusive");
8110262f2e0SEdward Tomasz Napierala 			if (secret != NULL)
81237ab1314SNiclas Zeising 				xo_errx(1, "-n and -s are mutually exclusive");
8130262f2e0SEdward Tomasz Napierala 		}
8140262f2e0SEdward Tomasz Napierala 
815806ea85aSEdward Tomasz Napierala 		if (aflag != 0)
816806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-a cannot be used with -M");
817806ea85aSEdward Tomasz Napierala 		if (discovery_host != NULL)
818806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-d cannot be used with -M");
819b0b3f0e1SEdward Tomasz Napierala 		if (rflag != 0)
820b0b3f0e1SEdward Tomasz Napierala 			xo_errx(1, "-r cannot be used with -M");
8210262f2e0SEdward Tomasz Napierala 		if (vflag != 0)
82201d54ad2SEdward Tomasz Napierala 			xo_errx(1, "-v cannot be used with -M");
8231dba27c1SEdward Tomasz Napierala 		if (timeout != -1)
8241dba27c1SEdward Tomasz Napierala 			xo_errx(1, "-w cannot be used with -M");
8250262f2e0SEdward Tomasz Napierala 
826009ea47eSEdward Tomasz Napierala 	} else if (Rflag != 0) {
827009ea47eSEdward Tomasz Napierala 		if (aflag != 0) {
8284d478469SEdward Tomasz Napierala 			if (portal != NULL)
82937ab1314SNiclas Zeising 				xo_errx(1, "-a and -p are mutually exclusive");
830009ea47eSEdward Tomasz Napierala 			if (target != NULL)
83137ab1314SNiclas Zeising 				xo_errx(1, "-a and -t are mutually exclusive");
832009ea47eSEdward Tomasz Napierala 			if (nickname != NULL)
83337ab1314SNiclas Zeising 				xo_errx(1, "-a and -n are mutually exclusive");
834009ea47eSEdward Tomasz Napierala 		} else if (nickname != NULL) {
8354d478469SEdward Tomasz Napierala 			if (portal != NULL)
83637ab1314SNiclas Zeising 				xo_errx(1, "-n and -p are mutually exclusive");
837009ea47eSEdward Tomasz Napierala 			if (target != NULL)
83837ab1314SNiclas Zeising 				xo_errx(1, "-n and -t are mutually exclusive");
839c7ee47a7SEdward Tomasz Napierala 		} else if (target == NULL && portal == NULL) {
84001d54ad2SEdward Tomasz Napierala 			xo_errx(1, "must specify either -a, -n, -t, or -p");
841c7ee47a7SEdward Tomasz Napierala 		}
842009ea47eSEdward Tomasz Napierala 
843806ea85aSEdward Tomasz Napierala 		if (discovery_host != NULL)
844806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-d cannot be used with -R");
845ba165a31SEdward Tomasz Napierala 		if (enable != ENABLE_UNSPECIFIED)
846ba165a31SEdward Tomasz Napierala 			xo_errx(1, "-e cannot be used with -R");
8470262f2e0SEdward Tomasz Napierala 		if (session_id != -1)
84801d54ad2SEdward Tomasz Napierala 			xo_errx(1, "-i cannot be used with -R");
849b0b3f0e1SEdward Tomasz Napierala 		if (rflag != 0)
850b0b3f0e1SEdward Tomasz Napierala 			xo_errx(1, "-r cannot be used with -R");
851806ea85aSEdward Tomasz Napierala 		if (user != NULL)
852806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-u cannot be used with -R");
853806ea85aSEdward Tomasz Napierala 		if (secret != NULL)
854806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-s cannot be used with -R");
855009ea47eSEdward Tomasz Napierala 		if (vflag != 0)
85601d54ad2SEdward Tomasz Napierala 			xo_errx(1, "-v cannot be used with -R");
8571dba27c1SEdward Tomasz Napierala 		if (timeout != -1)
8581dba27c1SEdward Tomasz Napierala 			xo_errx(1, "-w cannot be used with -R");
859009ea47eSEdward Tomasz Napierala 
860009ea47eSEdward Tomasz Napierala 	} else {
861009ea47eSEdward Tomasz Napierala 		assert(Lflag != 0);
862009ea47eSEdward Tomasz Napierala 
863009ea47eSEdward Tomasz Napierala 		if (discovery_host != NULL)
864806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-d cannot be used with -L");
8650262f2e0SEdward Tomasz Napierala 		if (session_id != -1)
86601d54ad2SEdward Tomasz Napierala 			xo_errx(1, "-i cannot be used with -L");
867806ea85aSEdward Tomasz Napierala 		if (nickname != NULL)
868806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-n cannot be used with -L");
869806ea85aSEdward Tomasz Napierala 		if (portal != NULL)
870806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-p cannot be used with -L");
871806ea85aSEdward Tomasz Napierala 		if (rflag != 0)
872806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-r cannot be used with -L");
873806ea85aSEdward Tomasz Napierala 		if (target != NULL)
874806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-t cannot be used with -L");
875806ea85aSEdward Tomasz Napierala 		if (user != NULL)
876806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-u cannot be used with -L");
877806ea85aSEdward Tomasz Napierala 		if (secret != NULL)
878806ea85aSEdward Tomasz Napierala 			xo_errx(1, "-s cannot be used with -L");
879009ea47eSEdward Tomasz Napierala 	}
880009ea47eSEdward Tomasz Napierala 
881009ea47eSEdward Tomasz Napierala 	iscsi_fd = open(ISCSI_PATH, O_RDWR);
882c76e8a9aSEdward Tomasz Napierala 	if (iscsi_fd < 0 && errno == ENOENT) {
883c76e8a9aSEdward Tomasz Napierala 		saved_errno = errno;
884c76e8a9aSEdward Tomasz Napierala 		retval = kldload("iscsi");
885c76e8a9aSEdward Tomasz Napierala 		if (retval != -1)
886c76e8a9aSEdward Tomasz Napierala 			iscsi_fd = open(ISCSI_PATH, O_RDWR);
887c76e8a9aSEdward Tomasz Napierala 		else
888c76e8a9aSEdward Tomasz Napierala 			errno = saved_errno;
889c76e8a9aSEdward Tomasz Napierala 	}
890009ea47eSEdward Tomasz Napierala 	if (iscsi_fd < 0)
89101d54ad2SEdward Tomasz Napierala 		xo_err(1, "failed to open %s", ISCSI_PATH);
892009ea47eSEdward Tomasz Napierala 
893009ea47eSEdward Tomasz Napierala 	if (Aflag != 0 && aflag != 0) {
894009ea47eSEdward Tomasz Napierala 		conf = conf_new_from_file(conf_path);
895009ea47eSEdward Tomasz Napierala 
896009ea47eSEdward Tomasz Napierala 		TAILQ_FOREACH(targ, &conf->conf_targets, t_next)
897009ea47eSEdward Tomasz Napierala 			failed += kernel_add(iscsi_fd, targ);
898009ea47eSEdward Tomasz Napierala 	} else if (nickname != NULL) {
899009ea47eSEdward Tomasz Napierala 		conf = conf_new_from_file(conf_path);
900009ea47eSEdward Tomasz Napierala 		targ = target_find(conf, nickname);
901009ea47eSEdward Tomasz Napierala 		if (targ == NULL)
90201d54ad2SEdward Tomasz Napierala 			xo_errx(1, "target %s not found in %s",
9030262f2e0SEdward Tomasz Napierala 			    nickname, conf_path);
904009ea47eSEdward Tomasz Napierala 
905009ea47eSEdward Tomasz Napierala 		if (Aflag != 0)
906009ea47eSEdward Tomasz Napierala 			failed += kernel_add(iscsi_fd, targ);
9070262f2e0SEdward Tomasz Napierala 		else if (Mflag != 0)
9080262f2e0SEdward Tomasz Napierala 			failed += kernel_modify(iscsi_fd, session_id, targ);
909009ea47eSEdward Tomasz Napierala 		else if (Rflag != 0)
910009ea47eSEdward Tomasz Napierala 			failed += kernel_remove(iscsi_fd, targ);
911009ea47eSEdward Tomasz Napierala 		else
912009ea47eSEdward Tomasz Napierala 			failed += kernel_list(iscsi_fd, targ, vflag);
9130262f2e0SEdward Tomasz Napierala 	} else if (Mflag != 0) {
9144d478469SEdward Tomasz Napierala 		kernel_modify_some(iscsi_fd, session_id, target, portal,
915ba165a31SEdward Tomasz Napierala 		    user, secret, enable);
916009ea47eSEdward Tomasz Napierala 	} else {
917009ea47eSEdward Tomasz Napierala 		if (Aflag != 0 && target != NULL) {
918*dd360374SJohn Baldwin 			if (valid_iscsi_name(target, xo_warnx) == false)
91901d54ad2SEdward Tomasz Napierala 				xo_errx(1, "invalid target name \"%s\"", target);
920009ea47eSEdward Tomasz Napierala 		}
921009ea47eSEdward Tomasz Napierala 		conf = conf_new();
922009ea47eSEdward Tomasz Napierala 		targ = target_new(conf);
923009ea47eSEdward Tomasz Napierala 		targ->t_initiator_name = default_initiator_name();
924009ea47eSEdward Tomasz Napierala 		targ->t_header_digest = DIGEST_NONE;
925009ea47eSEdward Tomasz Napierala 		targ->t_data_digest = DIGEST_NONE;
926009ea47eSEdward Tomasz Napierala 		targ->t_name = target;
927009ea47eSEdward Tomasz Napierala 		if (discovery_host != NULL) {
928009ea47eSEdward Tomasz Napierala 			targ->t_session_type = SESSION_TYPE_DISCOVERY;
929009ea47eSEdward Tomasz Napierala 			targ->t_address = discovery_host;
930009ea47eSEdward Tomasz Napierala 		} else {
931009ea47eSEdward Tomasz Napierala 			targ->t_session_type = SESSION_TYPE_NORMAL;
9324d478469SEdward Tomasz Napierala 			targ->t_address = portal;
933009ea47eSEdward Tomasz Napierala 		}
934ba165a31SEdward Tomasz Napierala 		targ->t_enable = enable;
935b0b3f0e1SEdward Tomasz Napierala 		if (rflag != 0)
936b0b3f0e1SEdward Tomasz Napierala 			targ->t_protocol = PROTOCOL_ISER;
937009ea47eSEdward Tomasz Napierala 		targ->t_user = user;
938009ea47eSEdward Tomasz Napierala 		targ->t_secret = secret;
939009ea47eSEdward Tomasz Napierala 
940009ea47eSEdward Tomasz Napierala 		if (Aflag != 0)
941009ea47eSEdward Tomasz Napierala 			failed += kernel_add(iscsi_fd, targ);
942009ea47eSEdward Tomasz Napierala 		else if (Rflag != 0)
943009ea47eSEdward Tomasz Napierala 			failed += kernel_remove(iscsi_fd, targ);
944009ea47eSEdward Tomasz Napierala 		else
945009ea47eSEdward Tomasz Napierala 			failed += kernel_list(iscsi_fd, targ, vflag);
946009ea47eSEdward Tomasz Napierala 	}
947009ea47eSEdward Tomasz Napierala 
9481dba27c1SEdward Tomasz Napierala 	if (timeout != -1)
9491dba27c1SEdward Tomasz Napierala 		failed += kernel_wait(iscsi_fd, timeout);
9501dba27c1SEdward Tomasz Napierala 
951009ea47eSEdward Tomasz Napierala 	error = close(iscsi_fd);
952009ea47eSEdward Tomasz Napierala 	if (error != 0)
95301d54ad2SEdward Tomasz Napierala 		xo_err(1, "close");
954009ea47eSEdward Tomasz Napierala 
95554fc4636SEdward Tomasz Napierala 	xo_close_container("iscsictl");
95600f003daSYan-Hao Wang 	if (xo_finish() < 0)
95700f003daSYan-Hao Wang 		xo_err(1, "stdout");
95854fc4636SEdward Tomasz Napierala 
959aa63d825SEdward Tomasz Napierala 	if (failed != 0)
96000f003daSYan-Hao Wang 		exit(1);
96101d54ad2SEdward Tomasz Napierala 
96200f003daSYan-Hao Wang 	exit(0);
963009ea47eSEdward Tomasz Napierala }
964