summaryrefslogtreecommitdiff
path: root/usr/iscsi_sysfs.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2013-05-13 03:15:34 -0500
committerMike Christie <michaelc@cs.wisc.edu>2013-05-28 02:58:28 -0500
commit42fa2585ff7a922ddea83d55aa7751a319cf29bf (patch)
tree636bde79ef22cd9245e472a7cc658cd4c1981bc8 /usr/iscsi_sysfs.c
parentfcab9b7b116ea861a5ed58b36ae88a3154b779d4 (diff)
downloadopen-iscsi-42fa2585ff7a922ddea83d55aa7751a319cf29bf.tar.gz
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>
Diffstat (limited to 'usr/iscsi_sysfs.c')
-rw-r--r--usr/iscsi_sysfs.c234
1 files changed, 234 insertions, 0 deletions
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