Implement new grammar and semantics for specifying file systems

and the root device:

- New "file-system" keyword is used to configure file systems into
  the kernel.
- New way of specifying root device, which allows root file system
  type to always be specified.  Examples:

	config gennetbsd swap generic
	config sdnetbsd root on sd0a swap on sd0b
	config nfsnetbsd root on nfs

  are replaced by:

	config gennetbsd root on ? type ?
	config sdnetbsd root on sd0a type ffs swap on sd0b
	config nfsnetbsd root on ? type nfs
	config lenetbsd root on le0 type nfs

  Note that specific network interfaces may now be specified as
  the root device.
- swapgeneric.c is no longer used; generate a swap*.c file for each
  "config" line in the kernel configuration file.
This commit is contained in:
thorpej 1997-01-31 03:12:30 +00:00
parent 593fdd462d
commit 07c71aa7f7
8 changed files with 244 additions and 69 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: config.h,v 1.28 1996/11/11 23:40:09 gwr Exp $ */
/* $NetBSD: config.h,v 1.29 1997/01/31 03:12:30 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@ -99,6 +99,7 @@ struct config {
struct config *cf_next; /* linked list */
const char *cf_name; /* "vmunix" */
int cf_lineno; /* source line */
const char *cf_fstype; /* file system type */
struct nvlist *cf_root; /* "root on ra0a" */
struct nvlist *cf_swap; /* "swap on ra0b and ra1b" */
struct nvlist *cf_dump; /* "dumps on ra0b" */
@ -274,11 +275,13 @@ int maxmaxusers; /* default "maxusers" parameter */
int maxusers; /* configuration's "maxusers" parameter */
int maxpartitions; /* configuration's "maxpartitions" parameter */
struct nvlist *options; /* options */
struct nvlist *fsoptions; /* filesystems */
struct nvlist *mkoptions; /* makeoptions */
struct hashtab *devbasetab; /* devbase lookup */
struct hashtab *devatab; /* devbase attachment lookup */
struct hashtab *selecttab; /* selects things that are "optional foo" */
struct hashtab *needcnttab; /* retains names marked "needs-count" */
struct hashtab *fsopttab; /* table of configured file systems */
struct devbase *allbases; /* list of all devbase structures */
struct deva *alldevas; /* list of all devbase attachment structures */
@ -319,6 +322,7 @@ const char *intern __P((const char *));
/* main.c */
void addoption __P((const char *name, const char *value));
void addfsoption __P((const char *name));
void addmkoption __P((const char *name, const char *value));
int devbase_has_instances __P((struct devbase *, int));
int deva_has_instances __P((struct deva *, int));

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: gram.y,v 1.12 1996/11/11 23:54:17 gwr Exp $ */
/* $NetBSD: gram.y,v 1.13 1997/01/31 03:12:32 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@ -100,9 +100,9 @@ static void check_maxpart __P((void));
}
%token AND AT ATTACH BUILD COMPILE_WITH CONFIG DEFINE DEVICE DUMPS ENDFILE
%token XFILE FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS MAXUSERS MAXPARTITIONS
%token MINOR ON OPTIONS PSEUDO_DEVICE ROOT SOURCE SWAP WITH
%token NEEDS_COUNT NEEDS_FLAG
%token XFILE FILE_SYSTEM FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS
%token MAXUSERS MAXPARTITIONS MINOR ON OPTIONS PSEUDO_DEVICE ROOT SOURCE
%token SWAP TYPE WITH NEEDS_COUNT NEEDS_FLAG
%token <val> NUMBER
%token <str> PATHNAME WORD
@ -110,6 +110,7 @@ static void check_maxpart __P((void));
%left '&'
%type <list> fopts fexpr fatom
%type <str> fs_spec
%type <val> fflgs fflag
%type <str> rule
%type <attr> attr
@ -309,10 +310,12 @@ spec:
config_spec:
file |
include |
FILE_SYSTEM fs_list |
OPTIONS opt_list |
MAKEOPTIONS mkopt_list |
MAXUSERS NUMBER { setmaxusers($2); } |
CONFIG conf sysparam_list { addconf(&conf); } |
CONFIG conf root_spec sysparam_list
{ addconf(&conf); } |
PSEUDO_DEVICE WORD npseudo { addpseudo($2, $3); } |
device_instance AT attachment locators flags_opt
{ adddev($1, $3, $4, $5); };
@ -332,19 +335,38 @@ option:
WORD { addoption($1, NULL); } |
WORD '=' value { addoption($1, $3); };
fs_list:
fs_list ',' fsoption |
fsoption;
fsoption:
WORD { addfsoption($1); };
conf:
WORD { conf.cf_name = $1;
conf.cf_lineno = currentline();
conf.cf_fstype = NULL;
conf.cf_root = NULL;
conf.cf_swap = NULL;
conf.cf_dump = NULL; };
root_spec:
ROOT on_opt dev_spec fs_spec_opt
{ setconf(&conf.cf_root, "root", $3); };
fs_spec_opt:
TYPE fs_spec { setfstype(&conf.cf_fstype, $2); } |
/* empty */;
fs_spec:
'?' { $$ = intern("?"); } |
WORD { $$ = intern($1); };
sysparam_list:
sysparam_list sysparam |
sysparam;
/* empty */;
sysparam:
ROOT on_opt dev_spec { setconf(&conf.cf_root, "root", $3); } |
SWAP on_opt swapdev_list { setconf(&conf.cf_swap, "swap", $3); } |
DUMPS on_opt dev_spec { setconf(&conf.cf_dump, "dumps", $3); };
@ -353,6 +375,7 @@ swapdev_list:
dev_spec { $$ = $1; };
dev_spec:
'?' { $$ = new_si(intern("?"), NODEV); } |
WORD { $$ = new_si($1, NODEV); } |
major_minor { $$ = new_si(NULL, $1); };

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.20 1996/11/11 23:41:54 gwr Exp $ */
/* $NetBSD: main.c,v 1.21 1997/01/31 03:12:32 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@ -71,6 +71,7 @@ static struct hashtab *opttab;
static struct hashtab *mkopttab;
static struct nvlist **nextopt;
static struct nvlist **nextmkopt;
static struct nvlist **nextfsopt;
static __dead void stop __P((void));
static int do_option __P((struct hashtab *, struct nvlist ***,
@ -162,8 +163,10 @@ usage:
needcnttab = ht_new();
opttab = ht_new();
mkopttab = ht_new();
fsopttab = ht_new();
nextopt = &options;
nextmkopt = &mkoptions;
nextfsopt = &fsoptions;
/*
* Handle profiling (must do this before we try to create any
@ -208,6 +211,11 @@ usage:
errors++;
}
}
if (fsoptions == NULL) {
(void)fprintf(stderr,
"config: need at least one \"file-system\" line\n");
errors++;
}
if (crosscheck() || errors)
stop();
@ -296,6 +304,40 @@ addoption(name, value)
(void)ht_insert(selecttab, n, (void *)n);
}
/*
* Add a file system option. This routine simply inserts the name into
* a list of valid file systems, which is used to validate the root
* file system type. The name is then treated like a standard option.
*/
void
addfsoption(name)
const char *name;
{
register struct nvlist *nv;
register const char *n;
register char *p, c;
char buf[500];
/* Convert to lowercase. */
for (n = name, p = buf; (c = *n) != '\0'; n++)
*p++ = isupper(c) ? tolower(c) : c;
*p = 0;
n = intern(buf);
if (do_option(fsopttab, &nextfsopt, n, NULL, "file-system"))
return;
/* Convert to uppercase. */
for (n = name, p = buf; (c = *n) != '\0'; n++)
*p++ = islower(c) ? toupper(c) : c;
*p = 0;
n = intern(buf);
addoption(n, NULL);
}
/*
* Add a "make" option.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkmakefile.c,v 1.32 1996/09/23 05:04:23 ghudson Exp $ */
/* $NetBSD: mkmakefile.c,v 1.33 1997/01/31 03:12:33 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@ -303,13 +303,7 @@ emitfiles(fp, suffix)
*/
if (suffix == 'c') {
for (cf = allcf; cf != NULL; cf = cf->cf_next) {
if (cf->cf_root == NULL)
(void)sprintf(swapname,
"$S/arch/%s/%s/swapgeneric.c",
machine, machine);
else
(void)sprintf(swapname, "swap%s.c",
cf->cf_name);
(void)sprintf(swapname, "swap%s.c", cf->cf_name);
len = strlen(swapname);
if (lpos + len > 72) {
if (fputs(" \\\n", fp) < 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkswap.c,v 1.5 1996/08/31 20:58:27 mycroft Exp $ */
/* $NetBSD: mkswap.c,v 1.6 1997/01/31 03:12:34 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@ -63,7 +63,7 @@ mkswap()
register struct config *cf;
for (cf = allcf; cf != NULL; cf = cf->cf_next)
if (cf->cf_root != NULL && mkoneswap(cf))
if (mkoneswap(cf))
return (1);
return (0);
}
@ -88,7 +88,7 @@ mkoneswap(cf)
register struct nvlist *nv;
register FILE *fp;
char fname[200];
char *mountroot;
char rootinfo[200];
(void)sprintf(fname, "swap%s.c", cf->cf_name);
if ((fp = fopen(fname, "w")) == NULL) {
@ -100,27 +100,63 @@ mkoneswap(cf)
#include <sys/param.h>\n\
#include <sys/conf.h>\n\n", fp) < 0)
goto wrerror;
/*
* Emit the root device.
*/
nv = cf->cf_root;
if (fprintf(fp, "dev_t\trootdev = %s;\t/* %s */\n",
mkdevstr(nv->nv_int), nv->nv_str) < 0)
if (cf->cf_root->nv_str == s_qmark)
strcpy(rootinfo, "NULL");
else
sprintf(rootinfo, "\"%s\"", cf->cf_root->nv_str);
if (fprintf(fp, "const char *rootspec = %s;\n", rootinfo) < 0)
goto wrerror;
if (fprintf(fp, "dev_t\trootdev = %s;\t/* %s */\n",
mkdevstr(nv->nv_int),
nv->nv_str == s_qmark ? "wildcarded" : nv->nv_str) < 0)
goto wrerror;
/*
* Emit the dump device.
*/
nv = cf->cf_dump;
if (fprintf(fp, "dev_t\tdumpdev = %s;\t/* %s */\n",
mkdevstr(nv->nv_int), nv->nv_str) < 0)
nv ? mkdevstr(nv->nv_int) : "NODEV",
nv ? (nv->nv_str ? nv->nv_str : "none") : "unspecified") < 0)
goto wrerror;
/*
* Emit the swap devices. If swap is unspecified (i.e. wildcarded
* root device), leave room for it to be filled in at run-time.
*/
if (fputs("\nstruct\tswdevt swdevt[] = {\n", fp) < 0)
goto wrerror;
for (nv = cf->cf_swap; nv != NULL; nv = nv->nv_next)
if (fprintf(fp, "\t{ %s,\t0,\t0 },\t/* %s */\n",
mkdevstr(nv->nv_int), nv->nv_str) < 0)
if (cf->cf_swap == NULL) {
if (fputs("\t{ NODEV, 0, 0 },\t/* unspecified */\n", fp) < 0)
goto wrerror;
} else if (cf->cf_swap->nv_str == NULL) {
if (fputs("\t{ NODEV, 0, 0 },\t/* none */\n", fp) < 0)
goto wrerror;
} else {
for (nv = cf->cf_swap; nv != NULL; nv = nv->nv_next)
if (fprintf(fp, "\t{ %s,\t0,\t0 },\t/* %s */\n",
mkdevstr(nv->nv_int), nv->nv_str) < 0)
goto wrerror;
}
if (fputs("\t{ NODEV, 0, 0 }\n};\n\n", fp) < 0)
goto wrerror;
mountroot =
cf->cf_root->nv_str == s_nfs ? "nfs_mountroot" : "ffs_mountroot";
if (fprintf(fp, "extern int %s __P((void *));\n", mountroot) < 0)
goto wrerror;
if (fprintf(fp, "int (*mountroot) __P((void *)) = %s;\n", mountroot) < 0)
/*
* Emit the root file system.
*/
if (cf->cf_fstype == NULL)
strcpy(rootinfo, "NULL");
else {
sprintf(rootinfo, "%s_mountroot", cf->cf_fstype);
if (fprintf(fp, "extern int %s __P((void));\n", rootinfo) < 0)
goto wrerror;
}
if (fprintf(fp, "int (*mountroot) __P((void)) = %s;\n", rootinfo) < 0)
goto wrerror;
if (fclose(fp)) {

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: scan.l,v 1.11 1996/11/13 18:42:18 gwr Exp $ */
/* $NetBSD: scan.l,v 1.12 1997/01/31 03:12:36 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@ -92,6 +92,7 @@ define return DEFINE;
device return DEVICE;
dumps return DUMPS;
file return XFILE;
file-system return FILE_SYSTEM;
flags return FLAGS;
include return INCLUDE;
machine return XMACHINE;
@ -108,6 +109,7 @@ pseudo-device return PSEUDO_DEVICE;
root return ROOT;
source return SOURCE;
swap return SWAP;
type return TYPE;
with return WITH;
{PATH} {

View File

@ -1,4 +1,4 @@
/* $NetBSD: sem.c,v 1.10 1996/11/11 23:40:11 gwr Exp $ */
/* $NetBSD: sem.c,v 1.11 1997/01/31 03:12:37 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@ -58,9 +58,9 @@
#define NAMESIZE 100 /* local name buffers */
const char *s_generic;
static const char *s_ifnet; /* magic attribute */
const char *s_nfs;
static const char *s_qmark;
const char *s_qmark;
static struct hashtab *attrtab; /* for attribute lookup */
static struct hashtab *cfhashtab; /* for config lookup */
@ -76,6 +76,7 @@ static struct devi **nextdevi;
static struct devi **nextpseudo;
static int has_errobj __P((struct nvlist *, void *));
static int has_attr __P((struct nvlist *, const char *));
static struct nvlist *addtoattr __P((struct nvlist *, struct devbase *));
static int exclude __P((struct nvlist *, const char *, const char *));
static int resolve __P((struct nvlist **, const char *, const char *,
@ -89,6 +90,7 @@ static int split __P((const char *, size_t, char *, size_t, int *));
static void selectbase __P((struct devbase *, struct deva *));
static int onlist __P((struct nvlist *, void *));
static const char **fixloc __P((const char *, struct attr *, struct nvlist *));
static const char *makedevstr __P((int, int));
void
initsem()
@ -115,7 +117,7 @@ initsem()
allpseudo = NULL;
nextpseudo = &allpseudo;
s_generic = intern("generic");
s_ifnet = intern("ifnet");
s_nfs = intern("nfs");
s_qmark = intern("?");
}
@ -232,6 +234,26 @@ has_errobj(nv, obj)
return (0);
}
/*
* Return true if the given attribute is embedded in the given
* pointer list.
*/
static int
has_attr(nv, attr)
register struct nvlist *nv;
register const char *attr;
{
register struct attr *a;
if ((a = getattr(attr)) == NULL)
return (0);
for (; nv != NULL; nv = nv->nv_next)
if (nv->nv_ptr == a)
return (1);
return (0);
}
/*
* Add a device base to a list in an attribute (actually, to any list).
* Note that this does not check for duplicates, and does reverse the
@ -526,12 +548,34 @@ exclude(nv, name, what)
{
if (nv != NULL) {
error("%s: swap generic must not specify %s", name, what);
error("%s: wildcarded root must not specify %s", name, what);
return (1);
}
return (0);
}
/*
* Make a string description of the device at maj/min.
*/
static const char *
makedevstr(maj, min)
int maj, min;
{
struct devbase *dev;
char buf[32];
for (dev = allbases; dev != NULL; dev = dev->d_next)
if (dev->d_major == maj)
break;
if (dev == NULL)
(void)sprintf(buf, "<%d/%d>", maj, min);
else
(void)sprintf(buf, "%s%d%c", dev->d_name,
min / maxpartitions, (min % maxpartitions) + 'a');
return (intern(buf));
}
/*
* Map things like "ra0b" => makedev(major("ra"), 0*maxpartitions + 'b'-'a').
* Handle the case where the device number is given but there is no
@ -544,10 +588,11 @@ resolve(nvp, name, what, dflt, part)
struct nvlist *dflt;
register int part;
{
register struct nvlist *nv;
register struct nvlist *nv, *anv;
register struct devbase *dev;
register const char *cp;
register int maj, min, l;
register int maj, min, i, l;
register struct attr *a;
int unit;
char buf[NAMESIZE];
@ -563,8 +608,10 @@ resolve(nvp, name, what, dflt, part)
maj = major(dflt->nv_int);
min = (minor(dflt->nv_int) / maxpartitions) + part;
d = makedev(maj, min);
}
*nvp = nv = newnv(NULL, NULL, NULL, d, NULL);
cp = makedevstr(maj, min);
} else
cp = NULL;
*nvp = nv = newnv(NULL, cp, NULL, d, NULL);
}
if (nv->nv_int != NODEV) {
/*
@ -573,21 +620,13 @@ resolve(nvp, name, what, dflt, part)
*/
maj = major(nv->nv_int);
min = minor(nv->nv_int);
for (dev = allbases; dev != NULL; dev = dev->d_next)
if (dev->d_major == maj)
break;
if (dev == NULL)
(void)sprintf(buf, "<%d/%d>", maj, min);
else
(void)sprintf(buf, "%s%d%c", dev->d_name,
min / maxpartitions, (min % maxpartitions) + 'a');
nv->nv_str = intern(buf);
nv->nv_str = makedevstr(maj, min);
return (0);
}
if (nv->nv_str == NULL || nv->nv_str == s_nfs)
if (nv->nv_str == NULL || nv->nv_str == s_qmark)
/*
* NFS spec. Leave as NODEV.
* Wildcarded or unspecified; leave it as NODEV.
*/
return (0);
@ -596,7 +635,7 @@ resolve(nvp, name, what, dflt, part)
* suffix, remove it if there, and split into name ("ra") and
* unit (2).
*/
l = strlen(nv->nv_str);
l = i = strlen(nv->nv_str);
cp = &nv->nv_str[l];
if (l > 1 && *--cp >= 'a' && *cp <= 'a'+maxpartitions &&
isdigit(cp[-1])) {
@ -609,13 +648,28 @@ resolve(nvp, name, what, dflt, part)
return (1);
}
dev = ht_lookup(devbasetab, intern(buf));
if (dev == NULL || dev->d_major == NODEV) {
error("%s: can't make %s device from `%s'",
name, what, nv->nv_str);
if (dev == NULL) {
error("%s: device `%s' does not exist", buf);
return (1);
}
/*
* Check for the magic network interface attribute, and
* don't bother making a device number.
*/
if (has_attr(dev->d_attrs, s_ifnet))
nv->nv_int = NODEV;
else {
if (dev->d_major == NODEV) {
error("%s: can't make %s device from `%s'",
name, what, nv->nv_str);
return (1);
}
nv->nv_int =
makedev(dev->d_major, unit * maxpartitions + part);
}
nv->nv_name = dev->d_name;
nv->nv_int = makedev(dev->d_major, unit * maxpartitions + part);
return (0);
}
@ -655,19 +709,14 @@ addconf(cf0)
*cf = *cf0;
/*
* Look for "swap generic".
* Check for wildcarded root device.
*/
for (nv = cf->cf_swap; nv != NULL; nv = nv->nv_next)
if (nv->nv_str == s_generic)
break;
if (nv != NULL) {
if (cf->cf_root->nv_str == s_qmark) {
/*
* Make sure no root or dump device specified, and no
* other swap devices. Note single | here (check all).
* Make sure no swap or dump device specified.
* Note single | here (check all).
*/
nv = cf->cf_swap;
if (exclude(cf->cf_root, name, "root device") |
exclude(nv->nv_next, name, "additional swap devices") |
if (exclude(cf->cf_swap, name, "swap devices") |
exclude(cf->cf_dump, name, "dump device"))
goto bad;
} else {
@ -681,6 +730,11 @@ addconf(cf0)
resolve(&cf->cf_dump, name, "dumps", nv, 'b'))
goto bad;
}
/* Wildcarded fstype is `unspecified'. */
if (cf->cf_fstype == s_qmark)
cf->cf_fstype = NULL;
*nextcf = cf;
nextcf = &cf->cf_next;
return;
@ -704,6 +758,25 @@ setconf(npp, what, v)
*npp = v;
}
void
setfstype(fstp, v)
const char **fstp;
const char *v;
{
if (*fstp != NULL) {
error("multiple fstype specifications");
return;
}
if (v != s_qmark && ht_lookup(fsopttab, v) == NULL) {
error("\"%s\" is not a configured file system", v);
return;
}
*fstp = v;
}
static struct devi *
newdevi(name, unit, d)
const char *name;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sem.h,v 1.6 1996/11/11 23:40:10 gwr Exp $ */
/* $NetBSD: sem.h,v 1.7 1997/01/31 03:12:38 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@ -59,11 +59,12 @@ struct attr *getattr __P((const char *name));
void setmajor __P((struct devbase *d, int n));
void addconf __P((struct config *));
void setconf __P((struct nvlist **, const char *, struct nvlist *));
void setfstype __P((const char **, const char *));
void adddev __P((const char *, const char *, struct nvlist *, int));
void addpseudo __P((const char *name, int number));
const char *ref __P((const char *name));
const char *starref __P((const char *name));
const char *wildref __P((const char *name));
extern const char *s_generic;
extern const char *s_qmark;
extern const char *s_nfs;