[stgt] help tgt segfault
FUJITA Tomonori
fujita.tomonori at lab.ntt.co.jp
Tue Dec 23 12:25:14 CET 2008
On Mon, 22 Dec 2008 21:52:26 +0100
Tomasz Chmielewski <mangoo at wpkg.org> wrote:
> FUJITA Tomonori schrieb:
>
> > Looks like tgtd works fine. Let me know the results later. If it works
> > fine, I'll clean up and merge the patch.
>
> I was running the tests for about 8 hours and everything worked fine.
>
> No more I/O errors from open-iscsi side as well.
Thanks a lot,
I've merged the following patch:
=
From: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
Subject: [PATCH] iscsi: fix session reinstatement ref-count mess-up
login_security_done calls conn_close() in case of session
reinstatement. if conn_close() was already called against a
connection, it messes up the connection ref-counting. conn_close()
must be called only once for a connection.
This patch introduces the closed to struct iscsi_connection to avoid
multiple calls of conn_close but it should be a new state.
Thanks to Tomasz Chmielewski <mangoo at wpkg.org> for helping me fix the
bugs.
Reported-by: Tomasz Chmielewski <mangoo at wpkg.org>
Tested-by: Tomasz Chmielewski <mangoo at wpkg.org>
Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
---
usr/iscsi/conn.c | 17 +++++++++++++++--
usr/iscsi/iscsi_tcp.c | 2 +-
usr/iscsi/iscsid.h | 4 ++++
usr/tgtd.c | 6 +++++-
4 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/usr/iscsi/conn.c b/usr/iscsi/conn.c
index c205397..e4b431e 100644
--- a/usr/iscsi/conn.c
+++ b/usr/iscsi/conn.c
@@ -82,15 +82,28 @@ void conn_exit(struct iscsi_connection *conn)
void conn_close(struct iscsi_connection *conn)
{
struct iscsi_task *task, *tmp;
+ int ret;
- conn->tp->ep_close(conn);
+ if (conn->closed) {
+ eprintf("already closed %p %u\n", conn, conn->refcount);
+ return;
+ }
+
+ conn->closed = 1;
- eprintf("connection closed %p %u\n", conn, conn->refcount);
+ ret = conn->tp->ep_close(conn);
+ if (ret)
+ eprintf("failed to close a connection, %p %u %s\n",
+ conn, conn->refcount, strerror(errno));
+ else
+ eprintf("connection closed, %p %u\n", conn, conn->refcount);
/* may not have been in FFP yet */
if (!conn->session)
goto done;
+ eprintf("sesson %p %d\n", conn->session, conn->session->refcount);
+
/*
* We just closed the ep so we are not going to send/recv anything.
* Just free these up since they are not going to complete.
diff --git a/usr/iscsi/iscsi_tcp.c b/usr/iscsi/iscsi_tcp.c
index 2320b3e..edc4e86 100644
--- a/usr/iscsi/iscsi_tcp.c
+++ b/usr/iscsi/iscsi_tcp.c
@@ -164,8 +164,8 @@ static void iscsi_tcp_event_handler(int fd, int events, void *data)
iscsi_tx_handler(conn);
if (conn->state == STATE_CLOSE) {
+ dprintf("connection closed %p\n", conn);
conn_close(conn);
- dprintf("connection closed\n");
}
}
diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
index c03263a..4a8deb9 100644
--- a/usr/iscsi/iscsid.h
+++ b/usr/iscsi/iscsid.h
@@ -130,6 +130,10 @@ struct iscsi_task {
struct iscsi_connection {
int state;
+
+ /* should be a new state */
+ int closed;
+
int rx_iostate;
int tx_iostate;
int refcount;
diff --git a/usr/tgtd.c b/usr/tgtd.c
index 758e7d5..1a3cc02 100644
--- a/usr/tgtd.c
+++ b/usr/tgtd.c
@@ -137,6 +137,7 @@ static struct event_data *tgt_event_lookup(int fd)
void tgt_event_del(int fd)
{
struct event_data *tev;
+ int ret;
tev = tgt_event_lookup(fd);
if (!tev) {
@@ -144,7 +145,10 @@ void tgt_event_del(int fd)
return;
}
- epoll_ctl(ep_fd, EPOLL_CTL_DEL, fd, NULL);
+ ret = epoll_ctl(ep_fd, EPOLL_CTL_DEL, fd, NULL);
+ if (ret < 0)
+ eprintf("fail to remove epoll event, %s\n", strerror(errno));
+
list_del(&tev->e_list);
free(tev);
}
--
1.5.6.5
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list