xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_patch_root.c (revision 2063:a6ebd483c3cf)
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  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * patch /etc/system file for the root device
30  */
31 
32 #include <dlfcn.h>
33 #include <meta.h>
34 
35 
36 /*
37  * set root device name in md.conf and vfstab, patch in mddb locations
38  */
39 int
meta_patch_rootdev(mdname_t * rootnp,char * sname,char * vname,char * cname,char * dbname,int doit,int verbose,md_error_t * ep)40 meta_patch_rootdev(
41 	mdname_t	*rootnp,	/* root device */
42 	char		*sname,		/* system file name */
43 	char		*vname,		/* vfstab file name */
44 	char		*cname,		/* mddb.cf file name */
45 	char		*dbname,	/* md.conf file name */
46 	int		doit,		/* really patch files */
47 	int		verbose,	/* show what we're doing */
48 	md_error_t	*ep		/* returned error */
49 )
50 {
51 	mdsetname_t	*sp;
52 	int		ismeta = metaismeta(rootnp);
53 	char		*tsname = NULL;
54 	FILE		*tsfp = NULL;
55 	char		*dbtname = NULL;
56 	FILE		*dbtfp = NULL;
57 	char		*tvname = NULL;
58 	int		rval = -1;
59 
60 	/* check names */
61 	if (sname == NULL)
62 		sname = "/etc/system";
63 	if (vname == NULL)
64 		vname = "/etc/vfstab";
65 	if (cname == NULL)
66 		cname = META_DBCONF;
67 	if (dbname == NULL)
68 		dbname = "/kernel/drv/md.conf";
69 
70 	/* make sure we have a local name */
71 	if ((sp = metagetset(rootnp, TRUE, ep)) == NULL)
72 		return (-1);
73 
74 	if (! metaislocalset(sp)) {
75 		return (mddeverror(ep, MDE_NOT_LOCAL, rootnp->dev,
76 		    rootnp->cname));
77 	}
78 
79 	/* replace forceload and rootdev lines in system */
80 	if (meta_systemfile_copy(sname, 1, 0, doit, verbose, &tsname, &tsfp,
81 	    ep) != 0) {
82 		goto out;
83 	}
84 	if (meta_systemfile_append_mdroot(rootnp, sname,
85 	    tsname, tsfp, ismeta, doit, verbose, ep) != 0) {
86 		goto out;
87 	}
88 
89 	/* replace bootlist lines in /kernel/drv/md.conf */
90 	if (meta_systemfile_copy(dbname, 0, 1, doit, verbose, &dbtname,
91 	    &dbtfp, ep) != 0) {
92 		goto out;
93 	}
94 	if (meta_systemfile_append_mddb(cname, dbname, dbtname, dbtfp, doit,
95 	    verbose, 1, ep) != 0) {
96 		goto out;
97 	}
98 
99 	/* force the file contents out to disk */
100 	if (doit) {
101 		if ((fflush(tsfp) != 0) ||
102 		    (fsync(fileno(tsfp)) != 0) ||
103 		    (fclose(tsfp) != 0)) {
104 			(void) mdsyserror(ep, errno, tsname);
105 			goto out;
106 		}
107 		tsfp = NULL;
108 		if ((fflush(dbtfp) != 0) ||
109 		    (fsync(fileno(dbtfp)) != 0) ||
110 		    (fclose(dbtfp) != 0)) {
111 			(void) mdsyserror(ep, errno, dbtname);
112 			goto out;
113 		}
114 		dbtfp = NULL;
115 	}
116 
117 	/* replace lines in vfstab */
118 	if (meta_patch_vfstab("/", rootnp, vname, NULL, doit, verbose, &tvname,
119 	    ep) != 0) {
120 		goto out;
121 	}
122 
123 	/* rename files, better hope both work */
124 	if (doit) {
125 		if (rename(tsname, sname) != 0) {
126 			(void) mdsyserror(ep, errno, sname);
127 			goto out;
128 		}
129 		Free(tsname);
130 		tsname = NULL;
131 		if (rename(dbtname, dbname) != 0) {
132 			(void) mdsyserror(ep, errno, dbname);
133 			goto out;
134 		}
135 		Free(dbtname);
136 		dbtname = NULL;
137 		if (rename(tvname, vname) != 0) {
138 			(void) mdsyserror(ep, errno, vname);
139 			goto out;
140 		}
141 		Free(tvname);
142 		tvname = NULL;
143 	}
144 	rval = 0;
145 
146 	/* cleanup, return error */
147 out:
148 	if (tsfp != NULL)
149 		(void) fclose(tsfp);
150 	if (tsname != NULL) {
151 		if (doit)
152 			(void) unlink(tsname);
153 		Free(tsname);
154 	}
155 	if (tvname != NULL) {
156 		if (doit)
157 			(void) unlink(tvname);
158 		Free(tvname);
159 	}
160 
161 	/* free the temporary files for md.conf */
162 	if (dbtfp != NULL)
163 		(void) fclose(dbtfp);
164 	if (dbtname != NULL) {
165 		if (doit)
166 			(void) unlink(dbtname);
167 		Free(dbtname);
168 	}
169 	return (rval);
170 }
171