Subject: config(8) -- attributes as option-dependencies
To: None <tech-kern@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-kern
Date: 10/10/2002 18:36:05
--vtzGhvizbBRQ85DL
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

config(8) allows options to have dependencies on other options, like so:

defflag	FOO
defflag	BAR: FOO

...means that if "options BAR" is specified, then "options FOO" is also
impled.

Unfortunately, options can only currently register dependencies on other
options.  The attached patch allows options to register dependencies on
attributes, e.g.:

define	foo_attr
file	foo_file.c	foo_attr

device	foobar: foo_attr
...

defflag BAR: foo_attr

This causes the file selected by "foo_attr" (foo_file.c) to be compiled
if either the "foobar" device is configured or "options BAR" is specified.

This is a much more natural way to specify the dependency relationship than
the current method:

file	foo_file.c	foobar | bar

...which requires you to update the foo_file.c selector list every time
you find another user of the code in foo_file.c.

This allows for the nice simplification also attached to this message.

I also took the opportunity to clean up an inconsistency in the config(8)
grammar.  Previously, attribute-dependencies and option-dependencies had
a slightly different syntax:

defflag	FOO: FOODEP1 FOODEP2 FOODEP3
define	bar: bardep1, bardep2, bardep3

They now both use commas, like so:

defflag	FOO: FOODEP1, FOODEP2, FOODEP3
define	bar: bardep1, bardep2, bardep3

Since nothing currently used the comma-less syntax, this is a totally
non-invasive change :-)

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>

--vtzGhvizbBRQ85DL
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=config-patch

Index: gram.y
===================================================================
RCS file: /cvsroot/syssrc/usr.sbin/config/gram.y,v
retrieving revision 1.37
diff -c -r1.37 gram.y
*** gram.y	2002/10/09 20:17:00	1.37
--- gram.y	2002/10/11 01:12:56
***************
*** 138,143 ****
--- 138,145 ----
  %type	<str>	fsoptfile_opt
  %type	<str>	defopt
  %type	<list>	defopts
+ %type	<str>	optdep
+ %type	<list>	optdeps
  %type	<list>	defoptdeps
  %type	<str>	optfile_opt
  %type	<list>	subarches_opt subarches
***************
*** 301,308 ****
  	WORD				{ $$ = $1; };
  
  defoptdeps:
! 	':' defopts			{ $$ = $2; } |
  	/* empty */			{ $$ = NULL; };
  
  defopts:
  	defopts defopt			{ $$ = new_nx($2, $1); } |
--- 303,317 ----
  	WORD				{ $$ = $1; };
  
  defoptdeps:
! 	':' optdeps			{ $$ = $2; } |
  	/* empty */			{ $$ = NULL; };
+ 
+ optdeps:
+ 	optdeps ',' optdep		{ $$ = new_nx($3, $1); } |
+ 	optdep				{ $$ = new_n($1); };
+ 
+ optdep:
+ 	WORD				{ $$ = $1; };
  
  defopts:
  	defopts defopt			{ $$ = new_nx($2, $1); } |
Index: main.c
===================================================================
RCS file: /cvsroot/syssrc/usr.sbin/config/main.c,v
retrieving revision 1.71
diff -c -r1.71 main.c
*** main.c	2002/09/26 04:07:36	1.71
--- main.c	2002/10/11 01:12:57
***************
*** 339,351 ****
  do_depend(struct nvlist *nv)
  {
  	struct nvlist *nextnv;
  
! 	if (nv != NULL && !(nv->nv_flags & NV_DEPENDED)) {
  		nv->nv_flags |= NV_DEPENDED;
! 		if (ht_lookup(opttab, nv->nv_name) == NULL)
! 			addoption(nv->nv_name, NULL);
! 		if ((nextnv = find_declared_option(nv->nv_name)) != NULL)
! 			do_depend(nextnv->nv_ptr);
  	}
  }
  
--- 339,364 ----
  do_depend(struct nvlist *nv)
  {
  	struct nvlist *nextnv;
+ 	struct attr *a;
  
! 	if (nv != NULL && (nv->nv_flags & NV_DEPENDED) == 0) {
  		nv->nv_flags |= NV_DEPENDED;
! 		/*
! 		 * If the dependency is an attribute, then just add
! 		 * it to the selecttab.
! 		 */
! 		if ((a = ht_lookup(attrtab, nv->nv_name)) != NULL) {
! 			if (a->a_iattr)
! 				panic("do_depend(%s): dep `%s' is an iattr",
! 				    nv->nv_name, a->a_name);
! 			expandattr(a, selectattr);
! 		} else {
! 			if (ht_lookup(opttab, nv->nv_name) == NULL)
! 				addoption(nv->nv_name, NULL);
! 			if ((nextnv =
! 			     find_declared_option(nv->nv_name)) != NULL)
! 				do_depend(nextnv->nv_ptr);
! 		}
  	}
  }
  
***************
*** 491,497 ****
  
  /*
   * Search for a defined option (defopt, filesystem, etc), and if found,
!  * return the  option's struct nvlist.
   */
  struct nvlist *
  find_declared_option(const char *name)
--- 504,510 ----
  
  /*
   * Search for a defined option (defopt, filesystem, etc), and if found,
!  * return the option's struct nvlist.
   */
  struct nvlist *
  find_declared_option(const char *name)
***************
*** 519,525 ****
  defopt(struct hashtab *ht, const char *fname, struct nvlist *opts,
         struct nvlist *deps)
  {
! 	struct nvlist *nv, *nextnv, *oldnv;
  	const char *name, *n;
  	char *p, c;
  	char low[500];
--- 532,539 ----
  defopt(struct hashtab *ht, const char *fname, struct nvlist *opts,
         struct nvlist *deps)
  {
! 	struct nvlist *nv, *nextnv, *oldnv, *dep;
! 	struct attr *a;
  	const char *name, *n;
  	char *p, c;
  	char low[500];
***************
*** 568,573 ****
--- 582,604 ----
  
  		/* Use nv_ptr to link any other options that are implied. */
  		nv->nv_ptr = deps;
+ 		for (dep = deps; dep != NULL; dep = dep->nv_next) {
+ 			/*
+ 			 * If the dependency is an attribute, it must not
+ 			 * be an interface attribute.  Otherwise, is must
+ 			 * be a previously declared option.
+ 			 */
+ 			if ((a = ht_lookup(attrtab, dep->nv_name)) != NULL) {
+ 				if (a->a_iattr)
+ 					error("option `%s' dependency `%s' "
+ 					    "is an interface attribute",
+ 					    nv->nv_name, a->a_name);
+ 			} else if (find_declared_option(dep->nv_name) == NULL) {
+ 				error("option `%s' dependency `%s' "
+ 				    "is an unknown option",
+ 				    nv->nv_name, dep->nv_name);
+ 			}
+ 		}
  
  		/*
  		 * Remove this option from the parameter list before adding
Index: sem.c
===================================================================
RCS file: /cvsroot/syssrc/usr.sbin/config/sem.c,v
retrieving revision 1.34
diff -c -r1.34 sem.c
*** sem.c	2002/10/09 20:17:00	1.34
--- sem.c	2002/10/11 01:12:58
***************
*** 1287,1293 ****
  	return (0);
  }
  
! static void
  selectattr(struct attr *a)
  {
  
--- 1287,1293 ----
  	return (0);
  }
  
! void
  selectattr(struct attr *a)
  {
  
Index: sem.h
===================================================================
RCS file: /cvsroot/syssrc/usr.sbin/config/sem.h,v
retrieving revision 1.16
diff -c -r1.16 sem.h
*** sem.h	2002/10/09 20:17:00	1.16
--- sem.h	2002/10/11 01:12:58
***************
*** 57,62 ****
--- 57,63 ----
  struct deva    *getdevattach(const char *);
  struct attr    *getattr(const char *);
  void		expandattr(struct attr *, void (*)(struct attr *));
+ void		selectattr(struct attr *);
  void		setmajor(struct devbase *, int);
  void		addconf(struct config *);
  void		setconf(struct nvlist **, const char *, struct nvlist *);

--vtzGhvizbBRQ85DL
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=files-patch

Index: conf/files
===================================================================
RCS file: /cvsroot/syssrc/sys/conf/files,v
retrieving revision 1.569
diff -c -r1.569 files
*** conf/files	2002/10/11 01:00:35	1.569
--- conf/files	2002/10/11 01:12:45
***************
*** 73,78 ****
--- 73,88 ----
  				COMPAT_13 COMPAT_14 COMPAT_15 COMPAT_NOMID
  
  #
+ # Cryptography support.  Include this early, since several things
+ # use it.
+ #
+ include "crypto/arc4/files.arc4"
+ include "crypto/des/files.des"
+ include "crypto/blowfish/files.blowfish"
+ include "crypto/cast128/files.cast128"
+ include "crypto/rijndael/files.rijndael"
+ 
+ #
  # Networking protocols
  #
  include "netatalk/files.netatalk"
***************
*** 202,208 ****
  define	ieee1394
  define	token
  define	sppp
! define	wlan
  define	crypto
  
  # devices ARPing IPv4 pull this in:
--- 212,218 ----
  define	ieee1394
  define	token
  define	sppp
! define	wlan: arc4
  define	crypto
  
  # devices ARPing IPv4 pull this in:
***************
*** 880,886 ****
  #
  defpseudo vnd:		disk
  defpseudo ccd:		disk
! defpseudo cgd:		disk
  defpseudo md:		disk
  defpseudo netsmb
  
--- 890,896 ----
  #
  defpseudo vnd:		disk
  defpseudo ccd:		disk
! defpseudo cgd:		disk, des, blowfish, cast128, rijndael
  defpseudo md:		disk
  defpseudo netsmb
  
***************
*** 948,966 ****
  #
  # kernel sources
  #
- file	crypto/arc4/arc4.c		wlan
- file	crypto/des/des_ecb.c		(ipsec & ipsec_esp) | cgd
- file	crypto/des/des_setkey.c		(ipsec & ipsec_esp) | cgd
- file	crypto/des/des_enc.c		((ipsec & ipsec_esp) | cgd) &
- 					    !crypto_md_des_enc
- file    crypto/des/des_cbc.c		cgd & !crypto_md_des_cbc
- file	crypto/blowfish/bf_enc.c	((ipsec & ipsec_esp) | cgd) &
- 					    !crypto_md_bf_enc
- file	crypto/blowfish/bf_cbc.c	cgd & !crypto_md_bf_cbc
- file	crypto/blowfish/bf_skey.c	(ipsec & ipsec_esp) | cgd
- file	crypto/cast128/cast128.c	(ipsec & ipsec_esp) | cgd
- file	crypto/rijndael/rijndael-alg-fst.c (ipsec & ipsec_esp) | cgd
- file	crypto/rijndael/rijndael-api-fst.c (ipsec & ipsec_esp) | cgd
  file	ddb/db_access.c			ddb | kgdb
  file	ddb/db_aout.c			ddb
  file	ddb/db_break.c			ddb
--- 958,963 ----
Index: crypto/arc4/files.arc4
===================================================================
RCS file: files.arc4
diff -N files.arc4
*** /dev/null	Fri Oct 11 04:12:42 2002
--- files.arc4	Fri Oct 11 04:12:45 2002
***************
*** 0 ****
--- 1,5 ----
+ #	$NetBSD$
+ 
+ define	arc4
+ 
+ file	crypto/arc4/arc4.c		arc4
Index: crypto/blowfish/files.blowfish
===================================================================
RCS file: files.blowfish
diff -N files.blowfish
*** /dev/null	Fri Oct 11 04:12:42 2002
--- files.blowfish	Fri Oct 11 04:12:45 2002
***************
*** 0 ****
--- 1,7 ----
+ #	$NetBSD$
+ 
+ define	blowfish
+ 
+ file	crypto/blowfish/bf_enc.c	blowfish
+ file	crypto/blowfish/bf_cbc.c	blowfish
+ file	crypto/blowfish/bf_skey.c	blowfish
Index: crypto/cast128/files.cast128
===================================================================
RCS file: files.cast128
diff -N files.cast128
*** /dev/null	Fri Oct 11 04:12:42 2002
--- files.cast128	Fri Oct 11 04:12:45 2002
***************
*** 0 ****
--- 1,5 ----
+ #	$NetBSD$
+ 
+ define	cast128
+ 
+ file	crypto/cast128/cast128.c	cast128
Index: crypto/des/files.des
===================================================================
RCS file: files.des
diff -N files.des
*** /dev/null	Fri Oct 11 04:12:42 2002
--- files.des	Fri Oct 11 04:12:45 2002
***************
*** 0 ****
--- 1,8 ----
+ #	$NetBSD$
+ 
+ define	des
+ 
+ file	crypto/des/des_ecb.c		des
+ file	crypto/des/des_setkey.c		des
+ file	crypto/des/des_enc.c		des & !crypto_md_des_enc
+ file	crypto/des/des_cbc.c		des & !crypto_md_des_cbc
Index: crypto/rijndael/files.rijndael
===================================================================
RCS file: files.rijndael
diff -N files.rijndael
*** /dev/null	Fri Oct 11 04:12:42 2002
--- files.rijndael	Fri Oct 11 04:12:45 2002
***************
*** 0 ****
--- 1,6 ----
+ #	$NetBSD$
+ 
+ define	rijndael
+ 
+ file	crypto/rijndael/rijndael-alg-fst.c	rijndael
+ file	crypto/rijndael/rijndael-api-fst.c	rijndael
Index: netinet6/files.netipsec
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet6/files.netipsec,v
retrieving revision 1.1
diff -c -r1.1 files.netipsec
*** netinet6/files.netipsec	2002/10/10 22:45:46	1.1
--- netinet6/files.netipsec	2002/10/11 01:12:45
***************
*** 1,6 ****
  #	$NetBSD: files.netipsec,v 1.1 2002/10/10 22:45:46 thorpej Exp $
  
! defflag opt_ipsec.h		IPSEC IPSEC_ESP
  
  file	netinet6/ah_core.c		ipsec
  file	netinet6/ah_input.c		ipsec
--- 1,7 ----
  #	$NetBSD: files.netipsec,v 1.1 2002/10/10 22:45:46 thorpej Exp $
  
! defflag opt_ipsec.h		IPSEC
! defflag opt_ipsec.h		IPSEC_ESP: des, blowfish, cast128, rijndael
  
  file	netinet6/ah_core.c		ipsec
  file	netinet6/ah_input.c		ipsec

--vtzGhvizbBRQ85DL--