aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2016-01-20 11:50:31 -0500
committerIlya Dryomov <idryomov@gmail.com>2016-03-25 13:51:38 -0400
commit0e04dc26cc594d31ee6b1382b452b6bc83b57937 (patch)
treebc0ee4c6236224b44f9e388672e2e0a1cbfe8253 /net
parent82dcabad750a36a2b749889bc89c5a3188775b2e (diff)
libceph: pick a different monitor when reconnecting
Don't try to reconnect to the same monitor when we fail to establish a session within a timeout or it's lost. For that, pick_new_mon() needs to see the old value of cur_mon, so don't clear it in __close_session() - all calls to __close_session() but one are followed by __open_session() anyway. __open_session() is only called when a new session needs to be established, so the "already open?" branch, which is now in the way, is simply dropped. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'net')
-rw-r--r--net/ceph/mon_client.c85
1 files changed, 57 insertions, 28 deletions
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 89029916315c..accfded53bae 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -122,45 +122,74 @@ static void __close_session(struct ceph_mon_client *monc)
122 ceph_msg_revoke(monc->m_subscribe); 122 ceph_msg_revoke(monc->m_subscribe);
123 ceph_msg_revoke_incoming(monc->m_subscribe_ack); 123 ceph_msg_revoke_incoming(monc->m_subscribe_ack);
124 ceph_con_close(&monc->con); 124 ceph_con_close(&monc->con);
125 monc->cur_mon = -1; 125
126 monc->pending_auth = 0; 126 monc->pending_auth = 0;
127 ceph_auth_reset(monc->auth); 127 ceph_auth_reset(monc->auth);
128} 128}
129 129
130/* 130/*
131 * Open a session with a (new) monitor. 131 * Pick a new monitor at random and set cur_mon. If we are repicking
132 * (i.e. cur_mon is already set), be sure to pick a different one.
132 */ 133 */
133static int __open_session(struct ceph_mon_client *monc) 134static void pick_new_mon(struct ceph_mon_client *monc)
134{ 135{
135 char r; 136 int old_mon = monc->cur_mon;
136 int ret;
137 137
138 if (monc->cur_mon < 0) { 138 BUG_ON(monc->monmap->num_mon < 1);
139 get_random_bytes(&r, 1);
140 monc->cur_mon = r % monc->monmap->num_mon;
141 dout("open_session num=%d r=%d -> mon%d\n",
142 monc->monmap->num_mon, r, monc->cur_mon);
143 monc->sub_renew_after = jiffies; /* i.e., expired */
144 monc->sub_renew_sent = 0;
145 139
146 dout("open_session mon%d opening\n", monc->cur_mon); 140 if (monc->monmap->num_mon == 1) {
147 ceph_con_open(&monc->con, 141 monc->cur_mon = 0;
148 CEPH_ENTITY_TYPE_MON, monc->cur_mon, 142 } else {
149 &monc->monmap->mon_inst[monc->cur_mon].addr); 143 int max = monc->monmap->num_mon;
144 int o = -1;
145 int n;
146
147 if (monc->cur_mon >= 0) {
148 if (monc->cur_mon < monc->monmap->num_mon)
149 o = monc->cur_mon;
150 if (o >= 0)
151 max--;
152 }
150 153
151 /* send an initial keepalive to ensure our timestamp is 154 n = prandom_u32() % max;
152 * valid by the time we are in an OPENED state */ 155 if (o >= 0 && n >= o)
153 ceph_con_keepalive(&monc->con); 156 n++;
154 157
155 /* initiatiate authentication handshake */ 158 monc->cur_mon = n;
156 ret = ceph_auth_build_hello(monc->auth,
157 monc->m_auth->front.iov_base,
158 monc->m_auth->front_alloc_len);
159 __send_prepared_auth_request(monc, ret);
160 } else {
161 dout("open_session mon%d already open\n", monc->cur_mon);
162 } 159 }
163 return 0; 160
161 dout("%s mon%d -> mon%d out of %d mons\n", __func__, old_mon,
162 monc->cur_mon, monc->monmap->num_mon);
163}
164
165/*
166 * Open a session with a new monitor.
167 */
168static void __open_session(struct ceph_mon_client *monc)
169{
170 int ret;
171
172 pick_new_mon(monc);
173
174 monc->sub_renew_after = jiffies; /* i.e., expired */
175 monc->sub_renew_sent = 0;
176
177 dout("%s opening mon%d\n", __func__, monc->cur_mon);
178 ceph_con_open(&monc->con, CEPH_ENTITY_TYPE_MON, monc->cur_mon,
179 &monc->monmap->mon_inst[monc->cur_mon].addr);
180
181 /*
182 * send an initial keepalive to ensure our timestamp is valid
183 * by the time we are in an OPENED state
184 */
185 ceph_con_keepalive(&monc->con);
186
187 /* initiate authentication handshake */
188 ret = ceph_auth_build_hello(monc->auth,
189 monc->m_auth->front.iov_base,
190 monc->m_auth->front_alloc_len);
191 BUG_ON(ret <= 0);
192 __send_prepared_auth_request(monc, ret);
164} 193}
165 194
166static bool __sub_expired(struct ceph_mon_client *monc) 195static bool __sub_expired(struct ceph_mon_client *monc)
@@ -907,7 +936,7 @@ void ceph_monc_stop(struct ceph_mon_client *monc)
907 936
908 mutex_lock(&monc->mutex); 937 mutex_lock(&monc->mutex);
909 __close_session(monc); 938 __close_session(monc);
910 939 monc->cur_mon = -1;
911 mutex_unlock(&monc->mutex); 940 mutex_unlock(&monc->mutex);
912 941
913 /* 942 /*