metaroot.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
* 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 1992-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* patch system files for root on metadevice
*/
#include <meta.h>
#include <stdlib.h>
#include <sdssc.h>
#define METAROOT_OK 0
#define METAROOT_ERR -1
#define METAROOT_NOTFOUND -2
struct def_map {
char **dm_fname; /* Location of file name */
char *dm_default; /* Default name */
};
/*
* options
*/
static int doit = 1;
static int verbose = 0;
/*
* Map of default system file names to the place where they are stored.
* This is used if the -R option is specified. Note that the members of
* the map point to the cname, sname, vname and dbname global variables
* above. These global variables are used in the call to
* meta_patch_rootdev() in main().
*/
static struct def_map default_names[] = {
&cname, META_DBCONF,
};
static int validate_stripe_root();
/*
* print usage message, md_exit
*/
static void
int eval
)
{
usage:\t%s [-n] [-k system-name] [-m md.conf-name] [-v vfstab-name] \\\n\
\t\t[-c mddb.cf-name] device\n\
\t%s [-n] [-R root-path] device\n"),
}
static void
free_mem()
{
int i;
for (i = 0, map = default_names;
i < sizeof (default_names) / sizeof (struct def_map);
i++, map++) {
}
}
}
/*
* Check if mirror, mirnp, is a valid root filesystem, ie all
* submirrors must be single disk stripe, and that the slice, slicenp,
* if not NULL, is a component of one of the submirrors.
* The arg metaroot is TRUE if mirnp is the current root filesystem.
* Returns:
* METAROOT_OK if mirror is valid and slicenp is a component
* METAROOT_NOTFOUND if mirror valid but slicenp not a component
* METAROOT_ERR if mirror not a valid root
*/
static int
int metaroot,
)
{
int smi;
char *miscname;
int found = 0;
int rval;
int err = 0;
return (METAROOT_ERR);
}
/* Check all submirrors */
/* skip unused submirrors */
if (submirnamep == NULL) {
continue;
}
submirnamep->cname));
}
return (METAROOT_ERR);
}
switch (rval) {
case METAROOT_OK:
found = 1;
break;
case METAROOT_ERR:
err++;
break;
case METAROOT_NOTFOUND:
default:
break;
}
}
if (err > 0)
return (METAROOT_ERR);
if (!found)
return (METAROOT_NOTFOUND);
return (METAROOT_OK);
}
/*
* Check if stripe, strnp, is a valid root filesystem, ie must
* be single disk stripe, and the the slice, slicenp, if not NULL, must
* be a component of this stripe.
* The arg metaroot is TRUE if strnp is the current root filesystem.
* Returns:
* METAROOT_OK if stripe is valid and slicenp is a component
* METAROOT_NOTFOUND if stripe valid but slicenp not a component
* METAROOT_ERR if stripe not a valid root
*/
static int
int metaroot,
)
{
return (METAROOT_ERR);
}
return (METAROOT_ERR);
}
return (METAROOT_ERR);
}
return (METAROOT_OK);
return (METAROOT_OK);
if (!metaroot) {
"Root %s is not a component of metadevice %s\n"),
}
return (METAROOT_NOTFOUND);
}
return (METAROOT_ERR);
}
/*
* Check if the device devnp is valid. It must be a component of the
* metadevice that contains the root filesystem
*/
static int
)
{
char *curroot;
char *miscname;
int rval;
return (METAROOT_ERR);
}
return (METAROOT_ERR);
}
if (metaismeta(rootnp)) {
/* get type */
return (METAROOT_ERR);
}
return (METAROOT_OK);
if (rval == METAROOT_NOTFOUND) {
"Slice %s is not a component of root %s\n"),
}
return (METAROOT_ERR);
return (METAROOT_OK);
if (rval == METAROOT_NOTFOUND) {
"Slice %s is not a component of root %s\n"),
}
return (METAROOT_ERR);
} else {
"Root metadevice, %s, is not a Slice or Mirror\n"),
return (METAROOT_ERR);
}
} else {
return (METAROOT_ERR);
}
}
/*
* What we're going to do:
*
* 1) Check if the device is a metadevice or not.
*
* 2) If a metadevice, and it is valid, ie a stripe or a mirror containing
* a single slice, add "forceload:{drv,misc}/<modname>" of
* underlying drivers for the meta-root and the metadevice
* database to system. Otherwise, remove forceloads from system if the
* slice is a component of the current root metadevice.
*
* 3) Add "rootdev:/devices/..." to system.
*
* 4) Replace / mount in vfstab.
*
* 5) Repatch database locations, just to be safe.
*/
int
main(
int argc,
char *argv[]
)
{
int i;
int c;
int ckmv_flag = 0; /* non-zero if -c, -k, -m or -v */
char *miscname;
char *curroot;
int error;
/*
* Get the locale set up before calling any other routines
* with messages to ouput. Just in case we're not in a build
* environment, make sure that TEXT_DOMAIN gets set to
* something.
*/
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
if ((sdssc_bind_library() == SDSSC_OKAY) &&
&error) == SDSSC_PROXY_DONE))
/* initialize */
meta_check_root(ep) != 0) {
}
/* parse options */
optind = 1;
opterr = 1;
switch (c) {
case 'h':
break;
case 'm':
ckmv_flag = 1;
break;
case 'n':
doit = 0;
verbose = 1;
break;
case 'k':
ckmv_flag = 1;
break;
case 'v':
ckmv_flag = 1;
break;
case 'c':
ckmv_flag = 1;
break;
case 'R':
break;
case '?':
if (optopt == '?')
/*FALLTHROUGH*/
default:
break;
}
}
if (argc != 1)
/* Can't use -R with any of -c, -k, -m or -v */
gettext("-R invalid with any of -c, -k, -m or -v\n"));
}
/* get device name */
}
}
/*
* Get device name of current root metadevice. If root is net
* mounted as happens if this command is part of the install
* process, currootnp will be set to NULL.
*/
/*
* If the argument is the name of the current root filesystem, then
* the command is allowed, otherwise check that the argument is
* valid.
*/
if (metaismeta(rootnp)) {
/*
* Validate that the metadevice is based on a
* single slice. If none of the -k, -m, -v, -c or
* -R options are specified, then the default
* system files are being modified and hence the
* current root slice must be a component of the
* metadevice. If any of the previously mentioned
* options are used don't check that the current
* root is a component.
*/
/* Get device name of current root slice */
if ((currootdevnp =
== NULL) {
}
} else currootdevnp = NULL;
}
/* Check that metadevice is a mirror or a stripe */
}
}
} else {
"%s is not a mirror or stripe\n"),
}
} else {
/*
* Check that the root device is a component of the
* current root filesystem only if the default system
* files are being modified
*/
}
}
}
}
}
/*
* If -R is specified, use the default system file names relative
* to the new root location.
*/
for (i = 0, map = default_names;
i < sizeof (default_names) / sizeof (struct def_map);
i++, map++) {
/* Add 1 for null terminator */
for system file path relocation\n"));
}
}
}
/* patch system and vfstab for root and mddb locations */
free_mem();
}
}
free_mem();
}
/* return success */
/*NOTREACHED*/
return (0);
}