From: Alex Elder <elder@inktank.com>
To: Sage Weil <sage@inktank.com>
Cc: ceph-devel@vger.kernel.org
Subject: Re: [PATCH 09/13] libceph: start tracking connection socket state
Date: Fri, 01 Jun 2012 07:15:31 -0500 [thread overview]
Message-ID: <4FC8B263.4060703@inktank.com> (raw)
In-Reply-To: <Pine.LNX.4.64.1205312127490.2166@cobra.newdream.net>
On 05/31/2012 11:28 PM, Sage Weil wrote:
> On Wed, 30 May 2012, Alex Elder wrote:
>> Start explicitly keeping track of the state of a ceph connection's
>> socket, separate from the state of the connection itself. Create
>> placeholder functions to encapsulate the state transitions.
>>
>> --------
>> | NEW* | transient initial state
>> --------
>> | con_sock_state_init()
>> v
>> ----------
>> | CLOSED | initialized, but no socket (and no
>> ---------- TCP connection)
>> ^ \
>> | \ con_sock_state_connecting()
>> | ----------------------
>> | \
>> + con_sock_state_closed() \
>> |\ \
>> | \ \
>> | ----------- \
>> | | CLOSING | socket event; \
>> | ----------- await close \
>> | ^ |
>> | | |
>> | + con_sock_state_closing() |
>> | / \ |
>> | / --------------- |
>> | / \ v
>> | / --------------
>> | / -----------------| CONNECTING | socket created, TCP
>> | | / -------------- connect initiated
>> | | | con_sock_state_connected()
>> | | v
>> -------------
>> | CONNECTED | TCP connection established
>> -------------
>
> Can we put this beautiful pictures in the header next to the states?
I can be quite the ASCII artist. Yes, I will add this, when I update
the state definitions with better names and numbers.
-Alex
> Reviewed-by: Sage Weil<sage@inktank.com>
>
>>
>> Make the socket state an atomic variable, reinforcing that it's a
>> distinct transtion with no possible "intermediate/both" states.
>> This is almost certainly overkill at this point, though the
>> transitions into CONNECTED and CLOSING state do get called via
>> socket callback (the rest of the transitions occur with the
>> connection mutex held). We can back out the atomicity later.
>>
>> Signed-off-by: Alex Elder<elder@inktank.com>
>> ---
>> include/linux/ceph/messenger.h | 8 ++++-
>> net/ceph/messenger.c | 63
>> ++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 69 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h
>> index 920235e..5e852f4 100644
>> --- a/include/linux/ceph/messenger.h
>> +++ b/include/linux/ceph/messenger.h
>> @@ -137,14 +137,18 @@ struct ceph_connection {
>> const struct ceph_connection_operations *ops;
>>
>> struct ceph_messenger *msgr;
>> +
>> + atomic_t sock_state;
>> struct socket *sock;
>> + struct ceph_entity_addr peer_addr; /* peer address */
>> + struct ceph_entity_addr peer_addr_for_me;
>> +
>> unsigned long flags;
>> unsigned long state;
>> const char *error_msg; /* error message, if any */
>>
>> - struct ceph_entity_addr peer_addr; /* peer address */
>> struct ceph_entity_name peer_name; /* peer name */
>> - struct ceph_entity_addr peer_addr_for_me;
>> +
>> unsigned peer_features;
>> u32 connect_seq; /* identify the most recent connection
>> attempt for this connection, client */
>> diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
>> index 29055df..7e11b07 100644
>> --- a/net/ceph/messenger.c
>> +++ b/net/ceph/messenger.c
>> @@ -29,6 +29,14 @@
>> * the sender.
>> */
>>
>> +/* State values for ceph_connection->sock_state; NEW is assumed to be 0 */
>> +
>> +#define CON_SOCK_STATE_NEW 0 /* -> CLOSED */
>> +#define CON_SOCK_STATE_CLOSED 1 /* -> CONNECTING */
>> +#define CON_SOCK_STATE_CONNECTING 2 /* -> CONNECTED or -> CLOSING
>> */
>> +#define CON_SOCK_STATE_CONNECTED 3 /* -> CLOSING or -> CLOSED */
>> +#define CON_SOCK_STATE_CLOSING 4 /* -> CLOSED */
>> +
>> /* static tag bytes (protocol control messages) */
>> static char tag_msg = CEPH_MSGR_TAG_MSG;
>> static char tag_ack = CEPH_MSGR_TAG_ACK;
>> @@ -147,6 +155,54 @@ void ceph_msgr_flush(void)
>> }
>> EXPORT_SYMBOL(ceph_msgr_flush);
>>
>> +/* Connection socket state transition functions */
>> +
>> +static void con_sock_state_init(struct ceph_connection *con)
>> +{
>> + int old_state;
>> +
>> + old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
>> + if (WARN_ON(old_state != CON_SOCK_STATE_NEW))
>> + printk("%s: unexpected old state %d\n", __func__, old_state);
>> +}
>> +
>> +static void con_sock_state_connecting(struct ceph_connection *con)
>> +{
>> + int old_state;
>> +
>> + old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTING);
>> + if (WARN_ON(old_state != CON_SOCK_STATE_CLOSED))
>> + printk("%s: unexpected old state %d\n", __func__, old_state);
>> +}
>> +
>> +static void con_sock_state_connected(struct ceph_connection *con)
>> +{
>> + int old_state;
>> +
>> + old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTED);
>> + if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTING))
>> + printk("%s: unexpected old state %d\n", __func__, old_state);
>> +}
>> +
>> +static void con_sock_state_closing(struct ceph_connection *con)
>> +{
>> + int old_state;
>> +
>> + old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSING);
>> + if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTING&&
>> + old_state != CON_SOCK_STATE_CONNECTED))
>> + printk("%s: unexpected old state %d\n", __func__, old_state);
>> +}
>> +
>> +static void con_sock_state_closed(struct ceph_connection *con)
>> +{
>> + int old_state;
>> +
>> + old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
>> + if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTED&&
>> + old_state != CON_SOCK_STATE_CLOSING))
>> + printk("%s: unexpected old state %d\n", __func__, old_state);
>> +}
>>
>> /*
>> * socket callback functions
>> @@ -203,6 +259,7 @@ static void ceph_sock_state_change(struct sock *sk)
>> dout("%s TCP_CLOSE\n", __func__);
>> case TCP_CLOSE_WAIT:
>> dout("%s TCP_CLOSE_WAIT\n", __func__);
>> + con_sock_state_closing(con);
>> if (test_and_set_bit(SOCK_CLOSED,&con->flags) == 0) {
>> if (test_bit(CONNECTING,&con->state))
>> con->error_msg = "connection failed";
>> @@ -213,6 +270,7 @@ static void ceph_sock_state_change(struct sock *sk)
>> break;
>> case TCP_ESTABLISHED:
>> dout("%s TCP_ESTABLISHED\n", __func__);
>> + con_sock_state_connected(con);
>> queue_con(con);
>> break;
>> default: /* Everything else is uninteresting */
>> @@ -277,6 +335,7 @@ static int ceph_tcp_connect(struct ceph_connection *con)
>> return ret;
>> }
>> con->sock = sock;
>> + con_sock_state_connecting(con);
>>
>> return 0;
>> }
>> @@ -341,6 +400,7 @@ static int con_close_socket(struct ceph_connection *con)
>> rc = con->sock->ops->shutdown(con->sock, SHUT_RDWR);
>> sock_release(con->sock);
>> con->sock = NULL;
>> + con_sock_state_closed(con);
>> return rc;
>> }
>>
>> @@ -460,6 +520,9 @@ void ceph_con_init(struct ceph_messenger *msgr, struct
>> ceph_connection *con)
>> memset(con, 0, sizeof(*con));
>> atomic_set(&con->nref, 1);
>> con->msgr = msgr;
>> +
>> + con_sock_state_init(con);
>> +
>> mutex_init(&con->mutex);
>> INIT_LIST_HEAD(&con->out_queue);
>> INIT_LIST_HEAD(&con->out_sent);
>> --
>> 1.7.5.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>>
>
next prev parent reply other threads:[~2012-06-01 12:15 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-30 19:24 [PATCH 00/13] libceph: cleanups preparing for state cleanup Alex Elder
2012-05-30 19:34 ` [PATCH 01/13] libceph: eliminate connection state "DEAD" Alex Elder
2012-05-31 16:20 ` Yehuda Sadeh
2012-05-30 19:34 ` [PATCH 02/13] libceph: kill bad_proto ceph connection op Alex Elder
2012-05-31 16:30 ` Yehuda Sadeh
2012-05-30 19:34 ` [PATCH 03/13] libceph: delete useless SOCK_CLOSED manipulations Alex Elder
2012-06-01 18:47 ` Alex Elder
2012-05-30 19:34 ` [PATCH 04/13] libceph: rename socket callbacks Alex Elder
2012-05-31 16:33 ` Yehuda Sadeh Weinraub
2012-06-01 4:02 ` Sage Weil
2012-05-30 19:34 ` [PATCH 05/13] libceph: rename kvec_reset and kvec_add functions Alex Elder
2012-05-31 16:34 ` Yehuda Sadeh
2012-06-01 4:02 ` Sage Weil
2012-05-30 19:34 ` [PATCH 06/13] libceph: embed ceph messenger structure in ceph_client Alex Elder
2012-05-31 16:44 ` Yehuda Sadeh
2012-06-01 4:04 ` Sage Weil
2012-05-30 19:34 ` [PATCH 07/13] libceph: embed ceph connection structure in mon_client Alex Elder
2012-06-01 4:24 ` Sage Weil
2012-06-01 12:12 ` Alex Elder
2012-06-01 13:30 ` Alex Elder
2012-06-01 16:20 ` Sage Weil
2012-06-01 16:32 ` Alex Elder
2012-06-01 16:39 ` Sage Weil
2012-06-01 17:09 ` Alex Elder
2012-06-01 17:10 ` Sage Weil
2012-05-30 19:35 ` [PATCH 08/13] libceph: start separating connection flags from state Alex Elder
2012-06-01 4:25 ` Sage Weil
2012-06-01 12:13 ` Alex Elder
2012-05-30 19:35 ` [PATCH 09/13] libceph: start tracking connection socket state Alex Elder
2012-06-01 4:28 ` Sage Weil
2012-06-01 12:15 ` Alex Elder [this message]
2012-06-12 4:52 ` Yan, Zheng
2012-06-12 5:00 ` Sage Weil
2012-06-12 5:02 ` Yan, Zheng
2012-06-12 16:58 ` Alex Elder
2012-06-13 1:50 ` Yan, Zheng
2012-05-30 19:35 ` [PATCH 10/13] libceph: provide osd number when creating osd Alex Elder
2012-06-01 4:29 ` Sage Weil
2012-05-30 19:35 ` [PATCH 11/13] libceph: init monitor connection when opening Alex Elder
2012-06-01 4:30 ` Sage Weil
2012-05-30 19:35 ` [PATCH 12/13] libceph: fully initialize connection in con_init() Alex Elder
2012-06-01 4:31 ` Sage Weil
2012-05-30 19:35 ` [PATCH 13/13] libceph: set CLOSED state bit in con_init Alex Elder
2012-06-01 4:32 ` Sage Weil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FC8B263.4060703@inktank.com \
--to=elder@inktank.com \
--cc=ceph-devel@vger.kernel.org \
--cc=sage@inktank.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox