137 svp_lrm_req_t *svrr = sdl->sdl_logrm;
138
139 mutex_enter(&sdl->sdl_lock);
140 if (status == SVP_S_OK || status == SVP_S_NOTFOUND) {
141 bcopy(vl3->svl3_id, &svrr->svrr_ids[svrr->svrr_count * 16],
142 UUID_LEN);
143 svrr->svrr_count++;
144 }
145 mutex_exit(&sdl->sdl_lock);
146
147 svp_shootdown_rele(sdl);
148 }
149
150 static int
151 svp_shootdown_logr_shoot(void *data, svp_log_type_t type, void *arg)
152 {
153 svp_sdlog_t *sdl = arg;
154 svp_remote_t *srp = sdl->sdl_remote;
155 svp_lrm_req_t *svrr = sdl->sdl_logrm;
156
157 if (type != SVP_LOG_VL2 && type != SVP_LOG_VL3)
158 libvarpd_panic("encountered unknown type: %d\n", type);
159
160 if (type == SVP_LOG_VL2) {
161 svp_log_vl2_t *svl2 = data;
162 svp_remote_shootdown_vl2(srp, svl2);
163 mutex_enter(&sdl->sdl_lock);
164 bcopy(svl2->svl2_id, &svrr->svrr_ids[svrr->svrr_count * 16],
165 UUID_LEN);
166 svrr->svrr_count++;
167 mutex_exit(&sdl->sdl_lock);
168 } else {
169 svp_log_vl3_t *svl3 = data;
170
171 /* Take a hold for the duration of this request */
172 svp_shootdown_ref(sdl);
173 svp_remote_shootdown_vl3(srp, svl3, sdl);
174 }
175
176 return (0);
177 }
178
179 static int
180 svp_shootdown_logr_count(void *data, svp_log_type_t type, void *arg)
181 {
182 uint_t *u = arg;
183 *u = *u + 1;
184 return (0);
185 }
186
187
188 static int
189 svp_shootdown_logr_iter(svp_remote_t *srp, void *buf, size_t len,
190 int (*cb)(void *, svp_log_type_t, void *), void *arg)
191 {
192 int ret;
193 off_t cboff = 0;
194 uint32_t *typep, type;
195 svp_log_vl2_t *svl2;
196 svp_log_vl3_t *svl3;
197
198 /* Adjust for initial status word */
199 assert(len >= sizeof (uint32_t));
200 len -= sizeof (uint32_t);
201 cboff += sizeof (uint32_t);
202
203 while (len > 0) {
204 size_t opsz;
205
206 if (len < sizeof (uint32_t)) {
207 (void) bunyan_warn(svp_bunyan,
208 "failed to get initial shootdown tag",
209 BUNYAN_T_STRING, "remote_host", srp->sr_hostname,
210 BUNYAN_T_INT32, "remote_port", srp->sr_rport,
211 BUNYAN_T_INT32, "response_size", cboff + len,
212 BUNYAN_T_INT32, "response_offset", cboff,
213 BUNYAN_T_END);
214 return (-1);
215 }
216
217 typep = buf + cboff;
218 type = ntohl(*typep);
219 if (type == SVP_LOG_VL2) {
220 opsz = sizeof (svp_log_vl2_t);
221 if (len < opsz) {
222 (void) bunyan_warn(svp_bunyan,
223 "not enough data for svp_log_vl2_t",
224 BUNYAN_T_STRING, "remote_host",
225 srp->sr_hostname,
226 BUNYAN_T_INT32, "remote_port",
227 srp->sr_rport,
228 BUNYAN_T_INT32, "response_size",
229 cboff + len,
230 BUNYAN_T_INT32, "response_offset", cboff,
231 BUNYAN_T_END);
232 return (-1);
233 }
234 svl2 = (void *)typep;
235 if ((ret = cb(svl2, type, arg)) != 0)
236 return (ret);
237 } else if (type == SVP_LOG_VL3) {
238
239 opsz = sizeof (svp_log_vl3_t);
240 if (len < opsz) {
241 (void) bunyan_warn(svp_bunyan,
242 "not enough data for svp_log_vl3_t",
243 BUNYAN_T_STRING, "remote_host",
244 srp->sr_hostname,
245 BUNYAN_T_INT32, "remote_port",
246 srp->sr_rport,
247 BUNYAN_T_INT32, "response_size",
248 cboff + len,
249 BUNYAN_T_INT32, "response_offset", cboff,
250 BUNYAN_T_END);
251 return (-1);
252 }
253 svl3 = (void *)typep;
254 if ((ret = cb(svl3, type, arg)) != 0)
255 return (ret);
256 } else {
257 (void) bunyan_warn(svp_bunyan,
258 "unknown log structure type",
259 BUNYAN_T_STRING, "remote_host",
260 srp->sr_hostname,
261 BUNYAN_T_INT32, "remote_port", srp->sr_rport,
262 BUNYAN_T_INT32, "response_size", cboff + len,
263 BUNYAN_T_INT32, "response_offset", cboff,
264 BUNYAN_T_INT32, "structure_type", type,
265 BUNYAN_T_END);
266 return (-1);
267 }
268 len -= opsz;
269 cboff += opsz;
270 }
271
272 return (0);
273 }
274
275 void
276 svp_shootdown_logr_cb(svp_remote_t *srp, svp_status_t status, void *cbdata,
277 size_t cbsize)
278 {
279 uint_t count;
280 svp_sdlog_t *sdl = &srp->sr_shoot;
281
282 if (status != SVP_S_OK) {
283 (void) bunyan_warn(svp_bunyan,
284 "log request not OK",
285 BUNYAN_T_STRING, "remote_host", srp->sr_hostname,
286 BUNYAN_T_INT32, "remote_port", srp->sr_rport,
287 BUNYAN_T_INT32, "response_size", cbsize,
288 BUNYAN_T_INT32, "status", status,
289 BUNYAN_T_END);
290 mutex_enter(&sdl->sdl_lock);
291 sdl->sdl_flags &= ~SVP_SD_RUNNING;
292 svp_shootdown_schedule(sdl, B_FALSE);
293 mutex_exit(&sdl->sdl_lock);
294 return;
295 }
296
297 /*
298 * First go ahead and count the number of entries. This effectively
299 * allows us to validate that all the data is valid, if this fails, then
300 * we fail the request.
301 */
302 count = 0;
303 if ((svp_shootdown_logr_iter(srp, cbdata, cbsize,
304 svp_shootdown_logr_count, &count)) != 0) {
305 mutex_enter(&sdl->sdl_lock);
306 sdl->sdl_flags &= ~SVP_SD_RUNNING;
307 svp_shootdown_schedule(sdl, B_FALSE);
308 mutex_exit(&sdl->sdl_lock);
309 return;
310 }
311
312 /*
313 * If we have no entries, then we're also done.
314 */
315 if (count == 0) {
316 mutex_enter(&sdl->sdl_lock);
317 sdl->sdl_flags &= ~SVP_SD_RUNNING;
318 svp_shootdown_schedule(sdl, B_FALSE);
319 mutex_exit(&sdl->sdl_lock);
320 return;
321 }
322
323 /*
324 * We have work to do. Because we may have asynchronous VL3 tasks, we're
325 * going to first grab a reference before we do the iteration. Then, for
326 * each asynchronous VL3 request we make, that'll also grab a hold. Once
327 * we're done with the iteration, we'll drop our hold. If that's the
328 * last one, it'll move on accordingly.
329 */
330 svp_shootdown_ref(sdl);
331 bzero(sdl->sdl_logrm, svp_shootdown_buf);
332
333 /*
334 * If this fails, we're going to determine what to do next based on the
335 * number of entries that were entered into the log removal. At this
336 * point success or failure don't really look different, all it changes
337 * is how many entries we have to remove.
338 */
339 (void) svp_shootdown_logr_iter(srp, cbdata, cbsize,
340 svp_shootdown_logr_shoot, sdl);
341
342 /*
343 * Now that we're done with our work, release the hold. If we don't have
344 * any vl3 tasks outstanding, this'll trigger the next phase of the log
345 * removals.
346 */
347 svp_shootdown_rele(sdl);
348 }
349
350 static void
351 svp_shootdown_timer(void *arg)
352 {
353 svp_sdlog_t *sdl = arg;
354 svp_remote_t *srp = sdl->sdl_remote;
355 boolean_t init = B_TRUE;
356
357 mutex_enter(&sdl->sdl_lock);
358
359 /*
360 * If we've been asked to quiesce, we're done.
|
137 svp_lrm_req_t *svrr = sdl->sdl_logrm;
138
139 mutex_enter(&sdl->sdl_lock);
140 if (status == SVP_S_OK || status == SVP_S_NOTFOUND) {
141 bcopy(vl3->svl3_id, &svrr->svrr_ids[svrr->svrr_count * 16],
142 UUID_LEN);
143 svrr->svrr_count++;
144 }
145 mutex_exit(&sdl->sdl_lock);
146
147 svp_shootdown_rele(sdl);
148 }
149
150 static int
151 svp_shootdown_logr_shoot(void *data, svp_log_type_t type, void *arg)
152 {
153 svp_sdlog_t *sdl = arg;
154 svp_remote_t *srp = sdl->sdl_remote;
155 svp_lrm_req_t *svrr = sdl->sdl_logrm;
156
157 if (type != SVP_LOG_VL2 && type != SVP_LOG_VL3 && type != SVP_LOG_ROUTE)
158 libvarpd_panic("encountered unknown type: %d\n", type);
159
160 if (type == SVP_LOG_VL2) {
161 svp_log_vl2_t *svl2 = data;
162 svp_remote_shootdown_vl2(srp, svl2);
163 mutex_enter(&sdl->sdl_lock);
164 bcopy(svl2->svl2_id, &svrr->svrr_ids[svrr->svrr_count * 16],
165 UUID_LEN);
166 svrr->svrr_count++;
167 mutex_exit(&sdl->sdl_lock);
168 } else if (type == SVP_LOG_VL3) {
169 svp_log_vl3_t *svl3 = data;
170
171 /* Take a hold for the duration of this request */
172 svp_shootdown_ref(sdl);
173 svp_remote_shootdown_vl3(srp, svl3, sdl);
174 } else {
175 svp_log_route_t *svlr = data;
176
177 svp_remote_shootdown_route(srp, svlr);
178 mutex_enter(&sdl->sdl_lock);
179 bcopy(svlr->svlr_id, &svrr->svrr_ids[svrr->svrr_count * 16],
180 UUID_LEN);
181 svrr->svrr_count++;
182 mutex_exit(&sdl->sdl_lock);
183 }
184
185 return (0);
186 }
187
188 static int
189 svp_shootdown_logr_count(void *data, svp_log_type_t type, void *arg)
190 {
191 uint_t *u = arg;
192 *u = *u + 1;
193 return (0);
194 }
195
196
197 static int
198 svp_shootdown_logr_iter(svp_remote_t *srp, void *buf, size_t len,
199 int (*cb)(void *, svp_log_type_t, void *), void *arg, uint16_t version)
200 {
201 int ret;
202 off_t cboff = 0;
203 uint32_t *typep, type;
204 svp_log_vl2_t *svl2;
205 svp_log_vl3_t *svl3;
206
207 /* Adjust for initial status word */
208 assert(len >= sizeof (uint32_t));
209 len -= sizeof (uint32_t);
210 cboff += sizeof (uint32_t);
211
212 while (len > 0) {
213 size_t opsz;
214 char *typestring;
215
216 if (len < sizeof (uint32_t)) {
217 (void) bunyan_warn(svp_bunyan,
218 "failed to get initial shootdown tag",
219 BUNYAN_T_STRING, "remote_host", srp->sr_hostname,
220 BUNYAN_T_INT32, "remote_port", srp->sr_rport,
221 BUNYAN_T_INT32, "response_size", cboff + len,
222 BUNYAN_T_INT32, "response_offset", cboff,
223 BUNYAN_T_END);
224 return (-1);
225 }
226
227 typep = buf + cboff;
228 type = ntohl(*typep);
229 switch (type) {
230 case SVP_LOG_VL2:
231 opsz = sizeof (svp_log_vl2_t);
232 typestring = "svp_log_vl2_t";
233 break;
234 case SVP_LOG_VL3:
235 opsz = sizeof (svp_log_vl3_t);
236 typestring = "svp_log_vl3_t";
237 break;
238 case SVP_LOG_ROUTE:
239 if (version < SVP_VERSION_TWO) {
240 (void) bunyan_warn(svp_bunyan,
241 "insufficient version for SVP_LOG_ROUTE",
242 BUNYAN_T_UINT32, "version", version,
243 BUNYAN_T_STRING, "remote_host",
244 srp->sr_hostname,
245 BUNYAN_T_INT32, "remote_port",
246 srp->sr_rport,
247 BUNYAN_T_INT32, "response_size",
248 cboff + len,
249 BUNYAN_T_INT32, "response_offset", cboff,
250 BUNYAN_T_END);
251 return (-1);
252 }
253 opsz = sizeof (svp_log_route_t);
254 typestring = "svp_log_route_t";
255 break;
256 default:
257 (void) bunyan_warn(svp_bunyan,
258 "unknown log structure type",
259 BUNYAN_T_STRING, "remote_host",
260 srp->sr_hostname,
261 BUNYAN_T_INT32, "remote_port", srp->sr_rport,
262 BUNYAN_T_INT32, "response_size", cboff + len,
263 BUNYAN_T_INT32, "response_offset", cboff,
264 BUNYAN_T_INT32, "structure_type", type,
265 BUNYAN_T_END);
266 return (-1);
267 }
268 if (len < opsz) {
269 (void) bunyan_warn(svp_bunyan,
270 "not enough data for",
271 BUNYAN_T_STRING, "", typestring,
272 BUNYAN_T_STRING, "remote_host", srp->sr_hostname,
273 BUNYAN_T_INT32, "remote_port", srp->sr_rport,
274 BUNYAN_T_INT32, "response_size", cboff + len,
275 BUNYAN_T_INT32, "response_offset", cboff,
276 BUNYAN_T_END);
277 return (-1);
278 }
279 if ((ret = cb((void *)typep, type, arg)) != 0)
280 return (ret);
281
282 len -= opsz;
283 cboff += opsz;
284 }
285
286 return (0);
287 }
288
289 void
290 svp_shootdown_logr_cb(svp_remote_t *srp, svp_status_t status, void *cbdata,
291 size_t cbsize, uint16_t version)
292 {
293 uint_t count;
294 svp_sdlog_t *sdl = &srp->sr_shoot;
295
296 if (status != SVP_S_OK) {
297 (void) bunyan_warn(svp_bunyan,
298 "log request not OK",
299 BUNYAN_T_STRING, "remote_host", srp->sr_hostname,
300 BUNYAN_T_INT32, "remote_port", srp->sr_rport,
301 BUNYAN_T_INT32, "response_size", cbsize,
302 BUNYAN_T_INT32, "status", status,
303 BUNYAN_T_END);
304 mutex_enter(&sdl->sdl_lock);
305 sdl->sdl_flags &= ~SVP_SD_RUNNING;
306 svp_shootdown_schedule(sdl, B_FALSE);
307 mutex_exit(&sdl->sdl_lock);
308 return;
309 }
310
311 /*
312 * First go ahead and count the number of entries. This effectively
313 * allows us to validate that all the data is valid, if this fails, then
314 * we fail the request.
315 */
316 count = 0;
317 if ((svp_shootdown_logr_iter(srp, cbdata, cbsize,
318 svp_shootdown_logr_count, &count, version)) != 0) {
319 mutex_enter(&sdl->sdl_lock);
320 sdl->sdl_flags &= ~SVP_SD_RUNNING;
321 svp_shootdown_schedule(sdl, B_FALSE);
322 mutex_exit(&sdl->sdl_lock);
323 return;
324 }
325
326 /*
327 * If we have no entries, then we're also done.
328 */
329 if (count == 0) {
330 mutex_enter(&sdl->sdl_lock);
331 sdl->sdl_flags &= ~SVP_SD_RUNNING;
332 svp_shootdown_schedule(sdl, B_FALSE);
333 mutex_exit(&sdl->sdl_lock);
334 return;
335 }
336
337 /*
338 * We have work to do. Because we may have asynchronous VL3 tasks, we're
339 * going to first grab a reference before we do the iteration. Then, for
340 * each asynchronous VL3 request we make, that'll also grab a hold. Once
341 * we're done with the iteration, we'll drop our hold. If that's the
342 * last one, it'll move on accordingly.
343 */
344 svp_shootdown_ref(sdl);
345 bzero(sdl->sdl_logrm, svp_shootdown_buf);
346
347 /*
348 * If this fails, we're going to determine what to do next based on the
349 * number of entries that were entered into the log removal. At this
350 * point success or failure don't really look different, all it changes
351 * is how many entries we have to remove.
352 */
353 (void) svp_shootdown_logr_iter(srp, cbdata, cbsize,
354 svp_shootdown_logr_shoot, sdl, version);
355
356 /*
357 * Now that we're done with our work, release the hold. If we don't have
358 * any vl3 tasks outstanding, this'll trigger the next phase of the log
359 * removals.
360 */
361 svp_shootdown_rele(sdl);
362 }
363
364 static void
365 svp_shootdown_timer(void *arg)
366 {
367 svp_sdlog_t *sdl = arg;
368 svp_remote_t *srp = sdl->sdl_remote;
369 boolean_t init = B_TRUE;
370
371 mutex_enter(&sdl->sdl_lock);
372
373 /*
374 * If we've been asked to quiesce, we're done.
|