2506 lines
82 KiB
Diff
2506 lines
82 KiB
Diff
|
From ade9aafd7cbbd3d1543ff005290e2571f56dd964 Mon Sep 17 00:00:00 2001
|
||
|
From: Mike Christie <michaelc@cs.wisc.edu>
|
||
|
Date: Mon, 13 May 2013 03:15:34 -0500
|
||
|
Subject: From: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
|
||
|
|
||
|
This support lets the user manage the target entries in adapter flash
|
||
|
and
|
||
|
perform various operations like add, delete, login, logout,
|
||
|
and update the target information.
|
||
|
|
||
|
The sysfs entries will look as cited below:
|
||
|
/sys/bus/iscsi_flashnode/devices/flashnode_sess-<host_no>:<flashnode_id>/<session
|
||
|
attrs>
|
||
|
/sys/bus/iscsi_flashnode/devices/flashnode_conn-<host_no>:<flashnode_id>:<conn_id>/<conn
|
||
|
attrs>
|
||
|
|
||
|
Operations using iscsiadm:
|
||
|
=========================
|
||
|
|
||
|
List all target nodes stored in the FLASH of the adapter
|
||
|
\# iscsiadm -m host -H hostno -C flashnode -o show
|
||
|
|
||
|
View all parameters of one particular flash node
|
||
|
\# iscsiadm -m host -H hostno -C flashnode -x <flashnode_idx> -o show
|
||
|
|
||
|
Update an entry and commit to adapter FLASH
|
||
|
\# iscsiadm -m host -H hostno -C flashnode -x <flashnode_idx> -n <name>
|
||
|
-v <value> -o update
|
||
|
|
||
|
Multiple name, value pairs can be specified in a single command for
|
||
|
update operation
|
||
|
|
||
|
Delete an entry
|
||
|
\# iscsiadm -m host -H hostno -C flashnode -x <flashnode_idx> -o delete
|
||
|
|
||
|
Create a new entry
|
||
|
\# iscsiadm -m host -H hostno -C flashnode -o new -A <ipv4/ipv6>
|
||
|
\# iscsiadm -m host -H hostno -C flashnode -x <flashnode_idx> -n <name>
|
||
|
-v <value> -o update
|
||
|
|
||
|
Example, create new entry:
|
||
|
\#iscsiadm -m host -H 7 -C flashnode -o new -A ipv4
|
||
|
Flashnode index: 2
|
||
|
|
||
|
New flashnode for host7 added
|
||
|
|
||
|
\#iscsiadm -m host -H 7 -C flashnode -o show
|
||
|
qla4xxx: [0] 192.168.1.12:3260,2
|
||
|
iqn.2002-03.com.compellent:5000d310004b0716
|
||
|
qla4xxx: [1] 192.168.1.12:3260,2
|
||
|
qla4xxx: [2]
|
||
|
|
||
|
Here - The newly created entry is at flashnode_idx 2, use it to update
|
||
|
the entry
|
||
|
|
||
|
\# iscsiadm -m host -H 7 -C flashnode -x 2 -o update
|
||
|
flashnode.conn[0].ipaddress -v 192.168.1.13
|
||
|
\#iscsiadm -m host -H 7 -C flashnode -o show
|
||
|
qla4xxx: [0] 192.168.1.12:3260,2
|
||
|
iqn.2002-03.com.compellent:5000d310004b0716
|
||
|
qla4xxx: [1] 192.168.1.12:3260,2
|
||
|
qla4xxx: [2] 192.168.1.13:3260,0
|
||
|
|
||
|
Login
|
||
|
\# iscsiadm -m host -H hostno -C flashnode -x <flashnode_idx> -o login
|
||
|
|
||
|
Logout
|
||
|
\# iscsiadm -m host -H hostno -C flashnode -x <flashnode_idx> -o logout
|
||
|
\# iscsiadm -m session -r sid -u
|
||
|
|
||
|
Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
|
||
|
Signed-off-by: Manish Rangankar <manish.rangankar@qlogic.com>
|
||
|
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
|
||
|
---
|
||
|
include/iscsi_if.h | 190 ++++++++++++++++-
|
||
|
usr/Makefile | 2 +-
|
||
|
usr/flashnode.c | 609 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
usr/flashnode.h | 127 +++++++++++
|
||
|
usr/idbm.c | 179 ++++++++++++++++
|
||
|
usr/idbm.h | 7 +
|
||
|
usr/idbm_fields.h | 63 ++++++
|
||
|
usr/iscsi_ipc.h | 13 ++
|
||
|
usr/iscsi_sysfs.c | 234 ++++++++++++++++++++
|
||
|
usr/iscsi_sysfs.h | 17 ++
|
||
|
usr/iscsiadm.c | 429 ++++++++++++++++++++++++++++++++++++-
|
||
|
usr/netlink.c | 171 ++++++++++++++-
|
||
|
12 files changed, 2031 insertions(+), 10 deletions(-)
|
||
|
create mode 100644 usr/flashnode.c
|
||
|
create mode 100644 usr/flashnode.h
|
||
|
|
||
|
diff --git a/include/iscsi_if.h b/include/iscsi_if.h
|
||
|
index dad9fd8..20f2bc2 100644
|
||
|
--- a/include/iscsi_if.h
|
||
|
+++ b/include/iscsi_if.h
|
||
|
@@ -68,8 +68,14 @@ enum iscsi_uevent_e {
|
||
|
ISCSI_UEVENT_PING = UEVENT_BASE + 22,
|
||
|
ISCSI_UEVENT_GET_CHAP = UEVENT_BASE + 23,
|
||
|
ISCSI_UEVENT_DELETE_CHAP = UEVENT_BASE + 24,
|
||
|
+ ISCSI_UEVENT_SET_FLASHNODE_PARAMS = UEVENT_BASE + 25,
|
||
|
+ ISCSI_UEVENT_NEW_FLASHNODE = UEVENT_BASE + 26,
|
||
|
+ ISCSI_UEVENT_DEL_FLASHNODE = UEVENT_BASE + 27,
|
||
|
+ ISCSI_UEVENT_LOGIN_FLASHNODE = UEVENT_BASE + 28,
|
||
|
+ ISCSI_UEVENT_LOGOUT_FLASHNODE = UEVENT_BASE + 29,
|
||
|
+ ISCSI_UEVENT_LOGOUT_FLASHNODE_SID = UEVENT_BASE + 30,
|
||
|
|
||
|
- ISCSI_UEVENT_MAX = ISCSI_UEVENT_DELETE_CHAP,
|
||
|
+ ISCSI_UEVENT_MAX = ISCSI_UEVENT_LOGOUT_FLASHNODE_SID,
|
||
|
|
||
|
/* up events */
|
||
|
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
|
||
|
@@ -219,6 +225,31 @@ struct iscsi_uevent {
|
||
|
uint32_t host_no;
|
||
|
uint16_t chap_tbl_idx;
|
||
|
} delete_chap;
|
||
|
+ struct msg_set_flashnode_param {
|
||
|
+ uint32_t host_no;
|
||
|
+ uint32_t flashnode_idx;
|
||
|
+ uint32_t count;
|
||
|
+ } set_flashnode;
|
||
|
+ struct msg_new_flashnode {
|
||
|
+ uint32_t host_no;
|
||
|
+ uint32_t len;
|
||
|
+ } new_flashnode;
|
||
|
+ struct msg_del_flashnode {
|
||
|
+ uint32_t host_no;
|
||
|
+ uint32_t flashnode_idx;
|
||
|
+ } del_flashnode;
|
||
|
+ struct msg_login_flashnode {
|
||
|
+ uint32_t host_no;
|
||
|
+ uint32_t flashnode_idx;
|
||
|
+ } login_flashnode;
|
||
|
+ struct msg_logout_flashnode {
|
||
|
+ uint32_t host_no;
|
||
|
+ uint32_t flashnode_idx;
|
||
|
+ } logout_flashnode;
|
||
|
+ struct msg_logout_flashnode_sid {
|
||
|
+ uint32_t host_no;
|
||
|
+ uint32_t sid;
|
||
|
+ } logout_flashnode_sid;
|
||
|
} u;
|
||
|
union {
|
||
|
/* messages k -> u */
|
||
|
@@ -276,6 +307,9 @@ struct iscsi_uevent {
|
||
|
with each ping request */
|
||
|
uint32_t data_size;
|
||
|
} ping_comp;
|
||
|
+ struct msg_new_flashnode_ret {
|
||
|
+ uint32_t flashnode_idx;
|
||
|
+ } new_flashnode_ret;
|
||
|
} r;
|
||
|
} __attribute__ ((aligned (sizeof(uint64_t))));
|
||
|
|
||
|
@@ -283,6 +317,7 @@ enum iscsi_param_type {
|
||
|
ISCSI_PARAM, /* iscsi_param (session, conn, target, LU) */
|
||
|
ISCSI_HOST_PARAM, /* iscsi_host_param */
|
||
|
ISCSI_NET_PARAM, /* iscsi_net_param */
|
||
|
+ ISCSI_FLASHNODE_PARAM, /* iscsi_flashnode_param */
|
||
|
};
|
||
|
|
||
|
struct iscsi_iface_param_info {
|
||
|
@@ -502,6 +537,159 @@ enum iscsi_param {
|
||
|
#define ISCSI_TGT_RESET_TMO (1ULL << ISCSI_PARAM_TGT_RESET_TMO)
|
||
|
#define ISCSI_TARGET_ALIAS (1ULL << ISCSI_PARAM_TARGET_ALIAS)
|
||
|
|
||
|
+/* iSCSI Flash Target params */
|
||
|
+enum iscsi_flashnode_param {
|
||
|
+ ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6,
|
||
|
+ ISCSI_FLASHNODE_PORTAL_TYPE,
|
||
|
+ ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE,
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_SESS,
|
||
|
+ ISCSI_FLASHNODE_ENTRY_EN,
|
||
|
+ ISCSI_FLASHNODE_HDR_DGST_EN,
|
||
|
+ ISCSI_FLASHNODE_DATA_DGST_EN,
|
||
|
+ ISCSI_FLASHNODE_IMM_DATA_EN,
|
||
|
+ ISCSI_FLASHNODE_INITIAL_R2T_EN,
|
||
|
+ ISCSI_FLASHNODE_DATASEQ_INORDER,
|
||
|
+ ISCSI_FLASHNODE_PDU_INORDER,
|
||
|
+ ISCSI_FLASHNODE_CHAP_AUTH_EN,
|
||
|
+ ISCSI_FLASHNODE_SNACK_REQ_EN,
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN,
|
||
|
+ ISCSI_FLASHNODE_BIDI_CHAP_EN,
|
||
|
+ /* make authentication for discovery sessions optional */
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL,
|
||
|
+ ISCSI_FLASHNODE_ERL,
|
||
|
+ ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT,
|
||
|
+ ISCSI_FLASHNODE_TCP_NAGLE_DISABLE,
|
||
|
+ ISCSI_FLASHNODE_TCP_WSF_DISABLE,
|
||
|
+ ISCSI_FLASHNODE_TCP_TIMER_SCALE,
|
||
|
+ ISCSI_FLASHNODE_TCP_TIMESTAMP_EN,
|
||
|
+ ISCSI_FLASHNODE_IP_FRAG_DISABLE,
|
||
|
+ ISCSI_FLASHNODE_MAX_RECV_DLENGTH,
|
||
|
+ ISCSI_FLASHNODE_MAX_XMIT_DLENGTH,
|
||
|
+ ISCSI_FLASHNODE_FIRST_BURST,
|
||
|
+ ISCSI_FLASHNODE_DEF_TIME2WAIT,
|
||
|
+ ISCSI_FLASHNODE_DEF_TIME2RETAIN,
|
||
|
+ ISCSI_FLASHNODE_MAX_R2T,
|
||
|
+ ISCSI_FLASHNODE_KEEPALIVE_TMO,
|
||
|
+ ISCSI_FLASHNODE_ISID,
|
||
|
+ ISCSI_FLASHNODE_TSID,
|
||
|
+ ISCSI_FLASHNODE_PORT,
|
||
|
+ ISCSI_FLASHNODE_MAX_BURST,
|
||
|
+ ISCSI_FLASHNODE_DEF_TASKMGMT_TMO,
|
||
|
+ ISCSI_FLASHNODE_IPADDR,
|
||
|
+ ISCSI_FLASHNODE_ALIAS,
|
||
|
+ ISCSI_FLASHNODE_REDIRECT_IPADDR,
|
||
|
+ ISCSI_FLASHNODE_MAX_SEGMENT_SIZE,
|
||
|
+ ISCSI_FLASHNODE_LOCAL_PORT,
|
||
|
+ ISCSI_FLASHNODE_IPV4_TOS,
|
||
|
+ ISCSI_FLASHNODE_IPV6_TC,
|
||
|
+ ISCSI_FLASHNODE_IPV6_FLOW_LABEL,
|
||
|
+ ISCSI_FLASHNODE_NAME,
|
||
|
+ ISCSI_FLASHNODE_TPGT,
|
||
|
+ ISCSI_FLASHNODE_LINK_LOCAL_IPV6,
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX,
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE,
|
||
|
+ ISCSI_FLASHNODE_TCP_XMIT_WSF,
|
||
|
+ ISCSI_FLASHNODE_TCP_RECV_WSF,
|
||
|
+ ISCSI_FLASHNODE_CHAP_IN_IDX,
|
||
|
+ ISCSI_FLASHNODE_CHAP_OUT_IDX,
|
||
|
+ ISCSI_FLASHNODE_USERNAME,
|
||
|
+ ISCSI_FLASHNODE_USERNAME_IN,
|
||
|
+ ISCSI_FLASHNODE_PASSWORD,
|
||
|
+ ISCSI_FLASHNODE_PASSWORD_IN,
|
||
|
+ ISCSI_FLASHNODE_STATSN,
|
||
|
+ ISCSI_FLASHNODE_EXP_STATSN,
|
||
|
+ ISCSI_FLASHNODE_IS_BOOT_TGT,
|
||
|
+
|
||
|
+ ISCSI_FLASHNODE_MAX,
|
||
|
+};
|
||
|
+
|
||
|
+#define ISCSI_FNODE_IS_FW_ASSIGNED_IPV6 \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6)
|
||
|
+#define ISCSI_FNODE_PORTAL_TYPE (1ULL << ISCSI_FLASHNODE_PORTAL_TYPE)
|
||
|
+#define ISCSI_FNODE_AUTO_SND_TGT_DISABLE \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_OPT_AUTO_SND_TGT_DISABLE)
|
||
|
+#define ISCSI_FNODE_DISCOVERY_SESS \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_OPT_DISCOVERY_SESS)
|
||
|
+#define ISCSI_FNODE_ENTRY_EN (1ULL << ISCSI_FLASHNODE_ENTRY_EN)
|
||
|
+#define ISCSI_FNODE_HDR_DGST_EN (1ULL << ISCSI_FLASHNODE_HDR_DGST_EN)
|
||
|
+#define ISCSI_FNODE_DATA_DGST_EN (1ULL << ISCSI_FLASHNODE_DATA_DGST_EN)
|
||
|
+#define ISCSI_FNODE_IMM_DATA_EN (1ULL << ISCSI_FLASHNODE_IMM_DATA_EN)
|
||
|
+#define ISCSI_FNODE_INITIAL_R2T_EN (1ULL << ISCSI_FLASHNODE_INITIAL_R2T_EN)
|
||
|
+#define ISCSI_FNODE_DATASEQ_INORDER \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_DATASEQ_INORDER)
|
||
|
+#define ISCSI_FNODE_PDU_INORDER (1ULL << ISCSI_FLASHNODE_PDU_INORDER)
|
||
|
+#define ISCSI_FNODE_CHAP_AUTH_EN (1ULL << ISCSI_FLASHNODE_CHAP_AUTH_EN)
|
||
|
+#define ISCSI_FNODE_SNACK_REQ_EN (1ULL << ISCSI_FLASHNODE_SNACK_REQ_EN)
|
||
|
+#define ISCSI_FNODE_DISCOVERY_LOGOUT_EN \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN)
|
||
|
+#define ISCSI_FNODE_BIDI_CHAP_EN (1ULL << ISCSI_FLASHNODE_BIDI_CHAP_EN)
|
||
|
+#define ISCSI_FNODE_DISCOVERY_AUTH_OPTIONAL \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL)
|
||
|
+#define ISCSI_FNODE_ERL (1ULL << ISCSI_FLASHNODE_ERL)
|
||
|
+#define ISCSI_FNODE_TCP_TIMESTAMP_STAT \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT)
|
||
|
+#define ISCSI_FNODE_TCP_NAGLE_DISABLE \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_TCP_NAGLE_DISABLE)
|
||
|
+#define ISCSI_FNODE_TCP_WSF_DISABLE \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_TCP_WSF_DISABLE)
|
||
|
+#define ISCSI_FNODE_TCP_TIMER_SCALE \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_TCP_TIMER_SCALE)
|
||
|
+#define ISCSI_FNODE_TCP_TIMESTAMP_ENABLE \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_TCP_TIMESTAMP_ENABLE)
|
||
|
+#define ISCSI_FNODE_IP_FRAG_DISABLE \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_IP_FRAG_DISABLE)
|
||
|
+#define ISCSI_FNODE_MAX_RECV_DLENGTH \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_MAX_RECV_DLENGTH)
|
||
|
+#define ISCSI_FNODE_MAX_XMIT_DLENGTH \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_MAX_XMIT_DLENGTH)
|
||
|
+#define ISCSI_FNODE_FIRST_BURST (1ULL << ISCSI_FLASHNODE_FIRST_BURST)
|
||
|
+#define ISCSI_FNODE_DEF_TIME2WAIT (1ULL << ISCSI_FLASHNODE_DEF_TIME2WAIT)
|
||
|
+#define ISCSI_FNODE_DEF_TIME2RETAIN \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_DEF_TIME2RETAIN)
|
||
|
+#define ISCSI_FNODE_MAX_R2T (1ULL << ISCSI_FLASHNODE_MAX_R2T)
|
||
|
+#define ISCSI_FNODE_KEEPALIVE_TMO (1ULL << ISCSI_FLASHNODE_KEEPALIVE_TMO)
|
||
|
+#define ISCSI_FNODE_ISID (1ULL << ISCSI_FLASHNODE_ISID)
|
||
|
+#define ISCSI_FNODE_TSID (1ULL << ISCSI_FLASHNODE_TSID)
|
||
|
+#define ISCSI_FNODE_PORT (1ULL << ISCSI_FLASHNODE_PORT)
|
||
|
+#define ISCSI_FNODE_MAX_BURST (1ULL << ISCSI_FLASHNODE_MAX_BURST)
|
||
|
+#define ISCSI_FNODE_DEF_TMF_TMO (1ULL << ISCSI_FLASHNODE_DEF_TMF_TMO)
|
||
|
+#define ISCSI_FNODE_IPADDR (1ULL << ISCSI_FLASHNODE_IPADDR)
|
||
|
+#define ISCSI_FNODE_ALIAS (1ULL << ISCSI_FLASHNODE_ALIAS)
|
||
|
+#define ISCSI_FNODE_REDIRECT_IPADDR \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_REDIRECT_IPADDR)
|
||
|
+#define ISCSI_FNODE_MAX_SEGMENT_SIZE \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_MAX_SEGMENT_SIZE)
|
||
|
+#define ISCSI_FNODE_LOCAL_PORT (1ULL << ISCSI_FLASHNODE_LOCAL_PORT)
|
||
|
+#define ISCSI_FNODE_IPV4_TOS (1ULL << ISCSI_FLASHNODE_IPV4_TOS)
|
||
|
+#define ISCSI_FNODE_IPV6_TC (1ULL << ISCSI_FLASHNODE_IPV6_TC)
|
||
|
+#define ISCSI_FNODE_IPV6_FLOW_LABEL \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_IPV6_FLOW_LABEL)
|
||
|
+#define ISCSI_FNODE_NAME (1ULL << ISCSI_FLASHNODE_NAME)
|
||
|
+#define ISCSI_FNODE_TPGT (1ULL << ISCSI_FLASHNODE_TPGT)
|
||
|
+#define ISCSI_FNODE_LINK_LOCAL_IPV6 \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_LINK_LOCAL_IPV6)
|
||
|
+#define ISCSI_FNODE_DISCOVERY_PARENT_IDX \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX)
|
||
|
+#define ISCSI_FNODE_DISCOVERY_PARENT_TYPE \
|
||
|
+ (1ULL << ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE)
|
||
|
+#define ISCSI_FNODE_TCP_XMIT_WSF (1ULL << ISCSI_FLASHNODE_TCP_XMIT_WSF)
|
||
|
+#define ISCSI_FNODE_TCP_RECV_WSF (1ULL << ISCSI_FLASHNODE_TCP_RECV_WSF)
|
||
|
+#define ISCSI_FNODE_CHAP_IN_IDX (1ULL << ISCSI_FLASHNODE_CHAP_IN_IDX)
|
||
|
+#define ISCSI_FNODE_CHAP_OUT_IDX (1ULL << ISCSI_FLASHNODE_CHAP_OUT_IDX)
|
||
|
+#define ISCSI_FNODE_USERNAME (1ULL << ISCSI_FLASHNODE_USERNAME)
|
||
|
+#define ISCSI_FNODE_USERNAME_IN (1ULL << ISCSI_FLASHNODE_USERNAME_IN)
|
||
|
+#define ISCSI_FNODE_PASSWORD (1ULL << ISCSI_FLASHNODE_PASSWORD)
|
||
|
+#define ISCSI_FNODE_PASSWORD_IN (1ULL << ISCSI_FLASHNODE_PASSWORD_IN)
|
||
|
+#define ISCSI_FNODE_STATSN (1ULL << ISCSI_FLASHNODE_STATSN)
|
||
|
+#define ISCSI_FNODE_EXP_STATSN (1ULL << ISCSI_FLASHNODE_EXP_STATSN)
|
||
|
+#define ISCSI_FNODE_IS_BOOT_TGT (1ULL << ISCSI_FLASHNODE_IS_BOOT_TGT)
|
||
|
+
|
||
|
+struct iscsi_flashnode_param_info {
|
||
|
+ uint32_t len; /* Actual length of the param */
|
||
|
+ uint16_t param; /* iscsi param value */
|
||
|
+ uint8_t value[0]; /* length sized value follows */
|
||
|
+} __attribute__((__packed__));
|
||
|
+
|
||
|
/* iSCSI HBA params */
|
||
|
enum iscsi_host_param {
|
||
|
ISCSI_HOST_PARAM_HWADDRESS,
|
||
|
diff --git a/usr/Makefile b/usr/Makefile
|
||
|
index 33b517c..3d8ee22 100644
|
||
|
--- a/usr/Makefile
|
||
|
+++ b/usr/Makefile
|
||
|
@@ -40,7 +40,7 @@ SYSDEPS_SRCS = $(wildcard ../utils/sysdeps/*.o)
|
||
|
ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o iscsi_timer.o login.o log.o md5.o \
|
||
|
sha1.o iface.o idbm.o sysfs.o host.o session_info.o iscsi_sysfs.o \
|
||
|
iscsi_net_util.o iscsid_req.o transport.o iser.o cxgbi.o be2iscsi.o \
|
||
|
- initiator_common.o iscsi_err.o uip_mgmt_ipc.o \
|
||
|
+ initiator_common.o iscsi_err.o flashnode.o uip_mgmt_ipc.o \
|
||
|
$(IPC_OBJ) $(SYSDEPS_SRCS)
|
||
|
# core initiator files
|
||
|
INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o kern_err_table.o
|
||
|
diff --git a/usr/flashnode.c b/usr/flashnode.c
|
||
|
new file mode 100644
|
||
|
index 0000000..da1392a
|
||
|
--- /dev/null
|
||
|
+++ b/usr/flashnode.c
|
||
|
@@ -0,0 +1,609 @@
|
||
|
+/*
|
||
|
+ * iSCSI flashnode helpers
|
||
|
+ *
|
||
|
+ * Copyright (C) 2013 QLogic Corporation.
|
||
|
+ * Maintained by open-iscsi@googlegroups.com
|
||
|
+ *
|
||
|
+ * This program is free software; you can redistribute it and/or modify
|
||
|
+ * it under the terms of the GNU General Public License as published
|
||
|
+ * by the Free Software Foundation; either version 2 of the License, or
|
||
|
+ * (at your option) any later version.
|
||
|
+ *
|
||
|
+ * This program is distributed in the hope that it will be useful, but
|
||
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
+ * General Public License for more details.
|
||
|
+ *
|
||
|
+ * See the file COPYING included with this distribution for more details.
|
||
|
+ */
|
||
|
+#include <errno.h>
|
||
|
+#include <stdlib.h>
|
||
|
+#include <stdio.h>
|
||
|
+#include <unistd.h>
|
||
|
+#include <string.h>
|
||
|
+#include <sys/stat.h>
|
||
|
+#include <arpa/inet.h>
|
||
|
+
|
||
|
+#include "log.h"
|
||
|
+#include "idbm.h"
|
||
|
+#include "iscsi_util.h"
|
||
|
+#include "transport.h"
|
||
|
+#include "iscsi_sysfs.h"
|
||
|
+#include "list.h"
|
||
|
+#include "sysdeps.h"
|
||
|
+#include "idbm_fields.h"
|
||
|
+#include "iscsi_err.h"
|
||
|
+#include "iscsi_ipc.h"
|
||
|
+#include "iscsi_netlink.h"
|
||
|
+#include "flashnode.h"
|
||
|
+#include "iscsi_settings.h"
|
||
|
+
|
||
|
+char key[NAME_MAXVAL];
|
||
|
+
|
||
|
+char *to_key(const char *fmt)
|
||
|
+{
|
||
|
+ int i = 0;
|
||
|
+ memset(key, 0, sizeof(key));
|
||
|
+ sprintf(key, fmt, i);
|
||
|
+ return key;
|
||
|
+}
|
||
|
+
|
||
|
+int flashnode_info_print_flat(void *data, struct flashnode_rec *fnode,
|
||
|
+ uint32_t host_no, uint32_t flashnode_idx)
|
||
|
+{
|
||
|
+ printf("%s: [%d] ", fnode->transport_name, flashnode_idx);
|
||
|
+ if (!strlen((char *)fnode->conn[0].ipaddress))
|
||
|
+ printf("%s:", UNKNOWN_VALUE);
|
||
|
+ else if (strchr((char *)fnode->conn[0].ipaddress, '.'))
|
||
|
+ printf("%s:", fnode->conn[0].ipaddress);
|
||
|
+ else
|
||
|
+ printf("[%s]:", fnode->conn[0].ipaddress);
|
||
|
+
|
||
|
+ if (!fnode->conn[0].port)
|
||
|
+ printf("%s,", UNKNOWN_VALUE);
|
||
|
+ else
|
||
|
+ printf("%u,", fnode->conn[0].port);
|
||
|
+
|
||
|
+ printf("%u ", fnode->sess.tpgt);
|
||
|
+
|
||
|
+ if (!strlen(fnode->sess.targetname))
|
||
|
+ printf("%s\n", UNKNOWN_VALUE);
|
||
|
+ else
|
||
|
+ printf("%s\n", fnode->sess.targetname);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int flashnode_fill_isid(struct flashnode_rec *fnode, struct iovec *iov)
|
||
|
+{
|
||
|
+ struct iscsi_flashnode_param_info *fnode_param;
|
||
|
+ struct nlattr *attr;
|
||
|
+ int len;
|
||
|
+ uint8_t isid[6];
|
||
|
+
|
||
|
+ len = sizeof(struct iscsi_flashnode_param_info) + 6;
|
||
|
+ iov->iov_base = iscsi_nla_alloc(ISCSI_FLASHNODE_ISID, len);
|
||
|
+ if (!iov->iov_base)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ attr = iov->iov_base;
|
||
|
+ iov->iov_len = NLA_ALIGN(attr->nla_len);
|
||
|
+
|
||
|
+ fnode_param = (struct iscsi_flashnode_param_info *)ISCSI_NLA_DATA(attr);
|
||
|
+ fnode_param->param = ISCSI_FLASHNODE_ISID;
|
||
|
+ fnode_param->len = 6;
|
||
|
+
|
||
|
+ sscanf(fnode->sess.isid, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
|
||
|
+ &isid[0], &isid[1], &isid[2], &isid[3], &isid[4], &isid[5]);
|
||
|
+
|
||
|
+ memcpy(fnode_param->value, isid, fnode_param->len);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int flashnode_fill_ipv4_addr(struct flashnode_rec *fnode,
|
||
|
+ struct iovec *iov, int param_type)
|
||
|
+{
|
||
|
+ struct iscsi_flashnode_param_info *fnode_param;
|
||
|
+ struct nlattr *attr;
|
||
|
+ int len;
|
||
|
+ int rc;
|
||
|
+
|
||
|
+ len = sizeof(struct iscsi_flashnode_param_info) + 4;
|
||
|
+ iov->iov_base = iscsi_nla_alloc(param_type, len);
|
||
|
+ if (!iov->iov_base)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ attr = iov->iov_base;
|
||
|
+ iov->iov_len = NLA_ALIGN(attr->nla_len);
|
||
|
+
|
||
|
+ fnode_param = (struct iscsi_flashnode_param_info *)ISCSI_NLA_DATA(attr);
|
||
|
+ fnode_param->param = param_type;
|
||
|
+ fnode_param->len = 4;
|
||
|
+
|
||
|
+ switch (param_type) {
|
||
|
+ case ISCSI_FLASHNODE_IPADDR:
|
||
|
+ rc = inet_pton(AF_INET, (char *)fnode->conn[0].ipaddress,
|
||
|
+ fnode_param->value);
|
||
|
+ break;
|
||
|
+ case ISCSI_FLASHNODE_REDIRECT_IPADDR:
|
||
|
+ rc = inet_pton(AF_INET, (char *)fnode->conn[0].redirect_ipaddr,
|
||
|
+ fnode_param->value);
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ goto free;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (rc <= 0)
|
||
|
+ goto free;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+
|
||
|
+free:
|
||
|
+ free(iov->iov_base);
|
||
|
+ iov->iov_base = NULL;
|
||
|
+ iov->iov_len = 0;
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
+static int flashnode_fill_ipv6_addr(struct flashnode_rec *fnode,
|
||
|
+ struct iovec *iov, int param_type)
|
||
|
+{
|
||
|
+ struct iscsi_flashnode_param_info *fnode_param;
|
||
|
+ struct nlattr *attr;
|
||
|
+ int len;
|
||
|
+ int rc;
|
||
|
+
|
||
|
+ len = sizeof(struct iscsi_flashnode_param_info) + 16;
|
||
|
+ iov->iov_base = iscsi_nla_alloc(param_type, len);
|
||
|
+ if (!iov->iov_base)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ attr = iov->iov_base;
|
||
|
+ iov->iov_len = NLA_ALIGN(attr->nla_len);
|
||
|
+
|
||
|
+ fnode_param = (struct iscsi_flashnode_param_info *)ISCSI_NLA_DATA(attr);
|
||
|
+ fnode_param->param = param_type;
|
||
|
+ fnode_param->len = 16;
|
||
|
+
|
||
|
+ switch (param_type) {
|
||
|
+ case ISCSI_FLASHNODE_IPADDR:
|
||
|
+ rc = inet_pton(AF_INET6, (char *)fnode->conn[0].ipaddress,
|
||
|
+ fnode_param->value);
|
||
|
+ break;
|
||
|
+ case ISCSI_FLASHNODE_REDIRECT_IPADDR:
|
||
|
+ rc = inet_pton(AF_INET6, (char *)fnode->conn[0].redirect_ipaddr,
|
||
|
+ fnode_param->value);
|
||
|
+ break;
|
||
|
+ case ISCSI_FLASHNODE_LINK_LOCAL_IPV6:
|
||
|
+ rc = inet_pton(AF_INET6, (char *)fnode->conn[0].link_local_ipv6,
|
||
|
+ fnode_param->value);
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ goto free;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (rc <= 0)
|
||
|
+ goto free;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+
|
||
|
+free:
|
||
|
+ free(iov->iov_base);
|
||
|
+ iov->iov_base = NULL;
|
||
|
+ iov->iov_len = 0;
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
+static int flashnode_fill_ipaddr(struct flashnode_rec *fnode, struct iovec *iov,
|
||
|
+ int param_type)
|
||
|
+{
|
||
|
+ int rc = 0;
|
||
|
+
|
||
|
+ if (!strncmp(fnode->sess.portal_type, "ipv4", 4))
|
||
|
+ rc = flashnode_fill_ipv4_addr(fnode, iov, param_type);
|
||
|
+ else
|
||
|
+ rc = flashnode_fill_ipv6_addr(fnode, iov, param_type);
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+static int flashnode_fill_uint8(struct flashnode_rec *fnode, struct iovec *iov,
|
||
|
+ int param_type, uint8_t val)
|
||
|
+{
|
||
|
+ struct iscsi_flashnode_param_info *fnode_param;
|
||
|
+ struct nlattr *attr;
|
||
|
+ int len;
|
||
|
+
|
||
|
+ len = sizeof(struct iscsi_flashnode_param_info) + 1;
|
||
|
+ iov->iov_base = iscsi_nla_alloc(param_type, len);
|
||
|
+ if (!iov->iov_base)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ attr = iov->iov_base;
|
||
|
+ iov->iov_len = NLA_ALIGN(attr->nla_len);
|
||
|
+
|
||
|
+ fnode_param = (struct iscsi_flashnode_param_info *)ISCSI_NLA_DATA(attr);
|
||
|
+ fnode_param->param = param_type;
|
||
|
+ fnode_param->len = 1;
|
||
|
+ fnode_param->value[0] = val;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int flashnode_fill_uint16(struct flashnode_rec *fnode, struct iovec *iov,
|
||
|
+ int param_type, uint16_t val)
|
||
|
+{
|
||
|
+ struct iscsi_flashnode_param_info *fnode_param;
|
||
|
+ struct nlattr *attr;
|
||
|
+ int len;
|
||
|
+
|
||
|
+ len = sizeof(struct iscsi_flashnode_param_info) + 2;
|
||
|
+ iov->iov_base = iscsi_nla_alloc(param_type, len);
|
||
|
+ if (!iov->iov_base)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ attr = iov->iov_base;
|
||
|
+ iov->iov_len = NLA_ALIGN(attr->nla_len);
|
||
|
+
|
||
|
+ fnode_param = (struct iscsi_flashnode_param_info *)ISCSI_NLA_DATA(attr);
|
||
|
+ fnode_param->param = param_type;
|
||
|
+ fnode_param->len = 2;
|
||
|
+ memcpy(fnode_param->value, &val, fnode_param->len);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int flashnode_fill_uint32(struct flashnode_rec *fnode, struct iovec *iov,
|
||
|
+ int param_type, uint32_t val)
|
||
|
+{
|
||
|
+ struct iscsi_flashnode_param_info *fnode_param;
|
||
|
+ struct nlattr *attr;
|
||
|
+ int len;
|
||
|
+
|
||
|
+ len = sizeof(struct iscsi_flashnode_param_info) + 4;
|
||
|
+ iov->iov_base = iscsi_nla_alloc(param_type, len);
|
||
|
+ if (!iov->iov_base)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ attr = iov->iov_base;
|
||
|
+ iov->iov_len = NLA_ALIGN(attr->nla_len);
|
||
|
+
|
||
|
+ fnode_param = (struct iscsi_flashnode_param_info *)ISCSI_NLA_DATA(attr);
|
||
|
+ fnode_param->param = param_type;
|
||
|
+ fnode_param->len = 4;
|
||
|
+ memcpy(fnode_param->value, &val, fnode_param->len);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int flashnode_fill_str(struct flashnode_rec *fnode, struct iovec *iov,
|
||
|
+ int param_type, char *buf, int buflen)
|
||
|
+{
|
||
|
+ struct iscsi_flashnode_param_info *fnode_param;
|
||
|
+ struct nlattr *attr;
|
||
|
+ int len;
|
||
|
+
|
||
|
+ len = sizeof(struct iscsi_flashnode_param_info) + buflen;
|
||
|
+ iov->iov_base = iscsi_nla_alloc(param_type, len);
|
||
|
+ if (!iov->iov_base)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ attr = iov->iov_base;
|
||
|
+ iov->iov_len = NLA_ALIGN(attr->nla_len);
|
||
|
+
|
||
|
+ fnode_param = (struct iscsi_flashnode_param_info *)ISCSI_NLA_DATA(attr);
|
||
|
+ fnode_param->param = param_type;
|
||
|
+ fnode_param->len = buflen;
|
||
|
+ memcpy(fnode_param->value, buf, fnode_param->len);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int flashnode_build_config(struct list_head *params,
|
||
|
+ struct flashnode_rec *fnode, struct iovec *iovs)
|
||
|
+{
|
||
|
+ struct user_param *param;
|
||
|
+ struct iovec *iov = NULL;
|
||
|
+ int count = 0;
|
||
|
+ int port = 3260;
|
||
|
+
|
||
|
+ /* start at 2, because 0 is for nlmsghdr and 1 for event */
|
||
|
+ iov = iovs + 2;
|
||
|
+
|
||
|
+ list_for_each_entry(param, params, list) {
|
||
|
+ if (!strcmp(param->name, FLASHNODE_SESS_AUTO_SND_TGT_DISABLE)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE,
|
||
|
+ fnode->sess.auto_snd_tgt_disable))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_DISCOVERY_SESS)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_SESS,
|
||
|
+ fnode->sess.discovery_session))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_ENTRY_EN)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_ENTRY_EN,
|
||
|
+ fnode->sess.entry_enable))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_IMM_DATA_EN)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_IMM_DATA_EN,
|
||
|
+ fnode->sess.immediate_data))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_INITIAL_R2T_EN)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_INITIAL_R2T_EN,
|
||
|
+ fnode->sess.initial_r2t))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_DATASEQ_INORDER)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DATASEQ_INORDER,
|
||
|
+ fnode->sess.data_seq_in_order))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_PDU_INORDER)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_PDU_INORDER,
|
||
|
+ fnode->sess.data_pdu_in_order))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_CHAP_AUTH_EN)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_CHAP_AUTH_EN,
|
||
|
+ fnode->sess.chap_auth_en))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_DISCOVERY_LOGOUT_EN)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN,
|
||
|
+ fnode->sess.discovery_logout_en))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_BIDI_CHAP_EN )) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_BIDI_CHAP_EN,
|
||
|
+ fnode->sess.bidi_chap_en))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_DISCOVERY_AUTH_OPTIONAL)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL,
|
||
|
+ fnode->sess.discovery_auth_optional))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_ERL)) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_ERL,
|
||
|
+ fnode->sess.erl))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_DEF_TIME2WAIT)) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DEF_TIME2WAIT,
|
||
|
+ fnode->sess.def_time2wait))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_DEF_TIME2RETAIN)) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DEF_TIME2RETAIN,
|
||
|
+ fnode->sess.def_time2retain))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_MAX_R2T)) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_MAX_R2T,
|
||
|
+ fnode->sess.max_outstanding_r2t))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_TSID)) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_TSID,
|
||
|
+ fnode->sess.tsid))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_MAX_BURST)) {
|
||
|
+ if (!flashnode_fill_uint32(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_MAX_BURST,
|
||
|
+ fnode->sess.max_burst_len))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_DEF_TASKMGMT_TMO)) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DEF_TASKMGMT_TMO,
|
||
|
+ fnode->sess.def_taskmgmt_tmo))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_NAME)) {
|
||
|
+ if (!flashnode_fill_str(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_NAME,
|
||
|
+ fnode->sess.targetname,
|
||
|
+ sizeof(fnode->sess.targetname)))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_FIRST_BURST)) {
|
||
|
+ if (!flashnode_fill_uint32(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_FIRST_BURST,
|
||
|
+ fnode->sess.first_burst_len))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_ISID)) {
|
||
|
+ if (!flashnode_fill_isid(fnode, &iov[count]))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_ALIAS)) {
|
||
|
+ if (!flashnode_fill_str(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_ALIAS,
|
||
|
+ fnode->sess.targetalias,
|
||
|
+ sizeof(fnode->sess.targetalias)))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_TPGT)) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_TPGT,
|
||
|
+ fnode->sess.tpgt))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_DISCOVERY_PARENT_IDX)) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX,
|
||
|
+ fnode->sess.discovery_parent_idx))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ FLASHNODE_SESS_DISCOVERY_PARENT_TYPE)) {
|
||
|
+ if (!flashnode_fill_str(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE,
|
||
|
+ fnode->sess.discovery_parent_type,
|
||
|
+ sizeof(fnode->sess.discovery_parent_type)))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, FLASHNODE_SESS_PORTAL_TYPE)) {
|
||
|
+ if (!flashnode_fill_str(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_PORTAL_TYPE,
|
||
|
+ fnode->sess.portal_type,
|
||
|
+ sizeof(fnode->sess.portal_type)))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name, to_key(FLASHNODE_CONN_PORT))) {
|
||
|
+ if (fnode->conn[0].port)
|
||
|
+ port = fnode->conn[0].port;
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_PORT, port))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_IPADDR))) {
|
||
|
+ if (!flashnode_fill_ipaddr(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_IPADDR))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_MAX_RECV_DLENGTH))) {
|
||
|
+ if (!flashnode_fill_uint32(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_MAX_RECV_DLENGTH,
|
||
|
+ fnode->conn[0].max_recv_dlength))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_IS_FW_ASSIGNED_IPV6))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6,
|
||
|
+ fnode->conn[0].is_fw_assigned_ipv6))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_HDR_DGST_EN))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_HDR_DGST_EN,
|
||
|
+ fnode->conn[0].header_digest_en))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_DATA_DGST_EN))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_DATA_DGST_EN,
|
||
|
+ fnode->conn[0].data_digest_en))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_SNACK_REQ_EN))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_SNACK_REQ_EN,
|
||
|
+ fnode->conn[0].snack_req_en))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_TCP_TIMESTAMP_STAT))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT,
|
||
|
+ fnode->conn[0].tcp_timestamp_stat))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_TCP_NAGLE_DISABLE))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_TCP_NAGLE_DISABLE,
|
||
|
+ fnode->conn[0].tcp_nagle_disable))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_TCP_WSF_DISABLE))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_TCP_WSF_DISABLE,
|
||
|
+ fnode->conn[0].tcp_wsf_disable))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_TCP_TIMER_SCALE))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_TCP_TIMER_SCALE,
|
||
|
+ fnode->conn[0].tcp_timer_scale))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_TCP_TIMESTAMP_EN))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_TCP_TIMESTAMP_EN,
|
||
|
+ fnode->conn[0].tcp_timestamp_en))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_IP_FRAG_DISABLE))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_IP_FRAG_DISABLE,
|
||
|
+ fnode->conn[0].fragment_disable))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_MAX_XMIT_DLENGTH))) {
|
||
|
+ if (!flashnode_fill_uint32(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_MAX_XMIT_DLENGTH,
|
||
|
+ fnode->conn[0].max_xmit_dlength))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_KEEPALIVE_TMO))) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_KEEPALIVE_TMO,
|
||
|
+ fnode->conn[0].keepalive_tmo))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_REDIRECT_IPADDR))) {
|
||
|
+ if (!flashnode_fill_ipaddr(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_REDIRECT_IPADDR))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_MAX_SEGMENT_SIZE))) {
|
||
|
+ if (!flashnode_fill_uint32(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_MAX_SEGMENT_SIZE,
|
||
|
+ fnode->conn[0].max_segment_size))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_LOCAL_PORT))) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_LOCAL_PORT,
|
||
|
+ fnode->conn[0].local_port))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_IPV4_TOS))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_IPV4_TOS,
|
||
|
+ fnode->conn[0].ipv4_tos))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_IPV6_TC))) {
|
||
|
+ if (!flashnode_fill_uint8(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_IPV6_TC,
|
||
|
+ fnode->conn[0].ipv6_traffic_class))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_IPV6_FLOW_LABEL))) {
|
||
|
+ if (!flashnode_fill_uint16(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_IPV6_FLOW_LABEL,
|
||
|
+ fnode->conn[0].ipv6_flow_lbl))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_LINK_LOCAL_IPV6))) {
|
||
|
+ if (!flashnode_fill_ipv6_addr(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_LINK_LOCAL_IPV6))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_TCP_XMIT_WSF))) {
|
||
|
+ if (!flashnode_fill_uint32(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_TCP_XMIT_WSF,
|
||
|
+ fnode->conn[0].tcp_xmit_wsf))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_TCP_RECV_WSF))) {
|
||
|
+ if (!flashnode_fill_uint32(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_TCP_RECV_WSF,
|
||
|
+ fnode->conn[0].tcp_recv_wsf))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_STATSN))) {
|
||
|
+ if (!flashnode_fill_uint32(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_STATSN,
|
||
|
+ fnode->conn[0].stat_sn))
|
||
|
+ count++;
|
||
|
+ } else if (!strcmp(param->name,
|
||
|
+ to_key(FLASHNODE_CONN_EXP_STATSN))) {
|
||
|
+ if (!flashnode_fill_uint32(fnode, &iov[count],
|
||
|
+ ISCSI_FLASHNODE_EXP_STATSN,
|
||
|
+ fnode->conn[0].exp_stat_sn))
|
||
|
+ count++;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ return count;
|
||
|
+}
|
||
|
diff --git a/usr/flashnode.h b/usr/flashnode.h
|
||
|
new file mode 100644
|
||
|
index 0000000..c1de9cc
|
||
|
--- /dev/null
|
||
|
+++ b/usr/flashnode.h
|
||
|
@@ -0,0 +1,127 @@
|
||
|
+/*
|
||
|
+ * iSCSI flashnode helpers
|
||
|
+ *
|
||
|
+ * Copyright (C) 2013 QLogic Corporation.
|
||
|
+ * Maintained by open-iscsi@googlegroups.com
|
||
|
+ *
|
||
|
+ * This program is free software; you can redistribute it and/or modify
|
||
|
+ * it under the terms of the GNU General Public License as published
|
||
|
+ * by the Free Software Foundation; either version 2 of the License, or
|
||
|
+ * (at your option) any later version.
|
||
|
+ *
|
||
|
+ * This program is distributed in the hope that it will be useful, but
|
||
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
+ * General Public License for more details.
|
||
|
+ *
|
||
|
+ * See the file COPYING included with this distribution for more details.
|
||
|
+ */
|
||
|
+#ifndef FLASHNODE_H
|
||
|
+#define FLASHNODE_H
|
||
|
+#include <sys/types.h>
|
||
|
+#include <netdb.h>
|
||
|
+#include <net/if.h>
|
||
|
+
|
||
|
+#include "types.h"
|
||
|
+#include "config.h"
|
||
|
+#include "auth.h"
|
||
|
+
|
||
|
+typedef enum portal_type {
|
||
|
+ IPV4,
|
||
|
+ IPV6,
|
||
|
+} portal_type_e;
|
||
|
+
|
||
|
+typedef struct flashnode_sess_rec {
|
||
|
+ char targetname[TARGET_NAME_MAXLEN];
|
||
|
+ char targetalias[TARGET_NAME_MAXLEN];
|
||
|
+ char username[AUTH_STR_MAX_LEN];
|
||
|
+ char username_in[AUTH_STR_MAX_LEN];
|
||
|
+ char password[AUTH_STR_MAX_LEN];
|
||
|
+ char password_in[AUTH_STR_MAX_LEN];
|
||
|
+ /* indicates if discovery was done through iSNS discovery service
|
||
|
+ * or through sendTarget */
|
||
|
+ char discovery_parent_type[ISCSI_MAX_STR_LEN];
|
||
|
+ char isid[16];
|
||
|
+ char portal_type[5]; /* ipv4 or ipv6 */
|
||
|
+ unsigned first_burst_len;
|
||
|
+ unsigned max_burst_len;
|
||
|
+ uint16_t def_time2wait;
|
||
|
+ uint16_t def_time2retain;
|
||
|
+ uint16_t max_outstanding_r2t;
|
||
|
+ uint16_t tsid;
|
||
|
+ uint16_t def_taskmgmt_tmo;
|
||
|
+ uint16_t tpgt;
|
||
|
+ uint16_t chap_out_idx;
|
||
|
+ uint16_t chap_in_idx;
|
||
|
+ /* index of iSCSI discovery session if the entry is
|
||
|
+ * discovered by iSCSI discovery session
|
||
|
+ */
|
||
|
+ uint16_t discovery_parent_idx;
|
||
|
+ /* Firmware auto sendtarget discovery disable */
|
||
|
+ uint8_t auto_snd_tgt_disable;
|
||
|
+ uint8_t discovery_session;
|
||
|
+ /* indicates if this flashnode entry is enabled or disabled */
|
||
|
+ uint8_t entry_enable;
|
||
|
+ uint8_t immediate_data;
|
||
|
+ uint8_t initial_r2t;
|
||
|
+ uint8_t data_seq_in_order;
|
||
|
+ uint8_t data_pdu_in_order;
|
||
|
+ uint8_t chap_auth_en;
|
||
|
+ /* enables firmware to auto logout the discovery session on discovery
|
||
|
+ * completion
|
||
|
+ */
|
||
|
+ uint8_t discovery_logout_en;
|
||
|
+ uint8_t bidi_chap_en;
|
||
|
+ /* makes authentication for discovery session optional */
|
||
|
+ uint8_t discovery_auth_optional;
|
||
|
+ uint8_t erl;
|
||
|
+ uint8_t is_boot_target;
|
||
|
+} flashnode_sess_rec_t;
|
||
|
+
|
||
|
+typedef struct flashnode_conn_rec {
|
||
|
+ char ipaddress[NI_MAXHOST];
|
||
|
+ char redirect_ipaddr[NI_MAXHOST];
|
||
|
+ char link_local_ipv6[NI_MAXHOST];
|
||
|
+ unsigned max_recv_dlength;
|
||
|
+ unsigned max_xmit_dlength;
|
||
|
+ unsigned max_segment_size;
|
||
|
+ unsigned tcp_xmit_wsf;
|
||
|
+ unsigned tcp_recv_wsf;
|
||
|
+ uint32_t stat_sn;
|
||
|
+ uint32_t exp_stat_sn;
|
||
|
+ uint16_t keepalive_tmo;
|
||
|
+ uint16_t port;
|
||
|
+ uint16_t local_port;
|
||
|
+ uint16_t ipv6_flow_lbl;
|
||
|
+ /* Link local IPv6 address is assigned by firmware or driver */
|
||
|
+ uint8_t is_fw_assigned_ipv6;
|
||
|
+ uint8_t header_digest_en;
|
||
|
+ uint8_t data_digest_en;
|
||
|
+ uint8_t snack_req_en;
|
||
|
+ /* tcp timestamp negotiation status */
|
||
|
+ uint8_t tcp_timestamp_stat;
|
||
|
+ uint8_t tcp_nagle_disable;
|
||
|
+ /* tcp window scale factor */
|
||
|
+ uint8_t tcp_wsf_disable;
|
||
|
+ uint8_t tcp_timer_scale;
|
||
|
+ uint8_t tcp_timestamp_en;
|
||
|
+ uint8_t fragment_disable;
|
||
|
+ uint8_t ipv4_tos;
|
||
|
+ uint8_t ipv6_traffic_class;
|
||
|
+} flashnode_conn_rec_t;
|
||
|
+
|
||
|
+struct flashnode_rec {
|
||
|
+ struct list_head list;
|
||
|
+ char transport_name[ISCSI_TRANSPORT_NAME_MAXLEN];
|
||
|
+ flashnode_sess_rec_t sess;
|
||
|
+ flashnode_conn_rec_t conn[ISCSI_CONN_MAX];
|
||
|
+};
|
||
|
+
|
||
|
+extern int flashnode_info_print_flat(void *data, struct flashnode_rec *tgt,
|
||
|
+ uint32_t host_no, uint32_t flashnode_idx);
|
||
|
+extern int iscsi_logout_flashnode_sid(struct iscsi_transport *t,
|
||
|
+ uint32_t host_no, uint32_t sid);
|
||
|
+extern int flashnode_build_config(struct list_head *params,
|
||
|
+ struct flashnode_rec *flashnode,
|
||
|
+ struct iovec *iovs);
|
||
|
+#endif
|
||
|
diff --git a/usr/idbm.c b/usr/idbm.c
|
||
|
index 4d30aa9..bc06058 100644
|
||
|
--- a/usr/idbm.c
|
||
|
+++ b/usr/idbm.c
|
||
|
@@ -94,6 +94,17 @@ static struct idbm *db;
|
||
|
_n++; \
|
||
|
} while (0)
|
||
|
|
||
|
+#define __recinfo_uint32(_key, _info, _rec, _name, _show, _n, _mod) do { \
|
||
|
+ _info[_n].type = TYPE_UINT32; \
|
||
|
+ strlcpy(_info[_n].name, _key, NAME_MAXVAL); \
|
||
|
+ snprintf(_info[_n].value, VALUE_MAXVAL, "%d", _rec->_name); \
|
||
|
+ _info[_n].data = &_rec->_name; \
|
||
|
+ _info[_n].data_len = sizeof(_rec->_name); \
|
||
|
+ _info[_n].visible = _show; \
|
||
|
+ _info[_n].can_modify = _mod; \
|
||
|
+ _n++; \
|
||
|
+} while (0)
|
||
|
+
|
||
|
#define __recinfo_int_o2(_key,_info,_rec,_name,_show,_op0,_op1,_n, _mod) do { \
|
||
|
_info[_n].type = TYPE_INT_O; \
|
||
|
strlcpy(_info[_n].name, _key, NAME_MAXVAL); \
|
||
|
@@ -469,6 +480,158 @@ static void idbm_recinfo_host_chap(struct iscsi_chap_rec *r, recinfo_t *ri)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+void idbm_recinfo_flashnode(struct flashnode_rec *r, recinfo_t *ri)
|
||
|
+{
|
||
|
+ int num = 0;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_AUTO_SND_TGT_DISABLE, ri, r,
|
||
|
+ sess.auto_snd_tgt_disable, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_DISCOVERY_SESS, ri, r,
|
||
|
+ sess.discovery_session, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_str(FLASHNODE_SESS_PORTAL_TYPE, ri, r, sess.portal_type,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_ENTRY_EN, ri, r,
|
||
|
+ sess.entry_enable, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_IMM_DATA_EN, ri, r, sess.immediate_data,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_INITIAL_R2T_EN, ri, r, sess.initial_r2t,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_DATASEQ_INORDER, ri, r,
|
||
|
+ sess.data_seq_in_order, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_PDU_INORDER, ri, r,
|
||
|
+ sess.data_pdu_in_order, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_CHAP_AUTH_EN, ri, r, sess.chap_auth_en,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_DISCOVERY_LOGOUT_EN, ri, r,
|
||
|
+ sess.discovery_logout_en, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_BIDI_CHAP_EN, ri, r, sess.bidi_chap_en,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_DISCOVERY_AUTH_OPTIONAL, ri, r,
|
||
|
+ sess.discovery_auth_optional, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_ERL, ri, r, sess.erl, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint32(FLASHNODE_SESS_FIRST_BURST, ri, r,
|
||
|
+ sess.first_burst_len, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint16(FLASHNODE_SESS_DEF_TIME2WAIT, ri, r,
|
||
|
+ sess.def_time2wait, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint16(FLASHNODE_SESS_DEF_TIME2RETAIN, ri, r,
|
||
|
+ sess.def_time2retain, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint16(FLASHNODE_SESS_MAX_R2T, ri, r,
|
||
|
+ sess.max_outstanding_r2t, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_str(FLASHNODE_SESS_ISID, ri, r, sess.isid, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint16(FLASHNODE_SESS_TSID, ri, r, sess.tsid, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ __recinfo_uint32(FLASHNODE_SESS_MAX_BURST, ri, r, sess.max_burst_len,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint16(FLASHNODE_SESS_DEF_TASKMGMT_TMO, ri, r,
|
||
|
+ sess.def_taskmgmt_tmo, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_str(FLASHNODE_SESS_ALIAS, ri, r, sess.targetalias, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ __recinfo_str(FLASHNODE_SESS_NAME, ri, r, sess.targetname, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ __recinfo_uint16(FLASHNODE_SESS_DISCOVERY_PARENT_IDX, ri, r,
|
||
|
+ sess.discovery_parent_idx, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_str(FLASHNODE_SESS_DISCOVERY_PARENT_TYPE, ri, r,
|
||
|
+ sess.discovery_parent_type, IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint16(FLASHNODE_SESS_TPGT, ri, r, sess.tpgt, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ __recinfo_uint16(FLASHNODE_SESS_CHAP_OUT_IDX, ri, r, sess.chap_out_idx,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint16(FLASHNODE_SESS_CHAP_IN_IDX, ri, r, sess.chap_in_idx,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_str(FLASHNODE_SESS_USERNAME, ri, r, sess.username, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ __recinfo_str(FLASHNODE_SESS_USERNAME_IN, ri, r, sess.username_in,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_str(FLASHNODE_SESS_PASSWORD, ri, r, sess.password, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ __recinfo_str(FLASHNODE_SESS_PASSWORD_IN, ri, r, sess.password_in,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ __recinfo_uint8(FLASHNODE_SESS_IS_BOOT_TGT, ri, r, sess.is_boot_target,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+
|
||
|
+ for (i = 0; i < ISCSI_CONN_MAX; i++) {
|
||
|
+ char key[NAME_MAXVAL];
|
||
|
+
|
||
|
+ sprintf(key, FLASHNODE_CONN_IS_FW_ASSIGNED_IPV6, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].is_fw_assigned_ipv6,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_HDR_DGST_EN, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].header_digest_en, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_DATA_DGST_EN, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].data_digest_en, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_SNACK_REQ_EN, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].snack_req_en, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_TCP_TIMESTAMP_STAT, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].tcp_timestamp_stat,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_TCP_NAGLE_DISABLE, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].tcp_nagle_disable,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_TCP_WSF_DISABLE, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].tcp_wsf_disable, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_TCP_TIMER_SCALE, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].tcp_timer_scale, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_TCP_TIMESTAMP_EN, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].tcp_timestamp_en,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_IP_FRAG_DISABLE, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].fragment_disable, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_MAX_XMIT_DLENGTH, i);
|
||
|
+ __recinfo_uint32(key, ri, r, conn[i].max_xmit_dlength,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_MAX_RECV_DLENGTH, i);
|
||
|
+ __recinfo_uint32(key, ri, r, conn[i].max_recv_dlength,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_KEEPALIVE_TMO, i);
|
||
|
+ __recinfo_uint16(key, ri, r, conn[i].keepalive_tmo, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_PORT, i);
|
||
|
+ __recinfo_uint16(key, ri, r, conn[i].port, IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_IPADDR, i);
|
||
|
+ __recinfo_str(key, ri, r, conn[i].ipaddress, IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_REDIRECT_IPADDR, i);
|
||
|
+ __recinfo_str(key, ri, r, conn[i].redirect_ipaddr, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_MAX_SEGMENT_SIZE, i);
|
||
|
+ __recinfo_uint32(key, ri, r, conn[i].max_segment_size,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_LOCAL_PORT, i);
|
||
|
+ __recinfo_uint16(key, ri, r, conn[i].local_port, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_IPV4_TOS, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].ipv4_tos, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_IPV6_TC, i);
|
||
|
+ __recinfo_uint8(key, ri, r, conn[i].ipv6_traffic_class,
|
||
|
+ IDBM_SHOW, num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_IPV6_FLOW_LABEL, i);
|
||
|
+ __recinfo_uint16(key, ri, r, conn[i].ipv6_flow_lbl, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_LINK_LOCAL_IPV6, i);
|
||
|
+ __recinfo_str(key, ri, r, conn[i].link_local_ipv6, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_TCP_XMIT_WSF, i);
|
||
|
+ __recinfo_uint32(key, ri, r, conn[i].tcp_xmit_wsf, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_TCP_RECV_WSF, i);
|
||
|
+ __recinfo_uint32(key, ri, r, conn[i].tcp_recv_wsf, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_STATSN, i);
|
||
|
+ __recinfo_uint32(key, ri, r, conn[i].stat_sn, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ sprintf(key, FLASHNODE_CONN_EXP_STATSN, i);
|
||
|
+ __recinfo_uint32(key, ri, r, conn[i].exp_stat_sn, IDBM_SHOW,
|
||
|
+ num, 1);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
recinfo_t *idbm_recinfo_alloc(int max_keys)
|
||
|
{
|
||
|
recinfo_t *info;
|
||
|
@@ -502,6 +665,9 @@ void idbm_print(int type, void *rec, int show, FILE *f)
|
||
|
case IDBM_PRINT_TYPE_HOST_CHAP:
|
||
|
idbm_recinfo_host_chap((struct iscsi_chap_rec *)rec, info);
|
||
|
break;
|
||
|
+ case IDBM_PRINT_TYPE_FLASHNODE:
|
||
|
+ idbm_recinfo_flashnode((struct flashnode_rec *)rec, info);
|
||
|
+ break;
|
||
|
}
|
||
|
|
||
|
fprintf(f, "%s\n", ISCSI_BEGIN_REC);
|
||
|
@@ -629,6 +795,13 @@ setup_passwd_len:
|
||
|
*(uint16_t *)info[i].data =
|
||
|
strtoul(value, NULL, 10);
|
||
|
goto updated;
|
||
|
+ } else if (info[i].type == TYPE_UINT32) {
|
||
|
+ if (!info[i].data)
|
||
|
+ continue;
|
||
|
+
|
||
|
+ *(uint32_t *)info[i].data =
|
||
|
+ strtoul(value, NULL, 10);
|
||
|
+ goto updated;
|
||
|
} else if (info[i].type == TYPE_STR) {
|
||
|
if (!info[i].data)
|
||
|
continue;
|
||
|
@@ -880,6 +1053,12 @@ int idbm_print_host_chap_info(struct iscsi_chap_rec *chap)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+int idbm_print_flashnode_info(struct flashnode_rec *fnode)
|
||
|
+{
|
||
|
+ idbm_print(IDBM_PRINT_TYPE_FLASHNODE, fnode, 1, stdout);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
int idbm_print_node_flat(void *data, node_rec_t *rec)
|
||
|
{
|
||
|
if (strchr(rec->conn[0].address, '.'))
|
||
|
diff --git a/usr/idbm.h b/usr/idbm.h
|
||
|
index 245f046..5e4038d 100644
|
||
|
--- a/usr/idbm.h
|
||
|
+++ b/usr/idbm.h
|
||
|
@@ -27,6 +27,7 @@
|
||
|
#include "initiator.h"
|
||
|
#include "config.h"
|
||
|
#include "list.h"
|
||
|
+#include "flashnode.h"
|
||
|
|
||
|
#define NODE_CONFIG_DIR ISCSI_CONFIG_ROOT"nodes"
|
||
|
#define SLP_CONFIG_DIR ISCSI_CONFIG_ROOT"slp"
|
||
|
@@ -42,6 +43,7 @@
|
||
|
#define TYPE_STR 2
|
||
|
#define TYPE_UINT8 3
|
||
|
#define TYPE_UINT16 4
|
||
|
+#define TYPE_UINT32 5
|
||
|
#define MAX_KEYS 256 /* number of keys total(including CNX_MAX) */
|
||
|
#define NAME_MAXVAL 128 /* the maximum length of key name */
|
||
|
#define VALUE_MAXVAL 256 /* the maximum length of 223 bytes in the RFC. */
|
||
|
@@ -85,6 +87,7 @@ struct user_param {
|
||
|
struct list_head list;
|
||
|
char *name;
|
||
|
char *value;
|
||
|
+ int param;
|
||
|
};
|
||
|
|
||
|
typedef int (idbm_iface_op_fn)(void *data, node_rec_t *rec);
|
||
|
@@ -168,6 +171,7 @@ enum {
|
||
|
IDBM_PRINT_TYPE_NODE,
|
||
|
IDBM_PRINT_TYPE_IFACE,
|
||
|
IDBM_PRINT_TYPE_HOST_CHAP,
|
||
|
+ IDBM_PRINT_TYPE_FLASHNODE
|
||
|
};
|
||
|
|
||
|
extern void idbm_print(int type, void *rec, int show, FILE *f);
|
||
|
@@ -182,4 +186,7 @@ idbm_create_rec_from_boot_context(struct boot_context *context);
|
||
|
|
||
|
extern int idbm_print_host_chap_info(struct iscsi_chap_rec *chap);
|
||
|
|
||
|
+extern int idbm_print_flashnode_info(struct flashnode_rec *target);
|
||
|
+extern void idbm_recinfo_flashnode(struct flashnode_rec *r, recinfo_t *ri);
|
||
|
+
|
||
|
#endif /* IDBM_H */
|
||
|
diff --git a/usr/idbm_fields.h b/usr/idbm_fields.h
|
||
|
index 358d014..179dda8 100644
|
||
|
--- a/usr/idbm_fields.h
|
||
|
+++ b/usr/idbm_fields.h
|
||
|
@@ -126,4 +126,67 @@
|
||
|
#define HOST_AUTH_PASSWORD_IN "host.auth.password_in"
|
||
|
#define HOST_AUTH_PASSWORD_IN_LEN "host.auth.password_in_length"
|
||
|
|
||
|
+/* flash target session fields */
|
||
|
+#define FLASHNODE_SESS_AUTO_SND_TGT_DISABLE "flashnode.session.auto_snd_tgt_disable"
|
||
|
+#define FLASHNODE_SESS_DISCOVERY_SESS "flashnode.session.discovery_session"
|
||
|
+#define FLASHNODE_SESS_PORTAL_TYPE "flashnode.session.portal_type"
|
||
|
+#define FLASHNODE_SESS_ENTRY_EN "flashnode.session.entry_enable"
|
||
|
+#define FLASHNODE_SESS_IMM_DATA_EN "flashnode.session.immediate_data"
|
||
|
+#define FLASHNODE_SESS_INITIAL_R2T_EN "flashnode.session.initial_r2t"
|
||
|
+#define FLASHNODE_SESS_DATASEQ_INORDER "flashnode.session.data_seq_in_order"
|
||
|
+#define FLASHNODE_SESS_PDU_INORDER "flashnode.session.data_pdu_in_order"
|
||
|
+#define FLASHNODE_SESS_CHAP_AUTH_EN "flashnode.session.chap_auth_en"
|
||
|
+#define FLASHNODE_SESS_DISCOVERY_LOGOUT_EN "flashnode.session.discovery_logout_en"
|
||
|
+#define FLASHNODE_SESS_BIDI_CHAP_EN "flashnode.session.bidi_chap_en"
|
||
|
+#define FLASHNODE_SESS_DISCOVERY_AUTH_OPTIONAL "flashnode.session.discovery_auth_optional"
|
||
|
+#define FLASHNODE_SESS_ERL "flashnode.session.erl"
|
||
|
+#define FLASHNODE_SESS_FIRST_BURST "flashnode.session.first_burst_len"
|
||
|
+#define FLASHNODE_SESS_DEF_TIME2WAIT "flashnode.session.def_time2wait"
|
||
|
+#define FLASHNODE_SESS_DEF_TIME2RETAIN "flashnode.session.def_time2retain"
|
||
|
+#define FLASHNODE_SESS_MAX_R2T "flashnode.session.max_outstanding_r2t"
|
||
|
+#define FLASHNODE_SESS_ISID "flashnode.session.isid"
|
||
|
+#define FLASHNODE_SESS_TSID "flashnode.session.tsid"
|
||
|
+#define FLASHNODE_SESS_MAX_BURST "flashnode.session.max_burst_len"
|
||
|
+#define FLASHNODE_SESS_DEF_TASKMGMT_TMO "flashnode.session.def_taskmgmt_tmo"
|
||
|
+#define FLASHNODE_SESS_ALIAS "flashnode.session.targetalias"
|
||
|
+#define FLASHNODE_SESS_NAME "flashnode.session.targetname"
|
||
|
+#define FLASHNODE_SESS_TPGT "flashnode.session.tpgt"
|
||
|
+#define FLASHNODE_SESS_DISCOVERY_PARENT_IDX "flashnode.session.discovery_parent_idx"
|
||
|
+#define FLASHNODE_SESS_DISCOVERY_PARENT_TYPE "flashnode.session.discovery_parent_type"
|
||
|
+#define FLASHNODE_SESS_CHAP_OUT_IDX "flashnode.session.chap_out_idx"
|
||
|
+#define FLASHNODE_SESS_CHAP_IN_IDX "flashnode.session.chap_in_idx"
|
||
|
+#define FLASHNODE_SESS_USERNAME "flashnode.session.username"
|
||
|
+#define FLASHNODE_SESS_USERNAME_IN "flashnode.session.username_in"
|
||
|
+#define FLASHNODE_SESS_PASSWORD "flashnode.session.password"
|
||
|
+#define FLASHNODE_SESS_PASSWORD_IN "flashnode.session.password_in"
|
||
|
+#define FLASHNODE_SESS_IS_BOOT_TGT "flashnode.session.is_boot_target"
|
||
|
+
|
||
|
+/* flash target connection fields */
|
||
|
+#define FLASHNODE_CONN_IS_FW_ASSIGNED_IPV6 "flashnode.conn[%d].is_fw_assigned_ipv6"
|
||
|
+#define FLASHNODE_CONN_HDR_DGST_EN "flashnode.conn[%d].header_digest_en"
|
||
|
+#define FLASHNODE_CONN_DATA_DGST_EN "flashnode.conn[%d].data_digest_en"
|
||
|
+#define FLASHNODE_CONN_SNACK_REQ_EN "flashnode.conn[%d].snack_req_en"
|
||
|
+#define FLASHNODE_CONN_TCP_TIMESTAMP_STAT "flashnode.conn[%d].tcp_timestamp_stat"
|
||
|
+#define FLASHNODE_CONN_TCP_NAGLE_DISABLE "flashnode.conn[%d].tcp_nagle_disable"
|
||
|
+#define FLASHNODE_CONN_TCP_WSF_DISABLE "flashnode.conn[%d].tcp_wsf_disable"
|
||
|
+#define FLASHNODE_CONN_TCP_TIMER_SCALE "flashnode.conn[%d].tcp_timer_scale"
|
||
|
+#define FLASHNODE_CONN_TCP_TIMESTAMP_EN "flashnode.conn[%d].tcp_timestamp_en"
|
||
|
+#define FLASHNODE_CONN_IP_FRAG_DISABLE "flashnode.conn[%d].fragment_disable"
|
||
|
+#define FLASHNODE_CONN_MAX_RECV_DLENGTH "flashnode.conn[%d].max_recv_dlength"
|
||
|
+#define FLASHNODE_CONN_MAX_XMIT_DLENGTH "flashnode.conn[%d].max_xmit_dlength"
|
||
|
+#define FLASHNODE_CONN_KEEPALIVE_TMO "flashnode.conn[%d].keepalive_tmo"
|
||
|
+#define FLASHNODE_CONN_PORT "flashnode.conn[%d].port"
|
||
|
+#define FLASHNODE_CONN_IPADDR "flashnode.conn[%d].ipaddress"
|
||
|
+#define FLASHNODE_CONN_REDIRECT_IPADDR "flashnode.conn[%d].redirect_ipaddr"
|
||
|
+#define FLASHNODE_CONN_MAX_SEGMENT_SIZE "flashnode.conn[%d].max_segment_size"
|
||
|
+#define FLASHNODE_CONN_LOCAL_PORT "flashnode.conn[%d].local_port"
|
||
|
+#define FLASHNODE_CONN_IPV4_TOS "flashnode.conn[%d].ipv4_tos"
|
||
|
+#define FLASHNODE_CONN_IPV6_TC "flashnode.conn[%d].ipv6_traffic_class"
|
||
|
+#define FLASHNODE_CONN_IPV6_FLOW_LABEL "flashnode.conn[%d].ipv6_flow_label"
|
||
|
+#define FLASHNODE_CONN_LINK_LOCAL_IPV6 "flashnode.conn[%d].link_local_ipv6"
|
||
|
+#define FLASHNODE_CONN_TCP_XMIT_WSF "flashnode.conn[%d].tcp_xmit_wsf"
|
||
|
+#define FLASHNODE_CONN_TCP_RECV_WSF "flashnode.conn[%d].tcp_recv_wsf"
|
||
|
+#define FLASHNODE_CONN_STATSN "flashnode.conn[%d].statsn"
|
||
|
+#define FLASHNODE_CONN_EXP_STATSN "flashnode.conn[%d].exp_statsn"
|
||
|
+
|
||
|
#endif
|
||
|
diff --git a/usr/iscsi_ipc.h b/usr/iscsi_ipc.h
|
||
|
index db5f1f0..b6665cb 100644
|
||
|
--- a/usr/iscsi_ipc.h
|
||
|
+++ b/usr/iscsi_ipc.h
|
||
|
@@ -145,6 +145,19 @@ struct iscsi_ipc {
|
||
|
|
||
|
int (*delete_chap) (uint64_t transport_handle, uint32_t host_no,
|
||
|
uint16_t chap_tbl_idx);
|
||
|
+ int (*set_flash_node_params) (uint64_t transport_handle,
|
||
|
+ uint32_t host_no, uint32_t flashnode_idx,
|
||
|
+ struct iovec *iovs, uint32_t param_count);
|
||
|
+ int (*new_flash_node) (uint64_t transport_handle, uint32_t host_no,
|
||
|
+ void *value, uint32_t *flashnode_idx);
|
||
|
+ int (*del_flash_node) (uint64_t transport_handle, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx);
|
||
|
+ int (*login_flash_node) (uint64_t transport_handle, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx);
|
||
|
+ int (*logout_flash_node) (uint64_t transport_handle, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx);
|
||
|
+ int (*logout_flash_node_sid) (uint64_t transport_handle,
|
||
|
+ uint32_t host_no, uint32_t sid);
|
||
|
};
|
||
|
|
||
|
#endif /* ISCSI_IPC_H */
|
||
|
diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c
|
||
|
index 4015b35..64a4ce7 100644
|
||
|
--- a/usr/iscsi_sysfs.c
|
||
|
+++ b/usr/iscsi_sysfs.c
|
||
|
@@ -29,6 +29,7 @@
|
||
|
#include "initiator.h"
|
||
|
#include "transport.h"
|
||
|
#include "idbm.h"
|
||
|
+#include "idbm_fields.h"
|
||
|
#include "version.h"
|
||
|
#include "iscsi_sysfs.h"
|
||
|
#include "sysdeps.h"
|
||
|
@@ -37,6 +38,7 @@
|
||
|
#include "session_info.h"
|
||
|
#include "host.h"
|
||
|
#include "iscsi_err.h"
|
||
|
+#include "flashnode.h"
|
||
|
|
||
|
/*
|
||
|
* TODO: remove the _DIR defines and search for subsys dirs like
|
||
|
@@ -45,18 +47,22 @@
|
||
|
#define ISCSI_TRANSPORT_DIR "/sys/class/iscsi_transport"
|
||
|
#define ISCSI_SESSION_DIR "/sys/class/iscsi_session"
|
||
|
#define ISCSI_HOST_DIR "/sys/class/iscsi_host"
|
||
|
+#define ISCSI_FLASHNODE_DIR "/sys/bus/iscsi_flashnode/devices"
|
||
|
|
||
|
#define ISCSI_SESSION_SUBSYS "iscsi_session"
|
||
|
#define ISCSI_CONN_SUBSYS "iscsi_connection"
|
||
|
#define ISCSI_HOST_SUBSYS "iscsi_host"
|
||
|
#define ISCSI_TRANSPORT_SUBSYS "iscsi_transport"
|
||
|
#define ISCSI_IFACE_SUBSYS "iscsi_iface"
|
||
|
+#define ISCSI_FLASHNODE_SUBSYS "iscsi_flashnode"
|
||
|
#define SCSI_HOST_SUBSYS "scsi_host"
|
||
|
#define SCSI_SUBSYS "scsi"
|
||
|
|
||
|
#define ISCSI_SESSION_ID "session%d"
|
||
|
#define ISCSI_CONN_ID "connection%d:0"
|
||
|
#define ISCSI_HOST_ID "host%d"
|
||
|
+#define ISCSI_FLASHNODE_SESS "flashnode_sess-%d:%d"
|
||
|
+#define ISCSI_FLASHNODE_CONN "flashnode_conn-%d:%d:0"
|
||
|
|
||
|
/*
|
||
|
* TODO: make this into a real API and check inputs better and add doc.
|
||
|
@@ -440,6 +446,234 @@ uint32_t iscsi_sysfs_get_host_no_from_hwinfo(struct iface_rec *iface, int *rc)
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
+ * Read the flash node attributes based on host and flash node index.
|
||
|
+ */
|
||
|
+int iscsi_sysfs_get_flashnode_info(struct flashnode_rec *fnode,
|
||
|
+ uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx)
|
||
|
+{
|
||
|
+ char sess_id[NAME_SIZE] = {'\0'};
|
||
|
+ char conn_id[NAME_SIZE] = {'\0'};
|
||
|
+ char fnode_path[PATH_SIZE] = {'\0'};
|
||
|
+ struct iscsi_transport *t;
|
||
|
+ int ret = 0;
|
||
|
+
|
||
|
+ t = iscsi_sysfs_get_transport_by_hba(host_no);
|
||
|
+ if (!t)
|
||
|
+ log_debug(7, "could not get transport name for host%d",
|
||
|
+ host_no);
|
||
|
+ else
|
||
|
+ strncpy(fnode->transport_name, t->name,
|
||
|
+ ISCSI_TRANSPORT_NAME_MAXLEN);
|
||
|
+
|
||
|
+ snprintf(sess_id, sizeof(sess_id), ISCSI_FLASHNODE_SESS, host_no,
|
||
|
+ flashnode_idx);
|
||
|
+
|
||
|
+ snprintf(fnode_path, sizeof(fnode_path), ISCSI_FLASHNODE_DIR"/%s",
|
||
|
+ sess_id);
|
||
|
+ if (access(fnode_path, F_OK) != 0)
|
||
|
+ return errno;
|
||
|
+
|
||
|
+ snprintf(conn_id, sizeof(conn_id), ISCSI_FLASHNODE_CONN, host_no,
|
||
|
+ flashnode_idx);
|
||
|
+
|
||
|
+ snprintf(fnode_path, sizeof(fnode_path), ISCSI_FLASHNODE_DIR"/%s",
|
||
|
+ conn_id);
|
||
|
+ if (access(fnode_path, F_OK) != 0)
|
||
|
+ return errno;
|
||
|
+
|
||
|
+
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "is_fw_assigned_ipv6",
|
||
|
+ &((fnode->conn[0]).is_fw_assigned_ipv6));
|
||
|
+ sysfs_get_str(sess_id, ISCSI_FLASHNODE_SUBSYS, "portal_type",
|
||
|
+ (fnode->sess).portal_type,
|
||
|
+ sizeof((fnode->sess).portal_type));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "auto_snd_tgt_disable",
|
||
|
+ &((fnode->sess).auto_snd_tgt_disable));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "discovery_session",
|
||
|
+ &((fnode->sess).discovery_session));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "entry_enable",
|
||
|
+ &((fnode->sess).entry_enable));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "header_digest",
|
||
|
+ &((fnode->conn[0]).header_digest_en));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "data_digest",
|
||
|
+ &((fnode->conn[0]).data_digest_en));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "immediate_data",
|
||
|
+ &((fnode->sess).immediate_data));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "initial_r2t",
|
||
|
+ &((fnode->sess).initial_r2t));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "data_seq_in_order",
|
||
|
+ &((fnode->sess).data_seq_in_order));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "data_pdu_in_order",
|
||
|
+ &((fnode->sess).data_pdu_in_order));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "chap_auth",
|
||
|
+ &((fnode->sess).chap_auth_en));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "snack_req",
|
||
|
+ &((fnode->conn[0]).snack_req_en));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "discovery_logout",
|
||
|
+ &((fnode->sess).discovery_logout_en));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "bidi_chap",
|
||
|
+ &((fnode->sess).bidi_chap_en));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS,
|
||
|
+ "discovery_auth_optional",
|
||
|
+ &((fnode->sess).discovery_auth_optional));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "erl",
|
||
|
+ &((fnode->sess).erl));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "tcp_timestamp_stat",
|
||
|
+ &((fnode->conn[0]).tcp_timestamp_stat));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "tcp_nagle_disable",
|
||
|
+ &((fnode->conn[0]).tcp_nagle_disable));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "tcp_wsf_disable",
|
||
|
+ &((fnode->conn[0]).tcp_wsf_disable));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "tcp_timer_scale",
|
||
|
+ &((fnode->conn[0]).tcp_timer_scale));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "tcp_timestamp_enable",
|
||
|
+ &((fnode->conn[0]).tcp_timestamp_en));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "fragment_disable",
|
||
|
+ &((fnode->conn[0]).fragment_disable));
|
||
|
+ sysfs_get_uint(conn_id, ISCSI_FLASHNODE_SUBSYS, "max_recv_dlength",
|
||
|
+ &((fnode->conn[0]).max_recv_dlength));
|
||
|
+ sysfs_get_uint(conn_id, ISCSI_FLASHNODE_SUBSYS, "max_xmit_dlength",
|
||
|
+ &((fnode->conn[0]).max_xmit_dlength));
|
||
|
+ sysfs_get_uint(sess_id, ISCSI_FLASHNODE_SUBSYS, "first_burst_len",
|
||
|
+ &((fnode->sess).first_burst_len));
|
||
|
+ sysfs_get_uint16(sess_id, ISCSI_FLASHNODE_SUBSYS, "def_time2wait",
|
||
|
+ &((fnode->sess).def_time2wait));
|
||
|
+ sysfs_get_uint16(sess_id, ISCSI_FLASHNODE_SUBSYS, "def_time2retain",
|
||
|
+ &((fnode->sess).def_time2retain));
|
||
|
+ sysfs_get_uint16(sess_id, ISCSI_FLASHNODE_SUBSYS, "max_outstanding_r2t",
|
||
|
+ &((fnode->sess).max_outstanding_r2t));
|
||
|
+ sysfs_get_uint16(conn_id, ISCSI_FLASHNODE_SUBSYS, "keepalive_tmo",
|
||
|
+ &((fnode->conn[0]).keepalive_tmo));
|
||
|
+ sysfs_get_str(sess_id, ISCSI_FLASHNODE_SUBSYS, "isid",
|
||
|
+ (fnode->sess).isid, sizeof((fnode->sess).isid));
|
||
|
+ sysfs_get_uint16(sess_id, ISCSI_FLASHNODE_SUBSYS, "tsid",
|
||
|
+ &((fnode->sess).tsid));
|
||
|
+ sysfs_get_uint16(conn_id, ISCSI_FLASHNODE_SUBSYS, "port",
|
||
|
+ &((fnode->conn[0]).port));
|
||
|
+ sysfs_get_uint(sess_id, ISCSI_FLASHNODE_SUBSYS, "max_burst_len",
|
||
|
+ &((fnode->sess).max_burst_len));
|
||
|
+ sysfs_get_uint16(sess_id, ISCSI_FLASHNODE_SUBSYS, "def_taskmgmt_tmo",
|
||
|
+ &((fnode->sess).def_taskmgmt_tmo));
|
||
|
+ sysfs_get_str(sess_id, ISCSI_FLASHNODE_SUBSYS, "targetalias",
|
||
|
+ (fnode->sess).targetalias,
|
||
|
+ sizeof((fnode->sess).targetalias));
|
||
|
+ sysfs_get_str(conn_id, ISCSI_FLASHNODE_SUBSYS, "ipaddress",
|
||
|
+ (fnode->conn[0]).ipaddress,
|
||
|
+ sizeof((fnode->conn[0]).ipaddress));
|
||
|
+ sysfs_get_str(conn_id, ISCSI_FLASHNODE_SUBSYS, "redirect_ipaddr",
|
||
|
+ (fnode->conn[0]).redirect_ipaddr,
|
||
|
+ sizeof((fnode->conn[0]).redirect_ipaddr));
|
||
|
+ sysfs_get_uint(conn_id, ISCSI_FLASHNODE_SUBSYS, "max_segment_size",
|
||
|
+ &((fnode->conn[0]).max_segment_size));
|
||
|
+ sysfs_get_uint16(conn_id, ISCSI_FLASHNODE_SUBSYS, "local_port",
|
||
|
+ &((fnode->conn[0]).local_port));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "ipv4_tos",
|
||
|
+ &((fnode->conn[0]).ipv4_tos));
|
||
|
+ sysfs_get_uint8(conn_id, ISCSI_FLASHNODE_SUBSYS, "ipv6_traffic_class",
|
||
|
+ &((fnode->conn[0]).ipv6_traffic_class));
|
||
|
+ sysfs_get_uint16(conn_id, ISCSI_FLASHNODE_SUBSYS, "ipv6_flow_label",
|
||
|
+ &((fnode->conn[0]).ipv6_flow_lbl));
|
||
|
+ sysfs_get_str(sess_id, ISCSI_FLASHNODE_SUBSYS, "targetname",
|
||
|
+ (fnode->sess).targetname,
|
||
|
+ sizeof((fnode->sess).targetname));
|
||
|
+ sysfs_get_str(conn_id, ISCSI_FLASHNODE_SUBSYS, "link_local_ipv6",
|
||
|
+ (fnode->conn[0]).link_local_ipv6,
|
||
|
+ sizeof((fnode->conn[0]).link_local_ipv6));
|
||
|
+ sysfs_get_uint16(sess_id, ISCSI_FLASHNODE_SUBSYS,
|
||
|
+ "discovery_parent_idx",
|
||
|
+ &((fnode->sess).discovery_parent_idx));
|
||
|
+ sysfs_get_str(sess_id, ISCSI_FLASHNODE_SUBSYS,
|
||
|
+ "discovery_parent_type",
|
||
|
+ (fnode->sess).discovery_parent_type,
|
||
|
+ sizeof((fnode->sess).discovery_parent_type));
|
||
|
+ sysfs_get_uint16(sess_id, ISCSI_FLASHNODE_SUBSYS, "tpgt",
|
||
|
+ &((fnode->sess).tpgt));
|
||
|
+ sysfs_get_uint(conn_id, ISCSI_FLASHNODE_SUBSYS, "tcp_xmit_wsf",
|
||
|
+ &((fnode->conn[0]).tcp_xmit_wsf));
|
||
|
+ sysfs_get_uint(conn_id, ISCSI_FLASHNODE_SUBSYS, "tcp_recv_wsf",
|
||
|
+ &((fnode->conn[0]).tcp_recv_wsf));
|
||
|
+ sysfs_get_uint16(sess_id, ISCSI_FLASHNODE_SUBSYS, "chap_out_idx",
|
||
|
+ &((fnode->sess).chap_out_idx));
|
||
|
+ sysfs_get_uint16(sess_id, ISCSI_FLASHNODE_SUBSYS, "chap_in_idx",
|
||
|
+ &((fnode->sess).chap_in_idx));
|
||
|
+ sysfs_get_str(sess_id, ISCSI_FLASHNODE_SUBSYS, "username",
|
||
|
+ (fnode->sess).username, sizeof((fnode->sess).username));
|
||
|
+ sysfs_get_str(sess_id, ISCSI_FLASHNODE_SUBSYS, "username_in",
|
||
|
+ (fnode->sess).username,
|
||
|
+ sizeof((fnode->sess).username_in));
|
||
|
+ sysfs_get_str(sess_id, ISCSI_FLASHNODE_SUBSYS, "password",
|
||
|
+ (fnode->sess).password, sizeof((fnode->sess).password));
|
||
|
+ sysfs_get_str(sess_id, ISCSI_FLASHNODE_SUBSYS, "password_in",
|
||
|
+ (fnode->sess).password,
|
||
|
+ sizeof((fnode->sess).password_in));
|
||
|
+ sysfs_get_uint(conn_id, ISCSI_FLASHNODE_SUBSYS, "statsn",
|
||
|
+ &((fnode->conn[0]).stat_sn));
|
||
|
+ sysfs_get_uint(conn_id, ISCSI_FLASHNODE_SUBSYS, "exp_statsn",
|
||
|
+ &((fnode->conn[0]).exp_stat_sn));
|
||
|
+ sysfs_get_uint8(sess_id, ISCSI_FLASHNODE_SUBSYS, "is_boot_target",
|
||
|
+ &((fnode->sess).is_boot_target));
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * For each flash node of the given host, perform operation specified in fn.
|
||
|
+ */
|
||
|
+int iscsi_sysfs_for_each_flashnode(void *data, uint32_t host_no, int *nr_found,
|
||
|
+ iscsi_sysfs_flashnode_op_fn *fn)
|
||
|
+{
|
||
|
+ struct dirent **namelist;
|
||
|
+ int rc = 0, i, n;
|
||
|
+ struct flashnode_rec *fnode;
|
||
|
+ uint32_t flashnode_idx;
|
||
|
+ uint32_t hostno;
|
||
|
+
|
||
|
+ fnode = malloc(sizeof(*fnode));
|
||
|
+ if (!fnode)
|
||
|
+ return ISCSI_ERR_NOMEM;
|
||
|
+
|
||
|
+ n = scandir(ISCSI_FLASHNODE_DIR, &namelist, trans_filter, alphasort);
|
||
|
+ if (n <= 0)
|
||
|
+ goto free_fnode;
|
||
|
+
|
||
|
+ for (i = 0; i < n; i++) {
|
||
|
+ memset(fnode, 0, sizeof(*fnode));
|
||
|
+
|
||
|
+ if (!strncmp(namelist[i]->d_name, "flashnode_conn",
|
||
|
+ strlen("flashnode_conn")))
|
||
|
+ continue;
|
||
|
+
|
||
|
+ if (sscanf(namelist[i]->d_name, ISCSI_FLASHNODE_SESS,
|
||
|
+ &hostno, &flashnode_idx) != 2) {
|
||
|
+ log_error("Invalid iscsi target dir: %s",
|
||
|
+ namelist[i]->d_name);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (host_no != hostno)
|
||
|
+ continue;
|
||
|
+
|
||
|
+ rc = iscsi_sysfs_get_flashnode_info(fnode, host_no,
|
||
|
+ flashnode_idx);
|
||
|
+ if (rc)
|
||
|
+ break;
|
||
|
+
|
||
|
+ rc = fn(data, fnode, host_no, flashnode_idx);
|
||
|
+ if (rc != 0)
|
||
|
+ break;
|
||
|
+ (*nr_found)++;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < n; i++)
|
||
|
+ free(namelist[i]);
|
||
|
+ free(namelist);
|
||
|
+
|
||
|
+free_fnode:
|
||
|
+ free(fnode);
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
* Read in iface settings based on host and session values. If
|
||
|
* session is not passed in, then the ifacename will not be set. And
|
||
|
* if the session is not passed in then iname will only be set for
|
||
|
diff --git a/usr/iscsi_sysfs.h b/usr/iscsi_sysfs.h
|
||
|
index 2b15d78..d130d36 100644
|
||
|
--- a/usr/iscsi_sysfs.h
|
||
|
+++ b/usr/iscsi_sysfs.h
|
||
|
@@ -31,6 +31,7 @@ struct iscsi_conn;
|
||
|
struct iscsi_session_operational_config;
|
||
|
struct iscsi_conn_operational_config;
|
||
|
struct iscsi_auth_config;
|
||
|
+struct flashnode_rec;
|
||
|
|
||
|
#define SCSI_MAX_STATE_VALUE 32
|
||
|
|
||
|
@@ -42,6 +43,8 @@ extern int iscsi_sysfs_session_has_leadconn(uint32_t sid);
|
||
|
|
||
|
typedef int (iscsi_sysfs_session_op_fn)(void *, struct session_info *);
|
||
|
typedef int (iscsi_sysfs_host_op_fn)(void *, struct host_info *);
|
||
|
+typedef int (iscsi_sysfs_flashnode_op_fn)(void *, struct flashnode_rec *,
|
||
|
+ uint32_t, uint32_t);
|
||
|
typedef int (iscsi_sysfs_iface_op_fn)(void *, struct iface_rec *);
|
||
|
|
||
|
extern int iscsi_sysfs_for_each_iface_on_host(void *data, uint32_t host_no,
|
||
|
@@ -56,6 +59,20 @@ extern uint32_t iscsi_sysfs_get_host_no_from_hwinfo(struct iface_rec *iface,
|
||
|
int *rc);
|
||
|
extern uint32_t iscsi_sysfs_get_host_no_from_hwaddress(char *hwaddress, int *rc);
|
||
|
extern int iscsi_sysfs_get_hostinfo_by_host_no(struct host_info *hinfo);
|
||
|
+extern int iscsi_sysfs_for_each_flashnode(void *data, uint32_t host_no,
|
||
|
+ int *nr_found,
|
||
|
+ iscsi_sysfs_flashnode_op_fn *fn);
|
||
|
+extern int iscsi_sysfs_get_flashnode_info(struct flashnode_rec *fnode,
|
||
|
+ uint32_t host_no,
|
||
|
+ uint32_t flashnode_id);
|
||
|
+extern int iscsi_sysfs_update_flashnode_param(uint32_t host_no,
|
||
|
+ uint32_t flashnode_id,
|
||
|
+ char *name, char *val);
|
||
|
+extern int iscsi_sysfs_create_flashnode(uint32_t host_no, char *ipver);
|
||
|
+extern int iscsi_sysfs_del_flashnode(uint32_t host_no, uint32_t flashnode_id);
|
||
|
+extern int iscsi_sysfs_login_flashnode(uint32_t host_no, uint32_t flashnode_id);
|
||
|
+extern int iscsi_sysfs_logout_flashnode(uint32_t host_no,
|
||
|
+ uint32_t flashnode_id);
|
||
|
extern int iscsi_sysfs_get_sid_from_path(char *session);
|
||
|
extern char *iscsi_sysfs_get_blockdev_from_lun(int hostno, int target, int sid);
|
||
|
|
||
|
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
|
||
|
index 8f9de05..5a18522 100644
|
||
|
--- a/usr/iscsiadm.c
|
||
|
+++ b/usr/iscsiadm.c
|
||
|
@@ -53,6 +53,7 @@
|
||
|
#include "iscsi_err.h"
|
||
|
#include "iscsi_ipc.h"
|
||
|
#include "iscsi_timer.h"
|
||
|
+#include "flashnode.h"
|
||
|
|
||
|
static char program_name[] = "iscsiadm";
|
||
|
static char config_file[TARGET_NAME_MAXLEN];
|
||
|
@@ -67,7 +68,8 @@ enum iscsiadm_mode {
|
||
|
MODE_IFACE,
|
||
|
MODE_FW,
|
||
|
MODE_PING,
|
||
|
- MODE_CHAP
|
||
|
+ MODE_CHAP,
|
||
|
+ MODE_FLASHNODE
|
||
|
};
|
||
|
|
||
|
enum iscsiadm_op {
|
||
|
@@ -78,7 +80,9 @@ enum iscsiadm_op {
|
||
|
OP_SHOW = 0x8,
|
||
|
OP_NONPERSISTENT = 0x10,
|
||
|
OP_APPLY = 0x20,
|
||
|
- OP_APPLY_ALL = 0x40
|
||
|
+ OP_APPLY_ALL = 0x40,
|
||
|
+ OP_LOGIN = 0x80,
|
||
|
+ OP_LOGOUT = 0x100
|
||
|
};
|
||
|
|
||
|
static struct option const long_options[] =
|
||
|
@@ -111,9 +115,11 @@ static struct option const long_options[] =
|
||
|
{"packetsize", required_argument, NULL, 'b'},
|
||
|
{"count", required_argument, NULL, 'c'},
|
||
|
{"interval", required_argument, NULL, 'i'},
|
||
|
+ {"flashnode_idx", optional_argument, NULL, 'x'},
|
||
|
+ {"portal_type", optional_argument, NULL, 'A'},
|
||
|
{NULL, 0, NULL, 0},
|
||
|
};
|
||
|
-static char *short_options = "RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:u";
|
||
|
+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:";
|
||
|
|
||
|
static void usage(int status)
|
||
|
{
|
||
|
@@ -130,7 +136,7 @@ iscsiadm -m node [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -L all,manual,au
|
||
|
iscsiadm -m session [ -hV ] [ -d debug_level ] [ -P printlevel] [ -r sessionid | sysfsdir [ -R | -u | -s ] [ -o operation ] [ -n name ] [ -v value ] ]\n\
|
||
|
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\
|
||
|
iscsiadm -m fw [ -l ]\n\
|
||
|
-iscsiadm -m host [ -P printlevel ] [ -H hostno|MAC ] [ -C chap [ -o operation ] [ -v chap_tbl_idx ] ]\n\
|
||
|
+iscsiadm -m host [ -P printlevel ] [ -H hostno|MAC ] [ [ -C chap [ -o operation ] [ -v chap_tbl_idx ] ] | [ -C flashnode [ -o operation ] [ -A portal_type ] [ -x flashnode_idx ] [ -n name ] [ -v value ] ] ]\n\
|
||
|
iscsiadm -k priority\n");
|
||
|
}
|
||
|
exit(status);
|
||
|
@@ -155,6 +161,10 @@ str_to_op(char *str)
|
||
|
op = OP_APPLY;
|
||
|
else if (!strcmp("applyall", str))
|
||
|
op = OP_APPLY_ALL;
|
||
|
+ else if (!strcmp("login", str))
|
||
|
+ op = OP_LOGIN;
|
||
|
+ else if (!strcmp("logout", str))
|
||
|
+ op = OP_LOGOUT;
|
||
|
else
|
||
|
op = OP_NOOP;
|
||
|
|
||
|
@@ -195,6 +205,8 @@ str_to_submode(char *str)
|
||
|
sub_mode = MODE_PING;
|
||
|
else if (!strcmp("chap", str))
|
||
|
sub_mode = MODE_CHAP;
|
||
|
+ else if (!strcmp("flashnode", str))
|
||
|
+ sub_mode = MODE_FLASHNODE;
|
||
|
else
|
||
|
sub_mode = -1;
|
||
|
|
||
|
@@ -221,6 +233,21 @@ str_to_type(char *str)
|
||
|
return type;
|
||
|
}
|
||
|
|
||
|
+static int
|
||
|
+str_to_portal_type(char *str)
|
||
|
+{
|
||
|
+ int ptype;
|
||
|
+
|
||
|
+ if (!strcmp("ipv4", str))
|
||
|
+ ptype = IPV4;
|
||
|
+ else if (!strcmp("ipv6", str))
|
||
|
+ ptype = IPV6;
|
||
|
+ else
|
||
|
+ ptype = -1;
|
||
|
+
|
||
|
+ return ptype;
|
||
|
+}
|
||
|
+
|
||
|
static void kill_iscsid(int priority)
|
||
|
{
|
||
|
iscsiadm_req_t req;
|
||
|
@@ -582,6 +609,8 @@ static int iscsi_logout_matched_portal(void *data, struct list_head *list,
|
||
|
{
|
||
|
struct node_rec *pattern_rec = data;
|
||
|
struct iscsi_transport *t;
|
||
|
+ uint32_t host_no;
|
||
|
+ int rc = 0;
|
||
|
|
||
|
t = iscsi_sysfs_get_transport_by_sid(info->sid);
|
||
|
if (!t)
|
||
|
@@ -590,7 +619,19 @@ static int iscsi_logout_matched_portal(void *data, struct list_head *list,
|
||
|
if (!iscsi_match_session(pattern_rec, info))
|
||
|
return -1;
|
||
|
|
||
|
- return iscsi_logout_portal(info, list);
|
||
|
+ host_no = iscsi_sysfs_get_host_no_from_sid(info->sid, &rc);
|
||
|
+ if (rc) {
|
||
|
+ log_error("could not get host_no for session%d: %s.",
|
||
|
+ info->sid, iscsi_err_to_str(rc));
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!iscsi_sysfs_session_user_created(info->sid))
|
||
|
+ rc = iscsi_logout_flashnode_sid(t, host_no, info->sid);
|
||
|
+ else
|
||
|
+ rc = iscsi_logout_portal(info, list);
|
||
|
+
|
||
|
+ return rc;
|
||
|
}
|
||
|
|
||
|
static int rec_match_fn(void *data, node_rec_t *rec)
|
||
|
@@ -1438,6 +1479,360 @@ static int exec_host_chap_op(int op, int info_level, uint32_t host_no,
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
+static int get_flashnode_info(uint32_t host_no, uint32_t flashnode_idx)
|
||
|
+{
|
||
|
+ struct flashnode_rec fnode;
|
||
|
+ int rc = 0;
|
||
|
+
|
||
|
+ memset(&fnode, 0, sizeof(fnode));
|
||
|
+ rc = iscsi_sysfs_get_flashnode_info(&fnode, host_no, flashnode_idx);
|
||
|
+ if (rc) {
|
||
|
+ log_error("Could not read info for flashnode %u of host %u, %s",
|
||
|
+ flashnode_idx, host_no, strerror(rc));
|
||
|
+ return rc;
|
||
|
+ }
|
||
|
+
|
||
|
+ idbm_print_flashnode_info(&fnode);
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+static int list_flashnodes(int info_level, uint32_t host_no)
|
||
|
+{
|
||
|
+ int rc = 0;
|
||
|
+ int num_found = 0;
|
||
|
+
|
||
|
+ rc = iscsi_sysfs_for_each_flashnode(NULL, host_no, &num_found,
|
||
|
+ flashnode_info_print_flat);
|
||
|
+
|
||
|
+ if (!num_found) {
|
||
|
+ log_error("No flashnodes attached to host %u.", host_no);
|
||
|
+ rc = ISCSI_ERR_NO_OBJS_FOUND;
|
||
|
+ }
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+int iscsi_set_flashnode_params(struct iscsi_transport *t, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx, struct list_head *params)
|
||
|
+{
|
||
|
+ struct flashnode_rec fnode;
|
||
|
+ recinfo_t *flashnode_info;
|
||
|
+ struct user_param *param;
|
||
|
+ struct iovec *iovs = NULL;
|
||
|
+ struct iovec *iov = NULL;
|
||
|
+ int fd, rc = 0;
|
||
|
+ int param_count = 0;
|
||
|
+ int param_used = 0;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ flashnode_info = idbm_recinfo_alloc(MAX_KEYS);
|
||
|
+ if (!flashnode_info) {
|
||
|
+ log_error("Out of Memory.");
|
||
|
+ rc = ISCSI_ERR_NOMEM;
|
||
|
+ goto free_info_rec;
|
||
|
+ }
|
||
|
+
|
||
|
+ memset(&fnode, 0, sizeof(fnode));
|
||
|
+ rc = iscsi_sysfs_get_flashnode_info(&fnode, host_no, flashnode_idx);
|
||
|
+ if (rc) {
|
||
|
+ log_error("Could not read info for flashnode %u, %s",
|
||
|
+ flashnode_idx, strerror(rc));
|
||
|
+ goto free_info_rec;
|
||
|
+ }
|
||
|
+
|
||
|
+ idbm_recinfo_flashnode(&fnode, flashnode_info);
|
||
|
+
|
||
|
+ i = 0;
|
||
|
+ list_for_each_entry(param, params, list) {
|
||
|
+ param_count++;
|
||
|
+ rc = idbm_verify_param(flashnode_info, param->name);
|
||
|
+ if (rc)
|
||
|
+ goto free_info_rec;
|
||
|
+ }
|
||
|
+
|
||
|
+ list_for_each_entry(param, params, list) {
|
||
|
+ rc = idbm_rec_update_param(flashnode_info, param->name,
|
||
|
+ param->value, 0);
|
||
|
+ if (rc)
|
||
|
+ goto free_info_rec;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* +2 for event and nlmsghdr */
|
||
|
+ param_count += 2;
|
||
|
+ iovs = calloc((param_count * sizeof(struct iovec)),
|
||
|
+ sizeof(char));
|
||
|
+ if (!iovs) {
|
||
|
+ log_error("Out of Memory.");
|
||
|
+ rc = ISCSI_ERR_NOMEM;
|
||
|
+ goto free_info_rec;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* param_used gives actual number of iovecs used for flashnode */
|
||
|
+ param_used = flashnode_build_config(params, &fnode, iovs);
|
||
|
+ if (!param_used) {
|
||
|
+ log_error("Build flashnode config failed.");
|
||
|
+ rc = ISCSI_ERR;
|
||
|
+ goto free_iovec;
|
||
|
+ }
|
||
|
+
|
||
|
+ fd = ipc->ctldev_open();
|
||
|
+ if (fd < 0) {
|
||
|
+ log_error("Netlink open failed.");
|
||
|
+ rc = ISCSI_ERR_INTERNAL;
|
||
|
+ goto free_iovec;
|
||
|
+ }
|
||
|
+
|
||
|
+ log_info("Update flashnode %u.", flashnode_idx);
|
||
|
+ rc = ipc->set_flash_node_params(t->handle, host_no, flashnode_idx,
|
||
|
+ iovs, param_count);
|
||
|
+ if (rc < 0)
|
||
|
+ rc = ISCSI_ERR;
|
||
|
+
|
||
|
+
|
||
|
+ ipc->ctldev_close();
|
||
|
+
|
||
|
+free_iovec:
|
||
|
+ /* start at 2, because 0 is for nlmsghdr and 1 for event */
|
||
|
+ iov = iovs + 2;
|
||
|
+ for (i = 0; i < param_used; i++, iov++) {
|
||
|
+ if (iov->iov_base)
|
||
|
+ free(iov->iov_base);
|
||
|
+ }
|
||
|
+
|
||
|
+ free(iovs);
|
||
|
+
|
||
|
+free_info_rec:
|
||
|
+ if (flashnode_info)
|
||
|
+ free(flashnode_info);
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+int iscsi_new_flashnode(struct iscsi_transport *t, uint32_t host_no, char *val,
|
||
|
+ uint32_t *flashnode_idx)
|
||
|
+{
|
||
|
+ int fd, rc = 0;
|
||
|
+
|
||
|
+ fd = ipc->ctldev_open();
|
||
|
+ if (fd < 0) {
|
||
|
+ log_error("Netlink open failed.");
|
||
|
+ rc = ISCSI_ERR_INTERNAL;
|
||
|
+ goto exit_new_flashnode;
|
||
|
+ }
|
||
|
+
|
||
|
+ log_info("Create new flashnode for host %u.", host_no);
|
||
|
+ rc = ipc->new_flash_node(t->handle, host_no, val, flashnode_idx);
|
||
|
+ if (rc < 0)
|
||
|
+ rc = ISCSI_ERR;
|
||
|
+
|
||
|
+ ipc->ctldev_close();
|
||
|
+
|
||
|
+exit_new_flashnode:
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+int iscsi_del_flashnode(struct iscsi_transport *t, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx)
|
||
|
+{
|
||
|
+ int fd, rc = 0;
|
||
|
+
|
||
|
+ fd = ipc->ctldev_open();
|
||
|
+ if (fd < 0) {
|
||
|
+ log_error("Netlink open failed.");
|
||
|
+ rc = ISCSI_ERR_INTERNAL;
|
||
|
+ goto exit_del_flashnode;
|
||
|
+ }
|
||
|
+
|
||
|
+ log_info("Delete flashnode %u.", flashnode_idx);
|
||
|
+ rc = ipc->del_flash_node(t->handle, host_no, flashnode_idx);
|
||
|
+ if (rc < 0)
|
||
|
+ rc = ISCSI_ERR;
|
||
|
+
|
||
|
+ ipc->ctldev_close();
|
||
|
+
|
||
|
+exit_del_flashnode:
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+int iscsi_login_flashnode(struct iscsi_transport *t, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx)
|
||
|
+{
|
||
|
+ int fd, rc = 0;
|
||
|
+
|
||
|
+ fd = ipc->ctldev_open();
|
||
|
+ if (fd < 0) {
|
||
|
+ log_error("Netlink open failed.");
|
||
|
+ rc = ISCSI_ERR_INTERNAL;
|
||
|
+ goto exit_login_flashnode;
|
||
|
+ }
|
||
|
+
|
||
|
+ log_info("Login to flashnode %u.", flashnode_idx);
|
||
|
+ rc = ipc->login_flash_node(t->handle, host_no, flashnode_idx);
|
||
|
+ if (rc == -EPERM)
|
||
|
+ rc = ISCSI_ERR_SESS_EXISTS;
|
||
|
+ else if (rc < 0)
|
||
|
+ rc = ISCSI_ERR_LOGIN;
|
||
|
+
|
||
|
+ ipc->ctldev_close();
|
||
|
+
|
||
|
+exit_login_flashnode:
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+int iscsi_logout_flashnode(struct iscsi_transport *t, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx)
|
||
|
+{
|
||
|
+ int fd, rc = 0;
|
||
|
+
|
||
|
+ fd = ipc->ctldev_open();
|
||
|
+ if (fd < 0) {
|
||
|
+ log_error("Netlink open failed.");
|
||
|
+ rc = ISCSI_ERR_INTERNAL;
|
||
|
+ goto exit_logout;
|
||
|
+ }
|
||
|
+
|
||
|
+ log_info("Logout flashnode %u.", flashnode_idx);
|
||
|
+ rc = ipc->logout_flash_node(t->handle, host_no, flashnode_idx);
|
||
|
+ if (rc == -ESRCH)
|
||
|
+ rc = ISCSI_ERR_SESS_NOT_FOUND;
|
||
|
+ else if (rc < 0)
|
||
|
+ rc = ISCSI_ERR_LOGOUT;
|
||
|
+
|
||
|
+ ipc->ctldev_close();
|
||
|
+
|
||
|
+exit_logout:
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+int iscsi_logout_flashnode_sid(struct iscsi_transport *t, uint32_t host_no,
|
||
|
+ uint32_t sid)
|
||
|
+{
|
||
|
+ int fd, rc = 0;
|
||
|
+
|
||
|
+ fd = ipc->ctldev_open();
|
||
|
+ if (fd < 0) {
|
||
|
+ log_error("Netlink open failed.");
|
||
|
+ rc = ISCSI_ERR_INTERNAL;
|
||
|
+ goto exit_logout_sid;
|
||
|
+ }
|
||
|
+
|
||
|
+ log_info("Logout sid %u.", sid);
|
||
|
+ rc = ipc->logout_flash_node_sid(t->handle, host_no, sid);
|
||
|
+ if (rc < 0) {
|
||
|
+ log_error("Logout of sid %u failed.", sid);
|
||
|
+ rc = ISCSI_ERR_LOGOUT;
|
||
|
+ } else {
|
||
|
+ log_info("Logout of sid %u successful.", sid);
|
||
|
+ }
|
||
|
+
|
||
|
+ ipc->ctldev_close();
|
||
|
+
|
||
|
+exit_logout_sid:
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+static int exec_flashnode_op(int op, int info_level, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx, int type,
|
||
|
+ struct list_head *params)
|
||
|
+{
|
||
|
+ struct iscsi_transport *t = NULL;
|
||
|
+ int rc = ISCSI_SUCCESS;
|
||
|
+ char *portal_type;
|
||
|
+
|
||
|
+ if (op != OP_SHOW && op != OP_NOOP && op != OP_NEW &&
|
||
|
+ flashnode_idx == 0xffffffff) {
|
||
|
+ log_error("Invalid flashnode index");
|
||
|
+ rc = ISCSI_ERR_INVAL;
|
||
|
+ goto exit_flashnode_op;
|
||
|
+ }
|
||
|
+
|
||
|
+ t = iscsi_sysfs_get_transport_by_hba(host_no);
|
||
|
+ if (!t) {
|
||
|
+ log_error("Could not match hostno %u to transport.", host_no);
|
||
|
+ rc = ISCSI_ERR_TRANS_NOT_FOUND;
|
||
|
+ goto exit_flashnode_op;
|
||
|
+ }
|
||
|
+
|
||
|
+ switch (op) {
|
||
|
+ case OP_NOOP:
|
||
|
+ case OP_SHOW:
|
||
|
+ if (flashnode_idx == 0xffffffff)
|
||
|
+ rc = list_flashnodes(info_level, host_no);
|
||
|
+ else
|
||
|
+ rc = get_flashnode_info(host_no, flashnode_idx);
|
||
|
+ break;
|
||
|
+ case OP_NEW:
|
||
|
+ if (type == IPV4) {
|
||
|
+ portal_type = "ipv4";
|
||
|
+ } else if (type == IPV6) {
|
||
|
+ portal_type = "ipv6";
|
||
|
+ } else {
|
||
|
+ log_error("Invalid type mentioned for flashnode");
|
||
|
+ rc = ISCSI_ERR_INVAL;
|
||
|
+ goto exit_flashnode_op;
|
||
|
+ }
|
||
|
+ rc = iscsi_new_flashnode(t, host_no, portal_type,
|
||
|
+ &flashnode_idx);
|
||
|
+ if (!rc)
|
||
|
+ log_info("New flashnode for host %u added at index %u.",
|
||
|
+ host_no, flashnode_idx);
|
||
|
+ else
|
||
|
+ log_error("Creation of flashnode for host %u failed.",
|
||
|
+ host_no);
|
||
|
+ break;
|
||
|
+ case OP_DELETE:
|
||
|
+ rc = iscsi_del_flashnode(t, host_no, flashnode_idx);
|
||
|
+ if (!rc)
|
||
|
+ log_info("Flashnode %u of host %u deleted.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ else
|
||
|
+ log_error("Deletion of flashnode %u of host %u failed.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ break;
|
||
|
+ case OP_UPDATE:
|
||
|
+ rc = iscsi_set_flashnode_params(t, host_no, flashnode_idx,
|
||
|
+ params);
|
||
|
+ if (!rc)
|
||
|
+ log_info("Update for flashnode %u of host %u successful.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ else
|
||
|
+ log_error("Update for flashnode %u of host %u failed.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ break;
|
||
|
+ case OP_LOGIN:
|
||
|
+ rc = iscsi_login_flashnode(t, host_no, flashnode_idx);
|
||
|
+ if (!rc)
|
||
|
+ log_info("Login to flashnode %u of host %u successful.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ else if (rc == ISCSI_ERR_SESS_EXISTS)
|
||
|
+ log_info("Flashnode %u of host %u already logged in.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ else
|
||
|
+ log_error("Login to flashnode %u of host %u failed.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ break;
|
||
|
+ case OP_LOGOUT:
|
||
|
+ rc = iscsi_logout_flashnode(t, host_no, flashnode_idx);
|
||
|
+ if (!rc)
|
||
|
+ log_info("Logout of flashnode %u of host %u successful.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ else if (rc == ISCSI_ERR_SESS_NOT_FOUND)
|
||
|
+ log_info("Flashnode %u of host %u not logged in.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ else
|
||
|
+ log_error("Logout of flashnode %u of host %u failed.",
|
||
|
+ flashnode_idx, host_no);
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ log_error("Invalid operation");
|
||
|
+ rc = ISCSI_ERR_INVAL;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+exit_flashnode_op:
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
static int verify_iface_params(struct list_head *params, struct node_rec *rec)
|
||
|
{
|
||
|
struct user_param *param;
|
||
|
@@ -2403,6 +2798,7 @@ main(int argc, char **argv)
|
||
|
int tpgt = PORTAL_GROUP_TAG_UNKNOWN, killiscsid=-1, do_show=0;
|
||
|
int packet_size=32, ping_count=1, ping_interval=0;
|
||
|
int do_discover = 0, sub_mode = -1;
|
||
|
+ int flashnode_idx = -1, portal_type = -1;
|
||
|
struct sigaction sa_old;
|
||
|
struct sigaction sa_new;
|
||
|
struct list_head ifaces;
|
||
|
@@ -2551,11 +2947,19 @@ main(int argc, char **argv)
|
||
|
printf("%s version %s\n", program_name,
|
||
|
ISCSI_VERSION_STR);
|
||
|
return 0;
|
||
|
+ case 'x':
|
||
|
+ flashnode_idx = atoi(optarg);
|
||
|
+ break;
|
||
|
+ case 'A':
|
||
|
+ portal_type = str_to_portal_type(optarg);
|
||
|
+ break;
|
||
|
case 'h':
|
||
|
usage(0);
|
||
|
}
|
||
|
|
||
|
- if (name && value) {
|
||
|
+ if ((mode == MODE_IFACE ||
|
||
|
+ (mode == MODE_HOST && sub_mode == MODE_FLASHNODE)) &&
|
||
|
+ name && value) {
|
||
|
param = idbm_alloc_user_param(name, value);
|
||
|
if (!param) {
|
||
|
log_error("Cannot allocate memory for params.");
|
||
|
@@ -2603,7 +3007,7 @@ main(int argc, char **argv)
|
||
|
|
||
|
switch (mode) {
|
||
|
case MODE_HOST:
|
||
|
- if ((rc = verify_mode_params(argc, argv, "CHdmPov", 0))) {
|
||
|
+ if ((rc = verify_mode_params(argc, argv, "CHdmPotnvxA", 0))) {
|
||
|
log_error("host mode: option '-%c' is not "
|
||
|
"allowed/supported", rc);
|
||
|
rc = ISCSI_ERR_INVAL;
|
||
|
@@ -2621,6 +3025,17 @@ main(int argc, char **argv)
|
||
|
rc = exec_host_chap_op(op, info_level, host_no,
|
||
|
value);
|
||
|
break;
|
||
|
+ case MODE_FLASHNODE:
|
||
|
+ if (!host_no) {
|
||
|
+ log_error("FLASHNODE mode requires host no");
|
||
|
+ rc = ISCSI_ERR_INVAL;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = exec_flashnode_op(op, info_level, host_no,
|
||
|
+ flashnode_idx,
|
||
|
+ portal_type, ¶ms);
|
||
|
+ break;
|
||
|
default:
|
||
|
log_error("Invalid Sub Mode");
|
||
|
break;
|
||
|
diff --git a/usr/netlink.c b/usr/netlink.c
|
||
|
index c43f686..c07fe3c 100644
|
||
|
--- a/usr/netlink.c
|
||
|
+++ b/usr/netlink.c
|
||
|
@@ -1252,6 +1252,169 @@ static int kdelete_chap(uint64_t transport_handle, uint32_t host_no,
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
+static int
|
||
|
+kset_flashnode_params(uint64_t transport_handle, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx, struct iovec *iovs,
|
||
|
+ uint32_t param_count)
|
||
|
+{
|
||
|
+ struct iscsi_uevent ev;
|
||
|
+ int rc, ev_len;
|
||
|
+ struct iovec *iov = iovs + 1;
|
||
|
+
|
||
|
+ log_debug(8, "in %s", __FUNCTION__);
|
||
|
+
|
||
|
+ ev_len = sizeof(ev);
|
||
|
+ ev.type = ISCSI_UEVENT_SET_FLASHNODE_PARAMS;
|
||
|
+ ev.transport_handle = transport_handle;
|
||
|
+ ev.u.set_flashnode.host_no = host_no;
|
||
|
+ ev.u.set_flashnode.flashnode_idx = flashnode_idx;
|
||
|
+ /* first two iovs for nlmsg hdr and ev */
|
||
|
+ ev.u.set_flashnode.count = param_count - 2;
|
||
|
+
|
||
|
+ iov->iov_base = &ev;
|
||
|
+ iov->iov_len = ev_len;
|
||
|
+ rc = __kipc_call(iovs, param_count);
|
||
|
+ if (rc < 0)
|
||
|
+ return rc;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+knew_flashnode(uint64_t transport_handle, uint32_t host_no, void *value,
|
||
|
+ uint32_t *flashnode_idx)
|
||
|
+{
|
||
|
+ struct iscsi_uevent *ev;
|
||
|
+ char *param_str;
|
||
|
+ int rc, len;
|
||
|
+ struct iovec iov[2];
|
||
|
+
|
||
|
+ log_debug(7, "in %s", __FUNCTION__);
|
||
|
+
|
||
|
+ memset(setparam_buf, 0, NLM_SETPARAM_DEFAULT_MAX);
|
||
|
+ ev = (struct iscsi_uevent *)setparam_buf;
|
||
|
+ ev->type = ISCSI_UEVENT_NEW_FLASHNODE;
|
||
|
+ ev->transport_handle = transport_handle;
|
||
|
+ ev->u.new_flashnode.host_no = host_no;
|
||
|
+
|
||
|
+ param_str = setparam_buf + sizeof(*ev);
|
||
|
+ if (!strlen(value))
|
||
|
+ return 0;
|
||
|
+ sprintf(param_str, "%s", (char *)value);
|
||
|
+ len = strlen(param_str) + 1;
|
||
|
+ ev->u.new_flashnode.len = len;
|
||
|
+
|
||
|
+
|
||
|
+ iov[1].iov_base = ev;
|
||
|
+ iov[1].iov_len = sizeof(*ev) + len;
|
||
|
+ rc = __kipc_call(iov, 2);
|
||
|
+ if (rc < 0)
|
||
|
+ return rc;
|
||
|
+
|
||
|
+ *flashnode_idx = ev->r.new_flashnode_ret.flashnode_idx;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+kdel_flashnode(uint64_t transport_handle, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx)
|
||
|
+{
|
||
|
+ struct iscsi_uevent ev;
|
||
|
+ int rc;
|
||
|
+ struct iovec iov[2];
|
||
|
+
|
||
|
+ log_debug(7, "in %s", __FUNCTION__);
|
||
|
+
|
||
|
+ memset(&ev, 0, sizeof(struct iscsi_uevent));
|
||
|
+ ev.type = ISCSI_UEVENT_DEL_FLASHNODE;
|
||
|
+ ev.transport_handle = transport_handle;
|
||
|
+ ev.u.del_flashnode.host_no = host_no;
|
||
|
+ ev.u.del_flashnode.flashnode_idx = flashnode_idx;
|
||
|
+
|
||
|
+ iov[1].iov_base = &ev;
|
||
|
+ iov[1].iov_len = sizeof(ev);
|
||
|
+ rc = __kipc_call(iov, 2);
|
||
|
+ if (rc < 0)
|
||
|
+ return rc;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+klogin_flashnode(uint64_t transport_handle, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx)
|
||
|
+{
|
||
|
+ struct iscsi_uevent ev;
|
||
|
+ int rc;
|
||
|
+ struct iovec iov[2];
|
||
|
+
|
||
|
+ log_debug(7, "in %s", __FUNCTION__);
|
||
|
+
|
||
|
+ memset(&ev, 0, sizeof(struct iscsi_uevent));
|
||
|
+ ev.type = ISCSI_UEVENT_LOGIN_FLASHNODE;
|
||
|
+ ev.transport_handle = transport_handle;
|
||
|
+ ev.u.login_flashnode.host_no = host_no;
|
||
|
+ ev.u.login_flashnode.flashnode_idx = flashnode_idx;
|
||
|
+
|
||
|
+ iov[1].iov_base = &ev;
|
||
|
+ iov[1].iov_len = sizeof(ev);
|
||
|
+ rc = __kipc_call(iov, 2);
|
||
|
+ if (rc < 0)
|
||
|
+ return rc;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+klogout_flashnode(uint64_t transport_handle, uint32_t host_no,
|
||
|
+ uint32_t flashnode_idx)
|
||
|
+{
|
||
|
+ struct iscsi_uevent ev;
|
||
|
+ int rc;
|
||
|
+ struct iovec iov[2];
|
||
|
+
|
||
|
+ log_debug(7, "in %s", __FUNCTION__);
|
||
|
+
|
||
|
+ memset(&ev, 0, sizeof(struct iscsi_uevent));
|
||
|
+ ev.type = ISCSI_UEVENT_LOGOUT_FLASHNODE;
|
||
|
+ ev.transport_handle = transport_handle;
|
||
|
+ ev.u.logout_flashnode.host_no = host_no;
|
||
|
+ ev.u.logout_flashnode.flashnode_idx = flashnode_idx;
|
||
|
+
|
||
|
+ iov[1].iov_base = &ev;
|
||
|
+ iov[1].iov_len = sizeof(ev);
|
||
|
+ rc = __kipc_call(iov, 2);
|
||
|
+ if (rc < 0)
|
||
|
+ return rc;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+klogout_flashnode_sid(uint64_t transport_handle, uint32_t host_no,
|
||
|
+ uint32_t sid)
|
||
|
+{
|
||
|
+ struct iscsi_uevent ev;
|
||
|
+ int rc;
|
||
|
+ struct iovec iov[2];
|
||
|
+
|
||
|
+ log_debug(7, "in %s", __FUNCTION__);
|
||
|
+
|
||
|
+ memset(&ev, 0, sizeof(struct iscsi_uevent));
|
||
|
+ ev.type = ISCSI_UEVENT_LOGOUT_FLASHNODE_SID;
|
||
|
+ ev.transport_handle = transport_handle;
|
||
|
+ ev.u.logout_flashnode_sid.host_no = host_no;
|
||
|
+ ev.u.logout_flashnode_sid.sid = sid;
|
||
|
+
|
||
|
+ iov[1].iov_base = &ev;
|
||
|
+ iov[1].iov_len = sizeof(ev);
|
||
|
+ rc = __kipc_call(iov, 2);
|
||
|
+ if (rc < 0)
|
||
|
+ return rc;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static void drop_data(struct nlmsghdr *nlh)
|
||
|
{
|
||
|
int ev_size;
|
||
|
@@ -1296,10 +1459,10 @@ static int ctldev_handle(void)
|
||
|
ev->r.c_session_ret.sid);
|
||
|
return 0;
|
||
|
case ISCSI_KEVENT_DESTROY_SESSION:
|
||
|
+ drop_data(nlh);
|
||
|
if (!ipc_ev_clbk)
|
||
|
return 0;
|
||
|
|
||
|
- drop_data(nlh);
|
||
|
if (ipc_ev_clbk->destroy_session)
|
||
|
ipc_ev_clbk->destroy_session(ev->r.d_session.host_no,
|
||
|
ev->r.d_session.sid);
|
||
|
@@ -1543,6 +1706,12 @@ struct iscsi_ipc nl_ipc = {
|
||
|
.exec_ping = kexec_ping,
|
||
|
.get_chap = kget_chap,
|
||
|
.delete_chap = kdelete_chap,
|
||
|
+ .set_flash_node_params = kset_flashnode_params,
|
||
|
+ .new_flash_node = knew_flashnode,
|
||
|
+ .del_flash_node = kdel_flashnode,
|
||
|
+ .login_flash_node = klogin_flashnode,
|
||
|
+ .logout_flash_node = klogout_flashnode,
|
||
|
+ .logout_flash_node_sid = klogout_flashnode_sid,
|
||
|
};
|
||
|
struct iscsi_ipc *ipc = &nl_ipc;
|
||
|
|
||
|
--
|
||
|
1.8.1.4
|
||
|
|