1 /* $OpenBSD: softraid.c,v 1.331 2014/01/22 23:32:42 jsing Exp $ */ 2 /* 3 * Copyright (c) 2007, 2008, 2009 Marco Peereboom <marco@peereboom.us> 4 * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org> 5 * Copyright (c) 2009 Joel Sing <jsing@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "bio.h" 21 22 #include <sys/param.h> 23 #include <sys/systm.h> 24 #include <sys/buf.h> 25 #include <sys/device.h> 26 #include <sys/ioctl.h> 27 #include <sys/proc.h> 28 #include <sys/malloc.h> 29 #include <sys/pool.h> 30 #include <sys/kernel.h> 31 #include <sys/disk.h> 32 #include <sys/rwlock.h> 33 #include <sys/queue.h> 34 #include <sys/fcntl.h> 35 #include <sys/disklabel.h> 36 #include <sys/vnode.h> 37 #include <sys/mount.h> 38 #include <sys/sensors.h> 39 #include <sys/stat.h> 40 #include <sys/conf.h> 41 #include <sys/uio.h> 42 #include <sys/task.h> 43 #include <sys/kthread.h> 44 #include <sys/dkio.h> 45 46 #ifdef AOE 47 #include <sys/mbuf.h> 48 #include <net/if_aoe.h> 49 #endif /* AOE */ 50 51 #include <crypto/cryptodev.h> 52 53 #include <scsi/scsi_all.h> 54 #include <scsi/scsiconf.h> 55 #include <scsi/scsi_disk.h> 56 57 #include <dev/softraidvar.h> 58 #include <dev/rndvar.h> 59 60 /* #define SR_FANCY_STATS */ 61 62 #ifdef SR_DEBUG 63 #define SR_FANCY_STATS 64 uint32_t sr_debug = 0 65 /* | SR_D_CMD */ 66 /* | SR_D_MISC */ 67 /* | SR_D_INTR */ 68 /* | SR_D_IOCTL */ 69 /* | SR_D_CCB */ 70 /* | SR_D_WU */ 71 /* | SR_D_META */ 72 /* | SR_D_DIS */ 73 /* | SR_D_STATE */ 74 /* | SR_D_REBUILD */ 75 ; 76 #endif 77 78 struct sr_softc *softraid0; 79 struct sr_uuid sr_bootuuid; 80 u_int8_t sr_bootkey[SR_CRYPTO_MAXKEYBYTES]; 81 82 int sr_match(struct device *, void *, void *); 83 void sr_attach(struct device *, struct device *, void *); 84 int sr_detach(struct device *, int); 85 void sr_map_root(void); 86 87 struct cfattach softraid_ca = { 88 sizeof(struct sr_softc), sr_match, sr_attach, sr_detach, 89 }; 90 91 struct cfdriver softraid_cd = { 92 NULL, "softraid", DV_DULL 93 }; 94 95 /* scsi & discipline */ 96 void sr_scsi_cmd(struct scsi_xfer *); 97 void sr_minphys(struct buf *, struct scsi_link *); 98 int sr_scsi_probe(struct scsi_link *); 99 void sr_copy_internal_data(struct scsi_xfer *, 100 void *, size_t); 101 int sr_scsi_ioctl(struct scsi_link *, u_long, 102 caddr_t, int); 103 int sr_bio_ioctl(struct device *, u_long, caddr_t); 104 int sr_ioctl_inq(struct sr_softc *, struct bioc_inq *); 105 int sr_ioctl_vol(struct sr_softc *, struct bioc_vol *); 106 int sr_ioctl_disk(struct sr_softc *, struct bioc_disk *); 107 int sr_ioctl_setstate(struct sr_softc *, 108 struct bioc_setstate *); 109 int sr_ioctl_createraid(struct sr_softc *, 110 struct bioc_createraid *, int, void *); 111 int sr_ioctl_deleteraid(struct sr_softc *, 112 struct bioc_deleteraid *); 113 int sr_ioctl_discipline(struct sr_softc *, 114 struct bioc_discipline *); 115 int sr_ioctl_installboot(struct sr_softc *, 116 struct bioc_installboot *); 117 void sr_chunks_unwind(struct sr_softc *, 118 struct sr_chunk_head *); 119 void sr_discipline_free(struct sr_discipline *); 120 void sr_discipline_shutdown(struct sr_discipline *, int); 121 int sr_discipline_init(struct sr_discipline *, int); 122 int sr_alloc_resources(struct sr_discipline *); 123 void sr_free_resources(struct sr_discipline *); 124 void sr_set_chunk_state(struct sr_discipline *, int, int); 125 void sr_set_vol_state(struct sr_discipline *); 126 127 /* utility functions */ 128 void sr_shutdown(struct sr_softc *); 129 void sr_shutdownhook(void *); 130 void sr_uuid_generate(struct sr_uuid *); 131 char *sr_uuid_format(struct sr_uuid *); 132 void sr_uuid_print(struct sr_uuid *, int); 133 void sr_checksum_print(u_int8_t *); 134 int sr_boot_assembly(struct sr_softc *); 135 int sr_already_assembled(struct sr_discipline *); 136 int sr_hotspare(struct sr_softc *, dev_t); 137 void sr_hotspare_rebuild(struct sr_discipline *); 138 int sr_rebuild_init(struct sr_discipline *, dev_t, int); 139 void sr_rebuild_start(void *); 140 void sr_rebuild_thread(void *); 141 void sr_rebuild(struct sr_discipline *); 142 void sr_roam_chunks(struct sr_discipline *); 143 int sr_chunk_in_use(struct sr_softc *, dev_t); 144 int sr_rw(struct sr_softc *, dev_t, char *, size_t, 145 daddr_t, long); 146 void sr_wu_done_callback(void *, void *); 147 148 /* don't include these on RAMDISK */ 149 #ifndef SMALL_KERNEL 150 void sr_sensors_refresh(void *); 151 int sr_sensors_create(struct sr_discipline *); 152 void sr_sensors_delete(struct sr_discipline *); 153 #endif 154 155 /* metadata */ 156 int sr_meta_probe(struct sr_discipline *, dev_t *, int); 157 int sr_meta_attach(struct sr_discipline *, int, int); 158 int sr_meta_rw(struct sr_discipline *, dev_t, void *, 159 size_t, daddr_t, long); 160 int sr_meta_clear(struct sr_discipline *); 161 void sr_meta_init(struct sr_discipline *, int, int); 162 void sr_meta_init_complete(struct sr_discipline *); 163 void sr_meta_opt_handler(struct sr_discipline *, 164 struct sr_meta_opt_hdr *); 165 166 /* hotplug magic */ 167 void sr_disk_attach(struct disk *, int); 168 169 struct sr_hotplug_list { 170 void (*sh_hotplug)(struct sr_discipline *, 171 struct disk *, int); 172 struct sr_discipline *sh_sd; 173 174 SLIST_ENTRY(sr_hotplug_list) shl_link; 175 }; 176 SLIST_HEAD(sr_hotplug_list_head, sr_hotplug_list); 177 178 struct sr_hotplug_list_head sr_hotplug_callbacks; 179 extern void (*softraid_disk_attach)(struct disk *, int); 180 181 /* scsi glue */ 182 struct scsi_adapter sr_switch = { 183 sr_scsi_cmd, sr_minphys, sr_scsi_probe, NULL, sr_scsi_ioctl 184 }; 185 186 /* native metadata format */ 187 int sr_meta_native_bootprobe(struct sr_softc *, dev_t, 188 struct sr_boot_chunk_head *); 189 #define SR_META_NOTCLAIMED (0) 190 #define SR_META_CLAIMED (1) 191 int sr_meta_native_probe(struct sr_softc *, 192 struct sr_chunk *); 193 int sr_meta_native_attach(struct sr_discipline *, int); 194 int sr_meta_native_write(struct sr_discipline *, dev_t, 195 struct sr_metadata *,void *); 196 197 #ifdef SR_DEBUG 198 void sr_meta_print(struct sr_metadata *); 199 #else 200 #define sr_meta_print(m) 201 #endif 202 203 /* the metadata driver should remain stateless */ 204 struct sr_meta_driver { 205 daddr_t smd_offset; /* metadata location */ 206 u_int32_t smd_size; /* size of metadata */ 207 208 int (*smd_probe)(struct sr_softc *, 209 struct sr_chunk *); 210 int (*smd_attach)(struct sr_discipline *, int); 211 int (*smd_detach)(struct sr_discipline *); 212 int (*smd_read)(struct sr_discipline *, dev_t, 213 struct sr_metadata *, void *); 214 int (*smd_write)(struct sr_discipline *, dev_t, 215 struct sr_metadata *, void *); 216 int (*smd_validate)(struct sr_discipline *, 217 struct sr_metadata *, void *); 218 } smd[] = { 219 { SR_META_OFFSET, SR_META_SIZE * 512, 220 sr_meta_native_probe, sr_meta_native_attach, NULL, 221 sr_meta_native_read, sr_meta_native_write, NULL }, 222 { 0, 0, NULL, NULL, NULL, NULL } 223 }; 224 225 int 226 sr_meta_attach(struct sr_discipline *sd, int chunk_no, int force) 227 { 228 struct sr_softc *sc = sd->sd_sc; 229 struct sr_chunk_head *cl; 230 struct sr_chunk *ch_entry, *chunk1, *chunk2; 231 int rv = 1, i = 0; 232 233 DNPRINTF(SR_D_META, "%s: sr_meta_attach(%d)\n", DEVNAME(sc)); 234 235 /* in memory copy of metadata */ 236 sd->sd_meta = malloc(SR_META_SIZE * 512, M_DEVBUF, M_ZERO | M_NOWAIT); 237 if (!sd->sd_meta) { 238 sr_error(sc, "could not allocate memory for metadata"); 239 goto bad; 240 } 241 242 if (sd->sd_meta_type != SR_META_F_NATIVE) { 243 /* in memory copy of foreign metadata */ 244 sd->sd_meta_foreign = malloc(smd[sd->sd_meta_type].smd_size, 245 M_DEVBUF, M_ZERO | M_NOWAIT); 246 if (!sd->sd_meta_foreign) { 247 /* unwind frees sd_meta */ 248 sr_error(sc, "could not allocate memory for foreign " 249 "metadata"); 250 goto bad; 251 } 252 } 253 254 /* we have a valid list now create an array index */ 255 cl = &sd->sd_vol.sv_chunk_list; 256 sd->sd_vol.sv_chunks = malloc(sizeof(struct sr_chunk *) * chunk_no, 257 M_DEVBUF, M_WAITOK | M_ZERO); 258 259 /* fill out chunk array */ 260 i = 0; 261 SLIST_FOREACH(ch_entry, cl, src_link) 262 sd->sd_vol.sv_chunks[i++] = ch_entry; 263 264 /* attach metadata */ 265 if (smd[sd->sd_meta_type].smd_attach(sd, force)) 266 goto bad; 267 268 /* Force chunks into correct order now that metadata is attached. */ 269 SLIST_FOREACH(ch_entry, cl, src_link) 270 SLIST_REMOVE(cl, ch_entry, sr_chunk, src_link); 271 for (i = 0; i < chunk_no; i++) { 272 ch_entry = sd->sd_vol.sv_chunks[i]; 273 chunk2 = NULL; 274 SLIST_FOREACH(chunk1, cl, src_link) { 275 if (chunk1->src_meta.scmi.scm_chunk_id > 276 ch_entry->src_meta.scmi.scm_chunk_id) 277 break; 278 chunk2 = chunk1; 279 } 280 if (chunk2 == NULL) 281 SLIST_INSERT_HEAD(cl, ch_entry, src_link); 282 else 283 SLIST_INSERT_AFTER(chunk2, ch_entry, src_link); 284 } 285 i = 0; 286 SLIST_FOREACH(ch_entry, cl, src_link) 287 sd->sd_vol.sv_chunks[i++] = ch_entry; 288 289 rv = 0; 290 bad: 291 return (rv); 292 } 293 294 int 295 sr_meta_probe(struct sr_discipline *sd, dev_t *dt, int no_chunk) 296 { 297 struct sr_softc *sc = sd->sd_sc; 298 struct vnode *vn; 299 struct sr_chunk *ch_entry, *ch_prev = NULL; 300 struct sr_chunk_head *cl; 301 char devname[32]; 302 int i, d, type, found, prevf, error; 303 dev_t dev; 304 305 DNPRINTF(SR_D_META, "%s: sr_meta_probe(%d)\n", DEVNAME(sc), no_chunk); 306 307 if (no_chunk == 0) 308 goto unwind; 309 310 cl = &sd->sd_vol.sv_chunk_list; 311 312 for (d = 0, prevf = SR_META_F_INVALID; d < no_chunk; d++) { 313 ch_entry = malloc(sizeof(struct sr_chunk), M_DEVBUF, 314 M_WAITOK | M_ZERO); 315 /* keep disks in user supplied order */ 316 if (ch_prev) 317 SLIST_INSERT_AFTER(ch_prev, ch_entry, src_link); 318 else 319 SLIST_INSERT_HEAD(cl, ch_entry, src_link); 320 ch_prev = ch_entry; 321 dev = dt[d]; 322 ch_entry->src_dev_mm = dev; 323 324 if (dev == NODEV) { 325 ch_entry->src_meta.scm_status = BIOC_SDOFFLINE; 326 continue; 327 } else { 328 sr_meta_getdevname(sc, dev, devname, sizeof(devname)); 329 if (bdevvp(dev, &vn)) { 330 sr_error(sc, "sr_meta_probe: cannot allocate " 331 "vnode"); 332 goto unwind; 333 } 334 335 /* 336 * XXX leaving dev open for now; move this to attach 337 * and figure out the open/close dance for unwind. 338 */ 339 error = VOP_OPEN(vn, FREAD | FWRITE, NOCRED, curproc); 340 if (error) { 341 DNPRINTF(SR_D_META,"%s: sr_meta_probe can't " 342 "open %s\n", DEVNAME(sc), devname); 343 vput(vn); 344 goto unwind; 345 } 346 347 strlcpy(ch_entry->src_devname, devname, 348 sizeof(ch_entry->src_devname)); 349 ch_entry->src_vn = vn; 350 } 351 352 /* determine if this is a device we understand */ 353 for (i = 0, found = SR_META_F_INVALID; smd[i].smd_probe; i++) { 354 type = smd[i].smd_probe(sc, ch_entry); 355 if (type == SR_META_F_INVALID) 356 continue; 357 else { 358 found = type; 359 break; 360 } 361 } 362 363 if (found == SR_META_F_INVALID) 364 goto unwind; 365 if (prevf == SR_META_F_INVALID) 366 prevf = found; 367 if (prevf != found) { 368 DNPRINTF(SR_D_META, "%s: prevf != found\n", 369 DEVNAME(sc)); 370 goto unwind; 371 } 372 } 373 374 return (prevf); 375 unwind: 376 return (SR_META_F_INVALID); 377 } 378 379 void 380 sr_meta_getdevname(struct sr_softc *sc, dev_t dev, char *buf, int size) 381 { 382 int maj, unit, part; 383 char *name; 384 385 DNPRINTF(SR_D_META, "%s: sr_meta_getdevname(%p, %d)\n", 386 DEVNAME(sc), buf, size); 387 388 if (!buf) 389 return; 390 391 maj = major(dev); 392 part = DISKPART(dev); 393 unit = DISKUNIT(dev); 394 395 name = findblkname(maj); 396 if (name == NULL) 397 return; 398 399 snprintf(buf, size, "%s%d%c", name, unit, part + 'a'); 400 } 401 402 int 403 sr_rw(struct sr_softc *sc, dev_t dev, char *buf, size_t size, daddr_t offset, 404 long flags) 405 { 406 struct vnode *vp; 407 struct buf b; 408 size_t bufsize, dma_bufsize; 409 int rv = 1; 410 char *dma_buf; 411 412 DNPRINTF(SR_D_MISC, "%s: sr_rw(0x%x, %p, %zu, %lld 0x%x)\n", 413 DEVNAME(sc), dev, buf, size, (long long)offset, flags); 414 415 dma_bufsize = (size > MAXPHYS) ? MAXPHYS : size; 416 dma_buf = dma_alloc(dma_bufsize, PR_WAITOK); 417 418 if (bdevvp(dev, &vp)) { 419 printf("%s: sr_rw: failed to allocate vnode\n", DEVNAME(sc)); 420 goto done; 421 } 422 423 while (size > 0) { 424 DNPRINTF(SR_D_MISC, "%s: dma_buf %p, size %d, offset %llu)\n", 425 DEVNAME(sc), dma_buf, size, offset); 426 427 bufsize = (size > MAXPHYS) ? MAXPHYS : size; 428 if (flags == B_WRITE) 429 bcopy(buf, dma_buf, bufsize); 430 431 bzero(&b, sizeof(b)); 432 b.b_flags = flags | B_PHYS; 433 b.b_proc = curproc; 434 b.b_dev = dev; 435 b.b_iodone = NULL; 436 b.b_error = 0; 437 b.b_blkno = offset; 438 b.b_data = dma_buf; 439 b.b_bcount = bufsize; 440 b.b_bufsize = bufsize; 441 b.b_resid = bufsize; 442 b.b_vp = vp; 443 444 if ((b.b_flags & B_READ) == 0) 445 vp->v_numoutput++; 446 447 LIST_INIT(&b.b_dep); 448 VOP_STRATEGY(&b); 449 biowait(&b); 450 451 if (b.b_flags & B_ERROR) { 452 printf("%s: I/O error %d on dev 0x%x at block %llu\n", 453 DEVNAME(sc), b.b_error, dev, b.b_blkno); 454 goto done; 455 } 456 457 if (flags == B_READ) 458 bcopy(dma_buf, buf, bufsize); 459 460 size -= bufsize; 461 buf += bufsize; 462 offset += howmany(bufsize, DEV_BSIZE); 463 } 464 465 rv = 0; 466 467 done: 468 if (vp) 469 vput(vp); 470 471 dma_free(dma_buf, dma_bufsize); 472 473 return (rv); 474 } 475 476 int 477 sr_meta_rw(struct sr_discipline *sd, dev_t dev, void *md, size_t size, 478 daddr_t offset, long flags) 479 { 480 int rv = 1; 481 482 DNPRINTF(SR_D_META, "%s: sr_meta_rw(0x%x, %p, %zu, %lld 0x%x)\n", 483 DEVNAME(sd->sd_sc), dev, md, size, (long long)offset, flags); 484 485 if (md == NULL) { 486 printf("%s: sr_meta_rw: invalid metadata pointer\n", 487 DEVNAME(sd->sd_sc)); 488 goto done; 489 } 490 491 rv = sr_rw(sd->sd_sc, dev, md, size, offset, flags); 492 493 done: 494 return (rv); 495 } 496 497 int 498 sr_meta_clear(struct sr_discipline *sd) 499 { 500 struct sr_softc *sc = sd->sd_sc; 501 struct sr_chunk_head *cl = &sd->sd_vol.sv_chunk_list; 502 struct sr_chunk *ch_entry; 503 void *m; 504 int rv = 1; 505 506 DNPRINTF(SR_D_META, "%s: sr_meta_clear\n", DEVNAME(sc)); 507 508 if (sd->sd_meta_type != SR_META_F_NATIVE) { 509 sr_error(sc, "cannot clear foreign metadata"); 510 goto done; 511 } 512 513 m = malloc(SR_META_SIZE * 512, M_DEVBUF, M_WAITOK | M_ZERO); 514 SLIST_FOREACH(ch_entry, cl, src_link) { 515 if (sr_meta_native_write(sd, ch_entry->src_dev_mm, m, NULL)) { 516 /* XXX mark disk offline */ 517 DNPRINTF(SR_D_META, "%s: sr_meta_clear failed to " 518 "clear %s\n", ch_entry->src_devname); 519 rv++; 520 continue; 521 } 522 bzero(&ch_entry->src_meta, sizeof(ch_entry->src_meta)); 523 } 524 525 bzero(sd->sd_meta, SR_META_SIZE * 512); 526 527 free(m, M_DEVBUF); 528 rv = 0; 529 done: 530 return (rv); 531 } 532 533 void 534 sr_meta_init(struct sr_discipline *sd, int level, int no_chunk) 535 { 536 struct sr_softc *sc = sd->sd_sc; 537 struct sr_metadata *sm = sd->sd_meta; 538 struct sr_chunk_head *cl = &sd->sd_vol.sv_chunk_list; 539 struct sr_meta_chunk *scm; 540 struct sr_chunk *chunk; 541 int cid = 0; 542 u_int64_t max_chunk_sz = 0, min_chunk_sz = 0; 543 544 DNPRINTF(SR_D_META, "%s: sr_meta_init\n", DEVNAME(sc)); 545 546 if (!sm) 547 return; 548 549 /* Initialise volume metadata. */ 550 sm->ssdi.ssd_magic = SR_MAGIC; 551 sm->ssdi.ssd_version = SR_META_VERSION; 552 sm->ssdi.ssd_vol_flags = sd->sd_meta_flags; 553 sm->ssdi.ssd_volid = 0; 554 sm->ssdi.ssd_chunk_no = no_chunk; 555 sm->ssdi.ssd_level = level; 556 557 sm->ssd_data_offset = SR_DATA_OFFSET; 558 sm->ssd_ondisk = 0; 559 560 sr_uuid_generate(&sm->ssdi.ssd_uuid); 561 562 /* Initialise chunk metadata and get min/max chunk sizes. */ 563 SLIST_FOREACH(chunk, cl, src_link) { 564 scm = &chunk->src_meta; 565 scm->scmi.scm_size = chunk->src_size; 566 scm->scmi.scm_chunk_id = cid++; 567 scm->scm_status = BIOC_SDONLINE; 568 scm->scmi.scm_volid = 0; 569 strlcpy(scm->scmi.scm_devname, chunk->src_devname, 570 sizeof(scm->scmi.scm_devname)); 571 bcopy(&sm->ssdi.ssd_uuid, &scm->scmi.scm_uuid, 572 sizeof(scm->scmi.scm_uuid)); 573 sr_checksum(sc, scm, &scm->scm_checksum, 574 sizeof(scm->scm_checksum)); 575 576 if (min_chunk_sz == 0) 577 min_chunk_sz = scm->scmi.scm_size; 578 min_chunk_sz = MIN(min_chunk_sz, scm->scmi.scm_size); 579 max_chunk_sz = MAX(max_chunk_sz, scm->scmi.scm_size); 580 } 581 582 /* Equalize chunk sizes. */ 583 SLIST_FOREACH(chunk, cl, src_link) 584 chunk->src_meta.scmi.scm_coerced_size = min_chunk_sz; 585 586 sd->sd_vol.sv_chunk_minsz = min_chunk_sz; 587 sd->sd_vol.sv_chunk_maxsz = max_chunk_sz; 588 } 589 590 void 591 sr_meta_init_complete(struct sr_discipline *sd) 592 { 593 #ifdef SR_DEBUG 594 struct sr_softc *sc = sd->sd_sc; 595 #endif 596 struct sr_metadata *sm = sd->sd_meta; 597 598 DNPRINTF(SR_D_META, "%s: sr_meta_complete\n", DEVNAME(sc)); 599 600 /* Complete initialisation of volume metadata. */ 601 strlcpy(sm->ssdi.ssd_vendor, "OPENBSD", sizeof(sm->ssdi.ssd_vendor)); 602 snprintf(sm->ssdi.ssd_product, sizeof(sm->ssdi.ssd_product), 603 "SR %s", sd->sd_name); 604 snprintf(sm->ssdi.ssd_revision, sizeof(sm->ssdi.ssd_revision), 605 "%03d", sm->ssdi.ssd_version); 606 } 607 608 void 609 sr_meta_opt_handler(struct sr_discipline *sd, struct sr_meta_opt_hdr *om) 610 { 611 if (om->som_type != SR_OPT_BOOT) 612 panic("unknown optional metadata type"); 613 } 614 615 void 616 sr_meta_save_callback(void *arg1, void *arg2) 617 { 618 struct sr_discipline *sd = arg1; 619 int s; 620 621 s = splbio(); 622 623 if (sr_meta_save(arg1, SR_META_DIRTY)) 624 printf("%s: save metadata failed\n", DEVNAME(sd->sd_sc)); 625 626 sd->sd_must_flush = 0; 627 splx(s); 628 } 629 630 int 631 sr_meta_save(struct sr_discipline *sd, u_int32_t flags) 632 { 633 struct sr_softc *sc = sd->sd_sc; 634 struct sr_metadata *sm = sd->sd_meta, *m; 635 struct sr_meta_driver *s; 636 struct sr_chunk *src; 637 struct sr_meta_chunk *cm; 638 struct sr_workunit wu; 639 struct sr_meta_opt_hdr *omh; 640 struct sr_meta_opt_item *omi; 641 int i; 642 643 DNPRINTF(SR_D_META, "%s: sr_meta_save %s\n", 644 DEVNAME(sc), sd->sd_meta->ssd_devname); 645 646 if (!sm) { 647 printf("%s: no in memory copy of metadata\n", DEVNAME(sc)); 648 goto bad; 649 } 650 651 /* meta scratchpad */ 652 s = &smd[sd->sd_meta_type]; 653 m = malloc(SR_META_SIZE * 512, M_DEVBUF, M_ZERO | M_NOWAIT); 654 if (!m) { 655 printf("%s: could not allocate metadata scratch area\n", 656 DEVNAME(sc)); 657 goto bad; 658 } 659 660 /* from here on out metadata is updated */ 661 restart: 662 sm->ssd_ondisk++; 663 sm->ssd_meta_flags = flags; 664 bcopy(sm, m, sizeof(*m)); 665 666 /* Chunk metadata. */ 667 cm = (struct sr_meta_chunk *)(m + 1); 668 for (i = 0; i < sm->ssdi.ssd_chunk_no; i++) { 669 src = sd->sd_vol.sv_chunks[i]; 670 bcopy(&src->src_meta, cm, sizeof(*cm)); 671 cm++; 672 } 673 674 /* Optional metadata. */ 675 omh = (struct sr_meta_opt_hdr *)(cm); 676 SLIST_FOREACH(omi, &sd->sd_meta_opt, omi_link) { 677 DNPRINTF(SR_D_META, "%s: saving optional metadata type %u with " 678 "length %u\n", DEVNAME(sc), omi->omi_som->som_type, 679 omi->omi_som->som_length); 680 bzero(&omi->omi_som->som_checksum, MD5_DIGEST_LENGTH); 681 sr_checksum(sc, omi->omi_som, &omi->omi_som->som_checksum, 682 omi->omi_som->som_length); 683 bcopy(omi->omi_som, omh, omi->omi_som->som_length); 684 omh = (struct sr_meta_opt_hdr *)((u_int8_t *)omh + 685 omi->omi_som->som_length); 686 } 687 688 for (i = 0; i < sm->ssdi.ssd_chunk_no; i++) { 689 src = sd->sd_vol.sv_chunks[i]; 690 691 /* skip disks that are offline */ 692 if (src->src_meta.scm_status == BIOC_SDOFFLINE) 693 continue; 694 695 /* calculate metadata checksum for correct chunk */ 696 m->ssdi.ssd_chunk_id = i; 697 sr_checksum(sc, m, &m->ssd_checksum, 698 sizeof(struct sr_meta_invariant)); 699 700 #ifdef SR_DEBUG 701 DNPRINTF(SR_D_META, "%s: sr_meta_save %s: volid: %d " 702 "chunkid: %d checksum: ", 703 DEVNAME(sc), src->src_meta.scmi.scm_devname, 704 m->ssdi.ssd_volid, m->ssdi.ssd_chunk_id); 705 706 if (sr_debug & SR_D_META) 707 sr_checksum_print((u_int8_t *)&m->ssd_checksum); 708 DNPRINTF(SR_D_META, "\n"); 709 sr_meta_print(m); 710 #endif 711 712 /* translate and write to disk */ 713 if (s->smd_write(sd, src->src_dev_mm, m, NULL /* XXX */)) { 714 printf("%s: could not write metadata to %s\n", 715 DEVNAME(sc), src->src_devname); 716 /* restart the meta write */ 717 src->src_meta.scm_status = BIOC_SDOFFLINE; 718 /* XXX recalculate volume status */ 719 goto restart; 720 } 721 } 722 723 /* not all disciplines have sync */ 724 if (sd->sd_scsi_sync) { 725 bzero(&wu, sizeof(wu)); 726 wu.swu_flags |= SR_WUF_FAKE; 727 wu.swu_dis = sd; 728 sd->sd_scsi_sync(&wu); 729 } 730 free(m, M_DEVBUF); 731 return (0); 732 bad: 733 return (1); 734 } 735 736 int 737 sr_meta_read(struct sr_discipline *sd) 738 { 739 struct sr_softc *sc = sd->sd_sc; 740 struct sr_chunk_head *cl = &sd->sd_vol.sv_chunk_list; 741 struct sr_metadata *sm; 742 struct sr_chunk *ch_entry; 743 struct sr_meta_chunk *cp; 744 struct sr_meta_driver *s; 745 void *fm = NULL; 746 int no_disk = 0, got_meta = 0; 747 748 DNPRINTF(SR_D_META, "%s: sr_meta_read\n", DEVNAME(sc)); 749 750 sm = malloc(SR_META_SIZE * 512, M_DEVBUF, M_WAITOK | M_ZERO); 751 s = &smd[sd->sd_meta_type]; 752 if (sd->sd_meta_type != SR_META_F_NATIVE) 753 fm = malloc(s->smd_size, M_DEVBUF, M_WAITOK | M_ZERO); 754 755 cp = (struct sr_meta_chunk *)(sm + 1); 756 SLIST_FOREACH(ch_entry, cl, src_link) { 757 /* skip disks that are offline */ 758 if (ch_entry->src_meta.scm_status == BIOC_SDOFFLINE) { 759 DNPRINTF(SR_D_META, 760 "%s: %s chunk marked offline, spoofing status\n", 761 DEVNAME(sc), ch_entry->src_devname); 762 cp++; /* adjust chunk pointer to match failure */ 763 continue; 764 } else if (s->smd_read(sd, ch_entry->src_dev_mm, sm, fm)) { 765 /* read and translate */ 766 /* XXX mark chunk offline, elsewhere!! */ 767 ch_entry->src_meta.scm_status = BIOC_SDOFFLINE; 768 cp++; /* adjust chunk pointer to match failure */ 769 DNPRINTF(SR_D_META, "%s: sr_meta_read failed\n", 770 DEVNAME(sc)); 771 continue; 772 } 773 774 if (sm->ssdi.ssd_magic != SR_MAGIC) { 775 DNPRINTF(SR_D_META, "%s: sr_meta_read !SR_MAGIC\n", 776 DEVNAME(sc)); 777 continue; 778 } 779 780 /* validate metadata */ 781 if (sr_meta_validate(sd, ch_entry->src_dev_mm, sm, fm)) { 782 DNPRINTF(SR_D_META, "%s: invalid metadata\n", 783 DEVNAME(sc)); 784 no_disk = -1; 785 goto done; 786 } 787 788 /* assume first chunk contains metadata */ 789 if (got_meta == 0) { 790 sr_meta_opt_load(sc, sm, &sd->sd_meta_opt); 791 bcopy(sm, sd->sd_meta, sizeof(*sd->sd_meta)); 792 got_meta = 1; 793 } 794 795 bcopy(cp, &ch_entry->src_meta, sizeof(ch_entry->src_meta)); 796 797 no_disk++; 798 cp++; 799 } 800 801 free(sm, M_DEVBUF); 802 if (fm) 803 free(fm, M_DEVBUF); 804 805 done: 806 DNPRINTF(SR_D_META, "%s: sr_meta_read found %d parts\n", DEVNAME(sc), 807 no_disk); 808 return (no_disk); 809 } 810 811 void 812 sr_meta_opt_load(struct sr_softc *sc, struct sr_metadata *sm, 813 struct sr_meta_opt_head *som) 814 { 815 struct sr_meta_opt_hdr *omh; 816 struct sr_meta_opt_item *omi; 817 u_int8_t checksum[MD5_DIGEST_LENGTH]; 818 int i; 819 820 /* Process optional metadata. */ 821 omh = (struct sr_meta_opt_hdr *)((u_int8_t *)(sm + 1) + 822 sizeof(struct sr_meta_chunk) * sm->ssdi.ssd_chunk_no); 823 for (i = 0; i < sm->ssdi.ssd_opt_no; i++) { 824 825 omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF, 826 M_WAITOK | M_ZERO); 827 SLIST_INSERT_HEAD(som, omi, omi_link); 828 829 if (omh->som_length == 0) { 830 831 /* Load old fixed length optional metadata. */ 832 DNPRINTF(SR_D_META, "%s: old optional metadata of type " 833 "%u\n", DEVNAME(sc), omh->som_type); 834 835 /* Validate checksum. */ 836 sr_checksum(sc, (void *)omh, &checksum, 837 SR_OLD_META_OPT_SIZE - MD5_DIGEST_LENGTH); 838 if (bcmp(&checksum, (void *)omh + SR_OLD_META_OPT_MD5, 839 sizeof(checksum))) 840 panic("%s: invalid optional metadata " 841 "checksum", DEVNAME(sc)); 842 843 /* Determine correct length. */ 844 switch (omh->som_type) { 845 case SR_OPT_CRYPTO: 846 omh->som_length = sizeof(struct sr_meta_crypto); 847 break; 848 case SR_OPT_BOOT: 849 omh->som_length = sizeof(struct sr_meta_boot); 850 break; 851 case SR_OPT_KEYDISK: 852 omh->som_length = 853 sizeof(struct sr_meta_keydisk); 854 break; 855 default: 856 panic("unknown old optional metadata " 857 "type %u\n", omh->som_type); 858 } 859 860 omi->omi_som = malloc(omh->som_length, M_DEVBUF, 861 M_WAITOK | M_ZERO); 862 bcopy((u_int8_t *)omh + SR_OLD_META_OPT_OFFSET, 863 (u_int8_t *)omi->omi_som + sizeof(*omi->omi_som), 864 omh->som_length - sizeof(*omi->omi_som)); 865 omi->omi_som->som_type = omh->som_type; 866 omi->omi_som->som_length = omh->som_length; 867 868 omh = (struct sr_meta_opt_hdr *)((void *)omh + 869 SR_OLD_META_OPT_SIZE); 870 } else { 871 872 /* Load variable length optional metadata. */ 873 DNPRINTF(SR_D_META, "%s: optional metadata of type %u, " 874 "length %u\n", DEVNAME(sc), omh->som_type, 875 omh->som_length); 876 omi->omi_som = malloc(omh->som_length, M_DEVBUF, 877 M_WAITOK | M_ZERO); 878 bcopy(omh, omi->omi_som, omh->som_length); 879 880 /* Validate checksum. */ 881 bcopy(&omi->omi_som->som_checksum, &checksum, 882 MD5_DIGEST_LENGTH); 883 bzero(&omi->omi_som->som_checksum, MD5_DIGEST_LENGTH); 884 sr_checksum(sc, omi->omi_som, 885 &omi->omi_som->som_checksum, omh->som_length); 886 if (bcmp(&checksum, &omi->omi_som->som_checksum, 887 sizeof(checksum))) 888 panic("%s: invalid optional metadata checksum", 889 DEVNAME(sc)); 890 891 omh = (struct sr_meta_opt_hdr *)((void *)omh + 892 omh->som_length); 893 } 894 } 895 } 896 897 int 898 sr_meta_validate(struct sr_discipline *sd, dev_t dev, struct sr_metadata *sm, 899 void *fm) 900 { 901 struct sr_softc *sc = sd->sd_sc; 902 struct sr_meta_driver *s; 903 #ifdef SR_DEBUG 904 struct sr_meta_chunk *mc; 905 #endif 906 u_int8_t checksum[MD5_DIGEST_LENGTH]; 907 char devname[32]; 908 int rv = 1; 909 910 DNPRINTF(SR_D_META, "%s: sr_meta_validate(%p)\n", DEVNAME(sc), sm); 911 912 sr_meta_getdevname(sc, dev, devname, sizeof(devname)); 913 914 s = &smd[sd->sd_meta_type]; 915 if (sd->sd_meta_type != SR_META_F_NATIVE) 916 if (s->smd_validate(sd, sm, fm)) { 917 sr_error(sc, "invalid foreign metadata"); 918 goto done; 919 } 920 921 /* 922 * at this point all foreign metadata has been translated to the native 923 * format and will be treated just like the native format 924 */ 925 926 if (sm->ssdi.ssd_magic != SR_MAGIC) { 927 sr_error(sc, "not valid softraid metadata"); 928 goto done; 929 } 930 931 /* Verify metadata checksum. */ 932 sr_checksum(sc, sm, &checksum, sizeof(struct sr_meta_invariant)); 933 if (bcmp(&checksum, &sm->ssd_checksum, sizeof(checksum))) { 934 sr_error(sc, "invalid metadata checksum"); 935 goto done; 936 } 937 938 /* Handle changes between versions. */ 939 if (sm->ssdi.ssd_version == 3) { 940 941 /* 942 * Version 3 - update metadata version and fix up data offset 943 * value since this did not exist in version 3. 944 */ 945 if (sm->ssd_data_offset == 0) 946 sm->ssd_data_offset = SR_META_V3_DATA_OFFSET; 947 948 } else if (sm->ssdi.ssd_version == 4) { 949 950 /* 951 * Version 4 - original metadata format did not store 952 * data offset so fix this up if necessary. 953 */ 954 if (sm->ssd_data_offset == 0) 955 sm->ssd_data_offset = SR_DATA_OFFSET; 956 957 } else if (sm->ssdi.ssd_version == SR_META_VERSION) { 958 959 /* 960 * Version 5 - variable length optional metadata. Migration 961 * from earlier fixed length optional metadata is handled 962 * in sr_meta_read(). 963 */ 964 965 } else { 966 967 sr_error(sc, "cannot read metadata version %u on %s, " 968 "expected version %u or earlier", 969 sm->ssdi.ssd_version, devname, SR_META_VERSION); 970 goto done; 971 972 } 973 974 /* Update version number and revision string. */ 975 sm->ssdi.ssd_version = SR_META_VERSION; 976 snprintf(sm->ssdi.ssd_revision, sizeof(sm->ssdi.ssd_revision), 977 "%03d", SR_META_VERSION); 978 979 #ifdef SR_DEBUG 980 /* warn if disk changed order */ 981 mc = (struct sr_meta_chunk *)(sm + 1); 982 if (strncmp(mc[sm->ssdi.ssd_chunk_id].scmi.scm_devname, devname, 983 sizeof(mc[sm->ssdi.ssd_chunk_id].scmi.scm_devname))) 984 DNPRINTF(SR_D_META, "%s: roaming device %s -> %s\n", 985 DEVNAME(sc), mc[sm->ssdi.ssd_chunk_id].scmi.scm_devname, 986 devname); 987 #endif 988 989 /* we have meta data on disk */ 990 DNPRINTF(SR_D_META, "%s: sr_meta_validate valid metadata %s\n", 991 DEVNAME(sc), devname); 992 993 rv = 0; 994 done: 995 return (rv); 996 } 997 998 int 999 sr_meta_native_bootprobe(struct sr_softc *sc, dev_t devno, 1000 struct sr_boot_chunk_head *bch) 1001 { 1002 struct vnode *vn; 1003 struct disklabel label; 1004 struct sr_metadata *md = NULL; 1005 struct sr_discipline *fake_sd = NULL; 1006 struct sr_boot_chunk *bc; 1007 char devname[32]; 1008 dev_t chrdev, rawdev; 1009 int error, i; 1010 int rv = SR_META_NOTCLAIMED; 1011 1012 DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe\n", DEVNAME(sc)); 1013 1014 /* 1015 * Use character raw device to avoid SCSI complaints about missing 1016 * media on removable media devices. 1017 */ 1018 chrdev = blktochr(devno); 1019 rawdev = MAKEDISKDEV(major(chrdev), DISKUNIT(devno), RAW_PART); 1020 if (cdevvp(rawdev, &vn)) { 1021 sr_error(sc, "sr_meta_native_bootprobe: cannot allocate vnode"); 1022 goto done; 1023 } 1024 1025 /* open device */ 1026 error = VOP_OPEN(vn, FREAD, NOCRED, curproc); 1027 if (error) { 1028 DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe open " 1029 "failed\n", DEVNAME(sc)); 1030 vput(vn); 1031 goto done; 1032 } 1033 1034 /* get disklabel */ 1035 error = VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, FREAD, NOCRED, 1036 curproc); 1037 if (error) { 1038 DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe ioctl " 1039 "failed\n", DEVNAME(sc)); 1040 VOP_CLOSE(vn, FREAD, NOCRED, curproc); 1041 vput(vn); 1042 goto done; 1043 } 1044 1045 /* we are done, close device */ 1046 error = VOP_CLOSE(vn, FREAD, NOCRED, curproc); 1047 if (error) { 1048 DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe close " 1049 "failed\n", DEVNAME(sc)); 1050 vput(vn); 1051 goto done; 1052 } 1053 vput(vn); 1054 1055 /* Make sure this is a 512-byte/sector device. */ 1056 if (label.d_secsize != DEV_BSIZE) { 1057 DNPRINTF(SR_D_META, "%s: %s has unsupported sector size (%d)", 1058 DEVNAME(sc), devname, label.d_secsize); 1059 goto done; 1060 } 1061 1062 md = malloc(SR_META_SIZE * 512, M_DEVBUF, M_ZERO | M_NOWAIT); 1063 if (md == NULL) { 1064 sr_error(sc, "not enough memory for metadata buffer"); 1065 goto done; 1066 } 1067 1068 /* create fake sd to use utility functions */ 1069 fake_sd = malloc(sizeof(struct sr_discipline), M_DEVBUF, 1070 M_ZERO | M_NOWAIT); 1071 if (fake_sd == NULL) { 1072 sr_error(sc, "not enough memory for fake discipline"); 1073 goto done; 1074 } 1075 fake_sd->sd_sc = sc; 1076 fake_sd->sd_meta_type = SR_META_F_NATIVE; 1077 1078 for (i = 0; i < MAXPARTITIONS; i++) { 1079 if (label.d_partitions[i].p_fstype != FS_RAID) 1080 continue; 1081 1082 /* open partition */ 1083 rawdev = MAKEDISKDEV(major(devno), DISKUNIT(devno), i); 1084 if (bdevvp(rawdev, &vn)) { 1085 sr_error(sc, "sr_meta_native_bootprobe: cannot " 1086 "allocate vnode for partition"); 1087 goto done; 1088 } 1089 error = VOP_OPEN(vn, FREAD, NOCRED, curproc); 1090 if (error) { 1091 DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe " 1092 "open failed, partition %d\n", 1093 DEVNAME(sc), i); 1094 vput(vn); 1095 continue; 1096 } 1097 1098 if (sr_meta_native_read(fake_sd, rawdev, md, NULL)) { 1099 sr_error(sc, "native bootprobe could not read native " 1100 "metadata"); 1101 VOP_CLOSE(vn, FREAD, NOCRED, curproc); 1102 vput(vn); 1103 continue; 1104 } 1105 1106 /* are we a softraid partition? */ 1107 if (md->ssdi.ssd_magic != SR_MAGIC) { 1108 VOP_CLOSE(vn, FREAD, NOCRED, curproc); 1109 vput(vn); 1110 continue; 1111 } 1112 1113 sr_meta_getdevname(sc, rawdev, devname, sizeof(devname)); 1114 if (sr_meta_validate(fake_sd, rawdev, md, NULL) == 0) { 1115 /* XXX fix M_WAITOK, this is boot time */ 1116 bc = malloc(sizeof(struct sr_boot_chunk), 1117 M_DEVBUF, M_WAITOK | M_ZERO); 1118 bc->sbc_metadata = malloc(sizeof(struct sr_metadata), 1119 M_DEVBUF, M_WAITOK | M_ZERO); 1120 bcopy(md, bc->sbc_metadata, sizeof(struct sr_metadata)); 1121 bc->sbc_mm = rawdev; 1122 SLIST_INSERT_HEAD(bch, bc, sbc_link); 1123 rv = SR_META_CLAIMED; 1124 } 1125 1126 /* we are done, close partition */ 1127 VOP_CLOSE(vn, FREAD, NOCRED, curproc); 1128 vput(vn); 1129 } 1130 1131 done: 1132 if (fake_sd) 1133 free(fake_sd, M_DEVBUF); 1134 if (md) 1135 free(md, M_DEVBUF); 1136 1137 return (rv); 1138 } 1139 1140 int 1141 sr_boot_assembly(struct sr_softc *sc) 1142 { 1143 struct sr_boot_volume_head bvh; 1144 struct sr_boot_chunk_head bch, kdh; 1145 struct sr_boot_volume *bv, *bv1, *bv2; 1146 struct sr_boot_chunk *bc, *bcnext, *bc1, *bc2; 1147 struct sr_disk_head sdklist; 1148 struct sr_disk *sdk; 1149 struct disk *dk; 1150 struct bioc_createraid bcr; 1151 struct sr_meta_chunk *hm; 1152 struct sr_chunk_head *cl; 1153 struct sr_chunk *hotspare, *chunk, *last; 1154 u_int64_t *ondisk = NULL; 1155 dev_t *devs = NULL; 1156 void *data; 1157 char devname[32]; 1158 int rv = 0, i; 1159 1160 DNPRINTF(SR_D_META, "%s: sr_boot_assembly\n", DEVNAME(sc)); 1161 1162 SLIST_INIT(&sdklist); 1163 SLIST_INIT(&bvh); 1164 SLIST_INIT(&bch); 1165 SLIST_INIT(&kdh); 1166 1167 dk = TAILQ_FIRST(&disklist); 1168 while (dk != TAILQ_END(&disklist)) { 1169 1170 /* See if this disk has been checked. */ 1171 SLIST_FOREACH(sdk, &sdklist, sdk_link) 1172 if (sdk->sdk_devno == dk->dk_devno) 1173 break; 1174 1175 if (sdk != NULL || dk->dk_devno == NODEV) { 1176 dk = TAILQ_NEXT(dk, dk_link); 1177 continue; 1178 } 1179 1180 /* Add this disk to the list that we've checked. */ 1181 sdk = malloc(sizeof(struct sr_disk), M_DEVBUF, 1182 M_NOWAIT | M_CANFAIL | M_ZERO); 1183 if (sdk == NULL) 1184 goto unwind; 1185 sdk->sdk_devno = dk->dk_devno; 1186 SLIST_INSERT_HEAD(&sdklist, sdk, sdk_link); 1187 1188 /* Only check sd(4) and wd(4) devices. */ 1189 if (strncmp(dk->dk_name, "sd", 2) && 1190 strncmp(dk->dk_name, "wd", 2)) { 1191 dk = TAILQ_NEXT(dk, dk_link); 1192 continue; 1193 } 1194 1195 /* native softraid uses partitions */ 1196 rw_enter_write(&sc->sc_lock); 1197 bio_status_init(&sc->sc_status, &sc->sc_dev); 1198 sr_meta_native_bootprobe(sc, dk->dk_devno, &bch); 1199 rw_exit_write(&sc->sc_lock); 1200 1201 /* probe non-native disks if native failed. */ 1202 1203 /* Restart scan since we may have slept. */ 1204 dk = TAILQ_FIRST(&disklist); 1205 } 1206 1207 /* 1208 * Create a list of volumes and associate chunks with each volume. 1209 */ 1210 for (bc = SLIST_FIRST(&bch); bc != SLIST_END(&bch); bc = bcnext) { 1211 1212 bcnext = SLIST_NEXT(bc, sbc_link); 1213 SLIST_REMOVE(&bch, bc, sr_boot_chunk, sbc_link); 1214 bc->sbc_chunk_id = bc->sbc_metadata->ssdi.ssd_chunk_id; 1215 1216 /* Handle key disks separately. */ 1217 if (bc->sbc_metadata->ssdi.ssd_level == SR_KEYDISK_LEVEL) { 1218 SLIST_INSERT_HEAD(&kdh, bc, sbc_link); 1219 continue; 1220 } 1221 1222 SLIST_FOREACH(bv, &bvh, sbv_link) { 1223 if (bcmp(&bc->sbc_metadata->ssdi.ssd_uuid, 1224 &bv->sbv_uuid, 1225 sizeof(bc->sbc_metadata->ssdi.ssd_uuid)) == 0) 1226 break; 1227 } 1228 1229 if (bv == NULL) { 1230 bv = malloc(sizeof(struct sr_boot_volume), 1231 M_DEVBUF, M_NOWAIT | M_CANFAIL | M_ZERO); 1232 if (bv == NULL) { 1233 printf("%s: failed to allocate boot volume\n", 1234 DEVNAME(sc)); 1235 goto unwind; 1236 } 1237 1238 bv->sbv_level = bc->sbc_metadata->ssdi.ssd_level; 1239 bv->sbv_volid = bc->sbc_metadata->ssdi.ssd_volid; 1240 bv->sbv_chunk_no = bc->sbc_metadata->ssdi.ssd_chunk_no; 1241 bv->sbv_flags = bc->sbc_metadata->ssdi.ssd_vol_flags; 1242 bcopy(&bc->sbc_metadata->ssdi.ssd_uuid, &bv->sbv_uuid, 1243 sizeof(bc->sbc_metadata->ssdi.ssd_uuid)); 1244 SLIST_INIT(&bv->sbv_chunks); 1245 1246 /* Maintain volume order. */ 1247 bv2 = NULL; 1248 SLIST_FOREACH(bv1, &bvh, sbv_link) { 1249 if (bv1->sbv_volid > bv->sbv_volid) 1250 break; 1251 bv2 = bv1; 1252 } 1253 if (bv2 == NULL) { 1254 DNPRINTF(SR_D_META, "%s: insert volume %u " 1255 "at head\n", DEVNAME(sc), bv->sbv_volid); 1256 SLIST_INSERT_HEAD(&bvh, bv, sbv_link); 1257 } else { 1258 DNPRINTF(SR_D_META, "%s: insert volume %u " 1259 "after %u\n", DEVNAME(sc), bv->sbv_volid, 1260 bv2->sbv_volid); 1261 SLIST_INSERT_AFTER(bv2, bv, sbv_link); 1262 } 1263 } 1264 1265 /* Maintain chunk order. */ 1266 bc2 = NULL; 1267 SLIST_FOREACH(bc1, &bv->sbv_chunks, sbc_link) { 1268 if (bc1->sbc_chunk_id > bc->sbc_chunk_id) 1269 break; 1270 bc2 = bc1; 1271 } 1272 if (bc2 == NULL) { 1273 DNPRINTF(SR_D_META, "%s: volume %u insert chunk %u " 1274 "at head\n", DEVNAME(sc), bv->sbv_volid, 1275 bc->sbc_chunk_id); 1276 SLIST_INSERT_HEAD(&bv->sbv_chunks, bc, sbc_link); 1277 } else { 1278 DNPRINTF(SR_D_META, "%s: volume %u insert chunk %u " 1279 "after %u\n", DEVNAME(sc), bv->sbv_volid, 1280 bc->sbc_chunk_id, bc2->sbc_chunk_id); 1281 SLIST_INSERT_AFTER(bc2, bc, sbc_link); 1282 } 1283 1284 bv->sbv_chunks_found++; 1285 } 1286 1287 /* Allocate memory for device and ondisk version arrays. */ 1288 devs = malloc(BIOC_CRMAXLEN * sizeof(dev_t), M_DEVBUF, 1289 M_NOWAIT | M_CANFAIL); 1290 if (devs == NULL) { 1291 printf("%s: failed to allocate device array\n", DEVNAME(sc)); 1292 goto unwind; 1293 } 1294 ondisk = malloc(BIOC_CRMAXLEN * sizeof(u_int64_t), M_DEVBUF, 1295 M_NOWAIT | M_CANFAIL); 1296 if (ondisk == NULL) { 1297 printf("%s: failed to allocate ondisk array\n", DEVNAME(sc)); 1298 goto unwind; 1299 } 1300 1301 /* 1302 * Assemble hotspare "volumes". 1303 */ 1304 SLIST_FOREACH(bv, &bvh, sbv_link) { 1305 1306 /* Check if this is a hotspare "volume". */ 1307 if (bv->sbv_level != SR_HOTSPARE_LEVEL || 1308 bv->sbv_chunk_no != 1) 1309 continue; 1310 1311 #ifdef SR_DEBUG 1312 DNPRINTF(SR_D_META, "%s: assembling hotspare volume ", 1313 DEVNAME(sc)); 1314 if (sr_debug & SR_D_META) 1315 sr_uuid_print(&bv->sbv_uuid, 0); 1316 DNPRINTF(SR_D_META, " volid %u with %u chunks\n", 1317 bv->sbv_volid, bv->sbv_chunk_no); 1318 #endif 1319 1320 /* Create hotspare chunk metadata. */ 1321 hotspare = malloc(sizeof(struct sr_chunk), M_DEVBUF, 1322 M_NOWAIT | M_CANFAIL | M_ZERO); 1323 if (hotspare == NULL) { 1324 printf("%s: failed to allocate hotspare\n", 1325 DEVNAME(sc)); 1326 goto unwind; 1327 } 1328 1329 bc = SLIST_FIRST(&bv->sbv_chunks); 1330 sr_meta_getdevname(sc, bc->sbc_mm, devname, sizeof(devname)); 1331 hotspare->src_dev_mm = bc->sbc_mm; 1332 strlcpy(hotspare->src_devname, devname, 1333 sizeof(hotspare->src_devname)); 1334 hotspare->src_size = bc->sbc_metadata->ssdi.ssd_size; 1335 1336 hm = &hotspare->src_meta; 1337 hm->scmi.scm_volid = SR_HOTSPARE_VOLID; 1338 hm->scmi.scm_chunk_id = 0; 1339 hm->scmi.scm_size = bc->sbc_metadata->ssdi.ssd_size; 1340 hm->scmi.scm_coerced_size = bc->sbc_metadata->ssdi.ssd_size; 1341 strlcpy(hm->scmi.scm_devname, devname, 1342 sizeof(hm->scmi.scm_devname)); 1343 bcopy(&bc->sbc_metadata->ssdi.ssd_uuid, &hm->scmi.scm_uuid, 1344 sizeof(struct sr_uuid)); 1345 1346 sr_checksum(sc, hm, &hm->scm_checksum, 1347 sizeof(struct sr_meta_chunk_invariant)); 1348 1349 hm->scm_status = BIOC_SDHOTSPARE; 1350 1351 /* Add chunk to hotspare list. */ 1352 rw_enter_write(&sc->sc_hs_lock); 1353 cl = &sc->sc_hotspare_list; 1354 if (SLIST_EMPTY(cl)) 1355 SLIST_INSERT_HEAD(cl, hotspare, src_link); 1356 else { 1357 SLIST_FOREACH(chunk, cl, src_link) 1358 last = chunk; 1359 SLIST_INSERT_AFTER(last, hotspare, src_link); 1360 } 1361 sc->sc_hotspare_no++; 1362 rw_exit_write(&sc->sc_hs_lock); 1363 1364 } 1365 1366 /* 1367 * Assemble RAID volumes. 1368 */ 1369 SLIST_FOREACH(bv, &bvh, sbv_link) { 1370 1371 bzero(&bcr, sizeof(bcr)); 1372 data = NULL; 1373 1374 /* Check if this is a hotspare "volume". */ 1375 if (bv->sbv_level == SR_HOTSPARE_LEVEL && 1376 bv->sbv_chunk_no == 1) 1377 continue; 1378 1379 /* 1380 * Skip volumes that are marked as no auto assemble, unless 1381 * this was the volume which we actually booted from. 1382 */ 1383 if (bcmp(&sr_bootuuid, &bv->sbv_uuid, sizeof(sr_bootuuid)) != 0) 1384 if (bv->sbv_flags & BIOC_SCNOAUTOASSEMBLE) 1385 continue; 1386 1387 #ifdef SR_DEBUG 1388 DNPRINTF(SR_D_META, "%s: assembling volume ", DEVNAME(sc)); 1389 if (sr_debug & SR_D_META) 1390 sr_uuid_print(&bv->sbv_uuid, 0); 1391 DNPRINTF(SR_D_META, " volid %u with %u chunks\n", 1392 bv->sbv_volid, bv->sbv_chunk_no); 1393 #endif 1394 1395 /* 1396 * If this is a crypto volume, try to find a matching 1397 * key disk... 1398 */ 1399 bcr.bc_key_disk = NODEV; 1400 if (bv->sbv_level == 'C') { 1401 SLIST_FOREACH(bc, &kdh, sbc_link) { 1402 if (bcmp(&bc->sbc_metadata->ssdi.ssd_uuid, 1403 &bv->sbv_uuid, 1404 sizeof(bc->sbc_metadata->ssdi.ssd_uuid)) 1405 == 0) 1406 bcr.bc_key_disk = bc->sbc_mm; 1407 } 1408 } 1409 1410 for (i = 0; i < BIOC_CRMAXLEN; i++) { 1411 devs[i] = NODEV; /* mark device as illegal */ 1412 ondisk[i] = 0; 1413 } 1414 1415 SLIST_FOREACH(bc, &bv->sbv_chunks, sbc_link) { 1416 if (devs[bc->sbc_chunk_id] != NODEV) { 1417 bv->sbv_chunks_found--; 1418 sr_meta_getdevname(sc, bc->sbc_mm, devname, 1419 sizeof(devname)); 1420 printf("%s: found duplicate chunk %u for " 1421 "volume %u on device %s\n", DEVNAME(sc), 1422 bc->sbc_chunk_id, bv->sbv_volid, devname); 1423 } 1424 1425 if (devs[bc->sbc_chunk_id] == NODEV || 1426 bc->sbc_metadata->ssd_ondisk > 1427 ondisk[bc->sbc_chunk_id]) { 1428 devs[bc->sbc_chunk_id] = bc->sbc_mm; 1429 ondisk[bc->sbc_chunk_id] = 1430 bc->sbc_metadata->ssd_ondisk; 1431 DNPRINTF(SR_D_META, "%s: using ondisk " 1432 "metadata version %llu for chunk %u\n", 1433 DEVNAME(sc), ondisk[bc->sbc_chunk_id], 1434 bc->sbc_chunk_id); 1435 } 1436 } 1437 1438 if (bv->sbv_chunk_no != bv->sbv_chunks_found) { 1439 printf("%s: not all chunks were provided; " 1440 "attempting to bring volume %d online\n", 1441 DEVNAME(sc), bv->sbv_volid); 1442 } 1443 1444 bcr.bc_level = bv->sbv_level; 1445 bcr.bc_dev_list_len = bv->sbv_chunk_no * sizeof(dev_t); 1446 bcr.bc_dev_list = devs; 1447 bcr.bc_flags = BIOC_SCDEVT | 1448 (bv->sbv_flags & BIOC_SCNOAUTOASSEMBLE); 1449 1450 if (bv->sbv_level == 'C' && 1451 bcmp(&sr_bootuuid, &bv->sbv_uuid, sizeof(sr_bootuuid)) == 0) 1452 data = sr_bootkey; 1453 1454 rw_enter_write(&sc->sc_lock); 1455 bio_status_init(&sc->sc_status, &sc->sc_dev); 1456 sr_ioctl_createraid(sc, &bcr, 0, data); 1457 rw_exit_write(&sc->sc_lock); 1458 1459 rv++; 1460 } 1461 1462 /* done with metadata */ 1463 unwind: 1464 /* Free boot volumes and associated chunks. */ 1465 for (bv1 = SLIST_FIRST(&bvh); bv1 != SLIST_END(&bvh); bv1 = bv2) { 1466 bv2 = SLIST_NEXT(bv1, sbv_link); 1467 for (bc1 = SLIST_FIRST(&bv1->sbv_chunks); 1468 bc1 != SLIST_END(&bv1->sbv_chunks); bc1 = bc2) { 1469 bc2 = SLIST_NEXT(bc1, sbc_link); 1470 if (bc1->sbc_metadata) 1471 free(bc1->sbc_metadata, M_DEVBUF); 1472 free(bc1, M_DEVBUF); 1473 } 1474 free(bv1, M_DEVBUF); 1475 } 1476 /* Free keydisks chunks. */ 1477 for (bc1 = SLIST_FIRST(&kdh); bc1 != SLIST_END(&kdh); bc1 = bc2) { 1478 bc2 = SLIST_NEXT(bc1, sbc_link); 1479 if (bc1->sbc_metadata) 1480 free(bc1->sbc_metadata, M_DEVBUF); 1481 free(bc1, M_DEVBUF); 1482 } 1483 /* Free unallocated chunks. */ 1484 for (bc1 = SLIST_FIRST(&bch); bc1 != SLIST_END(&bch); bc1 = bc2) { 1485 bc2 = SLIST_NEXT(bc1, sbc_link); 1486 if (bc1->sbc_metadata) 1487 free(bc1->sbc_metadata, M_DEVBUF); 1488 free(bc1, M_DEVBUF); 1489 } 1490 1491 while (!SLIST_EMPTY(&sdklist)) { 1492 sdk = SLIST_FIRST(&sdklist); 1493 SLIST_REMOVE_HEAD(&sdklist, sdk_link); 1494 free(sdk, M_DEVBUF); 1495 } 1496 1497 if (devs) 1498 free(devs, M_DEVBUF); 1499 if (ondisk) 1500 free(ondisk, M_DEVBUF); 1501 1502 return (rv); 1503 } 1504 1505 void 1506 sr_map_root(void) 1507 { 1508 struct sr_softc *sc = softraid0; 1509 struct sr_discipline *sd; 1510 struct sr_meta_opt_item *omi; 1511 struct sr_meta_boot *sbm; 1512 u_char duid[8]; 1513 int i; 1514 1515 DNPRINTF(SR_D_MISC, "%s: sr_map_root\n", DEVNAME(sc)); 1516 1517 if (sc == NULL) 1518 return; 1519 1520 bzero(duid, sizeof(duid)); 1521 if (bcmp(rootduid, duid, sizeof(duid)) == 0) { 1522 DNPRINTF(SR_D_MISC, "%s: root duid is zero\n", DEVNAME(sc)); 1523 return; 1524 } 1525 1526 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 1527 SLIST_FOREACH(omi, &sd->sd_meta_opt, omi_link) { 1528 if (omi->omi_som->som_type != SR_OPT_BOOT) 1529 continue; 1530 sbm = (struct sr_meta_boot *)omi->omi_som; 1531 for (i = 0; i < SR_MAX_BOOT_DISKS; i++) { 1532 if (bcmp(rootduid, sbm->sbm_boot_duid[i], 1533 sizeof(rootduid)) == 0) { 1534 bcopy(sbm->sbm_root_duid, rootduid, 1535 sizeof(rootduid)); 1536 DNPRINTF(SR_D_MISC, "%s: root duid " 1537 "mapped to %02hx%02hx%02hx%02hx" 1538 "%02hx%02hx%02hx%02hx\n", 1539 DEVNAME(sc), rootduid[0], 1540 rootduid[1], rootduid[2], 1541 rootduid[3], rootduid[4], 1542 rootduid[5], rootduid[6], 1543 rootduid[7]); 1544 return; 1545 } 1546 } 1547 } 1548 } 1549 } 1550 1551 int 1552 sr_meta_native_probe(struct sr_softc *sc, struct sr_chunk *ch_entry) 1553 { 1554 struct disklabel label; 1555 char *devname; 1556 int error, part; 1557 daddr_t size; 1558 1559 DNPRINTF(SR_D_META, "%s: sr_meta_native_probe(%s)\n", 1560 DEVNAME(sc), ch_entry->src_devname); 1561 1562 devname = ch_entry->src_devname; 1563 part = DISKPART(ch_entry->src_dev_mm); 1564 1565 /* get disklabel */ 1566 error = VOP_IOCTL(ch_entry->src_vn, DIOCGDINFO, (caddr_t)&label, FREAD, 1567 NOCRED, curproc); 1568 if (error) { 1569 DNPRINTF(SR_D_META, "%s: %s can't obtain disklabel\n", 1570 DEVNAME(sc), devname); 1571 goto unwind; 1572 } 1573 bcopy(label.d_uid, ch_entry->src_duid, sizeof(ch_entry->src_duid)); 1574 1575 /* Make sure this is a 512-byte/sector device. */ 1576 if (label.d_secsize != DEV_BSIZE) { 1577 sr_error(sc, "%s has unsupported sector size (%u)", 1578 devname, label.d_secsize); 1579 goto unwind; 1580 } 1581 1582 /* make sure the partition is of the right type */ 1583 if (label.d_partitions[part].p_fstype != FS_RAID) { 1584 DNPRINTF(SR_D_META, 1585 "%s: %s partition not of type RAID (%d)\n", DEVNAME(sc), 1586 devname, 1587 label.d_partitions[part].p_fstype); 1588 goto unwind; 1589 } 1590 1591 size = DL_SECTOBLK(&label, DL_GETPSIZE(&label.d_partitions[part])) - 1592 SR_DATA_OFFSET; 1593 if (size <= 0) { 1594 DNPRINTF(SR_D_META, "%s: %s partition too small\n", DEVNAME(sc), 1595 devname); 1596 goto unwind; 1597 } 1598 ch_entry->src_size = size; 1599 1600 DNPRINTF(SR_D_META, "%s: probe found %s size %lld\n", DEVNAME(sc), 1601 devname, (long long)size); 1602 1603 return (SR_META_F_NATIVE); 1604 unwind: 1605 DNPRINTF(SR_D_META, "%s: invalid device: %s\n", DEVNAME(sc), 1606 devname ? devname : "nodev"); 1607 return (SR_META_F_INVALID); 1608 } 1609 1610 int 1611 sr_meta_native_attach(struct sr_discipline *sd, int force) 1612 { 1613 struct sr_softc *sc = sd->sd_sc; 1614 struct sr_chunk_head *cl = &sd->sd_vol.sv_chunk_list; 1615 struct sr_metadata *md = NULL; 1616 struct sr_chunk *ch_entry, *ch_next; 1617 struct sr_uuid uuid; 1618 u_int64_t version = 0; 1619 int sr, not_sr, rv = 1, d, expected = -1, old_meta = 0; 1620 1621 DNPRINTF(SR_D_META, "%s: sr_meta_native_attach\n", DEVNAME(sc)); 1622 1623 md = malloc(SR_META_SIZE * 512, M_DEVBUF, M_ZERO | M_NOWAIT); 1624 if (md == NULL) { 1625 sr_error(sc, "not enough memory for metadata buffer"); 1626 goto bad; 1627 } 1628 1629 bzero(&uuid, sizeof uuid); 1630 1631 sr = not_sr = d = 0; 1632 SLIST_FOREACH(ch_entry, cl, src_link) { 1633 if (ch_entry->src_dev_mm == NODEV) 1634 continue; 1635 1636 if (sr_meta_native_read(sd, ch_entry->src_dev_mm, md, NULL)) { 1637 sr_error(sc, "could not read native metadata"); 1638 goto bad; 1639 } 1640 1641 if (md->ssdi.ssd_magic == SR_MAGIC) { 1642 sr++; 1643 ch_entry->src_meta.scmi.scm_chunk_id = 1644 md->ssdi.ssd_chunk_id; 1645 if (d == 0) { 1646 bcopy(&md->ssdi.ssd_uuid, &uuid, sizeof uuid); 1647 expected = md->ssdi.ssd_chunk_no; 1648 version = md->ssd_ondisk; 1649 d++; 1650 continue; 1651 } else if (bcmp(&md->ssdi.ssd_uuid, &uuid, 1652 sizeof uuid)) { 1653 sr_error(sc, "not part of the same volume"); 1654 goto bad; 1655 } 1656 if (md->ssd_ondisk != version) { 1657 old_meta++; 1658 version = MAX(md->ssd_ondisk, version); 1659 } 1660 } else 1661 not_sr++; 1662 } 1663 1664 if (sr && not_sr) { 1665 sr_error(sc, "not all chunks are of the native metadata " 1666 "format"); 1667 goto bad; 1668 } 1669 1670 /* mixed metadata versions; mark bad disks offline */ 1671 if (old_meta) { 1672 d = 0; 1673 for (ch_entry = SLIST_FIRST(cl); ch_entry != SLIST_END(cl); 1674 ch_entry = ch_next, d++) { 1675 ch_next = SLIST_NEXT(ch_entry, src_link); 1676 1677 /* XXX do we want to read this again? */ 1678 if (ch_entry->src_dev_mm == NODEV) 1679 panic("src_dev_mm == NODEV"); 1680 if (sr_meta_native_read(sd, ch_entry->src_dev_mm, md, 1681 NULL)) 1682 sr_warn(sc, "could not read native metadata"); 1683 if (md->ssd_ondisk != version) 1684 sd->sd_vol.sv_chunks[d]->src_meta.scm_status = 1685 BIOC_SDOFFLINE; 1686 } 1687 } 1688 1689 if (expected != sr && !force && expected != -1) { 1690 DNPRINTF(SR_D_META, "%s: not all chunks were provided, trying " 1691 "anyway\n", DEVNAME(sc)); 1692 } 1693 1694 rv = 0; 1695 bad: 1696 if (md) 1697 free(md, M_DEVBUF); 1698 return (rv); 1699 } 1700 1701 int 1702 sr_meta_native_read(struct sr_discipline *sd, dev_t dev, 1703 struct sr_metadata *md, void *fm) 1704 { 1705 #ifdef SR_DEBUG 1706 struct sr_softc *sc = sd->sd_sc; 1707 #endif 1708 DNPRINTF(SR_D_META, "%s: sr_meta_native_read(0x%x, %p)\n", 1709 DEVNAME(sc), dev, md); 1710 1711 return (sr_meta_rw(sd, dev, md, SR_META_SIZE * 512, SR_META_OFFSET, 1712 B_READ)); 1713 } 1714 1715 int 1716 sr_meta_native_write(struct sr_discipline *sd, dev_t dev, 1717 struct sr_metadata *md, void *fm) 1718 { 1719 #ifdef SR_DEBUG 1720 struct sr_softc *sc = sd->sd_sc; 1721 #endif 1722 DNPRINTF(SR_D_META, "%s: sr_meta_native_write(0x%x, %p)\n", 1723 DEVNAME(sc), dev, md); 1724 1725 return (sr_meta_rw(sd, dev, md, SR_META_SIZE * 512, SR_META_OFFSET, 1726 B_WRITE)); 1727 } 1728 1729 void 1730 sr_hotplug_register(struct sr_discipline *sd, void *func) 1731 { 1732 struct sr_hotplug_list *mhe; 1733 1734 DNPRINTF(SR_D_MISC, "%s: sr_hotplug_register: %p\n", 1735 DEVNAME(sd->sd_sc), func); 1736 1737 /* make sure we aren't on the list yet */ 1738 SLIST_FOREACH(mhe, &sr_hotplug_callbacks, shl_link) 1739 if (mhe->sh_hotplug == func) 1740 return; 1741 1742 mhe = malloc(sizeof(struct sr_hotplug_list), M_DEVBUF, 1743 M_WAITOK | M_ZERO); 1744 mhe->sh_hotplug = func; 1745 mhe->sh_sd = sd; 1746 SLIST_INSERT_HEAD(&sr_hotplug_callbacks, mhe, shl_link); 1747 } 1748 1749 void 1750 sr_hotplug_unregister(struct sr_discipline *sd, void *func) 1751 { 1752 struct sr_hotplug_list *mhe; 1753 1754 DNPRINTF(SR_D_MISC, "%s: sr_hotplug_unregister: %s %p\n", 1755 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, func); 1756 1757 /* make sure we are on the list yet */ 1758 SLIST_FOREACH(mhe, &sr_hotplug_callbacks, shl_link) 1759 if (mhe->sh_hotplug == func) { 1760 SLIST_REMOVE(&sr_hotplug_callbacks, mhe, 1761 sr_hotplug_list, shl_link); 1762 free(mhe, M_DEVBUF); 1763 if (SLIST_EMPTY(&sr_hotplug_callbacks)) 1764 SLIST_INIT(&sr_hotplug_callbacks); 1765 return; 1766 } 1767 } 1768 1769 void 1770 sr_disk_attach(struct disk *diskp, int action) 1771 { 1772 struct sr_hotplug_list *mhe; 1773 1774 SLIST_FOREACH(mhe, &sr_hotplug_callbacks, shl_link) 1775 if (mhe->sh_sd->sd_ready) 1776 mhe->sh_hotplug(mhe->sh_sd, diskp, action); 1777 } 1778 1779 int 1780 sr_match(struct device *parent, void *match, void *aux) 1781 { 1782 return (1); 1783 } 1784 1785 void 1786 sr_attach(struct device *parent, struct device *self, void *aux) 1787 { 1788 struct sr_softc *sc = (void *)self; 1789 struct scsibus_attach_args saa; 1790 1791 DNPRINTF(SR_D_MISC, "\n%s: sr_attach", DEVNAME(sc)); 1792 1793 if (softraid0 == NULL) 1794 softraid0 = sc; 1795 1796 rw_init(&sc->sc_lock, "sr_lock"); 1797 rw_init(&sc->sc_hs_lock, "sr_hs_lock"); 1798 1799 SLIST_INIT(&sr_hotplug_callbacks); 1800 TAILQ_INIT(&sc->sc_dis_list); 1801 SLIST_INIT(&sc->sc_hotspare_list); 1802 1803 #if NBIO > 0 1804 if (bio_register(&sc->sc_dev, sr_bio_ioctl) != 0) 1805 printf("%s: controller registration failed", DEVNAME(sc)); 1806 #endif /* NBIO > 0 */ 1807 1808 #ifndef SMALL_KERNEL 1809 strlcpy(sc->sc_sensordev.xname, DEVNAME(sc), 1810 sizeof(sc->sc_sensordev.xname)); 1811 sensordev_install(&sc->sc_sensordev); 1812 #endif /* SMALL_KERNEL */ 1813 1814 printf("\n"); 1815 1816 sc->sc_link.adapter_softc = sc; 1817 sc->sc_link.adapter = &sr_switch; 1818 sc->sc_link.adapter_target = SR_MAX_LD; 1819 sc->sc_link.adapter_buswidth = SR_MAX_LD; 1820 sc->sc_link.luns = 1; 1821 1822 bzero(&saa, sizeof(saa)); 1823 saa.saa_sc_link = &sc->sc_link; 1824 1825 sc->sc_scsibus = (struct scsibus_softc *)config_found(&sc->sc_dev, 1826 &saa, scsiprint); 1827 1828 softraid_disk_attach = sr_disk_attach; 1829 1830 sc->sc_shutdownhook = shutdownhook_establish(sr_shutdownhook, sc); 1831 1832 sr_boot_assembly(sc); 1833 1834 explicit_bzero(sr_bootkey, sizeof(sr_bootkey)); 1835 } 1836 1837 int 1838 sr_detach(struct device *self, int flags) 1839 { 1840 struct sr_softc *sc = (void *)self; 1841 int rv; 1842 1843 DNPRINTF(SR_D_MISC, "%s: sr_detach\n", DEVNAME(sc)); 1844 1845 if (sc->sc_shutdownhook) 1846 shutdownhook_disestablish(sc->sc_shutdownhook); 1847 1848 softraid_disk_attach = NULL; 1849 1850 sr_shutdown(sc); 1851 1852 #ifndef SMALL_KERNEL 1853 if (sc->sc_sensor_task != NULL) 1854 sensor_task_unregister(sc->sc_sensor_task); 1855 sensordev_deinstall(&sc->sc_sensordev); 1856 #endif /* SMALL_KERNEL */ 1857 1858 if (sc->sc_scsibus != NULL) { 1859 rv = config_detach((struct device *)sc->sc_scsibus, flags); 1860 if (rv != 0) 1861 return (rv); 1862 sc->sc_scsibus = NULL; 1863 } 1864 1865 return (0); 1866 } 1867 1868 void 1869 sr_info(struct sr_softc *sc, const char *fmt, ...) 1870 { 1871 va_list ap; 1872 1873 rw_assert_wrlock(&sc->sc_lock); 1874 1875 va_start(ap, fmt); 1876 bio_status(&sc->sc_status, 0, BIO_MSG_INFO, fmt, &ap); 1877 va_end(ap); 1878 } 1879 1880 void 1881 sr_warn(struct sr_softc *sc, const char *fmt, ...) 1882 { 1883 va_list ap; 1884 1885 rw_assert_wrlock(&sc->sc_lock); 1886 1887 va_start(ap, fmt); 1888 bio_status(&sc->sc_status, 1, BIO_MSG_WARN, fmt, &ap); 1889 va_end(ap); 1890 } 1891 1892 void 1893 sr_error(struct sr_softc *sc, const char *fmt, ...) 1894 { 1895 va_list ap; 1896 1897 rw_assert_wrlock(&sc->sc_lock); 1898 1899 va_start(ap, fmt); 1900 bio_status(&sc->sc_status, 1, BIO_MSG_ERROR, fmt, &ap); 1901 va_end(ap); 1902 } 1903 1904 void 1905 sr_minphys(struct buf *bp, struct scsi_link *sl) 1906 { 1907 DNPRINTF(SR_D_MISC, "sr_minphys: %d\n", bp->b_bcount); 1908 1909 /* XXX currently using SR_MAXFER = MAXPHYS */ 1910 if (bp->b_bcount > SR_MAXFER) 1911 bp->b_bcount = SR_MAXFER; 1912 minphys(bp); 1913 } 1914 1915 void 1916 sr_copy_internal_data(struct scsi_xfer *xs, void *v, size_t size) 1917 { 1918 size_t copy_cnt; 1919 1920 DNPRINTF(SR_D_MISC, "sr_copy_internal_data xs: %p size: %zu\n", 1921 xs, size); 1922 1923 if (xs->datalen) { 1924 copy_cnt = MIN(size, xs->datalen); 1925 bcopy(v, xs->data, copy_cnt); 1926 } 1927 } 1928 1929 int 1930 sr_ccb_alloc(struct sr_discipline *sd) 1931 { 1932 struct sr_ccb *ccb; 1933 int i; 1934 1935 if (!sd) 1936 return (1); 1937 1938 DNPRINTF(SR_D_CCB, "%s: sr_ccb_alloc\n", DEVNAME(sd->sd_sc)); 1939 1940 if (sd->sd_ccb) 1941 return (1); 1942 1943 sd->sd_ccb = malloc(sizeof(struct sr_ccb) * 1944 sd->sd_max_wu * sd->sd_max_ccb_per_wu, M_DEVBUF, M_WAITOK | M_ZERO); 1945 TAILQ_INIT(&sd->sd_ccb_freeq); 1946 for (i = 0; i < sd->sd_max_wu * sd->sd_max_ccb_per_wu; i++) { 1947 ccb = &sd->sd_ccb[i]; 1948 ccb->ccb_dis = sd; 1949 sr_ccb_put(ccb); 1950 } 1951 1952 DNPRINTF(SR_D_CCB, "%s: sr_ccb_alloc ccb: %d\n", 1953 DEVNAME(sd->sd_sc), sd->sd_max_wu * sd->sd_max_ccb_per_wu); 1954 1955 return (0); 1956 } 1957 1958 void 1959 sr_ccb_free(struct sr_discipline *sd) 1960 { 1961 struct sr_ccb *ccb; 1962 1963 if (!sd) 1964 return; 1965 1966 DNPRINTF(SR_D_CCB, "%s: sr_ccb_free %p\n", DEVNAME(sd->sd_sc), sd); 1967 1968 while ((ccb = TAILQ_FIRST(&sd->sd_ccb_freeq)) != NULL) 1969 TAILQ_REMOVE(&sd->sd_ccb_freeq, ccb, ccb_link); 1970 1971 if (sd->sd_ccb) 1972 free(sd->sd_ccb, M_DEVBUF); 1973 } 1974 1975 struct sr_ccb * 1976 sr_ccb_get(struct sr_discipline *sd) 1977 { 1978 struct sr_ccb *ccb; 1979 int s; 1980 1981 s = splbio(); 1982 1983 ccb = TAILQ_FIRST(&sd->sd_ccb_freeq); 1984 if (ccb) { 1985 TAILQ_REMOVE(&sd->sd_ccb_freeq, ccb, ccb_link); 1986 ccb->ccb_state = SR_CCB_INPROGRESS; 1987 } 1988 1989 splx(s); 1990 1991 DNPRINTF(SR_D_CCB, "%s: sr_ccb_get: %p\n", DEVNAME(sd->sd_sc), 1992 ccb); 1993 1994 return (ccb); 1995 } 1996 1997 void 1998 sr_ccb_put(struct sr_ccb *ccb) 1999 { 2000 struct sr_discipline *sd = ccb->ccb_dis; 2001 int s; 2002 2003 DNPRINTF(SR_D_CCB, "%s: sr_ccb_put: %p\n", DEVNAME(sd->sd_sc), 2004 ccb); 2005 2006 s = splbio(); 2007 2008 ccb->ccb_wu = NULL; 2009 ccb->ccb_state = SR_CCB_FREE; 2010 ccb->ccb_target = -1; 2011 ccb->ccb_opaque = NULL; 2012 2013 TAILQ_INSERT_TAIL(&sd->sd_ccb_freeq, ccb, ccb_link); 2014 2015 splx(s); 2016 } 2017 2018 struct sr_ccb * 2019 sr_ccb_rw(struct sr_discipline *sd, int chunk, daddr_t blkno, 2020 daddr_t len, u_int8_t *data, int xsflags, int ccbflags) 2021 { 2022 struct sr_chunk *sc = sd->sd_vol.sv_chunks[chunk]; 2023 struct sr_ccb *ccb = NULL; 2024 2025 ccb = sr_ccb_get(sd); 2026 if (ccb == NULL) 2027 goto out; 2028 2029 ccb->ccb_flags = ccbflags; 2030 ccb->ccb_target = chunk; 2031 2032 ccb->ccb_buf.b_flags = B_PHYS | B_CALL; 2033 if (ISSET(xsflags, SCSI_DATA_IN)) 2034 ccb->ccb_buf.b_flags |= B_READ; 2035 else 2036 ccb->ccb_buf.b_flags |= B_WRITE; 2037 2038 ccb->ccb_buf.b_blkno = blkno; 2039 ccb->ccb_buf.b_bcount = len; 2040 ccb->ccb_buf.b_bufsize = len; 2041 ccb->ccb_buf.b_resid = len; 2042 ccb->ccb_buf.b_data = data; 2043 ccb->ccb_buf.b_error = 0; 2044 ccb->ccb_buf.b_iodone = sd->sd_scsi_intr; 2045 ccb->ccb_buf.b_proc = curproc; 2046 ccb->ccb_buf.b_dev = sc->src_dev_mm; 2047 ccb->ccb_buf.b_vp = sc->src_vn; 2048 ccb->ccb_buf.b_bq = NULL; 2049 2050 if (!ISSET(ccb->ccb_buf.b_flags, B_READ)) 2051 ccb->ccb_buf.b_vp->v_numoutput++; 2052 2053 LIST_INIT(&ccb->ccb_buf.b_dep); 2054 2055 DNPRINTF(SR_D_DIS, "%s: %s %s ccb " 2056 "b_bcount %d b_blkno %lld b_flags 0x%0x b_data %p\n", 2057 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, sd->sd_name, 2058 ccb->ccb_buf.b_bcount, (long long)ccb->ccb_buf.b_blkno, 2059 ccb->ccb_buf.b_flags, ccb->ccb_buf.b_data); 2060 2061 out: 2062 return ccb; 2063 } 2064 2065 void 2066 sr_ccb_done(struct sr_ccb *ccb) 2067 { 2068 struct sr_workunit *wu = ccb->ccb_wu; 2069 struct sr_discipline *sd = wu->swu_dis; 2070 struct sr_softc *sc = sd->sd_sc; 2071 2072 DNPRINTF(SR_D_INTR, "%s: %s %s ccb done b_bcount %d b_resid %d" 2073 " b_flags 0x%0x block %lld target %d\n", 2074 DEVNAME(sc), sd->sd_meta->ssd_devname, sd->sd_name, 2075 ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_resid, ccb->ccb_buf.b_flags, 2076 (long long)ccb->ccb_buf.b_blkno, ccb->ccb_target); 2077 2078 splassert(IPL_BIO); 2079 2080 if (ccb->ccb_target == -1) 2081 panic("%s: invalid target on wu: %p", DEVNAME(sc), wu); 2082 2083 if (ccb->ccb_buf.b_flags & B_ERROR) { 2084 DNPRINTF(SR_D_INTR, "%s: i/o error on block %lld target %d\n", 2085 DEVNAME(sc), (long long)ccb->ccb_buf.b_blkno, 2086 ccb->ccb_target); 2087 if (ISSET(sd->sd_capabilities, SR_CAP_REDUNDANT)) 2088 sd->sd_set_chunk_state(sd, ccb->ccb_target, 2089 BIOC_SDOFFLINE); 2090 else 2091 printf("%s: i/o error on block %lld target %d " 2092 "b_error %d\n", DEVNAME(sc), 2093 (long long)ccb->ccb_buf.b_blkno, ccb->ccb_target, 2094 ccb->ccb_buf.b_error); 2095 ccb->ccb_state = SR_CCB_FAILED; 2096 wu->swu_ios_failed++; 2097 } else { 2098 ccb->ccb_state = SR_CCB_OK; 2099 wu->swu_ios_succeeded++; 2100 } 2101 2102 wu->swu_ios_complete++; 2103 } 2104 2105 int 2106 sr_wu_alloc(struct sr_discipline *sd, int wu_size) 2107 { 2108 struct sr_workunit *wu; 2109 int i, no_wu; 2110 2111 DNPRINTF(SR_D_WU, "%s: sr_wu_alloc %p %d\n", DEVNAME(sd->sd_sc), 2112 sd, sd->sd_max_wu); 2113 2114 no_wu = sd->sd_max_wu; 2115 sd->sd_wu_pending = no_wu; 2116 2117 mtx_init(&sd->sd_wu_mtx, IPL_BIO); 2118 TAILQ_INIT(&sd->sd_wu); 2119 TAILQ_INIT(&sd->sd_wu_freeq); 2120 TAILQ_INIT(&sd->sd_wu_pendq); 2121 TAILQ_INIT(&sd->sd_wu_defq); 2122 2123 for (i = 0; i < no_wu; i++) { 2124 wu = malloc(wu_size, M_DEVBUF, M_WAITOK | M_ZERO); 2125 TAILQ_INSERT_TAIL(&sd->sd_wu, wu, swu_next); 2126 TAILQ_INIT(&wu->swu_ccb); 2127 task_set(&wu->swu_task, sr_wu_done_callback, sd, wu); 2128 wu->swu_dis = sd; 2129 sr_wu_put(sd, wu); 2130 } 2131 2132 return (0); 2133 } 2134 2135 void 2136 sr_wu_free(struct sr_discipline *sd) 2137 { 2138 struct sr_workunit *wu; 2139 2140 DNPRINTF(SR_D_WU, "%s: sr_wu_free %p\n", DEVNAME(sd->sd_sc), sd); 2141 2142 while ((wu = TAILQ_FIRST(&sd->sd_wu_freeq)) != NULL) 2143 TAILQ_REMOVE(&sd->sd_wu_freeq, wu, swu_link); 2144 while ((wu = TAILQ_FIRST(&sd->sd_wu_pendq)) != NULL) 2145 TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link); 2146 while ((wu = TAILQ_FIRST(&sd->sd_wu_defq)) != NULL) 2147 TAILQ_REMOVE(&sd->sd_wu_defq, wu, swu_link); 2148 2149 while ((wu = TAILQ_FIRST(&sd->sd_wu)) != NULL) { 2150 TAILQ_REMOVE(&sd->sd_wu, wu, swu_next); 2151 free(wu, M_DEVBUF); 2152 } 2153 } 2154 2155 void * 2156 sr_wu_get(void *xsd) 2157 { 2158 struct sr_discipline *sd = (struct sr_discipline *)xsd; 2159 struct sr_workunit *wu; 2160 2161 mtx_enter(&sd->sd_wu_mtx); 2162 wu = TAILQ_FIRST(&sd->sd_wu_freeq); 2163 if (wu) { 2164 TAILQ_REMOVE(&sd->sd_wu_freeq, wu, swu_link); 2165 sd->sd_wu_pending++; 2166 } 2167 mtx_leave(&sd->sd_wu_mtx); 2168 2169 DNPRINTF(SR_D_WU, "%s: sr_wu_get: %p\n", DEVNAME(sd->sd_sc), wu); 2170 2171 return (wu); 2172 } 2173 2174 void 2175 sr_wu_put(void *xsd, void *xwu) 2176 { 2177 struct sr_discipline *sd = (struct sr_discipline *)xsd; 2178 struct sr_workunit *wu = (struct sr_workunit *)xwu; 2179 2180 DNPRINTF(SR_D_WU, "%s: sr_wu_put: %p\n", DEVNAME(sd->sd_sc), wu); 2181 2182 sr_wu_release_ccbs(wu); 2183 sr_wu_init(sd, wu); 2184 2185 mtx_enter(&sd->sd_wu_mtx); 2186 TAILQ_INSERT_TAIL(&sd->sd_wu_freeq, wu, swu_link); 2187 sd->sd_wu_pending--; 2188 mtx_leave(&sd->sd_wu_mtx); 2189 } 2190 2191 void 2192 sr_wu_init(struct sr_discipline *sd, struct sr_workunit *wu) 2193 { 2194 int s; 2195 2196 s = splbio(); 2197 if (wu->swu_cb_active == 1) 2198 panic("%s: sr_wu_init got active wu", DEVNAME(sd->sd_sc)); 2199 splx(s); 2200 2201 wu->swu_xs = NULL; 2202 wu->swu_state = SR_WU_FREE; 2203 wu->swu_flags = 0; 2204 wu->swu_blk_start = 0; 2205 wu->swu_blk_end = 0; 2206 wu->swu_collider = NULL; 2207 } 2208 2209 void 2210 sr_wu_enqueue_ccb(struct sr_workunit *wu, struct sr_ccb *ccb) 2211 { 2212 struct sr_discipline *sd = wu->swu_dis; 2213 int s; 2214 2215 s = splbio(); 2216 if (wu->swu_cb_active == 1) 2217 panic("%s: sr_wu_enqueue_ccb got active wu", 2218 DEVNAME(sd->sd_sc)); 2219 ccb->ccb_wu = wu; 2220 wu->swu_io_count++; 2221 TAILQ_INSERT_TAIL(&wu->swu_ccb, ccb, ccb_link); 2222 splx(s); 2223 } 2224 2225 void 2226 sr_wu_release_ccbs(struct sr_workunit *wu) 2227 { 2228 struct sr_ccb *ccb; 2229 2230 /* Return all ccbs that are associated with this workunit. */ 2231 while ((ccb = TAILQ_FIRST(&wu->swu_ccb)) != NULL) { 2232 TAILQ_REMOVE(&wu->swu_ccb, ccb, ccb_link); 2233 sr_ccb_put(ccb); 2234 } 2235 2236 wu->swu_io_count = 0; 2237 wu->swu_ios_complete = 0; 2238 wu->swu_ios_failed = 0; 2239 wu->swu_ios_succeeded = 0; 2240 } 2241 2242 void 2243 sr_wu_done(struct sr_workunit *wu) 2244 { 2245 struct sr_discipline *sd = wu->swu_dis; 2246 2247 DNPRINTF(SR_D_INTR, "%s: sr_wu_done count %d completed %d failed %d\n", 2248 DEVNAME(sd->sd_sc), wu->swu_io_count, wu->swu_ios_complete, 2249 wu->swu_ios_failed); 2250 2251 if (wu->swu_ios_complete < wu->swu_io_count) 2252 return; 2253 2254 task_add(sd->sd_taskq, &wu->swu_task); 2255 } 2256 2257 void 2258 sr_wu_done_callback(void *arg1, void *arg2) 2259 { 2260 struct sr_discipline *sd = (struct sr_discipline *)arg1; 2261 struct sr_workunit *wu = (struct sr_workunit *)arg2; 2262 struct scsi_xfer *xs = wu->swu_xs; 2263 struct sr_workunit *wup; 2264 int s; 2265 2266 /* 2267 * The SR_WUF_DISCIPLINE or SR_WUF_REBUILD flag must be set if 2268 * the work unit is not associated with a scsi_xfer. 2269 */ 2270 KASSERT(xs != NULL || 2271 (wu->swu_flags & (SR_WUF_DISCIPLINE|SR_WUF_REBUILD))); 2272 2273 s = splbio(); 2274 2275 if (xs != NULL) { 2276 if (wu->swu_ios_failed) 2277 xs->error = XS_DRIVER_STUFFUP; 2278 else 2279 xs->error = XS_NOERROR; 2280 } 2281 2282 if (sd->sd_scsi_wu_done) { 2283 if (sd->sd_scsi_wu_done(wu) == SR_WU_RESTART) 2284 goto done; 2285 } 2286 2287 /* Remove work unit from pending queue. */ 2288 TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) 2289 if (wup == wu) 2290 break; 2291 if (wup == NULL) 2292 panic("%s: wu %p not on pending queue", 2293 DEVNAME(sd->sd_sc), wu); 2294 TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link); 2295 2296 if (wu->swu_collider) { 2297 if (wu->swu_ios_failed) 2298 sr_raid_recreate_wu(wu->swu_collider); 2299 2300 /* XXX Should the collider be failed if this xs failed? */ 2301 sr_raid_startwu(wu->swu_collider); 2302 } 2303 2304 /* 2305 * If a discipline provides its own sd_scsi_done function, then it 2306 * is responsible for calling sr_scsi_done() once I/O is complete. 2307 */ 2308 if (wu->swu_flags & SR_WUF_REBUILD) 2309 wu->swu_flags |= SR_WUF_REBUILDIOCOMP; 2310 if (wu->swu_flags & SR_WUF_WAKEUP) 2311 wakeup(wu); 2312 if (sd->sd_scsi_done) 2313 sd->sd_scsi_done(wu); 2314 else if (wu->swu_flags & SR_WUF_DISCIPLINE) 2315 sr_scsi_wu_put(sd, wu); 2316 else if (!(wu->swu_flags & SR_WUF_REBUILD)) 2317 sr_scsi_done(sd, xs); 2318 2319 done: 2320 splx(s); 2321 } 2322 2323 struct sr_workunit * 2324 sr_scsi_wu_get(struct sr_discipline *sd, int flags) 2325 { 2326 return scsi_io_get(&sd->sd_iopool, flags); 2327 } 2328 2329 void 2330 sr_scsi_wu_put(struct sr_discipline *sd, struct sr_workunit *wu) 2331 { 2332 scsi_io_put(&sd->sd_iopool, wu); 2333 2334 if (sd->sd_sync && sd->sd_wu_pending == 0) 2335 wakeup(sd); 2336 } 2337 2338 void 2339 sr_scsi_done(struct sr_discipline *sd, struct scsi_xfer *xs) 2340 { 2341 DNPRINTF(SR_D_DIS, "%s: sr_scsi_done: xs %p\n", DEVNAME(sd->sd_sc), xs); 2342 2343 if (xs->error == XS_NOERROR) 2344 xs->resid = 0; 2345 2346 scsi_done(xs); 2347 2348 if (sd->sd_sync && sd->sd_wu_pending == 0) 2349 wakeup(sd); 2350 } 2351 2352 void 2353 sr_scsi_cmd(struct scsi_xfer *xs) 2354 { 2355 struct scsi_link *link = xs->sc_link; 2356 struct sr_softc *sc = link->adapter_softc; 2357 struct sr_workunit *wu = xs->io; 2358 struct sr_discipline *sd; 2359 2360 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd target %d xs %p flags %#x\n", 2361 DEVNAME(sc), link->target, xs, xs->flags); 2362 2363 sd = sc->sc_targets[link->target]; 2364 if (sd == NULL) { 2365 printf("%s: sr_scsi_cmd NULL discipline\n", DEVNAME(sc)); 2366 goto stuffup; 2367 } 2368 2369 if (sd->sd_deleted) { 2370 printf("%s: %s device is being deleted, failing io\n", 2371 DEVNAME(sc), sd->sd_meta->ssd_devname); 2372 goto stuffup; 2373 } 2374 2375 /* scsi layer *can* re-send wu without calling sr_wu_put(). */ 2376 sr_wu_release_ccbs(wu); 2377 sr_wu_init(sd, wu); 2378 wu->swu_state = SR_WU_INPROGRESS; 2379 wu->swu_xs = xs; 2380 2381 switch (xs->cmd->opcode) { 2382 case READ_COMMAND: 2383 case READ_BIG: 2384 case READ_16: 2385 case WRITE_COMMAND: 2386 case WRITE_BIG: 2387 case WRITE_16: 2388 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: READ/WRITE %02x\n", 2389 DEVNAME(sc), xs->cmd->opcode); 2390 if (sd->sd_scsi_rw(wu)) 2391 goto stuffup; 2392 break; 2393 2394 case SYNCHRONIZE_CACHE: 2395 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: SYNCHRONIZE_CACHE\n", 2396 DEVNAME(sc)); 2397 if (sd->sd_scsi_sync(wu)) 2398 goto stuffup; 2399 goto complete; 2400 2401 case TEST_UNIT_READY: 2402 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: TEST_UNIT_READY\n", 2403 DEVNAME(sc)); 2404 if (sd->sd_scsi_tur(wu)) 2405 goto stuffup; 2406 goto complete; 2407 2408 case START_STOP: 2409 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: START_STOP\n", 2410 DEVNAME(sc)); 2411 if (sd->sd_scsi_start_stop(wu)) 2412 goto stuffup; 2413 goto complete; 2414 2415 case INQUIRY: 2416 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: INQUIRY\n", 2417 DEVNAME(sc)); 2418 if (sd->sd_scsi_inquiry(wu)) 2419 goto stuffup; 2420 goto complete; 2421 2422 case READ_CAPACITY: 2423 case READ_CAPACITY_16: 2424 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd READ CAPACITY 0x%02x\n", 2425 DEVNAME(sc), xs->cmd->opcode); 2426 if (sd->sd_scsi_read_cap(wu)) 2427 goto stuffup; 2428 goto complete; 2429 2430 case REQUEST_SENSE: 2431 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd REQUEST SENSE\n", 2432 DEVNAME(sc)); 2433 if (sd->sd_scsi_req_sense(wu)) 2434 goto stuffup; 2435 goto complete; 2436 2437 default: 2438 DNPRINTF(SR_D_CMD, "%s: unsupported scsi command %x\n", 2439 DEVNAME(sc), xs->cmd->opcode); 2440 /* XXX might need to add generic function to handle others */ 2441 goto stuffup; 2442 } 2443 2444 return; 2445 stuffup: 2446 if (sd && sd->sd_scsi_sense.error_code) { 2447 xs->error = XS_SENSE; 2448 bcopy(&sd->sd_scsi_sense, &xs->sense, sizeof(xs->sense)); 2449 bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense)); 2450 } else { 2451 xs->error = XS_DRIVER_STUFFUP; 2452 } 2453 complete: 2454 sr_scsi_done(sd, xs); 2455 } 2456 2457 int 2458 sr_scsi_probe(struct scsi_link *link) 2459 { 2460 struct sr_softc *sc = link->adapter_softc; 2461 struct sr_discipline *sd; 2462 2463 KASSERT(link->target < SR_MAX_LD && link->lun == 0); 2464 2465 sd = sc->sc_targets[link->target]; 2466 if (sd == NULL) 2467 return (ENODEV); 2468 2469 link->pool = &sd->sd_iopool; 2470 if (sd->sd_openings) 2471 link->openings = sd->sd_openings(sd); 2472 else 2473 link->openings = sd->sd_max_wu; 2474 2475 return (0); 2476 } 2477 2478 int 2479 sr_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag) 2480 { 2481 DNPRINTF(SR_D_IOCTL, "%s: sr_scsi_ioctl cmd: %#x\n", 2482 DEVNAME((struct sr_softc *)link->adapter_softc), cmd); 2483 2484 /* Pass bio ioctls through to bio handler. */ 2485 if (IOCGROUP(cmd) == 'B') 2486 return (sr_bio_ioctl(link->adapter_softc, cmd, addr)); 2487 2488 switch (cmd) { 2489 case DIOCGCACHE: 2490 case DIOCSCACHE: 2491 return (EOPNOTSUPP); 2492 default: 2493 return (ENOTTY); 2494 } 2495 } 2496 2497 int 2498 sr_bio_ioctl(struct device *dev, u_long cmd, caddr_t addr) 2499 { 2500 struct sr_softc *sc = (struct sr_softc *)dev; 2501 struct bio *bio = (struct bio *)addr; 2502 int rv = 0; 2503 2504 DNPRINTF(SR_D_IOCTL, "%s: sr_bio_ioctl ", DEVNAME(sc)); 2505 2506 rw_enter_write(&sc->sc_lock); 2507 2508 bio_status_init(&sc->sc_status, &sc->sc_dev); 2509 2510 switch (cmd) { 2511 case BIOCINQ: 2512 DNPRINTF(SR_D_IOCTL, "inq\n"); 2513 rv = sr_ioctl_inq(sc, (struct bioc_inq *)addr); 2514 break; 2515 2516 case BIOCVOL: 2517 DNPRINTF(SR_D_IOCTL, "vol\n"); 2518 rv = sr_ioctl_vol(sc, (struct bioc_vol *)addr); 2519 break; 2520 2521 case BIOCDISK: 2522 DNPRINTF(SR_D_IOCTL, "disk\n"); 2523 rv = sr_ioctl_disk(sc, (struct bioc_disk *)addr); 2524 break; 2525 2526 case BIOCALARM: 2527 DNPRINTF(SR_D_IOCTL, "alarm\n"); 2528 /*rv = sr_ioctl_alarm(sc, (struct bioc_alarm *)addr); */ 2529 break; 2530 2531 case BIOCBLINK: 2532 DNPRINTF(SR_D_IOCTL, "blink\n"); 2533 /*rv = sr_ioctl_blink(sc, (struct bioc_blink *)addr); */ 2534 break; 2535 2536 case BIOCSETSTATE: 2537 DNPRINTF(SR_D_IOCTL, "setstate\n"); 2538 rv = sr_ioctl_setstate(sc, (struct bioc_setstate *)addr); 2539 break; 2540 2541 case BIOCCREATERAID: 2542 DNPRINTF(SR_D_IOCTL, "createraid\n"); 2543 rv = sr_ioctl_createraid(sc, (struct bioc_createraid *)addr, 2544 1, NULL); 2545 break; 2546 2547 case BIOCDELETERAID: 2548 DNPRINTF(SR_D_IOCTL, "deleteraid\n"); 2549 rv = sr_ioctl_deleteraid(sc, (struct bioc_deleteraid *)addr); 2550 break; 2551 2552 case BIOCDISCIPLINE: 2553 DNPRINTF(SR_D_IOCTL, "discipline\n"); 2554 rv = sr_ioctl_discipline(sc, (struct bioc_discipline *)addr); 2555 break; 2556 2557 case BIOCINSTALLBOOT: 2558 DNPRINTF(SR_D_IOCTL, "installboot\n"); 2559 rv = sr_ioctl_installboot(sc, (struct bioc_installboot *)addr); 2560 break; 2561 2562 default: 2563 DNPRINTF(SR_D_IOCTL, "invalid ioctl\n"); 2564 rv = ENOTTY; 2565 } 2566 2567 sc->sc_status.bs_status = (rv ? BIO_STATUS_ERROR : BIO_STATUS_SUCCESS); 2568 2569 bcopy(&sc->sc_status, &bio->bio_status, sizeof(struct bio_status)); 2570 2571 rw_exit_write(&sc->sc_lock); 2572 2573 return (0); 2574 } 2575 2576 int 2577 sr_ioctl_inq(struct sr_softc *sc, struct bioc_inq *bi) 2578 { 2579 struct sr_discipline *sd; 2580 int vol = 0, disk = 0; 2581 2582 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 2583 vol++; 2584 disk += sd->sd_meta->ssdi.ssd_chunk_no; 2585 } 2586 2587 strlcpy(bi->bi_dev, sc->sc_dev.dv_xname, sizeof(bi->bi_dev)); 2588 bi->bi_novol = vol + sc->sc_hotspare_no; 2589 bi->bi_nodisk = disk + sc->sc_hotspare_no; 2590 2591 return (0); 2592 } 2593 2594 int 2595 sr_ioctl_vol(struct sr_softc *sc, struct bioc_vol *bv) 2596 { 2597 int vol = -1, rv = EINVAL; 2598 struct sr_discipline *sd; 2599 struct sr_chunk *hotspare; 2600 daddr_t rb, sz; 2601 2602 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 2603 vol++; 2604 if (vol != bv->bv_volid) 2605 continue; 2606 2607 bv->bv_status = sd->sd_vol_status; 2608 bv->bv_size = sd->sd_meta->ssdi.ssd_size << DEV_BSHIFT; 2609 bv->bv_level = sd->sd_meta->ssdi.ssd_level; 2610 bv->bv_nodisk = sd->sd_meta->ssdi.ssd_chunk_no; 2611 2612 #ifdef CRYPTO 2613 if (sd->sd_meta->ssdi.ssd_level == 'C' && 2614 sd->mds.mdd_crypto.key_disk != NULL) 2615 bv->bv_nodisk++; 2616 #endif 2617 2618 if (bv->bv_status == BIOC_SVREBUILD) { 2619 sz = sd->sd_meta->ssdi.ssd_size; 2620 rb = sd->sd_meta->ssd_rebuild; 2621 if (rb > 0) 2622 bv->bv_percent = 100 - 2623 ((sz * 100 - rb * 100) / sz) - 1; 2624 else 2625 bv->bv_percent = 0; 2626 } 2627 strlcpy(bv->bv_dev, sd->sd_meta->ssd_devname, 2628 sizeof(bv->bv_dev)); 2629 strlcpy(bv->bv_vendor, sd->sd_meta->ssdi.ssd_vendor, 2630 sizeof(bv->bv_vendor)); 2631 rv = 0; 2632 goto done; 2633 } 2634 2635 /* Check hotspares list. */ 2636 SLIST_FOREACH(hotspare, &sc->sc_hotspare_list, src_link) { 2637 vol++; 2638 if (vol != bv->bv_volid) 2639 continue; 2640 2641 bv->bv_status = BIOC_SVONLINE; 2642 bv->bv_size = hotspare->src_meta.scmi.scm_size << DEV_BSHIFT; 2643 bv->bv_level = -1; /* Hotspare. */ 2644 bv->bv_nodisk = 1; 2645 strlcpy(bv->bv_dev, hotspare->src_meta.scmi.scm_devname, 2646 sizeof(bv->bv_dev)); 2647 strlcpy(bv->bv_vendor, hotspare->src_meta.scmi.scm_devname, 2648 sizeof(bv->bv_vendor)); 2649 rv = 0; 2650 goto done; 2651 } 2652 2653 done: 2654 return (rv); 2655 } 2656 2657 int 2658 sr_ioctl_disk(struct sr_softc *sc, struct bioc_disk *bd) 2659 { 2660 struct sr_discipline *sd; 2661 struct sr_chunk *src, *hotspare; 2662 int vol = -1, rv = EINVAL; 2663 2664 if (bd->bd_diskid < 0) 2665 goto done; 2666 2667 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 2668 vol++; 2669 if (vol != bd->bd_volid) 2670 continue; 2671 2672 if (bd->bd_diskid < sd->sd_meta->ssdi.ssd_chunk_no) 2673 src = sd->sd_vol.sv_chunks[bd->bd_diskid]; 2674 #ifdef CRYPTO 2675 else if (bd->bd_diskid == sd->sd_meta->ssdi.ssd_chunk_no && 2676 sd->sd_meta->ssdi.ssd_level == 'C' && 2677 sd->mds.mdd_crypto.key_disk != NULL) 2678 src = sd->mds.mdd_crypto.key_disk; 2679 #endif 2680 else 2681 break; 2682 2683 bd->bd_status = src->src_meta.scm_status; 2684 bd->bd_size = src->src_meta.scmi.scm_size << DEV_BSHIFT; 2685 bd->bd_channel = vol; 2686 bd->bd_target = bd->bd_diskid; 2687 strlcpy(bd->bd_vendor, src->src_meta.scmi.scm_devname, 2688 sizeof(bd->bd_vendor)); 2689 rv = 0; 2690 goto done; 2691 } 2692 2693 /* Check hotspares list. */ 2694 SLIST_FOREACH(hotspare, &sc->sc_hotspare_list, src_link) { 2695 vol++; 2696 if (vol != bd->bd_volid) 2697 continue; 2698 2699 if (bd->bd_diskid != 0) 2700 break; 2701 2702 bd->bd_status = hotspare->src_meta.scm_status; 2703 bd->bd_size = hotspare->src_meta.scmi.scm_size << DEV_BSHIFT; 2704 bd->bd_channel = vol; 2705 bd->bd_target = bd->bd_diskid; 2706 strlcpy(bd->bd_vendor, hotspare->src_meta.scmi.scm_devname, 2707 sizeof(bd->bd_vendor)); 2708 rv = 0; 2709 goto done; 2710 } 2711 2712 done: 2713 return (rv); 2714 } 2715 2716 int 2717 sr_ioctl_setstate(struct sr_softc *sc, struct bioc_setstate *bs) 2718 { 2719 int rv = EINVAL; 2720 int vol = -1, found, c; 2721 struct sr_discipline *sd; 2722 struct sr_chunk *ch_entry; 2723 struct sr_chunk_head *cl; 2724 2725 if (bs->bs_other_id_type == BIOC_SSOTHER_UNUSED) 2726 goto done; 2727 2728 if (bs->bs_status == BIOC_SSHOTSPARE) { 2729 rv = sr_hotspare(sc, (dev_t)bs->bs_other_id); 2730 goto done; 2731 } 2732 2733 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 2734 vol++; 2735 if (vol == bs->bs_volid) 2736 break; 2737 } 2738 if (sd == NULL) 2739 goto done; 2740 2741 switch (bs->bs_status) { 2742 case BIOC_SSOFFLINE: 2743 /* Take chunk offline */ 2744 found = c = 0; 2745 cl = &sd->sd_vol.sv_chunk_list; 2746 SLIST_FOREACH(ch_entry, cl, src_link) { 2747 if (ch_entry->src_dev_mm == bs->bs_other_id) { 2748 found = 1; 2749 break; 2750 } 2751 c++; 2752 } 2753 if (found == 0) { 2754 sr_error(sc, "chunk not part of array"); 2755 goto done; 2756 } 2757 2758 /* XXX: check current state first */ 2759 sd->sd_set_chunk_state(sd, c, BIOC_SDOFFLINE); 2760 2761 if (sr_meta_save(sd, SR_META_DIRTY)) { 2762 sr_error(sc, "could not save metadata for %s", 2763 sd->sd_meta->ssd_devname); 2764 goto done; 2765 } 2766 rv = 0; 2767 break; 2768 2769 case BIOC_SDSCRUB: 2770 break; 2771 2772 case BIOC_SSREBUILD: 2773 rv = sr_rebuild_init(sd, (dev_t)bs->bs_other_id, 0); 2774 break; 2775 2776 default: 2777 sr_error(sc, "unsupported state request %d", bs->bs_status); 2778 } 2779 2780 done: 2781 return (rv); 2782 } 2783 2784 int 2785 sr_chunk_in_use(struct sr_softc *sc, dev_t dev) 2786 { 2787 struct sr_discipline *sd; 2788 struct sr_chunk *chunk; 2789 int i; 2790 2791 DNPRINTF(SR_D_MISC, "%s: sr_chunk_in_use(%d)\n", DEVNAME(sc), dev); 2792 2793 if (dev == NODEV) 2794 return BIOC_SDINVALID; 2795 2796 /* See if chunk is already in use. */ 2797 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 2798 for (i = 0; i < sd->sd_meta->ssdi.ssd_chunk_no; i++) { 2799 chunk = sd->sd_vol.sv_chunks[i]; 2800 if (chunk->src_dev_mm == dev) 2801 return chunk->src_meta.scm_status; 2802 } 2803 } 2804 2805 /* Check hotspares list. */ 2806 SLIST_FOREACH(chunk, &sc->sc_hotspare_list, src_link) 2807 if (chunk->src_dev_mm == dev) 2808 return chunk->src_meta.scm_status; 2809 2810 return BIOC_SDINVALID; 2811 } 2812 2813 int 2814 sr_hotspare(struct sr_softc *sc, dev_t dev) 2815 { 2816 struct sr_discipline *sd = NULL; 2817 struct sr_metadata *sm = NULL; 2818 struct sr_meta_chunk *hm; 2819 struct sr_chunk_head *cl; 2820 struct sr_chunk *chunk, *last, *hotspare = NULL; 2821 struct sr_uuid uuid; 2822 struct disklabel label; 2823 struct vnode *vn; 2824 daddr_t size; 2825 char devname[32]; 2826 int rv = EINVAL; 2827 int c, part, open = 0; 2828 2829 /* 2830 * Add device to global hotspares list. 2831 */ 2832 2833 sr_meta_getdevname(sc, dev, devname, sizeof(devname)); 2834 2835 /* Make sure chunk is not already in use. */ 2836 c = sr_chunk_in_use(sc, dev); 2837 if (c != BIOC_SDINVALID && c != BIOC_SDOFFLINE) { 2838 if (c == BIOC_SDHOTSPARE) 2839 sr_error(sc, "%s is already a hotspare", devname); 2840 else 2841 sr_error(sc, "%s is already in use", devname); 2842 goto done; 2843 } 2844 2845 /* XXX - See if there is an existing degraded volume... */ 2846 2847 /* Open device. */ 2848 if (bdevvp(dev, &vn)) { 2849 sr_error(sc, "sr_hotspare: cannot allocate vnode"); 2850 goto done; 2851 } 2852 if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, curproc)) { 2853 DNPRINTF(SR_D_META,"%s: sr_hotspare cannot open %s\n", 2854 DEVNAME(sc), devname); 2855 vput(vn); 2856 goto fail; 2857 } 2858 open = 1; /* close dev on error */ 2859 2860 /* Get partition details. */ 2861 part = DISKPART(dev); 2862 if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, FREAD, 2863 NOCRED, curproc)) { 2864 DNPRINTF(SR_D_META, "%s: sr_hotspare ioctl failed\n", 2865 DEVNAME(sc)); 2866 VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); 2867 vput(vn); 2868 goto fail; 2869 } 2870 if (label.d_secsize != DEV_BSIZE) { 2871 sr_error(sc, "%s has unsupported sector size (%u)", 2872 devname, label.d_secsize); 2873 goto fail; 2874 } 2875 if (label.d_partitions[part].p_fstype != FS_RAID) { 2876 sr_error(sc, "%s partition not of type RAID (%d)", 2877 devname, label.d_partitions[part].p_fstype); 2878 goto fail; 2879 } 2880 2881 /* Calculate partition size. */ 2882 size = DL_SECTOBLK(&label, DL_GETPSIZE(&label.d_partitions[part])) - 2883 SR_DATA_OFFSET; 2884 2885 /* 2886 * Create and populate chunk metadata. 2887 */ 2888 2889 sr_uuid_generate(&uuid); 2890 hotspare = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK | M_ZERO); 2891 2892 hotspare->src_dev_mm = dev; 2893 hotspare->src_vn = vn; 2894 strlcpy(hotspare->src_devname, devname, sizeof(hm->scmi.scm_devname)); 2895 hotspare->src_size = size; 2896 2897 hm = &hotspare->src_meta; 2898 hm->scmi.scm_volid = SR_HOTSPARE_VOLID; 2899 hm->scmi.scm_chunk_id = 0; 2900 hm->scmi.scm_size = size; 2901 hm->scmi.scm_coerced_size = size; 2902 strlcpy(hm->scmi.scm_devname, devname, sizeof(hm->scmi.scm_devname)); 2903 bcopy(&uuid, &hm->scmi.scm_uuid, sizeof(struct sr_uuid)); 2904 2905 sr_checksum(sc, hm, &hm->scm_checksum, 2906 sizeof(struct sr_meta_chunk_invariant)); 2907 2908 hm->scm_status = BIOC_SDHOTSPARE; 2909 2910 /* 2911 * Create and populate our own discipline and metadata. 2912 */ 2913 2914 sm = malloc(sizeof(struct sr_metadata), M_DEVBUF, M_WAITOK | M_ZERO); 2915 sm->ssdi.ssd_magic = SR_MAGIC; 2916 sm->ssdi.ssd_version = SR_META_VERSION; 2917 sm->ssd_ondisk = 0; 2918 sm->ssdi.ssd_vol_flags = 0; 2919 bcopy(&uuid, &sm->ssdi.ssd_uuid, sizeof(struct sr_uuid)); 2920 sm->ssdi.ssd_chunk_no = 1; 2921 sm->ssdi.ssd_volid = SR_HOTSPARE_VOLID; 2922 sm->ssdi.ssd_level = SR_HOTSPARE_LEVEL; 2923 sm->ssdi.ssd_size = size; 2924 strlcpy(sm->ssdi.ssd_vendor, "OPENBSD", sizeof(sm->ssdi.ssd_vendor)); 2925 snprintf(sm->ssdi.ssd_product, sizeof(sm->ssdi.ssd_product), 2926 "SR %s", "HOTSPARE"); 2927 snprintf(sm->ssdi.ssd_revision, sizeof(sm->ssdi.ssd_revision), 2928 "%03d", SR_META_VERSION); 2929 2930 sd = malloc(sizeof(struct sr_discipline), M_DEVBUF, M_WAITOK | M_ZERO); 2931 sd->sd_sc = sc; 2932 sd->sd_meta = sm; 2933 sd->sd_meta_type = SR_META_F_NATIVE; 2934 sd->sd_vol_status = BIOC_SVONLINE; 2935 strlcpy(sd->sd_name, "HOTSPARE", sizeof(sd->sd_name)); 2936 SLIST_INIT(&sd->sd_meta_opt); 2937 2938 /* Add chunk to volume. */ 2939 sd->sd_vol.sv_chunks = malloc(sizeof(struct sr_chunk *), M_DEVBUF, 2940 M_WAITOK | M_ZERO); 2941 sd->sd_vol.sv_chunks[0] = hotspare; 2942 SLIST_INIT(&sd->sd_vol.sv_chunk_list); 2943 SLIST_INSERT_HEAD(&sd->sd_vol.sv_chunk_list, hotspare, src_link); 2944 2945 /* Save metadata. */ 2946 if (sr_meta_save(sd, SR_META_DIRTY)) { 2947 sr_error(sc, "could not save metadata to %s", devname); 2948 goto fail; 2949 } 2950 2951 /* 2952 * Add chunk to hotspare list. 2953 */ 2954 rw_enter_write(&sc->sc_hs_lock); 2955 cl = &sc->sc_hotspare_list; 2956 if (SLIST_EMPTY(cl)) 2957 SLIST_INSERT_HEAD(cl, hotspare, src_link); 2958 else { 2959 SLIST_FOREACH(chunk, cl, src_link) 2960 last = chunk; 2961 SLIST_INSERT_AFTER(last, hotspare, src_link); 2962 } 2963 sc->sc_hotspare_no++; 2964 rw_exit_write(&sc->sc_hs_lock); 2965 2966 rv = 0; 2967 goto done; 2968 2969 fail: 2970 if (hotspare) 2971 free(hotspare, M_DEVBUF); 2972 2973 done: 2974 if (sd && sd->sd_vol.sv_chunks) 2975 free(sd->sd_vol.sv_chunks, M_DEVBUF); 2976 if (sd) 2977 free(sd, M_DEVBUF); 2978 if (sm) 2979 free(sm, M_DEVBUF); 2980 if (open) { 2981 VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); 2982 vput(vn); 2983 } 2984 2985 return (rv); 2986 } 2987 2988 void 2989 sr_hotspare_rebuild_callback(void *arg1, void *arg2) 2990 { 2991 sr_hotspare_rebuild((struct sr_discipline *)arg1); 2992 } 2993 2994 void 2995 sr_hotspare_rebuild(struct sr_discipline *sd) 2996 { 2997 struct sr_softc *sc = sd->sd_sc; 2998 struct sr_chunk_head *cl; 2999 struct sr_chunk *hotspare, *chunk = NULL; 3000 struct sr_workunit *wu; 3001 struct sr_ccb *ccb; 3002 int i, s, chunk_no, busy; 3003 3004 /* 3005 * Attempt to locate a hotspare and initiate rebuild. 3006 */ 3007 3008 for (i = 0; i < sd->sd_meta->ssdi.ssd_chunk_no; i++) { 3009 if (sd->sd_vol.sv_chunks[i]->src_meta.scm_status == 3010 BIOC_SDOFFLINE) { 3011 chunk_no = i; 3012 chunk = sd->sd_vol.sv_chunks[i]; 3013 break; 3014 } 3015 } 3016 3017 if (chunk == NULL) { 3018 printf("%s: no offline chunk found on %s!\n", 3019 DEVNAME(sc), sd->sd_meta->ssd_devname); 3020 return; 3021 } 3022 3023 /* See if we have a suitable hotspare... */ 3024 rw_enter_write(&sc->sc_hs_lock); 3025 cl = &sc->sc_hotspare_list; 3026 SLIST_FOREACH(hotspare, cl, src_link) 3027 if (hotspare->src_size >= chunk->src_size) 3028 break; 3029 3030 if (hotspare != NULL) { 3031 3032 printf("%s: %s volume degraded, will attempt to " 3033 "rebuild on hotspare %s\n", DEVNAME(sc), 3034 sd->sd_meta->ssd_devname, hotspare->src_devname); 3035 3036 /* 3037 * Ensure that all pending I/O completes on the failed chunk 3038 * before trying to initiate a rebuild. 3039 */ 3040 i = 0; 3041 do { 3042 busy = 0; 3043 3044 s = splbio(); 3045 TAILQ_FOREACH(wu, &sd->sd_wu_pendq, swu_link) { 3046 TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) { 3047 if (ccb->ccb_target == chunk_no) 3048 busy = 1; 3049 } 3050 } 3051 TAILQ_FOREACH(wu, &sd->sd_wu_defq, swu_link) { 3052 TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) { 3053 if (ccb->ccb_target == chunk_no) 3054 busy = 1; 3055 } 3056 } 3057 splx(s); 3058 3059 if (busy) { 3060 tsleep(sd, PRIBIO, "sr_hotspare", hz); 3061 i++; 3062 } 3063 3064 } while (busy && i < 120); 3065 3066 DNPRINTF(SR_D_META, "%s: waited %i seconds for I/O to " 3067 "complete on failed chunk %s\n", DEVNAME(sc), 3068 i, chunk->src_devname); 3069 3070 if (busy) { 3071 printf("%s: pending I/O failed to complete on " 3072 "failed chunk %s, hotspare rebuild aborted...\n", 3073 DEVNAME(sc), chunk->src_devname); 3074 goto done; 3075 } 3076 3077 s = splbio(); 3078 rw_enter_write(&sc->sc_lock); 3079 bio_status_init(&sc->sc_status, &sc->sc_dev); 3080 if (sr_rebuild_init(sd, hotspare->src_dev_mm, 1) == 0) { 3081 3082 /* Remove hotspare from available list. */ 3083 sc->sc_hotspare_no--; 3084 SLIST_REMOVE(cl, hotspare, sr_chunk, src_link); 3085 free(hotspare, M_DEVBUF); 3086 3087 } 3088 rw_exit_write(&sc->sc_lock); 3089 splx(s); 3090 } 3091 done: 3092 rw_exit_write(&sc->sc_hs_lock); 3093 } 3094 3095 int 3096 sr_rebuild_init(struct sr_discipline *sd, dev_t dev, int hotspare) 3097 { 3098 struct sr_softc *sc = sd->sd_sc; 3099 struct sr_chunk *chunk = NULL; 3100 struct sr_meta_chunk *meta; 3101 struct disklabel label; 3102 struct vnode *vn; 3103 daddr_t size, csize; 3104 char devname[32]; 3105 int rv = EINVAL, open = 0; 3106 int cid, i, part, status; 3107 3108 /* 3109 * Attempt to initiate a rebuild onto the specified device. 3110 */ 3111 3112 if (!(sd->sd_capabilities & SR_CAP_REBUILD)) { 3113 sr_error(sc, "discipline does not support rebuild"); 3114 goto done; 3115 } 3116 3117 /* make sure volume is in the right state */ 3118 if (sd->sd_vol_status == BIOC_SVREBUILD) { 3119 sr_error(sc, "rebuild already in progress"); 3120 goto done; 3121 } 3122 if (sd->sd_vol_status != BIOC_SVDEGRADED) { 3123 sr_error(sc, "volume not degraded"); 3124 goto done; 3125 } 3126 3127 /* Find first offline chunk. */ 3128 for (cid = 0; cid < sd->sd_meta->ssdi.ssd_chunk_no; cid++) { 3129 if (sd->sd_vol.sv_chunks[cid]->src_meta.scm_status == 3130 BIOC_SDOFFLINE) { 3131 chunk = sd->sd_vol.sv_chunks[cid]; 3132 break; 3133 } 3134 } 3135 if (chunk == NULL) { 3136 sr_error(sc, "no offline chunks available to rebuild"); 3137 goto done; 3138 } 3139 3140 /* Get coerced size from another online chunk. */ 3141 for (i = 0; i < sd->sd_meta->ssdi.ssd_chunk_no; i++) { 3142 if (sd->sd_vol.sv_chunks[i]->src_meta.scm_status == 3143 BIOC_SDONLINE) { 3144 meta = &sd->sd_vol.sv_chunks[i]->src_meta; 3145 csize = meta->scmi.scm_coerced_size; 3146 break; 3147 } 3148 } 3149 3150 sr_meta_getdevname(sc, dev, devname, sizeof(devname)); 3151 if (bdevvp(dev, &vn)) { 3152 printf("%s: sr_rebuild_init: can't allocate vnode\n", 3153 DEVNAME(sc)); 3154 goto done; 3155 } 3156 if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, curproc)) { 3157 DNPRINTF(SR_D_META,"%s: sr_ioctl_setstate can't " 3158 "open %s\n", DEVNAME(sc), devname); 3159 vput(vn); 3160 goto done; 3161 } 3162 open = 1; /* close dev on error */ 3163 3164 /* Get disklabel and check partition. */ 3165 part = DISKPART(dev); 3166 if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, FREAD, 3167 NOCRED, curproc)) { 3168 DNPRINTF(SR_D_META, "%s: sr_ioctl_setstate ioctl failed\n", 3169 DEVNAME(sc)); 3170 goto done; 3171 } 3172 if (label.d_secsize != DEV_BSIZE) { 3173 sr_error(sc, "%s has unsupported sector size (%u)", 3174 devname, label.d_secsize); 3175 goto done; 3176 } 3177 if (label.d_partitions[part].p_fstype != FS_RAID) { 3178 sr_error(sc, "%s partition not of type RAID (%d)", 3179 devname, label.d_partitions[part].p_fstype); 3180 goto done; 3181 } 3182 3183 /* Is the partition large enough? */ 3184 size = DL_SECTOBLK(&label, DL_GETPSIZE(&label.d_partitions[part])) - 3185 SR_DATA_OFFSET; 3186 if (size < csize) { 3187 sr_error(sc, "%s partition too small, at least %lld bytes " 3188 "required", devname, (long long)(csize << DEV_BSHIFT)); 3189 goto done; 3190 } else if (size > csize) 3191 sr_warn(sc, "%s partition too large, wasting %lld bytes", 3192 devname, (long long)((size - csize) << DEV_BSHIFT)); 3193 3194 /* Ensure that this chunk is not already in use. */ 3195 status = sr_chunk_in_use(sc, dev); 3196 if (status != BIOC_SDINVALID && status != BIOC_SDOFFLINE && 3197 !(hotspare && status == BIOC_SDHOTSPARE)) { 3198 sr_error(sc, "%s is already in use", devname); 3199 goto done; 3200 } 3201 3202 /* Reset rebuild counter since we rebuilding onto a new chunk. */ 3203 sd->sd_meta->ssd_rebuild = 0; 3204 3205 open = 0; /* leave dev open from here on out */ 3206 3207 /* Fix up chunk. */ 3208 bcopy(label.d_uid, chunk->src_duid, sizeof(chunk->src_duid)); 3209 chunk->src_dev_mm = dev; 3210 chunk->src_vn = vn; 3211 3212 /* Reconstruct metadata. */ 3213 meta = &chunk->src_meta; 3214 meta->scmi.scm_volid = sd->sd_meta->ssdi.ssd_volid; 3215 meta->scmi.scm_chunk_id = cid; 3216 strlcpy(meta->scmi.scm_devname, devname, 3217 sizeof(meta->scmi.scm_devname)); 3218 meta->scmi.scm_size = size; 3219 meta->scmi.scm_coerced_size = csize; 3220 bcopy(&sd->sd_meta->ssdi.ssd_uuid, &meta->scmi.scm_uuid, 3221 sizeof(meta->scmi.scm_uuid)); 3222 sr_checksum(sc, meta, &meta->scm_checksum, 3223 sizeof(struct sr_meta_chunk_invariant)); 3224 3225 sd->sd_set_chunk_state(sd, cid, BIOC_SDREBUILD); 3226 3227 if (sr_meta_save(sd, SR_META_DIRTY)) { 3228 sr_error(sc, "could not save metadata to %s", devname); 3229 open = 1; 3230 goto done; 3231 } 3232 3233 sr_warn(sc, "rebuild of %s started on %s", 3234 sd->sd_meta->ssd_devname, devname); 3235 3236 sd->sd_reb_abort = 0; 3237 kthread_create_deferred(sr_rebuild_start, sd); 3238 3239 rv = 0; 3240 done: 3241 if (open) { 3242 VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); 3243 vput(vn); 3244 } 3245 3246 return (rv); 3247 } 3248 3249 void 3250 sr_roam_chunks(struct sr_discipline *sd) 3251 { 3252 struct sr_softc *sc = sd->sd_sc; 3253 struct sr_chunk *chunk; 3254 struct sr_meta_chunk *meta; 3255 int roamed = 0; 3256 3257 /* Have any chunks roamed? */ 3258 SLIST_FOREACH(chunk, &sd->sd_vol.sv_chunk_list, src_link) { 3259 meta = &chunk->src_meta; 3260 if (strncmp(meta->scmi.scm_devname, chunk->src_devname, 3261 sizeof(meta->scmi.scm_devname))) { 3262 3263 printf("%s: roaming device %s -> %s\n", DEVNAME(sc), 3264 meta->scmi.scm_devname, chunk->src_devname); 3265 3266 strlcpy(meta->scmi.scm_devname, chunk->src_devname, 3267 sizeof(meta->scmi.scm_devname)); 3268 3269 roamed++; 3270 } 3271 } 3272 3273 if (roamed) 3274 sr_meta_save(sd, SR_META_DIRTY); 3275 } 3276 3277 int 3278 sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, 3279 int user, void *data) 3280 { 3281 struct sr_meta_opt_item *omi; 3282 struct sr_chunk_head *cl; 3283 struct sr_discipline *sd = NULL; 3284 struct sr_chunk *ch_entry; 3285 struct scsi_link *link; 3286 struct device *dev; 3287 char *uuid, devname[32]; 3288 dev_t *dt; 3289 int i, no_chunk, rv = EINVAL, target, vol; 3290 int no_meta; 3291 3292 DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl_createraid(%d)\n", 3293 DEVNAME(sc), user); 3294 3295 /* user input */ 3296 if (bc->bc_dev_list_len > BIOC_CRMAXLEN) 3297 goto unwind; 3298 3299 dt = malloc(bc->bc_dev_list_len, M_DEVBUF, M_WAITOK | M_ZERO); 3300 if (user) { 3301 if (copyin(bc->bc_dev_list, dt, bc->bc_dev_list_len) != 0) 3302 goto unwind; 3303 } else 3304 bcopy(bc->bc_dev_list, dt, bc->bc_dev_list_len); 3305 3306 /* Initialise discipline. */ 3307 sd = malloc(sizeof(struct sr_discipline), M_DEVBUF, M_WAITOK | M_ZERO); 3308 sd->sd_sc = sc; 3309 SLIST_INIT(&sd->sd_meta_opt); 3310 sd->sd_taskq = taskq_create("srdis", 1, IPL_BIO); 3311 if (sd->sd_taskq == NULL) { 3312 sr_error(sc, "could not create discipline taskq"); 3313 goto unwind; 3314 } 3315 if (sr_discipline_init(sd, bc->bc_level)) { 3316 sr_error(sc, "could not initialize discipline"); 3317 goto unwind; 3318 } 3319 3320 no_chunk = bc->bc_dev_list_len / sizeof(dev_t); 3321 cl = &sd->sd_vol.sv_chunk_list; 3322 SLIST_INIT(cl); 3323 3324 /* Ensure that chunks are not already in use. */ 3325 for (i = 0; i < no_chunk; i++) { 3326 if (sr_chunk_in_use(sc, dt[i]) != BIOC_SDINVALID) { 3327 sr_meta_getdevname(sc, dt[i], devname, sizeof(devname)); 3328 sr_error(sc, "chunk %s already in use", devname); 3329 goto unwind; 3330 } 3331 } 3332 3333 sd->sd_meta_type = sr_meta_probe(sd, dt, no_chunk); 3334 if (sd->sd_meta_type == SR_META_F_INVALID) { 3335 sr_error(sc, "invalid metadata format"); 3336 goto unwind; 3337 } 3338 3339 if (sr_meta_attach(sd, no_chunk, bc->bc_flags & BIOC_SCFORCE)) 3340 goto unwind; 3341 3342 /* force the raid volume by clearing metadata region */ 3343 if (bc->bc_flags & BIOC_SCFORCE) { 3344 /* make sure disk isn't up and running */ 3345 if (sr_meta_read(sd)) 3346 if (sr_already_assembled(sd)) { 3347 uuid = sr_uuid_format( 3348 &sd->sd_meta->ssdi.ssd_uuid); 3349 sr_error(sc, "disk %s is currently in use; " 3350 "cannot force create", uuid); 3351 free(uuid, M_DEVBUF); 3352 goto unwind; 3353 } 3354 3355 if (sr_meta_clear(sd)) { 3356 sr_error(sc, "failed to clear metadata"); 3357 goto unwind; 3358 } 3359 } 3360 3361 no_meta = sr_meta_read(sd); 3362 if (no_meta == -1) { 3363 3364 /* Corrupt metadata on one or more chunks. */ 3365 sr_error(sc, "one of the chunks has corrupt metadata; " 3366 "aborting assembly"); 3367 goto unwind; 3368 3369 } else if (no_meta == 0) { 3370 3371 /* Initialise volume and chunk metadata. */ 3372 sr_meta_init(sd, bc->bc_level, no_chunk); 3373 sd->sd_vol_status = BIOC_SVONLINE; 3374 sd->sd_meta_flags = bc->bc_flags & BIOC_SCNOAUTOASSEMBLE; 3375 if (sd->sd_create) { 3376 if ((i = sd->sd_create(sd, bc, no_chunk, 3377 sd->sd_vol.sv_chunk_minsz))) { 3378 rv = i; 3379 goto unwind; 3380 } 3381 } 3382 sr_meta_init_complete(sd); 3383 3384 DNPRINTF(SR_D_IOCTL, 3385 "%s: sr_ioctl_createraid: vol_size: %lld\n", 3386 DEVNAME(sc), sd->sd_meta->ssdi.ssd_size); 3387 3388 /* Warn if we've wasted chunk space due to coercing. */ 3389 if ((sd->sd_capabilities & SR_CAP_NON_COERCED) == 0 && 3390 sd->sd_vol.sv_chunk_minsz != sd->sd_vol.sv_chunk_maxsz) 3391 sr_warn(sc, "chunk sizes are not equal; up to %llu " 3392 "blocks wasted per chunk", 3393 sd->sd_vol.sv_chunk_maxsz - 3394 sd->sd_vol.sv_chunk_minsz); 3395 3396 } else { 3397 3398 /* Ensure metadata level matches requested assembly level. */ 3399 if (sd->sd_meta->ssdi.ssd_level != bc->bc_level) { 3400 sr_error(sc, "volume level does not match metadata " 3401 "level"); 3402 goto unwind; 3403 } 3404 3405 if (sr_already_assembled(sd)) { 3406 uuid = sr_uuid_format(&sd->sd_meta->ssdi.ssd_uuid); 3407 sr_error(sc, "disk %s already assembled", uuid); 3408 free(uuid, M_DEVBUF); 3409 goto unwind; 3410 } 3411 3412 if (user == 0 && sd->sd_meta_flags & BIOC_SCNOAUTOASSEMBLE) { 3413 DNPRINTF(SR_D_META, "%s: disk not auto assembled from " 3414 "metadata\n", DEVNAME(sc)); 3415 goto unwind; 3416 } 3417 3418 if (no_meta != no_chunk) 3419 sr_warn(sc, "trying to bring up %s degraded", 3420 sd->sd_meta->ssd_devname); 3421 3422 if (sd->sd_meta->ssd_meta_flags & SR_META_DIRTY) 3423 sr_warn(sc, "%s was not shutdown properly", 3424 sd->sd_meta->ssd_devname); 3425 3426 SLIST_FOREACH(omi, &sd->sd_meta_opt, omi_link) 3427 if (sd->sd_meta_opt_handler == NULL || 3428 sd->sd_meta_opt_handler(sd, omi->omi_som) != 0) 3429 sr_meta_opt_handler(sd, omi->omi_som); 3430 3431 if (sd->sd_assemble) { 3432 if ((i = sd->sd_assemble(sd, bc, no_chunk, data))) { 3433 rv = i; 3434 goto unwind; 3435 } 3436 } 3437 3438 DNPRINTF(SR_D_META, "%s: disk assembled from metadata\n", 3439 DEVNAME(sc)); 3440 3441 } 3442 3443 /* Metadata MUST be fully populated by this point. */ 3444 TAILQ_INSERT_TAIL(&sc->sc_dis_list, sd, sd_link); 3445 3446 /* Allocate all resources. */ 3447 if ((rv = sd->sd_alloc_resources(sd))) 3448 goto unwind; 3449 3450 /* Adjust flags if necessary. */ 3451 if ((sd->sd_capabilities & SR_CAP_AUTO_ASSEMBLE) && 3452 (bc->bc_flags & BIOC_SCNOAUTOASSEMBLE) != 3453 (sd->sd_meta->ssdi.ssd_vol_flags & BIOC_SCNOAUTOASSEMBLE)) { 3454 sd->sd_meta->ssdi.ssd_vol_flags &= ~BIOC_SCNOAUTOASSEMBLE; 3455 sd->sd_meta->ssdi.ssd_vol_flags |= 3456 bc->bc_flags & BIOC_SCNOAUTOASSEMBLE; 3457 } 3458 3459 if (sd->sd_capabilities & SR_CAP_SYSTEM_DISK) { 3460 3461 /* Initialise volume state. */ 3462 sd->sd_set_vol_state(sd); 3463 if (sd->sd_vol_status == BIOC_SVOFFLINE) { 3464 sr_error(sc, "%s is offline, will not be brought " 3465 "online", sd->sd_meta->ssd_devname); 3466 goto unwind; 3467 } 3468 3469 /* Setup SCSI iopool. */ 3470 scsi_iopool_init(&sd->sd_iopool, sd, sr_wu_get, sr_wu_put); 3471 3472 /* 3473 * All checks passed - return ENXIO if volume cannot be created. 3474 */ 3475 rv = ENXIO; 3476 3477 /* 3478 * Find a free target. 3479 * 3480 * XXX: We reserve sd_target == 0 to indicate the 3481 * discipline is not linked into sc->sc_targets, so begin 3482 * the search with target = 1. 3483 */ 3484 for (target = 1; target < SR_MAX_LD; target++) 3485 if (sc->sc_targets[target] == NULL) 3486 break; 3487 if (target == SR_MAX_LD) { 3488 sr_error(sc, "no free target for %s", 3489 sd->sd_meta->ssd_devname); 3490 goto unwind; 3491 } 3492 3493 /* Clear sense data. */ 3494 bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense)); 3495 3496 /* Attach discipline and get midlayer to probe it. */ 3497 sd->sd_target = target; 3498 sc->sc_targets[target] = sd; 3499 if (scsi_probe_lun(sc->sc_scsibus, target, 0) != 0) { 3500 sr_error(sc, "scsi_probe_lun failed"); 3501 sc->sc_targets[target] = NULL; 3502 sd->sd_target = 0; 3503 goto unwind; 3504 } 3505 3506 link = scsi_get_link(sc->sc_scsibus, target, 0); 3507 dev = link->device_softc; 3508 DNPRINTF(SR_D_IOCTL, "%s: sr device added: %s at target %d\n", 3509 DEVNAME(sc), dev->dv_xname, sd->sd_target); 3510 3511 /* XXX - Count volumes, not targets. */ 3512 for (i = 0, vol = -1; i <= sd->sd_target; i++) 3513 if (sc->sc_targets[i]) 3514 vol++; 3515 3516 rv = 0; 3517 3518 if (sd->sd_meta->ssd_devname[0] != '\0' && 3519 strncmp(sd->sd_meta->ssd_devname, dev->dv_xname, 3520 sizeof(dev->dv_xname))) 3521 sr_warn(sc, "volume %s is roaming, it used to be %s, " 3522 "updating metadata", dev->dv_xname, 3523 sd->sd_meta->ssd_devname); 3524 3525 /* Populate remaining volume metadata. */ 3526 sd->sd_meta->ssdi.ssd_volid = vol; 3527 strlcpy(sd->sd_meta->ssd_devname, dev->dv_xname, 3528 sizeof(sd->sd_meta->ssd_devname)); 3529 3530 sr_info(sc, "%s volume attached as %s", 3531 sd->sd_name, sd->sd_meta->ssd_devname); 3532 3533 /* Update device name on any roaming chunks. */ 3534 sr_roam_chunks(sd); 3535 3536 #ifndef SMALL_KERNEL 3537 if (sr_sensors_create(sd)) 3538 sr_warn(sc, "unable to create sensor for %s", 3539 dev->dv_xname); 3540 #endif /* SMALL_KERNEL */ 3541 } else { 3542 /* This volume does not attach as a system disk. */ 3543 ch_entry = SLIST_FIRST(cl); /* XXX */ 3544 strlcpy(sd->sd_meta->ssd_devname, ch_entry->src_devname, 3545 sizeof(sd->sd_meta->ssd_devname)); 3546 3547 if (sd->sd_start_discipline(sd)) 3548 goto unwind; 3549 } 3550 3551 /* Save current metadata to disk. */ 3552 rv = sr_meta_save(sd, SR_META_DIRTY); 3553 3554 if (sd->sd_vol_status == BIOC_SVREBUILD) 3555 kthread_create_deferred(sr_rebuild_start, sd); 3556 3557 sd->sd_ready = 1; 3558 3559 return (rv); 3560 3561 unwind: 3562 sr_discipline_shutdown(sd, 0); 3563 3564 if (rv == EAGAIN) 3565 rv = 0; 3566 3567 return (rv); 3568 } 3569 3570 int 3571 sr_ioctl_deleteraid(struct sr_softc *sc, struct bioc_deleteraid *bd) 3572 { 3573 struct sr_discipline *sd; 3574 int rv = 1; 3575 3576 DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl_deleteraid %s\n", 3577 DEVNAME(sc), bd->bd_dev); 3578 3579 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 3580 if (!strncmp(sd->sd_meta->ssd_devname, bd->bd_dev, 3581 sizeof(sd->sd_meta->ssd_devname))) 3582 break; 3583 } 3584 if (sd == NULL) { 3585 sr_error(sc, "volume %s not found", bd->bd_dev); 3586 goto bad; 3587 } 3588 3589 sd->sd_deleted = 1; 3590 sd->sd_meta->ssdi.ssd_vol_flags = BIOC_SCNOAUTOASSEMBLE; 3591 sr_discipline_shutdown(sd, 1); 3592 3593 rv = 0; 3594 bad: 3595 return (rv); 3596 } 3597 3598 int 3599 sr_ioctl_discipline(struct sr_softc *sc, struct bioc_discipline *bd) 3600 { 3601 struct sr_discipline *sd; 3602 int rv = 1; 3603 3604 /* Dispatch a discipline specific ioctl. */ 3605 3606 DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl_discipline %s\n", DEVNAME(sc), 3607 bd->bd_dev); 3608 3609 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 3610 if (!strncmp(sd->sd_meta->ssd_devname, bd->bd_dev, 3611 sizeof(sd->sd_meta->ssd_devname))) 3612 break; 3613 } 3614 if (sd == NULL) { 3615 sr_error(sc, "volume %s not found", bd->bd_dev); 3616 goto bad; 3617 } 3618 3619 if (sd->sd_ioctl_handler) 3620 rv = sd->sd_ioctl_handler(sd, bd); 3621 3622 bad: 3623 return (rv); 3624 } 3625 3626 int 3627 sr_ioctl_installboot(struct sr_softc *sc, struct bioc_installboot *bb) 3628 { 3629 void *bootblk = NULL, *bootldr = NULL; 3630 struct sr_discipline *sd; 3631 struct sr_chunk *chunk; 3632 struct sr_meta_opt_item *omi; 3633 struct sr_meta_boot *sbm; 3634 struct disk *dk; 3635 u_int32_t bbs, bls; 3636 u_char duid[8]; 3637 int rv = EINVAL; 3638 int i; 3639 3640 DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl_installboot %s\n", DEVNAME(sc), 3641 bb->bb_dev); 3642 3643 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 3644 if (!strncmp(sd->sd_meta->ssd_devname, bb->bb_dev, 3645 sizeof(sd->sd_meta->ssd_devname))) 3646 break; 3647 } 3648 if (sd == NULL) { 3649 sr_error(sc, "volume %s not found", bb->bb_dev); 3650 goto done; 3651 } 3652 3653 bzero(duid, sizeof(duid)); 3654 TAILQ_FOREACH(dk, &disklist, dk_link) 3655 if (!strncmp(dk->dk_name, bb->bb_dev, sizeof(bb->bb_dev))) 3656 break; 3657 if (dk == NULL || dk->dk_label == NULL || 3658 (dk->dk_flags & DKF_LABELVALID) == 0 || 3659 bcmp(dk->dk_label->d_uid, &duid, sizeof(duid)) == 0) { 3660 sr_error(sc, "failed to get DUID for softraid volume"); 3661 goto done; 3662 } 3663 bcopy(dk->dk_label->d_uid, duid, sizeof(duid)); 3664 3665 /* Ensure that boot storage area is large enough. */ 3666 if (sd->sd_meta->ssd_data_offset < (SR_BOOT_OFFSET + SR_BOOT_SIZE)) { 3667 sr_error(sc, "insufficient boot storage"); 3668 goto done; 3669 } 3670 3671 if (bb->bb_bootblk_size > SR_BOOT_BLOCKS_SIZE * 512) 3672 goto done; 3673 3674 if (bb->bb_bootldr_size > SR_BOOT_LOADER_SIZE * 512) 3675 goto done; 3676 3677 /* Copy in boot block. */ 3678 bbs = howmany(bb->bb_bootblk_size, DEV_BSIZE) * DEV_BSIZE; 3679 bootblk = malloc(bbs, M_DEVBUF, M_WAITOK | M_ZERO); 3680 if (copyin(bb->bb_bootblk, bootblk, bb->bb_bootblk_size) != 0) 3681 goto done; 3682 3683 /* Copy in boot loader. */ 3684 bls = howmany(bb->bb_bootldr_size, DEV_BSIZE) * DEV_BSIZE; 3685 bootldr = malloc(bls, M_DEVBUF, M_WAITOK | M_ZERO); 3686 if (copyin(bb->bb_bootldr, bootldr, bb->bb_bootldr_size) != 0) 3687 goto done; 3688 3689 /* Create or update optional meta for bootable volumes. */ 3690 SLIST_FOREACH(omi, &sd->sd_meta_opt, omi_link) 3691 if (omi->omi_som->som_type == SR_OPT_BOOT) 3692 break; 3693 if (omi == NULL) { 3694 omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF, 3695 M_WAITOK | M_ZERO); 3696 omi->omi_som = malloc(sizeof(struct sr_meta_crypto), M_DEVBUF, 3697 M_WAITOK | M_ZERO); 3698 omi->omi_som->som_type = SR_OPT_BOOT; 3699 omi->omi_som->som_length = sizeof(struct sr_meta_boot); 3700 SLIST_INSERT_HEAD(&sd->sd_meta_opt, omi, omi_link); 3701 sd->sd_meta->ssdi.ssd_opt_no++; 3702 } 3703 sbm = (struct sr_meta_boot *)omi->omi_som; 3704 3705 bcopy(duid, sbm->sbm_root_duid, sizeof(sbm->sbm_root_duid)); 3706 bzero(&sbm->sbm_boot_duid, sizeof(sbm->sbm_boot_duid)); 3707 sbm->sbm_bootblk_size = bbs; 3708 sbm->sbm_bootldr_size = bls; 3709 3710 DNPRINTF(SR_D_IOCTL, "sr_ioctl_installboot: root duid is " 3711 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx\n", 3712 sbm->sbm_root_duid[0], sbm->sbm_root_duid[1], 3713 sbm->sbm_root_duid[2], sbm->sbm_root_duid[3], 3714 sbm->sbm_root_duid[4], sbm->sbm_root_duid[5], 3715 sbm->sbm_root_duid[6], sbm->sbm_root_duid[7]); 3716 3717 /* Save boot block and boot loader to each chunk. */ 3718 for (i = 0; i < sd->sd_meta->ssdi.ssd_chunk_no; i++) { 3719 3720 chunk = sd->sd_vol.sv_chunks[i]; 3721 if (chunk->src_meta.scm_status != BIOC_SDONLINE && 3722 chunk->src_meta.scm_status != BIOC_SDREBUILD) 3723 continue; 3724 3725 if (i < SR_MAX_BOOT_DISKS) 3726 bcopy(chunk->src_duid, &sbm->sbm_boot_duid[i], 3727 sizeof(sbm->sbm_boot_duid[i])); 3728 3729 /* Save boot blocks. */ 3730 DNPRINTF(SR_D_IOCTL, 3731 "sr_ioctl_installboot: saving boot block to %s " 3732 "(%u bytes)\n", chunk->src_devname, bbs); 3733 3734 if (sr_rw(sc, chunk->src_dev_mm, bootblk, bbs, 3735 SR_BOOT_BLOCKS_OFFSET, B_WRITE)) { 3736 sr_error(sc, "failed to write boot block", DEVNAME(sc)); 3737 goto done; 3738 } 3739 3740 /* Save boot loader.*/ 3741 DNPRINTF(SR_D_IOCTL, 3742 "sr_ioctl_installboot: saving boot loader to %s " 3743 "(%u bytes)\n", chunk->src_devname, bls); 3744 3745 if (sr_rw(sc, chunk->src_dev_mm, bootldr, bls, 3746 SR_BOOT_LOADER_OFFSET, B_WRITE)) { 3747 sr_error(sc, "failed to write boot loader"); 3748 goto done; 3749 } 3750 3751 } 3752 3753 /* XXX - Install boot block on disk - MD code. */ 3754 3755 /* Mark volume as bootable and save metadata. */ 3756 sd->sd_meta->ssdi.ssd_vol_flags |= BIOC_SCBOOTABLE; 3757 if (sr_meta_save(sd, SR_META_DIRTY)) { 3758 sr_error(sc, "could not save metadata to %s", 3759 chunk->src_devname); 3760 goto done; 3761 } 3762 3763 rv = 0; 3764 3765 done: 3766 if (bootblk) 3767 free(bootblk, M_DEVBUF); 3768 if (bootldr) 3769 free(bootldr, M_DEVBUF); 3770 3771 return (rv); 3772 } 3773 3774 void 3775 sr_chunks_unwind(struct sr_softc *sc, struct sr_chunk_head *cl) 3776 { 3777 struct sr_chunk *ch_entry, *ch_next; 3778 3779 DNPRINTF(SR_D_IOCTL, "%s: sr_chunks_unwind\n", DEVNAME(sc)); 3780 3781 if (!cl) 3782 return; 3783 3784 for (ch_entry = SLIST_FIRST(cl); 3785 ch_entry != SLIST_END(cl); ch_entry = ch_next) { 3786 ch_next = SLIST_NEXT(ch_entry, src_link); 3787 3788 DNPRINTF(SR_D_IOCTL, "%s: sr_chunks_unwind closing: %s\n", 3789 DEVNAME(sc), ch_entry->src_devname); 3790 if (ch_entry->src_vn) { 3791 /* 3792 * XXX - explicitly lock the vnode until we can resolve 3793 * the problem introduced by vnode aliasing... specfs 3794 * has no locking, whereas ufs/ffs does! 3795 */ 3796 vn_lock(ch_entry->src_vn, LK_EXCLUSIVE | 3797 LK_RETRY, curproc); 3798 VOP_CLOSE(ch_entry->src_vn, FREAD | FWRITE, NOCRED, 3799 curproc); 3800 vput(ch_entry->src_vn); 3801 } 3802 free(ch_entry, M_DEVBUF); 3803 } 3804 SLIST_INIT(cl); 3805 } 3806 3807 void 3808 sr_discipline_free(struct sr_discipline *sd) 3809 { 3810 struct sr_softc *sc; 3811 struct sr_discipline *sdtmp1, *sdtmp2; 3812 struct sr_meta_opt_head *som; 3813 struct sr_meta_opt_item *omi, *omi_next; 3814 3815 if (!sd) 3816 return; 3817 3818 sc = sd->sd_sc; 3819 3820 DNPRINTF(SR_D_DIS, "%s: sr_discipline_free %s\n", 3821 DEVNAME(sc), 3822 sd->sd_meta ? sd->sd_meta->ssd_devname : "nodev"); 3823 if (sd->sd_free_resources) 3824 sd->sd_free_resources(sd); 3825 if (sd->sd_vol.sv_chunks) 3826 free(sd->sd_vol.sv_chunks, M_DEVBUF); 3827 if (sd->sd_meta) 3828 free(sd->sd_meta, M_DEVBUF); 3829 if (sd->sd_meta_foreign) 3830 free(sd->sd_meta_foreign, M_DEVBUF); 3831 3832 som = &sd->sd_meta_opt; 3833 for (omi = SLIST_FIRST(som); omi != SLIST_END(som); omi = omi_next) { 3834 omi_next = SLIST_NEXT(omi, omi_link); 3835 if (omi->omi_som) 3836 free(omi->omi_som, M_DEVBUF); 3837 free(omi, M_DEVBUF); 3838 } 3839 3840 if (sd->sd_target != 0) { 3841 KASSERT(sc->sc_targets[sd->sd_target] == sd); 3842 sc->sc_targets[sd->sd_target] = NULL; 3843 } 3844 3845 TAILQ_FOREACH_SAFE(sdtmp1, &sc->sc_dis_list, sd_link, sdtmp2) { 3846 if (sdtmp1 == sd) { 3847 TAILQ_REMOVE(&sc->sc_dis_list, sd, sd_link); 3848 break; 3849 } 3850 } 3851 3852 explicit_bzero(sd, sizeof *sd); 3853 free(sd, M_DEVBUF); 3854 } 3855 3856 void 3857 sr_discipline_shutdown(struct sr_discipline *sd, int meta_save) 3858 { 3859 struct sr_softc *sc; 3860 int s; 3861 3862 if (!sd) 3863 return; 3864 sc = sd->sd_sc; 3865 3866 DNPRINTF(SR_D_DIS, "%s: sr_discipline_shutdown %s\n", DEVNAME(sc), 3867 sd->sd_meta ? sd->sd_meta->ssd_devname : "nodev"); 3868 3869 /* If rebuilding, abort rebuild and drain I/O. */ 3870 if (sd->sd_reb_active) { 3871 sd->sd_reb_abort = 1; 3872 while (sd->sd_reb_active) 3873 tsleep(sd, PWAIT, "sr_shutdown", 1); 3874 } 3875 3876 if (meta_save) 3877 sr_meta_save(sd, 0); 3878 3879 s = splbio(); 3880 3881 sd->sd_ready = 0; 3882 3883 /* make sure there isn't a sync pending and yield */ 3884 wakeup(sd); 3885 while (sd->sd_sync || sd->sd_must_flush) 3886 if (tsleep(&sd->sd_sync, MAXPRI, "sr_down", 60 * hz) == 3887 EWOULDBLOCK) 3888 break; 3889 3890 #ifndef SMALL_KERNEL 3891 sr_sensors_delete(sd); 3892 #endif /* SMALL_KERNEL */ 3893 3894 if (sd->sd_target != 0) 3895 scsi_detach_lun(sc->sc_scsibus, sd->sd_target, 0, DETACH_FORCE); 3896 3897 sr_chunks_unwind(sc, &sd->sd_vol.sv_chunk_list); 3898 3899 if (sd->sd_taskq) 3900 taskq_destroy(sd->sd_taskq); 3901 3902 sr_discipline_free(sd); 3903 3904 splx(s); 3905 } 3906 3907 int 3908 sr_discipline_init(struct sr_discipline *sd, int level) 3909 { 3910 int rv = 1; 3911 3912 /* Initialise discipline function pointers with defaults. */ 3913 sd->sd_alloc_resources = sr_alloc_resources; 3914 sd->sd_assemble = NULL; 3915 sd->sd_create = NULL; 3916 sd->sd_free_resources = sr_free_resources; 3917 sd->sd_ioctl_handler = NULL; 3918 sd->sd_openings = NULL; 3919 sd->sd_meta_opt_handler = NULL; 3920 sd->sd_rebuild = sr_rebuild; 3921 sd->sd_scsi_inquiry = sr_raid_inquiry; 3922 sd->sd_scsi_read_cap = sr_raid_read_cap; 3923 sd->sd_scsi_tur = sr_raid_tur; 3924 sd->sd_scsi_req_sense = sr_raid_request_sense; 3925 sd->sd_scsi_start_stop = sr_raid_start_stop; 3926 sd->sd_scsi_sync = sr_raid_sync; 3927 sd->sd_scsi_rw = NULL; 3928 sd->sd_scsi_intr = sr_raid_intr; 3929 sd->sd_scsi_wu_done = NULL; 3930 sd->sd_scsi_done = NULL; 3931 sd->sd_set_chunk_state = sr_set_chunk_state; 3932 sd->sd_set_vol_state = sr_set_vol_state; 3933 sd->sd_start_discipline = NULL; 3934 3935 task_set(&sd->sd_meta_save_task, sr_meta_save_callback, sd, NULL); 3936 3937 switch (level) { 3938 case 0: 3939 sr_raid0_discipline_init(sd); 3940 break; 3941 case 1: 3942 sr_raid1_discipline_init(sd); 3943 break; 3944 case 5: 3945 sr_raid5_discipline_init(sd); 3946 break; 3947 case 6: 3948 sr_raid6_discipline_init(sd); 3949 break; 3950 #ifdef AOE 3951 /* AOE target. */ 3952 case 'A': 3953 sr_aoe_server_discipline_init(sd); 3954 break; 3955 /* AOE initiator. */ 3956 case 'a': 3957 sr_aoe_discipline_init(sd); 3958 break; 3959 #endif 3960 #ifdef CRYPTO 3961 case 'C': 3962 sr_crypto_discipline_init(sd); 3963 break; 3964 #endif 3965 case 'c': 3966 sr_concat_discipline_init(sd); 3967 break; 3968 default: 3969 goto bad; 3970 } 3971 3972 rv = 0; 3973 bad: 3974 return (rv); 3975 } 3976 3977 int 3978 sr_raid_inquiry(struct sr_workunit *wu) 3979 { 3980 struct sr_discipline *sd = wu->swu_dis; 3981 struct scsi_xfer *xs = wu->swu_xs; 3982 struct scsi_inquiry *cdb = (struct scsi_inquiry *)xs->cmd; 3983 struct scsi_inquiry_data inq; 3984 3985 DNPRINTF(SR_D_DIS, "%s: sr_raid_inquiry\n", DEVNAME(sd->sd_sc)); 3986 3987 if (xs->cmdlen != sizeof(*cdb)) 3988 return (EINVAL); 3989 3990 if (ISSET(cdb->flags, SI_EVPD)) 3991 return (EOPNOTSUPP); 3992 3993 bzero(&inq, sizeof(inq)); 3994 inq.device = T_DIRECT; 3995 inq.dev_qual2 = 0; 3996 inq.version = 2; 3997 inq.response_format = 2; 3998 inq.additional_length = 32; 3999 inq.flags |= SID_CmdQue; 4000 strlcpy(inq.vendor, sd->sd_meta->ssdi.ssd_vendor, 4001 sizeof(inq.vendor)); 4002 strlcpy(inq.product, sd->sd_meta->ssdi.ssd_product, 4003 sizeof(inq.product)); 4004 strlcpy(inq.revision, sd->sd_meta->ssdi.ssd_revision, 4005 sizeof(inq.revision)); 4006 sr_copy_internal_data(xs, &inq, sizeof(inq)); 4007 4008 return (0); 4009 } 4010 4011 int 4012 sr_raid_read_cap(struct sr_workunit *wu) 4013 { 4014 struct sr_discipline *sd = wu->swu_dis; 4015 struct scsi_xfer *xs = wu->swu_xs; 4016 struct scsi_read_cap_data rcd; 4017 struct scsi_read_cap_data_16 rcd16; 4018 daddr_t addr; 4019 int rv = 1; 4020 4021 DNPRINTF(SR_D_DIS, "%s: sr_raid_read_cap\n", DEVNAME(sd->sd_sc)); 4022 4023 addr = sd->sd_meta->ssdi.ssd_size - 1; 4024 if (xs->cmd->opcode == READ_CAPACITY) { 4025 bzero(&rcd, sizeof(rcd)); 4026 if (addr > 0xffffffffllu) 4027 _lto4b(0xffffffff, rcd.addr); 4028 else 4029 _lto4b(addr, rcd.addr); 4030 _lto4b(512, rcd.length); 4031 sr_copy_internal_data(xs, &rcd, sizeof(rcd)); 4032 rv = 0; 4033 } else if (xs->cmd->opcode == READ_CAPACITY_16) { 4034 bzero(&rcd16, sizeof(rcd16)); 4035 _lto8b(addr, rcd16.addr); 4036 _lto4b(512, rcd16.length); 4037 sr_copy_internal_data(xs, &rcd16, sizeof(rcd16)); 4038 rv = 0; 4039 } 4040 4041 return (rv); 4042 } 4043 4044 int 4045 sr_raid_tur(struct sr_workunit *wu) 4046 { 4047 struct sr_discipline *sd = wu->swu_dis; 4048 4049 DNPRINTF(SR_D_DIS, "%s: sr_raid_tur\n", DEVNAME(sd->sd_sc)); 4050 4051 if (sd->sd_vol_status == BIOC_SVOFFLINE) { 4052 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT; 4053 sd->sd_scsi_sense.flags = SKEY_NOT_READY; 4054 sd->sd_scsi_sense.add_sense_code = 0x04; 4055 sd->sd_scsi_sense.add_sense_code_qual = 0x11; 4056 sd->sd_scsi_sense.extra_len = 4; 4057 return (1); 4058 } else if (sd->sd_vol_status == BIOC_SVINVALID) { 4059 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT; 4060 sd->sd_scsi_sense.flags = SKEY_HARDWARE_ERROR; 4061 sd->sd_scsi_sense.add_sense_code = 0x05; 4062 sd->sd_scsi_sense.add_sense_code_qual = 0x00; 4063 sd->sd_scsi_sense.extra_len = 4; 4064 return (1); 4065 } 4066 4067 return (0); 4068 } 4069 4070 int 4071 sr_raid_request_sense(struct sr_workunit *wu) 4072 { 4073 struct sr_discipline *sd = wu->swu_dis; 4074 struct scsi_xfer *xs = wu->swu_xs; 4075 4076 DNPRINTF(SR_D_DIS, "%s: sr_raid_request_sense\n", 4077 DEVNAME(sd->sd_sc)); 4078 4079 /* use latest sense data */ 4080 bcopy(&sd->sd_scsi_sense, &xs->sense, sizeof(xs->sense)); 4081 4082 /* clear sense data */ 4083 bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense)); 4084 4085 return (0); 4086 } 4087 4088 int 4089 sr_raid_start_stop(struct sr_workunit *wu) 4090 { 4091 struct scsi_xfer *xs = wu->swu_xs; 4092 struct scsi_start_stop *ss = (struct scsi_start_stop *)xs->cmd; 4093 4094 DNPRINTF(SR_D_DIS, "%s: sr_raid_start_stop\n", 4095 DEVNAME(wu->swu_dis->sd_sc)); 4096 4097 if (!ss) 4098 return (1); 4099 4100 /* 4101 * do nothing! 4102 * a softraid discipline should always reflect correct status 4103 */ 4104 return (0); 4105 } 4106 4107 int 4108 sr_raid_sync(struct sr_workunit *wu) 4109 { 4110 struct sr_discipline *sd = wu->swu_dis; 4111 int s, rv = 0, ios; 4112 4113 DNPRINTF(SR_D_DIS, "%s: sr_raid_sync\n", DEVNAME(sd->sd_sc)); 4114 4115 /* when doing a fake sync don't count the wu */ 4116 ios = (wu->swu_flags & SR_WUF_FAKE) ? 0 : 1; 4117 4118 s = splbio(); 4119 sd->sd_sync = 1; 4120 while (sd->sd_wu_pending > ios) { 4121 if (tsleep(sd, PRIBIO, "sr_sync", 15 * hz) == EWOULDBLOCK) { 4122 DNPRINTF(SR_D_DIS, "%s: sr_raid_sync timeout\n", 4123 DEVNAME(sd->sd_sc)); 4124 rv = 1; 4125 break; 4126 } 4127 } 4128 sd->sd_sync = 0; 4129 splx(s); 4130 4131 wakeup(&sd->sd_sync); 4132 4133 return (rv); 4134 } 4135 4136 void 4137 sr_raid_intr(struct buf *bp) 4138 { 4139 struct sr_ccb *ccb = (struct sr_ccb *)bp; 4140 struct sr_workunit *wu = ccb->ccb_wu; 4141 #ifdef SR_DEBUG 4142 struct sr_discipline *sd = wu->swu_dis; 4143 struct scsi_xfer *xs = wu->swu_xs; 4144 #endif 4145 int s; 4146 4147 DNPRINTF(SR_D_INTR, "%s: %s %s intr bp %p xs %p\n", 4148 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, sd->sd_name, bp, xs); 4149 4150 s = splbio(); 4151 sr_ccb_done(ccb); 4152 sr_wu_done(wu); 4153 splx(s); 4154 } 4155 4156 void 4157 sr_schedule_wu(struct sr_workunit *wu) 4158 { 4159 struct sr_discipline *sd = wu->swu_dis; 4160 struct sr_workunit *wup; 4161 int s; 4162 4163 DNPRINTF(SR_D_WU, "sr_schedule_wu: schedule wu %p state %i " 4164 "flags 0x%x\n", wu, wu->swu_state, wu->swu_flags); 4165 4166 KASSERT(wu->swu_io_count > 0); 4167 4168 s = splbio(); 4169 4170 /* Construct the work unit, do not schedule it. */ 4171 if (wu->swu_state == SR_WU_CONSTRUCT) 4172 goto queued; 4173 4174 /* Deferred work unit being reconstructed, do not start. */ 4175 if (wu->swu_state == SR_WU_REQUEUE) 4176 goto queued; 4177 4178 /* Current work unit failed, restart. */ 4179 if (wu->swu_state == SR_WU_RESTART) 4180 goto start; 4181 4182 if (wu->swu_state != SR_WU_INPROGRESS) 4183 panic("sr_schedule_wu: work unit not in progress (state %i)\n", 4184 wu->swu_state); 4185 4186 /* Walk queue backwards and fill in collider if we have one. */ 4187 TAILQ_FOREACH_REVERSE(wup, &sd->sd_wu_pendq, sr_wu_list, swu_link) { 4188 if (wu->swu_blk_end < wup->swu_blk_start || 4189 wup->swu_blk_end < wu->swu_blk_start) 4190 continue; 4191 4192 /* Defer work unit due to LBA collision. */ 4193 DNPRINTF(SR_D_WU, "sr_schedule_wu: deferring work unit %p\n", 4194 wu); 4195 wu->swu_state = SR_WU_DEFERRED; 4196 while (wup->swu_collider) 4197 wup = wup->swu_collider; 4198 wup->swu_collider = wu; 4199 TAILQ_INSERT_TAIL(&sd->sd_wu_defq, wu, swu_link); 4200 sd->sd_wu_collisions++; 4201 goto queued; 4202 } 4203 4204 start: 4205 sr_raid_startwu(wu); 4206 4207 queued: 4208 splx(s); 4209 } 4210 4211 void 4212 sr_raid_startwu(struct sr_workunit *wu) 4213 { 4214 struct sr_discipline *sd = wu->swu_dis; 4215 struct sr_ccb *ccb; 4216 4217 DNPRINTF(SR_D_WU, "sr_raid_startwu: start wu %p\n", wu); 4218 4219 splassert(IPL_BIO); 4220 4221 if (wu->swu_state == SR_WU_DEFERRED) { 4222 TAILQ_REMOVE(&sd->sd_wu_defq, wu, swu_link); 4223 wu->swu_state = SR_WU_INPROGRESS; 4224 } 4225 4226 if (wu->swu_state != SR_WU_RESTART) 4227 TAILQ_INSERT_TAIL(&sd->sd_wu_pendq, wu, swu_link); 4228 4229 /* Start all of the individual I/Os. */ 4230 if (wu->swu_cb_active == 1) 4231 panic("%s: sr_startwu_callback", DEVNAME(sd->sd_sc)); 4232 wu->swu_cb_active = 1; 4233 4234 TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) 4235 VOP_STRATEGY(&ccb->ccb_buf); 4236 4237 wu->swu_cb_active = 0; 4238 } 4239 4240 void 4241 sr_raid_recreate_wu(struct sr_workunit *wu) 4242 { 4243 struct sr_discipline *sd = wu->swu_dis; 4244 struct sr_workunit *wup = wu; 4245 4246 /* 4247 * Recreate a work unit by releasing the associated CCBs and reissuing 4248 * the SCSI I/O request. This process is then repeated for all of the 4249 * colliding work units. 4250 */ 4251 do { 4252 sr_wu_release_ccbs(wup); 4253 4254 wup->swu_state = SR_WU_REQUEUE; 4255 if (sd->sd_scsi_rw(wup)) 4256 panic("could not requeue I/O"); 4257 4258 wup = wup->swu_collider; 4259 } while (wup); 4260 } 4261 4262 int 4263 sr_alloc_resources(struct sr_discipline *sd) 4264 { 4265 if (sr_wu_alloc(sd, sizeof(struct sr_workunit))) { 4266 sr_error(sd->sd_sc, "unable to allocate work units"); 4267 return (ENOMEM); 4268 } 4269 if (sr_ccb_alloc(sd)) { 4270 sr_error(sd->sd_sc, "unable to allocate ccbs"); 4271 return (ENOMEM); 4272 } 4273 4274 return (0); 4275 } 4276 4277 void 4278 sr_free_resources(struct sr_discipline *sd) 4279 { 4280 sr_wu_free(sd); 4281 sr_ccb_free(sd); 4282 } 4283 4284 void 4285 sr_set_chunk_state(struct sr_discipline *sd, int c, int new_state) 4286 { 4287 int old_state, s; 4288 4289 DNPRINTF(SR_D_STATE, "%s: %s: %s: sr_set_chunk_state %d -> %d\n", 4290 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, 4291 sd->sd_vol.sv_chunks[c]->src_meta.scmi.scm_devname, c, new_state); 4292 4293 /* ok to go to splbio since this only happens in error path */ 4294 s = splbio(); 4295 old_state = sd->sd_vol.sv_chunks[c]->src_meta.scm_status; 4296 4297 /* multiple IOs to the same chunk that fail will come through here */ 4298 if (old_state == new_state) 4299 goto done; 4300 4301 switch (old_state) { 4302 case BIOC_SDONLINE: 4303 if (new_state == BIOC_SDOFFLINE) 4304 break; 4305 else 4306 goto die; 4307 break; 4308 4309 case BIOC_SDOFFLINE: 4310 goto die; 4311 4312 default: 4313 die: 4314 splx(s); /* XXX */ 4315 panic("%s: %s: %s: invalid chunk state transition " 4316 "%d -> %d\n", DEVNAME(sd->sd_sc), 4317 sd->sd_meta->ssd_devname, 4318 sd->sd_vol.sv_chunks[c]->src_meta.scmi.scm_devname, 4319 old_state, new_state); 4320 /* NOTREACHED */ 4321 } 4322 4323 sd->sd_vol.sv_chunks[c]->src_meta.scm_status = new_state; 4324 sd->sd_set_vol_state(sd); 4325 4326 sd->sd_must_flush = 1; 4327 task_add(systq, &sd->sd_meta_save_task); 4328 done: 4329 splx(s); 4330 } 4331 4332 void 4333 sr_set_vol_state(struct sr_discipline *sd) 4334 { 4335 int states[SR_MAX_STATES]; 4336 int new_state, i, s, nd; 4337 int old_state = sd->sd_vol_status; 4338 4339 DNPRINTF(SR_D_STATE, "%s: %s: sr_set_vol_state\n", 4340 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname); 4341 4342 nd = sd->sd_meta->ssdi.ssd_chunk_no; 4343 4344 for (i = 0; i < SR_MAX_STATES; i++) 4345 states[i] = 0; 4346 4347 for (i = 0; i < nd; i++) { 4348 s = sd->sd_vol.sv_chunks[i]->src_meta.scm_status; 4349 if (s >= SR_MAX_STATES) 4350 panic("%s: %s: %s: invalid chunk state", 4351 DEVNAME(sd->sd_sc), 4352 sd->sd_meta->ssd_devname, 4353 sd->sd_vol.sv_chunks[i]->src_meta.scmi.scm_devname); 4354 states[s]++; 4355 } 4356 4357 if (states[BIOC_SDONLINE] == nd) 4358 new_state = BIOC_SVONLINE; 4359 else 4360 new_state = BIOC_SVOFFLINE; 4361 4362 DNPRINTF(SR_D_STATE, "%s: %s: sr_set_vol_state %d -> %d\n", 4363 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, 4364 old_state, new_state); 4365 4366 switch (old_state) { 4367 case BIOC_SVONLINE: 4368 if (new_state == BIOC_SVOFFLINE || new_state == BIOC_SVONLINE) 4369 break; 4370 else 4371 goto die; 4372 break; 4373 4374 case BIOC_SVOFFLINE: 4375 /* XXX this might be a little too much */ 4376 goto die; 4377 4378 default: 4379 die: 4380 panic("%s: %s: invalid volume state transition " 4381 "%d -> %d\n", DEVNAME(sd->sd_sc), 4382 sd->sd_meta->ssd_devname, 4383 old_state, new_state); 4384 /* NOTREACHED */ 4385 } 4386 4387 sd->sd_vol_status = new_state; 4388 } 4389 4390 void * 4391 sr_block_get(struct sr_discipline *sd, int length) 4392 { 4393 return dma_alloc(length, PR_NOWAIT | PR_ZERO); 4394 } 4395 4396 void 4397 sr_block_put(struct sr_discipline *sd, void *ptr, int length) 4398 { 4399 dma_free(ptr, length); 4400 } 4401 4402 void 4403 sr_checksum_print(u_int8_t *md5) 4404 { 4405 int i; 4406 4407 for (i = 0; i < MD5_DIGEST_LENGTH; i++) 4408 printf("%02x", md5[i]); 4409 } 4410 4411 void 4412 sr_checksum(struct sr_softc *sc, void *src, void *md5, u_int32_t len) 4413 { 4414 MD5_CTX ctx; 4415 4416 DNPRINTF(SR_D_MISC, "%s: sr_checksum(%p %p %d)\n", DEVNAME(sc), src, 4417 md5, len); 4418 4419 MD5Init(&ctx); 4420 MD5Update(&ctx, src, len); 4421 MD5Final(md5, &ctx); 4422 } 4423 4424 void 4425 sr_uuid_generate(struct sr_uuid *uuid) 4426 { 4427 arc4random_buf(uuid->sui_id, sizeof(uuid->sui_id)); 4428 /* UUID version 4: random */ 4429 uuid->sui_id[6] &= 0x0f; 4430 uuid->sui_id[6] |= 0x40; 4431 /* RFC4122 variant */ 4432 uuid->sui_id[8] &= 0x3f; 4433 uuid->sui_id[8] |= 0x80; 4434 } 4435 4436 char * 4437 sr_uuid_format(struct sr_uuid *uuid) 4438 { 4439 char *uuidstr; 4440 4441 uuidstr = malloc(37, M_DEVBUF, M_WAITOK); 4442 4443 snprintf(uuidstr, 37, 4444 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" 4445 "%02x%02x%02x%02x%02x%02x", 4446 uuid->sui_id[0], uuid->sui_id[1], 4447 uuid->sui_id[2], uuid->sui_id[3], 4448 uuid->sui_id[4], uuid->sui_id[5], 4449 uuid->sui_id[6], uuid->sui_id[7], 4450 uuid->sui_id[8], uuid->sui_id[9], 4451 uuid->sui_id[10], uuid->sui_id[11], 4452 uuid->sui_id[12], uuid->sui_id[13], 4453 uuid->sui_id[14], uuid->sui_id[15]); 4454 4455 return uuidstr; 4456 } 4457 4458 void 4459 sr_uuid_print(struct sr_uuid *uuid, int cr) 4460 { 4461 char *uuidstr; 4462 4463 uuidstr = sr_uuid_format(uuid); 4464 printf("%s%s", uuidstr, (cr ? "\n" : "")); 4465 free(uuidstr, M_DEVBUF); 4466 } 4467 4468 int 4469 sr_already_assembled(struct sr_discipline *sd) 4470 { 4471 struct sr_softc *sc = sd->sd_sc; 4472 struct sr_discipline *sdtmp; 4473 4474 TAILQ_FOREACH(sdtmp, &sc->sc_dis_list, sd_link) { 4475 if (!bcmp(&sd->sd_meta->ssdi.ssd_uuid, 4476 &sdtmp->sd_meta->ssdi.ssd_uuid, 4477 sizeof(sd->sd_meta->ssdi.ssd_uuid))) 4478 return (1); 4479 } 4480 4481 return (0); 4482 } 4483 4484 int32_t 4485 sr_validate_stripsize(u_int32_t b) 4486 { 4487 int s = 0; 4488 4489 if (b % 512) 4490 return (-1); 4491 4492 while ((b & 1) == 0) { 4493 b >>= 1; 4494 s++; 4495 } 4496 4497 /* only multiple of twos */ 4498 b >>= 1; 4499 if (b) 4500 return(-1); 4501 4502 return (s); 4503 } 4504 4505 void 4506 sr_shutdownhook(void *arg) 4507 { 4508 sr_shutdown((struct sr_softc *)arg); 4509 } 4510 4511 void 4512 sr_shutdown(struct sr_softc *sc) 4513 { 4514 struct sr_discipline *sd; 4515 4516 DNPRINTF(SR_D_MISC, "%s: sr_shutdown\n", DEVNAME(sc)); 4517 4518 /* Shutdown disciplines in reverse attach order. */ 4519 while ((sd = TAILQ_LAST(&sc->sc_dis_list, sr_discipline_list)) != NULL) 4520 sr_discipline_shutdown(sd, 1); 4521 } 4522 4523 int 4524 sr_validate_io(struct sr_workunit *wu, daddr_t *blk, char *func) 4525 { 4526 struct sr_discipline *sd = wu->swu_dis; 4527 struct scsi_xfer *xs = wu->swu_xs; 4528 int rv = 1; 4529 4530 DNPRINTF(SR_D_DIS, "%s: %s 0x%02x\n", DEVNAME(sd->sd_sc), func, 4531 xs->cmd->opcode); 4532 4533 if (sd->sd_meta->ssd_data_offset == 0) 4534 panic("invalid data offset"); 4535 4536 if (sd->sd_vol_status == BIOC_SVOFFLINE) { 4537 DNPRINTF(SR_D_DIS, "%s: %s device offline\n", 4538 DEVNAME(sd->sd_sc), func); 4539 goto bad; 4540 } 4541 4542 if (xs->datalen == 0) { 4543 printf("%s: %s: illegal block count for %s\n", 4544 DEVNAME(sd->sd_sc), func, sd->sd_meta->ssd_devname); 4545 goto bad; 4546 } 4547 4548 if (xs->cmdlen == 10) 4549 *blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr); 4550 else if (xs->cmdlen == 16) 4551 *blk = _8btol(((struct scsi_rw_16 *)xs->cmd)->addr); 4552 else if (xs->cmdlen == 6) 4553 *blk = _3btol(((struct scsi_rw *)xs->cmd)->addr); 4554 else { 4555 printf("%s: %s: illegal cmdlen for %s\n", 4556 DEVNAME(sd->sd_sc), func, sd->sd_meta->ssd_devname); 4557 goto bad; 4558 } 4559 4560 wu->swu_blk_start = *blk; 4561 wu->swu_blk_end = *blk + (xs->datalen >> DEV_BSHIFT) - 1; 4562 4563 if (wu->swu_blk_end > sd->sd_meta->ssdi.ssd_size) { 4564 DNPRINTF(SR_D_DIS, "%s: %s out of bounds start: %lld " 4565 "end: %lld length: %d\n", 4566 DEVNAME(sd->sd_sc), func, (long long)wu->swu_blk_start, 4567 (long long)wu->swu_blk_end, xs->datalen); 4568 4569 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT | 4570 SSD_ERRCODE_VALID; 4571 sd->sd_scsi_sense.flags = SKEY_ILLEGAL_REQUEST; 4572 sd->sd_scsi_sense.add_sense_code = 0x21; 4573 sd->sd_scsi_sense.add_sense_code_qual = 0x00; 4574 sd->sd_scsi_sense.extra_len = 4; 4575 goto bad; 4576 } 4577 4578 rv = 0; 4579 bad: 4580 return (rv); 4581 } 4582 4583 void 4584 sr_rebuild_start(void *arg) 4585 { 4586 struct sr_discipline *sd = arg; 4587 struct sr_softc *sc = sd->sd_sc; 4588 4589 DNPRINTF(SR_D_REBUILD, "%s: %s starting rebuild thread\n", 4590 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname); 4591 4592 if (kthread_create(sr_rebuild_thread, sd, &sd->sd_background_proc, 4593 DEVNAME(sc)) != 0) 4594 printf("%s: unable to start background operation\n", 4595 DEVNAME(sc)); 4596 } 4597 4598 void 4599 sr_rebuild_thread(void *arg) 4600 { 4601 struct sr_discipline *sd = arg; 4602 4603 DNPRINTF(SR_D_REBUILD, "%s: %s rebuild thread started\n", 4604 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname); 4605 4606 sd->sd_reb_active = 1; 4607 sd->sd_rebuild(sd); 4608 sd->sd_reb_active = 0; 4609 4610 kthread_exit(0); 4611 } 4612 4613 void 4614 sr_rebuild(struct sr_discipline *sd) 4615 { 4616 struct sr_softc *sc = sd->sd_sc; 4617 daddr_t whole_blk, partial_blk, blk, sz, lba; 4618 daddr_t psz, rb, restart; 4619 struct sr_workunit *wu_r, *wu_w; 4620 struct scsi_xfer xs_r, xs_w; 4621 struct scsi_rw_16 *cr, *cw; 4622 int c, s, slept, percent = 0, old_percent = -1; 4623 u_int8_t *buf; 4624 4625 whole_blk = sd->sd_meta->ssdi.ssd_size / SR_REBUILD_IO_SIZE; 4626 partial_blk = sd->sd_meta->ssdi.ssd_size % SR_REBUILD_IO_SIZE; 4627 4628 restart = sd->sd_meta->ssd_rebuild / SR_REBUILD_IO_SIZE; 4629 if (restart > whole_blk) { 4630 printf("%s: bogus rebuild restart offset, starting from 0\n", 4631 DEVNAME(sc)); 4632 restart = 0; 4633 } 4634 if (restart) { 4635 /* 4636 * XXX there is a hole here; there is a posibility that we 4637 * had a restart however the chunk that was supposed to 4638 * be rebuilt is no longer valid; we can reach this situation 4639 * when a rebuild is in progress and the box crashes and 4640 * on reboot the rebuild chunk is different (like zero'd or 4641 * replaced). We need to check the uuid of the chunk that is 4642 * being rebuilt to assert this. 4643 */ 4644 psz = sd->sd_meta->ssdi.ssd_size; 4645 rb = sd->sd_meta->ssd_rebuild; 4646 if (rb > 0) 4647 percent = 100 - ((psz * 100 - rb * 100) / psz) - 1; 4648 else 4649 percent = 0; 4650 printf("%s: resuming rebuild on %s at %d%%\n", 4651 DEVNAME(sc), sd->sd_meta->ssd_devname, percent); 4652 } 4653 4654 /* currently this is 64k therefore we can use dma_alloc */ 4655 buf = dma_alloc(SR_REBUILD_IO_SIZE << DEV_BSHIFT, PR_WAITOK); 4656 for (blk = restart; blk <= whole_blk; blk++) { 4657 lba = blk * SR_REBUILD_IO_SIZE; 4658 sz = SR_REBUILD_IO_SIZE; 4659 if (blk == whole_blk) { 4660 if (partial_blk == 0) 4661 break; 4662 sz = partial_blk; 4663 } 4664 4665 /* get some wu */ 4666 wu_r = sr_scsi_wu_get(sd, 0); 4667 wu_w = sr_scsi_wu_get(sd, 0); 4668 4669 DNPRINTF(SR_D_REBUILD, "%s: %s rebuild wu_r %p, wu_w %p\n", 4670 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, wu_r, wu_w); 4671 4672 /* setup read io */ 4673 bzero(&xs_r, sizeof xs_r); 4674 xs_r.error = XS_NOERROR; 4675 xs_r.flags = SCSI_DATA_IN; 4676 xs_r.datalen = sz << DEV_BSHIFT; 4677 xs_r.data = buf; 4678 xs_r.cmdlen = sizeof(*cr); 4679 xs_r.cmd = &xs_r.cmdstore; 4680 cr = (struct scsi_rw_16 *)xs_r.cmd; 4681 cr->opcode = READ_16; 4682 _lto4b(sz, cr->length); 4683 _lto8b(lba, cr->addr); 4684 wu_r->swu_state = SR_WU_CONSTRUCT; 4685 wu_r->swu_flags |= SR_WUF_REBUILD; 4686 wu_r->swu_xs = &xs_r; 4687 if (sd->sd_scsi_rw(wu_r)) { 4688 printf("%s: could not create read io\n", 4689 DEVNAME(sc)); 4690 goto fail; 4691 } 4692 4693 /* setup write io */ 4694 bzero(&xs_w, sizeof xs_w); 4695 xs_w.error = XS_NOERROR; 4696 xs_w.flags = SCSI_DATA_OUT; 4697 xs_w.datalen = sz << DEV_BSHIFT; 4698 xs_w.data = buf; 4699 xs_w.cmdlen = sizeof(*cw); 4700 xs_w.cmd = &xs_w.cmdstore; 4701 cw = (struct scsi_rw_16 *)xs_w.cmd; 4702 cw->opcode = WRITE_16; 4703 _lto4b(sz, cw->length); 4704 _lto8b(lba, cw->addr); 4705 wu_w->swu_state = SR_WU_CONSTRUCT; 4706 wu_w->swu_flags |= SR_WUF_REBUILD | SR_WUF_WAKEUP; 4707 wu_w->swu_xs = &xs_w; 4708 if (sd->sd_scsi_rw(wu_w)) { 4709 printf("%s: could not create write io\n", 4710 DEVNAME(sc)); 4711 goto fail; 4712 } 4713 4714 /* 4715 * collide with the read io so that we get automatically 4716 * started when the read is done 4717 */ 4718 wu_w->swu_state = SR_WU_DEFERRED; 4719 wu_r->swu_collider = wu_w; 4720 s = splbio(); 4721 TAILQ_INSERT_TAIL(&sd->sd_wu_defq, wu_w, swu_link); 4722 splx(s); 4723 4724 DNPRINTF(SR_D_REBUILD, "%s: %s rebuild scheduling wu_r %p\n", 4725 DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, wu_r); 4726 4727 wu_r->swu_state = SR_WU_INPROGRESS; 4728 sr_schedule_wu(wu_r); 4729 4730 /* wait for write completion */ 4731 slept = 0; 4732 while ((wu_w->swu_flags & SR_WUF_REBUILDIOCOMP) == 0) { 4733 tsleep(wu_w, PRIBIO, "sr_rebuild", 0); 4734 slept = 1; 4735 } 4736 /* yield if we didn't sleep */ 4737 if (slept == 0) 4738 tsleep(sc, PWAIT, "sr_yield", 1); 4739 4740 sr_scsi_wu_put(sd, wu_r); 4741 sr_scsi_wu_put(sd, wu_w); 4742 4743 sd->sd_meta->ssd_rebuild = lba; 4744 4745 /* XXX - this should be based on size, not percentage. */ 4746 /* save metadata every percent */ 4747 psz = sd->sd_meta->ssdi.ssd_size; 4748 rb = sd->sd_meta->ssd_rebuild; 4749 if (rb > 0) 4750 percent = 100 - ((psz * 100 - rb * 100) / psz) - 1; 4751 else 4752 percent = 0; 4753 if (percent != old_percent && blk != whole_blk) { 4754 if (sr_meta_save(sd, SR_META_DIRTY)) 4755 printf("%s: could not save metadata to %s\n", 4756 DEVNAME(sc), sd->sd_meta->ssd_devname); 4757 old_percent = percent; 4758 } 4759 4760 if (sd->sd_reb_abort) 4761 goto abort; 4762 } 4763 4764 /* all done */ 4765 sd->sd_meta->ssd_rebuild = 0; 4766 for (c = 0; c < sd->sd_meta->ssdi.ssd_chunk_no; c++) { 4767 if (sd->sd_vol.sv_chunks[c]->src_meta.scm_status == 4768 BIOC_SDREBUILD) { 4769 sd->sd_set_chunk_state(sd, c, BIOC_SDONLINE); 4770 break; 4771 } 4772 } 4773 4774 abort: 4775 if (sr_meta_save(sd, SR_META_DIRTY)) 4776 printf("%s: could not save metadata to %s\n", 4777 DEVNAME(sc), sd->sd_meta->ssd_devname); 4778 fail: 4779 dma_free(buf, SR_REBUILD_IO_SIZE << DEV_BSHIFT); 4780 } 4781 4782 #ifndef SMALL_KERNEL 4783 int 4784 sr_sensors_create(struct sr_discipline *sd) 4785 { 4786 struct sr_softc *sc = sd->sd_sc; 4787 int rv = 1; 4788 4789 DNPRINTF(SR_D_STATE, "%s: %s: sr_sensors_create\n", 4790 DEVNAME(sc), sd->sd_meta->ssd_devname); 4791 4792 sd->sd_vol.sv_sensor.type = SENSOR_DRIVE; 4793 sd->sd_vol.sv_sensor.status = SENSOR_S_UNKNOWN; 4794 strlcpy(sd->sd_vol.sv_sensor.desc, sd->sd_meta->ssd_devname, 4795 sizeof(sd->sd_vol.sv_sensor.desc)); 4796 4797 sensor_attach(&sc->sc_sensordev, &sd->sd_vol.sv_sensor); 4798 sd->sd_vol.sv_sensor_attached = 1; 4799 4800 if (sc->sc_sensor_task == NULL) { 4801 sc->sc_sensor_task = sensor_task_register(sc, 4802 sr_sensors_refresh, 10); 4803 if (sc->sc_sensor_task == NULL) 4804 goto bad; 4805 } 4806 4807 rv = 0; 4808 bad: 4809 return (rv); 4810 } 4811 4812 void 4813 sr_sensors_delete(struct sr_discipline *sd) 4814 { 4815 DNPRINTF(SR_D_STATE, "%s: sr_sensors_delete\n", DEVNAME(sd->sd_sc)); 4816 4817 if (sd->sd_vol.sv_sensor_attached) 4818 sensor_detach(&sd->sd_sc->sc_sensordev, &sd->sd_vol.sv_sensor); 4819 } 4820 4821 void 4822 sr_sensors_refresh(void *arg) 4823 { 4824 struct sr_softc *sc = arg; 4825 struct sr_volume *sv; 4826 struct sr_discipline *sd; 4827 4828 DNPRINTF(SR_D_STATE, "%s: sr_sensors_refresh\n", DEVNAME(sc)); 4829 4830 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 4831 sv = &sd->sd_vol; 4832 4833 switch(sd->sd_vol_status) { 4834 case BIOC_SVOFFLINE: 4835 sv->sv_sensor.value = SENSOR_DRIVE_FAIL; 4836 sv->sv_sensor.status = SENSOR_S_CRIT; 4837 break; 4838 4839 case BIOC_SVDEGRADED: 4840 sv->sv_sensor.value = SENSOR_DRIVE_PFAIL; 4841 sv->sv_sensor.status = SENSOR_S_WARN; 4842 break; 4843 4844 case BIOC_SVSCRUB: 4845 case BIOC_SVONLINE: 4846 sv->sv_sensor.value = SENSOR_DRIVE_ONLINE; 4847 sv->sv_sensor.status = SENSOR_S_OK; 4848 break; 4849 4850 default: 4851 sv->sv_sensor.value = 0; /* unknown */ 4852 sv->sv_sensor.status = SENSOR_S_UNKNOWN; 4853 } 4854 } 4855 } 4856 #endif /* SMALL_KERNEL */ 4857 4858 #ifdef SR_FANCY_STATS 4859 void sr_print_stats(void); 4860 4861 void 4862 sr_print_stats(void) 4863 { 4864 struct sr_softc *sc = softraid0; 4865 struct sr_discipline *sd; 4866 4867 if (sc == NULL) { 4868 printf("no softraid softc found\n"); 4869 return; 4870 } 4871 4872 TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) { 4873 printf("%s: ios pending %d, collisions %llu\n", 4874 sd->sd_meta->ssd_devname, 4875 sd->sd_wu_pending, 4876 sd->sd_wu_collisions); 4877 } 4878 } 4879 #endif /* SR_FANCY_STATS */ 4880 4881 #ifdef SR_DEBUG 4882 void 4883 sr_meta_print(struct sr_metadata *m) 4884 { 4885 int i; 4886 struct sr_meta_chunk *mc; 4887 struct sr_meta_opt_hdr *omh; 4888 4889 if (!(sr_debug & SR_D_META)) 4890 return; 4891 4892 printf("\tssd_magic 0x%llx\n", m->ssdi.ssd_magic); 4893 printf("\tssd_version %d\n", m->ssdi.ssd_version); 4894 printf("\tssd_vol_flags 0x%x\n", m->ssdi.ssd_vol_flags); 4895 printf("\tssd_uuid "); 4896 sr_uuid_print(&m->ssdi.ssd_uuid, 1); 4897 printf("\tssd_chunk_no %d\n", m->ssdi.ssd_chunk_no); 4898 printf("\tssd_chunk_id %d\n", m->ssdi.ssd_chunk_id); 4899 printf("\tssd_opt_no %d\n", m->ssdi.ssd_opt_no); 4900 printf("\tssd_volid %d\n", m->ssdi.ssd_volid); 4901 printf("\tssd_level %d\n", m->ssdi.ssd_level); 4902 printf("\tssd_size %lld\n", m->ssdi.ssd_size); 4903 printf("\tssd_devname %s\n", m->ssd_devname); 4904 printf("\tssd_vendor %s\n", m->ssdi.ssd_vendor); 4905 printf("\tssd_product %s\n", m->ssdi.ssd_product); 4906 printf("\tssd_revision %s\n", m->ssdi.ssd_revision); 4907 printf("\tssd_strip_size %d\n", m->ssdi.ssd_strip_size); 4908 printf("\tssd_checksum "); 4909 sr_checksum_print(m->ssd_checksum); 4910 printf("\n"); 4911 printf("\tssd_meta_flags 0x%x\n", m->ssd_meta_flags); 4912 printf("\tssd_ondisk %llu\n", m->ssd_ondisk); 4913 4914 mc = (struct sr_meta_chunk *)(m + 1); 4915 for (i = 0; i < m->ssdi.ssd_chunk_no; i++, mc++) { 4916 printf("\t\tscm_volid %d\n", mc->scmi.scm_volid); 4917 printf("\t\tscm_chunk_id %d\n", mc->scmi.scm_chunk_id); 4918 printf("\t\tscm_devname %s\n", mc->scmi.scm_devname); 4919 printf("\t\tscm_size %lld\n", mc->scmi.scm_size); 4920 printf("\t\tscm_coerced_size %lld\n",mc->scmi.scm_coerced_size); 4921 printf("\t\tscm_uuid "); 4922 sr_uuid_print(&mc->scmi.scm_uuid, 1); 4923 printf("\t\tscm_checksum "); 4924 sr_checksum_print(mc->scm_checksum); 4925 printf("\n"); 4926 printf("\t\tscm_status %d\n", mc->scm_status); 4927 } 4928 4929 omh = (struct sr_meta_opt_hdr *)((u_int8_t *)(m + 1) + 4930 sizeof(struct sr_meta_chunk) * m->ssdi.ssd_chunk_no); 4931 for (i = 0; i < m->ssdi.ssd_opt_no; i++) { 4932 printf("\t\t\tsom_type %d\n", omh->som_type); 4933 printf("\t\t\tsom_checksum "); 4934 sr_checksum_print(omh->som_checksum); 4935 printf("\n"); 4936 omh = (struct sr_meta_opt_hdr *)((void *)omh + 4937 omh->som_length); 4938 } 4939 } 4940 4941 void 4942 sr_dump_block(void *blk, int len) 4943 { 4944 uint8_t *b = blk; 4945 int i, j, c; 4946 4947 for (i = 0; i < len; i += 16) { 4948 for (j = 0; j < 16; j++) 4949 printf("%.2x ", b[i + j]); 4950 printf(" "); 4951 for (j = 0; j < 16; j++) { 4952 c = b[i + j]; 4953 if (c < ' ' || c > 'z' || i + j > len) 4954 c = '.'; 4955 printf("%c", c); 4956 } 4957 printf("\n"); 4958 } 4959 } 4960 4961 void 4962 sr_dump_mem(u_int8_t *p, int len) 4963 { 4964 int i; 4965 4966 for (i = 0; i < len; i++) 4967 printf("%02x ", *p++); 4968 printf("\n"); 4969 } 4970 4971 #endif /* SR_DEBUG */ 4972