/* $NetBSD: iscsic_daemonif.c,v 1.3 2015/05/30 15:57:32 joerg Exp $ */
/*-
* Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "iscsic_globals.h"
/*
* do_add_target:
* Handle both the add_target and add_send_target commands.
*
* Parameter:
* argc, argv Shifted arguments
* kind Which list
*
* Returns: 0 if OK - else it doesn't return at all.
*/
STATIC int
do_add_target(int argc, char **argv, iscsid_list_kind_t kind)
{
iscsid_add_target_req_t *targ;
iscsid_set_target_authentication_req_t auth;
iscsid_get_set_target_options_t opt;
iscsid_response_t *rsp;
iscsid_add_target_rsp_t *res;
unsigned i;
int opts, auths, tlen;
uint32_t tid;
tlen = cl_get_target(&targ, argc, argv, kind != SEND_TARGETS_LIST);
if (tlen == 0) {
arg_missing("Target");
}
if (kind == SEND_TARGETS_LIST && !targ->num_portals) {
arg_missing("Target Address");
}
opts = cl_get_target_opts(&opt, argc, argv);
auths = cl_get_auth_opts(&auth, argc, argv);
cl_get_symname(targ->sym_name, argc, argv);
check_extra_args(argc, argv);
targ->list_kind = kind;
send_request(ISCSID_ADD_TARGET, tlen, targ);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
res = (iscsid_add_target_rsp_t *)(void *)rsp->parameter;
tid = res->target_id;
if (kind == SEND_TARGETS_LIST) {
printf("Added Send Target %d\n", res->target_id);
} else {
printf("Added Target %d", res->target_id);
if (res->num_portals) {
printf(", Portal ");
for (i = 0; i < res->num_portals; i++)
printf("%d ", res->portal_id[i]);
}
printf("\n");
}
free_response(rsp);
if (opts) {
opt.list_kind = kind;
opt.target_id.id = tid;
send_request(ISCSID_SET_TARGET_OPTIONS, sizeof(opt), &opt);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
}
if (auths) {
auth.list_kind = kind;
auth.target_id.id = tid;
send_request(ISCSID_SET_TARGET_AUTHENTICATION, sizeof(auth), &auth);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
}
return 0;
}
/*
* do_remove_target:
* Handle both the remove_target and remove_send_target commands.
*
* Parameter:
* argc, argv Shifted arguments
* kind Which list
*
* Returns: 0 if OK - else it doesn't return at all.
*/
STATIC int
do_remove_target(int argc, char **argv, iscsid_list_kind_t kind)
{
iscsid_list_id_t req;
iscsid_search_list_req_t srch;
iscsid_response_t *rsp;
if (!cl_get_id('I', &req.id, argc, argv)) {
if (!cl_get_string('n', (char *)srch.strval, argc, argv)) {
arg_missing("Target ID or Name");
}
check_extra_args(argc, argv);
srch.search_kind = FIND_TARGET_NAME;
srch.list_kind = kind;
send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch);
rsp = get_response(FALSE);
if (rsp->status) {
status_error_slist(rsp->status);
}
GET_SYM_ID(req.id.id, rsp->parameter);
free_response(rsp);
} else {
check_extra_args(argc, argv);
}
req.list_kind = kind;
send_request(ISCSID_REMOVE_TARGET, sizeof(req), &req);
rsp = get_response(TRUE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
printf("OK\n");
return 0;
}
/*
* do_refresh:
* Handle the refresh_targets and refresh_isns commands.
*
* Parameter:
* argc, argv Shifted arguments
* kind Which list
*
* Returns: 0 if OK - else it doesn't return at all.
*/
STATIC int
do_refresh(int argc, char **argv, iscsid_list_kind_t kind)
{
iscsid_sym_id_t id;
iscsid_response_t *rsp;
iscsid_refresh_req_t req;
req.kind = kind;
if (cl_get_id('I', &id, argc, argv)) {
check_extra_args(argc, argv);
if (!id.id) {
iscsid_search_list_req_t srch;
srch.search_kind = FIND_NAME;
srch.list_kind = kind;
strlcpy((char *)srch.strval, (char *)id.name,
sizeof(srch.strval));
send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch);
rsp = get_response(FALSE);
if (rsp->status) {
status_error_slist(rsp->status);
}
GET_SYM_ID(req.id[0], rsp->parameter);
free_response(rsp);
} else {
req.id[0] = id.id;
}
req.num_ids = 1;
} else {
req.num_ids = 0;
check_extra_args(argc, argv);
}
req.kind = kind;
send_request(ISCSID_REFRESH_TARGETS, sizeof(req), &req);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
printf("OK\n");
free_response(rsp);
return 0;
}
/*
* add_target:
* Handle the add_target command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
add_target(int argc, char **argv)
{
return do_add_target(argc, argv, TARGET_LIST);
}
/*
* remove_target:
* Handle the remove_target command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
remove_target(int argc, char **argv)
{
return do_remove_target(argc, argv, TARGET_LIST);
}
/*
* slp_find_targets:
* Handle the slp_find_targets command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*
* ToDo: Implement.
*/
int
/*ARGSUSED*/
slp_find_targets(int argc, char **argv)
{
printf("Not implemented\n");
return 5;
}
/*
* refresh_targets:
* Handle the refresh_targets command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
refresh_targets(int argc, char **argv)
{
return do_refresh(argc, argv, SEND_TARGETS_LIST);
}
/*
* add_portal:
* Handle the add_portal command.
*
* Parameter:
* argc, argv Shifted arguments
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
add_portal(int argc, char **argv)
{
iscsid_add_portal_req_t port;
iscsid_response_t *rsp;
iscsid_add_portal_rsp_t *res;
if (!cl_get_portal(&port, argc, argv)) {
arg_missing("Portal Address");
}
if (!cl_get_id('I', &port.target_id, argc, argv)) {
arg_missing("Target ID");
}
cl_get_symname(port.sym_name, argc, argv);
check_extra_args(argc, argv);
send_request(ISCSID_ADD_PORTAL, sizeof(port), &port);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
res = (iscsid_add_portal_rsp_t *)(void *)rsp->parameter;
printf("Added Portal %d to Target %d\n",
res->portal_id.id, res->target_id.id);
free_response(rsp);
return 0;
}
/*
* show_target:
* Get information about and display a target entry (including its portals).
*
* Parameter:
* target ID
* list kind
*/
STATIC void
show_target(uint32_t id, iscsid_list_kind_t kind)
{
iscsid_list_id_t req;
iscsid_response_t *trsp, *prsp;
iscsid_get_target_rsp_t *targ;
iscsid_get_portal_rsp_t *port;
unsigned i;
/* get target info */
req.list_kind = kind;
req.id.id = id;
req.id.name[0] = '\0';
send_request(ISCSID_GET_TARGET_INFO, sizeof(req), &req);
trsp = get_response(TRUE);
if (trsp->status) {
status_error(trsp->status);
}
targ = (iscsid_get_target_rsp_t *)(void *)trsp->parameter;
/* display basic target info */
printf("%6d", targ->target_id.id);
if (targ->target_id.name[0]) {
printf(" [%s]", targ->target_id.name);
}
printf(": %s", targ->TargetName);
if (targ->TargetAlias[0]) {
printf(" (%s)", targ->TargetAlias);
}
printf("\n");
/* now get and display info on the target's portals */
for (i = 0; i < targ->num_portals; i++) {
req.id.id = targ->portal[i];
send_request(ISCSID_GET_PORTAL_INFO, sizeof(req), &req);
prsp = get_response(FALSE);
if (prsp->status) {
status_error(prsp->status);
}
port = (iscsid_get_portal_rsp_t *)(void *)prsp->parameter;
printf(" %6d", port->portal_id.id);
if (port->portal_id.name[0]) {
printf(" [%s]", port->portal_id.name);
}
printf(": %s:%d", port->portal.address, port->portal.port);
if (kind != SEND_TARGETS_LIST) {
printf(",%d", port->portal.group_tag);
}
printf("\n");
free_response(prsp);
}
free_response(trsp);
}
/*
* do_list_targets:
* Handle both the list_targets and list_send_targets commands.
*
* Parameter:
* argc, argv Shifted arguments
* kind Which list
*
* Returns: 0 if OK - else it doesn't return at all.
*/
STATIC int
do_list_targets(int argc, char **argv, iscsid_list_kind_t kind)
{
iscsid_get_list_req_t lst;
iscsid_response_t *rsp;
iscsid_get_list_rsp_t *list;
unsigned i;
check_extra_args(argc, argv);
/* get the list of targets */
lst.list_kind = kind;
send_request(ISCSID_GET_LIST, sizeof(lst), &lst);
rsp = get_response(TRUE);
if (rsp->status) {
status_error(rsp->status);
}
list = (iscsid_get_list_rsp_t *)(void *)rsp->parameter;
/* display all targets */
for (i = 0; i < list->num_entries; i++) {
show_target(list->id[i], kind);
}
free_response(rsp);
return 0;
}
/*
* list_targets:
* Handle the list_targets command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
list_targets(int argc, char **argv)
{
return do_list_targets(argc, argv, TARGET_LIST);
}
/*
* add_send_target:
* Handle the add_target command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
add_send_target(int argc, char **argv)
{
return do_add_target(argc, argv, SEND_TARGETS_LIST);
}
/*
* remove_send_target:
* Handle the remove_target command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
remove_send_target(int argc, char **argv)
{
return do_remove_target(argc, argv, SEND_TARGETS_LIST);
}
/*
* list_send_targets:
* Handle the list_send_targets command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
list_send_targets(int argc, char **argv)
{
return do_list_targets(argc, argv, SEND_TARGETS_LIST);
}
/*
* add_isns_server:
* Handle the add_isns_server command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
add_isns_server(int argc, char **argv)
{
iscsid_add_isns_server_req_t arg;
iscsid_add_isns_server_rsp_t *res;
iscsid_response_t *rsp;
memset(&arg, 0x0, sizeof(arg));
if (!(cl_get_isns(&arg, argc, argv))) {
arg_missing("Server Address");
}
check_extra_args(argc, argv);
send_request(ISCSID_ADD_ISNS_SERVER, sizeof(arg), &arg);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
res = (iscsid_add_isns_server_rsp_t *)(void *)rsp->parameter;
printf("Added iSNS Server ID %d\n", res->server_id);
free_response(rsp);
return 0;
}
/*
* remove_isns_server:
* Handle the add_isns_server command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
remove_isns_server(int argc, char **argv)
{
iscsid_sym_id_t req;
iscsid_search_list_req_t srch;
iscsid_response_t *rsp;
if (!cl_get_id('I', &req, argc, argv)) {
if (!cl_get_string('a', (char *)srch.strval, argc, argv)) {
arg_missing("Server Address");
}
check_extra_args(argc, argv);
srch.search_kind = FIND_ADDRESS;
srch.list_kind = ISNS_LIST;
send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch);
rsp = get_response(FALSE);
if (rsp->status) {
status_error_slist(rsp->status);
}
GET_SYM_ID(req.id, rsp->parameter);
free_response(rsp);
} else {
check_extra_args(argc, argv);
}
send_request(ISCSID_REMOVE_ISNS_SERVER, sizeof(req), &req);
rsp = get_response(TRUE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
printf("OK\n");
return 0;
}
/*
* find_isns_servers:
* Handle the find_isns_servers command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
/*ARGSUSED*/
find_isns_servers(int argc, char **argv)
{
printf("Not implemented\n");
return 5;
}
/*
* list_isns_servers:
* Handle the list_isns_servers command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
list_isns_servers(int argc, char **argv)
{
iscsid_get_list_req_t lst;
iscsid_response_t *rsp, *prsp;
iscsid_get_list_rsp_t *list;
iscsid_get_isns_server_rsp_t *isns;
iscsid_sym_id_t req;
unsigned i;
memset(&req, 0x0, sizeof(req));
check_extra_args(argc, argv);
/* get the list of servers */
lst.list_kind = ISNS_LIST;
send_request(ISCSID_GET_LIST, sizeof(lst), &lst);
rsp = get_response(TRUE);
if (rsp->status) {
status_error(rsp->status);
}
list = (iscsid_get_list_rsp_t *)(void *)rsp->parameter;
/* display all servers */
for (i = 0; i < list->num_entries; i++) {
req.id = list->id[i];
send_request(ISCSID_GET_ISNS_SERVER, sizeof(req), &req);
prsp = get_response(FALSE);
if (prsp->status)
status_error(prsp->status);
isns = (iscsid_get_isns_server_rsp_t *)(void *)prsp->parameter;
printf("%6d: %s\n", list->id[i], isns->address);
free_response(prsp);
}
free_response(rsp);
return 0;
}
/*
* refresh_isns:
* Handle the refresh_isns command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
refresh_isns(int argc, char **argv)
{
return do_refresh(argc, argv, ISNS_LIST);
}
/*
* add_initiator:
* Handle the add_initiator command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
add_initiator(int argc, char **argv)
{
iscsid_add_initiator_req_t req;
iscsid_add_initiator_rsp_t *res;
iscsid_response_t *rsp;
memset(&req, 0x0, sizeof(req));
if (!cl_get_string('a', (char *)req.address, argc, argv)) {
arg_missing("Interface Address");
}
cl_get_symname(req.name, argc, argv);
check_extra_args(argc, argv);
send_request(ISCSID_ADD_INITIATOR_PORTAL, sizeof(req), &req);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
res = (iscsid_add_initiator_rsp_t *)(void *)rsp->parameter;
printf("Added Initiator Portal %d\n", res->portal_id);
free_response(rsp);
return 0;
}
/*
* remove_initiator:
* Handle the remove_initiator command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
remove_initiator(int argc, char **argv)
{
iscsid_sym_id_t req;
iscsid_response_t *rsp;
memset(&req, 0x0, sizeof(req));
if (!cl_get_id('I', &req, argc, argv)) {
arg_missing("Initiator Portal ID");
}
check_extra_args(argc, argv);
send_request(ISCSID_REMOVE_INITIATOR_PORTAL, sizeof(req), &req);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
printf("OK\n");
return 0;
}
/*
* list_initiators:
* Handle the list_initiators command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
list_initiators(int argc, char **argv)
{
iscsid_get_list_req_t lst;
iscsid_response_t *rsp, *prsp;
iscsid_get_list_rsp_t *list;
iscsid_get_initiator_rsp_t *init;
iscsid_sym_id_t req;
unsigned i;
memset(&req, 0x0, sizeof(req));
check_extra_args(argc, argv);
/* get the list of servers */
lst.list_kind = INITIATOR_LIST;
send_request(ISCSID_GET_LIST, sizeof(lst), &lst);
rsp = get_response(TRUE);
if (rsp->status) {
status_error(rsp->status);
}
list = (iscsid_get_list_rsp_t *)(void *)rsp->parameter;
/* display all servers */
for (i = 0; i < list->num_entries; i++) {
req.id = list->id[i];
send_request(ISCSID_GET_INITIATOR_PORTAL, sizeof(req), &req);
prsp = get_response(FALSE);
if (prsp->status) {
status_error(prsp->status);
}
init = (iscsid_get_initiator_rsp_t *)(void *)prsp->parameter;
printf("%6d", init->portal_id.id);
if (init->portal_id.name[0]) {
printf("[%s]", init->portal_id.name);
}
printf(": %s\n", init->address);
free_response(prsp);
}
free_response(rsp);
return 0;
}
/*
* login_or_add:
* Common routine for login and add_connection. Handles the actual command,
* the only pre-initialized component is the session ID in the login request
* for add_connection.
*
* Parameters: the login request, plus argc & argv
*/
STATIC void
login_or_add(iscsid_login_req_t * loginp, int argc, char **argv)
{
iscsid_add_target_req_t *targ = NULL;
iscsid_add_target_rsp_t *tgtrsp;
iscsid_set_target_authentication_req_t auth;
iscsid_get_set_target_options_t opt;
iscsid_search_list_req_t srch;
iscsid_response_t *rsp;
int opts, auths, tlen;
/* get the remaining parameters */
opts = cl_get_target_opts(&opt, argc, argv);
auths = cl_get_auth_opts(&auth, argc, argv);
cl_get_symname(loginp->sym_name, argc, argv);
cl_get_id ('i', &loginp->initiator_id, argc, argv);
/* do we have a portal ID? */
if (!cl_get_id('P', &loginp->portal_id, argc, argv)) {
/* No portal ID - then we must have a target name */
if (!(tlen = cl_get_target(&targ, argc, argv, TRUE))) {
if (NO_ID(&loginp->session_id)) {
arg_missing("Target");
}
}
check_extra_args(argc, argv);
if (targ != NULL) {
/* was a complete target with portal specified? */
if (targ->num_portals) {
/* then add it like in an add_target command */
targ->list_kind = TARGET_LIST;
send_request(ISCSID_ADD_TARGET, tlen, targ);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
tgtrsp = (iscsid_add_target_rsp_t *)(void *)(rsp->parameter);
(void) memcpy(&loginp->portal_id.id, &tgtrsp->target_id,
sizeof(loginp->portal_id.id));
} else {
/* else find the target by its TargetName */
srch.search_kind = FIND_TARGET_NAME;
srch.list_kind = TARGET_LIST;
strlcpy((char *)srch.strval, (char *)targ->TargetName,
sizeof(srch.strval));
send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch);
rsp = get_response(FALSE);
if (rsp->status) {
status_error_slist(rsp->status);
}
GET_SYM_ID(loginp->portal_id.id, rsp->parameter);
}
free_response(rsp);
}
} else
check_extra_args(argc, argv);
/* Options specified? Then set them */
if (opts) {
opt.target_id = loginp->portal_id;
opt.list_kind = TARGET_LIST;
send_request(ISCSID_SET_TARGET_OPTIONS, sizeof(opt), &opt);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
}
/* Authentication options specified? Then set them */
if (auths) {
auth.target_id = loginp->portal_id;
auth.list_kind = TARGET_LIST;
send_request(ISCSID_SET_TARGET_AUTHENTICATION, sizeof(auth), &auth);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
}
}
/*
* login:
* Handle login command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
login(int argc, char **argv)
{
iscsid_login_req_t loginp;
iscsid_login_rsp_t *res;
iscsid_response_t *rsp;
memset(&loginp, 0x0, sizeof(loginp));
loginp.login_type = (cl_get_opt('m', argc, argv))
? ISCSI_LOGINTYPE_NOMAP : ISCSI_LOGINTYPE_MAP;
login_or_add(&loginp, argc, argv);
send_request(ISCSID_LOGIN, sizeof(loginp), &loginp);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
res = (iscsid_login_rsp_t *)(void *)rsp->parameter;
printf("Created Session %d, Connection %d\n",
res->session_id.id, res->connection_id.id);
free_response(rsp);
return 0;
}
/*
* logout:
* Handle logout command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
logout(int argc, char **argv)
{
iscsid_sym_id_t req;
iscsid_response_t *rsp;
if (!cl_get_id('I', &req, argc, argv)) {
arg_missing("Session");
}
check_extra_args(argc, argv);
send_request(ISCSID_LOGOUT, sizeof(req), &req);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
printf("OK\n");
return 0;
}
/*
* add_connection:
* Handle add_connection command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
add_connection(int argc, char **argv)
{
iscsid_login_req_t loginp;
iscsid_login_rsp_t *loginrsp;
iscsid_response_t *rsp;
memset(&loginp, 0x0, sizeof(loginp));
loginp.login_type = ISCSI_LOGINTYPE_MAP;
cl_get_id('I', &loginp.session_id, argc, argv);
login_or_add(&loginp, argc, argv);
send_request(ISCSID_ADD_CONNECTION, sizeof(loginp), &loginp);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
loginrsp = (iscsid_login_rsp_t *)(void *)(rsp->parameter);
printf("Added Connection %d\n", loginrsp->connection_id.id);
free_response(rsp);
return 0;
}
/*
* remove_connection:
* Handle remove connection command
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
remove_connection(int argc, char **argv)
{
iscsid_remove_connection_req_t req;
iscsid_response_t *rsp;
if (!cl_get_id('I', &req.session_id, argc, argv)) {
arg_missing("Session");
}
if (!cl_get_id('C', &req.connection_id, argc, argv)) {
arg_missing("Connection");
}
check_extra_args(argc, argv);
send_request(ISCSID_REMOVE_CONNECTION, sizeof(req), &req);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
printf("OK\n");
return 0;
}
/*
* list_sessions:
* Handle list_sessions command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*
* ToDo: initiator portals, connection recurse
*/
int
list_sessions(int argc, char **argv)
{
iscsid_response_t *lrsp, *rsp;
iscsid_get_session_list_rsp_t *list;
iscsid_session_list_entry_t *ent;
iscsid_get_connection_info_req_t creq;
iscsid_get_connection_info_rsp_t *info;
iscsid_sym_id_t clreq;
iscsid_get_connection_list_rsp_t *clinfo;
iscsid_connection_list_entry_t *clent;
unsigned i;
unsigned j;
int lconn;
memset(&creq, 0x0, sizeof(creq));
memset(&clreq, 0x0, sizeof(clreq));
lconn = cl_get_opt('c', argc, argv);
check_extra_args(argc, argv);
send_request(ISCSID_GET_SESSION_LIST, 0, NULL);
lrsp = get_response(TRUE);
if (lrsp->status) {
status_error(lrsp->status);
}
list = (iscsid_get_session_list_rsp_t *)(void *)lrsp->parameter;
for (i = 0, ent = list->session; i < list->num_entries; i++, ent++) {
creq.session_id.id = ent->session_id.id;
send_request(ISCSID_GET_CONNECTION_INFO, sizeof(creq), &creq);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
info = (iscsid_get_connection_info_rsp_t *)(void *)rsp->parameter;
printf("Session %d", info->session_id.id);
if (info->session_id.name[0]) {
printf("[%s]", info->session_id.name);
}
printf(": Target %s", info->TargetName);
if (info->target_portal_id.name[0]) {
printf(" [%s]", info->target_portal_id.name);
}
printf("\n");
if (lconn) {
clreq.id = info->session_id.id;
send_request(ISCSID_GET_CONNECTION_LIST, sizeof(clreq), &clreq);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
clinfo = (iscsid_get_connection_list_rsp_t *)(void *)rsp->parameter;
for (j = 0, clent = clinfo->connection;
j < clinfo->num_connections; j++, clent++) {
printf(" Connection %d", clent->connection_id.id);
if (clent->connection_id.name[0]) {
printf("[%s]", clent->connection_id.name);
}
printf(" Address %s:%d,%d\n", clent->target_portal.address,
clent->target_portal.port,
clent->target_portal.group_tag);
}
}
}
return 0;
}
/*
* set_node_name:
* Handle the set_node_name command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
set_node_name(int argc, char **argv)
{
iscsid_set_node_name_req_t req;
iscsid_response_t *rsp;
uint64_t isid;
memset(&req, 0x0, sizeof(req));
if (!cl_get_string('n', (char *)req.InitiatorName, argc, argv)) {
arg_missing("Initiator Name");
}
cl_get_string('A', (char *)req.InitiatorAlias, argc, argv);
isid = cl_get_longlong('i', argc, argv);
hton6(req.ISID, isid);
check_extra_args(argc, argv);
send_request(ISCSID_SET_NODE_NAME, sizeof(req), &req);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
free_response(rsp);
printf("OK\n");
return 0;
}
/*
* get_version:
* Handle the version command.
*
* Parameter: argc, argv (shifted)
*
* Returns: 0 if OK - else it doesn't return at all.
*/
int
/*ARGSUSED*/
get_version(int argc, char **argv)
{
iscsid_response_t *rsp;
iscsid_get_version_rsp_t *ver;
send_request(ISCSID_GET_VERSION, 0, NULL);
rsp = get_response(FALSE);
if (rsp->status) {
status_error(rsp->status);
}
ver = (iscsid_get_version_rsp_t *)(void *)rsp->parameter;
printf("%s\n%s\n%s\n", VERSION_STRING, ver->version_string,
ver->driver_version_string);
return 0;
}