2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A * Just in case we're not in a build environment, make sure that
2N/A * TEXT_DOMAIN gets set to something.
2N/A */
2N/A#if !defined(TEXT_DOMAIN)
2N/A#define TEXT_DOMAIN "SYS_TEST"
2N/A#endif
2N/A
2N/A/*
2N/A * patch /etc/vfstab file
2N/A */
2N/A#include <meta.h>
2N/A#include <string.h>
2N/A
2N/A/*
2N/A * patch filesystem lines into vfstab file, return tempfilename
2N/A */
2N/Aint
2N/Ameta_patch_vfstab(
2N/A char *cmpname, /* filesystem mount point or */
2N/A /* "swap" if updating swap partition */
2N/A mdname_t *fsnp, /* filesystem device name */
2N/A char *vname, /* vfstab file name */
2N/A char *old_bdevname, /* old name of block device, needed */
2N/A /* for deciding which of multiple */
2N/A /* swap file entries to change */
2N/A /* if NULL then not changing swap */
2N/A int doit, /* really patch file */
2N/A int verbose, /* show what we're doing */
2N/A char **tname, /* returned temp file name */
2N/A md_error_t *ep /* returned error */
2N/A)
2N/A{
2N/A char *chrname = fsnp->rname;
2N/A char *blkname = fsnp->bname;
2N/A FILE *fp = NULL;
2N/A FILE *tfp = NULL;
2N/A struct stat sbuf;
2N/A char buf[512];
2N/A char cdev[512];
2N/A char bdev[512];
2N/A char mntpt[512];
2N/A char fstype[512];
2N/A char fsckpass[512];
2N/A char mntboot[512];
2N/A char mntopt[512];
2N/A int gotfs = 0;
2N/A char *cmpstr = &mntpt[0]; /* compare against mntpnt if fs, */
2N/A /* or fstype if swap */
2N/A char *char_device = chrname;
2N/A
2N/A /* check names */
2N/A assert(vname != NULL);
2N/A assert(tname != NULL);
2N/A
2N/A /* get temp names */
2N/A *tname = NULL;
2N/A *tname = Malloc(strlen(vname) + strlen(".tmp") + 1);
2N/A (void) strcpy(*tname, vname);
2N/A (void) strcat(*tname, ".tmp");
2N/A
2N/A /* check if going to update swap entry in file */
2N/A /* if so then compare against file system type */
2N/A if ((old_bdevname != NULL) && (strcmp("swap", cmpname) == 0)) {
2N/A cmpstr = &fstype[0];
2N/A char_device = &cdev[0];
2N/A }
2N/A
2N/A /* copy vfstab file, replace filesystem line */
2N/A if ((fp = fopen(vname, "r")) == NULL) {
2N/A (void) mdsyserror(ep, errno, vname);
2N/A goto out;
2N/A }
2N/A if (fstat(fileno(fp), &sbuf) != 0) {
2N/A (void) mdsyserror(ep, errno, vname);
2N/A goto out;
2N/A }
2N/A if (doit) {
2N/A if ((tfp = fopen(*tname, "w")) == NULL) {
2N/A (void) mdsyserror(ep, errno, *tname);
2N/A goto out;
2N/A }
2N/A if (fchmod(fileno(tfp), (sbuf.st_mode & 0777)) != 0) {
2N/A (void) mdsyserror(ep, errno, *tname);
2N/A goto out;
2N/A }
2N/A if (fchown(fileno(tfp), sbuf.st_uid, sbuf.st_gid) != 0) {
2N/A (void) mdsyserror(ep, errno, *tname);
2N/A goto out;
2N/A }
2N/A }
2N/A while (fgets(buf, sizeof (buf), fp) != NULL) {
2N/A
2N/A /* check that have all required params from vfstab file */
2N/A /* or that the line isnt a comment */
2N/A /* or that the fstype/mntpoint match what was passed in */
2N/A /* or that the block device matches if changing swap */
2N/A /* the last check is needed since there may be multiple */
2N/A /* entries of swap in the file, and so the fstype is not */
2N/A /* a sufficient check */
2N/A if ((sscanf(buf, "%512s %512s %512s %512s %512s %512s %512s",
2N/A bdev, cdev, mntpt, fstype, fsckpass,
2N/A mntboot, mntopt) != 7) ||
2N/A (bdev[0] == '#') || (strcmp(cmpstr, cmpname) != 0) ||
2N/A ((old_bdevname != NULL) &&
2N/A (strstr(bdev, old_bdevname) == NULL))) {
2N/A if (doit) {
2N/A if (fputs(buf, tfp) == EOF) {
2N/A (void) mdsyserror(ep, errno, *tname);
2N/A goto out;
2N/A }
2N/A }
2N/A continue;
2N/A }
2N/A
2N/A if (verbose) {
2N/A (void) printf(dgettext(TEXT_DOMAIN,
2N/A "Delete the following line from %s:\n\n"),
2N/A vname);
2N/A (void) printf("%s\n", buf);
2N/A (void) printf(
2N/A dgettext(TEXT_DOMAIN,
2N/A "Add the following line to %s:\n\n"),
2N/A vname);
2N/A (void) printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\n\n",
2N/A blkname, char_device, mntpt, fstype, fsckpass,
2N/A mntboot, mntopt);
2N/A }
2N/A if (doit) {
2N/A if (fprintf(tfp, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
2N/A blkname, char_device, mntpt, fstype, fsckpass,
2N/A mntboot, mntopt) == EOF) {
2N/A (void) mdsyserror(ep, errno, *tname);
2N/A goto out;
2N/A }
2N/A }
2N/A
2N/A
2N/A gotfs = 1;
2N/A }
2N/A if (! feof(fp)) {
2N/A (void) mdsyserror(ep, errno, vname);
2N/A goto out;
2N/A }
2N/A if (! gotfs) {
2N/A (void) mderror(ep, MDE_VFSTAB_FILE, vname);
2N/A goto out;
2N/A }
2N/A if (fclose(fp) != 0) {
2N/A (void) mdsyserror(ep, errno, vname);
2N/A goto out;
2N/A }
2N/A fp = NULL;
2N/A if (doit) {
2N/A if ((fflush(tfp) != 0) ||
2N/A (fsync(fileno(tfp)) != 0) ||
2N/A (fclose(tfp) != 0)) {
2N/A (void) mdsyserror(ep, errno, *tname);
2N/A goto out;
2N/A }
2N/A tfp = NULL;
2N/A }
2N/A
2N/A /* return success */
2N/A return (0);
2N/A
2N/A /* cleanup, return error */
2N/Aout:
2N/A if (fp != NULL)
2N/A (void) fclose(fp);
2N/A if (tfp != NULL)
2N/A (void) fclose(tfp);
2N/A if (*tname != NULL) {
2N/A (void) unlink(*tname);
2N/A Free(*tname);
2N/A }
2N/A return (-1);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * set filesystem device name in vfstab
2N/A */
2N/Aint
2N/Ameta_patch_fsdev(
2N/A char *fsname, /* filesystem mount point */
2N/A mdname_t *fsnp, /* filesystem device */
2N/A char *vname, /* vfstab file name */
2N/A md_error_t *ep /* returned error */
2N/A)
2N/A{
2N/A int doit = 1;
2N/A int verbose = 0;
2N/A char *tvname = NULL;
2N/A int rval = -1;
2N/A
2N/A /* check names */
2N/A assert(fsname != NULL);
2N/A if (vname == NULL)
2N/A vname = "/etc/vfstab";
2N/A
2N/A /* replace lines in vfstab */
2N/A if (meta_patch_vfstab(fsname, fsnp, vname, NULL, doit, verbose, &tvname,
2N/A ep) != 0) {
2N/A goto out;
2N/A }
2N/A
2N/A /* rename temp file on top of real one */
2N/A if (rename(tvname, vname) != 0) {
2N/A (void) mdsyserror(ep, errno, vname);
2N/A goto out;
2N/A }
2N/A Free(tvname);
2N/A tvname = NULL;
2N/A rval = 0;
2N/A
2N/A /* cleanup, return error */
2N/Aout:
2N/A if (tvname != NULL) {
2N/A if (doit)
2N/A (void) unlink(tvname);
2N/A Free(tvname);
2N/A }
2N/A return (rval);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * set filesystem device name in vfstab
2N/A */
2N/Aint
2N/Ameta_patch_swapdev(
2N/A mdname_t *fsnp, /* filesystem device */
2N/A char *vname, /* vfstab file name */
2N/A char *old_bdevname, /* block device name to change */
2N/A md_error_t *ep /* returned error */
2N/A)
2N/A{
2N/A int doit = 1;
2N/A int verbose = 0;
2N/A char *tvname = NULL;
2N/A int rval = -1;
2N/A
2N/A /* check names */
2N/A if (vname == NULL)
2N/A vname = "/etc/vfstab";
2N/A
2N/A /* replace lines in vfstab */
2N/A if (meta_patch_vfstab("swap", fsnp, vname, old_bdevname, doit,
2N/A verbose, &tvname, ep) != 0) {
2N/A goto out;
2N/A }
2N/A
2N/A /* rename temp file on top of real one */
2N/A if (rename(tvname, vname) != 0) {
2N/A (void) mdsyserror(ep, errno, vname);
2N/A goto out;
2N/A }
2N/A Free(tvname);
2N/A tvname = NULL;
2N/A rval = 0;
2N/A
2N/A /* cleanup, return error */
2N/Aout:
2N/A if (tvname != NULL) {
2N/A if (doit)
2N/A (void) unlink(tvname);
2N/A Free(tvname);
2N/A }
2N/A return (rval);
2N/A}