xref: /freebsd/sys/geom/multipath/g_multipath.c (revision 0957b409)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2011-2013 Alexander Motin <mav@FreeBSD.org>
5  * Copyright (c) 2006-2007 Matthew Jacob <mjacob@FreeBSD.org>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 /*
30  * Based upon work by Pawel Jakub Dawidek <pjd@FreeBSD.org> for all of the
31  * fine geom examples, and by Poul Henning Kamp <phk@FreeBSD.org> for GEOM
32  * itself, all of which is most gratefully acknowledged.
33  */
34 
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/module.h>
41 #include <sys/limits.h>
42 #include <sys/lock.h>
43 #include <sys/mutex.h>
44 #include <sys/bio.h>
45 #include <sys/sbuf.h>
46 #include <sys/sysctl.h>
47 #include <sys/kthread.h>
48 #include <sys/malloc.h>
49 #include <geom/geom.h>
50 #include <geom/multipath/g_multipath.h>
51 
52 FEATURE(geom_multipath, "GEOM multipath support");
53 
54 SYSCTL_DECL(_kern_geom);
55 static SYSCTL_NODE(_kern_geom, OID_AUTO, multipath, CTLFLAG_RW, 0,
56     "GEOM_MULTIPATH tunables");
57 static u_int g_multipath_debug = 0;
58 SYSCTL_UINT(_kern_geom_multipath, OID_AUTO, debug, CTLFLAG_RW,
59     &g_multipath_debug, 0, "Debug level");
60 static u_int g_multipath_exclusive = 1;
61 SYSCTL_UINT(_kern_geom_multipath, OID_AUTO, exclusive, CTLFLAG_RW,
62     &g_multipath_exclusive, 0, "Exclusively open providers");
63 
64 static enum {
65 	GKT_NIL,
66 	GKT_RUN,
67 	GKT_DIE
68 } g_multipath_kt_state;
69 static struct bio_queue_head gmtbq;
70 static struct mtx gmtbq_mtx;
71 
72 static int g_multipath_read_metadata(struct g_consumer *cp,
73     struct g_multipath_metadata *md);
74 static int g_multipath_write_metadata(struct g_consumer *cp,
75     struct g_multipath_metadata *md);
76 
77 static void g_multipath_orphan(struct g_consumer *);
78 static void g_multipath_resize(struct g_consumer *);
79 static void g_multipath_start(struct bio *);
80 static void g_multipath_done(struct bio *);
81 static void g_multipath_done_error(struct bio *);
82 static void g_multipath_kt(void *);
83 
84 static int g_multipath_destroy(struct g_geom *);
85 static int
86 g_multipath_destroy_geom(struct gctl_req *, struct g_class *, struct g_geom *);
87 
88 static struct g_geom *g_multipath_find_geom(struct g_class *, const char *);
89 static int g_multipath_rotate(struct g_geom *);
90 
91 static g_taste_t g_multipath_taste;
92 static g_ctl_req_t g_multipath_config;
93 static g_init_t g_multipath_init;
94 static g_fini_t g_multipath_fini;
95 static g_dumpconf_t g_multipath_dumpconf;
96 
97 struct g_class g_multipath_class = {
98 	.name		= G_MULTIPATH_CLASS_NAME,
99 	.version	= G_VERSION,
100 	.ctlreq		= g_multipath_config,
101 	.taste		= g_multipath_taste,
102 	.destroy_geom	= g_multipath_destroy_geom,
103 	.init		= g_multipath_init,
104 	.fini		= g_multipath_fini
105 };
106 
107 #define	MP_FAIL		0x00000001
108 #define	MP_LOST		0x00000002
109 #define	MP_NEW		0x00000004
110 #define	MP_POSTED	0x00000008
111 #define	MP_BAD		(MP_FAIL | MP_LOST | MP_NEW)
112 #define	MP_WITHER	0x00000010
113 #define	MP_IDLE		0x00000020
114 #define	MP_IDLE_MASK	0xffffffe0
115 
116 static int
117 g_multipath_good(struct g_geom *gp)
118 {
119 	struct g_consumer *cp;
120 	int n = 0;
121 
122 	LIST_FOREACH(cp, &gp->consumer, consumer) {
123 		if ((cp->index & MP_BAD) == 0)
124 			n++;
125 	}
126 	return (n);
127 }
128 
129 static void
130 g_multipath_fault(struct g_consumer *cp, int cause)
131 {
132 	struct g_multipath_softc *sc;
133 	struct g_consumer *lcp;
134 	struct g_geom *gp;
135 
136 	gp = cp->geom;
137 	sc = gp->softc;
138 	cp->index |= cause;
139 	if (g_multipath_good(gp) == 0 && sc->sc_ndisks > 0) {
140 		LIST_FOREACH(lcp, &gp->consumer, consumer) {
141 			if (lcp->provider == NULL ||
142 			    (lcp->index & (MP_LOST | MP_NEW)))
143 				continue;
144 			if (sc->sc_ndisks > 1 && lcp == cp)
145 				continue;
146 			printf("GEOM_MULTIPATH: "
147 			    "all paths in %s were marked FAIL, restore %s\n",
148 			    sc->sc_name, lcp->provider->name);
149 			lcp->index &= ~MP_FAIL;
150 		}
151 	}
152 	if (cp != sc->sc_active)
153 		return;
154 	sc->sc_active = NULL;
155 	LIST_FOREACH(lcp, &gp->consumer, consumer) {
156 		if ((lcp->index & MP_BAD) == 0) {
157 			sc->sc_active = lcp;
158 			break;
159 		}
160 	}
161 	if (sc->sc_active == NULL) {
162 		printf("GEOM_MULTIPATH: out of providers for %s\n",
163 		    sc->sc_name);
164 	} else if (sc->sc_active_active != 1) {
165 		printf("GEOM_MULTIPATH: %s is now active path in %s\n",
166 		    sc->sc_active->provider->name, sc->sc_name);
167 	}
168 }
169 
170 static struct g_consumer *
171 g_multipath_choose(struct g_geom *gp, struct bio *bp)
172 {
173 	struct g_multipath_softc *sc;
174 	struct g_consumer *best, *cp;
175 
176 	sc = gp->softc;
177 	if (sc->sc_active_active == 0 ||
178 	    (sc->sc_active_active == 2 && bp->bio_cmd != BIO_READ))
179 		return (sc->sc_active);
180 	best = NULL;
181 	LIST_FOREACH(cp, &gp->consumer, consumer) {
182 		if (cp->index & MP_BAD)
183 			continue;
184 		cp->index += MP_IDLE;
185 		if (best == NULL || cp->private < best->private ||
186 		    (cp->private == best->private && cp->index > best->index))
187 			best = cp;
188 	}
189 	if (best != NULL)
190 		best->index &= ~MP_IDLE_MASK;
191 	return (best);
192 }
193 
194 static void
195 g_mpd(void *arg, int flags __unused)
196 {
197 	struct g_geom *gp;
198 	struct g_multipath_softc *sc;
199 	struct g_consumer *cp;
200 	int w;
201 
202 	g_topology_assert();
203 	cp = arg;
204 	gp = cp->geom;
205 	if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) {
206 		w = cp->acw;
207 		g_access(cp, -cp->acr, -cp->acw, -cp->ace);
208 		if (w > 0 && cp->provider != NULL &&
209 		    (cp->provider->geom->flags & G_GEOM_WITHER) == 0) {
210 			cp->index |= MP_WITHER;
211 			g_post_event(g_mpd, cp, M_WAITOK, NULL);
212 			return;
213 		}
214 	}
215 	sc = gp->softc;
216 	mtx_lock(&sc->sc_mtx);
217 	if (cp->provider) {
218 		printf("GEOM_MULTIPATH: %s removed from %s\n",
219 		    cp->provider->name, gp->name);
220 		g_detach(cp);
221 	}
222 	g_destroy_consumer(cp);
223 	mtx_unlock(&sc->sc_mtx);
224 	if (LIST_EMPTY(&gp->consumer))
225 		g_multipath_destroy(gp);
226 }
227 
228 static void
229 g_multipath_orphan(struct g_consumer *cp)
230 {
231 	struct g_multipath_softc *sc;
232 	uintptr_t *cnt;
233 
234 	g_topology_assert();
235 	printf("GEOM_MULTIPATH: %s in %s was disconnected\n",
236 	    cp->provider->name, cp->geom->name);
237 	sc = cp->geom->softc;
238 	cnt = (uintptr_t *)&cp->private;
239 	mtx_lock(&sc->sc_mtx);
240 	sc->sc_ndisks--;
241 	g_multipath_fault(cp, MP_LOST);
242 	if (*cnt == 0 && (cp->index & MP_POSTED) == 0) {
243 		cp->index |= MP_POSTED;
244 		mtx_unlock(&sc->sc_mtx);
245 		g_mpd(cp, 0);
246 	} else
247 		mtx_unlock(&sc->sc_mtx);
248 }
249 
250 static void
251 g_multipath_resize(struct g_consumer *cp)
252 {
253 	struct g_multipath_softc *sc;
254 	struct g_geom *gp;
255 	struct g_consumer *cp1;
256 	struct g_provider *pp;
257 	struct g_multipath_metadata md;
258 	off_t size, psize, ssize;
259 	int error;
260 
261 	g_topology_assert();
262 
263 	gp = cp->geom;
264 	pp = cp->provider;
265 	sc = gp->softc;
266 
267 	if (sc->sc_stopping)
268 		return;
269 
270 	if (pp->mediasize < sc->sc_size) {
271 		size = pp->mediasize;
272 		ssize = pp->sectorsize;
273 	} else {
274 		size = ssize = OFF_MAX;
275 		mtx_lock(&sc->sc_mtx);
276 		LIST_FOREACH(cp1, &gp->consumer, consumer) {
277 			pp = cp1->provider;
278 			if (pp == NULL)
279 				continue;
280 			if (pp->mediasize < size) {
281 				size = pp->mediasize;
282 				ssize = pp->sectorsize;
283 			}
284 		}
285 		mtx_unlock(&sc->sc_mtx);
286 		if (size == OFF_MAX || size == sc->sc_size)
287 			return;
288 	}
289 	psize = size - ((sc->sc_uuid[0] != 0) ? ssize : 0);
290 	printf("GEOM_MULTIPATH: %s size changed from %jd to %jd\n",
291 	    sc->sc_name, sc->sc_pp->mediasize, psize);
292 	if (sc->sc_uuid[0] != 0 && size < sc->sc_size) {
293 		error = g_multipath_read_metadata(cp, &md);
294 		if (error ||
295 		    (strcmp(md.md_magic, G_MULTIPATH_MAGIC) != 0) ||
296 		    (memcmp(md.md_uuid, sc->sc_uuid, sizeof(sc->sc_uuid)) != 0) ||
297 		    (strcmp(md.md_name, sc->sc_name) != 0) ||
298 		    (md.md_size != 0 && md.md_size != size) ||
299 		    (md.md_sectorsize != 0 && md.md_sectorsize != ssize)) {
300 			g_multipath_destroy(gp);
301 			return;
302 		}
303 	}
304 	sc->sc_size = size;
305 	g_resize_provider(sc->sc_pp, psize);
306 
307 	if (sc->sc_uuid[0] != 0) {
308 		pp = cp->provider;
309 		strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic));
310 		memcpy(md.md_uuid, sc->sc_uuid, sizeof (sc->sc_uuid));
311 		strlcpy(md.md_name, sc->sc_name, sizeof(md.md_name));
312 		md.md_version = G_MULTIPATH_VERSION;
313 		md.md_size = size;
314 		md.md_sectorsize = ssize;
315 		md.md_active_active = sc->sc_active_active;
316 		error = g_multipath_write_metadata(cp, &md);
317 		if (error != 0)
318 			printf("GEOM_MULTIPATH: Can't update metadata on %s "
319 			    "(%d)\n", pp->name, error);
320 	}
321 }
322 
323 static void
324 g_multipath_start(struct bio *bp)
325 {
326 	struct g_multipath_softc *sc;
327 	struct g_geom *gp;
328 	struct g_consumer *cp;
329 	struct bio *cbp;
330 	uintptr_t *cnt;
331 
332 	gp = bp->bio_to->geom;
333 	sc = gp->softc;
334 	KASSERT(sc != NULL, ("NULL sc"));
335 	cbp = g_clone_bio(bp);
336 	if (cbp == NULL) {
337 		g_io_deliver(bp, ENOMEM);
338 		return;
339 	}
340 	mtx_lock(&sc->sc_mtx);
341 	cp = g_multipath_choose(gp, bp);
342 	if (cp == NULL) {
343 		mtx_unlock(&sc->sc_mtx);
344 		g_destroy_bio(cbp);
345 		g_io_deliver(bp, ENXIO);
346 		return;
347 	}
348 	if ((uintptr_t)bp->bio_driver1 < sc->sc_ndisks)
349 		bp->bio_driver1 = (void *)(uintptr_t)sc->sc_ndisks;
350 	cnt = (uintptr_t *)&cp->private;
351 	(*cnt)++;
352 	mtx_unlock(&sc->sc_mtx);
353 	cbp->bio_done = g_multipath_done;
354 	g_io_request(cbp, cp);
355 }
356 
357 static void
358 g_multipath_done(struct bio *bp)
359 {
360 	struct g_multipath_softc *sc;
361 	struct g_consumer *cp;
362 	uintptr_t *cnt;
363 
364 	if (bp->bio_error == ENXIO || bp->bio_error == EIO) {
365 		mtx_lock(&gmtbq_mtx);
366 		bioq_insert_tail(&gmtbq, bp);
367 		mtx_unlock(&gmtbq_mtx);
368 		wakeup(&g_multipath_kt_state);
369 	} else {
370 		cp = bp->bio_from;
371 		sc = cp->geom->softc;
372 		cnt = (uintptr_t *)&cp->private;
373 		mtx_lock(&sc->sc_mtx);
374 		(*cnt)--;
375 		if (*cnt == 0 && (cp->index & MP_LOST)) {
376 			if (g_post_event(g_mpd, cp, M_NOWAIT, NULL) == 0)
377 				cp->index |= MP_POSTED;
378 			mtx_unlock(&sc->sc_mtx);
379 		} else
380 			mtx_unlock(&sc->sc_mtx);
381 		g_std_done(bp);
382 	}
383 }
384 
385 static void
386 g_multipath_done_error(struct bio *bp)
387 {
388 	struct bio *pbp;
389 	struct g_geom *gp;
390 	struct g_multipath_softc *sc;
391 	struct g_consumer *cp;
392 	struct g_provider *pp;
393 	uintptr_t *cnt;
394 
395 	/*
396 	 * If we had a failure, we have to check first to see
397 	 * whether the consumer it failed on was the currently
398 	 * active consumer (i.e., this is the first in perhaps
399 	 * a number of failures). If so, we then switch consumers
400 	 * to the next available consumer.
401 	 */
402 
403 	pbp = bp->bio_parent;
404 	gp = pbp->bio_to->geom;
405 	sc = gp->softc;
406 	cp = bp->bio_from;
407 	pp = cp->provider;
408 	cnt = (uintptr_t *)&cp->private;
409 
410 	mtx_lock(&sc->sc_mtx);
411 	if ((cp->index & MP_FAIL) == 0) {
412 		printf("GEOM_MULTIPATH: Error %d, %s in %s marked FAIL\n",
413 		    bp->bio_error, pp->name, sc->sc_name);
414 		g_multipath_fault(cp, MP_FAIL);
415 	}
416 	(*cnt)--;
417 	if (*cnt == 0 && (cp->index & (MP_LOST | MP_POSTED)) == MP_LOST) {
418 		cp->index |= MP_POSTED;
419 		mtx_unlock(&sc->sc_mtx);
420 		g_post_event(g_mpd, cp, M_WAITOK, NULL);
421 	} else
422 		mtx_unlock(&sc->sc_mtx);
423 
424 	/*
425 	 * If we can fruitfully restart the I/O, do so.
426 	 */
427 	if (pbp->bio_children < (uintptr_t)pbp->bio_driver1) {
428 		pbp->bio_inbed++;
429 		g_destroy_bio(bp);
430 		g_multipath_start(pbp);
431 	} else {
432 		g_std_done(bp);
433 	}
434 }
435 
436 static void
437 g_multipath_kt(void *arg)
438 {
439 
440 	g_multipath_kt_state = GKT_RUN;
441 	mtx_lock(&gmtbq_mtx);
442 	while (g_multipath_kt_state == GKT_RUN) {
443 		for (;;) {
444 			struct bio *bp;
445 
446 			bp = bioq_takefirst(&gmtbq);
447 			if (bp == NULL)
448 				break;
449 			mtx_unlock(&gmtbq_mtx);
450 			g_multipath_done_error(bp);
451 			mtx_lock(&gmtbq_mtx);
452 		}
453 		if (g_multipath_kt_state != GKT_RUN)
454 			break;
455 		msleep(&g_multipath_kt_state, &gmtbq_mtx, PRIBIO,
456 		    "gkt:wait", 0);
457 	}
458 	mtx_unlock(&gmtbq_mtx);
459 	wakeup(&g_multipath_kt_state);
460 	kproc_exit(0);
461 }
462 
463 
464 static int
465 g_multipath_access(struct g_provider *pp, int dr, int dw, int de)
466 {
467 	struct g_geom *gp;
468 	struct g_consumer *cp, *badcp = NULL;
469 	struct g_multipath_softc *sc;
470 	int error;
471 
472 	gp = pp->geom;
473 
474 	/* Error used if we have no valid consumers. */
475 	error = (dr > 0 || dw > 0 || de > 0) ? ENXIO : 0;
476 
477 	LIST_FOREACH(cp, &gp->consumer, consumer) {
478 		if (cp->index & MP_WITHER)
479 			continue;
480 
481 		error = g_access(cp, dr, dw, de);
482 		if (error) {
483 			badcp = cp;
484 			goto fail;
485 		}
486 	}
487 
488 	if (error != 0)
489 		return (error);
490 
491 	sc = gp->softc;
492 	sc->sc_opened += dr + dw + de;
493 	if (sc->sc_stopping && sc->sc_opened == 0)
494 		g_multipath_destroy(gp);
495 
496 	return (0);
497 
498 fail:
499 	LIST_FOREACH(cp, &gp->consumer, consumer) {
500 		if (cp == badcp)
501 			break;
502 		if (cp->index & MP_WITHER)
503 			continue;
504 
505 		(void) g_access(cp, -dr, -dw, -de);
506 	}
507 	return (error);
508 }
509 
510 static struct g_geom *
511 g_multipath_create(struct g_class *mp, struct g_multipath_metadata *md)
512 {
513 	struct g_multipath_softc *sc;
514 	struct g_geom *gp;
515 	struct g_provider *pp;
516 
517 	g_topology_assert();
518 
519 	LIST_FOREACH(gp, &mp->geom, geom) {
520 		sc = gp->softc;
521 		if (sc == NULL || sc->sc_stopping)
522 			continue;
523 		if (strcmp(gp->name, md->md_name) == 0) {
524 			printf("GEOM_MULTIPATH: name %s already exists\n",
525 			    md->md_name);
526 			return (NULL);
527 		}
528 	}
529 
530 	gp = g_new_geomf(mp, "%s", md->md_name);
531 	sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO);
532 	mtx_init(&sc->sc_mtx, "multipath", NULL, MTX_DEF);
533 	memcpy(sc->sc_uuid, md->md_uuid, sizeof (sc->sc_uuid));
534 	memcpy(sc->sc_name, md->md_name, sizeof (sc->sc_name));
535 	sc->sc_active_active = md->md_active_active;
536 	sc->sc_size = md->md_size;
537 	gp->softc = sc;
538 	gp->start = g_multipath_start;
539 	gp->orphan = g_multipath_orphan;
540 	gp->resize = g_multipath_resize;
541 	gp->access = g_multipath_access;
542 	gp->dumpconf = g_multipath_dumpconf;
543 
544 	pp = g_new_providerf(gp, "multipath/%s", md->md_name);
545 	pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE;
546 	if (md->md_size != 0) {
547 		pp->mediasize = md->md_size -
548 		    ((md->md_uuid[0] != 0) ? md->md_sectorsize : 0);
549 		pp->sectorsize = md->md_sectorsize;
550 	}
551 	sc->sc_pp = pp;
552 	g_error_provider(pp, 0);
553 	printf("GEOM_MULTIPATH: %s created\n", gp->name);
554 	return (gp);
555 }
556 
557 static int
558 g_multipath_add_disk(struct g_geom *gp, struct g_provider *pp)
559 {
560 	struct g_multipath_softc *sc;
561 	struct g_consumer *cp, *nxtcp;
562 	int error, acr, acw, ace;
563 
564 	g_topology_assert();
565 
566 	sc = gp->softc;
567 	KASSERT(sc, ("no softc"));
568 
569 	/*
570 	 * Make sure that the passed provider isn't already attached
571 	 */
572 	LIST_FOREACH(cp, &gp->consumer, consumer) {
573 		if (cp->provider == pp)
574 			break;
575 	}
576 	if (cp) {
577 		printf("GEOM_MULTIPATH: provider %s already attached to %s\n",
578 		    pp->name, gp->name);
579 		return (EEXIST);
580 	}
581 	nxtcp = LIST_FIRST(&gp->consumer);
582 	cp = g_new_consumer(gp);
583 	cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
584 	cp->private = NULL;
585 	cp->index = MP_NEW;
586 	error = g_attach(cp, pp);
587 	if (error != 0) {
588 		printf("GEOM_MULTIPATH: cannot attach %s to %s",
589 		    pp->name, sc->sc_name);
590 		g_destroy_consumer(cp);
591 		return (error);
592 	}
593 
594 	/*
595 	 * Set access permissions on new consumer to match other consumers
596 	 */
597 	if (sc->sc_pp) {
598 		acr = sc->sc_pp->acr;
599 		acw = sc->sc_pp->acw;
600 		ace = sc->sc_pp->ace;
601 	} else
602 		acr = acw = ace = 0;
603 	if (g_multipath_exclusive) {
604 		acr++;
605 		acw++;
606 		ace++;
607 	}
608 	error = g_access(cp, acr, acw, ace);
609 	if (error) {
610 		printf("GEOM_MULTIPATH: cannot set access in "
611 		    "attaching %s to %s (%d)\n",
612 		    pp->name, sc->sc_name, error);
613 		g_detach(cp);
614 		g_destroy_consumer(cp);
615 		return (error);
616 	}
617 	if (sc->sc_size == 0) {
618 		sc->sc_size = pp->mediasize -
619 		    ((sc->sc_uuid[0] != 0) ? pp->sectorsize : 0);
620 		sc->sc_pp->mediasize = sc->sc_size;
621 		sc->sc_pp->sectorsize = pp->sectorsize;
622 	}
623 	if (sc->sc_pp->stripesize == 0 && sc->sc_pp->stripeoffset == 0) {
624 		sc->sc_pp->stripesize = pp->stripesize;
625 		sc->sc_pp->stripeoffset = pp->stripeoffset;
626 	}
627 	sc->sc_pp->flags |= pp->flags & G_PF_ACCEPT_UNMAPPED;
628 	mtx_lock(&sc->sc_mtx);
629 	cp->index = 0;
630 	sc->sc_ndisks++;
631 	mtx_unlock(&sc->sc_mtx);
632 	printf("GEOM_MULTIPATH: %s added to %s\n",
633 	    pp->name, sc->sc_name);
634 	if (sc->sc_active == NULL) {
635 		sc->sc_active = cp;
636 		if (sc->sc_active_active != 1)
637 			printf("GEOM_MULTIPATH: %s is now active path in %s\n",
638 			    pp->name, sc->sc_name);
639 	}
640 	return (0);
641 }
642 
643 static int
644 g_multipath_destroy(struct g_geom *gp)
645 {
646 	struct g_multipath_softc *sc;
647 	struct g_consumer *cp, *cp1;
648 
649 	g_topology_assert();
650 	if (gp->softc == NULL)
651 		return (ENXIO);
652 	sc = gp->softc;
653 	if (!sc->sc_stopping) {
654 		printf("GEOM_MULTIPATH: destroying %s\n", gp->name);
655 		sc->sc_stopping = 1;
656 	}
657 	if (sc->sc_opened != 0) {
658 		g_wither_provider(sc->sc_pp, ENXIO);
659 		sc->sc_pp = NULL;
660 		return (EINPROGRESS);
661 	}
662 	LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) {
663 		mtx_lock(&sc->sc_mtx);
664 		if ((cp->index & MP_POSTED) == 0) {
665 			cp->index |= MP_POSTED;
666 			mtx_unlock(&sc->sc_mtx);
667 			g_mpd(cp, 0);
668 			if (cp1 == NULL)
669 				return(0);	/* Recursion happened. */
670 		} else
671 			mtx_unlock(&sc->sc_mtx);
672 	}
673 	if (!LIST_EMPTY(&gp->consumer))
674 		return (EINPROGRESS);
675 	mtx_destroy(&sc->sc_mtx);
676 	g_free(gp->softc);
677 	gp->softc = NULL;
678 	printf("GEOM_MULTIPATH: %s destroyed\n", gp->name);
679 	g_wither_geom(gp, ENXIO);
680 	return (0);
681 }
682 
683 static int
684 g_multipath_destroy_geom(struct gctl_req *req, struct g_class *mp,
685     struct g_geom *gp)
686 {
687 
688 	return (g_multipath_destroy(gp));
689 }
690 
691 static int
692 g_multipath_rotate(struct g_geom *gp)
693 {
694 	struct g_consumer *lcp, *first_good_cp = NULL;
695 	struct g_multipath_softc *sc = gp->softc;
696 	int active_cp_seen = 0;
697 
698 	g_topology_assert();
699 	if (sc == NULL)
700 		return (ENXIO);
701 	LIST_FOREACH(lcp, &gp->consumer, consumer) {
702 		if ((lcp->index & MP_BAD) == 0) {
703 			if (first_good_cp == NULL)
704 				first_good_cp = lcp;
705 			if (active_cp_seen)
706 				break;
707 		}
708 		if (sc->sc_active == lcp)
709 			active_cp_seen = 1;
710 	}
711 	if (lcp == NULL)
712 		lcp = first_good_cp;
713 	if (lcp && lcp != sc->sc_active) {
714 		sc->sc_active = lcp;
715 		if (sc->sc_active_active != 1)
716 			printf("GEOM_MULTIPATH: %s is now active path in %s\n",
717 			    lcp->provider->name, sc->sc_name);
718 	}
719 	return (0);
720 }
721 
722 static void
723 g_multipath_init(struct g_class *mp)
724 {
725 	bioq_init(&gmtbq);
726 	mtx_init(&gmtbq_mtx, "gmtbq", NULL, MTX_DEF);
727 	kproc_create(g_multipath_kt, mp, NULL, 0, 0, "g_mp_kt");
728 }
729 
730 static void
731 g_multipath_fini(struct g_class *mp)
732 {
733 	if (g_multipath_kt_state == GKT_RUN) {
734 		mtx_lock(&gmtbq_mtx);
735 		g_multipath_kt_state = GKT_DIE;
736 		wakeup(&g_multipath_kt_state);
737 		msleep(&g_multipath_kt_state, &gmtbq_mtx, PRIBIO,
738 		    "gmp:fini", 0);
739 		mtx_unlock(&gmtbq_mtx);
740 	}
741 }
742 
743 static int
744 g_multipath_read_metadata(struct g_consumer *cp,
745     struct g_multipath_metadata *md)
746 {
747 	struct g_provider *pp;
748 	u_char *buf;
749 	int error;
750 
751 	g_topology_assert();
752 	error = g_access(cp, 1, 0, 0);
753 	if (error != 0)
754 		return (error);
755 	pp = cp->provider;
756 	g_topology_unlock();
757 	buf = g_read_data(cp, pp->mediasize - pp->sectorsize,
758 	    pp->sectorsize, &error);
759 	g_topology_lock();
760 	g_access(cp, -1, 0, 0);
761 	if (buf == NULL)
762 		return (error);
763 	multipath_metadata_decode(buf, md);
764 	g_free(buf);
765 	return (0);
766 }
767 
768 static int
769 g_multipath_write_metadata(struct g_consumer *cp,
770     struct g_multipath_metadata *md)
771 {
772 	struct g_provider *pp;
773 	u_char *buf;
774 	int error;
775 
776 	g_topology_assert();
777 	error = g_access(cp, 1, 1, 1);
778 	if (error != 0)
779 		return (error);
780 	pp = cp->provider;
781 	g_topology_unlock();
782 	buf = g_malloc(pp->sectorsize, M_WAITOK | M_ZERO);
783 	multipath_metadata_encode(md, buf);
784 	error = g_write_data(cp, pp->mediasize - pp->sectorsize,
785 	    buf, pp->sectorsize);
786 	g_topology_lock();
787 	g_access(cp, -1, -1, -1);
788 	g_free(buf);
789 	return (error);
790 }
791 
792 static struct g_geom *
793 g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
794 {
795 	struct g_multipath_metadata md;
796 	struct g_multipath_softc *sc;
797 	struct g_consumer *cp;
798 	struct g_geom *gp, *gp1;
799 	int error, isnew;
800 
801 	g_topology_assert();
802 
803 	gp = g_new_geomf(mp, "multipath:taste");
804 	gp->start = g_multipath_start;
805 	gp->access = g_multipath_access;
806 	gp->orphan = g_multipath_orphan;
807 	cp = g_new_consumer(gp);
808 	g_attach(cp, pp);
809 	error = g_multipath_read_metadata(cp, &md);
810 	g_detach(cp);
811 	g_destroy_consumer(cp);
812 	g_destroy_geom(gp);
813 	if (error != 0)
814 		return (NULL);
815 	gp = NULL;
816 
817 	if (strcmp(md.md_magic, G_MULTIPATH_MAGIC) != 0) {
818 		if (g_multipath_debug)
819 			printf("%s is not MULTIPATH\n", pp->name);
820 		return (NULL);
821 	}
822 	if (md.md_version != G_MULTIPATH_VERSION) {
823 		printf("%s has version %d multipath id- this module is version "
824 		    " %d: rejecting\n", pp->name, md.md_version,
825 		    G_MULTIPATH_VERSION);
826 		return (NULL);
827 	}
828 	if (md.md_size != 0 && md.md_size != pp->mediasize)
829 		return (NULL);
830 	if (md.md_sectorsize != 0 && md.md_sectorsize != pp->sectorsize)
831 		return (NULL);
832 	if (g_multipath_debug)
833 		printf("MULTIPATH: %s/%s\n", md.md_name, md.md_uuid);
834 
835 	/*
836 	 * Let's check if such a device already is present. We check against
837 	 * uuid alone first because that's the true distinguishor. If that
838 	 * passes, then we check for name conflicts. If there are conflicts,
839 	 * modify the name.
840 	 *
841 	 * The whole purpose of this is to solve the problem that people don't
842 	 * pick good unique names, but good unique names (like uuids) are a
843 	 * pain to use. So, we allow people to build GEOMs with friendly names
844 	 * and uuids, and modify the names in case there's a collision.
845 	 */
846 	sc = NULL;
847 	LIST_FOREACH(gp, &mp->geom, geom) {
848 		sc = gp->softc;
849 		if (sc == NULL || sc->sc_stopping)
850 			continue;
851 		if (strncmp(md.md_uuid, sc->sc_uuid, sizeof(md.md_uuid)) == 0)
852 			break;
853 	}
854 
855 	LIST_FOREACH(gp1, &mp->geom, geom) {
856 		if (gp1 == gp)
857 			continue;
858 		sc = gp1->softc;
859 		if (sc == NULL || sc->sc_stopping)
860 			continue;
861 		if (strncmp(md.md_name, sc->sc_name, sizeof(md.md_name)) == 0)
862 			break;
863 	}
864 
865 	/*
866 	 * If gp is NULL, we had no extant MULTIPATH geom with this uuid.
867 	 *
868 	 * If gp1 is *not* NULL, that means we have a MULTIPATH geom extant
869 	 * with the same name (but a different UUID).
870 	 *
871 	 * If gp is NULL, then modify the name with a random number and
872   	 * complain, but allow the creation of the geom to continue.
873 	 *
874 	 * If gp is *not* NULL, just use the geom's name as we're attaching
875 	 * this disk to the (previously generated) name.
876 	 */
877 
878 	if (gp1) {
879 		sc = gp1->softc;
880 		if (gp == NULL) {
881 			char buf[16];
882 			u_long rand = random();
883 
884 			snprintf(buf, sizeof (buf), "%s-%lu", md.md_name, rand);
885 			printf("GEOM_MULTIPATH: geom %s/%s exists already\n",
886 			    sc->sc_name, sc->sc_uuid);
887 			printf("GEOM_MULTIPATH: %s will be (temporarily) %s\n",
888 			    md.md_uuid, buf);
889 			strlcpy(md.md_name, buf, sizeof(md.md_name));
890 		} else {
891 			strlcpy(md.md_name, sc->sc_name, sizeof(md.md_name));
892 		}
893 	}
894 
895 	if (gp == NULL) {
896 		gp = g_multipath_create(mp, &md);
897 		if (gp == NULL) {
898 			printf("GEOM_MULTIPATH: cannot create geom %s/%s\n",
899 			    md.md_name, md.md_uuid);
900 			return (NULL);
901 		}
902 		isnew = 1;
903 	} else {
904 		isnew = 0;
905 	}
906 
907 	sc = gp->softc;
908 	KASSERT(sc != NULL, ("sc is NULL"));
909 	error = g_multipath_add_disk(gp, pp);
910 	if (error != 0) {
911 		if (isnew)
912 			g_multipath_destroy(gp);
913 		return (NULL);
914 	}
915 	return (gp);
916 }
917 
918 static void
919 g_multipath_ctl_add_name(struct gctl_req *req, struct g_class *mp,
920     const char *name)
921 {
922 	struct g_multipath_softc *sc;
923 	struct g_geom *gp;
924 	struct g_consumer *cp;
925 	struct g_provider *pp;
926 	const char *mpname;
927 	static const char devpf[6] = "/dev/";
928 	int error;
929 
930 	g_topology_assert();
931 
932 	mpname = gctl_get_asciiparam(req, "arg0");
933         if (mpname == NULL) {
934                 gctl_error(req, "No 'arg0' argument");
935                 return;
936         }
937 	gp = g_multipath_find_geom(mp, mpname);
938 	if (gp == NULL) {
939 		gctl_error(req, "Device %s is invalid", mpname);
940 		return;
941 	}
942 	sc = gp->softc;
943 
944 	if (strncmp(name, devpf, 5) == 0)
945 		name += 5;
946 	pp = g_provider_by_name(name);
947 	if (pp == NULL) {
948 		gctl_error(req, "Provider %s is invalid", name);
949 		return;
950 	}
951 
952 	/*
953 	 * Check to make sure parameters match.
954 	 */
955 	LIST_FOREACH(cp, &gp->consumer, consumer) {
956 		if (cp->provider == pp) {
957 			gctl_error(req, "provider %s is already there",
958 			    pp->name);
959 			return;
960 		}
961 	}
962 	if (sc->sc_pp->mediasize != 0 &&
963 	    sc->sc_pp->mediasize + (sc->sc_uuid[0] != 0 ? pp->sectorsize : 0)
964 	     != pp->mediasize) {
965 		gctl_error(req, "Providers size mismatch %jd != %jd",
966 		    (intmax_t) sc->sc_pp->mediasize +
967 			(sc->sc_uuid[0] != 0 ? pp->sectorsize : 0),
968 		    (intmax_t) pp->mediasize);
969 		return;
970 	}
971 	if (sc->sc_pp->sectorsize != 0 &&
972 	    sc->sc_pp->sectorsize != pp->sectorsize) {
973 		gctl_error(req, "Providers sectorsize mismatch %u != %u",
974 		    sc->sc_pp->sectorsize, pp->sectorsize);
975 		return;
976 	}
977 
978 	error = g_multipath_add_disk(gp, pp);
979 	if (error != 0)
980 		gctl_error(req, "Provider addition error: %d", error);
981 }
982 
983 static void
984 g_multipath_ctl_prefer(struct gctl_req *req, struct g_class *mp)
985 {
986 	struct g_geom *gp;
987 	struct g_multipath_softc *sc;
988 	struct g_consumer *cp;
989 	const char *name, *mpname;
990 	static const char devpf[6] = "/dev/";
991 	int *nargs;
992 
993 	g_topology_assert();
994 
995 	mpname = gctl_get_asciiparam(req, "arg0");
996         if (mpname == NULL) {
997                 gctl_error(req, "No 'arg0' argument");
998                 return;
999         }
1000 	gp = g_multipath_find_geom(mp, mpname);
1001 	if (gp == NULL) {
1002 		gctl_error(req, "Device %s is invalid", mpname);
1003 		return;
1004 	}
1005 	sc = gp->softc;
1006 
1007 	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
1008 	if (nargs == NULL) {
1009 		gctl_error(req, "No 'nargs' argument");
1010 		return;
1011 	}
1012 	if (*nargs != 2) {
1013 		gctl_error(req, "missing device");
1014 		return;
1015 	}
1016 
1017 	name = gctl_get_asciiparam(req, "arg1");
1018 	if (name == NULL) {
1019 		gctl_error(req, "No 'arg1' argument");
1020 		return;
1021 	}
1022 	if (strncmp(name, devpf, 5) == 0) {
1023 		name += 5;
1024 	}
1025 
1026 	LIST_FOREACH(cp, &gp->consumer, consumer) {
1027 		if (cp->provider != NULL
1028                       && strcmp(cp->provider->name, name) == 0)
1029 		    break;
1030 	}
1031 
1032 	if (cp == NULL) {
1033 		gctl_error(req, "Provider %s not found", name);
1034 		return;
1035 	}
1036 
1037 	mtx_lock(&sc->sc_mtx);
1038 
1039 	if (cp->index & MP_BAD) {
1040 		gctl_error(req, "Consumer %s is invalid", name);
1041 		mtx_unlock(&sc->sc_mtx);
1042 		return;
1043 	}
1044 
1045 	/* Here when the consumer is present and in good shape */
1046 
1047 	sc->sc_active = cp;
1048 	if (!sc->sc_active_active)
1049 	    printf("GEOM_MULTIPATH: %s now active path in %s\n",
1050 		sc->sc_active->provider->name, sc->sc_name);
1051 
1052 	mtx_unlock(&sc->sc_mtx);
1053 }
1054 
1055 static void
1056 g_multipath_ctl_add(struct gctl_req *req, struct g_class *mp)
1057 {
1058 	struct g_multipath_softc *sc;
1059 	struct g_geom *gp;
1060 	const char *mpname, *name;
1061 
1062 	mpname = gctl_get_asciiparam(req, "arg0");
1063         if (mpname == NULL) {
1064                 gctl_error(req, "No 'arg0' argument");
1065                 return;
1066         }
1067 	gp = g_multipath_find_geom(mp, mpname);
1068 	if (gp == NULL) {
1069 		gctl_error(req, "Device %s not found", mpname);
1070 		return;
1071 	}
1072 	sc = gp->softc;
1073 
1074 	name = gctl_get_asciiparam(req, "arg1");
1075 	if (name == NULL) {
1076 		gctl_error(req, "No 'arg1' argument");
1077 		return;
1078 	}
1079 	g_multipath_ctl_add_name(req, mp, name);
1080 }
1081 
1082 static void
1083 g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp)
1084 {
1085 	struct g_multipath_metadata md;
1086 	struct g_multipath_softc *sc;
1087 	struct g_geom *gp;
1088 	const char *mpname, *name;
1089 	char param[16];
1090 	int *nargs, i, *val;
1091 
1092 	g_topology_assert();
1093 
1094 	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
1095 	if (*nargs < 2) {
1096 		gctl_error(req, "wrong number of arguments.");
1097 		return;
1098 	}
1099 
1100 	mpname = gctl_get_asciiparam(req, "arg0");
1101         if (mpname == NULL) {
1102                 gctl_error(req, "No 'arg0' argument");
1103                 return;
1104         }
1105 	gp = g_multipath_find_geom(mp, mpname);
1106 	if (gp != NULL) {
1107 		gctl_error(req, "Device %s already exist", mpname);
1108 		return;
1109 	}
1110 
1111 	memset(&md, 0, sizeof(md));
1112 	strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic));
1113 	md.md_version = G_MULTIPATH_VERSION;
1114 	strlcpy(md.md_name, mpname, sizeof(md.md_name));
1115 	md.md_size = 0;
1116 	md.md_sectorsize = 0;
1117 	md.md_uuid[0] = 0;
1118 	md.md_active_active = 0;
1119 	val = gctl_get_paraml(req, "active_active", sizeof(*val));
1120 	if (val != NULL && *val != 0)
1121 		md.md_active_active = 1;
1122 	val = gctl_get_paraml(req, "active_read", sizeof(*val));
1123 	if (val != NULL && *val != 0)
1124 		md.md_active_active = 2;
1125 	gp = g_multipath_create(mp, &md);
1126 	if (gp == NULL) {
1127 		gctl_error(req, "GEOM_MULTIPATH: cannot create geom %s/%s\n",
1128 		    md.md_name, md.md_uuid);
1129 		return;
1130 	}
1131 	sc = gp->softc;
1132 
1133 	for (i = 1; i < *nargs; i++) {
1134 		snprintf(param, sizeof(param), "arg%d", i);
1135 		name = gctl_get_asciiparam(req, param);
1136 		g_multipath_ctl_add_name(req, mp, name);
1137 	}
1138 
1139 	if (sc->sc_ndisks != (*nargs - 1))
1140 		g_multipath_destroy(gp);
1141 }
1142 
1143 static void
1144 g_multipath_ctl_configure(struct gctl_req *req, struct g_class *mp)
1145 {
1146 	struct g_multipath_softc *sc;
1147 	struct g_geom *gp;
1148 	struct g_consumer *cp;
1149 	struct g_provider *pp;
1150 	struct g_multipath_metadata md;
1151 	const char *name;
1152 	int error, *val;
1153 
1154 	g_topology_assert();
1155 
1156 	name = gctl_get_asciiparam(req, "arg0");
1157 	if (name == NULL) {
1158 		gctl_error(req, "No 'arg0' argument");
1159 		return;
1160 	}
1161 	gp = g_multipath_find_geom(mp, name);
1162 	if (gp == NULL) {
1163 		gctl_error(req, "Device %s is invalid", name);
1164 		return;
1165 	}
1166 	sc = gp->softc;
1167 	val = gctl_get_paraml(req, "active_active", sizeof(*val));
1168 	if (val != NULL && *val != 0)
1169 		sc->sc_active_active = 1;
1170 	val = gctl_get_paraml(req, "active_read", sizeof(*val));
1171 	if (val != NULL && *val != 0)
1172 		sc->sc_active_active = 2;
1173 	val = gctl_get_paraml(req, "active_passive", sizeof(*val));
1174 	if (val != NULL && *val != 0)
1175 		sc->sc_active_active = 0;
1176 	if (sc->sc_uuid[0] != 0 && sc->sc_active != NULL) {
1177 		cp = sc->sc_active;
1178 		pp = cp->provider;
1179 		strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic));
1180 		memcpy(md.md_uuid, sc->sc_uuid, sizeof (sc->sc_uuid));
1181 		strlcpy(md.md_name, name, sizeof(md.md_name));
1182 		md.md_version = G_MULTIPATH_VERSION;
1183 		md.md_size = pp->mediasize;
1184 		md.md_sectorsize = pp->sectorsize;
1185 		md.md_active_active = sc->sc_active_active;
1186 		error = g_multipath_write_metadata(cp, &md);
1187 		if (error != 0)
1188 			gctl_error(req, "Can't update metadata on %s (%d)",
1189 			    pp->name, error);
1190 	}
1191 }
1192 
1193 static void
1194 g_multipath_ctl_fail(struct gctl_req *req, struct g_class *mp, int fail)
1195 {
1196 	struct g_multipath_softc *sc;
1197 	struct g_geom *gp;
1198 	struct g_consumer *cp;
1199 	const char *mpname, *name;
1200 	int found;
1201 
1202 	mpname = gctl_get_asciiparam(req, "arg0");
1203         if (mpname == NULL) {
1204                 gctl_error(req, "No 'arg0' argument");
1205                 return;
1206         }
1207 	gp = g_multipath_find_geom(mp, mpname);
1208 	if (gp == NULL) {
1209 		gctl_error(req, "Device %s not found", mpname);
1210 		return;
1211 	}
1212 	sc = gp->softc;
1213 
1214 	name = gctl_get_asciiparam(req, "arg1");
1215 	if (name == NULL) {
1216 		gctl_error(req, "No 'arg1' argument");
1217 		return;
1218 	}
1219 
1220 	found = 0;
1221 	mtx_lock(&sc->sc_mtx);
1222 	LIST_FOREACH(cp, &gp->consumer, consumer) {
1223 		if (cp->provider != NULL &&
1224 		    strcmp(cp->provider->name, name) == 0 &&
1225 		    (cp->index & MP_LOST) == 0) {
1226 			found = 1;
1227 			if (!fail == !(cp->index & MP_FAIL))
1228 				continue;
1229 			printf("GEOM_MULTIPATH: %s in %s is marked %s.\n",
1230 				name, sc->sc_name, fail ? "FAIL" : "OK");
1231 			if (fail) {
1232 				g_multipath_fault(cp, MP_FAIL);
1233 			} else {
1234 				cp->index &= ~MP_FAIL;
1235 			}
1236 		}
1237 	}
1238 	mtx_unlock(&sc->sc_mtx);
1239 	if (found == 0)
1240 		gctl_error(req, "Provider %s not found", name);
1241 }
1242 
1243 static void
1244 g_multipath_ctl_remove(struct gctl_req *req, struct g_class *mp)
1245 {
1246 	struct g_multipath_softc *sc;
1247 	struct g_geom *gp;
1248 	struct g_consumer *cp, *cp1;
1249 	const char *mpname, *name;
1250 	uintptr_t *cnt;
1251 	int found;
1252 
1253 	mpname = gctl_get_asciiparam(req, "arg0");
1254         if (mpname == NULL) {
1255                 gctl_error(req, "No 'arg0' argument");
1256                 return;
1257         }
1258 	gp = g_multipath_find_geom(mp, mpname);
1259 	if (gp == NULL) {
1260 		gctl_error(req, "Device %s not found", mpname);
1261 		return;
1262 	}
1263 	sc = gp->softc;
1264 
1265 	name = gctl_get_asciiparam(req, "arg1");
1266 	if (name == NULL) {
1267 		gctl_error(req, "No 'arg1' argument");
1268 		return;
1269 	}
1270 
1271 	found = 0;
1272 	mtx_lock(&sc->sc_mtx);
1273 	LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) {
1274 		if (cp->provider != NULL &&
1275 		    strcmp(cp->provider->name, name) == 0 &&
1276 		    (cp->index & MP_LOST) == 0) {
1277 			found = 1;
1278 			printf("GEOM_MULTIPATH: removing %s from %s\n",
1279 			    cp->provider->name, cp->geom->name);
1280 			sc->sc_ndisks--;
1281 			g_multipath_fault(cp, MP_LOST);
1282 			cnt = (uintptr_t *)&cp->private;
1283 			if (*cnt == 0 && (cp->index & MP_POSTED) == 0) {
1284 				cp->index |= MP_POSTED;
1285 				mtx_unlock(&sc->sc_mtx);
1286 				g_mpd(cp, 0);
1287 				if (cp1 == NULL)
1288 					return;	/* Recursion happened. */
1289 				mtx_lock(&sc->sc_mtx);
1290 			}
1291 		}
1292 	}
1293 	mtx_unlock(&sc->sc_mtx);
1294 	if (found == 0)
1295 		gctl_error(req, "Provider %s not found", name);
1296 }
1297 
1298 static struct g_geom *
1299 g_multipath_find_geom(struct g_class *mp, const char *name)
1300 {
1301 	struct g_geom *gp;
1302 	struct g_multipath_softc *sc;
1303 
1304 	LIST_FOREACH(gp, &mp->geom, geom) {
1305 		sc = gp->softc;
1306 		if (sc == NULL || sc->sc_stopping)
1307 			continue;
1308 		if (strcmp(gp->name, name) == 0)
1309 			return (gp);
1310 	}
1311 	return (NULL);
1312 }
1313 
1314 static void
1315 g_multipath_ctl_stop(struct gctl_req *req, struct g_class *mp)
1316 {
1317 	struct g_geom *gp;
1318 	const char *name;
1319 	int error;
1320 
1321 	g_topology_assert();
1322 
1323 	name = gctl_get_asciiparam(req, "arg0");
1324         if (name == NULL) {
1325                 gctl_error(req, "No 'arg0' argument");
1326                 return;
1327         }
1328 	gp = g_multipath_find_geom(mp, name);
1329 	if (gp == NULL) {
1330 		gctl_error(req, "Device %s is invalid", name);
1331 		return;
1332 	}
1333 	error = g_multipath_destroy(gp);
1334 	if (error != 0 && error != EINPROGRESS)
1335 		gctl_error(req, "failed to stop %s (err=%d)", name, error);
1336 }
1337 
1338 static void
1339 g_multipath_ctl_destroy(struct gctl_req *req, struct g_class *mp)
1340 {
1341 	struct g_geom *gp;
1342 	struct g_multipath_softc *sc;
1343 	struct g_consumer *cp;
1344 	struct g_provider *pp;
1345 	const char *name;
1346 	uint8_t *buf;
1347 	int error;
1348 
1349 	g_topology_assert();
1350 
1351 	name = gctl_get_asciiparam(req, "arg0");
1352         if (name == NULL) {
1353                 gctl_error(req, "No 'arg0' argument");
1354                 return;
1355         }
1356 	gp = g_multipath_find_geom(mp, name);
1357 	if (gp == NULL) {
1358 		gctl_error(req, "Device %s is invalid", name);
1359 		return;
1360 	}
1361 	sc = gp->softc;
1362 
1363 	if (sc->sc_uuid[0] != 0 && sc->sc_active != NULL) {
1364 		cp = sc->sc_active;
1365 		pp = cp->provider;
1366 		error = g_access(cp, 1, 1, 1);
1367 		if (error != 0) {
1368 			gctl_error(req, "Can't open %s (%d)", pp->name, error);
1369 			goto destroy;
1370 		}
1371 		g_topology_unlock();
1372 		buf = g_malloc(pp->sectorsize, M_WAITOK | M_ZERO);
1373 		error = g_write_data(cp, pp->mediasize - pp->sectorsize,
1374 		    buf, pp->sectorsize);
1375 		g_topology_lock();
1376 		g_access(cp, -1, -1, -1);
1377 		if (error != 0)
1378 			gctl_error(req, "Can't erase metadata on %s (%d)",
1379 			    pp->name, error);
1380 	}
1381 
1382 destroy:
1383 	error = g_multipath_destroy(gp);
1384 	if (error != 0 && error != EINPROGRESS)
1385 		gctl_error(req, "failed to destroy %s (err=%d)", name, error);
1386 }
1387 
1388 static void
1389 g_multipath_ctl_rotate(struct gctl_req *req, struct g_class *mp)
1390 {
1391 	struct g_geom *gp;
1392 	const char *name;
1393 	int error;
1394 
1395 	g_topology_assert();
1396 
1397 	name = gctl_get_asciiparam(req, "arg0");
1398         if (name == NULL) {
1399                 gctl_error(req, "No 'arg0' argument");
1400                 return;
1401         }
1402 	gp = g_multipath_find_geom(mp, name);
1403 	if (gp == NULL) {
1404 		gctl_error(req, "Device %s is invalid", name);
1405 		return;
1406 	}
1407 	error = g_multipath_rotate(gp);
1408 	if (error != 0) {
1409 		gctl_error(req, "failed to rotate %s (err=%d)", name, error);
1410 	}
1411 }
1412 
1413 static void
1414 g_multipath_ctl_getactive(struct gctl_req *req, struct g_class *mp)
1415 {
1416 	struct sbuf *sb;
1417 	struct g_geom *gp;
1418 	struct g_multipath_softc *sc;
1419 	struct g_consumer *cp;
1420 	const char *name;
1421 	int empty;
1422 
1423 	sb = sbuf_new_auto();
1424 
1425 	g_topology_assert();
1426 	name = gctl_get_asciiparam(req, "arg0");
1427         if (name == NULL) {
1428                 gctl_error(req, "No 'arg0' argument");
1429                 return;
1430         }
1431 	gp = g_multipath_find_geom(mp, name);
1432 	if (gp == NULL) {
1433 		gctl_error(req, "Device %s is invalid", name);
1434 		return;
1435 	}
1436 	sc = gp->softc;
1437 	if (sc->sc_active_active == 1) {
1438 		empty = 1;
1439 		LIST_FOREACH(cp, &gp->consumer, consumer) {
1440 			if (cp->index & MP_BAD)
1441 				continue;
1442 			if (!empty)
1443 				sbuf_cat(sb, " ");
1444 			sbuf_cat(sb, cp->provider->name);
1445 			empty = 0;
1446 		}
1447 		if (empty)
1448 			sbuf_cat(sb, "none");
1449 		sbuf_cat(sb, "\n");
1450 	} else if (sc->sc_active && sc->sc_active->provider) {
1451 		sbuf_printf(sb, "%s\n", sc->sc_active->provider->name);
1452 	} else {
1453 		sbuf_printf(sb, "none\n");
1454 	}
1455 	sbuf_finish(sb);
1456 	gctl_set_param_err(req, "output", sbuf_data(sb), sbuf_len(sb) + 1);
1457 	sbuf_delete(sb);
1458 }
1459 
1460 static void
1461 g_multipath_config(struct gctl_req *req, struct g_class *mp, const char *verb)
1462 {
1463 	uint32_t *version;
1464 	g_topology_assert();
1465 	version = gctl_get_paraml(req, "version", sizeof(*version));
1466 	if (version == NULL) {
1467 		gctl_error(req, "No 'version' argument");
1468 	} else if (*version != G_MULTIPATH_VERSION) {
1469 		gctl_error(req, "Userland and kernel parts are out of sync");
1470 	} else if (strcmp(verb, "add") == 0) {
1471 		g_multipath_ctl_add(req, mp);
1472 	} else if (strcmp(verb, "prefer") == 0) {
1473 		g_multipath_ctl_prefer(req, mp);
1474 	} else if (strcmp(verb, "create") == 0) {
1475 		g_multipath_ctl_create(req, mp);
1476 	} else if (strcmp(verb, "configure") == 0) {
1477 		g_multipath_ctl_configure(req, mp);
1478 	} else if (strcmp(verb, "stop") == 0) {
1479 		g_multipath_ctl_stop(req, mp);
1480 	} else if (strcmp(verb, "destroy") == 0) {
1481 		g_multipath_ctl_destroy(req, mp);
1482 	} else if (strcmp(verb, "fail") == 0) {
1483 		g_multipath_ctl_fail(req, mp, 1);
1484 	} else if (strcmp(verb, "restore") == 0) {
1485 		g_multipath_ctl_fail(req, mp, 0);
1486 	} else if (strcmp(verb, "remove") == 0) {
1487 		g_multipath_ctl_remove(req, mp);
1488 	} else if (strcmp(verb, "rotate") == 0) {
1489 		g_multipath_ctl_rotate(req, mp);
1490 	} else if (strcmp(verb, "getactive") == 0) {
1491 		g_multipath_ctl_getactive(req, mp);
1492 	} else {
1493 		gctl_error(req, "Unknown verb %s", verb);
1494 	}
1495 }
1496 
1497 static void
1498 g_multipath_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
1499     struct g_consumer *cp, struct g_provider *pp)
1500 {
1501 	struct g_multipath_softc *sc;
1502 	int good;
1503 
1504 	g_topology_assert();
1505 
1506 	sc = gp->softc;
1507 	if (sc == NULL)
1508 		return;
1509 	if (cp != NULL) {
1510 		sbuf_printf(sb, "%s<State>%s</State>\n", indent,
1511 		    (cp->index & MP_NEW) ? "NEW" :
1512 		    (cp->index & MP_LOST) ? "LOST" :
1513 		    (cp->index & MP_FAIL) ? "FAIL" :
1514 		    (sc->sc_active_active == 1 || sc->sc_active == cp) ?
1515 		     "ACTIVE" :
1516 		     sc->sc_active_active == 2 ? "READ" : "PASSIVE");
1517 	} else {
1518 		good = g_multipath_good(gp);
1519 		sbuf_printf(sb, "%s<State>%s</State>\n", indent,
1520 		    good == 0 ? "BROKEN" :
1521 		    (good != sc->sc_ndisks || sc->sc_ndisks == 1) ?
1522 		    "DEGRADED" : "OPTIMAL");
1523 	}
1524 	if (cp == NULL && pp == NULL) {
1525 		sbuf_printf(sb, "%s<UUID>%s</UUID>\n", indent, sc->sc_uuid);
1526 		sbuf_printf(sb, "%s<Mode>Active/%s</Mode>\n", indent,
1527 		    sc->sc_active_active == 2 ? "Read" :
1528 		    sc->sc_active_active == 1 ? "Active" : "Passive");
1529 		sbuf_printf(sb, "%s<Type>%s</Type>\n", indent,
1530 		    sc->sc_uuid[0] == 0 ? "MANUAL" : "AUTOMATIC");
1531 	}
1532 }
1533 
1534 DECLARE_GEOM_CLASS(g_multipath_class, g_multipath);
1535 MODULE_VERSION(geom_multipath, 0);
1536