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