diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2016-01-20 11:50:31 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-03-25 13:51:38 -0400 |
commit | 0e04dc26cc594d31ee6b1382b452b6bc83b57937 (patch) | |
tree | bc0ee4c6236224b44f9e388672e2e0a1cbfe8253 /net | |
parent | 82dcabad750a36a2b749889bc89c5a3188775b2e (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.c | 85 |
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 | */ |
133 | static int __open_session(struct ceph_mon_client *monc) | 134 | static 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 | */ | ||
168 | static 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 | ||
166 | static bool __sub_expired(struct ceph_mon_client *monc) | 195 | static 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 | /* |