|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* iSCSI Administration Utility
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* Copyright (C) 2004 Dmitry Yusupov, Alex Aizman
|
|
Packit Service |
646995 |
* Copyright (C) 2006 Mike Christie
|
|
Packit Service |
646995 |
* Copyright (C) 2006 Red Hat, Inc. All rights reserved.
|
|
Packit Service |
646995 |
* Copyright (C) 2011 Dell Inc.
|
|
Packit Service |
646995 |
* maintained by open-iscsi@googlegroups.com
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
646995 |
* it under the terms of the GNU General Public License as published
|
|
Packit Service |
646995 |
* by the Free Software Foundation; either version 2 of the License, or
|
|
Packit Service |
646995 |
* (at your option) any later version.
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit Service |
646995 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
646995 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
646995 |
* General Public License for more details.
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* See the file COPYING included with this distribution for more details.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
#include <errno.h>
|
|
Packit Service |
646995 |
#include <getopt.h>
|
|
Packit Service |
646995 |
#include <stdlib.h>
|
|
Packit Service |
646995 |
#include <stdio.h>
|
|
Packit Service |
646995 |
#include <unistd.h>
|
|
Packit Service |
646995 |
#include <string.h>
|
|
Packit Service |
646995 |
#include <signal.h>
|
|
Packit Service |
646995 |
#include <time.h>
|
|
Packit Service |
646995 |
#include <sys/stat.h>
|
|
Packit Service |
646995 |
#include <inttypes.h>
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
#include <libopeniscsiusr/libopeniscsiusr.h>
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
#include "initiator.h"
|
|
Packit Service |
646995 |
#include "discovery.h"
|
|
Packit Service |
646995 |
#include "log.h"
|
|
Packit Service |
646995 |
#include "mgmt_ipc.h"
|
|
Packit Service |
646995 |
#include "idbm.h"
|
|
Packit Service |
646995 |
#include "iscsi_util.h"
|
|
Packit Service |
646995 |
#include "transport.h"
|
|
Packit Service |
646995 |
#include "version.h"
|
|
Packit Service |
646995 |
#include "iscsi_sysfs.h"
|
|
Packit Service |
646995 |
#include "list.h"
|
|
Packit Service |
646995 |
#include "iscsi_settings.h"
|
|
Packit Service |
646995 |
#include "fw_context.h"
|
|
Packit Service |
646995 |
#include "iface.h"
|
|
Packit Service |
646995 |
#include "session_info.h"
|
|
Packit Service |
646995 |
#include "host.h"
|
|
Packit Service |
646995 |
#include "sysdeps.h"
|
|
Packit Service |
646995 |
#include "idbm_fields.h"
|
|
Packit Service |
646995 |
#include "session_mgmt.h"
|
|
Packit Service |
646995 |
#include "iscsid_req.h"
|
|
Packit Service |
646995 |
#include <libisns/isns-proto.h>
|
|
Packit Service |
646995 |
#include "iscsi_err.h"
|
|
Packit Service |
646995 |
#include "iscsi_ipc.h"
|
|
Packit Service |
646995 |
#include "iscsi_timer.h"
|
|
Packit Service |
646995 |
#include "flashnode.h"
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
#define _good(rc, rc_val, out) \
|
|
Packit Service |
646995 |
do { \
|
|
Packit Service |
646995 |
rc_val = rc; \
|
|
Packit Service |
646995 |
if (rc_val != LIBISCSI_OK) \
|
|
Packit Service |
646995 |
goto out; \
|
|
Packit Service |
646995 |
} while(0)
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static char program_name[] = "iscsiadm";
|
|
Packit Service |
646995 |
static char config_file[TARGET_NAME_MAXLEN];
|
|
Packit Service |
646995 |
extern struct iscsi_ipc *ipc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
enum iscsiadm_mode {
|
|
Packit Service |
646995 |
MODE_DISCOVERY,
|
|
Packit Service |
646995 |
MODE_DISCOVERYDB,
|
|
Packit Service |
646995 |
MODE_NODE,
|
|
Packit Service |
646995 |
MODE_SESSION,
|
|
Packit Service |
646995 |
MODE_HOST,
|
|
Packit Service |
646995 |
MODE_IFACE,
|
|
Packit Service |
646995 |
MODE_FW,
|
|
Packit Service |
646995 |
MODE_PING,
|
|
Packit Service |
646995 |
MODE_CHAP,
|
|
Packit Service |
646995 |
MODE_FLASHNODE,
|
|
Packit Service |
646995 |
MODE_HOST_STATS
|
|
Packit Service |
646995 |
};
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
enum iscsiadm_op {
|
|
Packit Service |
646995 |
OP_NOOP = 0x0,
|
|
Packit Service |
646995 |
OP_NEW = 0x1,
|
|
Packit Service |
646995 |
OP_DELETE = 0x2,
|
|
Packit Service |
646995 |
OP_UPDATE = 0x4,
|
|
Packit Service |
646995 |
OP_SHOW = 0x8,
|
|
Packit Service |
646995 |
OP_NONPERSISTENT = 0x10,
|
|
Packit Service |
646995 |
OP_APPLY = 0x20,
|
|
Packit Service |
646995 |
OP_APPLY_ALL = 0x40,
|
|
Packit Service |
646995 |
OP_LOGIN = 0x80,
|
|
Packit Service |
646995 |
OP_LOGOUT = 0x100
|
|
Packit Service |
646995 |
};
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
enum _print_node_tree_mode {
|
|
Packit Service |
646995 |
_PRINT_MODE_IFACE,
|
|
Packit Service |
646995 |
_PRINT_MODE_NODE,
|
|
Packit Service |
646995 |
};
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static struct option const long_options[] =
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
{"mode", required_argument, NULL, 'm'},
|
|
Packit Service |
646995 |
{"portal", required_argument, NULL, 'p'},
|
|
Packit Service |
646995 |
{"targetname", required_argument, NULL, 'T'},
|
|
Packit Service |
646995 |
{"interface", required_argument, NULL, 'I'},
|
|
Packit Service |
646995 |
{"op", required_argument, NULL, 'o'},
|
|
Packit Service |
646995 |
{"type", required_argument, NULL, 't'},
|
|
Packit Service |
646995 |
{"name", required_argument, NULL, 'n'},
|
|
Packit Service |
646995 |
{"value", required_argument, NULL, 'v'},
|
|
Packit Service |
646995 |
{"host", required_argument, NULL, 'H'},
|
|
Packit Service |
646995 |
{"sid", required_argument, NULL, 'r'},
|
|
Packit Service |
646995 |
{"rescan", no_argument, NULL, 'R'},
|
|
Packit Service |
646995 |
{"print", required_argument, NULL, 'P'},
|
|
Packit Service |
646995 |
{"discover", no_argument, NULL, 'D'},
|
|
Packit Service |
646995 |
{"login", no_argument, NULL, 'l'},
|
|
Packit Service |
646995 |
{"loginall", required_argument, NULL, 'L'},
|
|
Packit Service |
646995 |
{"logout", no_argument, NULL, 'u'},
|
|
Packit Service |
646995 |
{"logoutall", required_argument, NULL, 'U'},
|
|
Packit Service |
646995 |
{"stats", no_argument, NULL, 's'},
|
|
Packit Service |
646995 |
{"killiscsid", required_argument, NULL, 'k'},
|
|
Packit Service |
646995 |
{"debug", required_argument, NULL, 'd'},
|
|
Packit Service |
646995 |
{"show", no_argument, NULL, 'S'},
|
|
Packit Service |
646995 |
{"version", no_argument, NULL, 'V'},
|
|
Packit Service |
646995 |
{"help", no_argument, NULL, 'h'},
|
|
Packit Service |
646995 |
{"submode", required_argument, NULL, 'C'},
|
|
Packit Service |
646995 |
{"ip", required_argument, NULL, 'a'},
|
|
Packit Service |
646995 |
{"packetsize", required_argument, NULL, 'b'},
|
|
Packit Service |
646995 |
{"count", required_argument, NULL, 'c'},
|
|
Packit Service |
646995 |
{"interval", required_argument, NULL, 'i'},
|
|
Packit Service |
646995 |
{"index", required_argument, NULL, 'x'},
|
|
Packit Service |
646995 |
{"portal_type", optional_argument, NULL, 'A'},
|
|
Packit Service |
646995 |
{"no_wait", no_argument, NULL, 'W'},
|
|
Packit Service |
646995 |
{NULL, 0, NULL, 0},
|
|
Packit Service |
646995 |
};
|
|
Packit Service |
646995 |
static char *short_options = "RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:ux:A:W";
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void usage(int status)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (status != 0)
|
|
Packit Service |
646995 |
fprintf(stderr, "Try `%s --help' for more information.\n",
|
|
Packit Service |
646995 |
program_name);
|
|
Packit Service |
646995 |
else {
|
|
Packit Service |
646995 |
printf("\
|
|
Packit Service |
646995 |
iscsiadm -m discoverydb [-hV] [-d debug_level] [-P printlevel] [-t type -p ip:port -I ifaceN ... [-Dl]] | [[-p ip:port -t type] \
|
|
Packit Service |
646995 |
[-o operation] [-n name] [-v value] [-lD]] \n\
|
|
Packit Service |
646995 |
iscsiadm -m discovery [-hV] [-d debug_level] [-P printlevel] [-t type -p ip:port -I ifaceN ... [-l]] | [[-p ip:port] [-l | -D]] \n\
|
|
Packit Service |
646995 |
iscsiadm -m node [-hV] [-d debug_level] [-P printlevel] [-L all,manual,automatic,onboot] [-W] [-U all,manual,automatic,onboot] [-S] [[-T targetname -p ip:port -I ifaceN] [-l | -u | -R | -s]] \
|
|
Packit Service |
646995 |
[[-o operation ] [-n name] [-v value]]\n\
|
|
Packit Service |
646995 |
iscsiadm -m session [-hV] [-d debug_level] [-P printlevel] [-r sessionid | sysfsdir [-R | -u | -s] [-o operation] [-n name] [-v value]]\n\
|
|
Packit Service |
646995 |
iscsiadm -m iface [-hV] [-d debug_level] [-P printlevel] [-I ifacename | -H hostno|MAC] [[-o operation ] [-n name] [-v value]] [-C ping [-a ip] [-b packetsize] [-c count] [-i interval]]\n\
|
|
Packit Service |
646995 |
iscsiadm -m fw [-d debug_level] [-l]\n\
|
|
Packit Service |
646995 |
iscsiadm -m host [-P printlevel] [-H hostno|MAC] [[-C chap [-x chap_tbl_idx]] | [-C flashnode [-A portal_type] [-x flashnode_idx]] | [-C stats]] [[-o operation] [-n name] [-v value]] \n\
|
|
Packit Service |
646995 |
iscsiadm -k priority\n");
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
exit(status);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
str_to_op(char *str)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int op;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strcmp("new", str))
|
|
Packit Service |
646995 |
op = OP_NEW;
|
|
Packit Service |
646995 |
else if (!strcmp("delete", str))
|
|
Packit Service |
646995 |
op = OP_DELETE;
|
|
Packit Service |
646995 |
else if (!strcmp("update", str))
|
|
Packit Service |
646995 |
op = OP_UPDATE;
|
|
Packit Service |
646995 |
else if (!strcmp("show", str))
|
|
Packit Service |
646995 |
op = OP_SHOW;
|
|
Packit Service |
646995 |
else if (!strcmp("nonpersistent", str))
|
|
Packit Service |
646995 |
op = OP_NONPERSISTENT;
|
|
Packit Service |
646995 |
else if (!strcmp("apply", str))
|
|
Packit Service |
646995 |
op = OP_APPLY;
|
|
Packit Service |
646995 |
else if (!strcmp("applyall", str))
|
|
Packit Service |
646995 |
op = OP_APPLY_ALL;
|
|
Packit Service |
646995 |
else if (!strcmp("login", str))
|
|
Packit Service |
646995 |
op = OP_LOGIN;
|
|
Packit Service |
646995 |
else if (!strcmp("logout", str))
|
|
Packit Service |
646995 |
op = OP_LOGOUT;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
op = OP_NOOP;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return op;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
str_to_mode(char *str)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int mode;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strcmp("discovery", str))
|
|
Packit Service |
646995 |
mode = MODE_DISCOVERY;
|
|
Packit Service |
646995 |
else if (!strcmp("discoverydb", str))
|
|
Packit Service |
646995 |
mode = MODE_DISCOVERYDB;
|
|
Packit Service |
646995 |
else if (!strcmp("node", str))
|
|
Packit Service |
646995 |
mode = MODE_NODE;
|
|
Packit Service |
646995 |
else if (!strcmp("session", str))
|
|
Packit Service |
646995 |
mode = MODE_SESSION;
|
|
Packit Service |
646995 |
else if (!strcmp("iface", str))
|
|
Packit Service |
646995 |
mode = MODE_IFACE;
|
|
Packit Service |
646995 |
else if (!strcmp("fw", str))
|
|
Packit Service |
646995 |
mode = MODE_FW;
|
|
Packit Service |
646995 |
else if (!strcmp("host", str))
|
|
Packit Service |
646995 |
mode = MODE_HOST;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
mode = -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return mode;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
str_to_submode(char *str)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int sub_mode;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strcmp("ping", str))
|
|
Packit Service |
646995 |
sub_mode = MODE_PING;
|
|
Packit Service |
646995 |
else if (!strcmp("chap", str))
|
|
Packit Service |
646995 |
sub_mode = MODE_CHAP;
|
|
Packit Service |
646995 |
else if (!strcmp("flashnode", str))
|
|
Packit Service |
646995 |
sub_mode = MODE_FLASHNODE;
|
|
Packit Service |
646995 |
else if (!strcmp("stats", str))
|
|
Packit Service |
646995 |
sub_mode = MODE_HOST_STATS;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
sub_mode = -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return sub_mode;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
str_to_type(char *str)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int type;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strcmp("sendtargets", str) ||
|
|
Packit Service |
646995 |
!strcmp("st", str))
|
|
Packit Service |
646995 |
type = DISCOVERY_TYPE_SENDTARGETS;
|
|
Packit Service |
646995 |
else if (!strcmp("slp", str))
|
|
Packit Service |
646995 |
type = DISCOVERY_TYPE_SLP;
|
|
Packit Service |
646995 |
else if (!strcmp("isns", str))
|
|
Packit Service |
646995 |
type = DISCOVERY_TYPE_ISNS;
|
|
Packit Service |
646995 |
else if (!strcmp("fw", str))
|
|
Packit Service |
646995 |
type = DISCOVERY_TYPE_FW;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
type = -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return type;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
str_to_portal_type(char *str)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int ptype;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strcmp("ipv4", str))
|
|
Packit Service |
646995 |
ptype = IPV4;
|
|
Packit Service |
646995 |
else if (!strcmp("ipv6", str))
|
|
Packit Service |
646995 |
ptype = IPV6;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
ptype = -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return ptype;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void kill_iscsid(int priority, int tmo)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
iscsiadm_req_t req;
|
|
Packit Service |
646995 |
iscsiadm_rsp_t rsp;
|
|
Packit Service |
646995 |
int rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* We only support SIGTERM like stoppage of iscsid for now.
|
|
Packit Service |
646995 |
* In the future we can do something where we try go finish
|
|
Packit Service |
646995 |
* up operations like login, error handling, etc, before
|
|
Packit Service |
646995 |
* iscsid is stopped, and we can add different values to indicate
|
|
Packit Service |
646995 |
* that the user wants iscsid to log out existing sessions before
|
|
Packit Service |
646995 |
* exiting.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (priority != 0) {
|
|
Packit Service |
646995 |
log_error("Invalid iscsid priority %d. Priority must be 0.",
|
|
Packit Service |
646995 |
priority);
|
|
Packit Service |
646995 |
return;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&req, 0, sizeof(req));
|
|
Packit Service |
646995 |
req.command = MGMT_IPC_IMMEDIATE_STOP;
|
|
Packit Service |
646995 |
rc = iscsid_exec_req(&req, &rsp, 0, tmo);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
iscsi_err_print_msg(rc);
|
|
Packit Service |
646995 |
log_error("Could not stop iscsid. Trying sending iscsid "
|
|
Packit Service |
646995 |
"SIGTERM or SIGKILL signals manually");
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
match_startup_mode(node_rec_t *rec, char *mode)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if ((!strcmp(mode, "automatic") &&
|
|
Packit Service |
646995 |
rec->startup == ISCSI_STARTUP_AUTOMATIC) ||
|
|
Packit Service |
646995 |
(!strcmp(mode, "onboot") &&
|
|
Packit Service |
646995 |
rec->startup == ISCSI_STARTUP_ONBOOT) ||
|
|
Packit Service |
646995 |
(!strcmp(mode, "manual") &&
|
|
Packit Service |
646995 |
rec->startup == ISCSI_STARTUP_MANUAL) ||
|
|
Packit Service |
646995 |
!strcmp(mode, "all"))
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* support conn or session startup params */
|
|
Packit Service |
646995 |
if ((!strcmp(mode, "automatic") &&
|
|
Packit Service |
646995 |
rec->conn[0].startup == ISCSI_STARTUP_AUTOMATIC) ||
|
|
Packit Service |
646995 |
(!strcmp(mode, "onboot") &&
|
|
Packit Service |
646995 |
rec->conn[0].startup == ISCSI_STARTUP_ONBOOT) ||
|
|
Packit Service |
646995 |
(!strcmp(mode, "manual") &&
|
|
Packit Service |
646995 |
rec->conn[0].startup == ISCSI_STARTUP_MANUAL) ||
|
|
Packit Service |
646995 |
!strcmp(mode, "all"))
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
for_each_session(struct node_rec *rec, iscsi_sysfs_session_op_fn *fn,
|
|
Packit Service |
646995 |
int in_parallel)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int err, num_found = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (rec && rec->session.info) {
|
|
Packit Service |
646995 |
num_found = 1;
|
|
Packit Service |
646995 |
err = fn(rec, rec->session.info);
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
err = iscsi_sysfs_for_each_session(rec, &num_found, fn,
|
|
Packit Service |
646995 |
in_parallel);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
if (err)
|
|
Packit Service |
646995 |
log_error("Could not execute operation on all sessions: %s",
|
|
Packit Service |
646995 |
iscsi_err_to_str(err));
|
|
Packit Service |
646995 |
else if (!num_found) {
|
|
Packit Service |
646995 |
log_error("No session found.");
|
|
Packit Service |
646995 |
err = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return err;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int link_recs(void *data, struct node_rec *rec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct list_head *list = data;
|
|
Packit Service |
646995 |
struct node_rec *rec_copy;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rec_copy = calloc(1, sizeof(*rec_copy));
|
|
Packit Service |
646995 |
if (!rec_copy)
|
|
Packit Service |
646995 |
return ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
memcpy(rec_copy, rec, sizeof(*rec_copy));
|
|
Packit Service |
646995 |
INIT_LIST_HEAD(&rec_copy->list);
|
|
Packit Service |
646995 |
list_add_tail(&rec_copy->list, list);
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
__logout_by_startup(void *data, struct list_head *list,
|
|
Packit Service |
646995 |
struct session_info *info)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
char *mode = data;
|
|
Packit Service |
646995 |
node_rec_t rec;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&rec, 0, sizeof(node_rec_t));
|
|
Packit Service |
646995 |
if (idbm_rec_read(&rec, info->targetname, info->tpgt,
|
|
Packit Service |
646995 |
info->persistent_address,
|
|
Packit Service |
646995 |
info->persistent_port, &info->iface, false)) {
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* this is due to a HW driver or some other driver
|
|
Packit Service |
646995 |
* not hooked in
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
log_debug(7, "could not read data for [%s,%s.%d]",
|
|
Packit Service |
646995 |
info->targetname, info->persistent_address,
|
|
Packit Service |
646995 |
info->persistent_port);
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* multiple drivers could be connected to the same portal */
|
|
Packit Service |
646995 |
if (strcmp(rec.iface.transport_name, info->iface.transport_name))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* we always skip on boot because if the user killed this on
|
|
Packit Service |
646995 |
* they would not be able to do anything
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (rec.startup == ISCSI_STARTUP_ONBOOT)
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (rec.disc_type == DISCOVERY_TYPE_FW)
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (match_startup_mode(&rec, mode))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return iscsi_logout_portal(info, list);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
logout_by_startup(char *mode)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int nr_found;
|
|
Packit Service |
646995 |
int rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") ||
|
|
Packit Service |
646995 |
!strcmp(mode,"manual"))) {
|
|
Packit Service |
646995 |
log_error("Invalid logoutall option %s.", mode);
|
|
Packit Service |
646995 |
usage(ISCSI_ERR_INVAL);
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iscsi_logout_portals(mode, &nr_found, 1, __logout_by_startup);
|
|
Packit Service |
646995 |
if (rc == ISCSI_ERR_NO_OBJS_FOUND)
|
|
Packit Service |
646995 |
log_error("No matching sessions found");
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
struct startup_data {
|
|
Packit Service |
646995 |
char *mode;
|
|
Packit Service |
646995 |
struct list_head all_logins;
|
|
Packit Service |
646995 |
struct list_head leading_logins;
|
|
Packit Service |
646995 |
};
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int link_startup_recs(void *data, struct node_rec *rec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct startup_data *startup = data;
|
|
Packit Service |
646995 |
struct node_rec *rec_copy;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (match_startup_mode(rec, startup->mode))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rec_copy = calloc(1, sizeof(*rec_copy));
|
|
Packit Service |
646995 |
if (!rec_copy)
|
|
Packit Service |
646995 |
return ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
memcpy(rec_copy, rec, sizeof(*rec_copy));
|
|
Packit Service |
646995 |
INIT_LIST_HEAD(&rec_copy->list);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (rec_copy->leading_login)
|
|
Packit Service |
646995 |
list_add_tail(&rec_copy->list, &startup->leading_logins);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
list_add_tail(&rec_copy->list, &startup->all_logins);
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
__do_leading_login(void *data, struct list_head *list, struct node_rec *rec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct iface_rec *pattern_iface = data;
|
|
Packit Service |
646995 |
int nr_found;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_debug(1, "doing leading login using iface: %s", pattern_iface->name);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* Skip any records that do not match the pattern iface */
|
|
Packit Service |
646995 |
if (!iface_match(pattern_iface, &rec->iface))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* If there is an existing session that matcthes the target,
|
|
Packit Service |
646995 |
* the leading login is complete.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (iscsi_sysfs_for_each_session(rec, &nr_found, iscsi_match_target, 0)) {
|
|
Packit Service |
646995 |
log_debug(1, "Skipping %s: Already a session for that target",
|
|
Packit Service |
646995 |
rec->name);
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* No existing session: Attempt a login. */
|
|
Packit Service |
646995 |
return iscsi_login_portal(NULL, list, rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
login_by_startup(char *mode, bool wait)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int nr_found = 0, err, rc;
|
|
Packit Service |
646995 |
struct startup_data startup;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") ||
|
|
Packit Service |
646995 |
!strcmp(mode,"manual") || !strcmp(mode, "onboot"))) {
|
|
Packit Service |
646995 |
log_error("Invalid loginall option %s.", mode);
|
|
Packit Service |
646995 |
usage(ISCSI_ERR_INVAL);
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Filter all node records that match the given 'mode' into 2 lists:
|
|
Packit Service |
646995 |
* Those with leading_login enabled, and those without.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
startup.mode = mode;
|
|
Packit Service |
646995 |
INIT_LIST_HEAD(&startup.all_logins);
|
|
Packit Service |
646995 |
INIT_LIST_HEAD(&startup.leading_logins);
|
|
Packit Service |
646995 |
err = idbm_for_each_rec(&nr_found, &startup, link_startup_recs, false);
|
|
Packit Service |
646995 |
if (err && (!list_empty(&startup.all_logins) ||
|
|
Packit Service |
646995 |
!list_empty(&startup.leading_logins)))
|
|
Packit Service |
646995 |
/* log msg and try to log into what we found */
|
|
Packit Service |
646995 |
log_error("Could not read all records: %s",
|
|
Packit Service |
646995 |
iscsi_err_to_str(err));
|
|
Packit Service |
646995 |
else if (list_empty(&startup.all_logins) &&
|
|
Packit Service |
646995 |
list_empty(&startup.leading_logins)) {
|
|
Packit Service |
646995 |
if (err) {
|
|
Packit Service |
646995 |
log_error("Could not read node DB: %s.",
|
|
Packit Service |
646995 |
iscsi_err_to_str(err));
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
log_error("No records found");
|
|
Packit Service |
646995 |
err = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
return err;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
rc = err;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!list_empty(&startup.all_logins)) {
|
|
Packit Service |
646995 |
log_debug(1, "Logging into normal (non-leading-login) portals");
|
|
Packit Service |
646995 |
/* Login all regular (non-leading-login) portals first */
|
|
Packit Service |
646995 |
err = iscsi_login_portals(NULL, &nr_found, wait,
|
|
Packit Service |
646995 |
&startup.all_logins, iscsi_login_portal);
|
|
Packit Service |
646995 |
if (err)
|
|
Packit Service |
646995 |
log_error("Could not log into all portals");
|
|
Packit Service |
646995 |
if (err && !rc)
|
|
Packit Service |
646995 |
rc = err;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!list_empty(&startup.leading_logins)) {
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* For each iface in turn, try to login all portals on that
|
|
Packit Service |
646995 |
* iface that do not already have a session present.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
struct iface_rec *pattern_iface, *tmp_iface;
|
|
Packit Service |
646995 |
struct node_rec *rec, *tmp_rec;
|
|
Packit Service |
646995 |
LIST_HEAD(iface_list);
|
|
Packit Service |
646995 |
int missed_leading_login = 0;
|
|
Packit Service |
646995 |
log_debug(1, "Logging into leading-login portals");
|
|
Packit Service |
646995 |
iface_link_ifaces(&iface_list);
|
|
Packit Service |
646995 |
list_for_each_entry_safe(pattern_iface, tmp_iface, &iface_list,
|
|
Packit Service |
646995 |
list) {
|
|
Packit Service |
646995 |
log_debug(1, "Establishing leading-logins via iface %s",
|
|
Packit Service |
646995 |
pattern_iface->name);
|
|
Packit Service |
646995 |
err = iscsi_login_portals_safe(pattern_iface, &nr_found,
|
|
Packit Service |
646995 |
1,
|
|
Packit Service |
646995 |
&startup.leading_logins,
|
|
Packit Service |
646995 |
__do_leading_login);
|
|
Packit Service |
646995 |
if (err)
|
|
Packit Service |
646995 |
log_error("Could not log into all portals on "
|
|
Packit Service |
646995 |
"%s, trying next interface",
|
|
Packit Service |
646995 |
pattern_iface->name);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Note: We always try all iface records in case there
|
|
Packit Service |
646995 |
* are targets that are associated with only a subset
|
|
Packit Service |
646995 |
* of iface records. __do_leading_login already
|
|
Packit Service |
646995 |
* prevents duplicate sessions if an iface has succeeded
|
|
Packit Service |
646995 |
* for a particular target.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Double-check that all leading-login portals have at least
|
|
Packit Service |
646995 |
* one session
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
list_for_each_entry_safe(rec, tmp_rec, &startup.leading_logins,
|
|
Packit Service |
646995 |
list) {
|
|
Packit Service |
646995 |
if (!iscsi_sysfs_for_each_session(rec, &nr_found,
|
|
Packit Service |
646995 |
iscsi_match_target, 0))
|
|
Packit Service |
646995 |
missed_leading_login++;
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Cleanup the list, since 'iscsi_login_portals_safe'
|
|
Packit Service |
646995 |
* does not
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
list_del(&rec->list);
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
if (missed_leading_login) {
|
|
Packit Service |
646995 |
log_error("Could not login all leading-login portals");
|
|
Packit Service |
646995 |
if (!rc)
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_FATAL_LOGIN;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/**
|
|
Packit Service |
646995 |
* iscsi_logout_matched_portal - logout of targets matching the rec info
|
|
Packit Service |
646995 |
* @data: record to session with
|
|
Packit Service |
646995 |
* @list: list to add logout rec to
|
|
Packit Service |
646995 |
* @info: session to match with rec
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
static int iscsi_logout_matched_portal(void *data, struct list_head *list,
|
|
Packit Service |
646995 |
struct session_info *info)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct node_rec *pattern_rec = data;
|
|
Packit Service |
646995 |
struct iscsi_transport *t;
|
|
Packit Service |
646995 |
uint32_t host_no;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_sid(info->sid);
|
|
Packit Service |
646995 |
if (!t)
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!iscsi_match_session(pattern_rec, info))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
host_no = iscsi_sysfs_get_host_no_from_sid(info->sid, &rc);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("could not get host_no for session%d: %s.",
|
|
Packit Service |
646995 |
info->sid, iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!iscsi_sysfs_session_user_created(info->sid))
|
|
Packit Service |
646995 |
rc = iscsi_logout_flashnode_sid(t, host_no, info->sid);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
rc = iscsi_logout_portal(info, list);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int rec_match_fn(void *data, node_rec_t *rec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct rec_op_data *op_data = data;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!__iscsi_match_session(op_data->match_rec, rec->name,
|
|
Packit Service |
646995 |
rec->conn[0].address, rec->conn[0].port,
|
|
Packit Service |
646995 |
&rec->iface, rec->session.sid))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
return op_data->fn(op_data->data, rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int __for_each_matched_rec(int verbose, struct node_rec *rec,
|
|
Packit Service |
646995 |
void *data, idbm_iface_op_fn *fn)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct rec_op_data op_data;
|
|
Packit Service |
646995 |
int nr_found = 0, rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&op_data, 0, sizeof(struct rec_op_data));
|
|
Packit Service |
646995 |
op_data.data = data;
|
|
Packit Service |
646995 |
op_data.match_rec = rec;
|
|
Packit Service |
646995 |
op_data.fn = fn;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = idbm_for_each_rec(&nr_found, &op_data, rec_match_fn, true);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
if (verbose)
|
|
Packit Service |
646995 |
log_error("Could not execute operation on all "
|
|
Packit Service |
646995 |
"records: %s", iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
} else if (!nr_found) {
|
|
Packit Service |
646995 |
if (verbose)
|
|
Packit Service |
646995 |
log_error("No records found");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int for_each_matched_rec(struct node_rec *rec, void *data,
|
|
Packit Service |
646995 |
idbm_iface_op_fn *fn)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
return __for_each_matched_rec(1, rec, data, fn);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int login_portals(struct node_rec *pattern_rec, bool wait)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
LIST_HEAD(rec_list);
|
|
Packit Service |
646995 |
int nr_found, rc, err;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
err = for_each_matched_rec(pattern_rec, &rec_list, link_recs);
|
|
Packit Service |
646995 |
if (err == ISCSI_ERR_NO_OBJS_FOUND)
|
|
Packit Service |
646995 |
return err;
|
|
Packit Service |
646995 |
else if (err && list_empty(&rec_list))
|
|
Packit Service |
646995 |
return err;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = err;
|
|
Packit Service |
646995 |
/* if there is an err but some recs then try to login to what we have */
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
err = iscsi_login_portals(pattern_rec, &nr_found, wait ? 1 : 0, &rec_list,
|
|
Packit Service |
646995 |
iscsi_login_portal);
|
|
Packit Service |
646995 |
if (err)
|
|
Packit Service |
646995 |
log_error("Could not log into all portals");
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (err && !rc)
|
|
Packit Service |
646995 |
rc = err;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void print_node_flat(struct iscsi_node *node)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
printf("%s,%" PRIu16 " %s\n",
|
|
Packit Service |
646995 |
iscsi_node_portal_get(node),
|
|
Packit Service |
646995 |
iscsi_node_tpgt_get(node),
|
|
Packit Service |
646995 |
iscsi_node_target_name_get(node));
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void print_nodes_tree(struct iscsi_node **nodes, uint32_t node_count,
|
|
Packit Service |
646995 |
enum _print_node_tree_mode print_mode)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
unsigned int i;
|
|
Packit Service |
646995 |
struct iscsi_node *cur_node = NULL;
|
|
Packit Service |
646995 |
struct iscsi_node *prev_node = NULL;
|
|
Packit Service |
646995 |
const char *prefix = NULL;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (print_mode == _PRINT_MODE_IFACE)
|
|
Packit Service |
646995 |
prefix = "\t";
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
prefix = "";
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
// According to libopeniscsiusr document, nodes are sorted. There
|
|
Packit Service |
646995 |
// is no need to create hash table for this.
|
|
Packit Service |
646995 |
for (i = 0; i < node_count; ++i) {
|
|
Packit Service |
646995 |
cur_node = nodes[i];
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Print the target line if this is our first pass, or
|
|
Packit Service |
646995 |
* if if it does not match the prevous target. Always print
|
|
Packit Service |
646995 |
* the Portal line. The original code seemed to want to
|
|
Packit Service |
646995 |
* suppres duplicates here, as well, but it evidently
|
|
Packit Service |
646995 |
* didn't work that way, so let's not regress output format
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (!prev_node || strcmp(iscsi_node_target_name_get(prev_node),
|
|
Packit Service |
646995 |
iscsi_node_target_name_get(cur_node)))
|
|
Packit Service |
646995 |
printf("%sTarget: %s\n", prefix,
|
|
Packit Service |
646995 |
iscsi_node_target_name_get(cur_node));
|
|
Packit Service |
646995 |
printf("%s\tPortal: %s,%d\n", prefix,
|
|
Packit Service |
646995 |
iscsi_node_portal_get(cur_node),
|
|
Packit Service |
646995 |
iscsi_node_tpgt_get(cur_node));
|
|
Packit Service |
646995 |
if (print_mode == _PRINT_MODE_NODE)
|
|
Packit Service |
646995 |
printf("\t\tIface Name: %s\n",
|
|
Packit Service |
646995 |
iscsi_node_iface_name_get(cur_node));
|
|
Packit Service |
646995 |
prev_node = cur_node;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int print_nodes(struct iscsi_context *ctx, int info_level)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct iscsi_node **nodes = NULL;
|
|
Packit Service |
646995 |
uint32_t node_count = 0;
|
|
Packit Service |
646995 |
uint32_t i = 0;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if ((info_level != 0) && (info_level != -1) && (info_level != 1)) {
|
|
Packit Service |
646995 |
log_error("Invalid info level %d. Try 0 or 1.", info_level);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iscsi_nodes_get(ctx, &nodes, &node_count);
|
|
Packit Service |
646995 |
if (rc != LIBISCSI_OK)
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!node_count) {
|
|
Packit Service |
646995 |
log_error("No records found");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (info_level == 1)
|
|
Packit Service |
646995 |
print_nodes_tree(nodes, node_count, _PRINT_MODE_NODE);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
for (i = 0; i < node_count; ++i)
|
|
Packit Service |
646995 |
print_node_flat(nodes[i]);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
out:
|
|
Packit Service |
646995 |
iscsi_nodes_free(nodes, node_count);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int print_nodes_config(struct iscsi_context *ctx, bool show_secret,
|
|
Packit Service |
646995 |
const char *target_name, const char *address,
|
|
Packit Service |
646995 |
int32_t port, const char *iface_name)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
struct iscsi_node **nodes = NULL;
|
|
Packit Service |
646995 |
struct iscsi_node *node = NULL;
|
|
Packit Service |
646995 |
uint32_t node_count = 0;
|
|
Packit Service |
646995 |
uint32_t i = 0;
|
|
Packit Service |
646995 |
bool match = false;
|
|
Packit Service |
646995 |
bool has_match = false;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iscsi_nodes_get(ctx, &nodes, &node_count);
|
|
Packit Service |
646995 |
if (rc != LIBISCSI_OK)
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
for (i = 0; i < node_count; ++i) {
|
|
Packit Service |
646995 |
node = nodes[i];
|
|
Packit Service |
646995 |
match = true;
|
|
Packit Service |
646995 |
if ((target_name != NULL) &&
|
|
Packit Service |
646995 |
(strlen(target_name) != 0) &&
|
|
Packit Service |
646995 |
(strcmp(target_name,
|
|
Packit Service |
646995 |
iscsi_node_target_name_get(node)) != 0))
|
|
Packit Service |
646995 |
match = false;
|
|
Packit Service |
646995 |
if ((address != NULL) &&
|
|
Packit Service |
646995 |
(strlen(address) != 0) &&
|
|
Packit Service |
646995 |
(strcmp(address, iscsi_node_conn_address_get(node)) != 0))
|
|
Packit Service |
646995 |
match = false;
|
|
Packit Service |
646995 |
if ((port != -1) && (port != (int32_t)iscsi_node_conn_port_get(node)))
|
|
Packit Service |
646995 |
match = false;
|
|
Packit Service |
646995 |
if ((iface_name != NULL) &&
|
|
Packit Service |
646995 |
(strlen(iface_name) != 0) &&
|
|
Packit Service |
646995 |
(strcmp(iface_name, iscsi_node_iface_name_get(node)) != 0))
|
|
Packit Service |
646995 |
match = false;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (match == true) {
|
|
Packit Service |
646995 |
iscsi_node_print_config(node, show_secret);
|
|
Packit Service |
646995 |
has_match = true;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
iscsi_nodes_free(nodes, node_count);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (has_match == false) {
|
|
Packit Service |
646995 |
log_error("No records found");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static char *get_config_file(void)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc;
|
|
Packit Service |
646995 |
iscsiadm_req_t req;
|
|
Packit Service |
646995 |
iscsiadm_rsp_t rsp;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&req, 0, sizeof(req));
|
|
Packit Service |
646995 |
req.command = MGMT_IPC_CONFIG_FILE;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iscsid_exec_req(&req, &rsp, 1, ISCSID_REQ_TIMEOUT);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
return NULL;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (rsp.u.config.var[0] != '\0') {
|
|
Packit Service |
646995 |
strcpy(config_file, rsp.u.config.var);
|
|
Packit Service |
646995 |
return config_file;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return NULL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int rescan_portal(void *data, struct session_info *info)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int host_no, err;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!iscsi_match_session(data, info))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
printf("Rescanning session [sid: %d, target: %s, portal: "
|
|
Packit Service |
646995 |
"%s,%d]\n", info->sid, info->targetname,
|
|
Packit Service |
646995 |
info->persistent_address, info->port);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
host_no = iscsi_sysfs_get_host_no_from_sid(info->sid, &err;;
|
|
Packit Service |
646995 |
if (err) {
|
|
Packit Service |
646995 |
log_error("Could not rescan session sid %d.", info->sid);
|
|
Packit Service |
646995 |
return err;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
/* rescan each device to pick up size changes */
|
|
Packit Service |
646995 |
iscsi_sysfs_for_each_device(NULL, host_no, info->sid,
|
|
Packit Service |
646995 |
iscsi_sysfs_rescan_device);
|
|
Packit Service |
646995 |
/* now scan for new devices */
|
|
Packit Service |
646995 |
iscsi_sysfs_scan_host(host_no, 0, 1);
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
session_stats(void *data, struct session_info *info)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc, i;
|
|
Packit Service |
646995 |
iscsiadm_req_t req;
|
|
Packit Service |
646995 |
iscsiadm_rsp_t rsp;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!iscsi_match_session(data, info))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&req, 0, sizeof(req));
|
|
Packit Service |
646995 |
req.command = MGMT_IPC_SESSION_STATS;
|
|
Packit Service |
646995 |
req.u.session.sid = info->sid;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iscsid_exec_req(&req, &rsp, 1, info->iscsid_req_tmo);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
printf("Stats for session [sid: %d, target: %s, portal: "
|
|
Packit Service |
646995 |
"%s,%d]\n",
|
|
Packit Service |
646995 |
info->sid, info->targetname, info->persistent_address,
|
|
Packit Service |
646995 |
info->port);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
printf( "iSCSI SNMP:\n"
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
"\ttxdata_octets: %lld\n"
|
|
Packit Service |
646995 |
"\trxdata_octets: %lld\n"
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
"\tnoptx_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tscsicmd_pdus: %u\n"
|
|
Packit Service |
646995 |
"\ttmfcmd_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tlogin_pdus: %u\n"
|
|
Packit Service |
646995 |
"\ttext_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tdataout_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tlogout_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tsnack_pdus: %u\n"
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
"\tnoprx_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tscsirsp_pdus: %u\n"
|
|
Packit Service |
646995 |
"\ttmfrsp_pdus: %u\n"
|
|
Packit Service |
646995 |
"\ttextrsp_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tdatain_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tlogoutrsp_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tr2t_pdus: %u\n"
|
|
Packit Service |
646995 |
"\tasync_pdus: %u\n"
|
|
Packit Service |
646995 |
"\trjt_pdus: %u\n"
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
"\tdigest_err: %u\n"
|
|
Packit Service |
646995 |
"\ttimeout_err: %u\n",
|
|
Packit Service |
646995 |
(unsigned long long)rsp.u.getstats.stats.txdata_octets,
|
|
Packit Service |
646995 |
(unsigned long long)rsp.u.getstats.stats.rxdata_octets,
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.noptx_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.scsicmd_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.tmfcmd_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.login_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.text_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.dataout_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.logout_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.snack_pdus,
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.noprx_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.scsirsp_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.tmfrsp_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.textrsp_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.datain_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.logoutrsp_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.r2t_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.async_pdus,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.rjt_pdus,
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.digest_err,
|
|
Packit Service |
646995 |
rsp.u.getstats.stats.timeout_err);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (rsp.u.getstats.stats.custom_length)
|
|
Packit Service |
646995 |
printf( "iSCSI Extended:\n");
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
for (i = 0; i < (int)rsp.u.getstats.stats.custom_length; i++) {
|
|
Packit Service |
646995 |
printf("\t%s: %llu\n", rsp.u.getstats.stats.custom[i].desc,
|
|
Packit Service |
646995 |
(unsigned long long)rsp.u.getstats.stats.custom[i].value);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int add_static_rec(int *found, char *targetname, int tpgt,
|
|
Packit Service |
646995 |
char *ip, int port, struct iface_rec *iface)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
node_rec_t *rec;
|
|
Packit Service |
646995 |
discovery_rec_t *drec;
|
|
Packit Service |
646995 |
int rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rec = calloc(1, sizeof(*rec));
|
|
Packit Service |
646995 |
if (!rec) {
|
|
Packit Service |
646995 |
log_error("Could not allocate memory for node addition");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
drec = calloc(1, sizeof(*drec));
|
|
Packit Service |
646995 |
if (!drec) {
|
|
Packit Service |
646995 |
log_error("Could not allocate memory for node addition");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto free_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
drec->type = DISCOVERY_TYPE_STATIC;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
idbm_node_setup_from_conf(rec);
|
|
Packit Service |
646995 |
strlcpy(rec->name, targetname, TARGET_NAME_MAXLEN);
|
|
Packit Service |
646995 |
rec->tpgt = tpgt;
|
|
Packit Service |
646995 |
rec->conn[0].port = port;
|
|
Packit Service |
646995 |
strlcpy(rec->conn[0].address, ip, NI_MAXHOST);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (iface) {
|
|
Packit Service |
646995 |
rc = iface_conf_read(iface);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not read iface %s. Error %d",
|
|
Packit Service |
646995 |
iface->name, rc);
|
|
Packit Service |
646995 |
goto free_drec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
iface_copy(&rec->iface, iface);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = idbm_add_node(rec, drec, 1);
|
|
Packit Service |
646995 |
if (!rc) {
|
|
Packit Service |
646995 |
(*found)++;
|
|
Packit Service |
646995 |
printf("New iSCSI node [%s:" iface_fmt " %s,%d,%d %s] added\n",
|
|
Packit Service |
646995 |
rec->iface.transport_name, iface_str(&rec->iface),
|
|
Packit Service |
646995 |
ip, port, tpgt, targetname);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
free_drec:
|
|
Packit Service |
646995 |
free(drec);
|
|
Packit Service |
646995 |
free_rec:
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
done:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int add_static_portal(int *found, void *data, char *targetname,
|
|
Packit Service |
646995 |
int tpgt, char *ip, int port,
|
|
Packit Service |
646995 |
__attribute__((unused))bool ruw_lock)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
node_rec_t *rec = data;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (strlen(rec->conn[0].address) &&
|
|
Packit Service |
646995 |
strcmp(rec->conn[0].address, ip))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (rec->conn[0].port != -1 && rec->conn[0].port != port)
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return add_static_rec(found, targetname, tpgt, ip, port,
|
|
Packit Service |
646995 |
&rec->iface);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int add_static_node(int *found, void *data, char *targetname,
|
|
Packit Service |
646995 |
__attribute__((unused))bool ruw_lock)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
node_rec_t *rec = data;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strlen(rec->name))
|
|
Packit Service |
646995 |
goto search;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (strcmp(rec->name, targetname))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strlen(rec->conn[0].address))
|
|
Packit Service |
646995 |
goto search;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return add_static_rec(found, targetname, rec->tpgt,
|
|
Packit Service |
646995 |
rec->conn[0].address,
|
|
Packit Service |
646995 |
rec->conn[0].port, &rec->iface);
|
|
Packit Service |
646995 |
search:
|
|
Packit Service |
646995 |
return idbm_for_each_portal(found, data, add_static_portal,
|
|
Packit Service |
646995 |
targetname, false);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int add_static_recs(struct node_rec *rec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc, nr_found = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = idbm_for_each_node(&nr_found, rec, add_static_node, false);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
/* success */
|
|
Packit Service |
646995 |
if (nr_found > 0)
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* brand new target */
|
|
Packit Service |
646995 |
if (strlen(rec->name) && strlen(rec->conn[0].address)) {
|
|
Packit Service |
646995 |
rc = add_static_rec(&nr_found, rec->name, rec->tpgt,
|
|
Packit Service |
646995 |
rec->conn[0].address, rec->conn[0].port,
|
|
Packit Service |
646995 |
&rec->iface);
|
|
Packit Service |
646995 |
if (!rc)
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
done:
|
|
Packit Service |
646995 |
log_error("Error while adding record: %s", iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* start sendtargets discovery process based on the
|
|
Packit Service |
646995 |
* particular config
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
do_offload_sendtargets(discovery_rec_t *drec, int host_no, int do_login)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
drec->type = DISCOVERY_TYPE_OFFLOAD_SENDTARGETS;
|
|
Packit Service |
646995 |
return discovery_offload_sendtargets(host_no, do_login, drec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int delete_node(__attribute__((unused))void *data,
|
|
Packit Service |
646995 |
struct node_rec *rec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (iscsi_check_for_running_session(rec)) {
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* We could log out the session for the user, but if
|
|
Packit Service |
646995 |
* the session is being used the user may get something
|
|
Packit Service |
646995 |
* they were not expecting (FS errors and a read only
|
|
Packit Service |
646995 |
* remount).
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
log_error("This command will remove the record [iface: %s, "
|
|
Packit Service |
646995 |
"target: %s, portal: %s,%d], but a session is "
|
|
Packit Service |
646995 |
"using it. Logout session then rerun command to "
|
|
Packit Service |
646995 |
"remove record.", rec->iface.name, rec->name,
|
|
Packit Service |
646995 |
rec->conn[0].address, rec->conn[0].port);
|
|
Packit Service |
646995 |
return ISCSI_ERR_SESS_EXISTS;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return idbm_delete_node(rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int delete_stale_rec(void *data, struct node_rec *rec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct list_head *new_rec_list = data;
|
|
Packit Service |
646995 |
struct node_rec *new_rec;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry(new_rec, new_rec_list, list) {
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* We could also move this to idbm.c and instead of looping
|
|
Packit Service |
646995 |
* over every node just loop over disc to node links.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (rec->disc_type != new_rec->disc_type ||
|
|
Packit Service |
646995 |
rec->disc_port != new_rec->disc_port ||
|
|
Packit Service |
646995 |
strcmp(rec->disc_address, new_rec->disc_address))
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* if we are not from the same discovery source
|
|
Packit Service |
646995 |
* ignore it
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (__iscsi_match_session(rec,
|
|
Packit Service |
646995 |
new_rec->name,
|
|
Packit Service |
646995 |
new_rec->conn[0].address,
|
|
Packit Service |
646995 |
new_rec->conn[0].port,
|
|
Packit Service |
646995 |
&new_rec->iface,
|
|
Packit Service |
646995 |
new_rec->session.sid))
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
/* if there is a error we can continue on */
|
|
Packit Service |
646995 |
return delete_node(NULL, rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
exec_disc_op_on_recs(discovery_rec_t *drec, struct list_head *rec_list,
|
|
Packit Service |
646995 |
int info_level, int do_login, int op)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc = 0, err, found = 0;
|
|
Packit Service |
646995 |
struct node_rec *new_rec, tmp_rec;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* clean up node db */
|
|
Packit Service |
646995 |
if (op & OP_DELETE)
|
|
Packit Service |
646995 |
idbm_for_each_rec(&found, rec_list, delete_stale_rec, false);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (op & OP_NEW || op & OP_UPDATE) {
|
|
Packit Service |
646995 |
/* now add/update records */
|
|
Packit Service |
646995 |
list_for_each_entry(new_rec, rec_list, list) {
|
|
Packit Service |
646995 |
rc = idbm_add_node(new_rec, drec, op & OP_UPDATE);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
log_error("Could not add/update "
|
|
Packit Service |
646995 |
"[%s:" iface_fmt " %s,%d,%d %s]",
|
|
Packit Service |
646995 |
new_rec->iface.transport_name,
|
|
Packit Service |
646995 |
iface_str(&new_rec->iface),
|
|
Packit Service |
646995 |
new_rec->conn[0].address,
|
|
Packit Service |
646995 |
new_rec->conn[0].port,
|
|
Packit Service |
646995 |
new_rec->tpgt, new_rec->name);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&tmp_rec, 0, sizeof(node_rec_t));
|
|
Packit Service |
646995 |
list_for_each_entry(new_rec, rec_list, list) {
|
|
Packit Service |
646995 |
switch (info_level) {
|
|
Packit Service |
646995 |
case 0:
|
|
Packit Service |
646995 |
case -1:
|
|
Packit Service |
646995 |
idbm_print_node_flat(NULL, new_rec);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 1:
|
|
Packit Service |
646995 |
idbm_print_node_and_iface_tree(&tmp_rec, new_rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!do_login)
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
err = iscsi_login_portals(NULL, &found, 1, rec_list,
|
|
Packit Service |
646995 |
iscsi_login_portal);
|
|
Packit Service |
646995 |
if (err && !rc)
|
|
Packit Service |
646995 |
rc = err;
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
do_software_sendtargets(discovery_rec_t *drec, struct list_head *ifaces,
|
|
Packit Service |
646995 |
int info_level, int do_login, int op, int sync_drec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
LIST_HEAD(rec_list);
|
|
Packit Service |
646995 |
struct node_rec *rec, *tmp;
|
|
Packit Service |
646995 |
int rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* compat: if the user did not pass any op then we do all
|
|
Packit Service |
646995 |
* ops for them
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (!op)
|
|
Packit Service |
646995 |
op = OP_NEW | OP_DELETE | OP_UPDATE;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
drec->type = DISCOVERY_TYPE_SENDTARGETS;
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* we will probably want to know how a specific iface and discovery
|
|
Packit Service |
646995 |
* DB lined up, but for now just put all the targets found from
|
|
Packit Service |
646995 |
* a discovery portal in one place
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if ((!(op & OP_NONPERSISTENT)) && sync_drec) {
|
|
Packit Service |
646995 |
rc = idbm_add_discovery(drec);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not add new discovery record.");
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = idbm_bind_ifaces_to_nodes(discovery_sendtargets, drec, ifaces,
|
|
Packit Service |
646995 |
&rec_list);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not perform SendTargets discovery: %s",
|
|
Packit Service |
646995 |
iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
} else if (list_empty(&rec_list)) {
|
|
Packit Service |
646995 |
log_error("No portals found");
|
|
Packit Service |
646995 |
return ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_disc_op_on_recs(drec, &rec_list, info_level, do_login, op);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry_safe(rec, tmp, &rec_list, list) {
|
|
Packit Service |
646995 |
list_del(&rec->list);
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int do_isns(discovery_rec_t *drec, struct list_head *ifaces,
|
|
Packit Service |
646995 |
int info_level, int do_login, int op)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
LIST_HEAD(rec_list);
|
|
Packit Service |
646995 |
struct node_rec *rec, *tmp;
|
|
Packit Service |
646995 |
int rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* compat: if the user did not pass any op then we do all
|
|
Packit Service |
646995 |
* ops for them
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (!op)
|
|
Packit Service |
646995 |
op = OP_NEW | OP_DELETE | OP_UPDATE;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = idbm_bind_ifaces_to_nodes(discovery_isns, drec, ifaces,
|
|
Packit Service |
646995 |
&rec_list);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not perform iSNS discovery: %s",
|
|
Packit Service |
646995 |
iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
} else if (list_empty(&rec_list)) {
|
|
Packit Service |
646995 |
log_error("No portals found");
|
|
Packit Service |
646995 |
return ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_disc_op_on_recs(drec, &rec_list, info_level, do_login, op);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry_safe(rec, tmp, &rec_list, list) {
|
|
Packit Service |
646995 |
list_del(&rec->list);
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
do_target_discovery(discovery_rec_t *drec, struct list_head *ifaces,
|
|
Packit Service |
646995 |
int info_level, int do_login, int op, int sync_drec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
struct iface_rec *tmp, *iface;
|
|
Packit Service |
646995 |
int rc, host_no;
|
|
Packit Service |
646995 |
struct iscsi_transport *t;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (list_empty(ifaces)) {
|
|
Packit Service |
646995 |
ifaces = NULL;
|
|
Packit Service |
646995 |
goto sw_discovery;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* we allow users to mix hw and sw iscsi so we have to sort it out */
|
|
Packit Service |
646995 |
list_for_each_entry_safe(iface, tmp, ifaces, list) {
|
|
Packit Service |
646995 |
rc = iface_conf_read(iface);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not read iface info for %s. "
|
|
Packit Service |
646995 |
"Make sure an iface config with the file "
|
|
Packit Service |
646995 |
"name and iface.iscsi_ifacename %s is in %s.",
|
|
Packit Service |
646995 |
iface->name, iface->name, IFACE_CONFIG_DIR);
|
|
Packit Service |
646995 |
list_del(&iface->list);
|
|
Packit Service |
646995 |
free(iface);
|
|
Packit Service |
646995 |
continue;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
/* check for transport name first to make sure it is loaded */
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_name(iface->transport_name);
|
|
Packit Service |
646995 |
if (!t) {
|
|
Packit Service |
646995 |
log_error("Could not load transport %s."
|
|
Packit Service |
646995 |
"Dropping interface %s.",
|
|
Packit Service |
646995 |
iface->transport_name, iface->name);
|
|
Packit Service |
646995 |
list_del(&iface->list);
|
|
Packit Service |
646995 |
free(iface);
|
|
Packit Service |
646995 |
continue;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
host_no = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc);
|
|
Packit Service |
646995 |
if (rc || host_no == -1) {
|
|
Packit Service |
646995 |
log_debug(1, "Could not match iface" iface_fmt " to "
|
|
Packit Service |
646995 |
"host.", iface_str(iface));
|
|
Packit Service |
646995 |
/* try software iscsi */
|
|
Packit Service |
646995 |
continue;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (drec->type == DISCOVERY_TYPE_SENDTARGETS)
|
|
Packit Service |
646995 |
if (t->caps & CAP_SENDTARGETS_OFFLOAD) {
|
|
Packit Service |
646995 |
do_offload_sendtargets(drec, host_no, do_login);
|
|
Packit Service |
646995 |
list_del(&iface->list);
|
|
Packit Service |
646995 |
free(iface);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (list_empty(ifaces))
|
|
Packit Service |
646995 |
return ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
sw_discovery:
|
|
Packit Service |
646995 |
switch (drec->type) {
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_SENDTARGETS:
|
|
Packit Service |
646995 |
return do_software_sendtargets(drec, ifaces, info_level,
|
|
Packit Service |
646995 |
do_login, op, sync_drec);
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_ISNS:
|
|
Packit Service |
646995 |
return do_isns(drec, ifaces, info_level, do_login, op);
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
log_debug(1, "Unknown Discovery Type : %d", drec->type);
|
|
Packit Service |
646995 |
return ISCSI_ERR_UNKNOWN_DISCOVERY_TYPE;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int
|
|
Packit Service |
646995 |
verify_mode_params(int argc, char **argv, char *allowed, int skip_m)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int ch, longindex;
|
|
Packit Service |
646995 |
int ret = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
optind = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
while ((ch = getopt_long(argc, argv, short_options,
|
|
Packit Service |
646995 |
long_options, &longindex)) >= 0) {
|
|
Packit Service |
646995 |
if (!strchr(allowed, ch)) {
|
|
Packit Service |
646995 |
if (ch == 'm' && skip_m)
|
|
Packit Service |
646995 |
continue;
|
|
Packit Service |
646995 |
ret = ch;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return ret;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void catch_sigint(__attribute__((unused))int signo) {
|
|
Packit Service |
646995 |
log_warning("caught SIGINT, exiting...");
|
|
Packit Service |
646995 |
exit(1);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int iface_apply_net_config(struct iface_rec *iface, int op)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
uint32_t host_no;
|
|
Packit Service |
646995 |
int param_count;
|
|
Packit Service |
646995 |
int param_used;
|
|
Packit Service |
646995 |
int iface_all = 0;
|
|
Packit Service |
646995 |
int i;
|
|
Packit Service |
646995 |
struct iovec *iovs = NULL;
|
|
Packit Service |
646995 |
struct iovec *iov = NULL;
|
|
Packit Service |
646995 |
struct iscsi_transport *t = NULL;
|
|
Packit Service |
646995 |
int fd;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_debug(8, "Calling iscsid, to apply net config for"
|
|
Packit Service |
646995 |
"iface.name = %s", iface->name);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (op == OP_APPLY_ALL)
|
|
Packit Service |
646995 |
iface_all = 1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
param_count = iface_get_param_count(iface, iface_all);
|
|
Packit Service |
646995 |
if (!param_count) {
|
|
Packit Service |
646995 |
log_error("Nothing to configure.");
|
|
Packit Service |
646995 |
return ISCSI_SUCCESS;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* TODO: create a nicer interface where the caller does not have
|
|
Packit Service |
646995 |
* know the packet/hdr details
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* +2 for event and nlmsghdr */
|
|
Packit Service |
646995 |
param_count += 2;
|
|
Packit Service |
646995 |
iovs = calloc((param_count * sizeof(struct iovec)),
|
|
Packit Service |
646995 |
sizeof(char));
|
|
Packit Service |
646995 |
if (!iovs) {
|
|
Packit Service |
646995 |
log_error("Out of Memory.");
|
|
Packit Service |
646995 |
return ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* param_used gives actual number of iovecs used for netconfig */
|
|
Packit Service |
646995 |
param_used = iface_build_net_config(iface, iface_all, iovs);
|
|
Packit Service |
646995 |
if (!param_used) {
|
|
Packit Service |
646995 |
log_error("Build netconfig failed.");
|
|
Packit Service |
646995 |
goto free_buf;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_name(iface->transport_name);
|
|
Packit Service |
646995 |
if (!t) {
|
|
Packit Service |
646995 |
log_error("Can't find transport.");
|
|
Packit Service |
646995 |
goto free_buf;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
host_no = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc);
|
|
Packit Service |
646995 |
if (host_no == 0) {
|
|
Packit Service |
646995 |
log_error("Can't find host_no.");
|
|
Packit Service |
646995 |
goto free_buf;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
goto free_buf;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = ipc->set_net_config(t->handle, host_no, iovs, param_count);
|
|
Packit Service |
646995 |
if (rc < 0)
|
|
Packit Service |
646995 |
log_error("Set net_config failed. errno=%d", errno);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free_buf:
|
|
Packit Service |
646995 |
/* start at 2, because 0 is for nlmsghdr and 1 for event */
|
|
Packit Service |
646995 |
iov = iovs + 2;
|
|
Packit Service |
646995 |
for (i = 0; i < param_used; i++, iov++) {
|
|
Packit Service |
646995 |
if (iov->iov_base)
|
|
Packit Service |
646995 |
free(iov->iov_base);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free(iovs);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
return ISCSI_ERR;
|
|
Packit Service |
646995 |
return ISCSI_SUCCESS;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int get_host_chap_info(uint32_t host_no)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct iscsi_transport *t = NULL;
|
|
Packit Service |
646995 |
struct iscsi_chap_rec *crec = NULL;
|
|
Packit Service |
646995 |
char *req_buf = NULL;
|
|
Packit Service |
646995 |
uint32_t valid_chap_entries;
|
|
Packit Service |
646995 |
uint32_t num_entries;
|
|
Packit Service |
646995 |
uint16_t chap_tbl_idx = 0;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
int fd;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_hba(host_no);
|
|
Packit Service |
646995 |
if (!t) {
|
|
Packit Service |
646995 |
log_error("Could not match hostno %d to "
|
|
Packit Service |
646995 |
"transport.", host_no);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_TRANS_NOT_FOUND;
|
|
Packit Service |
646995 |
goto exit_chap_info;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
num_entries = MAX_CHAP_BUF_SZ / sizeof(*crec);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
req_buf = calloc(1, REQ_CHAP_BUF_SZ);
|
|
Packit Service |
646995 |
if (!req_buf) {
|
|
Packit Service |
646995 |
log_error("Could not allocate memory for CHAP request.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto exit_chap_info;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
goto exit_chap_info;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
get_chap:
|
|
Packit Service |
646995 |
memset(req_buf, 0, REQ_CHAP_BUF_SZ);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = ipc->get_chap(t->handle, host_no, chap_tbl_idx, num_entries,
|
|
Packit Service |
646995 |
req_buf, &valid_chap_entries);
|
|
Packit Service |
646995 |
if (rc < 0) {
|
|
Packit Service |
646995 |
log_error("get_chap_info failed. errno=%d", errno);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
goto exit_chap_info;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
crec = (struct iscsi_chap_rec *) (req_buf +
|
|
Packit Service |
646995 |
sizeof(struct iscsi_uevent));
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (valid_chap_entries)
|
|
Packit Service |
646995 |
chap_tbl_idx =
|
|
Packit Service |
646995 |
(crec + (valid_chap_entries - 1))->chap_tbl_idx + 1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* print chap info */
|
|
Packit Service |
646995 |
for (uint32_t i = 0; i < valid_chap_entries; i++) {
|
|
Packit Service |
646995 |
idbm_print_host_chap_info(crec);
|
|
Packit Service |
646995 |
crec++;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (valid_chap_entries != num_entries)
|
|
Packit Service |
646995 |
goto exit_chap_info;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
goto get_chap;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_chap_info:
|
|
Packit Service |
646995 |
if (req_buf)
|
|
Packit Service |
646995 |
free(req_buf);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int fill_host_chap_rec(struct list_head *params,
|
|
Packit Service |
646995 |
struct iscsi_chap_rec *crec, recinfo_t *cinfo,
|
|
Packit Service |
646995 |
uint16_t chap_tbl_idx, int type, int *param_count)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct user_param *param;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
crec->chap_tbl_idx = chap_tbl_idx;
|
|
Packit Service |
646995 |
crec->chap_type = type;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
idbm_recinfo_host_chap(crec, cinfo);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry(param, params, list) {
|
|
Packit Service |
646995 |
rc = idbm_rec_update_param(cinfo, param->name, param->value, 0);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!rc)
|
|
Packit Service |
646995 |
*param_count += 3; /* index, type and password_length */
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int verify_host_chap_params(struct list_head *params, int *type,
|
|
Packit Service |
646995 |
int *param_count)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct user_param *param;
|
|
Packit Service |
646995 |
int username = -1;
|
|
Packit Service |
646995 |
int password = -1;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry(param, params, list) {
|
|
Packit Service |
646995 |
*param_count += 1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strcmp(param->name, HOST_AUTH_USERNAME))
|
|
Packit Service |
646995 |
username = CHAP_TYPE_OUT;
|
|
Packit Service |
646995 |
else if (!strcmp(param->name, HOST_AUTH_PASSWORD))
|
|
Packit Service |
646995 |
password = CHAP_TYPE_OUT;
|
|
Packit Service |
646995 |
else if (!strcmp(param->name, HOST_AUTH_USERNAME_IN))
|
|
Packit Service |
646995 |
username = CHAP_TYPE_IN;
|
|
Packit Service |
646995 |
else if (!strcmp(param->name, HOST_AUTH_PASSWORD_IN))
|
|
Packit Service |
646995 |
password = CHAP_TYPE_IN;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
continue;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if ((username == CHAP_TYPE_OUT) && (password == CHAP_TYPE_OUT)) {
|
|
Packit Service |
646995 |
if (type)
|
|
Packit Service |
646995 |
*type = CHAP_TYPE_OUT;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = ISCSI_SUCCESS;
|
|
Packit Service |
646995 |
} else if ((username == CHAP_TYPE_IN) && (password == CHAP_TYPE_IN)) {
|
|
Packit Service |
646995 |
if (type)
|
|
Packit Service |
646995 |
*type = CHAP_TYPE_IN;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = ISCSI_SUCCESS;
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int set_host_chap_info(uint32_t host_no, uint64_t chap_index,
|
|
Packit Service |
646995 |
struct list_head *params)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct iscsi_transport *t = NULL;
|
|
Packit Service |
646995 |
struct iscsi_chap_rec crec;
|
|
Packit Service |
646995 |
recinfo_t *chap_info = NULL;
|
|
Packit Service |
646995 |
struct iovec *iovs = NULL;
|
|
Packit Service |
646995 |
struct iovec *iov = NULL;
|
|
Packit Service |
646995 |
int type;
|
|
Packit Service |
646995 |
int param_count = 0;
|
|
Packit Service |
646995 |
int param_used;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
int fd, i = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (list_empty(params)) {
|
|
Packit Service |
646995 |
log_error("Chap username/password not provided.");
|
|
Packit Service |
646995 |
goto exit_set_chap;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
chap_info = idbm_recinfo_alloc(MAX_KEYS);
|
|
Packit Service |
646995 |
if (!chap_info) {
|
|
Packit Service |
646995 |
log_error("Out of Memory.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto exit_set_chap;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_hba(host_no);
|
|
Packit Service |
646995 |
if (!t) {
|
|
Packit Service |
646995 |
log_error("Could not match hostno %d to transport.", host_no);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_TRANS_NOT_FOUND;
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = verify_host_chap_params(params, &type, ¶m_count);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Invalid username/password pair passed. Unable to determine the type of chap entry");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (param_count > 2) {
|
|
Packit Service |
646995 |
log_error("Only one pair of username/password can be passed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&crec, 0, sizeof(crec));
|
|
Packit Service |
646995 |
rc = fill_host_chap_rec(params, &crec, chap_info, chap_index, type,
|
|
Packit Service |
646995 |
¶m_count);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Unable to fill CHAP record");
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* +2 for event and nlmsghdr */
|
|
Packit Service |
646995 |
param_count += 2;
|
|
Packit Service |
646995 |
iovs = calloc((param_count * sizeof(struct iovec)),
|
|
Packit Service |
646995 |
sizeof(char));
|
|
Packit Service |
646995 |
if (!iovs) {
|
|
Packit Service |
646995 |
log_error("Out of Memory.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* param_used gives actual number of iovecs used for chap */
|
|
Packit Service |
646995 |
param_used = chap_build_config(&crec, iovs);
|
|
Packit Service |
646995 |
if (!param_used) {
|
|
Packit Service |
646995 |
log_error("Build chap config failed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
goto free_iovec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
goto free_iovec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = ipc->set_chap(t->handle, host_no, iovs, param_count);
|
|
Packit Service |
646995 |
if (rc < 0) {
|
|
Packit Service |
646995 |
log_error("CHAP setting failed");
|
|
Packit Service |
646995 |
if (rc == -EBUSY) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_BUSY;
|
|
Packit Service |
646995 |
log_error("CHAP index %d is in use.",
|
|
Packit Service |
646995 |
crec.chap_tbl_idx);
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
goto free_iovec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free_iovec:
|
|
Packit Service |
646995 |
/* start at 2, because 0 is for nlmsghdr and 1 for event */
|
|
Packit Service |
646995 |
iov = iovs + 2;
|
|
Packit Service |
646995 |
for (i = 0; i < param_used; i++, iov++) {
|
|
Packit Service |
646995 |
if (iov->iov_base)
|
|
Packit Service |
646995 |
free(iov->iov_base);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free(iovs);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free_info_rec:
|
|
Packit Service |
646995 |
if (chap_info)
|
|
Packit Service |
646995 |
free(chap_info);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_set_chap:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int delete_host_chap_info(uint32_t host_no, uint16_t chap_tbl_idx)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct iscsi_transport *t = NULL;
|
|
Packit Service |
646995 |
int fd, rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (chap_tbl_idx > MAX_CHAP_ENTRIES) {
|
|
Packit Service |
646995 |
log_error("Invalid chap table index.");
|
|
Packit Service |
646995 |
goto exit_delete_chap;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_hba(host_no);
|
|
Packit Service |
646995 |
if (!t) {
|
|
Packit Service |
646995 |
log_error("Could not match hostno %d to "
|
|
Packit Service |
646995 |
"transport.", host_no);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_TRANS_NOT_FOUND;
|
|
Packit Service |
646995 |
goto exit_delete_chap;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
goto exit_delete_chap;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_info("Deleting CHAP index: %d", chap_tbl_idx);
|
|
Packit Service |
646995 |
rc = ipc->delete_chap(t->handle, host_no, chap_tbl_idx);
|
|
Packit Service |
646995 |
if (rc < 0) {
|
|
Packit Service |
646995 |
log_error("CHAP Delete failed.");
|
|
Packit Service |
646995 |
if (rc == -EBUSY) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_BUSY;
|
|
Packit Service |
646995 |
log_error("CHAP index %d is in use.", chap_tbl_idx);
|
|
Packit Service |
646995 |
} else
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_delete_chap:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int exec_host_chap_op(int op,
|
|
Packit Service |
646995 |
__attribute__((unused))int info_level,
|
|
Packit Service |
646995 |
uint32_t host_no,
|
|
Packit Service |
646995 |
uint64_t chap_index,
|
|
Packit Service |
646995 |
struct list_head *params)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
switch (op) {
|
|
Packit Service |
646995 |
case OP_SHOW:
|
|
Packit Service |
646995 |
rc = get_host_chap_info(host_no);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_NEW:
|
|
Packit Service |
646995 |
case OP_UPDATE:
|
|
Packit Service |
646995 |
rc = set_host_chap_info(host_no, chap_index, params);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_DELETE:
|
|
Packit Service |
646995 |
rc = delete_host_chap_info(host_no, chap_index);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
log_error("Invalid operation.");
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int get_flashnode_info(uint32_t host_no, uint32_t flashnode_idx)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct flashnode_rec fnode;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&fnode, 0, sizeof(fnode));
|
|
Packit Service |
646995 |
rc = iscsi_sysfs_get_flashnode_info(&fnode, host_no, flashnode_idx);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not read info for flashnode %u of host %u, %s",
|
|
Packit Service |
646995 |
flashnode_idx, host_no, strerror(rc));
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
idbm_print_flashnode_info(&fnode);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int list_flashnodes(__attribute__((unused))int info_level,
|
|
Packit Service |
646995 |
uint32_t host_no)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
int num_found = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iscsi_sysfs_for_each_flashnode(NULL, host_no, &num_found,
|
|
Packit Service |
646995 |
flashnode_info_print_flat);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!num_found) {
|
|
Packit Service |
646995 |
log_error("No flashnodes attached to host %u.", host_no);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
int iscsi_set_flashnode_params(struct iscsi_transport *t, uint32_t host_no,
|
|
Packit Service |
646995 |
uint32_t flashnode_idx, struct list_head *params)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct flashnode_rec fnode;
|
|
Packit Service |
646995 |
recinfo_t *flashnode_info;
|
|
Packit Service |
646995 |
struct user_param *param;
|
|
Packit Service |
646995 |
struct iovec *iovs = NULL;
|
|
Packit Service |
646995 |
struct iovec *iov = NULL;
|
|
Packit Service |
646995 |
int fd, rc = 0;
|
|
Packit Service |
646995 |
int param_count = 0;
|
|
Packit Service |
646995 |
int param_used = 0;
|
|
Packit Service |
646995 |
int i;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
flashnode_info = idbm_recinfo_alloc(MAX_KEYS);
|
|
Packit Service |
646995 |
if (!flashnode_info) {
|
|
Packit Service |
646995 |
log_error("Out of Memory.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&fnode, 0, sizeof(fnode));
|
|
Packit Service |
646995 |
rc = iscsi_sysfs_get_flashnode_info(&fnode, host_no, flashnode_idx);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not read info for flashnode %u, %s",
|
|
Packit Service |
646995 |
flashnode_idx, strerror(rc));
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
idbm_recinfo_flashnode(&fnode, flashnode_info);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
i = 0;
|
|
Packit Service |
646995 |
list_for_each_entry(param, params, list) {
|
|
Packit Service |
646995 |
param_count++;
|
|
Packit Service |
646995 |
rc = idbm_verify_param(flashnode_info, param->name);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry(param, params, list) {
|
|
Packit Service |
646995 |
rc = idbm_rec_update_param(flashnode_info, param->name,
|
|
Packit Service |
646995 |
param->value, 0);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* +2 for event and nlmsghdr */
|
|
Packit Service |
646995 |
param_count += 2;
|
|
Packit Service |
646995 |
iovs = calloc((param_count * sizeof(struct iovec)),
|
|
Packit Service |
646995 |
sizeof(char));
|
|
Packit Service |
646995 |
if (!iovs) {
|
|
Packit Service |
646995 |
log_error("Out of Memory.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto free_info_rec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* param_used gives actual number of iovecs used for flashnode */
|
|
Packit Service |
646995 |
param_used = flashnode_build_config(params, &fnode, iovs);
|
|
Packit Service |
646995 |
if (!param_used) {
|
|
Packit Service |
646995 |
log_error("Build flashnode config failed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
goto free_iovec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
goto free_iovec;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_info("Update flashnode %u.", flashnode_idx);
|
|
Packit Service |
646995 |
rc = ipc->set_flash_node_params(t->handle, host_no, flashnode_idx,
|
|
Packit Service |
646995 |
iovs, param_count);
|
|
Packit Service |
646995 |
if (rc < 0)
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free_iovec:
|
|
Packit Service |
646995 |
/* start at 2, because 0 is for nlmsghdr and 1 for event */
|
|
Packit Service |
646995 |
iov = iovs + 2;
|
|
Packit Service |
646995 |
for (i = 0; i < param_used; i++, iov++) {
|
|
Packit Service |
646995 |
if (iov->iov_base)
|
|
Packit Service |
646995 |
free(iov->iov_base);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free(iovs);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free_info_rec:
|
|
Packit Service |
646995 |
if (flashnode_info)
|
|
Packit Service |
646995 |
free(flashnode_info);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
int iscsi_new_flashnode(struct iscsi_transport *t, uint32_t host_no, char *val,
|
|
Packit Service |
646995 |
uint32_t *flashnode_idx)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int fd, rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
goto exit_new_flashnode;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_info("Create new flashnode for host %u.", host_no);
|
|
Packit Service |
646995 |
rc = ipc->new_flash_node(t->handle, host_no, val, flashnode_idx);
|
|
Packit Service |
646995 |
if (rc < 0)
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_new_flashnode:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
int iscsi_del_flashnode(struct iscsi_transport *t, uint32_t host_no,
|
|
Packit Service |
646995 |
uint32_t flashnode_idx)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int fd, rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
goto exit_del_flashnode;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_info("Delete flashnode %u.", flashnode_idx);
|
|
Packit Service |
646995 |
rc = ipc->del_flash_node(t->handle, host_no, flashnode_idx);
|
|
Packit Service |
646995 |
if (rc < 0)
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_del_flashnode:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
int iscsi_login_flashnode(struct iscsi_transport *t, uint32_t host_no,
|
|
Packit Service |
646995 |
uint32_t flashnode_idx)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int fd, rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
goto exit_login_flashnode;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_info("Login to flashnode %u.", flashnode_idx);
|
|
Packit Service |
646995 |
rc = ipc->login_flash_node(t->handle, host_no, flashnode_idx);
|
|
Packit Service |
646995 |
if (rc == -EPERM)
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_SESS_EXISTS;
|
|
Packit Service |
646995 |
else if (rc < 0)
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_LOGIN;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_login_flashnode:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
int iscsi_logout_flashnode(struct iscsi_transport *t, uint32_t host_no,
|
|
Packit Service |
646995 |
uint32_t flashnode_idx)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int fd, rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
goto exit_logout;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_info("Logout flashnode %u.", flashnode_idx);
|
|
Packit Service |
646995 |
rc = ipc->logout_flash_node(t->handle, host_no, flashnode_idx);
|
|
Packit Service |
646995 |
if (rc == -ESRCH)
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_SESS_NOT_FOUND;
|
|
Packit Service |
646995 |
else if (rc < 0)
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_LOGOUT;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_logout:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int iscsi_check_session_use_count(uint32_t sid) {
|
|
Packit Service |
646995 |
char *config_file;
|
|
Packit Service |
646995 |
char *safe_logout;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
config_file = get_config_file();
|
|
Packit Service |
646995 |
if (!config_file) {
|
|
Packit Service |
646995 |
log_error("Could not get config file from iscsid");
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
safe_logout = cfg_get_string_param(config_file, "iscsid.safe_logout");
|
|
Packit Service |
646995 |
if (!safe_logout || strcmp(safe_logout, "Yes"))
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return session_in_use(sid);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
int iscsi_logout_flashnode_sid(struct iscsi_transport *t, uint32_t host_no,
|
|
Packit Service |
646995 |
uint32_t sid)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int fd, rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (iscsi_check_session_use_count(sid)) {
|
|
Packit Service |
646995 |
log_error("Session is actively in use for mounted storage, "
|
|
Packit Service |
646995 |
"and iscsid.safe_logout is configured.");
|
|
Packit Service |
646995 |
return ISCSI_ERR_BUSY;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
goto exit_logout_sid;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_info("Logout sid %u.", sid);
|
|
Packit Service |
646995 |
rc = ipc->logout_flash_node_sid(t->handle, host_no, sid);
|
|
Packit Service |
646995 |
if (rc < 0) {
|
|
Packit Service |
646995 |
log_error("Logout of sid %u failed.", sid);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_LOGOUT;
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
log_info("Logout of sid %u successful.", sid);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_logout_sid:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int exec_flashnode_op(int op, int info_level, uint32_t host_no,
|
|
Packit Service |
646995 |
uint64_t fnode_idx, int type,
|
|
Packit Service |
646995 |
struct list_head *params)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct iscsi_transport *t = NULL;
|
|
Packit Service |
646995 |
int rc = ISCSI_SUCCESS;
|
|
Packit Service |
646995 |
char *portal_type;
|
|
Packit Service |
646995 |
uint32_t flashnode_idx;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (op != OP_SHOW && op != OP_NOOP && op != OP_NEW &&
|
|
Packit Service |
646995 |
fnode_idx > MAX_FLASHNODE_IDX) {
|
|
Packit Service |
646995 |
log_error("Invalid flashnode index");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto exit_flashnode_op;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
flashnode_idx = (uint32_t)fnode_idx;
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_hba(host_no);
|
|
Packit Service |
646995 |
if (!t) {
|
|
Packit Service |
646995 |
log_error("Could not match hostno %u to transport.", host_no);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_TRANS_NOT_FOUND;
|
|
Packit Service |
646995 |
goto exit_flashnode_op;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
switch (op) {
|
|
Packit Service |
646995 |
case OP_NOOP:
|
|
Packit Service |
646995 |
case OP_SHOW:
|
|
Packit Service |
646995 |
if (fnode_idx > MAX_FLASHNODE_IDX)
|
|
Packit Service |
646995 |
rc = list_flashnodes(info_level, host_no);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
rc = get_flashnode_info(host_no, flashnode_idx);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_NEW:
|
|
Packit Service |
646995 |
if (type == IPV4) {
|
|
Packit Service |
646995 |
portal_type = "ipv4";
|
|
Packit Service |
646995 |
} else if (type == IPV6) {
|
|
Packit Service |
646995 |
portal_type = "ipv6";
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
log_error("Invalid type mentioned for flashnode");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto exit_flashnode_op;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
rc = iscsi_new_flashnode(t, host_no, portal_type,
|
|
Packit Service |
646995 |
&flashnode_idx);
|
|
Packit Service |
646995 |
if (!rc)
|
|
Packit Service |
646995 |
log_info("New flashnode for host %u added at index %u.",
|
|
Packit Service |
646995 |
host_no, flashnode_idx);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
log_error("Creation of flashnode for host %u failed.",
|
|
Packit Service |
646995 |
host_no);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_DELETE:
|
|
Packit Service |
646995 |
rc = iscsi_del_flashnode(t, host_no, flashnode_idx);
|
|
Packit Service |
646995 |
if (!rc)
|
|
Packit Service |
646995 |
log_info("Flashnode %u of host %u deleted.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
log_error("Deletion of flashnode %u of host %u failed.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_UPDATE:
|
|
Packit Service |
646995 |
rc = iscsi_set_flashnode_params(t, host_no, flashnode_idx,
|
|
Packit Service |
646995 |
params);
|
|
Packit Service |
646995 |
if (!rc)
|
|
Packit Service |
646995 |
log_info("Update for flashnode %u of host %u successful.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
log_error("Update for flashnode %u of host %u failed.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_LOGIN:
|
|
Packit Service |
646995 |
rc = iscsi_login_flashnode(t, host_no, flashnode_idx);
|
|
Packit Service |
646995 |
if (!rc)
|
|
Packit Service |
646995 |
log_info("Login to flashnode %u of host %u successful.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
else if (rc == ISCSI_ERR_SESS_EXISTS)
|
|
Packit Service |
646995 |
log_info("Flashnode %u of host %u already logged in.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
log_error("Login to flashnode %u of host %u failed.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_LOGOUT:
|
|
Packit Service |
646995 |
rc = iscsi_logout_flashnode(t, host_no, flashnode_idx);
|
|
Packit Service |
646995 |
if (!rc)
|
|
Packit Service |
646995 |
log_info("Logout of flashnode %u of host %u successful.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
else if (rc == ISCSI_ERR_SESS_NOT_FOUND)
|
|
Packit Service |
646995 |
log_info("Flashnode %u of host %u not logged in.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
log_error("Logout of flashnode %u of host %u failed.",
|
|
Packit Service |
646995 |
flashnode_idx, host_no);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
log_error("Invalid operation");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_flashnode_op:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void print_host_stats(struct iscsi_offload_host_stats *host_stats)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
/* MAC */
|
|
Packit Service |
646995 |
printf("Host Statistics:\n"
|
|
Packit Service |
646995 |
"\tmactx_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_bytes: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_multicast_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_broadcast_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_pause_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_control_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_deferral: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_excess_deferral: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_late_collision: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_abort: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_single_collision: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_multiple_collision: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_collision: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_frames_dropped: %lld\n"
|
|
Packit Service |
646995 |
"\tmactx_jumbo_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_bytes: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_unknown_control_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_pause_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_control_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_dribble: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_frame_length_error: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_jabber: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_carrier_sense_error: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_frame_discarded: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_frames_dropped: %lld\n"
|
|
Packit Service |
646995 |
"\tmac_crc_error: %lld\n"
|
|
Packit Service |
646995 |
"\tmac_encoding_error: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_length_error_large: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_length_error_small: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_multicast_frames: %lld\n"
|
|
Packit Service |
646995 |
"\tmacrx_broadcast_frames: %lld\n"
|
|
Packit Service |
646995 |
/* IP */
|
|
Packit Service |
646995 |
"\tiptx_packets: %lld\n"
|
|
Packit Service |
646995 |
"\tiptx_bytes: %lld\n"
|
|
Packit Service |
646995 |
"\tiptx_fragments: %lld\n"
|
|
Packit Service |
646995 |
"\tiprx_packets: %lld\n"
|
|
Packit Service |
646995 |
"\tiprx_bytes: %lld\n"
|
|
Packit Service |
646995 |
"\tiprx_fragments: %lld\n"
|
|
Packit Service |
646995 |
"\tip_datagram_reassembly: %lld\n"
|
|
Packit Service |
646995 |
"\tip_invalid_address_error: %lld\n"
|
|
Packit Service |
646995 |
"\tip_error_packets: %lld\n"
|
|
Packit Service |
646995 |
"\tip_fragrx_overlap: %lld\n"
|
|
Packit Service |
646995 |
"\tip_fragrx_outoforder: %lld\n"
|
|
Packit Service |
646995 |
"\tip_datagram_reassembly_timeout: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6tx_packets: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6tx_bytes: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6tx_fragments: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6rx_packets: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6rx_bytes: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6rx_fragments: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6_datagram_reassembly: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6_invalid_address_error: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6_error_packets: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6_fragrx_overlap: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6_fragrx_outoforder: %lld\n"
|
|
Packit Service |
646995 |
"\tipv6_datagram_reassembly_timeout: %lld\n"
|
|
Packit Service |
646995 |
/* TCP */
|
|
Packit Service |
646995 |
"\ttcptx_segments: %lld\n"
|
|
Packit Service |
646995 |
"\ttcptx_bytes: %lld\n"
|
|
Packit Service |
646995 |
"\ttcprx_segments: %lld\n"
|
|
Packit Service |
646995 |
"\ttcprx_byte: %lld\n"
|
|
Packit Service |
646995 |
"\ttcp_duplicate_ack_retx: %lld\n"
|
|
Packit Service |
646995 |
"\ttcp_retx_timer_expired: %lld\n"
|
|
Packit Service |
646995 |
"\ttcprx_duplicate_ack: %lld\n"
|
|
Packit Service |
646995 |
"\ttcprx_pure_ackr: %lld\n"
|
|
Packit Service |
646995 |
"\ttcptx_delayed_ack: %lld\n"
|
|
Packit Service |
646995 |
"\ttcptx_pure_ack: %lld\n"
|
|
Packit Service |
646995 |
"\ttcprx_segment_error: %lld\n"
|
|
Packit Service |
646995 |
"\ttcprx_segment_outoforder: %lld\n"
|
|
Packit Service |
646995 |
"\ttcprx_window_probe: %lld\n"
|
|
Packit Service |
646995 |
"\ttcprx_window_update: %lld\n"
|
|
Packit Service |
646995 |
"\ttcptx_window_probe_persist: %lld\n"
|
|
Packit Service |
646995 |
/* ECC */
|
|
Packit Service |
646995 |
"\tecc_error_correction: %lld\n"
|
|
Packit Service |
646995 |
/* iSCSI */
|
|
Packit Service |
646995 |
"\tiscsi_pdu_tx: %lld\n"
|
|
Packit Service |
646995 |
"\tiscsi_data_bytes_tx: %lld\n"
|
|
Packit Service |
646995 |
"\tiscsi_pdu_rx: %lld\n"
|
|
Packit Service |
646995 |
"\tiscsi_data_bytes_rx: %lld\n"
|
|
Packit Service |
646995 |
"\tiscsi_io_completed: %lld\n"
|
|
Packit Service |
646995 |
"\tiscsi_unexpected_io_rx: %lld\n"
|
|
Packit Service |
646995 |
"\tiscsi_format_error: %lld\n"
|
|
Packit Service |
646995 |
"\tiscsi_hdr_digest_error: %lld\n"
|
|
Packit Service |
646995 |
"\tiscsi_data_digest_error: %lld\n"
|
|
Packit Service |
646995 |
"\tiscsi_sequence_error: %lld\n",
|
|
Packit Service |
646995 |
/* MAC */
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_bytes,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_multicast_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_broadcast_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_pause_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_control_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_deferral,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_excess_deferral,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_late_collision,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_abort,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_single_collision,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_multiple_collision,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_collision,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_frames_dropped,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mactx_jumbo_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_bytes,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_unknown_control_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_pause_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_control_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_dribble,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_frame_length_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_jabber,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_carrier_sense_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_frame_discarded,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_frames_dropped,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mac_crc_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->mac_encoding_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_length_error_large,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_length_error_small,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_multicast_frames,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->macrx_broadcast_frames,
|
|
Packit Service |
646995 |
/* IP */
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iptx_packets,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iptx_bytes,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iptx_fragments,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iprx_packets,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iprx_bytes,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iprx_fragments,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ip_datagram_reassembly,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ip_invalid_address_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ip_error_packets,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ip_fragrx_overlap,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ip_fragrx_outoforder,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ip_datagram_reassembly_timeout,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6tx_packets,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6tx_bytes,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6tx_fragments,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6rx_packets,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6rx_bytes,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6rx_fragments,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6_datagram_reassembly,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6_invalid_address_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6_error_packets,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6_fragrx_overlap,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6_fragrx_outoforder,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ipv6_datagram_reassembly_timeout,
|
|
Packit Service |
646995 |
/* TCP */
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcptx_segments,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcptx_bytes,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcprx_segments,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcprx_byte,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcp_duplicate_ack_retx,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcp_retx_timer_expired,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcprx_duplicate_ack,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcprx_pure_ackr,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcptx_delayed_ack,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcptx_pure_ack,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcprx_segment_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcprx_segment_outoforder,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcprx_window_probe,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcprx_window_update,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->tcptx_window_probe_persist,
|
|
Packit Service |
646995 |
/* ECC */
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->ecc_error_correction,
|
|
Packit Service |
646995 |
/* iSCSI */
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_pdu_tx,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_data_bytes_tx,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_pdu_rx,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_data_bytes_rx,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_io_completed,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_unexpected_io_rx,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_format_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_hdr_digest_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_data_digest_error,
|
|
Packit Service |
646995 |
(unsigned long long)host_stats->iscsi_sequence_error);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int exec_host_stats_op(__attribute__((unused))int op,
|
|
Packit Service |
646995 |
__attribute__((unused))int info_level,
|
|
Packit Service |
646995 |
uint32_t host_no)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct iscsi_transport *t = NULL;
|
|
Packit Service |
646995 |
char *req_buf = NULL;
|
|
Packit Service |
646995 |
int rc = ISCSI_SUCCESS;
|
|
Packit Service |
646995 |
int fd = 0, buf_size = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_hba(host_no);
|
|
Packit Service |
646995 |
if (!t) {
|
|
Packit Service |
646995 |
log_error("Could not match hostno %u to transport.", host_no);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_TRANS_NOT_FOUND;
|
|
Packit Service |
646995 |
goto exit_host_stats;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
buf_size = sizeof(struct iscsi_offload_host_stats) +
|
|
Packit Service |
646995 |
sizeof(struct iscsi_uevent);
|
|
Packit Service |
646995 |
req_buf = calloc(1, buf_size);
|
|
Packit Service |
646995 |
if (!req_buf) {
|
|
Packit Service |
646995 |
log_error("Could not allocate memory for host stats request.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto exit_host_stats;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = ipc->ctldev_open();
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INTERNAL;
|
|
Packit Service |
646995 |
log_error("Netlink open failed.");
|
|
Packit Service |
646995 |
goto exit_host_stats;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = ipc->get_host_stats(t->handle, host_no, req_buf);
|
|
Packit Service |
646995 |
if (rc < 0) {
|
|
Packit Service |
646995 |
log_error("get_host_stats failed. errno=%d", errno);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
goto exit_host_stats;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
print_host_stats((struct iscsi_offload_host_stats *)(req_buf +
|
|
Packit Service |
646995 |
sizeof(struct iscsi_uevent)));
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ipc->ctldev_close();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
exit_host_stats:
|
|
Packit Service |
646995 |
free(req_buf);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int verify_iface_params(struct list_head *params, struct node_rec *rec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct user_param *param;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry(param, params, list) {
|
|
Packit Service |
646995 |
if (!strcmp(param->name, IFACE_ISCSINAME)) {
|
|
Packit Service |
646995 |
log_error("Can not update "
|
|
Packit Service |
646995 |
"iface.iscsi_ifacename. Delete it, "
|
|
Packit Service |
646995 |
"and then create a new one.");
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (iface_is_bound_by_hwaddr(&rec->iface) &&
|
|
Packit Service |
646995 |
!strcmp(param->name, IFACE_NETNAME)) {
|
|
Packit Service |
646995 |
log_error("Can not update interface binding "
|
|
Packit Service |
646995 |
"from hwaddress to net_ifacename. "
|
|
Packit Service |
646995 |
"You must delete the interface and "
|
|
Packit Service |
646995 |
"create a new one");
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (iface_is_bound_by_netdev(&rec->iface) &&
|
|
Packit Service |
646995 |
!strcmp(param->name, IFACE_HWADDR)) {
|
|
Packit Service |
646995 |
log_error("Can not update interface binding "
|
|
Packit Service |
646995 |
"from net_ifacename to hwaddress. "
|
|
Packit Service |
646995 |
"You must delete the interface and "
|
|
Packit Service |
646995 |
"create a new one");
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void _print_iface_tree(struct iscsi_node **nodes, uint32_t node_count,
|
|
Packit Service |
646995 |
const char *iface_name,
|
|
Packit Service |
646995 |
struct iscsi_node **matched_nodes)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct iscsi_node *node = NULL;
|
|
Packit Service |
646995 |
uint32_t matched_node_count = 0;
|
|
Packit Service |
646995 |
uint32_t i = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
for (i = 0; i < node_count; ++i) {
|
|
Packit Service |
646995 |
node = nodes[i];
|
|
Packit Service |
646995 |
if (strcmp(iface_name, iscsi_node_iface_name_get(node))
|
|
Packit Service |
646995 |
== 0)
|
|
Packit Service |
646995 |
matched_nodes[matched_node_count++] = node;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
printf("Iface: %s\n", iface_name);
|
|
Packit Service |
646995 |
print_nodes_tree(matched_nodes, matched_node_count, _PRINT_MODE_IFACE);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int print_iface_tree(struct iscsi_context *ctx,
|
|
Packit Service |
646995 |
const char *iface_name)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
struct iscsi_node **nodes = NULL;
|
|
Packit Service |
646995 |
struct iscsi_node **matched_nodes = NULL;
|
|
Packit Service |
646995 |
uint32_t node_count = 0;
|
|
Packit Service |
646995 |
struct iscsi_iface *iface = NULL;
|
|
Packit Service |
646995 |
struct iscsi_iface **ifaces = NULL;
|
|
Packit Service |
646995 |
uint32_t iface_count = 0;
|
|
Packit Service |
646995 |
uint32_t i = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
_good(iscsi_nodes_get(ctx, &nodes, &node_count),
|
|
Packit Service |
646995 |
rc, out);
|
|
Packit Service |
646995 |
if (node_count == 0)
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
matched_nodes = calloc(node_count, sizeof(struct iscsi_node *));
|
|
Packit Service |
646995 |
if (matched_nodes == NULL) {
|
|
Packit Service |
646995 |
log_error("No memory");
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (iface_name != NULL) {
|
|
Packit Service |
646995 |
// Just make sure specified iface exists
|
|
Packit Service |
646995 |
_good(iscsi_iface_get(ctx, iface_name, &iface), rc, out);
|
|
Packit Service |
646995 |
_print_iface_tree(nodes, node_count, iface_name,
|
|
Packit Service |
646995 |
matched_nodes);
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
_good(iscsi_ifaces_get(ctx, &ifaces, &iface_count),
|
|
Packit Service |
646995 |
rc, out);
|
|
Packit Service |
646995 |
for (i = 0; i < iface_count; ++i)
|
|
Packit Service |
646995 |
_print_iface_tree(nodes, node_count,
|
|
Packit Service |
646995 |
iscsi_iface_name_get(ifaces[i]),
|
|
Packit Service |
646995 |
matched_nodes);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
out:
|
|
Packit Service |
646995 |
free(matched_nodes);
|
|
Packit Service |
646995 |
iscsi_ifaces_free(ifaces, iface_count);
|
|
Packit Service |
646995 |
iscsi_iface_free(iface);
|
|
Packit Service |
646995 |
iscsi_nodes_free(nodes, node_count);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int iface_param_update(struct iface_rec *iface, struct list_head *params)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct node_rec *rec;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rec = idbm_create_rec(NULL, -1, NULL, -1, iface, 1);
|
|
Packit Service |
646995 |
if (!rec) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto update_fail;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (iscsi_check_for_running_session(rec))
|
|
Packit Service |
646995 |
log_warning("Updating iface while iscsi sessions "
|
|
Packit Service |
646995 |
"are using it. You must logout the running "
|
|
Packit Service |
646995 |
"sessions then log back in for the "
|
|
Packit Service |
646995 |
"new settings to take affect.");
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = verify_iface_params(params, rec);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto update_fail;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iface_conf_update(params, &rec->iface);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto update_fail;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = __for_each_matched_rec(0, rec, params, idbm_node_set_param);
|
|
Packit Service |
646995 |
if (rc == ISCSI_ERR_NO_OBJS_FOUND)
|
|
Packit Service |
646995 |
rc = 0;
|
|
Packit Service |
646995 |
else if (rc)
|
|
Packit Service |
646995 |
goto update_fail;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
printf("%s updated.\n", iface->name);
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
update_fail:
|
|
Packit Service |
646995 |
log_error("Could not update iface %s: %s",
|
|
Packit Service |
646995 |
iface->name, iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
struct iface_param_sync {
|
|
Packit Service |
646995 |
struct iface_rec *primary;
|
|
Packit Service |
646995 |
struct list_head *params;
|
|
Packit Service |
646995 |
int count;
|
|
Packit Service |
646995 |
};
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int update_sync_params(void *data, struct iface_rec *iface)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct iface_param_sync *iface_params = data;
|
|
Packit Service |
646995 |
struct iface_rec *primary = iface_params->primary;
|
|
Packit Service |
646995 |
struct list_head *params = iface_params->params;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if ((strcmp(primary->transport_name, iface->transport_name)) ||
|
|
Packit Service |
646995 |
(strcmp(primary->hwaddress, iface->hwaddress)) ||
|
|
Packit Service |
646995 |
(primary->iface_num != iface->iface_num))
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return iface_param_update(iface, params);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int split_vlan_params(struct list_head *params, struct list_head *vlan_params)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct user_param *param, *tmp;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry_safe(param, tmp, params, list) {
|
|
Packit Service |
646995 |
if (!strncmp(param->name, "iface.vlan", 10)) {
|
|
Packit Service |
646995 |
list_move_tail(¶m->list, vlan_params);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static inline void list_splice_tail(struct list_head *list, struct list_head *head)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
list->prev->next = head;
|
|
Packit Service |
646995 |
list->next->prev = head->prev;
|
|
Packit Service |
646995 |
head->prev->next = list->next;
|
|
Packit Service |
646995 |
head->prev = list->prev;
|
|
Packit Service |
646995 |
INIT_LIST_HEAD(list);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* TODO: merge iter helpers and clean them up, so we can use them here */
|
|
Packit Service |
646995 |
static int exec_iface_op(struct iscsi_context *ctx,
|
|
Packit Service |
646995 |
int op,
|
|
Packit Service |
646995 |
__attribute__((unused))int do_show,
|
|
Packit Service |
646995 |
int info_level,
|
|
Packit Service |
646995 |
struct iface_rec *iface,
|
|
Packit Service |
646995 |
uint64_t host_no,
|
|
Packit Service |
646995 |
struct list_head *params)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct host_info hinfo;
|
|
Packit Service |
646995 |
struct node_rec *rec = NULL;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
struct iscsi_iface **ifaces = NULL;
|
|
Packit Service |
646995 |
struct iscsi_iface *iface_info = NULL;
|
|
Packit Service |
646995 |
uint32_t iface_count = 0;
|
|
Packit Service |
646995 |
uint32_t i = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
LIST_HEAD(vlan_params);
|
|
Packit Service |
646995 |
struct iscsi_transport *t;
|
|
Packit Service |
646995 |
switch (op) {
|
|
Packit Service |
646995 |
case OP_NEW:
|
|
Packit Service |
646995 |
if (!iface) {
|
|
Packit Service |
646995 |
log_error("Could not add interface. No interface "
|
|
Packit Service |
646995 |
"passed in.");
|
|
Packit Service |
646995 |
return EINVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rec = idbm_create_rec(NULL, -1, NULL, -1, iface, 0);
|
|
Packit Service |
646995 |
if (rec && iscsi_check_for_running_session(rec)) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_SESS_EXISTS;
|
|
Packit Service |
646995 |
goto new_fail;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
iface_setup_defaults(iface);
|
|
Packit Service |
646995 |
rc = iface_conf_write(iface);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto new_fail;
|
|
Packit Service |
646995 |
printf("New interface %s added\n", iface->name);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
new_fail:
|
|
Packit Service |
646995 |
log_error("Could not create new interface %s.", iface->name);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_DELETE:
|
|
Packit Service |
646995 |
if (!iface) {
|
|
Packit Service |
646995 |
log_error("Could not delete interface. No interface "
|
|
Packit Service |
646995 |
"passed in.");
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rec = idbm_create_rec(NULL, -1, NULL, -1, iface, 1);
|
|
Packit Service |
646995 |
if (!rec) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto delete_fail;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* logout and delete records using it first */
|
|
Packit Service |
646995 |
rc = __for_each_matched_rec(0, rec, NULL, delete_node);
|
|
Packit Service |
646995 |
if (rc && rc != ISCSI_ERR_NO_OBJS_FOUND)
|
|
Packit Service |
646995 |
goto delete_fail;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iface_conf_delete(iface);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto delete_fail;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
printf("%s unbound and deleted.\n", iface->name);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
delete_fail:
|
|
Packit Service |
646995 |
log_error("Could not delete iface %s: %s", iface->name,
|
|
Packit Service |
646995 |
iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_UPDATE:
|
|
Packit Service |
646995 |
if (!iface || list_empty(params)) {
|
|
Packit Service |
646995 |
log_error("Update requires name, value, and iface.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rec = idbm_create_rec(NULL, -1, NULL, -1, iface, 1);
|
|
Packit Service |
646995 |
if (!rec) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_name(rec->iface.transport_name);
|
|
Packit Service |
646995 |
if (!t) {
|
|
Packit Service |
646995 |
log_error("Cound not locate transport for iface %s", iface->name);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
if (t->template->sync_vlan_settings) {
|
|
Packit Service |
646995 |
/* sync shared vlan settings across ifaces */
|
|
Packit Service |
646995 |
int nr_found = 0;
|
|
Packit Service |
646995 |
struct iface_param_sync sync_params = {
|
|
Packit Service |
646995 |
.primary = &rec->iface,
|
|
Packit Service |
646995 |
.params = &vlan_params,
|
|
Packit Service |
646995 |
.count = 0,
|
|
Packit Service |
646995 |
};
|
|
Packit Service |
646995 |
split_vlan_params(params, &vlan_params);
|
|
Packit Service |
646995 |
iface_for_each_iface(&sync_params, 1, &nr_found, update_sync_params);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
iface_param_update(&rec->iface, params);
|
|
Packit Service |
646995 |
list_splice_tail(&vlan_params, params);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_APPLY:
|
|
Packit Service |
646995 |
if (!iface) {
|
|
Packit Service |
646995 |
log_error("Apply requires iface.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
rc = iface_conf_read(iface);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not read iface %s (%d).",
|
|
Packit Service |
646995 |
iface->name, rc);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iface_apply_net_config(iface, op);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not apply net configuration: %s",
|
|
Packit Service |
646995 |
iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
printf("%s applied.\n", iface->name);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case OP_APPLY_ALL:
|
|
Packit Service |
646995 |
if (host_no > MAX_HOST_NO) {
|
|
Packit Service |
646995 |
log_error("Applyall requires a valid host number or MAC"
|
|
Packit Service |
646995 |
" passed in with the --host argument.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Need to get other iface info like transport.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
memset(&hinfo, 0, sizeof(struct host_info));
|
|
Packit Service |
646995 |
hinfo.host_no = host_no;
|
|
Packit Service |
646995 |
if (iscsi_sysfs_get_hostinfo_by_host_no(&hinfo)) {
|
|
Packit Service |
646995 |
log_error("Could not match host%" PRIu64 " to ifaces.",
|
|
Packit Service |
646995 |
host_no);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
rc = iface_apply_net_config(&hinfo.iface, op);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not apply net configuration: %s",
|
|
Packit Service |
646995 |
iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
printf("Applied settings to ifaces attached to host%" PRIu64 ".\n",
|
|
Packit Service |
646995 |
host_no);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
if ((op != OP_NOOP) && (op != OP_SHOW)) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
switch (info_level) {
|
|
Packit Service |
646995 |
case 0:
|
|
Packit Service |
646995 |
case -1:
|
|
Packit Service |
646995 |
if (iface == NULL) {
|
|
Packit Service |
646995 |
_good(iscsi_ifaces_get(ctx, &ifaces,
|
|
Packit Service |
646995 |
&iface_count),
|
|
Packit Service |
646995 |
rc, out);
|
|
Packit Service |
646995 |
if (iface_count == 0) {
|
|
Packit Service |
646995 |
log_error("No interfaces found.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
for (i = 0; i < iface_count; ++i)
|
|
Packit Service |
646995 |
iface_print_flat(ifaces[i]);
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
_good(iscsi_iface_get(ctx, iface->name,
|
|
Packit Service |
646995 |
&iface_info),
|
|
Packit Service |
646995 |
rc, out);
|
|
Packit Service |
646995 |
iscsi_iface_print_config(iface_info);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 1:
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* TODO: we can display how the ifaces are related to
|
|
Packit Service |
646995 |
* node records.
|
|
Packit Service |
646995 |
* And we can add a scsi_host mode which would display
|
|
Packit Service |
646995 |
* how sessions are related to hosts (scsi_host and
|
|
Packit Service |
646995 |
* iscsi_sessions are the currently running instance of
|
|
Packit Service |
646995 |
* an iface or node record).
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* TODO(Gris Ge): Once we have node support from
|
|
Packit Service |
646995 |
* libopeniscsiusr, change below codes.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
rc = print_iface_tree(ctx, iface ? iface->name : NULL);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
log_error("Invalid info level %d. Try 0 - 1.",
|
|
Packit Service |
646995 |
info_level);
|
|
Packit Service |
646995 |
rc = LIBISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
out:
|
|
Packit Service |
646995 |
iscsi_ifaces_free(ifaces, iface_count);
|
|
Packit Service |
646995 |
iscsi_iface_free(iface_info);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (rec)
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int verify_node_params(struct list_head *params, struct node_rec *rec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct user_param *param;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (list_empty(params)) {
|
|
Packit Service |
646995 |
log_error("update requires name and value");
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry(param, params, list) {
|
|
Packit Service |
646995 |
/* compat - old tools used node and iface transport name */
|
|
Packit Service |
646995 |
if (!strncmp(param->name, "iface.", 6) &&
|
|
Packit Service |
646995 |
strcmp(param->name, "iface.transport_name")) {
|
|
Packit Service |
646995 |
log_error("Cannot modify %s. Use iface mode to update "
|
|
Packit Service |
646995 |
"this value.", param->name);
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strcmp(param->name, "node.transport_name")) {
|
|
Packit Service |
646995 |
free(param->name);
|
|
Packit Service |
646995 |
param->name = strdup("iface.transport_name");
|
|
Packit Service |
646995 |
if (!param->name) {
|
|
Packit Service |
646995 |
log_error("Could not allocate memory for "
|
|
Packit Service |
646995 |
"param.");
|
|
Packit Service |
646995 |
return ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* tmp hack - we added compat crap above for the transport,
|
|
Packit Service |
646995 |
* but want to fix Doran's issue in this release too. However
|
|
Packit Service |
646995 |
* his patch is too harsh on many settings and we do not have
|
|
Packit Service |
646995 |
* time to update apps so we have this tmp hack until we
|
|
Packit Service |
646995 |
* can settle on a good interface that distros can use
|
|
Packit Service |
646995 |
* and we can mark stable.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (!strcmp(param->name, "iface.transport_name")) {
|
|
Packit Service |
646995 |
if (iscsi_check_for_running_session(rec)) {
|
|
Packit Service |
646995 |
log_warning("Cannot modify node/iface "
|
|
Packit Service |
646995 |
"transport name while a session "
|
|
Packit Service |
646995 |
"is using it. Log out the session "
|
|
Packit Service |
646995 |
"then update record.");
|
|
Packit Service |
646995 |
return ISCSI_ERR_SESS_EXISTS;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* TODO cleanup arguments */
|
|
Packit Service |
646995 |
static int exec_node_op(struct iscsi_context *ctx, int op, int do_login,
|
|
Packit Service |
646995 |
int do_logout, int do_show, int do_rescan, int do_stats,
|
|
Packit Service |
646995 |
bool wait, int info_level, struct node_rec *rec,
|
|
Packit Service |
646995 |
struct list_head *params)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (rec)
|
|
Packit Service |
646995 |
log_debug(2, "%s: %s:%s node [%s,%s,%d] sid %u", __FUNCTION__,
|
|
Packit Service |
646995 |
rec->iface.transport_name, rec->iface.name,
|
|
Packit Service |
646995 |
rec->name, rec->conn[0].address, rec->conn[0].port,
|
|
Packit Service |
646995 |
rec->session.sid);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (op == OP_NEW) {
|
|
Packit Service |
646995 |
rc = add_static_recs(rec);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (do_rescan) {
|
|
Packit Service |
646995 |
rc = for_each_session(rec, rescan_portal, 1);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (do_stats) {
|
|
Packit Service |
646995 |
rc = for_each_session(rec, session_stats, 0);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (do_login && do_logout) {
|
|
Packit Service |
646995 |
log_error("Invalid parameters. Both login and logout passed in");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if ((do_login || do_logout) && op > OP_NOOP) {
|
|
Packit Service |
646995 |
log_error("Invalid parameters. Login/logout and op passed in");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if ((!do_login && !do_logout && op == OP_NOOP) &&
|
|
Packit Service |
646995 |
((rec == NULL) ||
|
|
Packit Service |
646995 |
(!strlen(rec->name) && !strlen(rec->conn[0].address) &&
|
|
Packit Service |
646995 |
!strlen(rec->iface.name)))) {
|
|
Packit Service |
646995 |
rc = print_nodes(ctx, info_level);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (do_login) {
|
|
Packit Service |
646995 |
rc = login_portals(rec, wait);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (do_logout) {
|
|
Packit Service |
646995 |
int nr_found;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iscsi_logout_portals(rec, &nr_found, 1,
|
|
Packit Service |
646995 |
iscsi_logout_matched_portal);
|
|
Packit Service |
646995 |
if (rc == ISCSI_ERR_NO_OBJS_FOUND)
|
|
Packit Service |
646995 |
log_error("No matching sessions found");
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (op == OP_NOOP || (!do_login && !do_logout && op == OP_SHOW)) {
|
|
Packit Service |
646995 |
rc = print_nodes_config(ctx, do_show ? true : false,
|
|
Packit Service |
646995 |
rec->name, rec->conn[0].address,
|
|
Packit Service |
646995 |
rec->conn[0].port, rec->iface.name);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (op == OP_UPDATE) {
|
|
Packit Service |
646995 |
rc = verify_node_params(params, rec);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = for_each_matched_rec(rec, params, idbm_node_set_param);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
} else if (op == OP_DELETE) {
|
|
Packit Service |
646995 |
rc = for_each_matched_rec(rec, NULL, delete_node);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
log_error("operation is not supported.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
out:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int exec_fw_disc_op(discovery_rec_t *drec, struct list_head *ifaces,
|
|
Packit Service |
646995 |
int info_level, int do_login, int op)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
LIST_HEAD(targets);
|
|
Packit Service |
646995 |
LIST_HEAD(rec_list);
|
|
Packit Service |
646995 |
LIST_HEAD(new_ifaces);
|
|
Packit Service |
646995 |
struct iface_rec *iface, *tmp_iface;
|
|
Packit Service |
646995 |
struct node_rec *rec, *tmp_rec;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* compat: if the user did not pass any op then we do all
|
|
Packit Service |
646995 |
* ops for them
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (!op)
|
|
Packit Service |
646995 |
op = OP_NEW | OP_DELETE | OP_UPDATE;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* if a user passed in ifaces then we use them and ignore the ibft
|
|
Packit Service |
646995 |
* net info
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (!list_empty(ifaces)) {
|
|
Packit Service |
646995 |
list_for_each_entry_safe(iface, tmp_iface, ifaces, list) {
|
|
Packit Service |
646995 |
rc = iface_conf_read(iface);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not read iface info for %s. "
|
|
Packit Service |
646995 |
"Make sure an iface config with the "
|
|
Packit Service |
646995 |
"file name and iface.iscsi_ifacename "
|
|
Packit Service |
646995 |
"%s is in %s.", iface->name,
|
|
Packit Service |
646995 |
iface->name, IFACE_CONFIG_DIR);
|
|
Packit Service |
646995 |
list_del_init(&iface->list);
|
|
Packit Service |
646995 |
free(iface);
|
|
Packit Service |
646995 |
continue;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
goto discover_fw_tgts;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Next, check if we see any offload cards. If we do then
|
|
Packit Service |
646995 |
* we make an iface if needed.
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* Note1: if there is not a offload card we do not setup
|
|
Packit Service |
646995 |
* software iscsi binding with the nic used for booting,
|
|
Packit Service |
646995 |
* because we do not know if that was intended.
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* Note2: we assume that the user probably wanted to access
|
|
Packit Service |
646995 |
* all targets through all the ifaces instead of being limited
|
|
Packit Service |
646995 |
* to what you can export in ibft.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
rc = fw_get_targets(&targets;;
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not get list of targets from firmware. "
|
|
Packit Service |
646995 |
"(err %d)", rc);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
rc = iface_create_ifaces_from_boot_contexts(&new_ifaces, &targets;;
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
if (!list_empty(&new_ifaces))
|
|
Packit Service |
646995 |
ifaces = &new_ifaces;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
discover_fw_tgts:
|
|
Packit Service |
646995 |
rc = idbm_bind_ifaces_to_nodes(discovery_fw, drec,
|
|
Packit Service |
646995 |
ifaces, &rec_list);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
log_error("Could not perform fw discovery.");
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
rc = exec_disc_op_on_recs(drec, &rec_list, info_level,
|
|
Packit Service |
646995 |
do_login, op);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
done:
|
|
Packit Service |
646995 |
fw_free_targets(&targets;;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry_safe(iface, tmp_iface, &new_ifaces, list) {
|
|
Packit Service |
646995 |
list_del(&iface->list);
|
|
Packit Service |
646995 |
free(iface);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_for_each_entry_safe(rec, tmp_rec, &rec_list, list) {
|
|
Packit Service |
646995 |
list_del(&rec->list);
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int exec_fw_op(discovery_rec_t *drec, struct list_head *ifaces,
|
|
Packit Service |
646995 |
int info_level, int do_login, int op)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct boot_context *context;
|
|
Packit Service |
646995 |
LIST_HEAD(targets);
|
|
Packit Service |
646995 |
LIST_HEAD(rec_list);
|
|
Packit Service |
646995 |
struct node_rec *rec;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (drec)
|
|
Packit Service |
646995 |
return exec_fw_disc_op(drec, ifaces, info_level, do_login, op);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* The following ops do not interact with the DB */
|
|
Packit Service |
646995 |
rc = fw_get_targets(&targets;;
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not get list of targets from firmware. "
|
|
Packit Service |
646995 |
"(err %d)", rc);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (do_login) {
|
|
Packit Service |
646995 |
list_for_each_entry(context, &targets, list) {
|
|
Packit Service |
646995 |
rec = idbm_create_rec_from_boot_context(context);
|
|
Packit Service |
646995 |
if (!rec) {
|
|
Packit Service |
646995 |
log_error("Could not convert firmware info to "
|
|
Packit Service |
646995 |
"node record.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
iscsi_login_portal(NULL, NULL, rec);
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
list_for_each_entry(context, &targets, list)
|
|
Packit Service |
646995 |
fw_print_entry(context);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fw_free_targets(&targets;;
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void setup_drec_defaults(int type, char *ip, int port,
|
|
Packit Service |
646995 |
struct discovery_rec *drec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
switch (type) {
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_ISNS:
|
|
Packit Service |
646995 |
idbm_isns_defaults(&drec->u.isns);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_SENDTARGETS:
|
|
Packit Service |
646995 |
idbm_sendtargets_defaults(&drec->u.sendtargets);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
log_error("Invalid disc type.");
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
strlcpy(drec->address, ip, sizeof(drec->address));
|
|
Packit Service |
646995 |
drec->port = port;
|
|
Packit Service |
646995 |
drec->type = type;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/**
|
|
Packit Service |
646995 |
* exec_discover - prep, add, read and exec discovery on drec
|
|
Packit Service |
646995 |
* @type: discovery type
|
|
Packit Service |
646995 |
* @ip: IP address
|
|
Packit Service |
646995 |
* @port: port
|
|
Packit Service |
646995 |
* @ifaces: list of ifaces to bind to
|
|
Packit Service |
646995 |
* @info_level: print level
|
|
Packit Service |
646995 |
* @do_login: set to 1 if discovery function should also log into portals found
|
|
Packit Service |
646995 |
* @do_discover: set to 1 if discovery was requested
|
|
Packit Service |
646995 |
* @op: ops passed in by user
|
|
Packit Service |
646995 |
* @drec: discovery rec struct
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* This function determines what type of op needs to be executed
|
|
Packit Service |
646995 |
* and will read and add a drec, and perform discovery if needed.
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* returns:
|
|
Packit Service |
646995 |
* Greater than 0 - error
|
|
Packit Service |
646995 |
* 0 - op/discovery completed
|
|
Packit Service |
646995 |
* -1 - exec db op
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
static int exec_discover(int disc_type, char *ip, int port,
|
|
Packit Service |
646995 |
struct list_head *ifaces, int info_level,
|
|
Packit Service |
646995 |
int do_login, int do_discover, int op,
|
|
Packit Service |
646995 |
struct discovery_rec *drec)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (ip == NULL) {
|
|
Packit Service |
646995 |
log_error("Please specify portal as <ipaddr>[:<ipport>]");
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (op & OP_NEW && !do_discover) {
|
|
Packit Service |
646995 |
setup_drec_defaults(disc_type, ip, port, drec);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = idbm_add_discovery(drec);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not add new discovery record.");
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
printf("New discovery record for [%s,%d] added.\n", ip,
|
|
Packit Service |
646995 |
port);
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = idbm_discovery_read(drec, disc_type, ip, port);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
if (!do_discover) {
|
|
Packit Service |
646995 |
log_error("Discovery record [%s,%d] not found.",
|
|
Packit Service |
646995 |
ip, port);
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* Just add default rec for user */
|
|
Packit Service |
646995 |
log_debug(1, "Discovery record [%s,%d] not found!",
|
|
Packit Service |
646995 |
ip, port);
|
|
Packit Service |
646995 |
setup_drec_defaults(disc_type, ip, port, drec);
|
|
Packit Service |
646995 |
if (!(op & OP_NONPERSISTENT)) {
|
|
Packit Service |
646995 |
rc = idbm_add_discovery(drec);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not add new discovery "
|
|
Packit Service |
646995 |
"record.");
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
} else if (!do_discover)
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = 0;
|
|
Packit Service |
646995 |
switch (disc_type) {
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_SENDTARGETS:
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_ISNS:
|
|
Packit Service |
646995 |
rc = do_target_discovery(drec, ifaces, info_level, do_login, op,
|
|
Packit Service |
646995 |
0);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
log_error("Unsupported discovery type.");
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int exec_disc2_op(int disc_type, char *ip, int port,
|
|
Packit Service |
646995 |
struct list_head *ifaces, int info_level, int do_login,
|
|
Packit Service |
646995 |
int do_discover, int op, struct list_head *params,
|
|
Packit Service |
646995 |
int do_show)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct discovery_rec drec;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&drec, 0, sizeof(struct discovery_rec));
|
|
Packit Service |
646995 |
drec.iscsid_req_tmo = -1;
|
|
Packit Service |
646995 |
if (disc_type != -1)
|
|
Packit Service |
646995 |
drec.type = disc_type;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
switch (disc_type) {
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_SENDTARGETS:
|
|
Packit Service |
646995 |
if (port < 0)
|
|
Packit Service |
646995 |
port = ISCSI_LISTEN_PORT;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_discover(disc_type, ip, port, ifaces, info_level,
|
|
Packit Service |
646995 |
do_login, do_discover, op, &drec);
|
|
Packit Service |
646995 |
if (rc < 0)
|
|
Packit Service |
646995 |
goto do_db_op;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_SLP:
|
|
Packit Service |
646995 |
log_error("SLP discovery is not fully implemented yet.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_ISNS:
|
|
Packit Service |
646995 |
if (port < 0)
|
|
Packit Service |
646995 |
port = ISNS_DEFAULT_PORT;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_discover(disc_type, ip, port, ifaces, info_level,
|
|
Packit Service |
646995 |
do_login, do_discover, op, &drec);
|
|
Packit Service |
646995 |
if (rc < 0)
|
|
Packit Service |
646995 |
goto do_db_op;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_FW:
|
|
Packit Service |
646995 |
if (!do_discover) {
|
|
Packit Service |
646995 |
log_error("Invalid command. Possibly missing "
|
|
Packit Service |
646995 |
"--discover argument.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
drec.type = DISCOVERY_TYPE_FW;
|
|
Packit Service |
646995 |
rc = exec_fw_op(&drec, ifaces, info_level, do_login, op);
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!ip) {
|
|
Packit Service |
646995 |
if (op == OP_NOOP || op == OP_SHOW) {
|
|
Packit Service |
646995 |
if (idbm_print_all_discovery(info_level))
|
|
Packit Service |
646995 |
/* successfully found some recs */
|
|
Packit Service |
646995 |
rc = 0;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
} else
|
|
Packit Service |
646995 |
log_error("Invalid operation. Operation not "
|
|
Packit Service |
646995 |
"supported.");
|
|
Packit Service |
646995 |
} else if (op)
|
|
Packit Service |
646995 |
log_error("Invalid command. Possibly missing discovery "
|
|
Packit Service |
646995 |
"--type.");
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
log_error("Invalid command. Portal not needed or "
|
|
Packit Service |
646995 |
"Possibly missing discovery --type.");
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
do_db_op:
|
|
Packit Service |
646995 |
rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (op == OP_NOOP || op == OP_SHOW) {
|
|
Packit Service |
646995 |
if (!idbm_print_discovery_info(&drec, do_show)) {
|
|
Packit Service |
646995 |
log_error("No records found");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
} else if (op == OP_DELETE) {
|
|
Packit Service |
646995 |
rc = idbm_delete_discovery(&drec);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
log_error("Unable to delete record!");
|
|
Packit Service |
646995 |
} else if (op == OP_UPDATE) {
|
|
Packit Service |
646995 |
if (list_empty(params)) {
|
|
Packit Service |
646995 |
log_error("Update requires name and value.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
rc = idbm_discovery_set_param(params, &drec);
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
log_error("Operation is not supported.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
done:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int exec_disc_op(int disc_type,
|
|
Packit Service |
646995 |
char *ip,
|
|
Packit Service |
646995 |
int port,
|
|
Packit Service |
646995 |
struct list_head *ifaces,
|
|
Packit Service |
646995 |
int info_level,
|
|
Packit Service |
646995 |
int do_login,
|
|
Packit Service |
646995 |
int do_discover,
|
|
Packit Service |
646995 |
int op,
|
|
Packit Service |
646995 |
__attribute__((unused))struct list_head *params,
|
|
Packit Service |
646995 |
int do_show)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct discovery_rec drec;
|
|
Packit Service |
646995 |
int rc = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(&drec, 0, sizeof(struct discovery_rec));
|
|
Packit Service |
646995 |
drec.iscsid_req_tmo = -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
switch (disc_type) {
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_SENDTARGETS:
|
|
Packit Service |
646995 |
drec.type = DISCOVERY_TYPE_SENDTARGETS;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (port < 0)
|
|
Packit Service |
646995 |
port = ISCSI_LISTEN_PORT;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (ip == NULL) {
|
|
Packit Service |
646995 |
log_error("Please specify portal as "
|
|
Packit Service |
646995 |
"<ipaddr>[:<ipport>]");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
idbm_sendtargets_defaults(&drec.u.sendtargets);
|
|
Packit Service |
646995 |
strlcpy(drec.address, ip, sizeof(drec.address));
|
|
Packit Service |
646995 |
drec.port = port;
|
|
Packit Service |
646995 |
rc = do_target_discovery(&drec, ifaces, info_level,
|
|
Packit Service |
646995 |
do_login, op, 1);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_SLP:
|
|
Packit Service |
646995 |
log_error("SLP discovery is not fully implemented yet.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_ISNS:
|
|
Packit Service |
646995 |
if (!ip) {
|
|
Packit Service |
646995 |
log_error("Please specify portal as "
|
|
Packit Service |
646995 |
"<ipaddr>:[<ipport>]");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
strlcpy(drec.address, ip, sizeof(drec.address));
|
|
Packit Service |
646995 |
if (port < 0)
|
|
Packit Service |
646995 |
drec.port = ISNS_DEFAULT_PORT;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
drec.port = port;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
drec.type = DISCOVERY_TYPE_ISNS;
|
|
Packit Service |
646995 |
rc = do_target_discovery(&drec, ifaces, info_level,
|
|
Packit Service |
646995 |
do_login, op, 0);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case DISCOVERY_TYPE_FW:
|
|
Packit Service |
646995 |
drec.type = DISCOVERY_TYPE_FW;
|
|
Packit Service |
646995 |
rc = exec_fw_op(&drec, ifaces, info_level, do_login, op);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
if (ip) {
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* We only have sendtargets disc recs in discovery
|
|
Packit Service |
646995 |
* mode, so we can hardcode the port check to the
|
|
Packit Service |
646995 |
* iscsi default here.
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* For isns or slp recs then discovery db mode
|
|
Packit Service |
646995 |
* must be used.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (port < 0)
|
|
Packit Service |
646995 |
port = ISCSI_LISTEN_PORT;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (idbm_discovery_read(&drec,
|
|
Packit Service |
646995 |
DISCOVERY_TYPE_SENDTARGETS,
|
|
Packit Service |
646995 |
ip, port)) {
|
|
Packit Service |
646995 |
log_error("Discovery record [%s,%d] "
|
|
Packit Service |
646995 |
"not found!", ip, port);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
if ((do_discover || do_login) &&
|
|
Packit Service |
646995 |
drec.type == DISCOVERY_TYPE_SENDTARGETS) {
|
|
Packit Service |
646995 |
rc = do_target_discovery(&drec, ifaces,
|
|
Packit Service |
646995 |
info_level, do_login,
|
|
Packit Service |
646995 |
op, 0);
|
|
Packit Service |
646995 |
} else if (op == OP_NOOP || op == OP_SHOW) {
|
|
Packit Service |
646995 |
if (!idbm_print_discovery_info(&drec,
|
|
Packit Service |
646995 |
do_show)) {
|
|
Packit Service |
646995 |
log_error("No records found");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
} else if (op == OP_DELETE) {
|
|
Packit Service |
646995 |
rc = idbm_delete_discovery(&drec);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
log_error("Unable to delete record!");
|
|
Packit Service |
646995 |
} else if (op == OP_UPDATE || op == OP_NEW) {
|
|
Packit Service |
646995 |
log_error("Operations new and update for "
|
|
Packit Service |
646995 |
"discovery mode is not supported. "
|
|
Packit Service |
646995 |
"Use discoverydb mode.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
log_error("Invalid operation.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
} else if (op == OP_NOOP || op == OP_SHOW) {
|
|
Packit Service |
646995 |
if (!idbm_print_all_discovery(info_level))
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
log_error("Invalid operation.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto done;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
/* fall through */
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
done:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static uint64_t parse_host_info(char *optarg, int *rc)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int err = 0;
|
|
Packit Service |
646995 |
uint64_t host_no;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
*rc = 0;
|
|
Packit Service |
646995 |
if (strstr(optarg, ":")) {
|
|
Packit Service |
646995 |
transport_probe_for_offload();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
host_no = iscsi_sysfs_get_host_no_from_hwaddress(optarg,
|
|
Packit Service |
646995 |
&err;;
|
|
Packit Service |
646995 |
if (err) {
|
|
Packit Service |
646995 |
log_error("Could not match MAC to host.");
|
|
Packit Service |
646995 |
*rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
errno = 0; // ensure errors from strtoull are real
|
|
Packit Service |
646995 |
host_no = strtoull(optarg, NULL, 10);
|
|
Packit Service |
646995 |
if (errno || (host_no > MAX_HOST_NO)) {
|
|
Packit Service |
646995 |
if (host_no > MAX_HOST_NO)
|
|
Packit Service |
646995 |
errno = ERANGE;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
log_error("Invalid host no %s. %s.",
|
|
Packit Service |
646995 |
optarg, strerror(errno));
|
|
Packit Service |
646995 |
*rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
return host_no;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static char *iscsi_ping_stat_strs[] = {
|
|
Packit Service |
646995 |
/* ISCSI_PING_SUCCESS */
|
|
Packit Service |
646995 |
"success",
|
|
Packit Service |
646995 |
/* ISCSI_PING_FW_DISABLED */
|
|
Packit Service |
646995 |
"firmware disabled",
|
|
Packit Service |
646995 |
/* ISCSI_PING_IPADDR_INVALID */
|
|
Packit Service |
646995 |
"invalid IP address",
|
|
Packit Service |
646995 |
/* ISCSI_PING_LINKLOCAL_IPV6_ADDR_INVALID */
|
|
Packit Service |
646995 |
"invalid link local IPv6 address",
|
|
Packit Service |
646995 |
/* ISCSI_PING_TIMEOUT */
|
|
Packit Service |
646995 |
"timed out",
|
|
Packit Service |
646995 |
/* ISCSI_PING_INVALID_DEST_ADDR */
|
|
Packit Service |
646995 |
"invalid destination address",
|
|
Packit Service |
646995 |
/* ISCSI_PING_OVERSIZE_PACKET */
|
|
Packit Service |
646995 |
"oversized packet",
|
|
Packit Service |
646995 |
/* ISCSI_PING_ICMP_ERROR */
|
|
Packit Service |
646995 |
"ICMP error",
|
|
Packit Service |
646995 |
/* ISCSI_PING_MAX_REQ_EXCEEDED */
|
|
Packit Service |
646995 |
"Max request exceeded",
|
|
Packit Service |
646995 |
/* ISCSI_PING_NO_ARP_RECEIVED */
|
|
Packit Service |
646995 |
"No ARP response received",
|
|
Packit Service |
646995 |
};
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static char *iscsi_ping_stat_to_str(uint32_t status)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (status == 0 || status > ISCSI_PING_NO_ARP_RECEIVED) {
|
|
Packit Service |
646995 |
log_error("Invalid ping status %u", status);
|
|
Packit Service |
646995 |
return NULL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return iscsi_ping_stat_strs[status];
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int exec_ping_op(struct iface_rec *iface, char *ip, int size, int count,
|
|
Packit Service |
646995 |
int interval)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int rc = ISCSI_ERR;
|
|
Packit Service |
646995 |
uint32_t iface_type = ISCSI_IFACE_TYPE_IPV4;
|
|
Packit Service |
646995 |
struct iscsi_transport *t = NULL;
|
|
Packit Service |
646995 |
uint32_t host_no, status = 0;
|
|
Packit Service |
646995 |
struct sockaddr_storage addr;
|
|
Packit Service |
646995 |
struct host_info hinfo;
|
|
Packit Service |
646995 |
int i;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!iface) {
|
|
Packit Service |
646995 |
log_error("Ping requires iface.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto ping_exit;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!ip) {
|
|
Packit Service |
646995 |
log_error("Ping requires destination ipaddress.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto ping_exit;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (size <= 0) {
|
|
Packit Service |
646995 |
log_error("Invalid packet size: %d.", size);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto ping_exit;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (count <= 0) {
|
|
Packit Service |
646995 |
log_error("Invalid number of packets to transmit: %d.", count);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto ping_exit;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (interval < 0) {
|
|
Packit Service |
646995 |
log_error("Invalid timing interval: %d.", interval);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto ping_exit;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iface_conf_read(iface);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not read iface %s (%d).", iface->name, rc);
|
|
Packit Service |
646995 |
goto ping_exit;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
iface_type = iface_get_iptype(iface);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
t = iscsi_sysfs_get_transport_by_name(iface->transport_name);
|
|
Packit Service |
646995 |
if (!t) {
|
|
Packit Service |
646995 |
log_error("Can't find transport.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto ping_exit;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
host_no = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc);
|
|
Packit Service |
646995 |
if (host_no == 0) {
|
|
Packit Service |
646995 |
log_error("Can't find host_no.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto ping_exit;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = resolve_address(ip, NULL, &addr);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Invalid IP address.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto ping_exit;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* TODO: move this. It is needed by interface for pid */
|
|
Packit Service |
646995 |
srand(time(NULL));
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
for (i = 1; i <= count; i++) {
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* To support drivers like bnx2i that do not use
|
|
Packit Service |
646995 |
* the iscsi iface to send a ping, we invoke transport
|
|
Packit Service |
646995 |
* callout here.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
status = 0;
|
|
Packit Service |
646995 |
if (t->template->exec_ping) {
|
|
Packit Service |
646995 |
if (!strlen(iface->netdev)) {
|
|
Packit Service |
646995 |
memset(&hinfo, 0, sizeof(hinfo));
|
|
Packit Service |
646995 |
hinfo.host_no = host_no;
|
|
Packit Service |
646995 |
iscsi_sysfs_get_hostinfo_by_host_no(&hinfo);
|
|
Packit Service |
646995 |
strcpy(iface->netdev, hinfo.iface.netdev);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iscsi_set_net_config(t, NULL, iface);
|
|
Packit Service |
646995 |
if (rc && (rc != ISCSI_ERR_AGAIN))
|
|
Packit Service |
646995 |
goto ping_err;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = t->template->exec_ping(t, iface, size, &addr,
|
|
Packit Service |
646995 |
&status);
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
rc = ipc->exec_ping(t->handle, host_no,
|
|
Packit Service |
646995 |
(struct sockaddr *)&addr,
|
|
Packit Service |
646995 |
iface->iface_num, iface_type,
|
|
Packit Service |
646995 |
(uint32_t)size, &status);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ping_err:
|
|
Packit Service |
646995 |
if (!rc && !status)
|
|
Packit Service |
646995 |
printf("Ping %d completed\n", i);
|
|
Packit Service |
646995 |
else if (status)
|
|
Packit Service |
646995 |
printf("Ping %d failed: %s\n", i,
|
|
Packit Service |
646995 |
iscsi_ping_stat_to_str(status));
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
printf("Ping %d failed: %s\n", i, iscsi_err_to_str(rc));
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (i < count)
|
|
Packit Service |
646995 |
sleep(interval);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ping_exit:
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
int
|
|
Packit Service |
646995 |
main(int argc, char **argv)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
char *ip = NULL, *name = NULL, *value = NULL;
|
|
Packit Service |
646995 |
char *targetname = NULL, *group_session_mgmt_mode = NULL;
|
|
Packit Service |
646995 |
int ch, longindex, mode=-1, port=-1, do_login=0, do_rescan=0;
|
|
Packit Service |
646995 |
int rc=0, sid=-1, op=OP_NOOP, type=-1, do_logout=0, do_stats=0;
|
|
Packit Service |
646995 |
int do_login_all=0, do_logout_all=0, info_level=-1, num_ifaces = 0;
|
|
Packit Service |
646995 |
int tpgt = PORTAL_GROUP_TAG_UNKNOWN, killiscsid=-1, do_show=0;
|
|
Packit Service |
646995 |
int packet_size=32, ping_count=1, ping_interval=0;
|
|
Packit Service |
646995 |
int do_discover = 0, sub_mode = -1;
|
|
Packit Service |
646995 |
int portal_type = -1;
|
|
Packit Service |
646995 |
int timeout = ISCSID_REQ_TIMEOUT;
|
|
Packit Service |
646995 |
struct sigaction sa_old;
|
|
Packit Service |
646995 |
struct sigaction sa_new;
|
|
Packit Service |
646995 |
LIST_HEAD(ifaces);
|
|
Packit Service |
646995 |
struct iface_rec *iface = NULL, *tmp;
|
|
Packit Service |
646995 |
struct node_rec *rec = NULL;
|
|
Packit Service |
646995 |
uint32_t host_no = MAX_HOST_NO + 1;
|
|
Packit Service |
646995 |
uint64_t index = ULLONG_MAX;
|
|
Packit Service |
646995 |
struct user_param *param;
|
|
Packit Service |
646995 |
LIST_HEAD(params);
|
|
Packit Service |
646995 |
struct iscsi_context *ctx = NULL;
|
|
Packit Service |
646995 |
int librc = LIBISCSI_OK;
|
|
Packit Service |
646995 |
struct iscsi_session **ses = NULL;
|
|
Packit Service |
646995 |
uint32_t se_count = 0;
|
|
Packit Service |
646995 |
struct iscsi_session *se = NULL;
|
|
Packit Service |
646995 |
bool wait = true;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ctx = iscsi_context_new();
|
|
Packit Service |
646995 |
if (ctx == NULL) {
|
|
Packit Service |
646995 |
log_error("No memory");
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* do not allow ctrl-c for now... */
|
|
Packit Service |
646995 |
memset(&sa_old, 0, sizeof(struct sigaction));
|
|
Packit Service |
646995 |
memset(&sa_new, 0, sizeof(struct sigaction));
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
sa_new.sa_handler = catch_sigint;
|
|
Packit Service |
646995 |
sigemptyset(&sa_new.sa_mask);
|
|
Packit Service |
646995 |
sa_new.sa_flags = 0;
|
|
Packit Service |
646995 |
sigaction(SIGINT, &sa_new, &sa_old );
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
umask(0177);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* enable stdout logging */
|
|
Packit Service |
646995 |
log_init(program_name, 1024, log_do_log_std, NULL);
|
|
Packit Service |
646995 |
sysfs_init();
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
optopt = 0;
|
|
Packit Service |
646995 |
while ((ch = getopt_long(argc, argv, short_options,
|
|
Packit Service |
646995 |
long_options, &longindex)) >= 0) {
|
|
Packit Service |
646995 |
switch (ch) {
|
|
Packit Service |
646995 |
case 'k':
|
|
Packit Service |
646995 |
killiscsid = atoi(optarg);
|
|
Packit Service |
646995 |
if (killiscsid < 0) {
|
|
Packit Service |
646995 |
log_error("Invalid killiscsid priority %d "
|
|
Packit Service |
646995 |
"Priority must be greater than or "
|
|
Packit Service |
646995 |
"equal to zero.", killiscsid);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 't':
|
|
Packit Service |
646995 |
type = str_to_type(optarg);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'o':
|
|
Packit Service |
646995 |
op |= str_to_op(optarg);
|
|
Packit Service |
646995 |
if (op == OP_NOOP) {
|
|
Packit Service |
646995 |
log_error("can not recognize operation: '%s'",
|
|
Packit Service |
646995 |
optarg);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'n':
|
|
Packit Service |
646995 |
name = optarg;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'v':
|
|
Packit Service |
646995 |
value = optarg;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'H':
|
|
Packit Service |
646995 |
host_no = parse_host_info(optarg, &rc);
|
|
Packit Service |
646995 |
if (rc)
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'r':
|
|
Packit Service |
646995 |
sid = iscsi_sysfs_get_sid_from_path(optarg);
|
|
Packit Service |
646995 |
if (sid < 0) {
|
|
Packit Service |
646995 |
log_error("invalid sid '%s'",
|
|
Packit Service |
646995 |
optarg);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'R':
|
|
Packit Service |
646995 |
do_rescan = 1;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'P':
|
|
Packit Service |
646995 |
info_level = atoi(optarg);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'D':
|
|
Packit Service |
646995 |
do_discover = 1;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'l':
|
|
Packit Service |
646995 |
do_login = 1;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'u':
|
|
Packit Service |
646995 |
do_logout = 1;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'U':
|
|
Packit Service |
646995 |
do_logout_all = 1;
|
|
Packit Service |
646995 |
group_session_mgmt_mode= optarg;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'L':
|
|
Packit Service |
646995 |
do_login_all= 1;
|
|
Packit Service |
646995 |
group_session_mgmt_mode= optarg;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 's':
|
|
Packit Service |
646995 |
do_stats = 1;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'S':
|
|
Packit Service |
646995 |
do_show = 1;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'd':
|
|
Packit Service |
646995 |
log_level = atoi(optarg);
|
|
Packit Service |
646995 |
if (log_level >= 8)
|
|
Packit Service |
646995 |
iscsi_context_log_priority_set
|
|
Packit Service |
646995 |
(ctx, LIBISCSI_LOG_PRIORITY_DEBUG);
|
|
Packit Service |
646995 |
else if (log_level >= 4)
|
|
Packit Service |
646995 |
iscsi_context_log_priority_set
|
|
Packit Service |
646995 |
(ctx, LIBISCSI_LOG_PRIORITY_INFO);
|
|
Packit Service |
646995 |
else if (log_level >= 2)
|
|
Packit Service |
646995 |
iscsi_context_log_priority_set
|
|
Packit Service |
646995 |
(ctx, LIBISCSI_LOG_PRIORITY_WARNING);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
iscsi_context_log_priority_set
|
|
Packit Service |
646995 |
(ctx, LIBISCSI_LOG_PRIORITY_ERROR);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'm':
|
|
Packit Service |
646995 |
mode = str_to_mode(optarg);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'C':
|
|
Packit Service |
646995 |
sub_mode = str_to_submode(optarg);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'T':
|
|
Packit Service |
646995 |
targetname = optarg;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'p':
|
|
Packit Service |
646995 |
ip = str_to_ipport(optarg, &port, &tpgt);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'a':
|
|
Packit Service |
646995 |
ip = optarg;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'b':
|
|
Packit Service |
646995 |
packet_size = atoi(optarg);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'c':
|
|
Packit Service |
646995 |
ping_count = atoi(optarg);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'i':
|
|
Packit Service |
646995 |
ping_interval = atoi(optarg);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'I':
|
|
Packit Service |
646995 |
iface = iface_alloc(optarg, &rc);
|
|
Packit Service |
646995 |
if (rc == ISCSI_ERR_INVAL) {
|
|
Packit Service |
646995 |
printf("Invalid iface name %s. Must be from "
|
|
Packit Service |
646995 |
"1 to %d characters.\n",
|
|
Packit Service |
646995 |
optarg, ISCSI_MAX_IFACE_LEN - 1);
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
} else if (!iface || rc) {
|
|
Packit Service |
646995 |
printf("Could not add iface %s.", optarg);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
list_add_tail(&iface->list, &ifaces);
|
|
Packit Service |
646995 |
num_ifaces++;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'V':
|
|
Packit Service |
646995 |
printf("%s version %s\n", program_name,
|
|
Packit Service |
646995 |
ISCSI_VERSION_STR);
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
case 'x':
|
|
Packit Service |
646995 |
errno = 0; // ensure errors from strtoull are real
|
|
Packit Service |
646995 |
index = strtoull(optarg, NULL, 10);
|
|
Packit Service |
646995 |
if (errno) {
|
|
Packit Service |
646995 |
log_error("Invalid index %s. %s.",
|
|
Packit Service |
646995 |
optarg, strerror(errno));
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'A':
|
|
Packit Service |
646995 |
portal_type = str_to_portal_type(optarg);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'W':
|
|
Packit Service |
646995 |
wait = false;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case 'h':
|
|
Packit Service |
646995 |
usage(0);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (name && value) {
|
|
Packit Service |
646995 |
param = idbm_alloc_user_param(name, value);
|
|
Packit Service |
646995 |
if (!param) {
|
|
Packit Service |
646995 |
log_error("Cannot allocate memory for params.");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
list_add_tail(¶m->list, ¶ms);
|
|
Packit Service |
646995 |
name = NULL;
|
|
Packit Service |
646995 |
value = NULL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (optopt) {
|
|
Packit Service |
646995 |
log_error("unrecognized character '%c'", optopt);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (killiscsid >= 0) {
|
|
Packit Service |
646995 |
kill_iscsid(killiscsid, timeout);
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (mode < 0)
|
|
Packit Service |
646995 |
usage(ISCSI_ERR_INVAL);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (mode == MODE_FW) {
|
|
Packit Service |
646995 |
if ((rc = verify_mode_params(argc, argv, "dml", 0))) {
|
|
Packit Service |
646995 |
log_error("fw mode: option '-%c' is not "
|
|
Packit Service |
646995 |
"allowed/supported", rc);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_fw_op(NULL, NULL, info_level, do_login, op);
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
increase_max_files();
|
|
Packit Service |
646995 |
if (idbm_init(get_config_file)) {
|
|
Packit Service |
646995 |
log_warning("exiting due to idbm configuration error");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_IDBM;
|
|
Packit Service |
646995 |
goto free_ifaces;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
switch (mode) {
|
|
Packit Service |
646995 |
case MODE_HOST:
|
|
Packit Service |
646995 |
if ((rc = verify_mode_params(argc, argv, "CHdmPotnvxA", 0))) {
|
|
Packit Service |
646995 |
log_error("host mode: option '-%c' is not "
|
|
Packit Service |
646995 |
"allowed/supported", rc);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
if (sub_mode != -1) {
|
|
Packit Service |
646995 |
switch (sub_mode) {
|
|
Packit Service |
646995 |
case MODE_CHAP:
|
|
Packit Service |
646995 |
if (!op || (host_no > MAX_HOST_NO)) {
|
|
Packit Service |
646995 |
log_error("CHAP mode requires host "
|
|
Packit Service |
646995 |
"no and valid operation");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (index == ULLONG_MAX)
|
|
Packit Service |
646995 |
index = (uint64_t)MAX_CHAP_ENTRIES + 1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_host_chap_op(op, info_level, host_no,
|
|
Packit Service |
646995 |
index, ¶ms);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case MODE_FLASHNODE:
|
|
Packit Service |
646995 |
if (host_no > MAX_HOST_NO) {
|
|
Packit Service |
646995 |
log_error("FLASHNODE mode requires host no");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (index == ULLONG_MAX)
|
|
Packit Service |
646995 |
index = (uint64_t)MAX_FLASHNODE_IDX + 1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_flashnode_op(op, info_level, host_no,
|
|
Packit Service |
646995 |
index, portal_type,
|
|
Packit Service |
646995 |
¶ms);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case MODE_HOST_STATS:
|
|
Packit Service |
646995 |
if (host_no > MAX_HOST_NO) {
|
|
Packit Service |
646995 |
log_error("STATS mode requires host no");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_host_stats_op(op, info_level,
|
|
Packit Service |
646995 |
host_no);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
log_error("Invalid Sub Mode");
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
librc = iscsi_sessions_get(ctx, &ses, &se_count);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (librc != LIBISCSI_OK) {
|
|
Packit Service |
646995 |
log_error("Failed to query iSCSI sessions, "
|
|
Packit Service |
646995 |
"error %d: %s", librc,
|
|
Packit Service |
646995 |
iscsi_strerror(librc));
|
|
Packit Service |
646995 |
/* libopeniscsiusr rc is one-to-one map to iscsiadm
|
|
Packit Service |
646995 |
* rc
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
rc = librc;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
rc = host_info_print(info_level, host_no, ses,
|
|
Packit Service |
646995 |
se_count);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case MODE_IFACE:
|
|
Packit Service |
646995 |
iscsi_default_iface_setup(ctx);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if ((rc = verify_mode_params(argc, argv, "HIdnvmPoCabci", 0))) {
|
|
Packit Service |
646995 |
log_error("iface mode: option '-%c' is not "
|
|
Packit Service |
646995 |
"allowed/supported", rc);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!list_empty(&ifaces)) {
|
|
Packit Service |
646995 |
iface = list_entry(ifaces.next, struct iface_rec,
|
|
Packit Service |
646995 |
list);
|
|
Packit Service |
646995 |
if (num_ifaces > 1)
|
|
Packit Service |
646995 |
log_error("iface mode only accepts one "
|
|
Packit Service |
646995 |
"interface. Using the first one "
|
|
Packit Service |
646995 |
"%s.", iface->name);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (sub_mode == MODE_PING)
|
|
Packit Service |
646995 |
rc = exec_ping_op(iface, ip, packet_size, ping_count,
|
|
Packit Service |
646995 |
ping_interval);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
rc = exec_iface_op(ctx, op, do_show, info_level, iface,
|
|
Packit Service |
646995 |
host_no, ¶ms);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case MODE_DISCOVERYDB:
|
|
Packit Service |
646995 |
if ((rc = verify_mode_params(argc, argv, "DSIPdmntplov", 0))) {
|
|
Packit Service |
646995 |
log_error("discovery mode: option '-%c' is not "
|
|
Packit Service |
646995 |
"allowed/supported", rc);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_disc2_op(type, ip, port, &ifaces, info_level,
|
|
Packit Service |
646995 |
do_login, do_discover, op, ¶ms,
|
|
Packit Service |
646995 |
do_show);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case MODE_DISCOVERY:
|
|
Packit Service |
646995 |
if ((rc = verify_mode_params(argc, argv, "DSIPdmntplov", 0))) {
|
|
Packit Service |
646995 |
log_error("discovery mode: option '-%c' is not "
|
|
Packit Service |
646995 |
"allowed/supported", rc);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_disc_op(type, ip, port, &ifaces, info_level,
|
|
Packit Service |
646995 |
do_login, do_discover, op, ¶ms,
|
|
Packit Service |
646995 |
do_show);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case MODE_NODE:
|
|
Packit Service |
646995 |
if ((rc = verify_mode_params(argc, argv, "RsPIdmlSonvupTULW",
|
|
Packit Service |
646995 |
0))) {
|
|
Packit Service |
646995 |
log_error("node mode: option '-%c' is not "
|
|
Packit Service |
646995 |
"allowed/supported", rc);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (do_login_all) {
|
|
Packit Service |
646995 |
rc = login_by_startup(group_session_mgmt_mode, wait);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (do_logout_all) {
|
|
Packit Service |
646995 |
rc = logout_by_startup(group_session_mgmt_mode);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!list_empty(&ifaces)) {
|
|
Packit Service |
646995 |
iface = list_entry(ifaces.next, struct iface_rec,
|
|
Packit Service |
646995 |
list);
|
|
Packit Service |
646995 |
if (num_ifaces > 1)
|
|
Packit Service |
646995 |
log_error("NODE mode only accepts one "
|
|
Packit Service |
646995 |
"interface. Using the first one "
|
|
Packit Service |
646995 |
"driver %s hwaddress %s ipaddress "
|
|
Packit Service |
646995 |
"%s.", iface->transport_name,
|
|
Packit Service |
646995 |
iface->hwaddress, iface->ipaddress);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (ip && port == -1)
|
|
Packit Service |
646995 |
port = ISCSI_LISTEN_PORT;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rec = idbm_create_rec(targetname, tpgt, ip, port, iface, 1);
|
|
Packit Service |
646995 |
if (!rec) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = exec_node_op(ctx, op, do_login, do_logout, do_show,
|
|
Packit Service |
646995 |
do_rescan, do_stats, wait, info_level, rec,
|
|
Packit Service |
646995 |
¶ms);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
case MODE_SESSION:
|
|
Packit Service |
646995 |
if ((rc = verify_mode_params(argc, argv,
|
|
Packit Service |
646995 |
"PiRdrmusonuSv", 1))) {
|
|
Packit Service |
646995 |
log_error("session mode: option '-%c' is not "
|
|
Packit Service |
646995 |
"allowed or supported", rc);
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
if (sid >= 0) {
|
|
Packit Service |
646995 |
char session[64];
|
|
Packit Service |
646995 |
struct session_info *info;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
snprintf(session, 63, "session%d", sid);
|
|
Packit Service |
646995 |
session[63] = '\0';
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
info = calloc(1, sizeof(*info));
|
|
Packit Service |
646995 |
if (!info) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
info->iscsid_req_tmo = -1;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = iscsi_sysfs_get_sessioninfo_by_id(info, session);
|
|
Packit Service |
646995 |
if (rc) {
|
|
Packit Service |
646995 |
log_error("Could not get session info for sid "
|
|
Packit Service |
646995 |
"%d", sid);
|
|
Packit Service |
646995 |
goto free_info;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* We should be able to go on, but for now
|
|
Packit Service |
646995 |
* we only support session mode ops if the module
|
|
Packit Service |
646995 |
* is loaded and we support that module.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (!iscsi_sysfs_get_transport_by_sid(sid))
|
|
Packit Service |
646995 |
goto free_info;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!do_logout && !do_rescan && !do_stats &&
|
|
Packit Service |
646995 |
op == OP_NOOP && info_level > 0) {
|
|
Packit Service |
646995 |
librc = iscsi_session_get
|
|
Packit Service |
646995 |
(ctx, sid & UINT32_MAX, &se);
|
|
Packit Service |
646995 |
if (librc != LIBISCSI_OK) {
|
|
Packit Service |
646995 |
log_error("Failed to query iSCSI "
|
|
Packit Service |
646995 |
"session %d, error %d: %s",
|
|
Packit Service |
646995 |
sid, librc,
|
|
Packit Service |
646995 |
iscsi_strerror(librc));
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
ses = (struct iscsi_session **)
|
|
Packit Service |
646995 |
calloc(1,
|
|
Packit Service |
646995 |
sizeof(struct iscsi_session *));
|
|
Packit Service |
646995 |
ses[0] = se;
|
|
Packit Service |
646995 |
se_count = 1;
|
|
Packit Service |
646995 |
rc = session_info_print(info_level, ses,
|
|
Packit Service |
646995 |
se_count, do_show);
|
|
Packit Service |
646995 |
goto free_info;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rec = idbm_create_rec(info->targetname,
|
|
Packit Service |
646995 |
info->tpgt,
|
|
Packit Service |
646995 |
info->persistent_address,
|
|
Packit Service |
646995 |
info->persistent_port,
|
|
Packit Service |
646995 |
&info->iface, 1);
|
|
Packit Service |
646995 |
if (!rec) {
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto free_info;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
rec->session.info = info;
|
|
Packit Service |
646995 |
rec->session.sid = sid;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* A "new" session means to login a multiple of the
|
|
Packit Service |
646995 |
* currently-detected session.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (op == OP_NEW) {
|
|
Packit Service |
646995 |
op = OP_NOOP;
|
|
Packit Service |
646995 |
do_login = 1;
|
|
Packit Service |
646995 |
rec->session.multiple = 1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/* drop down to node ops */
|
|
Packit Service |
646995 |
rc = exec_node_op(ctx, op, do_login, do_logout, do_show,
|
|
Packit Service |
646995 |
do_rescan, do_stats, wait, info_level,
|
|
Packit Service |
646995 |
rec, ¶ms);
|
|
Packit Service |
646995 |
free_info:
|
|
Packit Service |
646995 |
free(info);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
} else {
|
|
Packit Service |
646995 |
if (op == OP_NEW) {
|
|
Packit Service |
646995 |
log_error("session mode: Operation 'new' only "
|
|
Packit Service |
646995 |
"allowed with specific session IDs");
|
|
Packit Service |
646995 |
rc = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
if (do_logout || do_rescan || do_stats) {
|
|
Packit Service |
646995 |
rc = exec_node_op(ctx, op, do_login, do_logout,
|
|
Packit Service |
646995 |
do_show, do_rescan, do_stats,
|
|
Packit Service |
646995 |
wait, info_level, NULL, ¶ms);
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
librc = iscsi_sessions_get(ctx, &ses, &se_count);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (librc != LIBISCSI_OK) {
|
|
Packit Service |
646995 |
log_error("Failed to query iSCSI sessions, "
|
|
Packit Service |
646995 |
"error %d: %s", librc,
|
|
Packit Service |
646995 |
iscsi_strerror(librc));
|
|
Packit Service |
646995 |
/* libopeniscsiusr rc is one-to-one map to iscsiadm
|
|
Packit Service |
646995 |
* rc
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
rc = librc;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
if (se_count == 0) {
|
|
Packit Service |
646995 |
log_error("No active sessions.");
|
|
Packit Service |
646995 |
rc =ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
goto out;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
rc = session_info_print(info_level, ses, se_count,
|
|
Packit Service |
646995 |
do_show);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
default:
|
|
Packit Service |
646995 |
log_error("This mode is not yet supported");
|
|
Packit Service |
646995 |
/* fall through */
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
out:
|
|
Packit Service |
646995 |
iscsi_context_free(ctx);
|
|
Packit Service |
646995 |
if (rec)
|
|
Packit Service |
646995 |
free(rec);
|
|
Packit Service |
646995 |
iscsi_sessions_free(ses, se_count);
|
|
Packit Service |
646995 |
idbm_terminate();
|
|
Packit Service |
646995 |
free_ifaces:
|
|
Packit Service |
646995 |
list_for_each_entry_safe(iface, tmp, &ifaces, list) {
|
|
Packit Service |
646995 |
list_del(&iface->list);
|
|
Packit Service |
646995 |
free(iface);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
free_transports();
|
|
Packit Service |
646995 |
sysfs_cleanup();
|
|
Packit Service |
646995 |
return rc;
|
|
Packit Service |
646995 |
}
|