10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*2063Shshaw * Common Development and Distribution License (the "License").
6*2063Shshaw * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*2063Shshaw * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
270Sstevel@tonic-gate
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate * patch /etc/system file for the root device
300Sstevel@tonic-gate */
310Sstevel@tonic-gate
320Sstevel@tonic-gate #include <dlfcn.h>
330Sstevel@tonic-gate #include <meta.h>
340Sstevel@tonic-gate
350Sstevel@tonic-gate
360Sstevel@tonic-gate /*
370Sstevel@tonic-gate * set root device name in md.conf and vfstab, patch in mddb locations
380Sstevel@tonic-gate */
390Sstevel@tonic-gate int
meta_patch_rootdev(mdname_t * rootnp,char * sname,char * vname,char * cname,char * dbname,int doit,int verbose,md_error_t * ep)400Sstevel@tonic-gate meta_patch_rootdev(
410Sstevel@tonic-gate mdname_t *rootnp, /* root device */
420Sstevel@tonic-gate char *sname, /* system file name */
430Sstevel@tonic-gate char *vname, /* vfstab file name */
440Sstevel@tonic-gate char *cname, /* mddb.cf file name */
450Sstevel@tonic-gate char *dbname, /* md.conf file name */
460Sstevel@tonic-gate int doit, /* really patch files */
470Sstevel@tonic-gate int verbose, /* show what we're doing */
480Sstevel@tonic-gate md_error_t *ep /* returned error */
490Sstevel@tonic-gate )
500Sstevel@tonic-gate {
510Sstevel@tonic-gate mdsetname_t *sp;
520Sstevel@tonic-gate int ismeta = metaismeta(rootnp);
530Sstevel@tonic-gate char *tsname = NULL;
540Sstevel@tonic-gate FILE *tsfp = NULL;
550Sstevel@tonic-gate char *dbtname = NULL;
560Sstevel@tonic-gate FILE *dbtfp = NULL;
570Sstevel@tonic-gate char *tvname = NULL;
580Sstevel@tonic-gate int rval = -1;
590Sstevel@tonic-gate
600Sstevel@tonic-gate /* check names */
610Sstevel@tonic-gate if (sname == NULL)
620Sstevel@tonic-gate sname = "/etc/system";
630Sstevel@tonic-gate if (vname == NULL)
640Sstevel@tonic-gate vname = "/etc/vfstab";
650Sstevel@tonic-gate if (cname == NULL)
660Sstevel@tonic-gate cname = META_DBCONF;
670Sstevel@tonic-gate if (dbname == NULL)
680Sstevel@tonic-gate dbname = "/kernel/drv/md.conf";
690Sstevel@tonic-gate
700Sstevel@tonic-gate /* make sure we have a local name */
710Sstevel@tonic-gate if ((sp = metagetset(rootnp, TRUE, ep)) == NULL)
720Sstevel@tonic-gate return (-1);
730Sstevel@tonic-gate
740Sstevel@tonic-gate if (! metaislocalset(sp)) {
750Sstevel@tonic-gate return (mddeverror(ep, MDE_NOT_LOCAL, rootnp->dev,
760Sstevel@tonic-gate rootnp->cname));
770Sstevel@tonic-gate }
780Sstevel@tonic-gate
790Sstevel@tonic-gate /* replace forceload and rootdev lines in system */
800Sstevel@tonic-gate if (meta_systemfile_copy(sname, 1, 0, doit, verbose, &tsname, &tsfp,
810Sstevel@tonic-gate ep) != 0) {
820Sstevel@tonic-gate goto out;
830Sstevel@tonic-gate }
840Sstevel@tonic-gate if (meta_systemfile_append_mdroot(rootnp, sname,
850Sstevel@tonic-gate tsname, tsfp, ismeta, doit, verbose, ep) != 0) {
860Sstevel@tonic-gate goto out;
870Sstevel@tonic-gate }
880Sstevel@tonic-gate
890Sstevel@tonic-gate /* replace bootlist lines in /kernel/drv/md.conf */
900Sstevel@tonic-gate if (meta_systemfile_copy(dbname, 0, 1, doit, verbose, &dbtname,
910Sstevel@tonic-gate &dbtfp, ep) != 0) {
920Sstevel@tonic-gate goto out;
930Sstevel@tonic-gate }
940Sstevel@tonic-gate if (meta_systemfile_append_mddb(cname, dbname, dbtname, dbtfp, doit,
95*2063Shshaw verbose, 1, ep) != 0) {
960Sstevel@tonic-gate goto out;
970Sstevel@tonic-gate }
980Sstevel@tonic-gate
990Sstevel@tonic-gate /* force the file contents out to disk */
1000Sstevel@tonic-gate if (doit) {
1010Sstevel@tonic-gate if ((fflush(tsfp) != 0) ||
1020Sstevel@tonic-gate (fsync(fileno(tsfp)) != 0) ||
1030Sstevel@tonic-gate (fclose(tsfp) != 0)) {
1040Sstevel@tonic-gate (void) mdsyserror(ep, errno, tsname);
1050Sstevel@tonic-gate goto out;
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate tsfp = NULL;
1080Sstevel@tonic-gate if ((fflush(dbtfp) != 0) ||
1090Sstevel@tonic-gate (fsync(fileno(dbtfp)) != 0) ||
1100Sstevel@tonic-gate (fclose(dbtfp) != 0)) {
1110Sstevel@tonic-gate (void) mdsyserror(ep, errno, dbtname);
1120Sstevel@tonic-gate goto out;
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate dbtfp = NULL;
1150Sstevel@tonic-gate }
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate /* replace lines in vfstab */
1180Sstevel@tonic-gate if (meta_patch_vfstab("/", rootnp, vname, NULL, doit, verbose, &tvname,
1190Sstevel@tonic-gate ep) != 0) {
1200Sstevel@tonic-gate goto out;
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate /* rename files, better hope both work */
1240Sstevel@tonic-gate if (doit) {
1250Sstevel@tonic-gate if (rename(tsname, sname) != 0) {
1260Sstevel@tonic-gate (void) mdsyserror(ep, errno, sname);
1270Sstevel@tonic-gate goto out;
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate Free(tsname);
1300Sstevel@tonic-gate tsname = NULL;
1310Sstevel@tonic-gate if (rename(dbtname, dbname) != 0) {
1320Sstevel@tonic-gate (void) mdsyserror(ep, errno, dbname);
1330Sstevel@tonic-gate goto out;
1340Sstevel@tonic-gate }
1350Sstevel@tonic-gate Free(dbtname);
1360Sstevel@tonic-gate dbtname = NULL;
1370Sstevel@tonic-gate if (rename(tvname, vname) != 0) {
1380Sstevel@tonic-gate (void) mdsyserror(ep, errno, vname);
1390Sstevel@tonic-gate goto out;
1400Sstevel@tonic-gate }
1410Sstevel@tonic-gate Free(tvname);
1420Sstevel@tonic-gate tvname = NULL;
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate rval = 0;
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate /* cleanup, return error */
1470Sstevel@tonic-gate out:
1480Sstevel@tonic-gate if (tsfp != NULL)
1490Sstevel@tonic-gate (void) fclose(tsfp);
1500Sstevel@tonic-gate if (tsname != NULL) {
1510Sstevel@tonic-gate if (doit)
1520Sstevel@tonic-gate (void) unlink(tsname);
1530Sstevel@tonic-gate Free(tsname);
1540Sstevel@tonic-gate }
1550Sstevel@tonic-gate if (tvname != NULL) {
1560Sstevel@tonic-gate if (doit)
1570Sstevel@tonic-gate (void) unlink(tvname);
1580Sstevel@tonic-gate Free(tvname);
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate /* free the temporary files for md.conf */
1620Sstevel@tonic-gate if (dbtfp != NULL)
1630Sstevel@tonic-gate (void) fclose(dbtfp);
1640Sstevel@tonic-gate if (dbtname != NULL) {
1650Sstevel@tonic-gate if (doit)
1660Sstevel@tonic-gate (void) unlink(dbtname);
1670Sstevel@tonic-gate Free(dbtname);
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate return (rval);
1700Sstevel@tonic-gate }
171