[CFT] multiple instance support in rc.d script
Allan Jude
allanjude at freebsd.org
Fri Oct 17 03:41:39 UTC 2014
On 2014-10-16 21:22, Hiroki Sato wrote:
> [Please reply to freebsd-rc@]
>
> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 834 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freebsd.org/pipermail/freebsd-current/attachments/20141016/9466cd82/attachment.sig>
More information about the freebsd-current
mailing list