1789Sahrens /*
2789Sahrens * CDDL HEADER START
3789Sahrens *
4789Sahrens * The contents of this file are subject to the terms of the
51544Seschrock * Common Development and Distribution License (the "License").
61544Seschrock * You may not use this file except in compliance with the License.
7789Sahrens *
8789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9789Sahrens * or http://www.opensolaris.org/os/licensing.
10789Sahrens * See the License for the specific language governing permissions
11789Sahrens * and limitations under the License.
12789Sahrens *
13789Sahrens * When distributing Covered Code, include this CDDL HEADER in each
14789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15789Sahrens * If applicable, add the following below this CDDL HEADER, with the
16789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying
17789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner]
18789Sahrens *
19789Sahrens * CDDL HEADER END
20789Sahrens */
21789Sahrens /*
22*11958SGeorge.Wilson@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23789Sahrens * Use is subject to license terms.
24789Sahrens */
25789Sahrens
26789Sahrens #include <sys/zfs_context.h>
27789Sahrens #include <sys/spa.h>
28789Sahrens #include <sys/vdev_impl.h>
29789Sahrens #include <sys/zio.h>
30789Sahrens #include <sys/fs/zfs.h>
31789Sahrens
32789Sahrens /*
33789Sahrens * Virtual device vector for the pool's root vdev.
34789Sahrens */
35789Sahrens
361775Sbillm /*
371775Sbillm * We should be able to tolerate one failure with absolutely no damage
381775Sbillm * to our metadata. Two failures will take out space maps, a bunch of
391775Sbillm * indirect block trees, meta dnodes, dnodes, etc. Probably not a happy
401775Sbillm * place to live. When we get smarter, we can liberalize this policy.
411775Sbillm * e.g. If we haven't lost two consecutive top-level vdevs, then we are
421775Sbillm * probably fine. Adding bean counters during alloc/free can make this
431775Sbillm * future guesswork more accurate.
441775Sbillm */
451775Sbillm static int
too_many_errors(vdev_t * vd,int numerrors)461775Sbillm too_many_errors(vdev_t *vd, int numerrors)
471775Sbillm {
485329Sgw25295 ASSERT3U(numerrors, <=, vd->vdev_children);
496976Seschrock return (numerrors > 0);
501775Sbillm }
511775Sbillm
52789Sahrens static int
vdev_root_open(vdev_t * vd,uint64_t * asize,uint64_t * ashift)53789Sahrens vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
54789Sahrens {
55789Sahrens int lasterror = 0;
561775Sbillm int numerrors = 0;
57789Sahrens
58789Sahrens if (vd->vdev_children == 0) {
59789Sahrens vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
60789Sahrens return (EINVAL);
61789Sahrens }
62789Sahrens
639846SEric.Taylor@Sun.COM vdev_open_children(vd);
64789Sahrens
659846SEric.Taylor@Sun.COM for (int c = 0; c < vd->vdev_children; c++) {
669846SEric.Taylor@Sun.COM vdev_t *cvd = vd->vdev_child[c];
679846SEric.Taylor@Sun.COM
689846SEric.Taylor@Sun.COM if (cvd->vdev_open_error && !cvd->vdev_islog) {
699846SEric.Taylor@Sun.COM lasterror = cvd->vdev_open_error;
701775Sbillm numerrors++;
71789Sahrens }
72789Sahrens }
73789Sahrens
746976Seschrock if (too_many_errors(vd, numerrors)) {
756976Seschrock vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS;
766976Seschrock return (lasterror);
771775Sbillm }
78789Sahrens
791732Sbonwick *asize = 0;
801732Sbonwick *ashift = 0;
811732Sbonwick
821775Sbillm return (0);
83789Sahrens }
84789Sahrens
85789Sahrens static void
vdev_root_close(vdev_t * vd)86789Sahrens vdev_root_close(vdev_t *vd)
87789Sahrens {
889846SEric.Taylor@Sun.COM for (int c = 0; c < vd->vdev_children; c++)
89789Sahrens vdev_close(vd->vdev_child[c]);
90789Sahrens }
91789Sahrens
92789Sahrens static void
vdev_root_state_change(vdev_t * vd,int faulted,int degraded)93789Sahrens vdev_root_state_change(vdev_t *vd, int faulted, int degraded)
94789Sahrens {
956976Seschrock if (too_many_errors(vd, faulted)) {
966976Seschrock vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
976976Seschrock VDEV_AUX_NO_REPLICAS);
985329Sgw25295 } else if (degraded) {
991544Seschrock vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_NONE);
1005329Sgw25295 } else {
1011544Seschrock vdev_set_state(vd, B_FALSE, VDEV_STATE_HEALTHY, VDEV_AUX_NONE);
1025329Sgw25295 }
103789Sahrens }
104789Sahrens
105789Sahrens vdev_ops_t vdev_root_ops = {
106789Sahrens vdev_root_open,
107789Sahrens vdev_root_close,
108789Sahrens vdev_default_asize,
109789Sahrens NULL, /* io_start - not applicable to the root */
110789Sahrens NULL, /* io_done - not applicable to the root */
111789Sahrens vdev_root_state_change,
112*11958SGeorge.Wilson@Sun.COM NULL,
113*11958SGeorge.Wilson@Sun.COM NULL,
114789Sahrens VDEV_TYPE_ROOT, /* name of this vdev type */
115789Sahrens B_FALSE /* not a leaf vdev */
116789Sahrens };
117