target: Add target_show_dynamic_sessions attribute helper
authorNicholas Bellinger <nab@linux-iscsi.org>
Sat, 7 Mar 2015 04:34:32 +0000 (20:34 -0800)
committerNicholas Bellinger <nab@linux-iscsi.org>
Sat, 7 Mar 2015 05:24:53 +0000 (21:24 -0800)
This patch adds a new helper function that can be used by fabric driver
TPG attributes for dumping the list of active sessions with a dynamically
generated se_node_acl. (generate_node_acl=1).

It prints one se_node_acl->initiatorname per line, up to PAGE_SIZE which
is due to the current limitiation of single page attribute output within
sysfs and configfs code.

Note that if a session is referencing a explicit NodeACL, the InitiatorName
will not appear within dynamic_sessions output.

Reported-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/target_core_transport.c
include/target/target_core_fabric.h
include/target/target_core_fabric_configfs.h

index 0adc0f6502134eb3292a7a2cab66ac75be4d6406..e06c136ff8391cf08647d6025b42232314f78c67 100644 (file)
@@ -404,6 +404,30 @@ void target_put_session(struct se_session *se_sess)
 }
 EXPORT_SYMBOL(target_put_session);
 
+ssize_t target_show_dynamic_sessions(struct se_portal_group *se_tpg, char *page)
+{
+       struct se_session *se_sess;
+       ssize_t len = 0;
+
+       spin_lock_bh(&se_tpg->session_lock);
+       list_for_each_entry(se_sess, &se_tpg->tpg_sess_list, sess_list) {
+               if (!se_sess->se_node_acl)
+                       continue;
+               if (!se_sess->se_node_acl->dynamic_node_acl)
+                       continue;
+               if (strlen(se_sess->se_node_acl->initiatorname) + 1 + len > PAGE_SIZE)
+                       break;
+
+               len += snprintf(page + len, PAGE_SIZE - len, "%s\n",
+                               se_sess->se_node_acl->initiatorname);
+               len += 1; /* Include NULL terminator */
+       }
+       spin_unlock_bh(&se_tpg->session_lock);
+
+       return len;
+}
+EXPORT_SYMBOL(target_show_dynamic_sessions);
+
 static void target_complete_nacl(struct kref *kref)
 {
        struct se_node_acl *nacl = container_of(kref,
index 22a4e98eec807ecaa93a735ad63fd05ef26809a9..2f4a2505db4c6ff1ed5f867360191b80c1e7fe0a 100644 (file)
@@ -95,6 +95,7 @@ void  transport_register_session(struct se_portal_group *,
                struct se_node_acl *, struct se_session *, void *);
 void   target_get_session(struct se_session *);
 void   target_put_session(struct se_session *);
+ssize_t        target_show_dynamic_sessions(struct se_portal_group *, char *);
 void   transport_free_session(struct se_session *);
 void   target_put_nacl(struct se_node_acl *);
 void   transport_deregister_session_configfs(struct se_session *);
index b32a14905cfa5d8eab71c0450cc6ef4d0a383c85..7a0649c09e792e27ea073892f368a958c33ce02c 100644 (file)
@@ -90,6 +90,11 @@ static struct target_fabric_tpg_attribute _fabric##_tpg_##_name =    \
        _fabric##_tpg_store_##_name);
 
 
+#define TF_TPG_BASE_ATTR_RO(_fabric, _name)                            \
+static struct target_fabric_tpg_attribute _fabric##_tpg_##_name =      \
+       __CONFIGFS_EATTR_RO(_name,                                      \
+       _fabric##_tpg_show_##_name);
+
 CONFIGFS_EATTR_STRUCT(target_fabric_wwn, target_fabric_configfs);
 #define TF_WWN_ATTR(_fabric, _name, _mode)                             \
 static struct target_fabric_wwn_attribute _fabric##_wwn_##_name =      \