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