diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-03-06 23:34:32 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-03-07 00:24:53 -0500 |
commit | f8e471f9eb9068bf5ac8c6a04da74329a442f75a (patch) | |
tree | 043f0d1b6029db33812fccfad085676806a96872 | |
parent | d4c5dcacfaffb7493d161d5cd0fbb7b1190b7bd5 (diff) |
target: Add target_show_dynamic_sessions attribute helper
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>
-rw-r--r-- | drivers/target/target_core_transport.c | 24 | ||||
-rw-r--r-- | include/target/target_core_fabric.h | 1 | ||||
-rw-r--r-- | include/target/target_core_fabric_configfs.h | 5 |
3 files changed, 30 insertions, 0 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 0adc0f650213..e06c136ff839 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -404,6 +404,30 @@ void target_put_session(struct se_session *se_sess) | |||
404 | } | 404 | } |
405 | EXPORT_SYMBOL(target_put_session); | 405 | EXPORT_SYMBOL(target_put_session); |
406 | 406 | ||
407 | ssize_t target_show_dynamic_sessions(struct se_portal_group *se_tpg, char *page) | ||
408 | { | ||
409 | struct se_session *se_sess; | ||
410 | ssize_t len = 0; | ||
411 | |||
412 | spin_lock_bh(&se_tpg->session_lock); | ||
413 | list_for_each_entry(se_sess, &se_tpg->tpg_sess_list, sess_list) { | ||
414 | if (!se_sess->se_node_acl) | ||
415 | continue; | ||
416 | if (!se_sess->se_node_acl->dynamic_node_acl) | ||
417 | continue; | ||
418 | if (strlen(se_sess->se_node_acl->initiatorname) + 1 + len > PAGE_SIZE) | ||
419 | break; | ||
420 | |||
421 | len += snprintf(page + len, PAGE_SIZE - len, "%s\n", | ||
422 | se_sess->se_node_acl->initiatorname); | ||
423 | len += 1; /* Include NULL terminator */ | ||
424 | } | ||
425 | spin_unlock_bh(&se_tpg->session_lock); | ||
426 | |||
427 | return len; | ||
428 | } | ||
429 | EXPORT_SYMBOL(target_show_dynamic_sessions); | ||
430 | |||
407 | static void target_complete_nacl(struct kref *kref) | 431 | static void target_complete_nacl(struct kref *kref) |
408 | { | 432 | { |
409 | struct se_node_acl *nacl = container_of(kref, | 433 | struct se_node_acl *nacl = container_of(kref, |
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 22a4e98eec80..2f4a2505db4c 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h | |||
@@ -95,6 +95,7 @@ void transport_register_session(struct se_portal_group *, | |||
95 | struct se_node_acl *, struct se_session *, void *); | 95 | struct se_node_acl *, struct se_session *, void *); |
96 | void target_get_session(struct se_session *); | 96 | void target_get_session(struct se_session *); |
97 | void target_put_session(struct se_session *); | 97 | void target_put_session(struct se_session *); |
98 | ssize_t target_show_dynamic_sessions(struct se_portal_group *, char *); | ||
98 | void transport_free_session(struct se_session *); | 99 | void transport_free_session(struct se_session *); |
99 | void target_put_nacl(struct se_node_acl *); | 100 | void target_put_nacl(struct se_node_acl *); |
100 | void transport_deregister_session_configfs(struct se_session *); | 101 | void transport_deregister_session_configfs(struct se_session *); |
diff --git a/include/target/target_core_fabric_configfs.h b/include/target/target_core_fabric_configfs.h index b32a14905cfa..7a0649c09e79 100644 --- a/include/target/target_core_fabric_configfs.h +++ b/include/target/target_core_fabric_configfs.h | |||
@@ -90,6 +90,11 @@ static struct target_fabric_tpg_attribute _fabric##_tpg_##_name = \ | |||
90 | _fabric##_tpg_store_##_name); | 90 | _fabric##_tpg_store_##_name); |
91 | 91 | ||
92 | 92 | ||
93 | #define TF_TPG_BASE_ATTR_RO(_fabric, _name) \ | ||
94 | static struct target_fabric_tpg_attribute _fabric##_tpg_##_name = \ | ||
95 | __CONFIGFS_EATTR_RO(_name, \ | ||
96 | _fabric##_tpg_show_##_name); | ||
97 | |||
93 | CONFIGFS_EATTR_STRUCT(target_fabric_wwn, target_fabric_configfs); | 98 | CONFIGFS_EATTR_STRUCT(target_fabric_wwn, target_fabric_configfs); |
94 | #define TF_WWN_ATTR(_fabric, _name, _mode) \ | 99 | #define TF_WWN_ATTR(_fabric, _name, _mode) \ |
95 | static struct target_fabric_wwn_attribute _fabric##_wwn_##_name = \ | 100 | static struct target_fabric_wwn_attribute _fabric##_wwn_##_name = \ |