From: Adheer Chandravanshi <adheer.chandravan...@qlogic.com>

This fetches and shows the host stats that are exported by kernel
iscsi modules through iscsi host sysfs attrs.

Signed-off-by: Adheer Chandravanshi <adheer.chandravan...@qlogic.com>
---
 include/iscsi_if.h |   24 ++++++++++++++
 usr/idbm.c         |   39 +++++++++++++++++++++++
 usr/idbm.h         |    4 ++-
 usr/idbm_fields.h  |   13 ++++++++
 usr/iscsi_sysfs.c  |   86 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 usr/iscsi_sysfs.h  |    3 ++
 usr/iscsiadm.c     |   41 ++++++++++++++++++++-----
 usr/transport.c    |    1 +
 usr/transport.h    |    1 +
 9 files changed, 203 insertions(+), 9 deletions(-)

diff --git a/include/iscsi_if.h b/include/iscsi_if.h
index 9d15811..7380541 100644
--- a/include/iscsi_if.h
+++ b/include/iscsi_if.h
@@ -639,6 +639,18 @@ enum iscsi_host_param {
        ISCSI_HOST_PARAM_IPADDRESS,
        ISCSI_HOST_PARAM_PORT_STATE,
        ISCSI_HOST_PARAM_PORT_SPEED,
+       ISCSI_HOST_PARAM_LOGIN_ACCEPT_RSPS,
+       ISCSI_HOST_PARAM_LOGIN_OTHER_FAILS,
+       ISCSI_HOST_PARAM_LOGIN_AUTHENTICATION_FAILS,
+       ISCSI_HOST_PARAM_LOGIN_AUTHORIZATION_FAILS,
+       ISCSI_HOST_PARAM_LOGIN_NEGOTIATION_FAILS,
+       ISCSI_HOST_PARAM_LOGIN_REDIRECT_RSPS,
+       ISCSI_HOST_PARAM_LOGOUT_NORMAL_RSPS,
+       ISCSI_HOST_PARAM_LOGOUT_OTHER_RSPS,
+       ISCSI_HOST_PARAM_DIGEST_ERR,
+       ISCSI_HOST_PARAM_TIMEOUT_ERR,
+       ISCSI_HOST_PARAM_FORMAT_ERR,
+       ISCSI_HOST_PARAM_SESSION_FAILS,
        ISCSI_HOST_PARAM_MAX,
 };
 
@@ -824,6 +836,18 @@ struct iscsi_stats {
        /* errors */
        uint32_t digest_err;
        uint32_t timeout_err;
+       uint32_t format_err;
+       uint32_t session_fails;
+
+       /* login/logout stats */
+       uint32_t login_accept_rsps;
+       uint32_t login_other_fails;
+       uint32_t login_authentication_fails;
+       uint32_t login_authorization_fails;
+       uint32_t login_negotiation_fails;
+       uint32_t login_redirect_rsps;
+       uint32_t logout_normal_rsps;
+       uint32_t logout_other_rsps;
 
        /*
         * iSCSI Custom Statistics support, i.e. Transport could
diff --git a/usr/idbm.c b/usr/idbm.c
index 198a5ef..854b624 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -822,6 +822,36 @@ void idbm_recinfo_flashnode(struct flashnode_rec *r, 
recinfo_t *ri)
        }
 }
 
+void idbm_recinfo_host_stats(struct iscsi_stats *r, recinfo_t *ri)
+{
+       int num = 0;
+
+       __recinfo_uint32(ISCSI_HOST_STATS_LOGIN_ACCEPT_RSPS, ri, r,
+                        login_accept_rsps, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_LOGIN_OTHER_FAILS, ri, r,
+                        login_other_fails, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_LOGIN_AUTHENTICATION_FAILS, ri, r,
+                        login_authentication_fails, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_LOGIN_AUTHORIZATION_FAILS, ri, r,
+                        login_authorization_fails, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_LOGIN_NEGOTIATION_FAILS, ri, r,
+                        login_negotiation_fails, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_LOGIN_REDIRECT_RSPS, ri, r,
+                        login_redirect_rsps, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_LOGOUT_NORMAL_RSPS, ri, r,
+                       logout_normal_rsps, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_LOGOUT_OTHER_RSPS, ri, r,
+                        logout_other_rsps, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_DIGEST_ERR, ri, r,
+                        digest_err, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_TIMEOUT_ERR, ri, r,
+                        timeout_err, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_FORMAT_ERR, ri, r,
+                        format_err, IDBM_SHOW, num, 1);
+       __recinfo_uint32(ISCSI_HOST_STATS_SESSION_FAILS, ri, r,
+                        session_fails, IDBM_SHOW, num, 1);
+}
+
 recinfo_t *idbm_recinfo_alloc(int max_keys)
 {
        recinfo_t *info;
@@ -858,6 +888,9 @@ void idbm_print(int type, void *rec, int show, FILE *f)
        case IDBM_PRINT_TYPE_FLASHNODE:
                idbm_recinfo_flashnode((struct flashnode_rec *)rec, info);
                break;
+       case IDBM_PRINT_TYPE_HOST_STATS:
+               idbm_recinfo_host_stats((struct iscsi_stats *)rec, info);
+               break;
        }
 
        fprintf(f, "%s\n", ISCSI_BEGIN_REC);
@@ -1296,6 +1329,12 @@ int idbm_print_node_and_iface_tree(void *data, 
node_rec_t *rec)
        return 0;
 }
 
+int idbm_print_host_stats(struct iscsi_stats *stats)
+{
+       idbm_print(IDBM_PRINT_TYPE_HOST_STATS, stats, 1, stdout);
+       return 0;
+}
+
 static int
 get_params_from_disc_link(char *link, char **target, char **tpgt,
                          char **address, char **port, char **ifaceid)
diff --git a/usr/idbm.h b/usr/idbm.h
index b9020fe..0f6fc6f 100644
--- a/usr/idbm.h
+++ b/usr/idbm.h
@@ -171,7 +171,8 @@ enum {
        IDBM_PRINT_TYPE_NODE,
        IDBM_PRINT_TYPE_IFACE,
        IDBM_PRINT_TYPE_HOST_CHAP,
-       IDBM_PRINT_TYPE_FLASHNODE
+       IDBM_PRINT_TYPE_FLASHNODE,
+       IDBM_PRINT_TYPE_HOST_STATS,
 };
 
 extern void idbm_print(int type, void *rec, int show, FILE *f);
@@ -189,5 +190,6 @@ extern void idbm_recinfo_host_chap(struct iscsi_chap_rec 
*r, recinfo_t *ri);
 
 extern int idbm_print_flashnode_info(struct flashnode_rec *target);
 extern void idbm_recinfo_flashnode(struct flashnode_rec *r, recinfo_t *ri);
+extern int idbm_print_host_stats(struct iscsi_stats *stats);
 
 #endif /* IDBM_H */
diff --git a/usr/idbm_fields.h b/usr/idbm_fields.h
index 5790a03..ec661e6 100644
--- a/usr/idbm_fields.h
+++ b/usr/idbm_fields.h
@@ -238,4 +238,17 @@
 #define FLASHNODE_CONN_STATSN          "flashnode.conn[%d].statsn"
 #define FLASHNODE_CONN_EXP_STATSN      "flashnode.conn[%d].exp_statsn"
 
+#define ISCSI_HOST_STATS_LOGIN_ACCEPT_RSPS             
"iscsi_stats.login_accept_rsps"
+#define ISCSI_HOST_STATS_LOGIN_OTHER_FAILS             
"iscsi_stats.login_other_fails"
+#define ISCSI_HOST_STATS_LOGIN_AUTHENTICATION_FAILS    
"iscsi_stats.login_authentication_fails"
+#define ISCSI_HOST_STATS_LOGIN_AUTHORIZATION_FAILS     
"iscsi_stats.login_authorization_fails"
+#define ISCSI_HOST_STATS_LOGIN_NEGOTIATION_FAILS       
"iscsi_stats.login_negotiation_fails"
+#define ISCSI_HOST_STATS_LOGIN_REDIRECT_RSPS           
"iscsi_stats.login_redirect_rsps"
+#define ISCSI_HOST_STATS_LOGOUT_NORMAL_RSPS            
"iscsi_stats.logout_normal_rsps"
+#define ISCSI_HOST_STATS_LOGOUT_OTHER_RSPS             
"iscsi_stats.logout_other_rsps"
+#define ISCSI_HOST_STATS_DIGEST_ERR                    "iscsi_stats.digest_err"
+#define ISCSI_HOST_STATS_TIMEOUT_ERR                   
"iscsi_stats.timeout_err"
+#define ISCSI_HOST_STATS_FORMAT_ERR                    "iscsi_stats.format_err"
+#define ISCSI_HOST_STATS_SESSION_FAILS                 
"iscsi_stats.session_fails"
+
 #endif
diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c
index 3a37a48..7653f25 100644
--- a/usr/iscsi_sysfs.c
+++ b/usr/iscsi_sysfs.c
@@ -1913,3 +1913,89 @@ char *iscsi_sysfs_get_iscsi_kernel_version(void)
 {
        return sysfs_attr_get_value("/module/scsi_transport_iscsi", "version");
 }
+
+int iscsi_sysfs_get_host_stats(struct iscsi_stats *stats, uint32_t host_no)
+{
+       char host_id[NAME_SIZE];
+       int ret = 0;
+
+       snprintf(host_id, sizeof(host_id), ISCSI_HOST_ID, host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS, "login_accept_rsps",
+                            &stats->login_accept_rsps);
+       if (ret)
+               log_debug(7, "could not read login_accept_rsps for host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS, "login_other_fails",
+                            &stats->login_other_fails);
+       if (ret)
+               log_debug(7, "could not read login_other_fails for host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS,
+                            "login_authentication_fails",
+                            &stats->login_authentication_fails);
+       if (ret)
+               log_debug(7, "could not read login_authentication_fails for 
host%d",
+                         host_no);
+
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS,
+                            "login_authorization_fails",
+                            &stats->login_authorization_fails);
+       if (ret)
+               log_debug(7, "could not read login_authorization_fails for 
host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS,
+                            "login_negotiation_fails",
+                            &stats->login_negotiation_fails);
+       if (ret)
+               log_debug(7, "could not read login_negotiation_fails for 
host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS, "login_redirect_rsps",
+                            &stats->login_redirect_rsps);
+       if (ret)
+               log_debug(7, "could not read login_redirect_rsps for host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS, "logout_normal_rsps",
+                            &stats->logout_normal_rsps);
+       if (ret)
+               log_debug(7, "could not read logout_normal_rsps for host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS, "logout_other_rsps",
+                            &stats->logout_other_rsps);
+       if (ret)
+               log_debug(7, "could not read logout_other_rsps for host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS, "digest_err",
+                            &stats->digest_err);
+       if (ret)
+               log_debug(7, "could not read direct_err for host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS, "timeout_err",
+                            &stats->timeout_err);
+       if (ret)
+               log_debug(7, "could not read timeout_err for host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS, "format_err",
+                            &stats->format_err);
+       if (ret)
+               log_debug(7, "could not read format_err for host%d",
+                         host_no);
+
+       ret = sysfs_get_uint(host_id, ISCSI_HOST_SUBSYS, "session_fails",
+                            &stats->session_fails);
+       if (ret)
+               log_debug(7, "could not read session_fails for host%d",
+                         host_no);
+
+       return ret;
+}
diff --git a/usr/iscsi_sysfs.h b/usr/iscsi_sysfs.h
index 9a56105..32993ac 100644
--- a/usr/iscsi_sysfs.h
+++ b/usr/iscsi_sysfs.h
@@ -32,6 +32,7 @@ struct iscsi_session_operational_config;
 struct iscsi_conn_operational_config;
 struct iscsi_auth_config;
 struct flashnode_rec;
+struct iscsi_stats;
 
 #define SCSI_MAX_STATE_VALUE 32
 
@@ -109,6 +110,8 @@ extern struct iscsi_transport 
*iscsi_sysfs_get_transport_by_name(char *transport
 extern int iscsi_sysfs_is_transport_loaded(char *transport_name);
 extern int iscsi_sysfs_session_supports_nop(int sid);
 extern int iscsi_sysfs_session_user_created(int sid);
+extern int iscsi_sysfs_get_host_stats(struct iscsi_stats *stats,
+                                     uint32_t host_no);
 
 extern struct list_head transports;
 
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index c6705bd..57736b6 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -2208,19 +2208,13 @@ static void print_host_stats(struct 
iscsi_offload_host_stats *host_stats)
               (unsigned long long)host_stats->iscsi_sequence_error);
 }
 
-static int exec_host_stats_op(int op, int info_level, uint32_t host_no)
+static int get_offload_host_stats(struct iscsi_transport *t, int op,
+                                 int info_level, uint32_t host_no)
 {
-       struct iscsi_transport *t = NULL;
        char *req_buf = NULL;
        int rc = ISCSI_SUCCESS;
        int fd = 0, buf_size = 0;
 
-       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_host_stats;
-       }
 
        buf_size = sizeof(struct iscsi_offload_host_stats) +
                   sizeof(struct iscsi_uevent);
@@ -2255,6 +2249,36 @@ exit_host_stats:
        return rc;
 }
 
+static int exec_host_stats_op(int op, int info_level, uint32_t host_no)
+{
+       struct iscsi_transport *t = NULL;
+       struct iscsi_stats stats;
+       int rc = ISCSI_SUCCESS;
+
+       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 done;
+       }
+
+       if (t->template->offload_host_stats) {
+               rc = get_offload_host_stats(t, op, info_level, host_no);
+               goto done;
+       }
+
+       rc = iscsi_sysfs_get_host_stats(&stats, host_no);
+       if (rc) {
+               log_error("Could not read stats for host %u, %s",
+                         host_no, strerror(rc));
+       } else {
+               idbm_print_host_stats(&stats);
+       }
+
+done:
+       return rc;
+}
+
 static int verify_iface_params(struct list_head *params, struct node_rec *rec)
 {
        struct user_param *param;
@@ -3051,6 +3075,7 @@ static uint64_t parse_host_info(char *optarg, int *rc)
 {
        int err = 0;
        uint64_t host_no;
+       errno = 0;
 
        *rc = 0;
        if (strstr(optarg, ":")) {
diff --git a/usr/transport.c b/usr/transport.c
index 18b7704..4797641 100644
--- a/usr/transport.c
+++ b/usr/transport.c
@@ -101,6 +101,7 @@ struct iscsi_transport_template qla4xxx = {
        .name           = "qla4xxx",
        .set_host_ip    = SET_HOST_IP_NOT_REQ,
         .bind_ep_required = 1,
+       .offload_host_stats = 1,
        .ep_connect     = ktransport_ep_connect,
        .ep_poll        = ktransport_ep_poll,
        .ep_disconnect  = ktransport_ep_disconnect,
diff --git a/usr/transport.h b/usr/transport.h
index 4d3bdbf..42bc3a5 100644
--- a/usr/transport.h
+++ b/usr/transport.h
@@ -39,6 +39,7 @@ struct iscsi_transport_template {
        uint8_t set_host_ip;
        uint8_t use_boot_info;
         uint8_t bind_ep_required;
+       uint8_t offload_host_stats;
        int (*ep_connect) (struct iscsi_conn *conn, int non_blocking);
        int (*ep_poll) (struct iscsi_conn *conn, int timeout_ms);
        void (*ep_disconnect) (struct iscsi_conn *conn);
-- 
1.7.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To post to this group, send email to open-iscsi@googlegroups.com.
Visit this group at https://groups.google.com/group/open-iscsi.
For more options, visit https://groups.google.com/d/optout.

Reply via email to