xref: /titanic_41/usr/src/lib/lvm/libmeta/common/metagetroot.c (revision d7cd82522afdd890a66c7600b499590ad44e84bd)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * get root device
31  */
32 
33 #include <meta.h>
34 #include "meta_lib_prv.h"
35 
36 #include <sys/mnttab.h>
37 
38 /*
39  * Return the current root filesystem block device name
40  */
41 void *
meta_get_current_root(md_error_t * ep)42 meta_get_current_root(
43 	md_error_t	*ep
44 )
45 {
46 	FILE		*fp;
47 	struct mnttab	mp;
48 
49 	if ((fp = open_mnttab()) == NULL) {
50 		(void) mdsyserror(ep, errno, MNTTAB);
51 		return (NULL);
52 	}
53 
54 	while (getmntent(fp, &mp) == 0) {
55 	if (strcmp(mp.mnt_mountp, "/") == 0)
56 		return (mp.mnt_special);
57 	}
58 	(void) mderror(ep, MDE_NOROOT, NULL);
59 	return (NULL);
60 }
61 
62 /*
63  * Return the current root filesystem block device name. This is only valid
64  * when root is either a slice, a stripe or a mirror.
65  */
66 mdname_t *
meta_get_current_root_dev(mdsetname_t * sp,md_error_t * ep)67 meta_get_current_root_dev(
68 	mdsetname_t	*sp,
69 	md_error_t	*ep
70 )
71 {
72 	md_stripe_t	*stripep;
73 	md_mirror_t	*mirrorp;
74 	md_row_t	*rp;
75 	md_comp_t	*cp;
76 	mdname_t	*rootnp;
77 	void		*curroot;
78 	char		*miscname;
79 	int		smi;
80 
81 	if ((curroot = meta_get_current_root(ep)) == NULL)
82 		return (NULL);
83 	if ((rootnp = metaname(&sp, curroot, UNKNOWN, ep)) == NULL)
84 		return (NULL);
85 	if (metaismeta(rootnp)) {
86 		if ((miscname = metagetmiscname(rootnp, ep)) == NULL)
87 			return (NULL);
88 		if ((strcmp(miscname, MD_MIRROR) == 0) &&
89 		    ((mirrorp = meta_get_mirror(sp, rootnp, ep)) != NULL)) {
90 			for (smi = 0; smi < NMIRROR; smi++) {
91 				md_submirror_t *mdsp =
92 				    &mirrorp->submirrors[smi];
93 				rootnp = mdsp->submirnamep;
94 				/* skip unused submirrors */
95 				if (rootnp == NULL) {
96 					assert(mdsp->state == SMS_UNUSED);
97 					continue;
98 				}
99 				if ((miscname = metagetmiscname(rootnp, ep))
100 				    == NULL) {
101 					(void) mdmderror(ep, MDE_UNKNOWN_TYPE,
102 					    meta_getminor(rootnp->dev),
103 					    rootnp->cname);
104 					return (NULL);
105 				}
106 				break;
107 			}
108 		}
109 		if ((strcmp(miscname, MD_STRIPE) == 0) &&
110 		    ((stripep = meta_get_stripe(sp, rootnp, ep)) != NULL)) {
111 			rp = &stripep->rows.rows_val[0];
112 			cp = &rp->comps.comps_val[0];
113 			if (metachkcomp(cp->compnamep, ep) == 0)
114 				return (cp->compnamep);
115 		}
116 		/* Root is not a single stripe metadevice */
117 		(void) mddeverror(ep, MDE_INV_ROOT, rootnp->dev, rootnp->cname);
118 		return (NULL);
119 	} else return (rootnp);
120 }
121