Print this page
Support route deletion entries in SVP_R_LOG_ACK.


 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.