History

libceph: start tracking connection socket state

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 ------------- 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.

Alex Elder committed 14 years ago

Commit ce2c8901 parent 928443c2 files · +70 −2Browse files

Unified · Split

2 files
  1. include/linux/ceph/messenger.h +6 −2
  2. net/ceph/messenger.c +64 −0
include/linux/ceph/messenger.h+6−2
@@ -137,14 +137,18 @@ struct ceph_connection { · 136 unmodified lines
137137 const struct ceph_connection_operations *ops;
138138
139139 struct ceph_messenger *msgr;
140+
141+ atomic_t sock_state;
140142 struct socket *sock;
143+ struct ceph_entity_addr peer_addr; /* peer address */
144+ struct ceph_entity_addr peer_addr_for_me;
145+
141146 unsigned long flags;
142147 unsigned long state;
143148 const char *error_msg; /* error message, if any */
144149
145− struct ceph_entity_addr peer_addr; /* peer address */
146150 struct ceph_entity_name peer_name; /* peer name */
147− struct ceph_entity_addr peer_addr_for_me;
151+
148152 unsigned peer_features;
149153 u32 connect_seq; /* identify the most recent connection
150154 attempt for this connection, client */
net/ceph/messenger.c+64−0
@@ -29,6 +29,14 @@ · 28 unmodified lines
2929 * the sender.
3030 */
3131
32+/* State values for ceph_connection->sock_state; NEW is assumed to be 0 */
33+
34+#define CON_SOCK_STATE_NEW 0 /* -> CLOSED */
35+#define CON_SOCK_STATE_CLOSED 1 /* -> CONNECTING */
36+#define CON_SOCK_STATE_CONNECTING 2 /* -> CONNECTED or -> CLOSING */
37+#define CON_SOCK_STATE_CONNECTED 3 /* -> CLOSING or -> CLOSED */
38+#define CON_SOCK_STATE_CLOSING 4 /* -> CLOSED */
39+
3240 /* static tag bytes (protocol control messages) */
3341 static char tag_msg = CEPH_MSGR_TAG_MSG;
3442 static char tag_ack = CEPH_MSGR_TAG_ACK;
@@ -147,6 +155,55 @@ void ceph_msgr_flush(void) · 112 unmodified lines
147155 }
148156 EXPORT_SYMBOL(ceph_msgr_flush);
149157
158+/* Connection socket state transition functions */
159+
160+static void con_sock_state_init(struct ceph_connection *con)
161+{
162+ int old_state;
163+
164+ old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
165+ if (WARN_ON(old_state != CON_SOCK_STATE_NEW))
166+ printk("%s: unexpected old state %d\n", __func__, old_state);
167+}
168+
169+static void con_sock_state_connecting(struct ceph_connection *con)
170+{
171+ int old_state;
172+
173+ old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTING);
174+ if (WARN_ON(old_state != CON_SOCK_STATE_CLOSED))
175+ printk("%s: unexpected old state %d\n", __func__, old_state);
176+}
177+
178+static void con_sock_state_connected(struct ceph_connection *con)
179+{
180+ int old_state;
181+
182+ old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTED);
183+ if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTING))
184+ printk("%s: unexpected old state %d\n", __func__, old_state);
185+}
186+
187+static void con_sock_state_closing(struct ceph_connection *con)
188+{
189+ int old_state;
190+
191+ old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSING);
192+ if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTING &&
193+ old_state != CON_SOCK_STATE_CONNECTED &&
194+ old_state != CON_SOCK_STATE_CLOSING))
195+ printk("%s: unexpected old state %d\n", __func__, old_state);
196+}
197+
198+static void con_sock_state_closed(struct ceph_connection *con)
199+{
200+ int old_state;
201+
202+ old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
203+ if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTED &&
204+ old_state != CON_SOCK_STATE_CLOSING))
205+ printk("%s: unexpected old state %d\n", __func__, old_state);
206+}
150207
151208 /*
152209 * socket callback functions
@@ -203,6 +260,7 @@ static void ceph_sock_state_change(struct sock *sk) · 50 unmodified lines
203260 dout("%s TCP_CLOSE\n", __func__);
204261 case TCP_CLOSE_WAIT:
205262 dout("%s TCP_CLOSE_WAIT\n", __func__);
263+ con_sock_state_closing(con);
206264 if (test_and_set_bit(SOCK_CLOSED, &con->flags) == 0) {
207265 if (test_bit(CONNECTING, &con->state))
208266 con->error_msg = "connection failed";
@@ -213,6 +271,7 @@ static void ceph_sock_state_change(struct sock *sk) · 4 unmodified lines
213271 break;
214272 case TCP_ESTABLISHED:
215273 dout("%s TCP_ESTABLISHED\n", __func__);
274+ con_sock_state_connected(con);
216275 queue_con(con);
217276 break;
218277 default: /* Everything else is uninteresting */
@@ -277,6 +336,7 @@ static int ceph_tcp_connect(struct ceph_connection *con) · 58 unmodified lines
277336 return ret;
278337 }
279338 con->sock = sock;
339+ con_sock_state_connecting(con);
280340
281341 return 0;
282342 }
@@ -343,6 +403,7 @@ static int con_close_socket(struct ceph_connection *con) · 60 unmodified lines
343403 sock_release(con->sock);
344404 con->sock = NULL;
345405 clear_bit(SOCK_CLOSED, &con->state);
406+ con_sock_state_closed(con);
346407 return rc;
347408 }
348409
@@ -462,6 +523,9 @@ void ceph_con_init(struct ceph_messenger *msgr, struct ceph_connection *con) · 113 unmodified lines
462523 memset(con, 0, sizeof(*con));
463524 atomic_set(&con->nref, 1);
464525 con->msgr = msgr;
526+
527+ con_sock_state_init(con);
528+
465529 mutex_init(&con->mutex);
466530 INIT_LIST_HEAD(&con->out_queue);
467531 INIT_LIST_HEAD(&con->out_sent);