1 /* $OpenBSD: softraid.c,v 1.105 2008/04/02 21:32:03 martin Exp $ */ 2 /* 3 * Copyright (c) 2007 Marco Peereboom <marco@peereboom.us> 4 * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "bio.h" 20 21 #include <sys/param.h> 22 #include <sys/systm.h> 23 #include <sys/buf.h> 24 #include <sys/device.h> 25 #include <sys/ioctl.h> 26 #include <sys/proc.h> 27 #include <sys/malloc.h> 28 #include <sys/kernel.h> 29 #include <sys/disk.h> 30 #include <sys/rwlock.h> 31 #include <sys/queue.h> 32 #include <sys/fcntl.h> 33 #include <sys/disklabel.h> 34 #include <sys/mount.h> 35 #include <sys/sensors.h> 36 #include <sys/stat.h> 37 #include <sys/conf.h> 38 #include <sys/uio.h> 39 40 #include <crypto/cryptodev.h> 41 42 #include <scsi/scsi_all.h> 43 #include <scsi/scsiconf.h> 44 #include <scsi/scsi_disk.h> 45 46 #include <dev/softraidvar.h> 47 #include <dev/rndvar.h> 48 49 /* #define SR_FANCY_STATS */ 50 51 #ifdef SR_DEBUG 52 #define SR_FANCY_STATS 53 uint32_t sr_debug = 0 54 /* | SR_D_CMD */ 55 /* | SR_D_MISC */ 56 /* | SR_D_INTR */ 57 /* | SR_D_IOCTL */ 58 /* | SR_D_CCB */ 59 /* | SR_D_WU */ 60 /* | SR_D_META */ 61 /* | SR_D_DIS */ 62 /* | SR_D_STATE */ 63 ; 64 #endif 65 66 int sr_match(struct device *, void *, void *); 67 void sr_attach(struct device *, struct device *, void *); 68 int sr_detach(struct device *, int); 69 int sr_activate(struct device *, enum devact); 70 71 struct cfattach softraid_ca = { 72 sizeof(struct sr_softc), sr_match, sr_attach, sr_detach, 73 sr_activate 74 }; 75 76 struct cfdriver softraid_cd = { 77 NULL, "softraid", DV_DULL 78 }; 79 80 int sr_scsi_cmd(struct scsi_xfer *); 81 void sr_minphys(struct buf *bp); 82 void sr_copy_internal_data(struct scsi_xfer *, 83 void *, size_t); 84 int sr_scsi_ioctl(struct scsi_link *, u_long, 85 caddr_t, int, struct proc *); 86 int sr_ioctl(struct device *, u_long, caddr_t); 87 int sr_ioctl_inq(struct sr_softc *, struct bioc_inq *); 88 int sr_ioctl_vol(struct sr_softc *, struct bioc_vol *); 89 int sr_ioctl_disk(struct sr_softc *, struct bioc_disk *); 90 int sr_ioctl_setstate(struct sr_softc *, 91 struct bioc_setstate *); 92 int sr_ioctl_createraid(struct sr_softc *, 93 struct bioc_createraid *, int); 94 int sr_open_chunks(struct sr_softc *, 95 struct sr_chunk_head *, dev_t *, int); 96 int sr_read_meta(struct sr_discipline *); 97 int sr_create_chunk_meta(struct sr_softc *, 98 struct sr_chunk_head *); 99 void sr_unwind_chunks(struct sr_softc *, 100 struct sr_chunk_head *); 101 void sr_free_discipline(struct sr_discipline *); 102 void sr_shutdown_discipline(struct sr_discipline *); 103 104 /* utility functions */ 105 void sr_shutdown(void *); 106 void sr_get_uuid(struct sr_uuid *); 107 void sr_print_uuid(struct sr_uuid *, int); 108 u_int32_t sr_checksum(char *, u_int32_t *, u_int32_t); 109 int sr_clear_metadata(struct sr_discipline *); 110 int sr_save_metadata(struct sr_discipline *, u_int32_t); 111 int sr_boot_assembly(struct sr_softc *); 112 int sr_already_assembled(struct sr_discipline *); 113 int sr_validate_metadata(struct sr_softc *, dev_t, 114 struct sr_metadata *); 115 116 /* don't include these on RAMDISK */ 117 #ifndef SMALL_KERNEL 118 void sr_refresh_sensors(void *); 119 int sr_create_sensors(struct sr_discipline *); 120 void sr_delete_sensors(struct sr_discipline *); 121 #endif 122 123 #ifdef SR_DEBUG 124 void sr_print_metadata(struct sr_metadata *); 125 #else 126 #define sr_print_metadata(m) 127 #endif 128 129 struct scsi_adapter sr_switch = { 130 sr_scsi_cmd, sr_minphys, NULL, NULL, sr_scsi_ioctl 131 }; 132 133 struct scsi_device sr_dev = { 134 NULL, NULL, NULL, NULL 135 }; 136 137 int 138 sr_match(struct device *parent, void *match, void *aux) 139 { 140 return (1); 141 } 142 143 void 144 sr_attach(struct device *parent, struct device *self, void *aux) 145 { 146 struct sr_softc *sc = (void *)self; 147 148 DNPRINTF(SR_D_MISC, "\n%s: sr_attach", DEVNAME(sc)); 149 150 rw_init(&sc->sc_lock, "sr_lock"); 151 152 if (bio_register(&sc->sc_dev, sr_ioctl) != 0) 153 printf("%s: controller registration failed", DEVNAME(sc)); 154 else 155 sc->sc_ioctl = sr_ioctl; 156 157 printf("\n"); 158 159 sr_boot_assembly(sc); 160 } 161 162 int 163 sr_detach(struct device *self, int flags) 164 { 165 return (0); 166 } 167 168 int 169 sr_activate(struct device *self, enum devact act) 170 { 171 return (1); 172 } 173 174 void 175 sr_minphys(struct buf *bp) 176 { 177 DNPRINTF(SR_D_MISC, "sr_minphys: %d\n", bp->b_bcount); 178 179 /* XXX currently using SR_MAXFER = MAXPHYS */ 180 if (bp->b_bcount > SR_MAXFER) 181 bp->b_bcount = SR_MAXFER; 182 minphys(bp); 183 } 184 185 void 186 sr_copy_internal_data(struct scsi_xfer *xs, void *v, size_t size) 187 { 188 size_t copy_cnt; 189 190 DNPRINTF(SR_D_MISC, "sr_copy_internal_data xs: %p size: %d\n", 191 xs, size); 192 193 if (xs->datalen) { 194 copy_cnt = MIN(size, xs->datalen); 195 bcopy(v, xs->data, copy_cnt); 196 } 197 } 198 199 int 200 sr_alloc_ccb(struct sr_discipline *sd) 201 { 202 struct sr_ccb *ccb; 203 int i; 204 205 if (!sd) 206 return (1); 207 208 DNPRINTF(SR_D_CCB, "%s: sr_alloc_ccb\n", DEVNAME(sd->sd_sc)); 209 210 if (sd->sd_ccb) 211 return (1); 212 213 sd->sd_ccb = malloc(sizeof(struct sr_ccb) * 214 sd->sd_max_wu * sd->sd_max_ccb_per_wu, M_DEVBUF, M_WAITOK | M_ZERO); 215 TAILQ_INIT(&sd->sd_ccb_freeq); 216 for (i = 0; i < sd->sd_max_wu * sd->sd_max_ccb_per_wu; i++) { 217 ccb = &sd->sd_ccb[i]; 218 ccb->ccb_dis = sd; 219 sr_put_ccb(ccb); 220 } 221 222 DNPRINTF(SR_D_CCB, "%s: sr_alloc_ccb ccb: %d\n", 223 DEVNAME(sd->sd_sc), sd->sd_max_wu * sd->sd_max_ccb_per_wu); 224 225 return (0); 226 } 227 228 void 229 sr_free_ccb(struct sr_discipline *sd) 230 { 231 struct sr_ccb *ccb; 232 233 if (!sd) 234 return; 235 236 DNPRINTF(SR_D_CCB, "%s: sr_free_ccb %p\n", DEVNAME(sd->sd_sc), sd); 237 238 while ((ccb = TAILQ_FIRST(&sd->sd_ccb_freeq)) != NULL) 239 TAILQ_REMOVE(&sd->sd_ccb_freeq, ccb, ccb_link); 240 241 if (sd->sd_ccb) 242 free(sd->sd_ccb, M_DEVBUF); 243 } 244 245 struct sr_ccb * 246 sr_get_ccb(struct sr_discipline *sd) 247 { 248 struct sr_ccb *ccb; 249 int s; 250 251 s = splbio(); 252 253 ccb = TAILQ_FIRST(&sd->sd_ccb_freeq); 254 if (ccb) { 255 TAILQ_REMOVE(&sd->sd_ccb_freeq, ccb, ccb_link); 256 ccb->ccb_state = SR_CCB_INPROGRESS; 257 } 258 259 splx(s); 260 261 DNPRINTF(SR_D_CCB, "%s: sr_get_ccb: %p\n", DEVNAME(sd->sd_sc), 262 ccb); 263 264 return (ccb); 265 } 266 267 void 268 sr_put_ccb(struct sr_ccb *ccb) 269 { 270 struct sr_discipline *sd = ccb->ccb_dis; 271 int s; 272 273 DNPRINTF(SR_D_CCB, "%s: sr_put_ccb: %p\n", DEVNAME(sd->sd_sc), 274 ccb); 275 276 s = splbio(); 277 278 ccb->ccb_wu = NULL; 279 ccb->ccb_state = SR_CCB_FREE; 280 ccb->ccb_target = -1; 281 ccb->ccb_opaque = NULL; 282 283 TAILQ_INSERT_TAIL(&sd->sd_ccb_freeq, ccb, ccb_link); 284 285 splx(s); 286 } 287 288 int 289 sr_alloc_wu(struct sr_discipline *sd) 290 { 291 struct sr_workunit *wu; 292 int i, no_wu; 293 294 if (!sd) 295 return (1); 296 297 DNPRINTF(SR_D_WU, "%s: sr_alloc_wu %p %d\n", DEVNAME(sd->sd_sc), 298 sd, sd->sd_max_wu); 299 300 if (sd->sd_wu) 301 return (1); 302 303 no_wu = sd->sd_max_wu; 304 sd->sd_wu_pending = no_wu; 305 306 sd->sd_wu = malloc(sizeof(struct sr_workunit) * no_wu, 307 M_DEVBUF, M_WAITOK | M_ZERO); 308 TAILQ_INIT(&sd->sd_wu_freeq); 309 TAILQ_INIT(&sd->sd_wu_pendq); 310 TAILQ_INIT(&sd->sd_wu_defq); 311 for (i = 0; i < no_wu; i++) { 312 wu = &sd->sd_wu[i]; 313 wu->swu_dis = sd; 314 sr_put_wu(wu); 315 } 316 317 return (0); 318 } 319 320 void 321 sr_free_wu(struct sr_discipline *sd) 322 { 323 struct sr_workunit *wu; 324 325 if (!sd) 326 return; 327 328 DNPRINTF(SR_D_WU, "%s: sr_free_wu %p\n", DEVNAME(sd->sd_sc), sd); 329 330 while ((wu = TAILQ_FIRST(&sd->sd_wu_freeq)) != NULL) 331 TAILQ_REMOVE(&sd->sd_wu_freeq, wu, swu_link); 332 while ((wu = TAILQ_FIRST(&sd->sd_wu_pendq)) != NULL) 333 TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link); 334 while ((wu = TAILQ_FIRST(&sd->sd_wu_defq)) != NULL) 335 TAILQ_REMOVE(&sd->sd_wu_defq, wu, swu_link); 336 337 if (sd->sd_wu) 338 free(sd->sd_wu, M_DEVBUF); 339 } 340 341 void 342 sr_put_wu(struct sr_workunit *wu) 343 { 344 struct sr_discipline *sd = wu->swu_dis; 345 struct sr_ccb *ccb; 346 347 int s; 348 349 DNPRINTF(SR_D_WU, "%s: sr_put_wu: %p\n", DEVNAME(sd->sd_sc), wu); 350 351 s = splbio(); 352 353 wu->swu_xs = NULL; 354 wu->swu_state = SR_WU_FREE; 355 wu->swu_ios_complete = 0; 356 wu->swu_ios_failed = 0; 357 wu->swu_ios_succeeded = 0; 358 wu->swu_io_count = 0; 359 wu->swu_blk_start = 0; 360 wu->swu_blk_end = 0; 361 wu->swu_collider = NULL; 362 wu->swu_fake = 0; 363 364 while ((ccb = TAILQ_FIRST(&wu->swu_ccb)) != NULL) { 365 TAILQ_REMOVE(&wu->swu_ccb, ccb, ccb_link); 366 sr_put_ccb(ccb); 367 } 368 TAILQ_INIT(&wu->swu_ccb); 369 370 TAILQ_INSERT_TAIL(&sd->sd_wu_freeq, wu, swu_link); 371 sd->sd_wu_pending--; 372 373 splx(s); 374 } 375 376 struct sr_workunit * 377 sr_get_wu(struct sr_discipline *sd) 378 { 379 struct sr_workunit *wu; 380 int s; 381 382 s = splbio(); 383 384 wu = TAILQ_FIRST(&sd->sd_wu_freeq); 385 if (wu) { 386 TAILQ_REMOVE(&sd->sd_wu_freeq, wu, swu_link); 387 wu->swu_state = SR_WU_INPROGRESS; 388 } 389 sd->sd_wu_pending++; 390 391 splx(s); 392 393 DNPRINTF(SR_D_WU, "%s: sr_get_wu: %p\n", DEVNAME(sd->sd_sc), wu); 394 395 return (wu); 396 } 397 398 int 399 sr_scsi_cmd(struct scsi_xfer *xs) 400 { 401 int s; 402 struct scsi_link *link = xs->sc_link; 403 struct sr_softc *sc = link->adapter_softc; 404 struct sr_workunit *wu; 405 struct sr_discipline *sd; 406 407 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: scsibus%d xs: %p " 408 "flags: %#x\n", DEVNAME(sc), link->scsibus, xs, xs->flags); 409 410 sd = sc->sc_dis[link->scsibus]; 411 if (sd == NULL) { 412 s = splhigh(); 413 sd = sc->sc_attach_dis; 414 splx(s); 415 416 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: attaching %p\n", 417 DEVNAME(sc), sd); 418 if (sd == NULL) { 419 wu = NULL; 420 printf("%s: sr_scsi_cmd NULL discipline\n", 421 DEVNAME(sc)); 422 goto stuffup; 423 } 424 } 425 426 if ((wu = sr_get_wu(sd)) == NULL) { 427 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd no wu\n", DEVNAME(sc)); 428 return (TRY_AGAIN_LATER); 429 } 430 431 xs->error = XS_NOERROR; 432 wu->swu_xs = xs; 433 434 switch (xs->cmd->opcode) { 435 case READ_COMMAND: 436 case READ_BIG: 437 case READ_16: 438 case WRITE_COMMAND: 439 case WRITE_BIG: 440 case WRITE_16: 441 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: READ/WRITE %02x\n", 442 DEVNAME(sc), xs->cmd->opcode); 443 if (sd->sd_scsi_rw(wu)) 444 goto stuffup; 445 break; 446 447 case SYNCHRONIZE_CACHE: 448 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: SYNCHRONIZE_CACHE\n", 449 DEVNAME(sc)); 450 if (sd->sd_scsi_sync(wu)) 451 goto stuffup; 452 goto complete; 453 454 case TEST_UNIT_READY: 455 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: TEST_UNIT_READY\n", 456 DEVNAME(sc)); 457 if (sd->sd_scsi_tur(wu)) 458 goto stuffup; 459 goto complete; 460 461 case START_STOP: 462 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: START_STOP\n", 463 DEVNAME(sc)); 464 if (sd->sd_scsi_start_stop(wu)) 465 goto stuffup; 466 goto complete; 467 468 case INQUIRY: 469 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: INQUIRY\n", 470 DEVNAME(sc)); 471 if (sd->sd_scsi_inquiry(wu)) 472 goto stuffup; 473 goto complete; 474 475 case READ_CAPACITY: 476 case READ_CAPACITY_16: 477 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd READ CAPACITY 0x%02x\n", 478 DEVNAME(sc), xs->cmd->opcode); 479 if (sd->sd_scsi_read_cap(wu)) 480 goto stuffup; 481 goto complete; 482 483 case REQUEST_SENSE: 484 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd REQUEST SENSE\n", 485 DEVNAME(sc)); 486 if (sd->sd_scsi_req_sense(wu)) 487 goto stuffup; 488 goto complete; 489 490 default: 491 DNPRINTF(SR_D_CMD, "%s: unsupported scsi command %x\n", 492 DEVNAME(sc), xs->cmd->opcode); 493 /* XXX might need to add generic function to handle others */ 494 goto stuffup; 495 } 496 497 return (SUCCESSFULLY_QUEUED); 498 stuffup: 499 if (sd->sd_scsi_sense.error_code) { 500 xs->error = XS_SENSE; 501 bcopy(&sd->sd_scsi_sense, &xs->sense, sizeof(xs->sense)); 502 bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense)); 503 } else { 504 xs->error = XS_DRIVER_STUFFUP; 505 xs->flags |= ITSDONE; 506 } 507 complete: 508 s = splbio(); 509 scsi_done(xs); 510 splx(s); 511 if (wu) 512 sr_put_wu(wu); 513 return (COMPLETE); 514 } 515 int 516 sr_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag, 517 struct proc *p) 518 { 519 DNPRINTF(SR_D_IOCTL, "%s: sr_scsi_ioctl cmd: %#x\n", 520 DEVNAME((struct sr_softc *)link->adapter_softc), cmd); 521 522 return (sr_ioctl(link->adapter_softc, cmd, addr)); 523 } 524 525 int 526 sr_ioctl(struct device *dev, u_long cmd, caddr_t addr) 527 { 528 struct sr_softc *sc = (struct sr_softc *)dev; 529 int rv = 0; 530 531 DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl ", DEVNAME(sc)); 532 533 rw_enter_write(&sc->sc_lock); 534 535 switch (cmd) { 536 case BIOCINQ: 537 DNPRINTF(SR_D_IOCTL, "inq\n"); 538 rv = sr_ioctl_inq(sc, (struct bioc_inq *)addr); 539 break; 540 541 case BIOCVOL: 542 DNPRINTF(SR_D_IOCTL, "vol\n"); 543 rv = sr_ioctl_vol(sc, (struct bioc_vol *)addr); 544 break; 545 546 case BIOCDISK: 547 DNPRINTF(SR_D_IOCTL, "disk\n"); 548 rv = sr_ioctl_disk(sc, (struct bioc_disk *)addr); 549 break; 550 551 case BIOCALARM: 552 DNPRINTF(SR_D_IOCTL, "alarm\n"); 553 /*rv = sr_ioctl_alarm(sc, (struct bioc_alarm *)addr); */ 554 break; 555 556 case BIOCBLINK: 557 DNPRINTF(SR_D_IOCTL, "blink\n"); 558 /*rv = sr_ioctl_blink(sc, (struct bioc_blink *)addr); */ 559 break; 560 561 case BIOCSETSTATE: 562 DNPRINTF(SR_D_IOCTL, "setstate\n"); 563 rv = sr_ioctl_setstate(sc, (struct bioc_setstate *)addr); 564 break; 565 566 case BIOCCREATERAID: 567 DNPRINTF(SR_D_IOCTL, "createraid\n"); 568 rv = sr_ioctl_createraid(sc, (struct bioc_createraid *)addr, 1); 569 break; 570 571 default: 572 DNPRINTF(SR_D_IOCTL, "invalid ioctl\n"); 573 rv = ENOTTY; 574 } 575 576 rw_exit_write(&sc->sc_lock); 577 578 return (rv); 579 } 580 581 int 582 sr_ioctl_inq(struct sr_softc *sc, struct bioc_inq *bi) 583 { 584 int i, vol, disk; 585 586 for (i = 0, vol = 0, disk = 0; i < SR_MAXSCSIBUS; i++) 587 /* XXX this will not work when we stagger disciplines */ 588 if (sc->sc_dis[i]) { 589 vol++; 590 disk += sc->sc_dis[i]->sd_vol.sv_meta.svm_no_chunk; 591 } 592 593 strlcpy(bi->bi_dev, sc->sc_dev.dv_xname, sizeof(bi->bi_dev)); 594 bi->bi_novol = vol; 595 bi->bi_nodisk = disk; 596 597 return (0); 598 } 599 600 int 601 sr_ioctl_vol(struct sr_softc *sc, struct bioc_vol *bv) 602 { 603 int i, vol, rv = EINVAL; 604 struct sr_volume *sv; 605 606 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) { 607 /* XXX this will not work when we stagger disciplines */ 608 if (sc->sc_dis[i]) 609 vol++; 610 if (vol != bv->bv_volid) 611 continue; 612 613 sv = &sc->sc_dis[i]->sd_vol; 614 bv->bv_status = sv->sv_meta.svm_status; 615 bv->bv_size = sv->sv_meta.svm_size << DEV_BSHIFT; 616 bv->bv_level = sv->sv_meta.svm_level; 617 bv->bv_nodisk = sv->sv_meta.svm_no_chunk; 618 strlcpy(bv->bv_dev, sv->sv_meta.svm_devname, 619 sizeof(bv->bv_dev)); 620 strlcpy(bv->bv_vendor, sv->sv_meta.svm_vendor, 621 sizeof(bv->bv_vendor)); 622 rv = 0; 623 break; 624 } 625 626 return (rv); 627 } 628 629 int 630 sr_ioctl_disk(struct sr_softc *sc, struct bioc_disk *bd) 631 { 632 int i, vol, rv = EINVAL, id; 633 struct sr_chunk *src; 634 635 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) { 636 /* XXX this will not work when we stagger disciplines */ 637 if (sc->sc_dis[i]) 638 vol++; 639 if (vol != bd->bd_volid) 640 continue; 641 642 id = bd->bd_diskid; 643 if (id >= sc->sc_dis[i]->sd_vol.sv_meta.svm_no_chunk) 644 break; 645 646 src = sc->sc_dis[i]->sd_vol.sv_chunks[id]; 647 bd->bd_status = src->src_meta.scm_status; 648 bd->bd_size = src->src_meta.scm_size << DEV_BSHIFT; 649 bd->bd_channel = vol; 650 bd->bd_target = id; 651 strlcpy(bd->bd_vendor, src->src_meta.scm_devname, 652 sizeof(bd->bd_vendor)); 653 rv = 0; 654 break; 655 } 656 657 return (rv); 658 } 659 660 int 661 sr_ioctl_setstate(struct sr_softc *sc, struct bioc_setstate *bs) 662 { 663 int rv = EINVAL; 664 665 #ifdef SR_UNIT_TEST 666 int i, vol, state; 667 struct sr_discipline *sd; 668 669 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) { 670 /* XXX this will not work when we stagger disciplines */ 671 if (sc->sc_dis[i]) 672 vol++; 673 if (vol != bs->bs_channel) 674 continue; 675 676 sd = sc->sc_dis[vol]; 677 if (bs->bs_target >= sd->sd_vol.sv_meta.svm_no_chunk) 678 goto done; 679 680 switch (bs->bs_status) { 681 case BIOC_SSONLINE: 682 state = BIOC_SDONLINE; 683 break; 684 case BIOC_SSOFFLINE: 685 state = BIOC_SDOFFLINE; 686 break; 687 case BIOC_SSHOTSPARE: 688 state = BIOC_SDHOTSPARE; 689 break; 690 case BIOC_SSREBUILD: 691 state = BIOC_SDREBUILD; 692 break; 693 default: 694 printf("invalid state %d\n", bs->bs_status); 695 goto done; 696 } 697 698 printf("status change for %u:%u -> %u %u\n", 699 bs->bs_channel, bs->bs_target, bs->bs_status, state); 700 701 sd->sd_set_chunk_state(sd, bs->bs_target, bs->bs_status); 702 703 rv = 0; 704 705 break; 706 } 707 708 done: 709 #endif 710 return (rv); 711 } 712 713 int 714 sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user) 715 { 716 dev_t *dt; 717 int i, s, no_chunk, rv = EINVAL, vol; 718 int no_meta, updatemeta = 0; 719 u_int64_t vol_size; 720 int32_t strip_size = 0; 721 struct sr_chunk_head *cl; 722 struct sr_discipline *sd = NULL; 723 struct sr_chunk *ch_entry; 724 struct device *dev, *dev2; 725 struct scsibus_attach_args saa; 726 727 DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl_createraid(%d)\n", 728 DEVNAME(sc), user); 729 730 /* user input */ 731 if (bc->bc_dev_list_len > BIOC_CRMAXLEN) 732 goto unwind; 733 734 dt = malloc(bc->bc_dev_list_len, M_DEVBUF, M_WAITOK | M_ZERO); 735 if (user) 736 copyin(bc->bc_dev_list, dt, bc->bc_dev_list_len); 737 else 738 bcopy(bc->bc_dev_list, dt, bc->bc_dev_list_len); 739 740 sd = malloc(sizeof(struct sr_discipline), M_DEVBUF, M_WAITOK | M_ZERO); 741 sd->sd_sc = sc; 742 743 no_chunk = bc->bc_dev_list_len / sizeof(dev_t); 744 cl = &sd->sd_vol.sv_chunk_list; 745 SLIST_INIT(cl); 746 if (sr_open_chunks(sc, cl, dt, no_chunk)) 747 goto unwind; 748 749 /* in memory copy of metadata */ 750 sd->sd_meta = malloc(SR_META_SIZE * 512 , M_DEVBUF, M_WAITOK | M_ZERO); 751 752 /* we have a valid list now create an array index */ 753 sd->sd_vol.sv_chunks = malloc(sizeof(struct sr_chunk *) * no_chunk, 754 M_DEVBUF, M_WAITOK | M_ZERO); 755 756 /* force the raid volume by clearing metadata region */ 757 if (bc->bc_flags & BIOC_SCFORCE) { 758 /* make sure disk isn't up and running */ 759 if (sr_read_meta(sd)) 760 if (sr_already_assembled(sd)) { 761 printf("%s: disk ", DEVNAME(sc)); 762 sr_print_uuid(&sd->sd_meta->ssd_uuid, 0); 763 printf(" is currently in use; can't force " 764 "create\n"); 765 goto unwind; 766 } 767 768 /* zero out pointers and metadata again to create disk */ 769 bzero(sd->sd_vol.sv_chunks, 770 sizeof(struct sr_chunk *) * no_chunk); 771 bzero(sd->sd_meta, SR_META_SIZE * 512); 772 773 if (sr_clear_metadata(sd)) { 774 printf("%s: failed to clear metadata\n", DEVNAME(sc)); 775 goto unwind; 776 } 777 } 778 779 if ((no_meta = sr_read_meta(sd)) == 0) { 780 /* fill out chunk array */ 781 i = 0; 782 SLIST_FOREACH(ch_entry, cl, src_link) 783 sd->sd_vol.sv_chunks[i++] = ch_entry; 784 785 /* fill out all chunk metadata */ 786 sr_create_chunk_meta(sc, cl); 787 ch_entry = SLIST_FIRST(cl); 788 789 /* no metadata available */ 790 switch (bc->bc_level) { 791 case 0: 792 if (no_chunk < 2) 793 goto unwind; 794 strlcpy(sd->sd_name, "RAID 0", sizeof(sd->sd_name)); 795 /* 796 * XXX add variable strip size later even though 797 * MAXPHYS is really the clever value, users like 798 * to tinker with that type of stuff 799 */ 800 strip_size = MAXPHYS; 801 vol_size = 802 ch_entry->src_meta.scm_coerced_size * no_chunk; 803 break; 804 case 1: 805 if (no_chunk < 2) 806 goto unwind; 807 strlcpy(sd->sd_name, "RAID 1", sizeof(sd->sd_name)); 808 vol_size = ch_entry->src_meta.scm_coerced_size; 809 break; 810 #if 0 811 #ifdef CRYPTO 812 case 'C': 813 if (no_chunk < 1 || no_chunk > 2) 814 goto unwind; 815 strlcpy(sd->sd_name, "CRYPTO", sizeof(sd->sd_name)); 816 vol_size = ch_entry->src_meta.scm_size; 817 818 /* create crypto keys and encrypt them */ 819 sr_crypto_create_keys(sd); 820 sr_crypto_encrypt_key(sd); 821 break; 822 #endif /* CRYPTO */ 823 #endif 824 default: 825 goto unwind; 826 } 827 828 /* fill out all volume metadata */ 829 DNPRINTF(SR_D_IOCTL, 830 "%s: sr_ioctl_createraid: vol_size: %lld\n", 831 DEVNAME(sc), vol_size); 832 sd->sd_vol.sv_meta.svm_no_chunk = no_chunk; 833 sd->sd_vol.sv_meta.svm_size = vol_size; 834 sd->sd_vol.sv_meta.svm_status = BIOC_SVONLINE; 835 sd->sd_vol.sv_meta.svm_level = bc->bc_level; 836 sd->sd_vol.sv_meta.svm_strip_size = strip_size; 837 strlcpy(sd->sd_vol.sv_meta.svm_vendor, "OPENBSD", 838 sizeof(sd->sd_vol.sv_meta.svm_vendor)); 839 snprintf(sd->sd_vol.sv_meta.svm_product, 840 sizeof(sd->sd_vol.sv_meta.svm_product), "SR %s", 841 sd->sd_name); 842 snprintf(sd->sd_vol.sv_meta.svm_revision, 843 sizeof(sd->sd_vol.sv_meta.svm_revision), "%03d", 844 SR_META_VERSION); 845 846 sd->sd_meta_flags = bc->bc_flags & BIOC_SCNOAUTOASSEMBLE; 847 updatemeta = 1; 848 } else if (no_meta == no_chunk) { 849 if (user == 0 && sd->sd_meta_flags & BIOC_SCNOAUTOASSEMBLE) { 850 DNPRINTF(SR_D_META, "%s: disk not auto assembled from " 851 "metadata\n", DEVNAME(sc)); 852 goto unwind; 853 } 854 if (sr_already_assembled(sd)) { 855 printf("%s: disk ", DEVNAME(sc)); 856 sr_print_uuid(&sd->sd_meta->ssd_uuid, 0); 857 printf(" already assembled\n"); 858 goto unwind; 859 } 860 DNPRINTF(SR_D_META, "%s: disk assembled from metadata\n", 861 DEVNAME(sc)); 862 updatemeta = 0; 863 } else { 864 if (sr_already_assembled(sd)) { 865 printf("%s: disk ", DEVNAME(sc)); 866 sr_print_uuid(&sd->sd_meta->ssd_uuid, 0); 867 printf(" already assembled; will not partial " 868 "assemble it\n"); 869 goto unwind; 870 } 871 printf("%s: not yet partial bringup\n", DEVNAME(sc)); 872 goto unwind; 873 } 874 875 /* XXX metadata SHALL be fully filled in at this point */ 876 877 switch (bc->bc_level) { 878 case 0: 879 /* fill out discipline members */ 880 sd->sd_type = SR_MD_RAID0; 881 sd->sd_max_ccb_per_wu = 882 (MAXPHYS / sd->sd_vol.sv_meta.svm_strip_size + 1) * 883 SR_RAID0_NOWU * sd->sd_vol.sv_meta.svm_no_chunk; 884 sd->sd_max_wu = SR_RAID0_NOWU; 885 886 /* setup discipline pointers */ 887 sd->sd_alloc_resources = sr_raid0_alloc_resources; 888 sd->sd_free_resources = sr_raid0_free_resources; 889 sd->sd_scsi_inquiry = sr_raid_inquiry; 890 sd->sd_scsi_read_cap = sr_raid_read_cap; 891 sd->sd_scsi_tur = sr_raid_tur; 892 sd->sd_scsi_req_sense = sr_raid_request_sense; 893 sd->sd_scsi_start_stop = sr_raid_start_stop; 894 sd->sd_scsi_sync = sr_raid_sync; 895 sd->sd_scsi_rw = sr_raid0_rw; 896 sd->sd_set_chunk_state = sr_raid0_set_chunk_state; 897 sd->sd_set_vol_state = sr_raid0_set_vol_state; 898 break; 899 case 1: 900 /* fill out discipline members */ 901 sd->sd_type = SR_MD_RAID1; 902 sd->sd_max_ccb_per_wu = no_chunk; 903 sd->sd_max_wu = SR_RAID1_NOWU; 904 905 /* setup discipline pointers */ 906 sd->sd_alloc_resources = sr_raid1_alloc_resources; 907 sd->sd_free_resources = sr_raid1_free_resources; 908 sd->sd_scsi_inquiry = sr_raid_inquiry; 909 sd->sd_scsi_read_cap = sr_raid_read_cap; 910 sd->sd_scsi_tur = sr_raid_tur; 911 sd->sd_scsi_req_sense = sr_raid_request_sense; 912 sd->sd_scsi_start_stop = sr_raid_start_stop; 913 sd->sd_scsi_sync = sr_raid_sync; 914 sd->sd_scsi_rw = sr_raid1_rw; 915 sd->sd_set_chunk_state = sr_raid1_set_chunk_state; 916 sd->sd_set_vol_state = sr_raid1_set_vol_state; 917 break; 918 #ifdef CRYPTO 919 case 'C': 920 /* fill out discipline members */ 921 sd->sd_type = SR_MD_CRYPTO; 922 sd->sd_max_ccb_per_wu = no_chunk; 923 sd->sd_max_wu = SR_CRYPTO_NOWU; 924 925 /* setup discipline pointers */ 926 sd->sd_alloc_resources = sr_crypto_alloc_resources; 927 sd->sd_free_resources = sr_crypto_free_resources; 928 sd->sd_scsi_inquiry = sr_raid_inquiry; 929 sd->sd_scsi_read_cap = sr_raid_read_cap; 930 sd->sd_scsi_tur = sr_raid_tur; 931 sd->sd_scsi_req_sense = sr_raid_request_sense; 932 sd->sd_scsi_start_stop = sr_raid_start_stop; 933 sd->sd_scsi_sync = sr_raid_sync; 934 sd->sd_scsi_rw = sr_crypto_rw; 935 /* XXX reuse raid 1 functions for now FIXME */ 936 sd->sd_set_chunk_state = sr_raid1_set_chunk_state; 937 sd->sd_set_vol_state = sr_raid1_set_vol_state; 938 break; 939 #endif 940 default: 941 goto unwind; 942 } 943 944 /* allocate all resources */ 945 if ((rv = sd->sd_alloc_resources(sd))) 946 goto unwind; 947 948 /* setup scsi midlayer */ 949 sd->sd_link.openings = sd->sd_max_wu; 950 sd->sd_link.device = &sr_dev; 951 sd->sd_link.device_softc = sc; 952 sd->sd_link.adapter_softc = sc; 953 sd->sd_link.adapter = &sr_switch; 954 sd->sd_link.adapter_target = SR_MAX_LD; 955 sd->sd_link.adapter_buswidth = 1; 956 bzero(&saa, sizeof(saa)); 957 saa.saa_sc_link = &sd->sd_link; 958 959 /* we passed all checks return ENXIO if volume can't be created */ 960 rv = ENXIO; 961 962 /* clear sense data */ 963 bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense)); 964 965 /* use temporary discipline pointer */ 966 s = splhigh(); 967 sc->sc_attach_dis = sd; 968 splx(s); 969 dev2 = config_found(&sc->sc_dev, &saa, scsiprint); 970 s = splhigh(); 971 sc->sc_attach_dis = NULL; 972 splx(s); 973 TAILQ_FOREACH(dev, &alldevs, dv_list) 974 if (dev->dv_parent == dev2) 975 break; 976 if (dev == NULL) 977 goto unwind; 978 979 DNPRINTF(SR_D_IOCTL, "%s: sr device added: %s on scsibus%d\n", 980 DEVNAME(sc), dev->dv_xname, sd->sd_link.scsibus); 981 982 sc->sc_dis[sd->sd_link.scsibus] = sd; 983 for (i = 0, vol = -1; i <= sd->sd_link.scsibus; i++) 984 if (sc->sc_dis[i]) 985 vol++; 986 987 rv = 0; 988 if (updatemeta) { 989 /* fill out remaining volume metadata */ 990 sd->sd_vol.sv_meta.svm_volid = vol; 991 strlcpy(sd->sd_vol.sv_meta.svm_devname, dev->dv_xname, 992 sizeof(sd->sd_vol.sv_meta.svm_devname)); 993 994 } 995 996 /* save metadata to disk */ 997 rv = sr_save_metadata(sd, SR_VOL_DIRTY); 998 999 #ifndef SMALL_KERNEL 1000 if (sr_create_sensors(sd)) 1001 printf("%s: unable to create sensor for %s\n", DEVNAME(sc), 1002 dev->dv_xname); 1003 else 1004 sd->sd_vol.sv_sensor_valid = 1; 1005 #endif /* SMALL_KERNEL */ 1006 1007 sd->sd_scsibus_dev = dev2; 1008 sd->sd_shutdownhook = shutdownhook_establish(sr_shutdown, sd); 1009 1010 return (rv); 1011 1012 unwind: 1013 sr_shutdown_discipline(sd); 1014 1015 return (rv); 1016 } 1017 1018 int 1019 sr_open_chunks(struct sr_softc *sc, struct sr_chunk_head *cl, dev_t *dt, 1020 int no_chunk) 1021 { 1022 struct sr_chunk *ch_entry, *ch_prev = NULL; 1023 struct disklabel label; 1024 struct bdevsw *bdsw; 1025 char *name; 1026 int maj, unit, part, i, error; 1027 daddr64_t size; 1028 dev_t dev; 1029 1030 DNPRINTF(SR_D_IOCTL, "%s: sr_open_chunks(%d)\n", DEVNAME(sc), no_chunk); 1031 1032 /* fill out chunk list */ 1033 for (i = 0; i < no_chunk; i++) { 1034 ch_entry = malloc(sizeof(struct sr_chunk), M_DEVBUF, 1035 M_WAITOK | M_ZERO); 1036 /* keep disks in user supplied order */ 1037 if (ch_prev) 1038 SLIST_INSERT_AFTER(ch_prev, ch_entry, src_link); 1039 else 1040 SLIST_INSERT_HEAD(cl, ch_entry, src_link); 1041 ch_prev = ch_entry; 1042 1043 dev = dt[i]; 1044 maj = major(dev); 1045 part = DISKPART(dev); 1046 unit = DISKUNIT(dev); 1047 bdsw = &bdevsw[maj]; 1048 1049 name = findblkname(maj); 1050 if (name == NULL) 1051 goto unwind; 1052 1053 snprintf(ch_entry->src_devname, sizeof(ch_entry->src_devname), 1054 "%s%d%c", name, unit, part + 'a'); 1055 name = ch_entry->src_devname; 1056 1057 /* open device */ 1058 error = bdsw->d_open(dev, FREAD | FWRITE , S_IFBLK, curproc); 1059 1060 /* get disklabel */ 1061 error = bdsw->d_ioctl(dev, DIOCGDINFO, (void *)&label, 1062 0, NULL); 1063 if (error) { 1064 printf("%s: %s can't obtain disklabel\n", 1065 DEVNAME(sc), name); 1066 bdsw->d_close(dev, FWRITE, S_IFBLK, curproc); 1067 goto unwind; 1068 } 1069 1070 /* make sure the partition is of the right type */ 1071 if (label.d_partitions[part].p_fstype != FS_RAID) { 1072 printf("%s: %s partition not of type RAID (%d)\n", 1073 DEVNAME(sc), name, 1074 label.d_partitions[part].p_fstype); 1075 bdsw->d_close(dev, FWRITE, S_IFBLK, curproc); 1076 goto unwind; 1077 } 1078 1079 /* get partition size while accounting for metadata! */ 1080 ch_entry->src_size = size = 1081 DL_GETPSIZE(&label.d_partitions[part]) - 1082 SR_META_SIZE - SR_META_OFFSET; 1083 if (size <= 0) { 1084 printf("%s: %s partition too small\n", 1085 DEVNAME(sc), name); 1086 bdsw->d_close(dev, FWRITE, S_IFBLK, curproc); 1087 goto unwind; 1088 } 1089 1090 1091 ch_entry->src_dev_mm = dev; /* major/minor */ 1092 1093 DNPRINTF(SR_D_IOCTL, "%s: found %s size %d\n", DEVNAME(sc), 1094 name, size); 1095 } 1096 1097 return (0); 1098 unwind: 1099 printf("%s: invalid device: %s\n", DEVNAME(sc), name ? name : "nodev"); 1100 return (1); 1101 } 1102 1103 int 1104 sr_read_meta(struct sr_discipline *sd) 1105 { 1106 struct sr_softc *sc = sd->sd_sc; 1107 struct sr_chunk_head *cl = &sd->sd_vol.sv_chunk_list; 1108 struct sr_metadata *sm = sd->sd_meta, *m; 1109 struct sr_chunk *ch_entry; 1110 struct buf b; 1111 struct sr_vol_meta *mv; 1112 struct sr_chunk_meta *mc; 1113 struct sr_opt_meta *mo; 1114 size_t sz = SR_META_SIZE * 512; 1115 int no_chunk = 0; 1116 u_int32_t volid, ondisk = 0, cid; 1117 1118 DNPRINTF(SR_D_META, "%s: sr_read_meta\n", DEVNAME(sc)); 1119 1120 m = malloc(sz , M_DEVBUF, M_WAITOK | M_ZERO); 1121 1122 SLIST_FOREACH(ch_entry, cl, src_link) { 1123 bzero(&b, sizeof(b)); 1124 1125 b.b_flags = B_READ; 1126 b.b_blkno = SR_META_OFFSET; 1127 b.b_bcount = sz; 1128 b.b_bufsize = sz; 1129 b.b_resid = sz; 1130 b.b_data = (void *)m; 1131 b.b_error = 0; 1132 b.b_proc = curproc; 1133 b.b_dev = ch_entry->src_dev_mm; 1134 b.b_vp = NULL; 1135 b.b_iodone = NULL; 1136 LIST_INIT(&b.b_dep); 1137 bdevsw_lookup(b.b_dev)->d_strategy(&b); 1138 biowait(&b); 1139 1140 /* XXX mark chunk offline and restart metadata write */ 1141 if (b.b_flags & B_ERROR) { 1142 printf("%s: %s i/o error on block %d while reading " 1143 "metadata %d\n", DEVNAME(sc), 1144 ch_entry->src_devname, b.b_blkno, b.b_error); 1145 continue; 1146 } 1147 1148 if (m->ssd_magic != SR_MAGIC) 1149 continue; 1150 1151 /* validate metadata */ 1152 if (sr_validate_metadata(sc, ch_entry->src_dev_mm, m)) { 1153 printf("%s: invalid metadata\n", DEVNAME(sc)); 1154 no_chunk = -1; 1155 goto bad; 1156 } 1157 1158 mv = (struct sr_vol_meta *)(m + 1); 1159 mc = (struct sr_chunk_meta *)(mv + 1); 1160 1161 /* we asssume that the first chunk has the initial metadata */ 1162 if (no_chunk++ == 0) { 1163 bcopy(m, sm, sz); 1164 bcopy(m, sd->sd_meta, sizeof(*sd->sd_meta)); 1165 bcopy(mv, &sd->sd_vol.sv_meta, 1166 sizeof(sd->sd_vol.sv_meta)); 1167 1168 volid = m->ssd_vd_volid; 1169 sd->sd_meta_flags = sm->ssd_flags; 1170 } 1171 1172 if (bcmp(&sm->ssd_uuid, &sd->sd_vol.sv_meta.svm_uuid, 1173 sizeof(struct sr_uuid))) { 1174 printf("%s: %s invalid chunk uuid ", 1175 DEVNAME(sc), ch_entry->src_devname); 1176 sr_print_uuid(&sm->ssd_uuid, 0); 1177 printf(", expected "); 1178 sr_print_uuid(&sd->sd_vol.sv_meta.svm_uuid, 1); 1179 no_chunk = -1; 1180 goto bad; 1181 } 1182 1183 /* we have meta data on disk */ 1184 ch_entry->src_meta_ondisk = 1; 1185 1186 /* make sure we are part of this vd */ 1187 if (volid != m->ssd_vd_volid) { 1188 printf("%s: %s invalid volume id %d, expected %d\n", 1189 DEVNAME(sc), ch_entry->src_devname, 1190 volid, m->ssd_vd_volid); 1191 no_chunk = -1; 1192 goto bad; 1193 } 1194 1195 if (m->ssd_chunk_id > m->ssd_chunk_no) { 1196 printf("%s: %s chunk id out of range %d, expected " 1197 "lower than %d\n", DEVNAME(sc), 1198 ch_entry->src_devname, 1199 m->ssd_chunk_id, m->ssd_chunk_no); 1200 no_chunk = -1; 1201 goto bad; 1202 } 1203 1204 if (sd->sd_vol.sv_chunks[m->ssd_chunk_id]) { 1205 printf("%s: %s chunk id %d already in use\n", 1206 DEVNAME(sc), ch_entry->src_devname, 1207 m->ssd_chunk_id); 1208 no_chunk = -1; 1209 goto bad; 1210 } 1211 1212 sd->sd_vol.sv_chunks[m->ssd_chunk_id] = ch_entry; 1213 bcopy(mc + m->ssd_chunk_id, &ch_entry->src_meta, 1214 sizeof(ch_entry->src_meta)); 1215 1216 if (ondisk == 0) { 1217 ondisk = m->ssd_ondisk; 1218 cid = m->ssd_chunk_id; 1219 } 1220 1221 if (m->ssd_ondisk != ondisk) { 1222 printf("%s: %s chunk id %d contains stale metadata\n", 1223 DEVNAME(sc), ch_entry->src_devname, 1224 m->ssd_ondisk < ondisk ? m->ssd_chunk_id : cid); 1225 no_chunk = -1; 1226 goto bad; 1227 } 1228 1229 /* XXX fix this check, sd_type isnt filled in yet */ 1230 if (mv->svm_level == 'C') { 1231 mo = (struct sr_opt_meta *)(mc + mv->svm_no_chunk); 1232 if (m->ssd_chunk_id > 2) { 1233 no_chunk = -1; 1234 goto bad; 1235 } 1236 bcopy(&mo->som_meta, 1237 &sd->mds.mdd_crypto.scr_meta[m->ssd_chunk_id], 1238 sizeof(sd->mds.mdd_crypto.scr_meta[m->ssd_chunk_id]) 1239 ); 1240 } 1241 } 1242 1243 if (no_chunk != m->ssd_chunk_no) { 1244 DNPRINTF(SR_D_META, "%s: not enough chunks supplied\n", 1245 DEVNAME(sc)); 1246 no_chunk = -1; 1247 goto bad; 1248 } 1249 1250 DNPRINTF(SR_D_META, "%s: sr_read_meta: found %d elements\n", 1251 DEVNAME(sc), no_chunk); 1252 1253 sr_print_metadata(m); 1254 1255 bad: 1256 /* return nr of chunks that contain metadata */ 1257 free(m, M_DEVBUF); 1258 return (no_chunk); 1259 } 1260 1261 int 1262 sr_create_chunk_meta(struct sr_softc *sc, struct sr_chunk_head *cl) 1263 { 1264 struct sr_chunk *ch_entry; 1265 struct sr_uuid uuid; 1266 int rv = 1, cid = 0; 1267 char *name; 1268 u_int64_t max_chunk_sz = 0, min_chunk_sz; 1269 1270 DNPRINTF(SR_D_IOCTL, "%s: sr_create_chunk_meta\n", DEVNAME(sc)); 1271 1272 sr_get_uuid(&uuid); 1273 1274 /* fill out stuff and get largest chunk size while looping */ 1275 SLIST_FOREACH(ch_entry, cl, src_link) { 1276 name = ch_entry->src_devname; 1277 ch_entry->src_meta.scm_size = ch_entry->src_size; 1278 ch_entry->src_meta.scm_chunk_id = cid++; 1279 ch_entry->src_meta.scm_status = BIOC_SDONLINE; 1280 strlcpy(ch_entry->src_meta.scm_devname, name, 1281 sizeof(ch_entry->src_meta.scm_devname)); 1282 bcopy(&uuid, &ch_entry->src_meta.scm_uuid, 1283 sizeof(ch_entry->src_meta.scm_uuid)); 1284 1285 if (ch_entry->src_meta.scm_size > max_chunk_sz) 1286 max_chunk_sz = ch_entry->src_meta.scm_size; 1287 } 1288 1289 /* get smallest chunk size */ 1290 min_chunk_sz = max_chunk_sz; 1291 SLIST_FOREACH(ch_entry, cl, src_link) 1292 if (ch_entry->src_meta.scm_size < min_chunk_sz) 1293 min_chunk_sz = ch_entry->src_meta.scm_size; 1294 1295 /* equalize all sizes */ 1296 SLIST_FOREACH(ch_entry, cl, src_link) 1297 ch_entry->src_meta.scm_coerced_size = min_chunk_sz; 1298 1299 /* whine if chunks are not the same size */ 1300 if (min_chunk_sz != max_chunk_sz) 1301 printf("%s: chunk sizes are not equal; up to %llu blocks " 1302 "wasted per chunk\n", 1303 DEVNAME(sc), max_chunk_sz - min_chunk_sz); 1304 1305 rv = 0; 1306 1307 return (rv); 1308 } 1309 1310 void 1311 sr_unwind_chunks(struct sr_softc *sc, struct sr_chunk_head *cl) 1312 { 1313 struct sr_chunk *ch_entry, *ch_next; 1314 dev_t dev; 1315 1316 DNPRINTF(SR_D_IOCTL, "%s: sr_unwind_chunks\n", DEVNAME(sc)); 1317 1318 if (!cl) 1319 return; 1320 1321 for (ch_entry = SLIST_FIRST(cl); 1322 ch_entry != SLIST_END(cl); ch_entry = ch_next) { 1323 ch_next = SLIST_NEXT(ch_entry, src_link); 1324 1325 dev = ch_entry->src_dev_mm; 1326 1327 if (dev != NODEV) 1328 bdevsw_lookup(dev)->d_close(dev, FWRITE, S_IFBLK, 1329 curproc); 1330 1331 free(ch_entry, M_DEVBUF); 1332 } 1333 SLIST_INIT(cl); 1334 } 1335 1336 void 1337 sr_free_discipline(struct sr_discipline *sd) 1338 { 1339 #ifdef SR_DEBUG 1340 struct sr_softc *sc = sd->sd_sc; 1341 #endif 1342 if (!sd) 1343 return; 1344 1345 DNPRINTF(SR_D_DIS, "%s: sr_free_discipline %s\n", 1346 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname); 1347 1348 if (sd->sd_free_resources) 1349 sd->sd_free_resources(sd); 1350 if (sd->sd_vol.sv_chunks) 1351 free(sd->sd_vol.sv_chunks, M_DEVBUF); 1352 free(sd, M_DEVBUF); 1353 } 1354 1355 void 1356 sr_shutdown_discipline(struct sr_discipline *sd) 1357 { 1358 struct sr_softc *sc = sd->sd_sc; 1359 int s; 1360 1361 if (!sd || !sc) 1362 return; 1363 1364 DNPRINTF(SR_D_DIS, "%s: sr_shutdown_discipline %s\n", 1365 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname); 1366 1367 s = splbio(); 1368 1369 /* make sure there isn't a sync pending and yield */ 1370 wakeup(sd); 1371 while (sd->sd_sync || sd->sd_must_flush) 1372 if (tsleep(&sd->sd_sync, MAXPRI, "sr_down", 60 * hz) == 1373 EWOULDBLOCK) 1374 break; 1375 1376 #ifndef SMALL_KERNEL 1377 sr_delete_sensors(sd); 1378 #endif /* SMALL_KERNEL */ 1379 1380 if (sd->sd_scsibus_dev) 1381 config_detach(sd->sd_scsibus_dev, DETACH_FORCE); 1382 1383 sr_unwind_chunks(sc, &sd->sd_vol.sv_chunk_list); 1384 1385 if (sd) 1386 sr_free_discipline(sd); 1387 1388 splx(s); 1389 } 1390 1391 int 1392 sr_raid_inquiry(struct sr_workunit *wu) 1393 { 1394 struct sr_discipline *sd = wu->swu_dis; 1395 struct scsi_xfer *xs = wu->swu_xs; 1396 struct scsi_inquiry_data inq; 1397 1398 DNPRINTF(SR_D_DIS, "%s: sr_raid_inquiry\n", DEVNAME(sd->sd_sc)); 1399 1400 bzero(&inq, sizeof(inq)); 1401 inq.device = T_DIRECT; 1402 inq.dev_qual2 = 0; 1403 inq.version = 2; 1404 inq.response_format = 2; 1405 inq.additional_length = 32; 1406 strlcpy(inq.vendor, sd->sd_vol.sv_meta.svm_vendor, 1407 sizeof(inq.vendor)); 1408 strlcpy(inq.product, sd->sd_vol.sv_meta.svm_product, 1409 sizeof(inq.product)); 1410 strlcpy(inq.revision, sd->sd_vol.sv_meta.svm_revision, 1411 sizeof(inq.revision)); 1412 sr_copy_internal_data(xs, &inq, sizeof(inq)); 1413 1414 return (0); 1415 } 1416 1417 int 1418 sr_raid_read_cap(struct sr_workunit *wu) 1419 { 1420 struct sr_discipline *sd = wu->swu_dis; 1421 struct scsi_xfer *xs = wu->swu_xs; 1422 struct scsi_read_cap_data rcd; 1423 struct scsi_read_cap_data_16 rcd16; 1424 int rv = 1; 1425 1426 DNPRINTF(SR_D_DIS, "%s: sr_raid_read_cap\n", DEVNAME(sd->sd_sc)); 1427 1428 if (xs->cmd->opcode == READ_CAPACITY) { 1429 bzero(&rcd, sizeof(rcd)); 1430 if (sd->sd_vol.sv_meta.svm_size > 0xffffffffllu) 1431 _lto4b(0xffffffff, rcd.addr); 1432 else 1433 _lto4b(sd->sd_vol.sv_meta.svm_size, rcd.addr); 1434 _lto4b(512, rcd.length); 1435 sr_copy_internal_data(xs, &rcd, sizeof(rcd)); 1436 rv = 0; 1437 } else if (xs->cmd->opcode == READ_CAPACITY_16) { 1438 bzero(&rcd16, sizeof(rcd16)); 1439 _lto8b(sd->sd_vol.sv_meta.svm_size, rcd16.addr); 1440 _lto4b(512, rcd16.length); 1441 sr_copy_internal_data(xs, &rcd16, sizeof(rcd16)); 1442 rv = 0; 1443 } 1444 1445 return (rv); 1446 } 1447 1448 int 1449 sr_raid_tur(struct sr_workunit *wu) 1450 { 1451 struct sr_discipline *sd = wu->swu_dis; 1452 1453 DNPRINTF(SR_D_DIS, "%s: sr_raid_tur\n", DEVNAME(sd->sd_sc)); 1454 1455 if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) { 1456 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT; 1457 sd->sd_scsi_sense.flags = SKEY_NOT_READY; 1458 sd->sd_scsi_sense.add_sense_code = 0x04; 1459 sd->sd_scsi_sense.add_sense_code_qual = 0x11; 1460 sd->sd_scsi_sense.extra_len = 4; 1461 return (1); 1462 } else if (sd->sd_vol.sv_meta.svm_status == BIOC_SVINVALID) { 1463 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT; 1464 sd->sd_scsi_sense.flags = SKEY_HARDWARE_ERROR; 1465 sd->sd_scsi_sense.add_sense_code = 0x05; 1466 sd->sd_scsi_sense.add_sense_code_qual = 0x00; 1467 sd->sd_scsi_sense.extra_len = 4; 1468 return (1); 1469 } 1470 1471 return (0); 1472 } 1473 1474 int 1475 sr_raid_request_sense(struct sr_workunit *wu) 1476 { 1477 struct sr_discipline *sd = wu->swu_dis; 1478 struct scsi_xfer *xs = wu->swu_xs; 1479 1480 DNPRINTF(SR_D_DIS, "%s: sr_raid_request_sense\n", 1481 DEVNAME(sd->sd_sc)); 1482 1483 /* use latest sense data */ 1484 bcopy(&sd->sd_scsi_sense, &xs->sense, sizeof(xs->sense)); 1485 1486 /* clear sense data */ 1487 bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense)); 1488 1489 return (0); 1490 } 1491 1492 int 1493 sr_raid_start_stop(struct sr_workunit *wu) 1494 { 1495 struct sr_discipline *sd = wu->swu_dis; 1496 struct scsi_xfer *xs = wu->swu_xs; 1497 struct scsi_start_stop *ss = (struct scsi_start_stop *)xs->cmd; 1498 int rv = 1; 1499 1500 DNPRINTF(SR_D_DIS, "%s: sr_raid_start_stop\n", 1501 DEVNAME(sd->sd_sc)); 1502 1503 if (!ss) 1504 return (rv); 1505 1506 if (ss->byte2 == 0x00) { 1507 /* START */ 1508 if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) { 1509 /* bring volume online */ 1510 /* XXX check to see if volume can be brought online */ 1511 sd->sd_vol.sv_meta.svm_status = BIOC_SVONLINE; 1512 } 1513 rv = 0; 1514 } else /* XXX is this the check? if (byte == 0x01) */ { 1515 /* STOP */ 1516 if (sd->sd_vol.sv_meta.svm_status == BIOC_SVONLINE) { 1517 /* bring volume offline */ 1518 sd->sd_vol.sv_meta.svm_status = BIOC_SVOFFLINE; 1519 } 1520 rv = 0; 1521 } 1522 1523 return (rv); 1524 } 1525 1526 int 1527 sr_raid_sync(struct sr_workunit *wu) 1528 { 1529 struct sr_discipline *sd = wu->swu_dis; 1530 int s, rv = 0, ios; 1531 1532 DNPRINTF(SR_D_DIS, "%s: sr_raid_sync\n", DEVNAME(sd->sd_sc)); 1533 1534 /* when doing a fake sync don't coun't the wu */ 1535 ios = wu->swu_fake ? 0 : 1; 1536 1537 s = splbio(); 1538 sd->sd_sync = 1; 1539 1540 while (sd->sd_wu_pending > ios) 1541 if (tsleep(sd, PRIBIO, "sr_sync", 15 * hz) == EWOULDBLOCK) { 1542 DNPRINTF(SR_D_DIS, "%s: sr_raid_sync timeout\n", 1543 DEVNAME(sd->sd_sc)); 1544 rv = 1; 1545 break; 1546 } 1547 1548 sd->sd_sync = 0; 1549 splx(s); 1550 1551 wakeup(&sd->sd_sync); 1552 1553 return (rv); 1554 } 1555 1556 void 1557 sr_raid_startwu(struct sr_workunit *wu) 1558 { 1559 struct sr_discipline *sd = wu->swu_dis; 1560 struct sr_ccb *ccb; 1561 1562 splassert(IPL_BIO); 1563 1564 if (wu->swu_state == SR_WU_RESTART) 1565 /* 1566 * no need to put the wu on the pending queue since we 1567 * are restarting the io 1568 */ 1569 ; 1570 else 1571 /* move wu to pending queue */ 1572 TAILQ_INSERT_TAIL(&sd->sd_wu_pendq, wu, swu_link); 1573 1574 /* start all individual ios */ 1575 TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) { 1576 bdevsw_lookup(ccb->ccb_buf.b_dev)->d_strategy(&ccb->ccb_buf); 1577 } 1578 } 1579 1580 u_int32_t 1581 sr_checksum(char *s, u_int32_t *p, u_int32_t size) 1582 { 1583 u_int32_t chk = 0; 1584 int i; 1585 1586 DNPRINTF(SR_D_MISC, "%s: sr_checksum %p %d\n", s, p, size); 1587 1588 if (size % sizeof(u_int32_t)) 1589 return (0); /* 0 is failure */ 1590 1591 for (i = 0; i < size / sizeof(u_int32_t); i++) 1592 chk ^= p[i]; 1593 1594 return (chk); 1595 } 1596 1597 void 1598 sr_get_uuid(struct sr_uuid *uuid) 1599 { 1600 arc4random_bytes(uuid->sui_id, sizeof(uuid->sui_id)); 1601 } 1602 1603 void 1604 sr_print_uuid(struct sr_uuid *uuid, int cr) 1605 { 1606 int i; 1607 1608 for (i = 0; i < SR_UUID_MAX; i++) 1609 printf("%x%s", uuid->sui_id[i], 1610 i < SR_UUID_MAX - 1 ? ":" : ""); 1611 1612 if (cr) 1613 printf("\n"); 1614 } 1615 1616 int 1617 sr_clear_metadata(struct sr_discipline *sd) 1618 { 1619 struct sr_softc *sc = sd->sd_sc; 1620 struct sr_chunk_head *cl = &sd->sd_vol.sv_chunk_list; 1621 struct sr_chunk *ch_entry; 1622 struct buf b; 1623 size_t sz = SR_META_SIZE * 512; 1624 void *m; 1625 int rv = 0; 1626 1627 DNPRINTF(SR_D_META, "%s: sr_clear_metadata\n", DEVNAME(sc)); 1628 1629 m = malloc(sz , M_DEVBUF, M_WAITOK | M_ZERO); 1630 1631 SLIST_FOREACH(ch_entry, cl, src_link) { 1632 bzero(&b, sizeof(b)); 1633 1634 b.b_flags = B_WRITE; 1635 b.b_blkno = SR_META_OFFSET; 1636 b.b_bcount = sz; 1637 b.b_bufsize = sz; 1638 b.b_resid = sz; 1639 b.b_data = (void *)m; 1640 b.b_error = 0; 1641 b.b_proc = curproc; 1642 b.b_dev = ch_entry->src_dev_mm; 1643 b.b_vp = NULL; 1644 b.b_iodone = NULL; 1645 LIST_INIT(&b.b_dep); 1646 bdevsw_lookup(b.b_dev)->d_strategy(&b); 1647 biowait(&b); 1648 1649 if (b.b_flags & B_ERROR) { 1650 printf("%s: %s i/o error on block %d while clearing " 1651 "metadata %d\n", DEVNAME(sc), 1652 ch_entry->src_devname, b.b_blkno, b.b_error); 1653 rv++; 1654 continue; 1655 } 1656 } 1657 1658 free(m, M_DEVBUF); 1659 return (rv); 1660 } 1661 1662 int 1663 sr_already_assembled(struct sr_discipline *sd) 1664 { 1665 struct sr_softc *sc = sd->sd_sc; 1666 int i; 1667 1668 for (i = 0; i < SR_MAXSCSIBUS; i++) 1669 if (sc->sc_dis[i]) 1670 if (!bcmp(&sd->sd_meta->ssd_uuid, 1671 &sc->sc_dis[i]->sd_meta->ssd_uuid, 1672 sizeof(sd->sd_meta->ssd_uuid))) 1673 return (1); 1674 1675 return (0); 1676 } 1677 1678 void 1679 sr_save_metadata_callback(void *arg1, void *arg2) 1680 { 1681 struct sr_discipline *sd = arg1; 1682 int s; 1683 1684 s = splbio(); 1685 1686 if (sr_save_metadata(arg1, SR_VOL_DIRTY)) 1687 printf("%s: save metadata failed\n", 1688 DEVNAME(sd->sd_sc)); 1689 1690 sd->sd_must_flush = 0; 1691 splx(s); 1692 } 1693 1694 int 1695 sr_save_metadata(struct sr_discipline *sd, u_int32_t flags) 1696 { 1697 struct sr_softc *sc = sd->sd_sc; 1698 struct sr_metadata *sm = sd->sd_meta; 1699 struct sr_vol_meta *sv = &sd->sd_vol.sv_meta, *im_sv; 1700 struct sr_chunk_meta *im_sc; 1701 struct sr_opt_meta *im_so; 1702 struct sr_chunk *src; 1703 struct buf b; 1704 struct sr_workunit wu; 1705 int i, rv = 1, ch = 0, no_chunk, sz_opt; 1706 size_t sz = SR_META_SIZE * 512; 1707 1708 DNPRINTF(SR_D_META, "%s: sr_save_metadata %s\n", 1709 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname); 1710 1711 if (!sm) { 1712 printf("%s: no in memory copy of metadata\n", DEVNAME(sc)); 1713 goto bad; 1714 } 1715 1716 im_sv = (struct sr_vol_meta *)(sm + 1); 1717 im_sc = (struct sr_chunk_meta *)(im_sv + 1); 1718 no_chunk = sd->sd_vol.sv_meta.svm_no_chunk; 1719 im_so = (struct sr_opt_meta *)(im_sc + no_chunk); 1720 1721 /* XXX this is a temporary hack until meta is properly redone */ 1722 if (sd->sd_type == SR_MD_CRYPTO) 1723 sz_opt = sizeof(struct sr_opt_meta); 1724 else 1725 sz_opt = 0; 1726 1727 if (sizeof(struct sr_metadata) + sizeof(struct sr_vol_meta) + 1728 (sizeof(struct sr_chunk_meta) * no_chunk) + 1729 sz_opt > sz) { 1730 printf("%s: too much metadata; metadata NOT written\n", 1731 DEVNAME(sc)); 1732 goto bad; 1733 } 1734 1735 if (sm->ssd_magic == 0) { 1736 /* initial metadata */ 1737 sm->ssd_magic = SR_MAGIC; 1738 sm->ssd_version = SR_META_VERSION; 1739 sm->ssd_size = sizeof(struct sr_metadata); 1740 sm->ssd_ondisk = 0; 1741 sm->ssd_flags = sd->sd_meta_flags; 1742 /* get uuid from chunk 0 */ 1743 bcopy(&sd->sd_vol.sv_chunks[0]->src_meta.scm_uuid, 1744 &sm->ssd_uuid, 1745 sizeof(struct sr_uuid)); 1746 1747 /* volume */ 1748 bcopy(sv, im_sv, sizeof(struct sr_vol_meta)); 1749 bcopy(&sm->ssd_uuid, &im_sv->svm_uuid, 1750 sizeof(im_sv->svm_uuid)); 1751 sm->ssd_vd_ver = SR_VOL_VERSION; 1752 sm->ssd_vd_size = sizeof(struct sr_vol_meta); 1753 1754 /* chunk */ 1755 for (i = 0; i < no_chunk; i++) 1756 bcopy(sd->sd_vol.sv_chunks[i], &im_sc[i], 1757 sizeof(struct sr_chunk_meta)); 1758 1759 sm->ssd_chunk_ver = SR_CHUNK_VERSION; 1760 sm->ssd_chunk_size = sizeof(struct sr_chunk_meta); 1761 sm->ssd_chunk_no = no_chunk; 1762 1763 /* optional */ 1764 sm->ssd_opt_ver = SR_OPT_VERSION; 1765 if (sd->sd_type == SR_MD_CRYPTO) { 1766 bzero(im_so, sizeof(*im_so)); 1767 sm->ssd_opt_size = sizeof(struct sr_opt_meta); 1768 sm->ssd_opt_no = 1; 1769 } else { 1770 sm->ssd_opt_size = 0; 1771 sm->ssd_opt_no = 0; 1772 } 1773 } 1774 1775 /* from here on out metadata is updated */ 1776 sm->ssd_ondisk++; 1777 im_sv->svm_flags |= flags; 1778 sm->ssd_vd_chk = sr_checksum(DEVNAME(sc), 1779 (u_int32_t *)im_sv, sm->ssd_vd_size); 1780 1781 sm->ssd_chunk_chk = 0; 1782 for (ch = 0; ch < sm->ssd_chunk_no; ch++) 1783 sm->ssd_chunk_chk ^= sr_checksum(DEVNAME(sc), 1784 (u_int32_t *)&im_sc[ch], sm->ssd_chunk_size); 1785 1786 /* XXX do checksum on optional meta too */ 1787 1788 sr_print_metadata(sm); 1789 1790 for (i = 0; i < sm->ssd_chunk_no; i++) { 1791 memset(&b, 0, sizeof(b)); 1792 1793 src = sd->sd_vol.sv_chunks[i]; 1794 1795 /* skip disks that are offline */ 1796 if (src->src_meta.scm_status == BIOC_SDOFFLINE) 1797 continue; 1798 1799 /* copy encrypted key / passphrase into optinal metadata area */ 1800 if (sd->sd_type == SR_MD_CRYPTO && i < 2) { 1801 im_so->som_type = SR_OPT_CRYPTO; 1802 bcopy(&sd->mds.mdd_crypto.scr_meta[i], 1803 &im_so->som_meta.smm_crypto, 1804 sizeof(im_so->som_meta.smm_crypto)); 1805 } 1806 1807 /* calculate metdata checksum and ids */ 1808 sm->ssd_vd_volid = im_sv->svm_volid; 1809 sm->ssd_chunk_id = i; 1810 sm->ssd_checksum = sr_checksum(DEVNAME(sc), 1811 (u_int32_t *)sm, sm->ssd_size); 1812 1813 DNPRINTF(SR_D_META, "%s: sr_save_metadata %s: volid: %d " 1814 "chunkid: %d checksum: 0x%x\n", 1815 DEVNAME(sc), src->src_meta.scm_devname, 1816 sm->ssd_vd_volid, sm->ssd_chunk_id, 1817 sm->ssd_checksum); 1818 1819 b.b_flags = B_WRITE; 1820 b.b_blkno = SR_META_OFFSET; 1821 b.b_bcount = sz; 1822 b.b_bufsize = sz; 1823 b.b_resid = sz; 1824 b.b_data = (void *)sm; 1825 b.b_error = 0; 1826 b.b_proc = curproc; 1827 b.b_dev = src->src_dev_mm; 1828 b.b_vp = NULL; 1829 b.b_iodone = NULL; 1830 LIST_INIT(&b.b_dep); 1831 bdevsw_lookup(b.b_dev)->d_strategy(&b); 1832 1833 biowait(&b); 1834 1835 /* make sure in memory copy is clean */ 1836 if (sd->sd_type == SR_MD_CRYPTO) 1837 bzero(im_so, sizeof(*im_so)); 1838 sm->ssd_vd_volid = 0; 1839 sm->ssd_chunk_id = 0; 1840 sm->ssd_checksum = 0; 1841 1842 /* XXX do something smart here */ 1843 /* mark chunk offline and restart metadata write */ 1844 if (b.b_flags & B_ERROR) { 1845 printf("%s: %s i/o error on block %d while writing " 1846 "metadata %d\n", DEVNAME(sc), 1847 src->src_meta.scm_devname, b.b_blkno, b.b_error); 1848 goto bad; 1849 } 1850 1851 DNPRINTF(SR_D_META, "%s: sr_save_metadata written to %s\n", 1852 DEVNAME(sc), src->src_meta.scm_devname); 1853 } 1854 1855 bzero(&wu, sizeof(wu)); 1856 wu.swu_fake = 1; 1857 wu.swu_dis = sd; 1858 sd->sd_scsi_sync(&wu); 1859 1860 rv = 0; 1861 bad: 1862 return (rv); 1863 } 1864 1865 int 1866 sr_boot_assembly(struct sr_softc *sc) 1867 { 1868 struct device *dv; 1869 struct buf *bp; 1870 struct bdevsw *bdsw; 1871 struct disklabel label; 1872 struct sr_metadata *sm; 1873 struct sr_metadata_list_head mlh; 1874 struct sr_metadata_list *mle, *mle2; 1875 struct sr_vol_meta *vm; 1876 struct bioc_createraid bc; 1877 dev_t dev, devr, *dt = NULL; 1878 int error, majdev, i, no_dev, rv = 0; 1879 size_t sz = SR_META_SIZE * 512; 1880 1881 DNPRINTF(SR_D_META, "%s: sr_boot_assembly\n", DEVNAME(sc)); 1882 1883 SLIST_INIT(&mlh); 1884 bp = geteblk(sz); 1885 if (!bp) 1886 return (ENOMEM); 1887 1888 TAILQ_FOREACH(dv, &alldevs, dv_list) { 1889 if (dv->dv_class != DV_DISK) 1890 continue; 1891 1892 majdev = findblkmajor(dv); 1893 if (majdev == -1) 1894 continue; 1895 1896 bp->b_dev = dev = MAKEDISKDEV(majdev, dv->dv_unit, RAW_PART); 1897 bdsw = &bdevsw[majdev]; 1898 1899 /* XXX is there a better way of excluding some devices? */ 1900 if (!strncmp(dv->dv_xname, "fd", 2) || 1901 !strncmp(dv->dv_xname, "cd", 2) || 1902 !strncmp(dv->dv_xname, "rx", 2)) 1903 continue; 1904 /* 1905 * The devices are being opened with S_IFCHR instead of 1906 * S_IFBLK so that the SCSI mid-layer does not whine when 1907 * media is not inserted in certain devices like zip drives 1908 * and such. 1909 */ 1910 1911 /* open device */ 1912 error = (*bdsw->d_open)(dev, FREAD, S_IFCHR, curproc); 1913 if (error) { 1914 DNPRINTF(SR_D_META, "%s: sr_boot_assembly open failed" 1915 "\n", DEVNAME(sc)); 1916 continue; 1917 } 1918 1919 /* get disklabel */ 1920 error = (*bdsw->d_ioctl)(dev, DIOCGDINFO, (void *)&label, 1921 FREAD, curproc); 1922 if (error) { 1923 DNPRINTF(SR_D_META, "%s: sr_boot_assembly ioctl " 1924 "failed\n", DEVNAME(sc)); 1925 error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc); 1926 continue; 1927 } 1928 1929 /* we are done, close device */ 1930 error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc); 1931 if (error) { 1932 DNPRINTF(SR_D_META, "%s: sr_boot_assembly close " 1933 "failed\n", DEVNAME(sc)); 1934 continue; 1935 } 1936 1937 /* are we a softraid partition? */ 1938 for (i = 0; i < MAXPARTITIONS; i++) { 1939 if (label.d_partitions[i].p_fstype != FS_RAID) 1940 continue; 1941 1942 /* open device */ 1943 bp->b_dev = devr = MAKEDISKDEV(majdev, dv->dv_unit, i); 1944 error = (*bdsw->d_open)(devr, FREAD, S_IFCHR, curproc); 1945 if (error) { 1946 DNPRINTF(SR_D_META, "%s: sr_boot_assembly " 1947 "open failed, partition %d\n", 1948 DEVNAME(sc), i); 1949 continue; 1950 } 1951 /* read metadat */ 1952 bp->b_flags = B_BUSY | B_READ; 1953 bp->b_blkno = SR_META_OFFSET; 1954 bp->b_cylinder = 0; 1955 bp->b_bcount = sz; 1956 bp->b_bufsize = sz; 1957 bp->b_resid = sz; 1958 (*bdsw->d_strategy)(bp); 1959 if ((error = biowait(bp))) { 1960 DNPRINTF(SR_D_META, "%s: sr_boot_assembly " 1961 "strategy failed, partition %d\n", 1962 DEVNAME(sc)); 1963 error = (*bdsw->d_close)(devr, FREAD, S_IFCHR, 1964 curproc); 1965 continue; 1966 } 1967 1968 sm = (struct sr_metadata *)bp->b_data; 1969 if (!sr_validate_metadata(sc, devr, sm)) { 1970 /* we got one; save it off */ 1971 mle = malloc(sizeof(*mle), M_DEVBUF, 1972 M_WAITOK | M_ZERO); 1973 mle->sml_metadata = malloc(sz, M_DEVBUF, 1974 M_WAITOK | M_ZERO); 1975 bcopy(sm, mle->sml_metadata, sz); 1976 mle->sml_mm = devr; 1977 SLIST_INSERT_HEAD(&mlh, mle, sml_link); 1978 } 1979 1980 /* we are done, close device */ 1981 error = (*bdsw->d_close)(devr, FREAD, S_IFCHR, 1982 curproc); 1983 if (error) { 1984 DNPRINTF(SR_D_META, "%s: sr_boot_assembly " 1985 "close failed\n", DEVNAME(sc)); 1986 continue; 1987 } 1988 } 1989 } 1990 1991 /* 1992 * XXX poor mans hack that doesn't keep disks in order and does not 1993 * roam disks correctly. replace this with something smarter that 1994 * orders disks by volid, chunkid and uuid. 1995 */ 1996 dt = malloc(BIOC_CRMAXLEN, M_DEVBUF, M_WAITOK); 1997 SLIST_FOREACH(mle, &mlh, sml_link) { 1998 /* chunk used already? */ 1999 if (mle->sml_used) 2000 continue; 2001 2002 no_dev = 0; 2003 bzero(dt, BIOC_CRMAXLEN); 2004 SLIST_FOREACH(mle2, &mlh, sml_link) { 2005 /* chunk used already? */ 2006 if (mle2->sml_used) 2007 continue; 2008 2009 /* are we the same volume? */ 2010 if (mle->sml_metadata->ssd_vd_volid != 2011 mle2->sml_metadata->ssd_vd_volid) 2012 continue; 2013 2014 /* same uuid? */ 2015 if (bcmp(&mle->sml_metadata->ssd_uuid, 2016 &mle2->sml_metadata->ssd_uuid, 2017 sizeof(mle->sml_metadata->ssd_uuid))) 2018 continue; 2019 2020 /* sanity */ 2021 if (dt[mle2->sml_metadata->ssd_chunk_id]) { 2022 printf("%s: chunk id already in use; can not " 2023 "assemble volume\n", DEVNAME(sc)); 2024 goto unwind; 2025 } 2026 dt[mle2->sml_metadata->ssd_chunk_id] = mle2->sml_mm; 2027 no_dev++; 2028 mle2->sml_used = 1; 2029 } 2030 if (mle->sml_metadata->ssd_chunk_no != no_dev) { 2031 printf("%s: not assembling partial disk that used to " 2032 "be volume %d\n", DEVNAME(sc), 2033 mle->sml_metadata->ssd_vd_volid); 2034 continue; 2035 } 2036 2037 bzero(&bc, sizeof(bc)); 2038 vm = (struct sr_vol_meta *)(mle->sml_metadata + 1); 2039 bc.bc_level = vm->svm_level; 2040 bc.bc_dev_list_len = no_dev * sizeof(dev_t); 2041 bc.bc_dev_list = dt; 2042 bc.bc_flags = BIOC_SCDEVT; 2043 sr_ioctl_createraid(sc, &bc, 0); 2044 rv++; 2045 } 2046 2047 unwind: 2048 if (dt) 2049 free(dt, M_DEVBUF); 2050 2051 for (mle = SLIST_FIRST(&mlh); mle != SLIST_END(&mlh); mle = mle2) { 2052 mle2 = SLIST_NEXT(mle, sml_link); 2053 2054 free(mle->sml_metadata, M_DEVBUF); 2055 free(mle, M_DEVBUF); 2056 } 2057 SLIST_INIT(&mlh); 2058 2059 return (rv); 2060 } 2061 2062 int 2063 sr_validate_metadata(struct sr_softc *sc, dev_t dev, struct sr_metadata *sm) 2064 { 2065 struct sr_vol_meta *mv; 2066 struct sr_chunk_meta *mc; 2067 char *name, devname[32]; 2068 int maj, part, unit; 2069 u_int32_t chk; 2070 2071 DNPRINTF(SR_D_META, "%s: sr_validate_metadata(0x%x)\n", 2072 DEVNAME(sc), dev); 2073 2074 bzero(devname, sizeof(devname)); 2075 2076 if (sm->ssd_magic != SR_MAGIC) 2077 goto bad; 2078 2079 maj = major(dev); 2080 part = DISKPART(dev); 2081 unit = DISKUNIT(dev); 2082 2083 name = findblkname(maj); 2084 if (name == NULL) 2085 goto bad; 2086 2087 snprintf(devname, sizeof(devname), 2088 "%s%d%c", name, unit, part + 'a'); 2089 name = devname; 2090 2091 /* validate metadata */ 2092 if (sm->ssd_version != SR_META_VERSION) { 2093 printf("%s: %s can not read metadata version %d, " 2094 "expected %d\n", DEVNAME(sc), 2095 devname, sm->ssd_version, 2096 SR_META_VERSION); 2097 goto bad; 2098 } 2099 if (sm->ssd_size != sizeof(struct sr_metadata)) { 2100 printf("%s: %s invalid metadata size %d, " 2101 "expected %d\n", DEVNAME(sc), 2102 devname, sm->ssd_size, 2103 sizeof(struct sr_metadata)); 2104 goto bad; 2105 } 2106 chk = sr_checksum(DEVNAME(sc), (u_int32_t *)sm, sm->ssd_size); 2107 /* 2108 * since the checksum value is part of the checksum a good 2109 * result equals 0 2110 */ 2111 if (chk != 0) { 2112 printf("%s: %s invalid metadata checksum 0x%x, " 2113 "expected 0x%x\n", DEVNAME(sc), 2114 devname, sm->ssd_checksum, chk); 2115 goto bad; 2116 } 2117 2118 /* validate volume metadata */ 2119 if (sm->ssd_vd_ver != SR_VOL_VERSION) { 2120 printf("%s: %s can not read volume metadata version " 2121 "%d, expected %d\n", DEVNAME(sc), 2122 devname, sm->ssd_vd_ver, 2123 SR_VOL_VERSION); 2124 goto bad; 2125 } 2126 if (sm->ssd_vd_size != sizeof(struct sr_vol_meta)) { 2127 printf("%s: %s invalid volume metadata size %d, " 2128 "expected %d\n", DEVNAME(sc), 2129 devname, sm->ssd_vd_size, 2130 sizeof(struct sr_vol_meta)); 2131 goto bad; 2132 } 2133 mv = (struct sr_vol_meta *)(sm + 1); 2134 chk = sr_checksum(DEVNAME(sc), (u_int32_t *)mv, sm->ssd_vd_size); 2135 if (chk != sm->ssd_vd_chk) { 2136 printf("%s: %s invalid volume metadata checksum 0x%x, " 2137 "expected 0x%x\n", DEVNAME(sc), 2138 devname, sm->ssd_vd_chk, chk); 2139 goto bad; 2140 } 2141 2142 /* validate chunk metadata */ 2143 if (sm->ssd_chunk_ver != SR_CHUNK_VERSION) { 2144 printf("%s: %s can not read chunk metadata version " 2145 "%d, expected %d\n", DEVNAME(sc), 2146 devname, sm->ssd_chunk_ver, 2147 SR_CHUNK_VERSION); 2148 goto bad; 2149 } 2150 if (sm->ssd_chunk_size != sizeof(struct sr_chunk_meta)) { 2151 printf("%s: %s invalid chunk metadata size %d, " 2152 "expected %d\n", DEVNAME(sc), 2153 devname, sm->ssd_chunk_size, 2154 sizeof(struct sr_chunk_meta)); 2155 goto bad; 2156 } 2157 2158 mc = (struct sr_chunk_meta *)(mv + 1); 2159 /* checksum is calculated over ALL chunks */ 2160 chk = sr_checksum(DEVNAME(sc), (u_int32_t *)(mc), 2161 sm->ssd_chunk_size * sm->ssd_chunk_no); 2162 2163 if (chk != sm->ssd_chunk_chk) { 2164 printf("%s: %s invalid chunk metadata checksum 0x%x, " 2165 "expected 0x%x\n", DEVNAME(sc), 2166 devname, sm->ssd_chunk_chk, chk); 2167 goto bad; 2168 } 2169 2170 /* warn if disk changed order */ 2171 if (strncmp(mc[sm->ssd_chunk_id].scm_devname, name, 2172 sizeof(mc[sm->ssd_chunk_id].scm_devname))) 2173 printf("%s: roaming device %s -> %s\n", DEVNAME(sc), 2174 mc[sm->ssd_chunk_id].scm_devname, name); 2175 2176 /* we have meta data on disk */ 2177 DNPRINTF(SR_D_META, "%s: sr_validate_metadata valid metadata %s\n", 2178 DEVNAME(sc), devname); 2179 2180 return (0); 2181 bad: 2182 DNPRINTF(SR_D_META, "%s: sr_validate_metadata invalid metadata %s\n", 2183 DEVNAME(sc), devname); 2184 2185 return (1); 2186 } 2187 2188 int32_t 2189 sr_validate_stripsize(u_int32_t b) 2190 { 2191 int s = 0; 2192 2193 if (b % 512) 2194 return (-1); 2195 2196 while ((b & 1) == 0) { 2197 b >>= 1; 2198 s++; 2199 } 2200 2201 /* only multiple of twos */ 2202 b >>= 1; 2203 if (b) 2204 return(-1); 2205 2206 return (s); 2207 } 2208 2209 void 2210 sr_shutdown(void *arg) 2211 { 2212 struct sr_discipline *sd = arg; 2213 #ifdef SR_DEBUG 2214 struct sr_softc *sc = sd->sd_sc; 2215 #endif 2216 DNPRINTF(SR_D_DIS, "%s: sr_shutdown %s\n", 2217 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname); 2218 2219 sr_save_metadata(sd, 0); 2220 2221 sr_shutdown_discipline(sd); 2222 } 2223 2224 int 2225 sr_validate_io(struct sr_workunit *wu, daddr64_t *blk, char *func) 2226 { 2227 struct sr_discipline *sd = wu->swu_dis; 2228 struct scsi_xfer *xs = wu->swu_xs; 2229 int rv = 1; 2230 2231 DNPRINTF(SR_D_DIS, "%s: %s 0x%02x\n", DEVNAME(sd->sd_sc), func, 2232 xs->cmd->opcode); 2233 2234 if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) { 2235 DNPRINTF(SR_D_DIS, "%s: %s device offline\n", 2236 DEVNAME(sd->sd_sc)); 2237 goto bad; 2238 } 2239 2240 if (xs->datalen == 0) { 2241 printf("%s: %s: illegal block count\n", 2242 DEVNAME(sd->sd_sc), func, sd->sd_vol.sv_meta.svm_devname); 2243 goto bad; 2244 } 2245 2246 if (xs->cmdlen == 10) 2247 *blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr); 2248 else if (xs->cmdlen == 16) 2249 *blk = _8btol(((struct scsi_rw_16 *)xs->cmd)->addr); 2250 else if (xs->cmdlen == 6) 2251 *blk = _3btol(((struct scsi_rw *)xs->cmd)->addr); 2252 else { 2253 printf("%s: %s: illegal cmdlen\n", DEVNAME(sd->sd_sc), func, 2254 sd->sd_vol.sv_meta.svm_devname); 2255 goto bad; 2256 } 2257 2258 wu->swu_blk_start = *blk; 2259 wu->swu_blk_end = *blk + (xs->datalen >> DEV_BSHIFT) - 1; 2260 2261 if (wu->swu_blk_end > sd->sd_vol.sv_meta.svm_size) { 2262 DNPRINTF(SR_D_DIS, "%s: %s out of bounds start: %lld " 2263 "end: %lld length: %d\n", 2264 DEVNAME(sd->sd_sc), func, wu->swu_blk_start, 2265 wu->swu_blk_end, xs->datalen); 2266 2267 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT | 2268 SSD_ERRCODE_VALID; 2269 sd->sd_scsi_sense.flags = SKEY_ILLEGAL_REQUEST; 2270 sd->sd_scsi_sense.add_sense_code = 0x21; 2271 sd->sd_scsi_sense.add_sense_code_qual = 0x00; 2272 sd->sd_scsi_sense.extra_len = 4; 2273 goto bad; 2274 } 2275 2276 rv = 0; 2277 bad: 2278 return (rv); 2279 } 2280 2281 int 2282 sr_check_io_collision(struct sr_workunit *wu) 2283 { 2284 struct sr_discipline *sd = wu->swu_dis; 2285 struct sr_workunit *wup; 2286 2287 splassert(IPL_BIO); 2288 2289 /* walk queue backwards and fill in collider if we have one */ 2290 TAILQ_FOREACH_REVERSE(wup, &sd->sd_wu_pendq, sr_wu_list, swu_link) { 2291 if (wu->swu_blk_end < wup->swu_blk_start || 2292 wup->swu_blk_end < wu->swu_blk_start) 2293 continue; 2294 2295 /* we have an LBA collision, defer wu */ 2296 wu->swu_state = SR_WU_DEFERRED; 2297 if (wup->swu_collider) 2298 /* wu is on deferred queue, append to last wu */ 2299 while (wup->swu_collider) 2300 wup = wup->swu_collider; 2301 2302 wup->swu_collider = wu; 2303 TAILQ_INSERT_TAIL(&sd->sd_wu_defq, wu, swu_link); 2304 sd->sd_wu_collisions++; 2305 goto queued; 2306 } 2307 2308 return (0); 2309 queued: 2310 return (1); 2311 } 2312 2313 #ifndef SMALL_KERNEL 2314 int 2315 sr_create_sensors(struct sr_discipline *sd) 2316 { 2317 struct sr_softc *sc = sd->sd_sc; 2318 int rv = 1; 2319 2320 DNPRINTF(SR_D_STATE, "%s: %s: sr_create_sensors\n", 2321 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname); 2322 2323 strlcpy(sd->sd_vol.sv_sensordev.xname, DEVNAME(sc), 2324 sizeof(sd->sd_vol.sv_sensordev.xname)); 2325 2326 sd->sd_vol.sv_sensor.type = SENSOR_DRIVE; 2327 sd->sd_vol.sv_sensor.status = SENSOR_S_UNKNOWN; 2328 strlcpy(sd->sd_vol.sv_sensor.desc, sd->sd_vol.sv_meta.svm_devname, 2329 sizeof(sd->sd_vol.sv_sensor.desc)); 2330 2331 sensor_attach(&sd->sd_vol.sv_sensordev, &sd->sd_vol.sv_sensor); 2332 2333 if (sc->sc_sensors_running == 0) { 2334 if (sensor_task_register(sc, sr_refresh_sensors, 10) == NULL) 2335 goto bad; 2336 sc->sc_sensors_running = 1; 2337 } 2338 sensordev_install(&sd->sd_vol.sv_sensordev); 2339 2340 rv = 0; 2341 bad: 2342 return (rv); 2343 } 2344 2345 void 2346 sr_delete_sensors(struct sr_discipline *sd) 2347 { 2348 #ifdef SR_DEBUG 2349 struct sr_softc *sc = sd->sd_sc; 2350 #endif 2351 DNPRINTF(SR_D_STATE, "%s: %s: sr_delete_sensors\n", 2352 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname); 2353 2354 if (sd->sd_vol.sv_sensor_valid) 2355 sensordev_deinstall(&sd->sd_vol.sv_sensordev); 2356 } 2357 2358 void 2359 sr_refresh_sensors(void *arg) 2360 { 2361 struct sr_softc *sc = arg; 2362 int i, vol; 2363 struct sr_volume *sv; 2364 2365 DNPRINTF(SR_D_STATE, "%s: sr_refresh_sensors\n", DEVNAME(sc)); 2366 2367 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) { 2368 /* XXX this will not work when we stagger disciplines */ 2369 if (!sc->sc_dis[i]) 2370 continue; 2371 2372 sv = &sc->sc_dis[i]->sd_vol; 2373 2374 switch(sv->sv_meta.svm_status) { 2375 case BIOC_SVOFFLINE: 2376 sv->sv_sensor.value = SENSOR_DRIVE_FAIL; 2377 sv->sv_sensor.status = SENSOR_S_CRIT; 2378 break; 2379 2380 case BIOC_SVDEGRADED: 2381 sv->sv_sensor.value = SENSOR_DRIVE_PFAIL; 2382 sv->sv_sensor.status = SENSOR_S_WARN; 2383 break; 2384 2385 case BIOC_SVSCRUB: 2386 case BIOC_SVONLINE: 2387 sv->sv_sensor.value = SENSOR_DRIVE_ONLINE; 2388 sv->sv_sensor.status = SENSOR_S_OK; 2389 break; 2390 2391 default: 2392 sv->sv_sensor.value = 0; /* unknown */ 2393 sv->sv_sensor.status = SENSOR_S_UNKNOWN; 2394 } 2395 } 2396 } 2397 #endif /* SMALL_KERNEL */ 2398 2399 #ifdef SR_FANCY_STATS 2400 void sr_print_stats(void); 2401 2402 void 2403 sr_print_stats(void) 2404 { 2405 struct sr_softc *sc; 2406 struct sr_discipline *sd; 2407 int i, vol; 2408 2409 for (i = 0; i < softraid_cd.cd_ndevs; i++) 2410 if (softraid_cd.cd_devs[i]) { 2411 sc = softraid_cd.cd_devs[i]; 2412 /* we'll only have one softc */ 2413 break; 2414 } 2415 2416 if (!sc) { 2417 printf("no softraid softc found\n"); 2418 return; 2419 } 2420 2421 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) { 2422 /* XXX this will not work when we stagger disciplines */ 2423 if (!sc->sc_dis[i]) 2424 continue; 2425 2426 sd = sc->sc_dis[i]; 2427 printf("%s: ios pending: %d collisions %llu\n", 2428 sd->sd_vol.sv_meta.svm_devname, 2429 sd->sd_wu_pending, 2430 sd->sd_wu_collisions); 2431 } 2432 } 2433 #endif /* SR_FANCY_STATS */ 2434 2435 #ifdef SR_DEBUG 2436 void 2437 sr_print_metadata(struct sr_metadata *sm) 2438 { 2439 struct sr_vol_meta *im_sv; 2440 struct sr_chunk_meta *im_sc; 2441 struct sr_opt_meta *im_so; 2442 int ch; 2443 2444 if (!(sr_debug & SR_D_META)) 2445 return; 2446 2447 im_sv = (struct sr_vol_meta *)(sm + 1); 2448 im_sc = (struct sr_chunk_meta *)(im_sv + 1); 2449 im_so = (struct sr_opt_meta *)(im_sc + im_sv->svm_no_chunk); 2450 2451 DNPRINTF(SR_D_META, "\tmeta magic 0x%llx\n", sm->ssd_magic); 2452 DNPRINTF(SR_D_META, "\tmeta version %d\n", sm->ssd_version); 2453 DNPRINTF(SR_D_META, "\tmeta checksum 0x%x\n", sm->ssd_checksum); 2454 DNPRINTF(SR_D_META, "\tmeta size %d\n", sm->ssd_size); 2455 DNPRINTF(SR_D_META, "\tmeta on disk version %u\n", sm->ssd_ondisk); 2456 DNPRINTF(SR_D_META, "\tmeta uuid "); 2457 sr_print_uuid(&sm->ssd_uuid, 1); 2458 DNPRINTF(SR_D_META, "\tvd version %d\n", sm->ssd_vd_ver); 2459 DNPRINTF(SR_D_META, "\tvd size %lu\n", sm->ssd_vd_size); 2460 DNPRINTF(SR_D_META, "\tvd id %u\n", sm->ssd_vd_volid); 2461 DNPRINTF(SR_D_META, "\tvd checksum 0x%x\n", sm->ssd_vd_chk); 2462 DNPRINTF(SR_D_META, "\tchunk version %d\n", sm->ssd_chunk_ver); 2463 DNPRINTF(SR_D_META, "\tchunks %d\n", sm->ssd_chunk_no); 2464 DNPRINTF(SR_D_META, "\tchunk size %u\n", sm->ssd_chunk_size); 2465 DNPRINTF(SR_D_META, "\tchunk id %u\n", sm->ssd_chunk_id); 2466 DNPRINTF(SR_D_META, "\tchunk checksum 0x%x\n", sm->ssd_chunk_chk); 2467 if (sm->ssd_opt_no) { 2468 DNPRINTF(SR_D_META, "\topt version %d\n", sm->ssd_opt_ver); 2469 DNPRINTF(SR_D_META, "\topt items %d\n", sm->ssd_opt_no); 2470 DNPRINTF(SR_D_META, "\topt size %d\n", sm->ssd_opt_size); 2471 DNPRINTF(SR_D_META, "\topt chk 0x%x\n", sm->ssd_opt_chk); 2472 } 2473 2474 2475 DNPRINTF(SR_D_META, "\t\tvol id %d\n", im_sv->svm_volid); 2476 DNPRINTF(SR_D_META, "\t\tvol status %d\n", im_sv->svm_status); 2477 DNPRINTF(SR_D_META, "\t\tvol flags 0x%x\n", im_sv->svm_flags); 2478 DNPRINTF(SR_D_META, "\t\tvol level %d\n", im_sv->svm_level); 2479 DNPRINTF(SR_D_META, "\t\tvol size %lld\n", im_sv->svm_size); 2480 DNPRINTF(SR_D_META, "\t\tvol name %s\n", im_sv->svm_devname); 2481 DNPRINTF(SR_D_META, "\t\tvol vendor %s\n", im_sv->svm_vendor); 2482 DNPRINTF(SR_D_META, "\t\tvol prod %s\n", im_sv->svm_product); 2483 DNPRINTF(SR_D_META, "\t\tvol rev %s\n", im_sv->svm_revision); 2484 DNPRINTF(SR_D_META, "\t\tvol no chunks %d\n", im_sv->svm_no_chunk); 2485 DNPRINTF(SR_D_META, "\t\tvol uuid "); 2486 sr_print_uuid(& im_sv->svm_uuid, 1); 2487 DNPRINTF(SR_D_META, "\t\tvol stripsize %d\n", im_sv->svm_strip_size); 2488 2489 for (ch = 0; ch < im_sv->svm_no_chunk; ch++) { 2490 DNPRINTF(SR_D_META, "\t\t\tchunk vol id %d\n", 2491 im_sc[ch].scm_volid); 2492 DNPRINTF(SR_D_META, "\t\t\tchunk id %d\n", 2493 im_sc[ch].scm_chunk_id); 2494 DNPRINTF(SR_D_META, "\t\t\tchunk status %d\n", 2495 im_sc[ch].scm_status); 2496 DNPRINTF(SR_D_META, "\t\t\tchunk name %s\n", 2497 im_sc[ch].scm_devname); 2498 DNPRINTF(SR_D_META, "\t\t\tchunk size %lld\n", 2499 im_sc[ch].scm_size); 2500 DNPRINTF(SR_D_META, "\t\t\tchunk coerced size %lld\n", 2501 im_sc[ch].scm_coerced_size); 2502 DNPRINTF(SR_D_META, "\t\t\tchunk uuid "); 2503 sr_print_uuid(&im_sc[ch].scm_uuid, 1); 2504 } 2505 } 2506 2507 void 2508 sr_dump_mem(u_int8_t *p, int len) 2509 { 2510 int i; 2511 2512 for (i = 0; i < len; i++) 2513 printf("%02x ", *p++); 2514 printf("\n"); 2515 } 2516 2517 #endif /* SR_DEBUG */ 2518