linux/drivers/target/iscsi/iscsi_target_stat.c
<<
>>
Prefs
   1/*******************************************************************************
   2 * Modern ConfigFS group context specific iSCSI statistics based on original
   3 * iscsi_target_mib.c code
   4 *
   5 * Copyright (c) 2011 Rising Tide Systems
   6 *
   7 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
   8 *
   9 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; either version 2 of the License, or
  14 * (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 ******************************************************************************/
  21
  22#include <linux/configfs.h>
  23#include <linux/export.h>
  24#include <scsi/iscsi_proto.h>
  25#include <target/target_core_base.h>
  26#include <target/configfs_macros.h>
  27
  28#include "iscsi_target_core.h"
  29#include "iscsi_target_parameters.h"
  30#include "iscsi_target_device.h"
  31#include "iscsi_target_tpg.h"
  32#include "iscsi_target_util.h"
  33#include "iscsi_target_stat.h"
  34
  35#ifndef INITIAL_JIFFIES
  36#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
  37#endif
  38
  39/* Instance Attributes Table */
  40#define ISCSI_INST_NUM_NODES            1
  41#define ISCSI_INST_DESCR                "Storage Engine Target"
  42#define ISCSI_INST_LAST_FAILURE_TYPE    0
  43#define ISCSI_DISCONTINUITY_TIME        0
  44
  45#define ISCSI_NODE_INDEX                1
  46
  47#define ISPRINT(a)   ((a >= ' ') && (a <= '~'))
  48
  49/****************************************************************************
  50 * iSCSI MIB Tables
  51 ****************************************************************************/
  52/*
  53 * Instance Attributes Table
  54 */
  55CONFIGFS_EATTR_STRUCT(iscsi_stat_instance, iscsi_wwn_stat_grps);
  56#define ISCSI_STAT_INSTANCE_ATTR(_name, _mode)                  \
  57static struct iscsi_stat_instance_attribute                     \
  58                        iscsi_stat_instance_##_name =           \
  59        __CONFIGFS_EATTR(_name, _mode,                          \
  60        iscsi_stat_instance_show_attr_##_name,                  \
  61        iscsi_stat_instance_store_attr_##_name);
  62
  63#define ISCSI_STAT_INSTANCE_ATTR_RO(_name)                      \
  64static struct iscsi_stat_instance_attribute                     \
  65                        iscsi_stat_instance_##_name =           \
  66        __CONFIGFS_EATTR_RO(_name,                              \
  67        iscsi_stat_instance_show_attr_##_name);
  68
  69static ssize_t iscsi_stat_instance_show_attr_inst(
  70        struct iscsi_wwn_stat_grps *igrps, char *page)
  71{
  72        struct iscsi_tiqn *tiqn = container_of(igrps,
  73                                struct iscsi_tiqn, tiqn_stat_grps);
  74
  75        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
  76}
  77ISCSI_STAT_INSTANCE_ATTR_RO(inst);
  78
  79static ssize_t iscsi_stat_instance_show_attr_min_ver(
  80        struct iscsi_wwn_stat_grps *igrps, char *page)
  81{
  82        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
  83}
  84ISCSI_STAT_INSTANCE_ATTR_RO(min_ver);
  85
  86static ssize_t iscsi_stat_instance_show_attr_max_ver(
  87        struct iscsi_wwn_stat_grps *igrps, char *page)
  88{
  89        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
  90}
  91ISCSI_STAT_INSTANCE_ATTR_RO(max_ver);
  92
  93static ssize_t iscsi_stat_instance_show_attr_portals(
  94        struct iscsi_wwn_stat_grps *igrps, char *page)
  95{
  96        struct iscsi_tiqn *tiqn = container_of(igrps,
  97                                struct iscsi_tiqn, tiqn_stat_grps);
  98
  99        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_num_tpg_nps);
 100}
 101ISCSI_STAT_INSTANCE_ATTR_RO(portals);
 102
 103static ssize_t iscsi_stat_instance_show_attr_nodes(
 104        struct iscsi_wwn_stat_grps *igrps, char *page)
 105{
 106        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_INST_NUM_NODES);
 107}
 108ISCSI_STAT_INSTANCE_ATTR_RO(nodes);
 109
 110static ssize_t iscsi_stat_instance_show_attr_sessions(
 111        struct iscsi_wwn_stat_grps *igrps, char *page)
 112{
 113        struct iscsi_tiqn *tiqn = container_of(igrps,
 114                                struct iscsi_tiqn, tiqn_stat_grps);
 115
 116        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_nsessions);
 117}
 118ISCSI_STAT_INSTANCE_ATTR_RO(sessions);
 119
 120static ssize_t iscsi_stat_instance_show_attr_fail_sess(
 121        struct iscsi_wwn_stat_grps *igrps, char *page)
 122{
 123        struct iscsi_tiqn *tiqn = container_of(igrps,
 124                                struct iscsi_tiqn, tiqn_stat_grps);
 125        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 126        u32 sess_err_count;
 127
 128        spin_lock_bh(&sess_err->lock);
 129        sess_err_count = (sess_err->digest_errors +
 130                          sess_err->cxn_timeout_errors +
 131                          sess_err->pdu_format_errors);
 132        spin_unlock_bh(&sess_err->lock);
 133
 134        return snprintf(page, PAGE_SIZE, "%u\n", sess_err_count);
 135}
 136ISCSI_STAT_INSTANCE_ATTR_RO(fail_sess);
 137
 138static ssize_t iscsi_stat_instance_show_attr_fail_type(
 139        struct iscsi_wwn_stat_grps *igrps, char *page)
 140{
 141        struct iscsi_tiqn *tiqn = container_of(igrps,
 142                                struct iscsi_tiqn, tiqn_stat_grps);
 143        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 144
 145        return snprintf(page, PAGE_SIZE, "%u\n",
 146                        sess_err->last_sess_failure_type);
 147}
 148ISCSI_STAT_INSTANCE_ATTR_RO(fail_type);
 149
 150static ssize_t iscsi_stat_instance_show_attr_fail_rem_name(
 151        struct iscsi_wwn_stat_grps *igrps, char *page)
 152{
 153        struct iscsi_tiqn *tiqn = container_of(igrps,
 154                                struct iscsi_tiqn, tiqn_stat_grps);
 155        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 156
 157        return snprintf(page, PAGE_SIZE, "%s\n",
 158                        sess_err->last_sess_fail_rem_name[0] ?
 159                        sess_err->last_sess_fail_rem_name : NONE);
 160}
 161ISCSI_STAT_INSTANCE_ATTR_RO(fail_rem_name);
 162
 163static ssize_t iscsi_stat_instance_show_attr_disc_time(
 164        struct iscsi_wwn_stat_grps *igrps, char *page)
 165{
 166        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DISCONTINUITY_TIME);
 167}
 168ISCSI_STAT_INSTANCE_ATTR_RO(disc_time);
 169
 170static ssize_t iscsi_stat_instance_show_attr_description(
 171        struct iscsi_wwn_stat_grps *igrps, char *page)
 172{
 173        return snprintf(page, PAGE_SIZE, "%s\n", ISCSI_INST_DESCR);
 174}
 175ISCSI_STAT_INSTANCE_ATTR_RO(description);
 176
 177static ssize_t iscsi_stat_instance_show_attr_vendor(
 178        struct iscsi_wwn_stat_grps *igrps, char *page)
 179{
 180        return snprintf(page, PAGE_SIZE, "RisingTide Systems iSCSI-Target\n");
 181}
 182ISCSI_STAT_INSTANCE_ATTR_RO(vendor);
 183
 184static ssize_t iscsi_stat_instance_show_attr_version(
 185        struct iscsi_wwn_stat_grps *igrps, char *page)
 186{
 187        return snprintf(page, PAGE_SIZE, "%s\n", ISCSIT_VERSION);
 188}
 189ISCSI_STAT_INSTANCE_ATTR_RO(version);
 190
 191CONFIGFS_EATTR_OPS(iscsi_stat_instance, iscsi_wwn_stat_grps,
 192                iscsi_instance_group);
 193
 194static struct configfs_attribute *iscsi_stat_instance_attrs[] = {
 195        &iscsi_stat_instance_inst.attr,
 196        &iscsi_stat_instance_min_ver.attr,
 197        &iscsi_stat_instance_max_ver.attr,
 198        &iscsi_stat_instance_portals.attr,
 199        &iscsi_stat_instance_nodes.attr,
 200        &iscsi_stat_instance_sessions.attr,
 201        &iscsi_stat_instance_fail_sess.attr,
 202        &iscsi_stat_instance_fail_type.attr,
 203        &iscsi_stat_instance_fail_rem_name.attr,
 204        &iscsi_stat_instance_disc_time.attr,
 205        &iscsi_stat_instance_description.attr,
 206        &iscsi_stat_instance_vendor.attr,
 207        &iscsi_stat_instance_version.attr,
 208        NULL,
 209};
 210
 211static struct configfs_item_operations iscsi_stat_instance_item_ops = {
 212        .show_attribute         = iscsi_stat_instance_attr_show,
 213        .store_attribute        = iscsi_stat_instance_attr_store,
 214};
 215
 216struct config_item_type iscsi_stat_instance_cit = {
 217        .ct_item_ops            = &iscsi_stat_instance_item_ops,
 218        .ct_attrs               = iscsi_stat_instance_attrs,
 219        .ct_owner               = THIS_MODULE,
 220};
 221
 222/*
 223 * Instance Session Failure Stats Table
 224 */
 225CONFIGFS_EATTR_STRUCT(iscsi_stat_sess_err, iscsi_wwn_stat_grps);
 226#define ISCSI_STAT_SESS_ERR_ATTR(_name, _mode)                  \
 227static struct iscsi_stat_sess_err_attribute                     \
 228                        iscsi_stat_sess_err_##_name =           \
 229        __CONFIGFS_EATTR(_name, _mode,                          \
 230        iscsi_stat_sess_err_show_attr_##_name,                  \
 231        iscsi_stat_sess_err_store_attr_##_name);
 232
 233#define ISCSI_STAT_SESS_ERR_ATTR_RO(_name)                      \
 234static struct iscsi_stat_sess_err_attribute                     \
 235                        iscsi_stat_sess_err_##_name =           \
 236        __CONFIGFS_EATTR_RO(_name,                              \
 237        iscsi_stat_sess_err_show_attr_##_name);
 238
 239static ssize_t iscsi_stat_sess_err_show_attr_inst(
 240        struct iscsi_wwn_stat_grps *igrps, char *page)
 241{
 242        struct iscsi_tiqn *tiqn = container_of(igrps,
 243                                struct iscsi_tiqn, tiqn_stat_grps);
 244
 245        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 246}
 247ISCSI_STAT_SESS_ERR_ATTR_RO(inst);
 248
 249static ssize_t iscsi_stat_sess_err_show_attr_digest_errors(
 250        struct iscsi_wwn_stat_grps *igrps, char *page)
 251{
 252        struct iscsi_tiqn *tiqn = container_of(igrps,
 253                                struct iscsi_tiqn, tiqn_stat_grps);
 254        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 255
 256        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->digest_errors);
 257}
 258ISCSI_STAT_SESS_ERR_ATTR_RO(digest_errors);
 259
 260static ssize_t iscsi_stat_sess_err_show_attr_cxn_errors(
 261        struct iscsi_wwn_stat_grps *igrps, char *page)
 262{
 263        struct iscsi_tiqn *tiqn = container_of(igrps,
 264                                struct iscsi_tiqn, tiqn_stat_grps);
 265        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 266
 267        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->cxn_timeout_errors);
 268}
 269ISCSI_STAT_SESS_ERR_ATTR_RO(cxn_errors);
 270
 271static ssize_t iscsi_stat_sess_err_show_attr_format_errors(
 272        struct iscsi_wwn_stat_grps *igrps, char *page)
 273{
 274        struct iscsi_tiqn *tiqn = container_of(igrps,
 275                                struct iscsi_tiqn, tiqn_stat_grps);
 276        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 277
 278        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->pdu_format_errors);
 279}
 280ISCSI_STAT_SESS_ERR_ATTR_RO(format_errors);
 281
 282CONFIGFS_EATTR_OPS(iscsi_stat_sess_err, iscsi_wwn_stat_grps,
 283                iscsi_sess_err_group);
 284
 285static struct configfs_attribute *iscsi_stat_sess_err_attrs[] = {
 286        &iscsi_stat_sess_err_inst.attr,
 287        &iscsi_stat_sess_err_digest_errors.attr,
 288        &iscsi_stat_sess_err_cxn_errors.attr,
 289        &iscsi_stat_sess_err_format_errors.attr,
 290        NULL,
 291};
 292
 293static struct configfs_item_operations iscsi_stat_sess_err_item_ops = {
 294        .show_attribute         = iscsi_stat_sess_err_attr_show,
 295        .store_attribute        = iscsi_stat_sess_err_attr_store,
 296};
 297
 298struct config_item_type iscsi_stat_sess_err_cit = {
 299        .ct_item_ops            = &iscsi_stat_sess_err_item_ops,
 300        .ct_attrs               = iscsi_stat_sess_err_attrs,
 301        .ct_owner               = THIS_MODULE,
 302};
 303
 304/*
 305 * Target Attributes Table
 306 */
 307CONFIGFS_EATTR_STRUCT(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps);
 308#define ISCSI_STAT_TGT_ATTR(_name, _mode)                       \
 309static struct iscsi_stat_tgt_attr_attribute                     \
 310                        iscsi_stat_tgt_attr_##_name =           \
 311        __CONFIGFS_EATTR(_name, _mode,                          \
 312        iscsi_stat_tgt-attr_show_attr_##_name,                  \
 313        iscsi_stat_tgt_attr_store_attr_##_name);
 314
 315#define ISCSI_STAT_TGT_ATTR_RO(_name)                           \
 316static struct iscsi_stat_tgt_attr_attribute                     \
 317                        iscsi_stat_tgt_attr_##_name =           \
 318        __CONFIGFS_EATTR_RO(_name,                              \
 319        iscsi_stat_tgt_attr_show_attr_##_name);
 320
 321static ssize_t iscsi_stat_tgt_attr_show_attr_inst(
 322        struct iscsi_wwn_stat_grps *igrps, char *page)
 323{
 324        struct iscsi_tiqn *tiqn = container_of(igrps,
 325                                struct iscsi_tiqn, tiqn_stat_grps);
 326
 327        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 328}
 329ISCSI_STAT_TGT_ATTR_RO(inst);
 330
 331static ssize_t iscsi_stat_tgt_attr_show_attr_indx(
 332        struct iscsi_wwn_stat_grps *igrps, char *page)
 333{
 334        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 335}
 336ISCSI_STAT_TGT_ATTR_RO(indx);
 337
 338static ssize_t iscsi_stat_tgt_attr_show_attr_login_fails(
 339        struct iscsi_wwn_stat_grps *igrps, char *page)
 340{
 341        struct iscsi_tiqn *tiqn = container_of(igrps,
 342                                struct iscsi_tiqn, tiqn_stat_grps);
 343        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 344        u32 fail_count;
 345
 346        spin_lock(&lstat->lock);
 347        fail_count = (lstat->redirects + lstat->authorize_fails +
 348                        lstat->authenticate_fails + lstat->negotiate_fails +
 349                        lstat->other_fails);
 350        spin_unlock(&lstat->lock);
 351
 352        return snprintf(page, PAGE_SIZE, "%u\n", fail_count);
 353}
 354ISCSI_STAT_TGT_ATTR_RO(login_fails);
 355
 356static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_time(
 357        struct iscsi_wwn_stat_grps *igrps, char *page)
 358{
 359        struct iscsi_tiqn *tiqn = container_of(igrps,
 360                                struct iscsi_tiqn, tiqn_stat_grps);
 361        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 362        u32 last_fail_time;
 363
 364        spin_lock(&lstat->lock);
 365        last_fail_time = lstat->last_fail_time ?
 366                        (u32)(((u32)lstat->last_fail_time -
 367                                INITIAL_JIFFIES) * 100 / HZ) : 0;
 368        spin_unlock(&lstat->lock);
 369
 370        return snprintf(page, PAGE_SIZE, "%u\n", last_fail_time);
 371}
 372ISCSI_STAT_TGT_ATTR_RO(last_fail_time);
 373
 374static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_type(
 375        struct iscsi_wwn_stat_grps *igrps, char *page)
 376{
 377        struct iscsi_tiqn *tiqn = container_of(igrps,
 378                                struct iscsi_tiqn, tiqn_stat_grps);
 379        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 380        u32 last_fail_type;
 381
 382        spin_lock(&lstat->lock);
 383        last_fail_type = lstat->last_fail_type;
 384        spin_unlock(&lstat->lock);
 385
 386        return snprintf(page, PAGE_SIZE, "%u\n", last_fail_type);
 387}
 388ISCSI_STAT_TGT_ATTR_RO(last_fail_type);
 389
 390static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_name(
 391        struct iscsi_wwn_stat_grps *igrps, char *page)
 392{
 393        struct iscsi_tiqn *tiqn = container_of(igrps,
 394                                struct iscsi_tiqn, tiqn_stat_grps);
 395        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 396        unsigned char buf[224];
 397
 398        spin_lock(&lstat->lock);
 399        snprintf(buf, 224, "%s", lstat->last_intr_fail_name[0] ?
 400                                lstat->last_intr_fail_name : NONE);
 401        spin_unlock(&lstat->lock);
 402
 403        return snprintf(page, PAGE_SIZE, "%s\n", buf);
 404}
 405ISCSI_STAT_TGT_ATTR_RO(fail_intr_name);
 406
 407static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr_type(
 408        struct iscsi_wwn_stat_grps *igrps, char *page)
 409{
 410        struct iscsi_tiqn *tiqn = container_of(igrps,
 411                        struct iscsi_tiqn, tiqn_stat_grps);
 412        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 413        unsigned char buf[8];
 414
 415        spin_lock(&lstat->lock);
 416        snprintf(buf, 8, "%s", (lstat->last_intr_fail_ip_addr != NULL) ?
 417                                "ipv6" : "ipv4");
 418        spin_unlock(&lstat->lock);
 419
 420        return snprintf(page, PAGE_SIZE, "%s\n", buf);
 421}
 422ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr_type);
 423
 424static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr(
 425        struct iscsi_wwn_stat_grps *igrps, char *page)
 426{
 427        struct iscsi_tiqn *tiqn = container_of(igrps,
 428                        struct iscsi_tiqn, tiqn_stat_grps);
 429        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 430        unsigned char buf[32];
 431
 432        spin_lock(&lstat->lock);
 433        if (lstat->last_intr_fail_ip_family == AF_INET6)
 434                snprintf(buf, 32, "[%s]", lstat->last_intr_fail_ip_addr);
 435        else
 436                snprintf(buf, 32, "%s", lstat->last_intr_fail_ip_addr);
 437        spin_unlock(&lstat->lock);
 438
 439        return snprintf(page, PAGE_SIZE, "%s\n", buf);
 440}
 441ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr);
 442
 443CONFIGFS_EATTR_OPS(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps,
 444                iscsi_tgt_attr_group);
 445
 446static struct configfs_attribute *iscsi_stat_tgt_attr_attrs[] = {
 447        &iscsi_stat_tgt_attr_inst.attr,
 448        &iscsi_stat_tgt_attr_indx.attr,
 449        &iscsi_stat_tgt_attr_login_fails.attr,
 450        &iscsi_stat_tgt_attr_last_fail_time.attr,
 451        &iscsi_stat_tgt_attr_last_fail_type.attr,
 452        &iscsi_stat_tgt_attr_fail_intr_name.attr,
 453        &iscsi_stat_tgt_attr_fail_intr_addr_type.attr,
 454        &iscsi_stat_tgt_attr_fail_intr_addr.attr,
 455        NULL,
 456};
 457
 458static struct configfs_item_operations iscsi_stat_tgt_attr_item_ops = {
 459        .show_attribute         = iscsi_stat_tgt_attr_attr_show,
 460        .store_attribute        = iscsi_stat_tgt_attr_attr_store,
 461};
 462
 463struct config_item_type iscsi_stat_tgt_attr_cit = {
 464        .ct_item_ops            = &iscsi_stat_tgt_attr_item_ops,
 465        .ct_attrs               = iscsi_stat_tgt_attr_attrs,
 466        .ct_owner               = THIS_MODULE,
 467};
 468
 469/*
 470 * Target Login Stats Table
 471 */
 472CONFIGFS_EATTR_STRUCT(iscsi_stat_login, iscsi_wwn_stat_grps);
 473#define ISCSI_STAT_LOGIN(_name, _mode)                          \
 474static struct iscsi_stat_login_attribute                        \
 475                        iscsi_stat_login_##_name =              \
 476        __CONFIGFS_EATTR(_name, _mode,                          \
 477        iscsi_stat_login_show_attr_##_name,                     \
 478        iscsi_stat_login_store_attr_##_name);
 479
 480#define ISCSI_STAT_LOGIN_RO(_name)                              \
 481static struct iscsi_stat_login_attribute                        \
 482                        iscsi_stat_login_##_name =              \
 483        __CONFIGFS_EATTR_RO(_name,                              \
 484        iscsi_stat_login_show_attr_##_name);
 485
 486static ssize_t iscsi_stat_login_show_attr_inst(
 487        struct iscsi_wwn_stat_grps *igrps, char *page)
 488{
 489        struct iscsi_tiqn *tiqn = container_of(igrps,
 490                                struct iscsi_tiqn, tiqn_stat_grps);
 491
 492        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 493}
 494ISCSI_STAT_LOGIN_RO(inst);
 495
 496static ssize_t iscsi_stat_login_show_attr_indx(
 497        struct iscsi_wwn_stat_grps *igrps, char *page)
 498{
 499        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 500}
 501ISCSI_STAT_LOGIN_RO(indx);
 502
 503static ssize_t iscsi_stat_login_show_attr_accepts(
 504        struct iscsi_wwn_stat_grps *igrps, char *page)
 505{
 506        struct iscsi_tiqn *tiqn = container_of(igrps,
 507                                struct iscsi_tiqn, tiqn_stat_grps);
 508        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 509        ssize_t ret;
 510
 511        spin_lock(&lstat->lock);
 512        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->accepts);
 513        spin_unlock(&lstat->lock);
 514
 515        return ret;
 516}
 517ISCSI_STAT_LOGIN_RO(accepts);
 518
 519static ssize_t iscsi_stat_login_show_attr_other_fails(
 520        struct iscsi_wwn_stat_grps *igrps, char *page)
 521{
 522        struct iscsi_tiqn *tiqn = container_of(igrps,
 523                                struct iscsi_tiqn, tiqn_stat_grps);
 524        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 525        ssize_t ret;
 526
 527        spin_lock(&lstat->lock);
 528        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->other_fails);
 529        spin_unlock(&lstat->lock);
 530
 531        return ret;
 532}
 533ISCSI_STAT_LOGIN_RO(other_fails);
 534
 535static ssize_t iscsi_stat_login_show_attr_redirects(
 536        struct iscsi_wwn_stat_grps *igrps, char *page)
 537{
 538        struct iscsi_tiqn *tiqn = container_of(igrps,
 539                                struct iscsi_tiqn, tiqn_stat_grps);
 540        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 541        ssize_t ret;
 542
 543        spin_lock(&lstat->lock);
 544        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->redirects);
 545        spin_unlock(&lstat->lock);
 546
 547        return ret;
 548}
 549ISCSI_STAT_LOGIN_RO(redirects);
 550
 551static ssize_t iscsi_stat_login_show_attr_authorize_fails(
 552        struct iscsi_wwn_stat_grps *igrps, char *page)
 553{
 554        struct iscsi_tiqn *tiqn = container_of(igrps,
 555                                struct iscsi_tiqn, tiqn_stat_grps);
 556        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 557        ssize_t ret;
 558
 559        spin_lock(&lstat->lock);
 560        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authorize_fails);
 561        spin_unlock(&lstat->lock);
 562
 563        return ret;
 564}
 565ISCSI_STAT_LOGIN_RO(authorize_fails);
 566
 567static ssize_t iscsi_stat_login_show_attr_authenticate_fails(
 568        struct iscsi_wwn_stat_grps *igrps, char *page)
 569{
 570        struct iscsi_tiqn *tiqn = container_of(igrps,
 571                                struct iscsi_tiqn, tiqn_stat_grps);
 572        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 573        ssize_t ret;
 574
 575        spin_lock(&lstat->lock);
 576        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authenticate_fails);
 577        spin_unlock(&lstat->lock);
 578
 579        return ret;
 580}
 581ISCSI_STAT_LOGIN_RO(authenticate_fails);
 582
 583static ssize_t iscsi_stat_login_show_attr_negotiate_fails(
 584        struct iscsi_wwn_stat_grps *igrps, char *page)
 585{
 586        struct iscsi_tiqn *tiqn = container_of(igrps,
 587                                struct iscsi_tiqn, tiqn_stat_grps);
 588        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 589        ssize_t ret;
 590
 591        spin_lock(&lstat->lock);
 592        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->negotiate_fails);
 593        spin_unlock(&lstat->lock);
 594
 595        return ret;
 596}
 597ISCSI_STAT_LOGIN_RO(negotiate_fails);
 598
 599CONFIGFS_EATTR_OPS(iscsi_stat_login, iscsi_wwn_stat_grps,
 600                iscsi_login_stats_group);
 601
 602static struct configfs_attribute *iscsi_stat_login_stats_attrs[] = {
 603        &iscsi_stat_login_inst.attr,
 604        &iscsi_stat_login_indx.attr,
 605        &iscsi_stat_login_accepts.attr,
 606        &iscsi_stat_login_other_fails.attr,
 607        &iscsi_stat_login_redirects.attr,
 608        &iscsi_stat_login_authorize_fails.attr,
 609        &iscsi_stat_login_authenticate_fails.attr,
 610        &iscsi_stat_login_negotiate_fails.attr,
 611        NULL,
 612};
 613
 614static struct configfs_item_operations iscsi_stat_login_stats_item_ops = {
 615        .show_attribute         = iscsi_stat_login_attr_show,
 616        .store_attribute        = iscsi_stat_login_attr_store,
 617};
 618
 619struct config_item_type iscsi_stat_login_cit = {
 620        .ct_item_ops            = &iscsi_stat_login_stats_item_ops,
 621        .ct_attrs               = iscsi_stat_login_stats_attrs,
 622        .ct_owner               = THIS_MODULE,
 623};
 624
 625/*
 626 * Target Logout Stats Table
 627 */
 628
 629CONFIGFS_EATTR_STRUCT(iscsi_stat_logout, iscsi_wwn_stat_grps);
 630#define ISCSI_STAT_LOGOUT(_name, _mode)                         \
 631static struct iscsi_stat_logout_attribute                       \
 632                        iscsi_stat_logout_##_name =             \
 633        __CONFIGFS_EATTR(_name, _mode,                          \
 634        iscsi_stat_logout_show_attr_##_name,                    \
 635        iscsi_stat_logout_store_attr_##_name);
 636
 637#define ISCSI_STAT_LOGOUT_RO(_name)                             \
 638static struct iscsi_stat_logout_attribute                       \
 639                        iscsi_stat_logout_##_name =             \
 640        __CONFIGFS_EATTR_RO(_name,                              \
 641        iscsi_stat_logout_show_attr_##_name);
 642
 643static ssize_t iscsi_stat_logout_show_attr_inst(
 644        struct iscsi_wwn_stat_grps *igrps, char *page)
 645{
 646        struct iscsi_tiqn *tiqn = container_of(igrps,
 647                        struct iscsi_tiqn, tiqn_stat_grps);
 648
 649        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 650}
 651ISCSI_STAT_LOGOUT_RO(inst);
 652
 653static ssize_t iscsi_stat_logout_show_attr_indx(
 654        struct iscsi_wwn_stat_grps *igrps, char *page)
 655{
 656        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 657}
 658ISCSI_STAT_LOGOUT_RO(indx);
 659
 660static ssize_t iscsi_stat_logout_show_attr_normal_logouts(
 661        struct iscsi_wwn_stat_grps *igrps, char *page)
 662{
 663        struct iscsi_tiqn *tiqn = container_of(igrps,
 664                        struct iscsi_tiqn, tiqn_stat_grps);
 665        struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
 666
 667        return snprintf(page, PAGE_SIZE, "%u\n", lstats->normal_logouts);
 668}
 669ISCSI_STAT_LOGOUT_RO(normal_logouts);
 670
 671static ssize_t iscsi_stat_logout_show_attr_abnormal_logouts(
 672        struct iscsi_wwn_stat_grps *igrps, char *page)
 673{
 674        struct iscsi_tiqn *tiqn = container_of(igrps,
 675                        struct iscsi_tiqn, tiqn_stat_grps);
 676        struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
 677
 678        return snprintf(page, PAGE_SIZE, "%u\n", lstats->abnormal_logouts);
 679}
 680ISCSI_STAT_LOGOUT_RO(abnormal_logouts);
 681
 682CONFIGFS_EATTR_OPS(iscsi_stat_logout, iscsi_wwn_stat_grps,
 683                iscsi_logout_stats_group);
 684
 685static struct configfs_attribute *iscsi_stat_logout_stats_attrs[] = {
 686        &iscsi_stat_logout_inst.attr,
 687        &iscsi_stat_logout_indx.attr,
 688        &iscsi_stat_logout_normal_logouts.attr,
 689        &iscsi_stat_logout_abnormal_logouts.attr,
 690        NULL,
 691};
 692
 693static struct configfs_item_operations iscsi_stat_logout_stats_item_ops = {
 694        .show_attribute         = iscsi_stat_logout_attr_show,
 695        .store_attribute        = iscsi_stat_logout_attr_store,
 696};
 697
 698struct config_item_type iscsi_stat_logout_cit = {
 699        .ct_item_ops            = &iscsi_stat_logout_stats_item_ops,
 700        .ct_attrs               = iscsi_stat_logout_stats_attrs,
 701        .ct_owner               = THIS_MODULE,
 702};
 703
 704/*
 705 * Session Stats Table
 706 */
 707
 708CONFIGFS_EATTR_STRUCT(iscsi_stat_sess, iscsi_node_stat_grps);
 709#define ISCSI_STAT_SESS(_name, _mode)                           \
 710static struct iscsi_stat_sess_attribute                         \
 711                        iscsi_stat_sess_##_name =               \
 712        __CONFIGFS_EATTR(_name, _mode,                          \
 713        iscsi_stat_sess_show_attr_##_name,                      \
 714        iscsi_stat_sess_store_attr_##_name);
 715
 716#define ISCSI_STAT_SESS_RO(_name)                               \
 717static struct iscsi_stat_sess_attribute                         \
 718                        iscsi_stat_sess_##_name =               \
 719        __CONFIGFS_EATTR_RO(_name,                              \
 720        iscsi_stat_sess_show_attr_##_name);
 721
 722static ssize_t iscsi_stat_sess_show_attr_inst(
 723        struct iscsi_node_stat_grps *igrps, char *page)
 724{
 725        struct iscsi_node_acl *acl = container_of(igrps,
 726                        struct iscsi_node_acl, node_stat_grps);
 727        struct se_wwn *wwn = acl->se_node_acl.se_tpg->se_tpg_wwn;
 728        struct iscsi_tiqn *tiqn = container_of(wwn,
 729                        struct iscsi_tiqn, tiqn_wwn);
 730
 731        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 732}
 733ISCSI_STAT_SESS_RO(inst);
 734
 735static ssize_t iscsi_stat_sess_show_attr_node(
 736        struct iscsi_node_stat_grps *igrps, char *page)
 737{
 738        struct iscsi_node_acl *acl = container_of(igrps,
 739                        struct iscsi_node_acl, node_stat_grps);
 740        struct se_node_acl *se_nacl = &acl->se_node_acl;
 741        struct iscsi_session *sess;
 742        struct se_session *se_sess;
 743        ssize_t ret = 0;
 744
 745        spin_lock_bh(&se_nacl->nacl_sess_lock);
 746        se_sess = se_nacl->nacl_sess;
 747        if (se_sess) {
 748                sess = se_sess->fabric_sess_ptr;
 749                if (sess)
 750                        ret = snprintf(page, PAGE_SIZE, "%u\n",
 751                                sess->sess_ops->SessionType ? 0 : ISCSI_NODE_INDEX);
 752        }
 753        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 754
 755        return ret;
 756}
 757ISCSI_STAT_SESS_RO(node);
 758
 759static ssize_t iscsi_stat_sess_show_attr_indx(
 760        struct iscsi_node_stat_grps *igrps, char *page)
 761{
 762        struct iscsi_node_acl *acl = container_of(igrps,
 763                        struct iscsi_node_acl, node_stat_grps);
 764        struct se_node_acl *se_nacl = &acl->se_node_acl;
 765        struct iscsi_session *sess;
 766        struct se_session *se_sess;
 767        ssize_t ret = 0;
 768
 769        spin_lock_bh(&se_nacl->nacl_sess_lock);
 770        se_sess = se_nacl->nacl_sess;
 771        if (se_sess) {
 772                sess = se_sess->fabric_sess_ptr;
 773                if (sess)
 774                        ret = snprintf(page, PAGE_SIZE, "%u\n",
 775                                        sess->session_index);
 776        }
 777        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 778
 779        return ret;
 780}
 781ISCSI_STAT_SESS_RO(indx);
 782
 783static ssize_t iscsi_stat_sess_show_attr_cmd_pdus(
 784        struct iscsi_node_stat_grps *igrps, char *page)
 785{
 786        struct iscsi_node_acl *acl = container_of(igrps,
 787                        struct iscsi_node_acl, node_stat_grps);
 788        struct se_node_acl *se_nacl = &acl->se_node_acl;
 789        struct iscsi_session *sess;
 790        struct se_session *se_sess;
 791        ssize_t ret = 0;
 792
 793        spin_lock_bh(&se_nacl->nacl_sess_lock);
 794        se_sess = se_nacl->nacl_sess;
 795        if (se_sess) {
 796                sess = se_sess->fabric_sess_ptr;
 797                if (sess)
 798                        ret = snprintf(page, PAGE_SIZE, "%u\n", sess->cmd_pdus);
 799        }
 800        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 801
 802        return ret;
 803}
 804ISCSI_STAT_SESS_RO(cmd_pdus);
 805
 806static ssize_t iscsi_stat_sess_show_attr_rsp_pdus(
 807        struct iscsi_node_stat_grps *igrps, char *page)
 808{
 809        struct iscsi_node_acl *acl = container_of(igrps,
 810                        struct iscsi_node_acl, node_stat_grps);
 811        struct se_node_acl *se_nacl = &acl->se_node_acl;
 812        struct iscsi_session *sess;
 813        struct se_session *se_sess;
 814        ssize_t ret = 0;
 815
 816        spin_lock_bh(&se_nacl->nacl_sess_lock);
 817        se_sess = se_nacl->nacl_sess;
 818        if (se_sess) {
 819                sess = se_sess->fabric_sess_ptr;
 820                if (sess)
 821                        ret = snprintf(page, PAGE_SIZE, "%u\n", sess->rsp_pdus);
 822        }
 823        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 824
 825        return ret;
 826}
 827ISCSI_STAT_SESS_RO(rsp_pdus);
 828
 829static ssize_t iscsi_stat_sess_show_attr_txdata_octs(
 830        struct iscsi_node_stat_grps *igrps, char *page)
 831{
 832        struct iscsi_node_acl *acl = container_of(igrps,
 833                        struct iscsi_node_acl, node_stat_grps);
 834        struct se_node_acl *se_nacl = &acl->se_node_acl;
 835        struct iscsi_session *sess;
 836        struct se_session *se_sess;
 837        ssize_t ret = 0;
 838
 839        spin_lock_bh(&se_nacl->nacl_sess_lock);
 840        se_sess = se_nacl->nacl_sess;
 841        if (se_sess) {
 842                sess = se_sess->fabric_sess_ptr;
 843                if (sess)
 844                        ret = snprintf(page, PAGE_SIZE, "%llu\n",
 845                                (unsigned long long)sess->tx_data_octets);
 846        }
 847        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 848
 849        return ret;
 850}
 851ISCSI_STAT_SESS_RO(txdata_octs);
 852
 853static ssize_t iscsi_stat_sess_show_attr_rxdata_octs(
 854        struct iscsi_node_stat_grps *igrps, char *page)
 855{
 856        struct iscsi_node_acl *acl = container_of(igrps,
 857                        struct iscsi_node_acl, node_stat_grps);
 858        struct se_node_acl *se_nacl = &acl->se_node_acl;
 859        struct iscsi_session *sess;
 860        struct se_session *se_sess;
 861        ssize_t ret = 0;
 862
 863        spin_lock_bh(&se_nacl->nacl_sess_lock);
 864        se_sess = se_nacl->nacl_sess;
 865        if (se_sess) {
 866                sess = se_sess->fabric_sess_ptr;
 867                if (sess)
 868                        ret = snprintf(page, PAGE_SIZE, "%llu\n",
 869                                (unsigned long long)sess->rx_data_octets);
 870        }
 871        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 872
 873        return ret;
 874}
 875ISCSI_STAT_SESS_RO(rxdata_octs);
 876
 877static ssize_t iscsi_stat_sess_show_attr_conn_digest_errors(
 878        struct iscsi_node_stat_grps *igrps, char *page)
 879{
 880        struct iscsi_node_acl *acl = container_of(igrps,
 881                        struct iscsi_node_acl, node_stat_grps);
 882        struct se_node_acl *se_nacl = &acl->se_node_acl;
 883        struct iscsi_session *sess;
 884        struct se_session *se_sess;
 885        ssize_t ret = 0;
 886
 887        spin_lock_bh(&se_nacl->nacl_sess_lock);
 888        se_sess = se_nacl->nacl_sess;
 889        if (se_sess) {
 890                sess = se_sess->fabric_sess_ptr;
 891                if (sess)
 892                        ret = snprintf(page, PAGE_SIZE, "%u\n",
 893                                        sess->conn_digest_errors);
 894        }
 895        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 896
 897        return ret;
 898}
 899ISCSI_STAT_SESS_RO(conn_digest_errors);
 900
 901static ssize_t iscsi_stat_sess_show_attr_conn_timeout_errors(
 902        struct iscsi_node_stat_grps *igrps, char *page)
 903{
 904        struct iscsi_node_acl *acl = container_of(igrps,
 905                        struct iscsi_node_acl, node_stat_grps);
 906        struct se_node_acl *se_nacl = &acl->se_node_acl;
 907        struct iscsi_session *sess;
 908        struct se_session *se_sess;
 909        ssize_t ret = 0;
 910
 911        spin_lock_bh(&se_nacl->nacl_sess_lock);
 912        se_sess = se_nacl->nacl_sess;
 913        if (se_sess) {
 914                sess = se_sess->fabric_sess_ptr;
 915                if (sess)
 916                        ret = snprintf(page, PAGE_SIZE, "%u\n",
 917                                        sess->conn_timeout_errors);
 918        }
 919        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 920
 921        return ret;
 922}
 923ISCSI_STAT_SESS_RO(conn_timeout_errors);
 924
 925CONFIGFS_EATTR_OPS(iscsi_stat_sess, iscsi_node_stat_grps,
 926                iscsi_sess_stats_group);
 927
 928static struct configfs_attribute *iscsi_stat_sess_stats_attrs[] = {
 929        &iscsi_stat_sess_inst.attr,
 930        &iscsi_stat_sess_node.attr,
 931        &iscsi_stat_sess_indx.attr,
 932        &iscsi_stat_sess_cmd_pdus.attr,
 933        &iscsi_stat_sess_rsp_pdus.attr,
 934        &iscsi_stat_sess_txdata_octs.attr,
 935        &iscsi_stat_sess_rxdata_octs.attr,
 936        &iscsi_stat_sess_conn_digest_errors.attr,
 937        &iscsi_stat_sess_conn_timeout_errors.attr,
 938        NULL,
 939};
 940
 941static struct configfs_item_operations iscsi_stat_sess_stats_item_ops = {
 942        .show_attribute         = iscsi_stat_sess_attr_show,
 943        .store_attribute        = iscsi_stat_sess_attr_store,
 944};
 945
 946struct config_item_type iscsi_stat_sess_cit = {
 947        .ct_item_ops            = &iscsi_stat_sess_stats_item_ops,
 948        .ct_attrs               = iscsi_stat_sess_stats_attrs,
 949        .ct_owner               = THIS_MODULE,
 950};
 951