1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/kernel.h> 33 #include <sys/module.h> 34 #include <sys/lock.h> 35 #include <sys/mutex.h> 36 #include <sys/bio.h> 37 #include <sys/sysctl.h> 38 #include <sys/malloc.h> 39 #include <sys/bitstring.h> 40 #include <vm/uma.h> 41 #include <machine/atomic.h> 42 #include <geom/geom.h> 43 #include <sys/proc.h> 44 #include <sys/kthread.h> 45 #include <geom/raid3/g_raid3.h> 46 47 static struct g_raid3_softc * 48 g_raid3_find_device(struct g_class *mp, const char *name) 49 { 50 struct g_raid3_softc *sc; 51 struct g_geom *gp; 52 53 g_topology_lock(); 54 LIST_FOREACH(gp, &mp->geom, geom) { 55 sc = gp->softc; 56 if (sc == NULL) 57 continue; 58 if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_DESTROY) != 0) 59 continue; 60 if (strcmp(gp->name, name) == 0 || 61 strcmp(sc->sc_name, name) == 0) { 62 g_topology_unlock(); 63 sx_xlock(&sc->sc_lock); 64 return (sc); 65 } 66 } 67 g_topology_unlock(); 68 return (NULL); 69 } 70 71 static struct g_raid3_disk * 72 g_raid3_find_disk(struct g_raid3_softc *sc, const char *name) 73 { 74 struct g_raid3_disk *disk; 75 u_int n; 76 77 sx_assert(&sc->sc_lock, SX_XLOCKED); 78 if (strncmp(name, _PATH_DEV, 5) == 0) 79 name += 5; 80 for (n = 0; n < sc->sc_ndisks; n++) { 81 disk = &sc->sc_disks[n]; 82 if (disk->d_state == G_RAID3_DISK_STATE_NODISK) 83 continue; 84 if (disk->d_consumer == NULL) 85 continue; 86 if (disk->d_consumer->provider == NULL) 87 continue; 88 if (strcmp(disk->d_consumer->provider->name, name) == 0) 89 return (disk); 90 } 91 return (NULL); 92 } 93 94 static void 95 g_raid3_ctl_configure(struct gctl_req *req, struct g_class *mp) 96 { 97 struct g_raid3_softc *sc; 98 struct g_raid3_disk *disk; 99 const char *name; 100 int *nargs, do_sync = 0, dirty = 1; 101 int *autosync, *noautosync; 102 int *failsync, *nofailsync; 103 int *round_robin, *noround_robin; 104 int *verify, *noverify; 105 u_int n; 106 107 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 108 if (nargs == NULL) { 109 gctl_error(req, "No '%s' argument.", "nargs"); 110 return; 111 } 112 if (*nargs != 1) { 113 gctl_error(req, "Invalid number of arguments."); 114 return; 115 } 116 autosync = gctl_get_paraml(req, "autosync", sizeof(*autosync)); 117 if (autosync == NULL) { 118 gctl_error(req, "No '%s' argument.", "autosync"); 119 return; 120 } 121 noautosync = gctl_get_paraml(req, "noautosync", sizeof(*noautosync)); 122 if (noautosync == NULL) { 123 gctl_error(req, "No '%s' argument.", "noautosync"); 124 return; 125 } 126 if (*autosync && *noautosync) { 127 gctl_error(req, "'%s' and '%s' specified.", "autosync", 128 "noautosync"); 129 return; 130 } 131 failsync = gctl_get_paraml(req, "failsync", sizeof(*failsync)); 132 if (failsync == NULL) { 133 gctl_error(req, "No '%s' argument.", "failsync"); 134 return; 135 } 136 nofailsync = gctl_get_paraml(req, "nofailsync", sizeof(*nofailsync)); 137 if (nofailsync == NULL) { 138 gctl_error(req, "No '%s' argument.", "nofailsync"); 139 return; 140 } 141 if (*failsync && *nofailsync) { 142 gctl_error(req, "'%s' and '%s' specified.", "failsync", 143 "nofailsync"); 144 return; 145 } 146 round_robin = gctl_get_paraml(req, "round_robin", sizeof(*round_robin)); 147 if (round_robin == NULL) { 148 gctl_error(req, "No '%s' argument.", "round_robin"); 149 return; 150 } 151 noround_robin = gctl_get_paraml(req, "noround_robin", 152 sizeof(*noround_robin)); 153 if (noround_robin == NULL) { 154 gctl_error(req, "No '%s' argument.", "noround_robin"); 155 return; 156 } 157 if (*round_robin && *noround_robin) { 158 gctl_error(req, "'%s' and '%s' specified.", "round_robin", 159 "noround_robin"); 160 return; 161 } 162 verify = gctl_get_paraml(req, "verify", sizeof(*verify)); 163 if (verify == NULL) { 164 gctl_error(req, "No '%s' argument.", "verify"); 165 return; 166 } 167 noverify = gctl_get_paraml(req, "noverify", sizeof(*noverify)); 168 if (noverify == NULL) { 169 gctl_error(req, "No '%s' argument.", "noverify"); 170 return; 171 } 172 if (*verify && *noverify) { 173 gctl_error(req, "'%s' and '%s' specified.", "verify", 174 "noverify"); 175 return; 176 } 177 if (!*autosync && !*noautosync && !*failsync && !*nofailsync && 178 !*round_robin && !*noround_robin && !*verify && !*noverify) { 179 gctl_error(req, "Nothing has changed."); 180 return; 181 } 182 name = gctl_get_asciiparam(req, "arg0"); 183 if (name == NULL) { 184 gctl_error(req, "No 'arg%u' argument.", 0); 185 return; 186 } 187 sc = g_raid3_find_device(mp, name); 188 if (sc == NULL) { 189 gctl_error(req, "No such device: %s.", name); 190 return; 191 } 192 if (g_raid3_ndisks(sc, -1) < sc->sc_ndisks) { 193 gctl_error(req, "Not all disks connected."); 194 sx_xunlock(&sc->sc_lock); 195 return; 196 } 197 if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_NOAUTOSYNC) != 0) { 198 if (*autosync) { 199 sc->sc_flags &= ~G_RAID3_DEVICE_FLAG_NOAUTOSYNC; 200 do_sync = 1; 201 } 202 } else { 203 if (*noautosync) 204 sc->sc_flags |= G_RAID3_DEVICE_FLAG_NOAUTOSYNC; 205 } 206 if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_NOFAILSYNC) != 0) { 207 if (*failsync) 208 sc->sc_flags &= ~G_RAID3_DEVICE_FLAG_NOFAILSYNC; 209 } else { 210 if (*nofailsync) { 211 sc->sc_flags |= G_RAID3_DEVICE_FLAG_NOFAILSYNC; 212 dirty = 0; 213 } 214 } 215 if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_VERIFY) != 0) { 216 if (*noverify) 217 sc->sc_flags &= ~G_RAID3_DEVICE_FLAG_VERIFY; 218 } else { 219 if (*verify) 220 sc->sc_flags |= G_RAID3_DEVICE_FLAG_VERIFY; 221 } 222 if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_ROUND_ROBIN) != 0) { 223 if (*noround_robin) 224 sc->sc_flags &= ~G_RAID3_DEVICE_FLAG_ROUND_ROBIN; 225 } else { 226 if (*round_robin) 227 sc->sc_flags |= G_RAID3_DEVICE_FLAG_ROUND_ROBIN; 228 } 229 if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_VERIFY) != 0 && 230 (sc->sc_flags & G_RAID3_DEVICE_FLAG_ROUND_ROBIN) != 0) { 231 /* 232 * VERIFY and ROUND-ROBIN options are mutally exclusive. 233 */ 234 sc->sc_flags &= ~G_RAID3_DEVICE_FLAG_ROUND_ROBIN; 235 } 236 for (n = 0; n < sc->sc_ndisks; n++) { 237 disk = &sc->sc_disks[n]; 238 if (do_sync) { 239 if (disk->d_state == G_RAID3_DISK_STATE_SYNCHRONIZING) 240 disk->d_flags &= ~G_RAID3_DISK_FLAG_FORCE_SYNC; 241 } 242 if (!dirty) 243 disk->d_flags &= ~G_RAID3_DISK_FLAG_DIRTY; 244 g_raid3_update_metadata(disk); 245 if (do_sync) { 246 if (disk->d_state == G_RAID3_DISK_STATE_STALE) { 247 /* 248 * XXX: This is probably possible that this 249 * component will not be retasted. 250 */ 251 g_raid3_event_send(disk, 252 G_RAID3_DISK_STATE_DISCONNECTED, 253 G_RAID3_EVENT_DONTWAIT); 254 } 255 } 256 } 257 sx_xunlock(&sc->sc_lock); 258 } 259 260 static void 261 g_raid3_ctl_rebuild(struct gctl_req *req, struct g_class *mp) 262 { 263 struct g_raid3_metadata md; 264 struct g_raid3_softc *sc; 265 struct g_raid3_disk *disk; 266 struct g_provider *pp; 267 const char *name; 268 int error, *nargs; 269 270 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 271 if (nargs == NULL) { 272 gctl_error(req, "No '%s' argument.", "nargs"); 273 return; 274 } 275 if (*nargs != 2) { 276 gctl_error(req, "Invalid number of arguments."); 277 return; 278 } 279 name = gctl_get_asciiparam(req, "arg0"); 280 if (name == NULL) { 281 gctl_error(req, "No 'arg%u' argument.", 0); 282 return; 283 } 284 sc = g_raid3_find_device(mp, name); 285 if (sc == NULL) { 286 gctl_error(req, "No such device: %s.", name); 287 return; 288 } 289 name = gctl_get_asciiparam(req, "arg1"); 290 if (name == NULL) { 291 gctl_error(req, "No 'arg%u' argument.", 1); 292 sx_xunlock(&sc->sc_lock); 293 return; 294 } 295 disk = g_raid3_find_disk(sc, name); 296 if (disk == NULL) { 297 gctl_error(req, "No such provider: %s.", name); 298 sx_xunlock(&sc->sc_lock); 299 return; 300 } 301 if (disk->d_state == G_RAID3_DISK_STATE_ACTIVE && 302 g_raid3_ndisks(sc, G_RAID3_DISK_STATE_ACTIVE) < sc->sc_ndisks) { 303 gctl_error(req, "There is one stale disk already."); 304 sx_xunlock(&sc->sc_lock); 305 return; 306 } 307 /* 308 * Do rebuild by resetting syncid and disconnecting disk. 309 * It'll be retasted, connected to the device and synchronized. 310 */ 311 disk->d_sync.ds_syncid = 0; 312 if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_NOAUTOSYNC) != 0) 313 disk->d_flags |= G_RAID3_DISK_FLAG_FORCE_SYNC; 314 g_raid3_update_metadata(disk); 315 pp = disk->d_consumer->provider; 316 g_topology_lock(); 317 error = g_raid3_read_metadata(disk->d_consumer, &md); 318 g_topology_unlock(); 319 g_raid3_event_send(disk, G_RAID3_DISK_STATE_DISCONNECTED, 320 G_RAID3_EVENT_WAIT); 321 if (error != 0) { 322 gctl_error(req, "Cannot read metadata from %s.", pp->name); 323 sx_xunlock(&sc->sc_lock); 324 return; 325 } 326 error = g_raid3_add_disk(sc, pp, &md); 327 if (error != 0) 328 gctl_error(req, "Cannot reconnect component %s.", pp->name); 329 sx_xunlock(&sc->sc_lock); 330 } 331 332 static void 333 g_raid3_ctl_stop(struct gctl_req *req, struct g_class *mp) 334 { 335 struct g_raid3_softc *sc; 336 int *force, *nargs, error; 337 const char *name; 338 char param[16]; 339 u_int i; 340 int how; 341 342 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 343 if (nargs == NULL) { 344 gctl_error(req, "No '%s' argument.", "nargs"); 345 return; 346 } 347 if (*nargs < 1) { 348 gctl_error(req, "Missing device(s)."); 349 return; 350 } 351 force = gctl_get_paraml(req, "force", sizeof(*force)); 352 if (force == NULL) { 353 gctl_error(req, "No '%s' argument.", "force"); 354 return; 355 } 356 if (*force) 357 how = G_RAID3_DESTROY_HARD; 358 else 359 how = G_RAID3_DESTROY_SOFT; 360 361 for (i = 0; i < (u_int)*nargs; i++) { 362 snprintf(param, sizeof(param), "arg%u", i); 363 name = gctl_get_asciiparam(req, param); 364 if (name == NULL) { 365 gctl_error(req, "No 'arg%u' argument.", i); 366 return; 367 } 368 sc = g_raid3_find_device(mp, name); 369 if (sc == NULL) { 370 gctl_error(req, "No such device: %s.", name); 371 return; 372 } 373 g_cancel_event(sc); 374 error = g_raid3_destroy(sc, how); 375 if (error != 0) { 376 gctl_error(req, "Cannot destroy device %s (error=%d).", 377 sc->sc_geom->name, error); 378 sx_xunlock(&sc->sc_lock); 379 return; 380 } 381 /* No need to unlock, because lock is already dead. */ 382 } 383 } 384 385 static void 386 g_raid3_ctl_insert_orphan(struct g_consumer *cp) 387 { 388 389 KASSERT(1 == 0, ("%s called while inserting %s.", __func__, 390 cp->provider->name)); 391 } 392 393 static void 394 g_raid3_ctl_insert(struct gctl_req *req, struct g_class *mp) 395 { 396 struct g_raid3_metadata md; 397 struct g_raid3_softc *sc; 398 struct g_raid3_disk *disk; 399 struct g_geom *gp; 400 struct g_provider *pp; 401 struct g_consumer *cp; 402 const char *name; 403 u_char *sector; 404 off_t compsize; 405 intmax_t *no; 406 int *hardcode, *nargs, error, autono; 407 408 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 409 if (nargs == NULL) { 410 gctl_error(req, "No '%s' argument.", "nargs"); 411 return; 412 } 413 if (*nargs != 2) { 414 gctl_error(req, "Invalid number of arguments."); 415 return; 416 } 417 hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode)); 418 if (hardcode == NULL) { 419 gctl_error(req, "No '%s' argument.", "hardcode"); 420 return; 421 } 422 pp = gctl_get_provider(req, "arg1"); 423 if (pp == NULL) 424 return; 425 if (gctl_get_param(req, "number", NULL) != NULL) 426 no = gctl_get_paraml(req, "number", sizeof(*no)); 427 else 428 no = NULL; 429 gp = g_new_geomf(mp, "raid3:insert"); 430 gp->orphan = g_raid3_ctl_insert_orphan; 431 cp = g_new_consumer(gp); 432 error = g_attach(cp, pp); 433 if (error != 0) { 434 g_topology_unlock(); 435 gctl_error(req, "Cannot attach to %s.", pp->name); 436 goto end; 437 } 438 error = g_access(cp, 0, 1, 1); 439 if (error != 0) { 440 g_topology_unlock(); 441 gctl_error(req, "Cannot access %s.", pp->name); 442 goto end; 443 } 444 g_topology_unlock(); 445 name = gctl_get_asciiparam(req, "arg0"); 446 if (name == NULL) { 447 gctl_error(req, "No 'arg%u' argument.", 0); 448 goto end; 449 } 450 sc = g_raid3_find_device(mp, name); 451 if (sc == NULL) { 452 gctl_error(req, "No such device: %s.", name); 453 goto end; 454 } 455 if (no != NULL) { 456 if (*no < 0 || *no >= sc->sc_ndisks) { 457 sx_xunlock(&sc->sc_lock); 458 gctl_error(req, "Invalid component number."); 459 goto end; 460 } 461 disk = &sc->sc_disks[*no]; 462 if (disk->d_state != G_RAID3_DISK_STATE_NODISK) { 463 sx_xunlock(&sc->sc_lock); 464 gctl_error(req, "Component %jd is already connected.", 465 *no); 466 goto end; 467 } 468 } else { 469 disk = NULL; 470 for (autono = 0; autono < sc->sc_ndisks && disk == NULL; autono++) 471 if (sc->sc_disks[autono].d_state == 472 G_RAID3_DISK_STATE_NODISK) 473 disk = &sc->sc_disks[autono]; 474 if (disk == NULL) { 475 sx_xunlock(&sc->sc_lock); 476 gctl_error(req, "No disconnected components."); 477 goto end; 478 } 479 } 480 if (((sc->sc_sectorsize / (sc->sc_ndisks - 1)) % pp->sectorsize) != 0) { 481 sx_xunlock(&sc->sc_lock); 482 gctl_error(req, 483 "Cannot insert provider %s, because of its sector size.", 484 pp->name); 485 goto end; 486 } 487 compsize = sc->sc_mediasize / (sc->sc_ndisks - 1); 488 if (compsize > pp->mediasize - pp->sectorsize) { 489 sx_xunlock(&sc->sc_lock); 490 gctl_error(req, "Provider %s too small.", pp->name); 491 goto end; 492 } 493 if (compsize < pp->mediasize - pp->sectorsize) { 494 gctl_error(req, 495 "warning: %s: only %jd bytes from %jd bytes used.", 496 pp->name, (intmax_t)compsize, 497 (intmax_t)(pp->mediasize - pp->sectorsize)); 498 } 499 g_raid3_fill_metadata(disk, &md); 500 sx_xunlock(&sc->sc_lock); 501 md.md_syncid = 0; 502 md.md_dflags = 0; 503 if (*hardcode) 504 strlcpy(md.md_provider, pp->name, sizeof(md.md_provider)); 505 else 506 bzero(md.md_provider, sizeof(md.md_provider)); 507 md.md_provsize = pp->mediasize; 508 sector = g_malloc(pp->sectorsize, M_WAITOK); 509 raid3_metadata_encode(&md, sector); 510 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector, 511 pp->sectorsize); 512 g_free(sector); 513 if (error != 0) 514 gctl_error(req, "Cannot store metadata on %s.", pp->name); 515 end: 516 g_topology_lock(); 517 if (cp->acw > 0) 518 g_access(cp, 0, -1, -1); 519 if (cp->provider != NULL) 520 g_detach(cp); 521 g_destroy_consumer(cp); 522 g_destroy_geom(gp); 523 g_topology_unlock(); 524 } 525 526 static void 527 g_raid3_ctl_remove(struct gctl_req *req, struct g_class *mp) 528 { 529 struct g_raid3_softc *sc; 530 struct g_raid3_disk *disk; 531 const char *name; 532 intmax_t *no; 533 int *nargs; 534 535 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 536 if (nargs == NULL) { 537 gctl_error(req, "No '%s' argument.", "nargs"); 538 return; 539 } 540 if (*nargs != 1) { 541 gctl_error(req, "Invalid number of arguments."); 542 return; 543 } 544 no = gctl_get_paraml(req, "number", sizeof(*no)); 545 if (no == NULL) { 546 gctl_error(req, "No '%s' argument.", "no"); 547 return; 548 } 549 name = gctl_get_asciiparam(req, "arg0"); 550 if (name == NULL) { 551 gctl_error(req, "No 'arg%u' argument.", 0); 552 return; 553 } 554 sc = g_raid3_find_device(mp, name); 555 if (sc == NULL) { 556 gctl_error(req, "No such device: %s.", name); 557 return; 558 } 559 if (*no >= sc->sc_ndisks) { 560 sx_xunlock(&sc->sc_lock); 561 gctl_error(req, "Invalid component number."); 562 return; 563 } 564 disk = &sc->sc_disks[*no]; 565 switch (disk->d_state) { 566 case G_RAID3_DISK_STATE_ACTIVE: 567 /* 568 * When replacing ACTIVE component, all the rest has to be also 569 * ACTIVE. 570 */ 571 if (g_raid3_ndisks(sc, G_RAID3_DISK_STATE_ACTIVE) < 572 sc->sc_ndisks) { 573 gctl_error(req, "Cannot replace component number %jd.", 574 *no); 575 break; 576 } 577 /* FALLTHROUGH */ 578 case G_RAID3_DISK_STATE_STALE: 579 case G_RAID3_DISK_STATE_SYNCHRONIZING: 580 if (g_raid3_clear_metadata(disk) != 0) { 581 gctl_error(req, "Cannot clear metadata on %s.", 582 g_raid3_get_diskname(disk)); 583 } else { 584 g_raid3_event_send(disk, 585 G_RAID3_DISK_STATE_DISCONNECTED, 586 G_RAID3_EVENT_DONTWAIT); 587 } 588 break; 589 case G_RAID3_DISK_STATE_NODISK: 590 break; 591 default: 592 gctl_error(req, "Cannot replace component number %jd.", *no); 593 break; 594 } 595 sx_xunlock(&sc->sc_lock); 596 } 597 598 void 599 g_raid3_config(struct gctl_req *req, struct g_class *mp, const char *verb) 600 { 601 uint32_t *version; 602 603 g_topology_assert(); 604 605 version = gctl_get_paraml(req, "version", sizeof(*version)); 606 if (version == NULL) { 607 gctl_error(req, "No '%s' argument.", "version"); 608 return; 609 } 610 if (*version != G_RAID3_VERSION) { 611 gctl_error(req, "Userland and kernel parts are out of sync."); 612 return; 613 } 614 615 g_topology_unlock(); 616 if (strcmp(verb, "configure") == 0) 617 g_raid3_ctl_configure(req, mp); 618 else if (strcmp(verb, "insert") == 0) 619 g_raid3_ctl_insert(req, mp); 620 else if (strcmp(verb, "rebuild") == 0) 621 g_raid3_ctl_rebuild(req, mp); 622 else if (strcmp(verb, "remove") == 0) 623 g_raid3_ctl_remove(req, mp); 624 else if (strcmp(verb, "stop") == 0) 625 g_raid3_ctl_stop(req, mp); 626 else 627 gctl_error(req, "Unknown verb."); 628 g_topology_lock(); 629 } 630