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 */ 39int 40meta_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 */ 147out: 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