CEPH filesystem development
 help / color / mirror / Atom feed
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
>>
>>
>


  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