Re: [CFT] multiple instance support in rc.d script

From: Allan Jude <allanjude_at_freebsd.org>
Date: Thu, 16 Oct 2014 23:41:39 -0400
On 2014-10-16 21:22, Hiroki Sato wrote:
> [Please reply to freebsd-rc_at_]
> 
> Hi,
> 
>  I would like your feedback and testers of the attached patch.  This
>  implements multiple instance support in rc.d scripts.  You can try it
>  by replacing /etc/rc.subr with the attached one.
> 
>  More details are as follow.  Typically, an rc.d/foo script has the
>  following structure and rc.conf variables:
> 
>    /etc/rc.d/foo:
>    ----
>    name=foo
>    rcvar=foo_enable
>    ...
>    load_rc_command $name
>    run_rc_command $*
>    ----
> 
>    /etc/rc.conf:
>    ----
>    foo_enable="YES"
>    foo_flags="-f -l -a -g"
>    ----
> 
>  The above supports one instance for one script.  After replacing
>  rc.subr, you can specify additional instances in rc.conf:
> 
>    /etc/rc.conf:
>    ----
>    foo_instances="one two"
> 
>    foo_one_enable="YES"
>    foo_one_flags="-f -l -a -g"
> 
>    foo_two_enable="YES"
>    foo_two_flags="-F -L -A -G"
>    ----
> 
>  $foo_instances defines instances by space-separated list of instance
>  names, and rc.conf variables for them are something like
>  ${name}_${instname}_enable.  The following command
> 
>   # service foo start
> 
>  starts foo_one and foo_two with the specified flags.  Instances can
>  be specified in the following form:
> 
>   # service foo start:one
> 
>  or multiple instances in a particular order:
> 
>   # service foo start:two,one
> 
>  Basically, no change is required for the rc.d/foo script itself.
>  However, there is a problem that default values of the instantiated
>  variables are not defined.
> 
>  For example, if an rc.d/script uses $foo_mode, you need to define
>  $foo_one_mode.  The default value of $foo_mode is usually defined in
>  etc/defaults/rc.conf for rc.d scripts in the base system and ":
>  ${foo_mode:=value}" idiom in scripts from Ports Collection.  So all
>  of the variables should be defined for each instance, too.  As you
>  noticed, this is not easy without editing the script itself.
> 
>  To alleviate this, set_rcvar() can be used:
> 
>    /etc/rc.d/foo:
>    ----
>    name=foo
>    rcvar=foo_enable
> 
>    set_rcvar foo_enable		YES		"Enable $name"
>    set_rcvar foo_program	"/tmp/test"	"Command for $name"
>    ...
>    load_rc_command $name
>    run_rc_command $*
>    ----
> 
>  The three arguments are varname, default value, and description.  If
>  a variable is defined by set_rcvar(), default values instantiated
>  variables will be set automatically---foo_one_program is set by
>  foo_program if it is not defined.
> 
>  This approach still has another problem.  set_rcvar() is not
>  supported in all branches, so a script using it does not work in old
>  supported branches.  One solution which can be used for scripts in
>  Ports Collection is adding both definitions before and after
>  load_rc_command() until EoL of old branches like this:
> 
>    /etc/rc.d/foo:
>    ----
>    name=foo
>    rcvar=foo_enable
> 
>    if type set_rcvar >/dev/null 2>&1; then
> 	set_rcvar foo_enable	YES		"Enable $name"
> 	set_rcvar foo_program	"/tmp/test"	"Command for $name"
>    fi
>    ...
>    load_rc_command $name
> 
>    # will be removed after all supported branches have set_rcvar().
>    if ! type set_rcvar >/dev/null 2>&1; then
> 	: ${foo_enable:="YES"}
> 	: ${foo_program:="/tmp/test"}
> 	for _i in $foo_instances; do
> 		for _j in enable program; do
> 			eval : \${foo_${_i}_enable:=\$foo_$_j}
> 		done
> 	done
>    fi
> 
>    run_rc_command $*
>    ----
> 
>  This is a bit ugly but should work fine.
> 
>  I am using this patch to invoke multiple named (caching
>  server/contents server) and syslogd (local only/listens INET/INET6
>  socket only) daemons.  While $foo_instances is designed as a
>  user-defined knob, this can be applied to software which need to
>  invoke multiple/different daemons which depend on each other in a
>  script, too.
> 
>  I am feeling this patch still needs more careful review from others.
>  Any comments are welcome.  Thank you.
> 
> -- Hiroki
> 

This feature is quite useful. I've used the built in version that the
rc.d script in memcached and it is very helpful to be able to run
multiple named instances.

I wonder if sysrc could be improved to support an 'append', so you can have:

foo_instances="one two"

and do:
sysrc --append foo_instances=three

to get:
foo_instances="one two three"

instead of having to do:

sysrc foo_instances="`sysrc -n foo_instances` three"

or something more convoluted

-- 
Allan Jude


Received on Fri Oct 17 2014 - 01:41:39 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:53 UTC