Skip to content

Commit

Permalink
[SCSI] iscsi class: export pid of process that created
Browse files Browse the repository at this point in the history
There could be multiple userspace entities creating/destroying/
recoverying sessions and also the kernel's iscsi drivers could
be doing this too. If the userspace apps do try to manage the kernel
ones it can get the driver/fw out of sync and cause the user to
loose the root disk, oopses or ping ponging becasue userspace
wants to do one thing but the kernel manager thought we
are trying to do another.

This patch fixes the problem by just exporting the pid of
the entity that created the session. Userspace programs like
iscsid, iscsiadm, iscsistart, qlogic's tools, etc, can then
figure out which sessions they own and only manage them.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Mike Christie authored and James Bottomley committed Dec 15, 2011
1 parent ef8c985 commit 0c70d84
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
21 changes: 19 additions & 2 deletions drivers/scsi/scsi_transport_iscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,7 @@ iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
return NULL;

session->transport = transport;
session->creator = -1;
session->recovery_tmo = 120;
session->state = ISCSI_SESSION_FREE;
INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
Expand Down Expand Up @@ -1634,8 +1635,9 @@ EXPORT_SYMBOL_GPL(iscsi_session_event);

static int
iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
struct iscsi_uevent *ev, uint32_t initial_cmdsn,
uint16_t cmds_max, uint16_t queue_depth)
struct iscsi_uevent *ev, pid_t pid,
uint32_t initial_cmdsn, uint16_t cmds_max,
uint16_t queue_depth)
{
struct iscsi_transport *transport = priv->iscsi_transport;
struct iscsi_cls_session *session;
Expand All @@ -1646,6 +1648,7 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
if (!session)
return -ENOMEM;

session->creator = pid;
shost = iscsi_session_to_shost(session);
ev->r.c_session_ret.host_no = shost->host_no;
ev->r.c_session_ret.sid = session->sid;
Expand Down Expand Up @@ -1938,6 +1941,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_CREATE_SESSION:
err = iscsi_if_create_session(priv, ep, ev,
NETLINK_CREDS(skb)->pid,
ev->u.c_session.initial_cmdsn,
ev->u.c_session.cmds_max,
ev->u.c_session.queue_depth);
Expand All @@ -1950,6 +1954,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
}

err = iscsi_if_create_session(priv, ep, ev,
NETLINK_CREDS(skb)->pid,
ev->u.c_bound_session.initial_cmdsn,
ev->u.c_bound_session.cmds_max,
ev->u.c_bound_session.queue_depth);
Expand Down Expand Up @@ -2298,6 +2303,15 @@ show_priv_session_state(struct device *dev, struct device_attribute *attr,
}
static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state,
NULL);
static ssize_t
show_priv_session_creator(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
return sprintf(buf, "%d\n", session->creator);
}
static ISCSI_CLASS_ATTR(priv_sess, creator, S_IRUGO, show_priv_session_creator,
NULL);

#define iscsi_priv_session_attr_show(field, format) \
static ssize_t \
Expand Down Expand Up @@ -2367,6 +2381,7 @@ static struct attribute *iscsi_session_attrs[] = {
&dev_attr_sess_targetalias.attr,
&dev_attr_priv_sess_recovery_tmo.attr,
&dev_attr_priv_sess_state.attr,
&dev_attr_priv_sess_creator.attr,
NULL,
};

Expand Down Expand Up @@ -2424,6 +2439,8 @@ static mode_t iscsi_session_attr_is_visible(struct kobject *kobj,
return S_IRUGO | S_IWUSR;
else if (attr == &dev_attr_priv_sess_state.attr)
return S_IRUGO;
else if (attr == &dev_attr_priv_sess_creator.attr)
return S_IRUGO;
else {
WARN_ONCE(1, "Invalid session attr");
return 0;
Expand Down
5 changes: 5 additions & 0 deletions include/scsi/scsi_transport_iscsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ struct iscsi_cls_session {
unsigned int target_id;
bool ida_used;

/*
* pid of userspace process that created session or -1 if
* created by the kernel.
*/
pid_t creator;
int state;
int sid; /* session id */
void *dd_data; /* LLD private data */
Expand Down

0 comments on commit 0c70d84

Please sign in to comment.