[PATCH RESEND 2/3] Show new statistics in various modes; integrate scsi and iscsi stats where relevant

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Alexander Nezhinsky <alexandern@xxxxxxxxxxxx>

Implemented statistics presentation using --op stat instead of --mode stat,
as --op may be applied to various modes.

Added --op stat to --mode session and --mode conn.

When presenting iscsi connestions/sessions, show integrated scsi and iscsi statistics.
Session stats show the counters for all luns accessible through the session,
along with iscsi counters for all the connections comprising the session
(practically just one). Connection stats only show the iscsi counters.

Signed-off-by: Alexander Nezhinsky <alexandern@xxxxxxxxxxxx>
---
 usr/driver.h       |    1 +
 usr/iscsi/iscsid.c |    1 +
 usr/iscsi/iscsid.h |    2 +
 usr/iscsi/iser.c   |    1 +
 usr/iscsi/target.c |  165 ++++++++++++++++++++++++++++++++++++++++++----------
 usr/mgmt.c         |   64 ++++++++++++++++++++
 usr/target.c       |   97 ++++++++++++++++++++++++++++++
 usr/target.h       |    2 +-
 usr/tgtadm.c       |    7 ++-
 usr/tgtadm.h       |    2 +-
 usr/tgtd.h         |    9 +++
 11 files changed, 317 insertions(+), 34 deletions(-)

diff --git a/usr/driver.h b/usr/driver.h
index 53c19b6..d643fac 100644
--- a/usr/driver.h
+++ b/usr/driver.h
@@ -27,6 +27,7 @@ struct tgt_driver {
 
 	tgtadm_err (*update)(int, int, int ,uint64_t, uint64_t, uint32_t, char *);
 	tgtadm_err (*show)(int, int, uint64_t, uint32_t, uint64_t, struct concat_buf *);
+	tgtadm_err (*stat)(int, int, uint64_t, uint32_t, uint64_t, struct concat_buf *);
 
 	uint64_t (*scsi_get_lun)(uint8_t *);
 
diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
index ae249cd..4545018 100644
--- a/usr/iscsi/iscsid.c
+++ b/usr/iscsi/iscsid.c
@@ -2467,6 +2467,7 @@ static struct tgt_driver iscsi = {
 
 	.update			= iscsi_target_update,
 	.show			= iscsi_target_show,
+	.stat			= iscsi_stat,
 	.cmd_end_notify		= iscsi_scsi_cmd_done,
 	.mgmt_end_notify	= iscsi_tm_done,
 	.transportid		= iscsi_transportid,
diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
index 897ff63..f274857 100644
--- a/usr/iscsi/iscsid.h
+++ b/usr/iscsi/iscsid.h
@@ -339,6 +339,8 @@ extern int iscsi_target_create(struct target *);
 extern void iscsi_target_destroy(int tid, int force);
 extern tgtadm_err iscsi_target_show(int mode, int tid, uint64_t sid, uint32_t cid,
 				    uint64_t lun, struct concat_buf *b);
+extern tgtadm_err iscsi_stat(int mode, int tid, uint64_t sid, uint32_t cid,
+			     uint64_t lun, struct concat_buf *b);
 extern tgtadm_err iscsi_target_update(int mode, int op, int tid, uint64_t sid, uint64_t lun,
 				      uint32_t cid, char *name);
 extern int target_redirected(struct iscsi_target *target,
diff --git a/usr/iscsi/iser.c b/usr/iscsi/iser.c
index 656a8e0..f864ff9 100644
--- a/usr/iscsi/iser.c
+++ b/usr/iscsi/iser.c
@@ -3514,6 +3514,7 @@ static struct tgt_driver iser = {
 
 	.update 		= iscsi_target_update,
 	.show 			= iscsi_target_show,
+	.stat                   = iscsi_stat,
 	.cmd_end_notify 	= iser_scsi_cmd_done,
 	.mgmt_end_notify	= iser_tm_done,
 	.transportid    	= iscsi_transportid,
diff --git a/usr/iscsi/target.c b/usr/iscsi/target.c
index f3df61e..3a91404 100644
--- a/usr/iscsi/target.c
+++ b/usr/iscsi/target.c
@@ -605,34 +605,6 @@ static tgtadm_err iscsi_target_show_session(struct iscsi_target *target, uint64_
 	return adm_err;
 }
 
-static tgtadm_err iscsi_target_show_stats(struct iscsi_target *target, uint64_t sid,
-					  struct concat_buf *b)
-{
-	tgtadm_err adm_err = TGTADM_SUCCESS;
-	struct iscsi_session *session;
-	struct iscsi_connection *conn;
-
-	session = iscsi_target_find_session(target, sid);
-
-	if (session) {
-		list_for_each_entry(conn, &session->conn_list, clist) {
-			concat_printf(b, "rxdata_octets: %" PRIu64 "\n"
-				       "txdata_octets: %" PRIu64 "\n"
-				       "dataout_pdus:  %d\n"
-				       "datain_pdus:   %d\n"
-				       "scsicmd_pdus:  %d\n"
-				       "scsirsp_pdus:  %d\n",
-				       conn->stats.rxdata_octets,
-				       conn->stats.txdata_octets,
-				       conn->stats.dataout_pdus,
-				       conn->stats.datain_pdus,
-				       conn->stats.scsicmd_pdus,
-				       conn->stats.scsirsp_pdus);
-		}
-	}
-	return adm_err;
-}
-
 static tgtadm_err iscsi_target_show_connections(struct iscsi_target *target,
 						uint64_t sid,
 						struct concat_buf *b)
@@ -738,8 +710,140 @@ tgtadm_err iscsi_target_show(int mode, int tid, uint64_t sid, uint32_t cid, uint
 	case MODE_CONNECTION:
 		adm_err = iscsi_target_show_connections(target, sid, b);
 		break;
-	case MODE_STATS:
-		adm_err = iscsi_target_show_stats(target, sid, b);
+	default:
+		break;
+	}
+
+	return adm_err;
+}
+
+static void _stat_iscsi_conn_hdr(struct concat_buf *b)
+{
+	concat_printf(b,
+		"sid cid rxdata_octets txdata_octets dataout_pdus datain_pdus cmd_pdus rsp_pdus\n");
+}
+
+static void _stat_iscsi_conn(struct iscsi_connection *conn, struct concat_buf *b)
+{
+	concat_printf(b, "%3d %3d"
+		      " %13" PRIu64
+		      " %13" PRIu64
+		      " %12" PRIu32
+		      " %11" PRIu32
+		      " %8" PRIu32
+		      " %8" PRIu32 "\n",
+		      (unsigned int)conn->session->tsih,
+		      (unsigned int)conn->cid,
+		      conn->stats.rxdata_octets,
+		      conn->stats.txdata_octets,
+		      conn->stats.dataout_pdus,
+		      conn->stats.datain_pdus,
+		      conn->stats.scsicmd_pdus,
+		      conn->stats.scsirsp_pdus);
+}
+
+static tgtadm_err _stat_iscsi_session(struct iscsi_session *session,
+				      uint64_t lun, int filter_lun,
+				      struct concat_buf *b)
+{
+	struct iscsi_target *target = session->target;
+	uint64_t itn_id = session->tsih;
+	int tid = target->tid;	/* global target id */
+	struct it_nexus *itn;
+	struct it_nexus_lu_info *itn_lu;
+	struct scsi_lu *lu;
+	struct iscsi_connection *conn;
+
+	dprintf("tsih:%d lun:%" PRIu64 " filter_lun:%d\n",
+		(unsigned int)session->tsih, lun, filter_lun);
+
+	itn = it_nexus_lookup(tid, itn_id);
+	if (!itn) {
+		eprintf("invalid nexus %d %" PRIx64 "\n", tid, itn_id);
+		return TGTADM_NO_SESSION;
+	}
+
+	tgt_stat_header(b);
+	list_for_each_entry(itn_lu, &itn->itn_itl_info_list, itn_itl_info_siblings) {
+		lu = itn_lu->lu;
+		tgt_stat_line(tid, lu->lun, session->tsih, &itn_lu->stat, b);
+	}
+
+	if (!list_empty(&session->conn_list)) {
+		concat_printf(b, "\n");
+		_stat_iscsi_conn_hdr(b);
+	}
+	list_for_each_entry(conn, &session->conn_list, clist) {
+		_stat_iscsi_conn(conn, b);
+	}
+
+	return TGTADM_SUCCESS;
+}
+
+static tgtadm_err iscsi_stat_connection(uint64_t sid, uint32_t cid, struct concat_buf *b)
+{
+	struct iscsi_session *session;
+	struct iscsi_connection *conn;
+
+	dprintf("sid:%" PRIu64 "cid:%" PRIu32 "\n", sid, cid);
+
+	session = session_lookup_by_tsih((uint16_t)sid);
+	if (!session)
+		return TGTADM_NO_SESSION;
+
+	conn = conn_find(session, cid);
+	if (!conn)
+		return TGTADM_NO_CONNECTION;
+
+	_stat_iscsi_conn_hdr(b);
+	_stat_iscsi_conn(conn, b);
+
+	return TGTADM_SUCCESS;
+}
+
+static tgtadm_err iscsi_stat_session_by_sid(uint64_t sid, struct concat_buf *b)
+{
+	struct iscsi_session *session;
+
+	dprintf("sid:%" PRIu64 "\n", sid);
+
+	session = session_lookup_by_tsih((uint16_t)sid);
+	if (session)
+		return _stat_iscsi_session(session, 0, 0, b);
+	else
+		return TGTADM_NO_SESSION;
+}
+
+static tgtadm_err iscsi_stat_device_by_id(uint64_t lun, uint64_t sid, struct concat_buf *b)
+{
+	struct iscsi_session *session;
+
+	dprintf("lun:%" PRIu64 " sid:%" PRIu64 "\n", lun, sid);
+
+	session = session_lookup_by_tsih((uint16_t)sid);
+	if (session)
+		return _stat_iscsi_session(session, lun, 1, b);
+	else
+		return TGTADM_NO_SESSION;
+}
+
+tgtadm_err iscsi_stat(int mode, int tid, uint64_t sid, uint32_t cid, uint64_t lun,
+		      struct concat_buf *b)
+{
+	tgtadm_err adm_err = TGTADM_INVALID_REQUEST;
+
+	dprintf("mode:%d tid:%d sid:%" PRIu64 " cid:%" PRIu32 " lun:%" PRIx64 "\n",
+		mode, tid, sid, cid, lun);
+
+	switch (mode) {
+	case MODE_DEVICE:
+		adm_err = iscsi_stat_device_by_id(lun, sid, b);
+		break;
+	case MODE_SESSION:
+		adm_err = iscsi_stat_session_by_sid(sid, b);
+		break;
+	case MODE_CONNECTION:
+		adm_err = iscsi_stat_connection(sid, cid, b);
 		break;
 	default:
 		break;
@@ -747,3 +851,4 @@ tgtadm_err iscsi_target_show(int mode, int tid, uint64_t sid, uint32_t cid, uint
 
 	return adm_err;
 }
+
diff --git a/usr/mgmt.c b/usr/mgmt.c
index 56f89bb..1c8cc92 100644
--- a/usr/mgmt.c
+++ b/usr/mgmt.c
@@ -191,6 +191,13 @@ static tgtadm_err target_mgmt(int lld_no, struct mgmt_task *mtask)
 		concat_buf_finish(&mtask->rsp_concat);
 		break;
 	}
+	case OP_STATS:
+	{
+		concat_buf_init(&mtask->rsp_concat);
+		adm_err = tgt_stat_target_by_id(req->tid, &mtask->rsp_concat);
+		concat_buf_finish(&mtask->rsp_concat);
+		break;
+	}
 	default:
 		break;
 	}
@@ -245,6 +252,17 @@ static tgtadm_err device_mgmt(int lld_no, struct mgmt_task *mtask)
 	case OP_UPDATE:
 		adm_err = tgt_device_update(req->tid, req->lun, params);
 		break;
+	case OP_STATS:
+		concat_buf_init(&mtask->rsp_concat);
+		if (!req->sid)
+			adm_err = tgt_stat_device_by_id(req->tid, req->lun,
+							&mtask->rsp_concat);
+		else if (tgt_drivers[lld_no]->stat)
+			adm_err = tgt_drivers[lld_no]->stat(req->mode, req->tid,
+							    req->sid, req->cid, req->lun,
+							    &mtask->rsp_concat);
+		concat_buf_finish(&mtask->rsp_concat);
+		break;
 	default:
 		break;
 	}
@@ -331,6 +349,11 @@ static tgtadm_err sys_mgmt(int lld_no, struct mgmt_task *mtask)
 							&mtask->rsp_concat);
 		concat_buf_finish(&mtask->rsp_concat);
 		break;
+	case OP_STATS:
+		concat_buf_init(&mtask->rsp_concat);
+		adm_err = tgt_stat_system(&mtask->rsp_concat);
+		concat_buf_finish(&mtask->rsp_concat);
+		break;
 	case OP_DELETE:
 		if (is_system_inactive())
 			adm_err = TGTADM_SUCCESS;
@@ -342,6 +365,34 @@ static tgtadm_err sys_mgmt(int lld_no, struct mgmt_task *mtask)
 	return adm_err;
 }
 
+static tgtadm_err session_mgmt(int lld_no, struct mgmt_task *mtask)
+{
+	struct tgtadm_req *req = &mtask->req;
+	int adm_err = TGTADM_INVALID_REQUEST;
+
+	switch (req->op) {
+	case OP_STATS:
+		if (tgt_drivers[lld_no]->stat) {
+			concat_buf_init(&mtask->rsp_concat);
+			adm_err = tgt_drivers[lld_no]->stat(req->mode,
+							    req->tid, req->sid,
+							    req->cid, req->lun,
+							    &mtask->rsp_concat);
+			concat_buf_finish(&mtask->rsp_concat);
+		}
+		break;
+	default:
+		if (tgt_drivers[lld_no]->update)
+			adm_err = tgt_drivers[lld_no]->update(req->mode, req->op,
+							      req->tid,
+							      req->sid, req->lun,
+							      req->cid, mtask->req_buf);
+		break;
+	}
+
+	return adm_err;
+}
+
 static tgtadm_err connection_mgmt(int lld_no, struct mgmt_task *mtask)
 {
 	struct tgtadm_req *req = &mtask->req;
@@ -359,6 +410,16 @@ static tgtadm_err connection_mgmt(int lld_no, struct mgmt_task *mtask)
 			break;
 		}
 		break;
+	case OP_STATS:
+		if (tgt_drivers[lld_no]->stat) {
+			concat_buf_init(&mtask->rsp_concat);
+			adm_err = tgt_drivers[lld_no]->stat(req->mode,
+							    req->tid, req->sid,
+							    req->cid, req->lun,
+							    &mtask->rsp_concat);
+			concat_buf_finish(&mtask->rsp_concat);
+		}
+		break;
 	default:
 		if (tgt_drivers[lld_no]->update)
 			adm_err = tgt_drivers[lld_no]->update(req->mode, req->op,
@@ -411,6 +472,9 @@ static tgtadm_err mtask_execute(struct mgmt_task *mtask)
 	case MODE_ACCOUNT:
 		adm_err = account_mgmt(lld_no, mtask);
 		break;
+	case MODE_SESSION:
+		adm_err = session_mgmt(lld_no, mtask);
+		break;
 	case MODE_CONNECTION:
 		adm_err = connection_mgmt(lld_no, mtask);
 		break;
diff --git a/usr/target.c b/usr/target.c
index ad951f9..a801e5b 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -913,6 +913,103 @@ tgtadm_err tgt_device_update(int tid, uint64_t dev_id, char *params)
 	return adm_err;
 }
 
+void tgt_stat_header(struct concat_buf *b)
+{
+	concat_printf(b,
+		"tgt lun sid "
+		"rd_subm(bytes,cmds) rd_done(bytes,cmds) "
+		"wr_subm(bytes,cmds) wr_done(bytes,cmds) "
+		"errs\n");
+}
+
+void tgt_stat_line(int tid, uint64_t lun, uint64_t sid, struct lu_stat *stat,
+		   struct concat_buf *b)
+{
+	concat_printf(b,
+		"%3d %3" PRIu64 " %3" PRIu64 " "
+		"%12" PRIu64 " %6" PRIu32 " "
+		"%12" PRIu64 " %6" PRIu32 " "
+		"%12" PRIu64 " %6" PRIu32 " "
+		"%12" PRIu64 " %6" PRIu32 " "
+		"%4" PRIu32 "\n",
+		tid, lun, sid,
+		stat->rd_subm_bytes, stat->rd_subm_cmds,
+		stat->rd_done_bytes, stat->rd_done_cmds,
+		stat->wr_subm_bytes, stat->wr_subm_cmds,
+		stat->wr_done_bytes, stat->wr_done_cmds,
+		stat->err_num);
+}
+
+void tgt_stat_device(struct target *target, struct scsi_lu *lu, struct concat_buf *b)
+{
+	struct it_nexus_lu_info *itn_lu;
+
+	list_for_each_entry(itn_lu, &lu->lu_itl_info_list, lu_itl_info_siblings) {
+		tgt_stat_line(target->tid, lu->lun, itn_lu->itn_id, &itn_lu->stat, b);
+	}
+}
+
+tgtadm_err tgt_stat_device_by_id(int tid, uint64_t dev_id, struct concat_buf *b)
+{
+	struct target *target;
+	struct scsi_lu *lu;
+	tgtadm_err adm_err = TGTADM_SUCCESS;
+
+	target = target_lookup(tid);
+	if (!target)
+		return TGTADM_NO_TARGET;
+
+	lu = device_lookup(target, dev_id);
+	if (!lu) {
+		eprintf("device %" PRIu64 " not found\n", dev_id);
+		return TGTADM_NO_LUN;
+	}
+
+	tgt_stat_header(b);
+	tgt_stat_device(target, lu, b);
+
+	return adm_err;
+}
+
+tgtadm_err tgt_stat_target(struct target *target, struct concat_buf *b)
+{
+	struct scsi_lu *lu;
+	tgtadm_err adm_err = TGTADM_SUCCESS;
+
+	list_for_each_entry(lu, &target->device_list, device_siblings)
+		tgt_stat_device(target, lu, b);
+
+	return adm_err;
+}
+
+tgtadm_err tgt_stat_target_by_id(int tid, struct concat_buf *b)
+{
+	struct target *target;
+	tgtadm_err adm_err = TGTADM_SUCCESS;
+
+	target = target_lookup(tid);
+	if (!target)
+		return TGTADM_NO_TARGET;
+
+	tgt_stat_header(b);
+	adm_err = tgt_stat_target(target, b);
+
+	return adm_err;
+}
+
+tgtadm_err tgt_stat_system(struct concat_buf *b)
+{
+	struct target *target;
+	tgtadm_err adm_err = TGTADM_SUCCESS;
+
+	tgt_stat_header(b);
+
+	list_for_each_entry(target, &target_list, target_siblings)
+		adm_err = tgt_stat_target(target, b);
+
+	return adm_err;
+}
+
 static int cmd_enabled(struct tgt_cmd_queue *q, struct scsi_cmd *cmd)
 {
 	int enabled = 0;
diff --git a/usr/target.h b/usr/target.h
index ba03f3c..da4f675 100644
--- a/usr/target.h
+++ b/usr/target.h
@@ -57,7 +57,7 @@ struct it_nexus {
 	/* dirty hack for IBMVIO */
 	int host_no;
 
-	struct list_head it_nexus_lu_info_list;
+	struct list_head itn_itl_info_list;
 
 	/* only used for show operation */
 	char *info;
diff --git a/usr/tgtadm.c b/usr/tgtadm.c
index 92f2dc7..55e539b 100644
--- a/usr/tgtadm.c
+++ b/usr/tgtadm.c
@@ -405,8 +405,6 @@ static int str_to_mode(char *str)
 		return MODE_CONNECTION;
 	else if (!strcmp("account", str))
 		return MODE_ACCOUNT;
-	else if (!strcmp("stats", str))
-		return MODE_STATS;
 	else {
 		eprintf("unknown mode: %s\n", str);
 		exit(1);
@@ -427,6 +425,8 @@ static int str_to_op(char *str)
 		return OP_SHOW;
 	else if (!strcmp("update", str))
 		return OP_UPDATE;
+	else if (!strcmp("stat", str))
+		return OP_STATS;
 	else {
 		eprintf("unknown operation: %s\n", str);
 		exit(1);
@@ -627,6 +627,7 @@ int main(int argc, char **argv)
 			break;
 		case OP_SHOW:
 		case OP_DELETE:
+		case OP_STATS:
 			break;
 		default:
 			eprintf("option %d not supported in system mode\n", op);
@@ -662,6 +663,7 @@ int main(int argc, char **argv)
 			}
 			break;
 		case OP_SHOW:
+		case OP_STATS:
 			rc = verify_mode_params(argc, argv, "LmotC");
 			if (rc) {
 				eprintf("target mode: option '-%c' is not "
@@ -794,6 +796,7 @@ int main(int argc, char **argv)
 			}
 			break;
 		case OP_DELETE:
+		case OP_STATS:
 			rc = verify_mode_params(argc, argv, "LmotlC");
 			if (rc) {
 				eprintf("target mode: option '-%c' is not "
diff --git a/usr/tgtadm.h b/usr/tgtadm.h
index eedcf60..18e7d58 100644
--- a/usr/tgtadm.h
+++ b/usr/tgtadm.h
@@ -15,6 +15,7 @@ enum tgtadm_op {
 	OP_BIND,
 	OP_UNBIND,
 	OP_UPDATE,
+	OP_STATS,
 };
 
 enum tgtadm_mode {
@@ -26,7 +27,6 @@ enum tgtadm_mode {
 	MODE_SESSION,
 	MODE_CONNECTION,
 	MODE_ACCOUNT,
-	MODE_STATS,
 };
 
 enum tgtadm_account_dir {
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 9fac774..8bee2e3 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -336,6 +336,15 @@ extern tgtadm_err iqn_acl_add(int tid, char *name);
 extern tgtadm_err iqn_acl_del(int tid, char *name);
 extern char *iqn_acl_get(int tid, int idx);
 
+extern void tgt_stat_header(struct concat_buf *b);
+extern void tgt_stat_line(int tid, uint64_t lun, uint64_t sid, struct lu_stat *stat, struct concat_buf *b);
+extern void tgt_stat_device(struct target *target, struct scsi_lu *lu, struct concat_buf *b);
+
+extern tgtadm_err tgt_stat_device_by_id(int tid, uint64_t dev_id, struct concat_buf *b);
+extern tgtadm_err tgt_stat_target(struct target *target, struct concat_buf *b);
+extern tgtadm_err tgt_stat_target_by_id(int tid, struct concat_buf *b);
+extern tgtadm_err tgt_stat_system(struct concat_buf *b);
+
 extern int account_lookup(int tid, int type, char *user, int ulen, char *password, int plen);
 extern tgtadm_err account_add(char *user, char *password);
 extern tgtadm_err account_del(char *user);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux