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 2003 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 * Just in case we're not in a build environment, make sure that
31 * TEXT_DOMAIN gets set to something.
32 */
33 #if !defined(TEXT_DOMAIN)
34 #define TEXT_DOMAIN "SYS_TEST"
35 #endif
36
37 /*
38 * patch /etc/vfstab file
39 */
40 #include <meta.h>
41 #include <string.h>
42
43 /*
44 * patch filesystem lines into vfstab file, return tempfilename
45 */
46 int
meta_patch_vfstab(char * cmpname,mdname_t * fsnp,char * vname,char * old_bdevname,int doit,int verbose,char ** tname,md_error_t * ep)47 meta_patch_vfstab(
48 char *cmpname, /* filesystem mount point or */
49 /* "swap" if updating swap partition */
50 mdname_t *fsnp, /* filesystem device name */
51 char *vname, /* vfstab file name */
52 char *old_bdevname, /* old name of block device, needed */
53 /* for deciding which of multiple */
54 /* swap file entries to change */
55 /* if NULL then not changing swap */
56 int doit, /* really patch file */
57 int verbose, /* show what we're doing */
58 char **tname, /* returned temp file name */
59 md_error_t *ep /* returned error */
60 )
61 {
62 char *chrname = fsnp->rname;
63 char *blkname = fsnp->bname;
64 FILE *fp = NULL;
65 FILE *tfp = NULL;
66 struct stat sbuf;
67 char buf[512];
68 char cdev[512];
69 char bdev[512];
70 char mntpt[512];
71 char fstype[512];
72 char fsckpass[512];
73 char mntboot[512];
74 char mntopt[512];
75 int gotfs = 0;
76 char *cmpstr = &mntpt[0]; /* compare against mntpnt if fs, */
77 /* or fstype if swap */
78 char *char_device = chrname;
79
80 /* check names */
81 assert(vname != NULL);
82 assert(tname != NULL);
83
84 /* get temp names */
85 *tname = NULL;
86 *tname = Malloc(strlen(vname) + strlen(".tmp") + 1);
87 (void) strcpy(*tname, vname);
88 (void) strcat(*tname, ".tmp");
89
90 /* check if going to update swap entry in file */
91 /* if so then compare against file system type */
92 if ((old_bdevname != NULL) && (strcmp("swap", cmpname) == 0)) {
93 cmpstr = &fstype[0];
94 char_device = &cdev[0];
95 }
96
97 /* copy vfstab file, replace filesystem line */
98 if ((fp = fopen(vname, "r")) == NULL) {
99 (void) mdsyserror(ep, errno, vname);
100 goto out;
101 }
102 if (fstat(fileno(fp), &sbuf) != 0) {
103 (void) mdsyserror(ep, errno, vname);
104 goto out;
105 }
106 if (doit) {
107 if ((tfp = fopen(*tname, "w")) == NULL) {
108 (void) mdsyserror(ep, errno, *tname);
109 goto out;
110 }
111 if (fchmod(fileno(tfp), (sbuf.st_mode & 0777)) != 0) {
112 (void) mdsyserror(ep, errno, *tname);
113 goto out;
114 }
115 if (fchown(fileno(tfp), sbuf.st_uid, sbuf.st_gid) != 0) {
116 (void) mdsyserror(ep, errno, *tname);
117 goto out;
118 }
119 }
120 while (fgets(buf, sizeof (buf), fp) != NULL) {
121
122 /* check that have all required params from vfstab file */
123 /* or that the line isnt a comment */
124 /* or that the fstype/mntpoint match what was passed in */
125 /* or that the block device matches if changing swap */
126 /* the last check is needed since there may be multiple */
127 /* entries of swap in the file, and so the fstype is not */
128 /* a sufficient check */
129 if ((sscanf(buf, "%512s %512s %512s %512s %512s %512s %512s",
130 bdev, cdev, mntpt, fstype, fsckpass,
131 mntboot, mntopt) != 7) ||
132 (bdev[0] == '#') || (strcmp(cmpstr, cmpname) != 0) ||
133 ((old_bdevname != NULL) &&
134 (strstr(bdev, old_bdevname) == NULL))) {
135 if (doit) {
136 if (fputs(buf, tfp) == EOF) {
137 (void) mdsyserror(ep, errno, *tname);
138 goto out;
139 }
140 }
141 continue;
142 }
143
144 if (verbose) {
145 (void) printf(dgettext(TEXT_DOMAIN,
146 "Delete the following line from %s:\n\n"),
147 vname);
148 (void) printf("%s\n", buf);
149 (void) printf(
150 dgettext(TEXT_DOMAIN,
151 "Add the following line to %s:\n\n"),
152 vname);
153 (void) printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\n\n",
154 blkname, char_device, mntpt, fstype, fsckpass,
155 mntboot, mntopt);
156 }
157 if (doit) {
158 if (fprintf(tfp, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
159 blkname, char_device, mntpt, fstype, fsckpass,
160 mntboot, mntopt) == EOF) {
161 (void) mdsyserror(ep, errno, *tname);
162 goto out;
163 }
164 }
165
166
167 gotfs = 1;
168 }
169 if (! feof(fp)) {
170 (void) mdsyserror(ep, errno, vname);
171 goto out;
172 }
173 if (! gotfs) {
174 (void) mderror(ep, MDE_VFSTAB_FILE, vname);
175 goto out;
176 }
177 if (fclose(fp) != 0) {
178 (void) mdsyserror(ep, errno, vname);
179 goto out;
180 }
181 fp = NULL;
182 if (doit) {
183 if ((fflush(tfp) != 0) ||
184 (fsync(fileno(tfp)) != 0) ||
185 (fclose(tfp) != 0)) {
186 (void) mdsyserror(ep, errno, *tname);
187 goto out;
188 }
189 tfp = NULL;
190 }
191
192 /* return success */
193 return (0);
194
195 /* cleanup, return error */
196 out:
197 if (fp != NULL)
198 (void) fclose(fp);
199 if (tfp != NULL)
200 (void) fclose(tfp);
201 if (*tname != NULL) {
202 (void) unlink(*tname);
203 Free(*tname);
204 }
205 return (-1);
206 }
207
208
209 /*
210 * set filesystem device name in vfstab
211 */
212 int
meta_patch_fsdev(char * fsname,mdname_t * fsnp,char * vname,md_error_t * ep)213 meta_patch_fsdev(
214 char *fsname, /* filesystem mount point */
215 mdname_t *fsnp, /* filesystem device */
216 char *vname, /* vfstab file name */
217 md_error_t *ep /* returned error */
218 )
219 {
220 int doit = 1;
221 int verbose = 0;
222 char *tvname = NULL;
223 int rval = -1;
224
225 /* check names */
226 assert(fsname != NULL);
227 if (vname == NULL)
228 vname = "/etc/vfstab";
229
230 /* replace lines in vfstab */
231 if (meta_patch_vfstab(fsname, fsnp, vname, NULL, doit, verbose, &tvname,
232 ep) != 0) {
233 goto out;
234 }
235
236 /* rename temp file on top of real one */
237 if (rename(tvname, vname) != 0) {
238 (void) mdsyserror(ep, errno, vname);
239 goto out;
240 }
241 Free(tvname);
242 tvname = NULL;
243 rval = 0;
244
245 /* cleanup, return error */
246 out:
247 if (tvname != NULL) {
248 if (doit)
249 (void) unlink(tvname);
250 Free(tvname);
251 }
252 return (rval);
253 }
254
255
256 /*
257 * set filesystem device name in vfstab
258 */
259 int
meta_patch_swapdev(mdname_t * fsnp,char * vname,char * old_bdevname,md_error_t * ep)260 meta_patch_swapdev(
261 mdname_t *fsnp, /* filesystem device */
262 char *vname, /* vfstab file name */
263 char *old_bdevname, /* block device name to change */
264 md_error_t *ep /* returned error */
265 )
266 {
267 int doit = 1;
268 int verbose = 0;
269 char *tvname = NULL;
270 int rval = -1;
271
272 /* check names */
273 if (vname == NULL)
274 vname = "/etc/vfstab";
275
276 /* replace lines in vfstab */
277 if (meta_patch_vfstab("swap", fsnp, vname, old_bdevname, doit,
278 verbose, &tvname, ep) != 0) {
279 goto out;
280 }
281
282 /* rename temp file on top of real one */
283 if (rename(tvname, vname) != 0) {
284 (void) mdsyserror(ep, errno, vname);
285 goto out;
286 }
287 Free(tvname);
288 tvname = NULL;
289 rval = 0;
290
291 /* cleanup, return error */
292 out:
293 if (tvname != NULL) {
294 if (doit)
295 (void) unlink(tvname);
296 Free(tvname);
297 }
298 return (rval);
299 }
300