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