aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2011-12-05 17:44:01 -0500
committerJames Bottomley <JBottomley@Parallels.com>2011-12-15 01:57:40 -0500
commit0c70d84b794c9a99f7395b617ecaef34c00d82ec (patch)
tree135e42139e5404d73685c03ff040ce9557a000e8 /drivers/scsi
parentef8c98543c3ad75240599d4032f7e56b793740a9 (diff)
[SCSI] iscsi class: export pid of process that created
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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 96029e6d027f..c1b172b76689 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1030,6 +1030,7 @@ iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
1030 return NULL; 1030 return NULL;
1031 1031
1032 session->transport = transport; 1032 session->transport = transport;
1033 session->creator = -1;
1033 session->recovery_tmo = 120; 1034 session->recovery_tmo = 120;
1034 session->state = ISCSI_SESSION_FREE; 1035 session->state = ISCSI_SESSION_FREE;
1035 INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout); 1036 INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
@@ -1634,8 +1635,9 @@ EXPORT_SYMBOL_GPL(iscsi_session_event);
1634 1635
1635static int 1636static int
1636iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep, 1637iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
1637 struct iscsi_uevent *ev, uint32_t initial_cmdsn, 1638 struct iscsi_uevent *ev, pid_t pid,
1638 uint16_t cmds_max, uint16_t queue_depth) 1639 uint32_t initial_cmdsn, uint16_t cmds_max,
1640 uint16_t queue_depth)
1639{ 1641{
1640 struct iscsi_transport *transport = priv->iscsi_transport; 1642 struct iscsi_transport *transport = priv->iscsi_transport;
1641 struct iscsi_cls_session *session; 1643 struct iscsi_cls_session *session;
@@ -1646,6 +1648,7 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
1646 if (!session) 1648 if (!session)
1647 return -ENOMEM; 1649 return -ENOMEM;
1648 1650
1651 session->creator = pid;
1649 shost = iscsi_session_to_shost(session); 1652 shost = iscsi_session_to_shost(session);
1650 ev->r.c_session_ret.host_no = shost->host_no; 1653 ev->r.c_session_ret.host_no = shost->host_no;
1651 ev->r.c_session_ret.sid = session->sid; 1654 ev->r.c_session_ret.sid = session->sid;
@@ -1938,6 +1941,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
1938 switch (nlh->nlmsg_type) { 1941 switch (nlh->nlmsg_type) {
1939 case ISCSI_UEVENT_CREATE_SESSION: 1942 case ISCSI_UEVENT_CREATE_SESSION:
1940 err = iscsi_if_create_session(priv, ep, ev, 1943 err = iscsi_if_create_session(priv, ep, ev,
1944 NETLINK_CREDS(skb)->pid,
1941 ev->u.c_session.initial_cmdsn, 1945 ev->u.c_session.initial_cmdsn,
1942 ev->u.c_session.cmds_max, 1946 ev->u.c_session.cmds_max,
1943 ev->u.c_session.queue_depth); 1947 ev->u.c_session.queue_depth);
@@ -1950,6 +1954,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
1950 } 1954 }
1951 1955
1952 err = iscsi_if_create_session(priv, ep, ev, 1956 err = iscsi_if_create_session(priv, ep, ev,
1957 NETLINK_CREDS(skb)->pid,
1953 ev->u.c_bound_session.initial_cmdsn, 1958 ev->u.c_bound_session.initial_cmdsn,
1954 ev->u.c_bound_session.cmds_max, 1959 ev->u.c_bound_session.cmds_max,
1955 ev->u.c_bound_session.queue_depth); 1960 ev->u.c_bound_session.queue_depth);
@@ -2298,6 +2303,15 @@ show_priv_session_state(struct device *dev, struct device_attribute *attr,
2298} 2303}
2299static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state, 2304static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state,
2300 NULL); 2305 NULL);
2306static ssize_t
2307show_priv_session_creator(struct device *dev, struct device_attribute *attr,
2308 char *buf)
2309{
2310 struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
2311 return sprintf(buf, "%d\n", session->creator);
2312}
2313static ISCSI_CLASS_ATTR(priv_sess, creator, S_IRUGO, show_priv_session_creator,
2314 NULL);
2301 2315
2302#define iscsi_priv_session_attr_show(field, format) \ 2316#define iscsi_priv_session_attr_show(field, format) \
2303static ssize_t \ 2317static ssize_t \
@@ -2367,6 +2381,7 @@ static struct attribute *iscsi_session_attrs[] = {
2367 &dev_attr_sess_targetalias.attr, 2381 &dev_attr_sess_targetalias.attr,
2368 &dev_attr_priv_sess_recovery_tmo.attr, 2382 &dev_attr_priv_sess_recovery_tmo.attr,
2369 &dev_attr_priv_sess_state.attr, 2383 &dev_attr_priv_sess_state.attr,
2384 &dev_attr_priv_sess_creator.attr,
2370 NULL, 2385 NULL,
2371}; 2386};
2372 2387
@@ -2424,6 +2439,8 @@ static mode_t iscsi_session_attr_is_visible(struct kobject *kobj,
2424 return S_IRUGO | S_IWUSR; 2439 return S_IRUGO | S_IWUSR;
2425 else if (attr == &dev_attr_priv_sess_state.attr) 2440 else if (attr == &dev_attr_priv_sess_state.attr)
2426 return S_IRUGO; 2441 return S_IRUGO;
2442 else if (attr == &dev_attr_priv_sess_creator.attr)
2443 return S_IRUGO;
2427 else { 2444 else {
2428 WARN_ONCE(1, "Invalid session attr"); 2445 WARN_ONCE(1, "Invalid session attr");
2429 return 0; 2446 return 0;