xref: /titanic_41/usr/src/lib/lvm/libmeta/common/meta_mdcf.c (revision 69bb4bb45c98da60d21839c4dc3c01ea1be60585)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 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 /*
31  * Just in case we're not in a build environment, make sure that
32  * TEXT_DOMAIN gets set to something.
33  */
34 #if !defined(TEXT_DOMAIN)
35 #define	TEXT_DOMAIN "SYS_TEST"
36 #endif
37 
38 /*
39  * patch md.cf file
40  */
41 
42 #include <meta.h>
43 
44 /*
45  * save metadevice configuration in md.cf
46  */
47 int
48 meta_update_md_cf(
49 	mdsetname_t	*sp,
50 	md_error_t	*ep
51 )
52 {
53 	char		*name = METACONF;
54 	char		*tname = METACONFTMP;
55 	FILE		*tfp = NULL;
56 	FILE		*mfp = NULL;
57 	mdprtopts_t	options = PRINT_SHORT | PRINT_FAST;
58 	struct stat	sbuf;
59 	char		line[1000];
60 
61 	/* If this is not the local set, no need to do anything */
62 	if (!metaislocalset(sp))
63 		return (0);
64 
65 	/* open temp file */
66 	if ((tfp = fopen(tname, "w")) == NULL)
67 		return (mdsyserror(ep, errno, tname));
68 	if (stat(name, &sbuf) == 0) {
69 		(void) fchmod(fileno(tfp), (sbuf.st_mode & 0777));
70 		(void) fchown(fileno(tfp), sbuf.st_uid, sbuf.st_gid);
71 	}
72 
73 	/* dump header */
74 	if (fputs(dgettext(TEXT_DOMAIN,
75 	    "# metadevice configuration file\n"
76 	    "# do not hand edit\n"), tfp) == EOF) {
77 		(void) mdsyserror(ep, errno, tname);
78 		goto errout;
79 	}
80 
81 	/* dump device configuration */
82 	if (meta_print_all(sp, tname, NULL, tfp, options, NULL, ep) != 0)
83 		goto errout;
84 
85 	/* close and rename file */
86 	if (fclose(tfp) != 0) {
87 		(void) mdsyserror(ep, errno, tname);
88 		goto errout;
89 	}
90 	tfp = NULL;
91 
92 	/*
93 	 * Renames don't work in the miniroot since tmpfiles are
94 	 * created in /var/tmp. Hence we copy the data out.
95 	 */
96 
97 	if (rename(tname, name) != 0) {
98 		if (errno == EROFS) {
99 			if ((tfp = fopen(tname, "r")) == NULL) {
100 				goto errout;
101 			}
102 			if ((mfp = fopen(METACONF, "w+")) == NULL) {
103 				goto errout;
104 			}
105 			while (fgets(line, 1000, tfp) != NULL) {
106 				if (fputs(line, mfp) == NULL) {
107 					(void) mdsyserror(ep, errno, METACONF);
108 					goto errout;
109 				}
110 			}
111 			if (fclose(tfp) != 0) {
112 				tfp = NULL;
113 				goto errout;
114 			}
115 			tfp = NULL;
116 			/* delete the tempfile */
117 			(void) unlink(tname);
118 			if (fflush(mfp) != 0) {
119 				goto errout;
120 			}
121 			if (fsync(fileno(mfp)) != 0) {
122 				goto errout;
123 			}
124 			if (fclose(mfp) != 0) {
125 				mfp = NULL;
126 				goto errout;
127 			}
128 			mfp = NULL;
129 		} else {
130 			(void) mdsyserror(ep, errno, name);
131 			goto errout;
132 		}
133 	}
134 
135 	/* success */
136 	return (0);
137 
138 	/* cleanup, return error */
139 errout:
140 	if (tfp != NULL) {
141 		(void) fclose(tfp);
142 		(void) unlink(tname);
143 	}
144 	if (mfp != NULL) {
145 		(void) fclose(mfp);
146 	}
147 	return (-1);
148 }
149