/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * patch /etc/system file for the root device */ #include #include /* * set root device name in md.conf and vfstab, patch in mddb locations */ int meta_patch_rootdev( mdname_t *rootnp, /* root device */ char *sname, /* system file name */ char *vname, /* vfstab file name */ char *cname, /* mddb.cf file name */ char *dbname, /* md.conf file name */ int doit, /* really patch files */ int verbose, /* show what we're doing */ md_error_t *ep /* returned error */ ) { mdsetname_t *sp; int ismeta = metaismeta(rootnp); char *tsname = NULL; FILE *tsfp = NULL; char *dbtname = NULL; FILE *dbtfp = NULL; char *tvname = NULL; int rval = -1; /* check names */ if (sname == NULL) sname = "/etc/system"; if (vname == NULL) vname = "/etc/vfstab"; if (cname == NULL) cname = META_DBCONF; if (dbname == NULL) dbname = "/kernel/drv/md.conf"; /* make sure we have a local name */ if ((sp = metagetset(rootnp, TRUE, ep)) == NULL) return (-1); if (! metaislocalset(sp)) { return (mddeverror(ep, MDE_NOT_LOCAL, rootnp->dev, rootnp->cname)); } /* replace forceload and rootdev lines in system */ if (meta_systemfile_copy(sname, 1, 0, doit, verbose, &tsname, &tsfp, ep) != 0) { goto out; } if (meta_systemfile_append_mdroot(rootnp, sname, tsname, tsfp, ismeta, doit, verbose, ep) != 0) { goto out; } /* replace bootlist lines in /kernel/drv/md.conf */ if (meta_systemfile_copy(dbname, 0, 1, doit, verbose, &dbtname, &dbtfp, ep) != 0) { goto out; } if (meta_systemfile_append_mddb(cname, dbname, dbtname, dbtfp, doit, verbose, 1, ep) != 0) { goto out; } /* force the file contents out to disk */ if (doit) { if ((fflush(tsfp) != 0) || (fsync(fileno(tsfp)) != 0) || (fclose(tsfp) != 0)) { (void) mdsyserror(ep, errno, tsname); goto out; } tsfp = NULL; if ((fflush(dbtfp) != 0) || (fsync(fileno(dbtfp)) != 0) || (fclose(dbtfp) != 0)) { (void) mdsyserror(ep, errno, dbtname); goto out; } dbtfp = NULL; } /* replace lines in vfstab */ if (meta_patch_vfstab("/", rootnp, vname, NULL, doit, verbose, &tvname, ep) != 0) { goto out; } /* rename files, better hope both work */ if (doit) { if (rename(tsname, sname) != 0) { (void) mdsyserror(ep, errno, sname); goto out; } Free(tsname); tsname = NULL; if (rename(dbtname, dbname) != 0) { (void) mdsyserror(ep, errno, dbname); goto out; } Free(dbtname); dbtname = NULL; if (rename(tvname, vname) != 0) { (void) mdsyserror(ep, errno, vname); goto out; } Free(tvname); tvname = NULL; } rval = 0; /* cleanup, return error */ out: if (tsfp != NULL) (void) fclose(tsfp); if (tsname != NULL) { if (doit) (void) unlink(tsname); Free(tsname); } if (tvname != NULL) { if (doit) (void) unlink(tvname); Free(tvname); } /* free the temporary files for md.conf */ if (dbtfp != NULL) (void) fclose(dbtfp); if (dbtname != NULL) { if (doit) (void) unlink(dbtname); Free(dbtname); } return (rval); }