scst, iscsi-scst: Add thread_pid attribute

For SCST devices with a short name determining which SCST command
threads serve a given LUN requires an (expensive) walk of the
process table. For SCST devices with a long name it is not possible
to determine unambiguously which command threads serve a given
LUN. Hence add a thread_pid sysfs attribute that makes it easy to
figure out which command threads serve a LUN.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5851 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2014-10-17 02:35:01 +00:00
parent a17fde27f9
commit 827e5b1461
5 changed files with 73 additions and 2 deletions
+7 -2
View File
@@ -332,8 +332,13 @@ Each target subdirectory contains the following entries:
- tid - TID of this target.
Subdirectory "sessions" contains one subdirectory for each connected
session with name equal to name of the connected initiator.
The "sessions" subdirectory contains the following attribute:
- thread_pid - the process identifiers (PIDs) of the iscsird and iscsiwr
threads that process SCSI commands associated with this session.
Additionally, the "sessions" subdirectory contains one subdirectory for each
connected session with name equal to name of the connected initiator.
Each session subdirectory contains the following entries:
+32
View File
@@ -560,6 +560,37 @@ static ssize_t iscsi_sess_reinstating_show(struct kobject *kobj,
static struct kobj_attribute iscsi_sess_attr_reinstating =
__ATTR(reinstating, S_IRUGO, iscsi_sess_reinstating_show, NULL);
static ssize_t iscsi_sess_thread_pid_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct scst_session *scst_sess = container_of(kobj, struct scst_session,
sess_kobj);
struct iscsi_session *sess = scst_sess_get_tgt_priv(scst_sess);
struct iscsi_thread_pool *thr_pool = sess->sess_thr_pool;
struct iscsi_thread *t;
int res = -ENOENT;
if (!thr_pool)
goto out;
res = 0;
mutex_lock(&thr_pool->tp_mutex);
list_for_each_entry(t, &thr_pool->threads_list, threads_list_entry)
res += scnprintf(buf + res, PAGE_SIZE - res, "%d%s",
task_pid_vnr(t->thr),
list_is_last(&t->threads_list_entry,
&thr_pool->threads_list) ?
"\n" : " ");
mutex_unlock(&thr_pool->tp_mutex);
out:
return res;
}
static struct kobj_attribute iscsi_sess_thread_pid =
__ATTR(thread_pid, S_IRUGO, iscsi_sess_thread_pid_show, NULL);
const struct attribute *iscsi_sess_attrs[] = {
&iscsi_sess_attr_initial_r2t.attr,
&iscsi_sess_attr_immediate_data.attr,
@@ -572,6 +603,7 @@ const struct attribute *iscsi_sess_attrs[] = {
&iscsi_sess_attr_data_digest.attr,
&iscsi_attr_sess_sid.attr,
&iscsi_sess_attr_reinstating.attr,
&iscsi_sess_thread_pid.attr,
NULL,
};
+4
View File
@@ -695,6 +695,10 @@ Each sessions/<sess>/lun<X> subdirectory contains the following entries:
- active_commands - contains number of active, i.e. not yet or being
executed, SCSI commands for lun<X> in session <sess>.
- thread_pid - contains a single line with all the process identifiers
(PIDs) of the kernel threads that process SCSI commands intended for
lun<X> in session <sess>.
Access and devices visibility management (LUN masking)
------------------------------------------------------
+4
View File
@@ -557,6 +557,10 @@ Each sessions/<sess>/lun<X> subdirectory contains the following entries:
- active_commands - contains number of active, i.e. not yet or being
executed, SCSI commands for lun<X> in session <sess>.
- thread_pid - contains a single line with all the process identifiers
(PIDs) of the kernel threads that process SCSI commands intended for
lun<X> in session <sess>.
Access and devices visibility management (LUN masking)
------------------------------------------------------
+26
View File
@@ -3506,6 +3506,31 @@ static struct kobj_attribute tgt_dev_latency_attr =
#endif /* CONFIG_SCST_MEASURE_LATENCY */
static ssize_t scst_tgt_dev_thread_pid_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buffer)
{
struct scst_tgt_dev *tgt_dev =
container_of(kobj, struct scst_tgt_dev, tgt_dev_kobj);
struct scst_cmd_threads *cmd_threads = tgt_dev->active_cmd_threads;
struct scst_cmd_thread_t *t;
int res = 0;
spin_lock(&cmd_threads->thr_lock);
list_for_each_entry(t, &cmd_threads->threads_list, thread_list_entry)
res += scnprintf(buffer + res, PAGE_SIZE - res, "%d%s",
task_pid_vnr(t->cmd_thread),
list_is_last(&t->thread_list_entry,
&cmd_threads->threads_list) ?
"\n" : " ");
spin_unlock(&cmd_threads->thr_lock);
return res;
}
static struct kobj_attribute tgt_dev_thread_pid_attr =
__ATTR(thread_pid, S_IRUGO, scst_tgt_dev_thread_pid_show, NULL);
static ssize_t scst_tgt_dev_active_commands_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -3524,6 +3549,7 @@ static struct kobj_attribute tgt_dev_active_commands_attr =
scst_tgt_dev_active_commands_show, NULL);
static struct attribute *scst_tgt_dev_attrs[] = {
&tgt_dev_thread_pid_attr.attr,
&tgt_dev_active_commands_attr.attr,
#ifdef CONFIG_SCST_MEASURE_LATENCY
&tgt_dev_latency_attr.attr,