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 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 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 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