Date: Tue, 07 Jul 2009 07:05:45 +0900 (JST) From: Hiroki Sato <hrs@FreeBSD.org> To: freebsd-rc@FreeBSD.org Cc: freebsd-current@FreeBSD.org Subject: RFC: set_rcvar in rc.subr Message-ID: <20090707.070545.02771440.hrs@allbsd.org>
next in thread | raw e-mail | index | archive | help
----Security_Multipart0(Tue_Jul__7_07_05_45_2009_685)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Tue_Jul__7_07_05_45_2009_646)--" Content-Transfer-Encoding: 7bit ----Next_Part(Tue_Jul__7_07_05_45_2009_646)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, I would like to propose an expansion of set_rcvar() in rc.subr. The motivation and the change are the following. The current rc.d scripts depend on variables defined in /etc/defaults/rc.conf. However, it is unclear that which variables are used in a script and assigning a default value to a variable is scattered and inconsistent. Also, it is difficult to detect definition of obsolete variables in /etc/rc.conf and /etc/defaults/rc.conf. The proposed changes are: 1. Add a functionality to declare a rc.conf variable and its default value to set_rcvar(). The syntax is: set_rcvar <varname> <defvalue> <desc> The declared variables are set by load_rc_config(). Note that this behavior of set_rcvar() is backward compatible. For example, a script for routed(8) will be something like this: ---- name="routed" rcvar=`set_rcvar` set_rcvar ${name}_enable NO set_rcvar ${name}_flags "-q" \ "Flags for ${name}(8)." set_rcvar ${name}_program "/usr/sbin/routed" \ "Program name for ${name}(8)." load_rc_config $name run_rc_command "$1" ---- 2. Display the declared variables by "rc.d/foo rcvar" with the default value and description like this: % /etc/rc.d/routed rcvar # routed : network RIP and router discovery routing daemon # routed_enable="NO" # (default: "NO") routed_flags="-q" # - Flags for routed(8). # (default: "-q") routed_program="/sbin/routed" # - Program name for routed(8). # (default: "/usr/sbin/routed") It should be easier to understand the variables than the current /etc/defaults/rc.conf and always consistent. To do this, all of rc.d scripts have to have run_rc_command() while currently some scripts which always run have no $rcvar and run_rc_command(). Adding run_rc_command() becomes no problem and rather good for consistency, IMHO. Also, $desc is added for description of the script displayed in above example. Entries for each rc.d script in /etc/defaults/rc.conf can be removed, and the equivalent contents can be generated by the following command: # for F in `rcorder /etc/rc.d/*`; do $F rcvar; done 3. Add a way to obsolete a variable. This is done by adding set_rcvar_obsolete() function. set_rcvar_obsolete <oldvar> <newvar> If <oldvar> is defined, do newvar=$oldvar and display a warning in load_rc_config(). This makes easier to detect an obsolete variable in an old rc.conf file. The attached patch is a working example. If there is no strong objection I want to convert all of the current rc.d scripts in this way. Note that this patch include a change not directly related to the above; handling $_override_command in run_rc_command() looks wrong to me. When ${name}_program is defined and $command is not the former is used as the command, and if $command is defined directly it is used by priority. Comments or objections? -- Hiroki ----Next_Part(Tue_Jul__7_07_05_45_2009_646)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rc_set_rcvar.diff" Index: rc.subr =================================================================== --- rc.subr (revision 195284) +++ rc.subr (working copy) @@ -72,38 +72,64 @@ # functions # --------- +# set_rcvar [var] [defval] [desc] # -# set_rcvar base_var -# Set the variable name enabling a specific service. -# FreeBSD uses ${service}_enable, while NetBSD uses -# just the name of the service. For example: -# FreeBSD: sendmail_enable="YES" -# NetBSD : sendmail="YES" -# $1 - if $name is not the base to work of off, specify -# a different one +# Echo or define a rc.conf(5) variable name. Global variable +# $rcvars is used. # +# If no argument is specified, echo "${name}_enable". +# +# If only a var is specified, echo "${var}_enable". +# +# If var and defval are specified, the ${var} is defined as +# rc.conf(5) variable and the default value is ${defvar}. An +# optional argument $desc can also be specified to add a +# description for that. +# set_rcvar() { - if [ -z "$1" ]; then - base_var=${name} - else - base_var="$1" - fi - - case ${OSTYPE} in - FreeBSD) - echo ${base_var}_enable + case $# in + 0) + echo ${name}_enable ;; - NetBSD) - echo ${base_var} + 1) + echo ${1}_enable ;; *) - echo 'XXX' + debug "rcvar_define: \$$1=$2 is added" \ + " as a rc.conf(5) variable." + + local _var + _var=$1 + rcvars="${rcvars# } $_var" + eval ${_var}_defval=\"$2\" + shift 2 + # encode multiple lines of _desc + for l in "$@"; do + eval ${_var}_desc=\"\${${_var}_desc#^^}^^$l\" + done + eval ${_var}_desc=\"\${${_var}_desc#^^}\" ;; esac } +# set_rcvar_obsolete oldvar [newvar] [msg] +# Define obsolete variable. +# Global variable $rcvars_obsolete is used. # +set_rcvar_obsolete() +{ + local _var + _var=$1 + debug "rcvar_obsolete: \$$1(old) -> \$$2(new) is defined" + + rcvars_obsolete="${rcvars_obsolete# } $1" + eval ${1}_newvar=\"$2\" + shift 2 + eval ${_var}_obsolete_msg=\"$*\" +} + +# # force_depend script # Force a service to start. Intended for use by services # to resolve dependency issues. It is assumed the caller @@ -401,6 +427,8 @@ # command_interpreter n If not empty, command is interpreted, so # call check_{pidfile,process}() appropriately. # +# desc n Description of script. +# # extra_commands n List of extra commands supported. # # pidfile n If set, use check_pidfile $pidfile $command, @@ -574,7 +602,7 @@ esac eval _override_command=\$${name}_program - command=${command:+${_override_command:-$command}} + command=${command:-${_override_command}} _keywords="start stop restart rcvar $extra_commands" rc_pid= @@ -778,14 +806,49 @@ ;; rcvar) - echo "# $name" - if [ -n "$rcvar" ]; then - if checkyesno ${rcvar}; then - echo "${rcvar}=YES" - else - echo "${rcvar}=NO" + echo -n "# $name" + if [ -n "$desc" ]; then + echo " : $desc" + else + echo "" + fi + echo "#" + # Get unique vars in $rcvar $rcvars + for _v in $rcvar $rcvars; do + case $v in + $_v\ *|\ *$_v|*\ $_v\ *) ;; + *) v="${v# } $_v" ;; + esac + done + + # Display variables. + for _v in $v; do + if [ -z "$_v" ]; then + continue fi - fi + + eval _desc=\$${_v}_desc + eval _defval=\$${_v}_defval + _h="-" + + eval echo \"$_v=\\\"\$$_v\\\"\" + # decode multiple lines of _desc + while [ -n "$_desc" ]; do + case $_desc in + *^^*) + echo "# $_h ${_desc%%^^*}" + _desc=${_desc#*^^} + _h=" " + ;; + *) + echo "# $_h ${_desc}" + break + ;; + esac + done + echo "# (default: \"$_defval\")" + done + echo "" ;; *) @@ -896,7 +959,8 @@ unset name command command_args command_interpreter \ extra_commands pidfile procname \ - rcvar required_dirs required_files required_vars + rcvar rcvars rcvars_obsolete required_dirs required_files \ + required_vars eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd case "$_file" in @@ -927,6 +991,7 @@ # load_rc_config() { + local _name _var _defval _v _msg _new _name=$1 if [ -z "$_name" ]; then err 3 'USAGE: load_rc_config name' @@ -953,6 +1018,36 @@ # Old variable names support # [ -n "$enable_quotas" ] && quota_enable="$enable_quotas" + + # Set defaults if defined. + for _var in $rcvar $rcvars; do + _defval=`eval echo "\\\$${_var}_defval"` + if [ -n "$_defval" ]; then + eval : \${$_var:=\$${_var}_defval} + fi + done + + # check obsolete rc.conf variables + for _var in $rcvars_obsolete; do + _v=`eval echo \\$$_var` + _msg=`eval echo \\$${_var}_obsolete_msg` + _new=`eval echo \\$${_var}_newvar` + case $_v in + "") + ;; + *) + if [ -z "$_new" ]; then + _msg="Ignored." + else + eval $_new=\"\$$_var\" + if [ -z "$_msg" ]; then + _msg="Use \$$_new instead." + fi + fi + warn "\$$_var is obsolete. $_msg" + ;; + esac + done } # Index: rc.d/routed =================================================================== --- rc.d/routed (revision 195284) +++ rc.d/routed (working copy) @@ -10,13 +10,17 @@ . /etc/rc.subr name="routed" +desc="network RIP and router discovery routing daemon" +rcvar=`set_rcvar` -# XXX - Executable may be in a different location. The $name variable -# is different from the variable in rc.conf(5) so the -# subroutines in rc.subr won't catch it. -# +set_rcvar ${name}_enable NO +set_rcvar ${name}_flags "-q" \ + "Flags for ${name}(8)." +set_rcvar ${name}_program "/sbin/routed" \ + "Program name for ${name}(8)." +set_rcvar_obsolete router_enable routed_enable +set_rcvar_obsolete router routed_program +set_rcvar_obsolete router_flags routed_flags + load_rc_config $name -rcvar="router_enable" -command="${router:-/sbin/${name}}" -eval ${name}_flags=\"${router_flags}\" run_rc_command "$1" ----Next_Part(Tue_Jul__7_07_05_45_2009_646)---- ----Security_Multipart0(Tue_Jul__7_07_05_45_2009_685)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (FreeBSD) iEYEABECAAYFAkpSdTkACgkQTyzT2CeTzy3ZeACfTdSNAkynvEEwSXu9Y3/voeUb gdgAoJcBSN5Pljxqo0y/SCK2AkQjUlw0 =wRkO -----END PGP SIGNATURE----- ----Security_Multipart0(Tue_Jul__7_07_05_45_2009_685)----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090707.070545.02771440.hrs>