mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-19 23:03:55 +00:00
Update rc(8) manpage to reflect rc.d
Add an rc.subr(8) manpage Hook rc.subr.8 up to the build. Submitted by: Mike Makonnen <mtm@identd.net> Approved by: re@ (bmah) Obtained from: NetBSD
This commit is contained in:
parent
fc7cd97211
commit
54e347fb3b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=107143
|
@ -8,6 +8,7 @@ MAN= adding_user.8 \
|
|||
picobsd.8 \
|
||||
rc.8 \
|
||||
rc.sendmail.8 \
|
||||
rc.subr.8 \
|
||||
sticky.8 \
|
||||
yp.8
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
.\" Copyright (c) 1980, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Portions of this manual page are Copyrighted by
|
||||
.\" The NetBSD Foundation.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
|
@ -32,7 +35,7 @@
|
|||
.\" @(#)rc.8 8.2 (Berkeley) 12/11/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 11, 1993
|
||||
.Dd November 4, 2002
|
||||
.Dt RC 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -40,52 +43,271 @@
|
|||
.Nd command scripts for auto\-reboot and daemon startup
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Nm rc.d/
|
||||
.Nm rc.d/atm*
|
||||
.Nm rc.d/network*
|
||||
.Nm rc.d/pccard
|
||||
.Nm rc.d/serial
|
||||
.Nm rc.conf
|
||||
.Nm rc.conf.local
|
||||
.Nm rc.early
|
||||
.Nm rc.d
|
||||
.Nm rc.serial
|
||||
.Nm rc.pccard
|
||||
.Nm rc.network
|
||||
.Nm rc.firewall
|
||||
.Nm rc.atm
|
||||
.Nm rc.<arch>
|
||||
.Nm rc.local
|
||||
.Nm rc.shutdown
|
||||
.Nm rc.subr
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility is the command script which controls the automatic reboot
|
||||
(calling the other scripts) and
|
||||
utility is the command script which controls the automatic boot process
|
||||
after being called by
|
||||
.Xr init 8 .
|
||||
The
|
||||
.Nm rc.local
|
||||
is the script holding commands which are pertinent only
|
||||
to a specific site. Typically, the /usr/local/etc/rc.d
|
||||
mechanism is used instead of rc.local these days but if
|
||||
you do want to use rc.local, /etc/rc still supports it.
|
||||
In this case, rc.local should source /etc/rc.conf and
|
||||
contain additional custom startup code for your system.
|
||||
script contains commands which are pertinent only
|
||||
to a specific site. Typically, the
|
||||
.Nm /usr/local/etc/rc.d
|
||||
mechanism is used instead of
|
||||
.Nm rc.local
|
||||
these days but if
|
||||
you want to use
|
||||
.Nm rc.local
|
||||
it is still supported. In this case it should source
|
||||
.Nm /etc/rc.conf
|
||||
and contain additional custom startup code for your system.
|
||||
The best way to handle
|
||||
.Nm rc.local ;
|
||||
however, is to separate it out into
|
||||
.Nm /etc/rc.d
|
||||
style scripts and place them in
|
||||
.Nm /usr/local/etc/rc.d .
|
||||
The
|
||||
.Nm rc.conf
|
||||
file contains the global system configuration information referenced
|
||||
by the rc files, while
|
||||
by the startup scripts, while
|
||||
.Nm rc.conf.local
|
||||
contains the local system configuration.
|
||||
See
|
||||
.Xr rc.conf 5 .
|
||||
.Xr rc.conf 5
|
||||
for more information.
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.d
|
||||
directories contain scripts which will be automatically
|
||||
executed at boot time and shutdown time.
|
||||
At boot time,
|
||||
the specified directories are processed immediately after
|
||||
.Nm rc.local
|
||||
is executed.
|
||||
(See below for details on how to specify directories to check.)
|
||||
At shutdown time,
|
||||
the directories are processed by
|
||||
.Nm rc.shutdown .
|
||||
The following key points apply to the scripts within each directory:
|
||||
.Ss Operation of rc
|
||||
.Bl -enum
|
||||
.It
|
||||
Source
|
||||
.Pa /etc/rc.subr
|
||||
to load various
|
||||
.Xr rc.subr 8
|
||||
shell functions to use.
|
||||
.It
|
||||
If autobooting, set
|
||||
.Sy autoboot=yes
|
||||
and enable a flag
|
||||
.Sy ( rc_fast=yes ) ,
|
||||
which prevents the
|
||||
.Nm rc.d
|
||||
scripts from performing the check for already running processes
|
||||
(thus speeding up the boot process).
|
||||
This
|
||||
.Sy rc_fast=yes
|
||||
speedup won't occur when
|
||||
.Nm
|
||||
is started up after exiting the single-user shell.
|
||||
.It
|
||||
Invoke
|
||||
.Xr rcorder 8
|
||||
to order the files in
|
||||
.Pa /etc/rc.d/
|
||||
that do not have a
|
||||
.Dq nostart
|
||||
keyword (refer to
|
||||
.Xr rcorder 8 's
|
||||
.Fl s
|
||||
flag),
|
||||
and assigns the result to a variable.
|
||||
.It
|
||||
Calls each script in turn using run_rc_script() (from
|
||||
.Xr rc.subr 8 ) ,
|
||||
which sets
|
||||
.Dv $1
|
||||
to
|
||||
.Sq start ,
|
||||
and sources the script in a subshell.
|
||||
If the script has a
|
||||
.Sq .sh
|
||||
suffix then it is sourced directly into the current shell.
|
||||
.El
|
||||
.Ss Operation of rc.shutdown
|
||||
.Bl -enum
|
||||
.It
|
||||
Source
|
||||
.Pa /etc/rc.subr
|
||||
to load various
|
||||
.Xr rc.subr 8
|
||||
shell functions to use.
|
||||
.It
|
||||
Invoke
|
||||
.Xr rcorder 8
|
||||
to order the files in
|
||||
.Pa /etc/rc.d/
|
||||
that have a
|
||||
.Dq shutdown
|
||||
keyword (refer to
|
||||
.Xr rcorder 8 's
|
||||
.Fl k
|
||||
flag),
|
||||
reverses that order, and assigns the result to a variable.
|
||||
.It
|
||||
Calls each script in turn using run_rc_script() (from
|
||||
.Xr rc.subr 8 ) ,
|
||||
which sets
|
||||
.Dv $1
|
||||
to
|
||||
.Sq stop ,
|
||||
and sources the script in a subshell.
|
||||
If the script has a
|
||||
.Sq .sh
|
||||
suffix then it is sourced directly into the current shell.
|
||||
.El
|
||||
.Ss Contents of rc.d/
|
||||
.Nm rc.d/
|
||||
is located in
|
||||
.Pa /etc/rc.d .
|
||||
The following file naming conventions are currently used in
|
||||
.Nm rc.d/ :
|
||||
.Bl -tag -width ALLUPPERCASExx -offset indent
|
||||
.It Pa ALLUPPERCASE
|
||||
Scripts that are
|
||||
.Sq placeholders
|
||||
to ensure that certain operations are performed before others.
|
||||
In order of startup, these are:
|
||||
.Bl -tag -width NETWORKINGxx
|
||||
.It Pa NETWORKING
|
||||
Ensure basic network services are running, including general
|
||||
network configuration (
|
||||
.Pa network1,
|
||||
.Pa network2
|
||||
.Pa network3 ) .
|
||||
.It Pa SERVERS
|
||||
Ensure basic services (such as
|
||||
.Pa NETWORKING ,
|
||||
.Pa ppp-user ,
|
||||
.Pa syslogd ,
|
||||
and
|
||||
.Pa isdnd )
|
||||
exist for services that start early (such as
|
||||
.Pa named ) ,
|
||||
because they're required by
|
||||
.Pa DAEMON
|
||||
below.
|
||||
.It Pa DAEMON
|
||||
Check-point before all general purpose daemons such as
|
||||
.Pa lpd
|
||||
and
|
||||
.Pa ntpd .
|
||||
.It Pa LOGIN
|
||||
Check-point before user login services
|
||||
.Pa ( inetd
|
||||
and
|
||||
.Pa sshd ) ,
|
||||
as well as services which might run commands as users
|
||||
.Pa ( cron
|
||||
and
|
||||
.Pa sendmail ) .
|
||||
.El
|
||||
.It Pa foo.sh
|
||||
Scripts that are to be sourced into the current shell rather than a subshell
|
||||
have a
|
||||
.Sq Pa .sh
|
||||
suffix.
|
||||
Extreme care must be taken in using this, as the startup sequence will
|
||||
terminate if the script does.
|
||||
.It Pa bar
|
||||
Scripts that are sourced in a subshell.
|
||||
These can stop the boot if necessary with the following shell
|
||||
commands:
|
||||
.Bd -literal -offset
|
||||
if [ "$autoboot" = yes ]; then
|
||||
kill -TERM $$
|
||||
fi
|
||||
exit 1
|
||||
.Ed
|
||||
.Pp
|
||||
Note that this should be used extremely sparingly!
|
||||
.El
|
||||
.Pp
|
||||
Each script should contain
|
||||
.Xr rcorder 8
|
||||
keywords, especially an appropriate
|
||||
.Dq PROVIDE
|
||||
entry, and if necessary
|
||||
.Dq REQUIRE
|
||||
and
|
||||
.Dq BEFORE
|
||||
keywords. In addition, all scripts must have a
|
||||
.Dq # KEYWORD: FreeBSD
|
||||
line.
|
||||
.Pp
|
||||
Each script is expected to support at least the following arguments, which
|
||||
are automatically supported if it uses the run_rc_command() function.
|
||||
.Bl -tag -width restart -offset indent
|
||||
.It Sy start
|
||||
Start the service.
|
||||
This should check that the service is to be started as specified by
|
||||
.Xr rc.conf 5 .
|
||||
Also checks if the service is already running and refuses to start if
|
||||
it is.
|
||||
This latter check is not performed by standard
|
||||
.Fx
|
||||
scripts if the system is starting directly to multi-user mode, to
|
||||
speed up the boot process.
|
||||
If
|
||||
.Sq forcestart
|
||||
is given, ignore the
|
||||
.Xr rc.conf 5
|
||||
check and start anyway.
|
||||
.It Sy stop
|
||||
If the service is to be started as specified by
|
||||
.Xr rc.conf 5 ,
|
||||
stop the service.
|
||||
This should check that the service is running and complain if it's not.
|
||||
If
|
||||
.Sq forcestop
|
||||
is given, ignore the
|
||||
.Xr rc.conf 5
|
||||
check and attempt to stop.
|
||||
.It Sy restart
|
||||
Perform a
|
||||
.Sy stop
|
||||
then a
|
||||
.Sy start .
|
||||
.It Sy status
|
||||
If the script starts a process (rather than performing a one-off
|
||||
operation), show the status of the process.
|
||||
Otherwise it's not necessary to support this argument.
|
||||
Defaults to displaying the process ID of the program (if running).
|
||||
.It Sy poll
|
||||
If the script starts a process (rather than performing a one-off
|
||||
operation), wait for the command to exit.
|
||||
Otherwise it's not necessary to support this argument.
|
||||
.It Sy rcvar
|
||||
Display which
|
||||
.Xr rc.conf 5
|
||||
variables are used to control the startup of the service (if any).
|
||||
.El
|
||||
.Pp
|
||||
If a script must implement additional commands it can list them in
|
||||
the
|
||||
.Sq extra_commands
|
||||
variable and define their actions in a variable constructed from
|
||||
the command name (see the
|
||||
.Sx EXAMPLES
|
||||
section).
|
||||
.Pp
|
||||
The following key points apply to old-style scripts in
|
||||
.Nm /usr/local/etc/rc.d :
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
|
@ -118,16 +340,52 @@ so for example
|
|||
would be executed before
|
||||
.Pa 200.bar ;
|
||||
without the numeric prefixes the opposite would be true.
|
||||
.El
|
||||
.Pp
|
||||
.It
|
||||
The output from each script is traditionally a space character,
|
||||
followed by the name of the software package being started or shut down,
|
||||
.Em without
|
||||
a trailing newline character (see the
|
||||
.Sx EXAMPLES
|
||||
section).
|
||||
.El
|
||||
.Sh Scripts of Interest
|
||||
When an automatic reboot is in progress,
|
||||
.Nm
|
||||
is invoked with the argument
|
||||
.Em autoboot .
|
||||
One of the scripts run from
|
||||
.Nm /etc/rc.d
|
||||
is
|
||||
.Pa /etc/rc.d/fsck .
|
||||
This script runs
|
||||
.Xr fsck 8
|
||||
with option
|
||||
.Fl p
|
||||
and
|
||||
.Fl F
|
||||
to ``preen'' all the disks of minor inconsistencies resulting
|
||||
from the last system shutdown. If this fails, then checks/repairs of serious inconsistencies
|
||||
caused by hardware or software failure will be performed in the background at the end
|
||||
of the booting process. If
|
||||
.Em autoboot
|
||||
is not set, when going from single-user to multi-user mode for example, the script
|
||||
does not do anything.
|
||||
.Pp
|
||||
The system initialization scripts can execute scripts from multiple
|
||||
The
|
||||
.Nm rc.early
|
||||
script is run very early in the startup process, immediately before the
|
||||
filesystem check. The
|
||||
.Nm rc.early
|
||||
script is deprecated. Any commands in this
|
||||
file should be separated out into
|
||||
.Nm rc.d
|
||||
style scripts and integrated into the
|
||||
.Nm rc
|
||||
system.
|
||||
.Pp
|
||||
The
|
||||
.Nm /etc/rc.d/local
|
||||
script can execute scripts from multiple
|
||||
.Nm rc.d
|
||||
directories.
|
||||
The default locations are
|
||||
|
@ -140,59 +398,27 @@ but these may be overridden with the
|
|||
variable.
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.shutdown
|
||||
script contains any necessary commands
|
||||
to be executed as the system is shut down.
|
||||
.Pp
|
||||
When an automatic reboot is in progress,
|
||||
.Nm
|
||||
is invoked with the argument
|
||||
.Em autoboot .
|
||||
The first portion of
|
||||
.Nm
|
||||
runs an
|
||||
.Xr fsck 8
|
||||
with option
|
||||
.Fl p
|
||||
to ``preen'' all the disks of minor inconsistencies resulting
|
||||
from the last system shutdown and to check for serious inconsistencies
|
||||
caused by hardware or software failure.
|
||||
If this auto-check and repair succeeds, then the second part of
|
||||
.Nm
|
||||
is run.
|
||||
.Pp
|
||||
The second part of
|
||||
.Nm ,
|
||||
which is run after an auto-reboot succeeds and also if
|
||||
.Nm
|
||||
is invoked when a single user shell terminates (see
|
||||
.Xr init 8 ) ,
|
||||
starts all the daemons on the system, preserves editor files
|
||||
and clears the scratch directory
|
||||
.Pa /tmp .
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.early
|
||||
script is run very early in the startup process, immediately before the
|
||||
filesystem check.
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.serial
|
||||
.Nm /etc/rc.d/serial
|
||||
script is used to set any special configurations for serial devices.
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.pccard
|
||||
.Nm /etc/rc.d/pccard
|
||||
script is used to enable PC-cards.
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.network
|
||||
script is used to start the network.
|
||||
.Nm /etc/rc.d/network*
|
||||
scripts are used to start the network.
|
||||
The network is started in three passes.
|
||||
The first pass sets the hostname and domainname, configures the network
|
||||
interfaces, turns on any IP firewall rules, and starts routing.
|
||||
The second pass starts most of the network related daemons.
|
||||
The third pass starts NFS, amd, rwhod, Kerberos and
|
||||
the multicast routing daemon.
|
||||
The first pass,
|
||||
.Nm /etc/rc.d/network1 ,
|
||||
sets the hostname and domainname and configures the network
|
||||
interfaces. The
|
||||
.Nm /etc/rc.d/network2
|
||||
script starts routing and sets routing options. The
|
||||
.Nm /etc/rc.d/network3
|
||||
script sets additional networking options. Lastly, the
|
||||
.Nm /etc/rc.d/network_ipv6
|
||||
script configures IPv6 interfaces and options.
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.firewall
|
||||
|
@ -216,33 +442,80 @@ will load the rules in the given filename (full path required).
|
|||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.atm
|
||||
script is used to configure ATM network interfaces.
|
||||
.Nm /etc/rc.d/atm*
|
||||
scripts are used to configure ATM network interfaces.
|
||||
The interfaces are configured in three passes.
|
||||
The first pass performs the initial interface configuration.
|
||||
The second pass completes the interface configuration and defines PVCs and
|
||||
permanent ATMARP entries.
|
||||
The third pass starts any ATM daemons.
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.<arch>
|
||||
script runs architecture specific programs.
|
||||
Most daemons, including network related daemons, have their own script in
|
||||
.Nm /etc/rc.d ,
|
||||
which can be used to start, stop, and check the status of the service.
|
||||
.Pp
|
||||
The
|
||||
.Nm rc.local
|
||||
script is executed after the scripts above, but before the rest of the
|
||||
.Nm
|
||||
file is completed.
|
||||
In a default installation
|
||||
.Nm rc.local
|
||||
does not exist, but its contents will be executed if the file is created
|
||||
by the administrator.
|
||||
Any architecture specific scripts, such as
|
||||
.Pa /etc/rc.d/apm
|
||||
for example, specifically check that they are on that architecture
|
||||
before starting the daemon.
|
||||
.Pp
|
||||
Following tradition, the startup files reside in
|
||||
Following tradition, all startup files reside in
|
||||
.Pa /etc .
|
||||
.Sh EXAMPLES
|
||||
The following is a simple, hypothetical example of an
|
||||
.Nm rc.d
|
||||
The following is a minimal
|
||||
.Nm /etc/rc.d
|
||||
style script. Most scripts require little more than the following.
|
||||
.Bd -literal -offset indent
|
||||
#!/bin/sh
|
||||
#
|
||||
|
||||
# PROVIDE: foo
|
||||
# REQUIRE: bar_service_required_to_precede_foo
|
||||
# BEFORE: baz_service_requiring_foo_to_precede_it
|
||||
# KEYWORD: FreeBSD
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
name="foo"
|
||||
rcvar=`set_rcvar`
|
||||
command="/usr/local/bin/foo"
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$1"
|
||||
.Ed
|
||||
.Pp
|
||||
Certain scripts may want to provide enhanced functionality. The
|
||||
user may access this functionality through additional commands. The
|
||||
script may list and define as many commands at it needs.
|
||||
.Bd -literal -offset indent
|
||||
#!/bin/sh
|
||||
#
|
||||
|
||||
# PROVIDE: foo
|
||||
# REQUIRE: bar_service_required_to_precede_foo
|
||||
# BEFORE: baz_service_requiring_foo_to_precede_it
|
||||
# KEYWORD: FreeBSD
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
name="foo"
|
||||
rcvar=`set_rcvar`
|
||||
command="/usr/local/bin/foo"
|
||||
extra_commands="nop hello"
|
||||
hello_cmd="echo Hello World."
|
||||
nop_cmd="do_nop"
|
||||
|
||||
do_nop()
|
||||
{
|
||||
echo "I do nothing."
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$1"
|
||||
.Ed
|
||||
.Pp
|
||||
The following is a simple, hypothetical example of an old-style
|
||||
.Nm /usr/local/etc/rc.d
|
||||
script,
|
||||
which would start a daemon at boot time,
|
||||
and kill it at shutdown time.
|
||||
|
@ -273,6 +546,8 @@ is unnecessary, but is often included.
|
|||
.Xr kill 1 ,
|
||||
.Xr rc.conf 5 ,
|
||||
.Xr init 8 ,
|
||||
.Xr rc.subr 8 ,
|
||||
.Xr rcorder 8 ,
|
||||
.Xr reboot 8 ,
|
||||
.Xr savecore 8
|
||||
.Sh HISTORY
|
||||
|
|
770
share/man/man8/rc.subr.8
Normal file
770
share/man/man8/rc.subr.8
Normal file
|
@ -0,0 +1,770 @@
|
|||
.\" $NetBSD: rc.subr.8,v 1.9 2002/07/08 16:14:55 atatat Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Luke Mewburn.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd April 18, 2002
|
||||
.Dt RC.SUBR 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rc.subr
|
||||
.Nd functions used by system shell scripts
|
||||
.Sh SYNOPSIS
|
||||
.Bl -item
|
||||
.It
|
||||
.Li . /etc/rc.subr
|
||||
.It
|
||||
.Ic backup_file Ar action Ar file Ar current Ar backup
|
||||
.It
|
||||
.Ic checkyesno Ar var
|
||||
.It
|
||||
.Ic check_pidfile Ar pidfile Ar procname Op Ar interpreter
|
||||
.It
|
||||
.Ic check_process Ar procname Op Ar interpreter
|
||||
.It
|
||||
.Ic debug Ar message
|
||||
.It
|
||||
.Ic err Ar exitval Ar message
|
||||
.It
|
||||
.Ic force_depend Ar name
|
||||
.It
|
||||
.Ic info Ar message
|
||||
.It
|
||||
.Ic load_rc_config Ar command
|
||||
.It
|
||||
.Ic mount_critical_filesystems Ar type
|
||||
.It
|
||||
.Ic rc_usage Ar command Op Ar ...
|
||||
.It
|
||||
.Ic reverse_list Ar item Op Ar ...
|
||||
.It
|
||||
.Ic run_rc_command Ar argument
|
||||
.It
|
||||
.Ic run_rc_script Ar file Ar argument
|
||||
.It
|
||||
.Ic set_rcvar Op Ar base
|
||||
.It
|
||||
.Ic wait_for_pids Op Ar pid Op Ar ...
|
||||
.It
|
||||
.Ic warn Ar message
|
||||
.El
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
contains commonly used shell script functions and variable
|
||||
definitions which are used by various scripts such as
|
||||
.Xr rc 8 .
|
||||
Scripts required by ports in
|
||||
.Pa /usr/local/etc/rc.d
|
||||
will also eventually
|
||||
be rewritten to make use of it.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
functions were mostly imported from
|
||||
.Nx
|
||||
and it is intended that they remain synced between the
|
||||
two projects. With that in mind there are several variable
|
||||
defenitions that can help in this regard. They are:
|
||||
.Bl -tag -width 4n
|
||||
.It Ic OSTYPE
|
||||
Its value will be either
|
||||
.Fx
|
||||
or
|
||||
.Nx ,
|
||||
depending on which OS it is running on.
|
||||
.It Ic SYSCTL
|
||||
The path to the
|
||||
.Xr sysctl 8
|
||||
command.
|
||||
.It Ic SYSCTL_N
|
||||
The path and argument list to display only the
|
||||
.Xr sysctl 8
|
||||
values instead of a name=value pair.
|
||||
.It Ic SYSCTL_W
|
||||
The path and argument to write or modify
|
||||
.Xr sysctl 8
|
||||
values.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
functions are accessed by sourcing
|
||||
.Pa /etc/rc.subr
|
||||
into the current shell.
|
||||
.Pp
|
||||
The following shell functions are available:
|
||||
.Bl -tag -width 4n
|
||||
.It Xo
|
||||
.Ic backup_file Ar action Ar file Ar current Ar backup
|
||||
.Xc
|
||||
Make a backup copy of
|
||||
.Ar file
|
||||
into
|
||||
.Ar current .
|
||||
If the
|
||||
.Xr rc.conf 5
|
||||
variable
|
||||
.Sy backup_uses_rcs
|
||||
is
|
||||
.Sq YES ,
|
||||
use
|
||||
.Xr rcs 1
|
||||
to archive the previous version of
|
||||
.Ar current ,
|
||||
otherwise save the previous version of
|
||||
.Ar current
|
||||
as
|
||||
.Ar backup .
|
||||
.Pp
|
||||
.Ar action
|
||||
may be one of the following:
|
||||
.Bl -tag -width remove
|
||||
.It Sy add
|
||||
.Ar file
|
||||
is now being backed up by or possibly re-entered into this backup mechanism.
|
||||
.Ar current
|
||||
is created, and if necessary, the
|
||||
.Xr rcs 1
|
||||
files are created as well.
|
||||
.It Sy update
|
||||
.Ar file
|
||||
has changed and needs to be backed up.
|
||||
If
|
||||
.Ar current
|
||||
exists, it is copied to
|
||||
.Ar backup
|
||||
or checked into
|
||||
.Xr rcs 1
|
||||
(if the repository file is old),
|
||||
and then
|
||||
.Ar file
|
||||
is copied to
|
||||
.Ar current .
|
||||
.It Sy remove
|
||||
.Ar file
|
||||
is no longer being tracked by this backup mechanism.
|
||||
If
|
||||
.Xr rcs 1
|
||||
is being used, an empty file is checked in and
|
||||
.Ar current
|
||||
is removed,
|
||||
otherwise
|
||||
.Ar current
|
||||
is moved to
|
||||
.Ar backup .
|
||||
.El
|
||||
.It Ic checkyesno Ar var
|
||||
Return 0 if
|
||||
.Ar var
|
||||
is defined to
|
||||
.Sq YES ,
|
||||
.Sq TRUE ,
|
||||
.Sq ON ,
|
||||
or
|
||||
.Sq 1 .
|
||||
Return 1 if
|
||||
.Ar var
|
||||
is defined to
|
||||
.Sq NO ,
|
||||
.Sq FALSE ,
|
||||
.Sq OFF ,
|
||||
or
|
||||
.Sq 0 .
|
||||
Otherwise, warn that
|
||||
.Ar var
|
||||
is not set correctly.
|
||||
The values are case insensitive.
|
||||
.It Xo
|
||||
.Ic check_pidfile
|
||||
.Ar pidfile
|
||||
.Ar procname
|
||||
.Op Ar interpreter
|
||||
.Xc
|
||||
Parses the first word of the first line of
|
||||
.Ar pidfile
|
||||
for a PID, and ensures that the process with that PID
|
||||
is running and its first argument matches
|
||||
.Ar procname .
|
||||
Prints the matching PID if successfull, otherwise nothing.
|
||||
If
|
||||
.Ar interpreter
|
||||
is provided, parse the first line of
|
||||
.Ar procname ,
|
||||
ensure that the line is of the form
|
||||
.Dl #! interpreter [...]
|
||||
and use
|
||||
.Ar interpreter
|
||||
with its optional arguments and
|
||||
.Ar procname
|
||||
appended as the process string to search for.
|
||||
.It Ic check_process Ar procname Op Ar interpreter
|
||||
Prints the PIDs of any processes that are running with a first
|
||||
argument that matches
|
||||
.Ar procname .
|
||||
.Ar interpreter
|
||||
is handled as per
|
||||
.Ic check_pidfile .
|
||||
.It Ic debug Ar message
|
||||
Display a debugging message to
|
||||
.Em stderr ,
|
||||
log it to the system log using
|
||||
.Xr logger 1 ,
|
||||
and
|
||||
return to the caller.
|
||||
The error message consists of the sript name
|
||||
(from
|
||||
.Sy $0 ) ,
|
||||
followed by
|
||||
.Dq ": DEBUG: " ,
|
||||
and then
|
||||
.Ar message .
|
||||
This function is intended to be used by developers
|
||||
as an aid to debuging scripts. It can be turned on or off
|
||||
by the
|
||||
.Xr rc.conf 5
|
||||
variable
|
||||
.Em rc_debug .
|
||||
.It Ic err Ar exitval Ar message
|
||||
Display an error message to
|
||||
.Em stderr ,
|
||||
log it to the system log
|
||||
using
|
||||
.Xr logger 1 ,
|
||||
and
|
||||
.Cm exit
|
||||
with an exit value of
|
||||
.Ar exitval .
|
||||
The error message consists of the script name
|
||||
(from
|
||||
.Sy $0 ) ,
|
||||
followed by
|
||||
.Dq ": ERROR: " ,
|
||||
and then
|
||||
.Ar message .
|
||||
.It Ic force_depend name
|
||||
Output an advisory message and force the
|
||||
.Ar name
|
||||
service to start. The
|
||||
.Ar name
|
||||
argument is the
|
||||
.Xr basename 1 ,
|
||||
component of the path to the script, usually
|
||||
.Em /etc/rc.d/name .
|
||||
If the script fails for any reason it will output a warning
|
||||
and return with a return value of 1. If it was successful
|
||||
it will return 0.
|
||||
.It Ic info Ar message
|
||||
Display an informational message to
|
||||
.Em stdout ,
|
||||
and log it to the system log using
|
||||
.Xr logger 1 .
|
||||
The message consists of the script name
|
||||
(from
|
||||
.Sy $0 ) ,
|
||||
followed by
|
||||
.Dq ": INFO: " ,
|
||||
and then
|
||||
.Ar mesage .
|
||||
The display of this informational output can be
|
||||
turned on or off by the
|
||||
.Xr rc.conf 5
|
||||
variable
|
||||
.Em rc_info .
|
||||
.It Ic load_rc_config Ar command
|
||||
Source in the configuration files for
|
||||
.Ar command .
|
||||
First,
|
||||
.Pa /etc/rc.conf
|
||||
is sourced if it has not yet been read in.
|
||||
Then,
|
||||
.Pa /etc/rc.conf.d/ Ns Ar command
|
||||
is sourced if it is an existing file.
|
||||
The latter may also contain other variable assignments to override
|
||||
.Ic run_rc_command
|
||||
arguments defined by the calling script, to provide an easy
|
||||
mechanism for an administrator to override the behaviour of a given
|
||||
.Xr rc.d 8
|
||||
script without requiring the editing of that script.
|
||||
.It Ic mount_critical_filesystems Ar type
|
||||
Go through a list of critical file systems,
|
||||
as found in the
|
||||
.Xr rc.conf 5
|
||||
variable
|
||||
.Sy critical_filesystems_ Ns Ar type ,
|
||||
mounting each one that
|
||||
is not currently mounted.
|
||||
.It Ic rc_usage Ar command Op Ar ...
|
||||
Print a usage message for
|
||||
.Sy $0 ,
|
||||
with
|
||||
.Ar commands
|
||||
being the list of valid arguments
|
||||
prefixed by
|
||||
.Dq "[fast|force]" .
|
||||
.It Ic reverse_list Ar item Op Ar ...
|
||||
Print the list of
|
||||
.Ar items
|
||||
in reverse order.
|
||||
.It Ic run_rc_command Ar argument
|
||||
Run the
|
||||
.Ar argument
|
||||
method for the current
|
||||
.Xr rc.d 8
|
||||
script, based on the settings of various shell variables.
|
||||
.Ic run_rc_command
|
||||
is extremely flexible, and allows fully functional
|
||||
.Xr rc.d 8
|
||||
scripts to be implemented in a small amount of shell code.
|
||||
.Pp
|
||||
.Ar argument
|
||||
is searched for in the list of supported commands, which may be one
|
||||
of:
|
||||
.Dl start stop restart rcvar
|
||||
as well as any word listed in the optional variable
|
||||
.Sy extra_commands .
|
||||
If
|
||||
.Sy pidfile
|
||||
or
|
||||
.Sy procname
|
||||
is set, also allow:
|
||||
.Dl status poll
|
||||
.Pp
|
||||
.Ar argument
|
||||
may have one of the following prefixes which alters its operation:
|
||||
.Bl -tag -width "Prefix" -offset indent -compact
|
||||
.It Sy Prefix
|
||||
.Sy Operation
|
||||
.It Li fast
|
||||
Skip the check for an existing running process,
|
||||
and sets
|
||||
.Sy rc_fast=YES .
|
||||
.It Li force
|
||||
Skip the checks for
|
||||
.Sy rcvar
|
||||
being set to yes,
|
||||
and sets
|
||||
.Sy rc_force=YES .
|
||||
This ignores
|
||||
.Ar argument Ns Sy _precmd
|
||||
returning non-zero, and ignores any of the
|
||||
.Sy required_*
|
||||
tests failing .
|
||||
.El
|
||||
.Pp
|
||||
.Ic run_rc_command
|
||||
uses the following shell variables to control its behaviour.
|
||||
Unless otherwise stated, these are optional.
|
||||
.Bl -tag -width procname -offset indent
|
||||
.It Sy name
|
||||
The name of this script.
|
||||
This is not optional.
|
||||
.It Sy rcvar
|
||||
The value of
|
||||
.Sy rcvar
|
||||
is checked with
|
||||
.Ic checkyesno
|
||||
to determine if this method should be run.
|
||||
.It Sy command
|
||||
Full path to the command.
|
||||
Not required if
|
||||
.Ar argument Ns Sy _cmd
|
||||
is defined for each supported keyword.
|
||||
.It Sy command_args
|
||||
Optional arguments and/or shell directives for
|
||||
.Sy command .
|
||||
.It Sy command_interpreter
|
||||
.Sy command
|
||||
is started with
|
||||
.Dl #! command_interpreter [...]
|
||||
which results in its
|
||||
.Xr ps 1
|
||||
command being
|
||||
.Dl command_interpreter [...] command
|
||||
so use that string to find the PID(s) of the running command
|
||||
rather than
|
||||
.Ql command .
|
||||
.It Sy extra_commands
|
||||
Extra commands/keywords/arguments supported.
|
||||
.It Sy pidfile
|
||||
Path to pid file.
|
||||
Used to determine the PID(s) of the running command.
|
||||
If
|
||||
.Sy pidfile
|
||||
is set, use
|
||||
.Dl check_pidfile $pidfile $procname
|
||||
to find the PID.
|
||||
Otherwise, if
|
||||
.Sy command
|
||||
is set, use
|
||||
.Dl check_process $procname
|
||||
to find the PID.
|
||||
.It Sy procname
|
||||
Process name to check for.
|
||||
Defaults to the value of
|
||||
.Sy command .
|
||||
.It Sy required_dirs
|
||||
Check for the existence of the listed directories
|
||||
before running the default start method.
|
||||
.It Sy required_files
|
||||
Check for the readability of the listed files
|
||||
before running the default start method.
|
||||
.It Sy required_vars
|
||||
Perform
|
||||
.Ic checkyesno
|
||||
on each of the list variables
|
||||
before running the default start method.
|
||||
.It Sy ${name}_chdir
|
||||
Directory to
|
||||
.Ic cd
|
||||
to before running
|
||||
.Sy command ,
|
||||
if
|
||||
.Sy ${name}_chroot
|
||||
is not provided.
|
||||
.It Sy ${name}_chroot
|
||||
Directory to
|
||||
.Xr chroot 8
|
||||
to before running
|
||||
.Sy command .
|
||||
Only supported after
|
||||
.Pa /usr
|
||||
is mounted.
|
||||
.It Sy ${name}_flags
|
||||
Arguments to call
|
||||
.Sy command
|
||||
with.
|
||||
This is usually set in
|
||||
.Xr rc.conf 5 ,
|
||||
and not in the
|
||||
.Xr rc.d 8
|
||||
script.
|
||||
The environment variable
|
||||
.Sq Ev flags
|
||||
can be used to override this.
|
||||
.It Sy ${name}_nice
|
||||
.Xr nice 1
|
||||
level to run
|
||||
.Sy command
|
||||
as.
|
||||
Only supported after
|
||||
.Pa /usr
|
||||
is mounted.
|
||||
.It Sy ${name}_user
|
||||
User to run
|
||||
.Sy command
|
||||
as, using
|
||||
.Xr chroot 8 .
|
||||
if
|
||||
.Sy ${name}_chroot
|
||||
is set, otherwise
|
||||
uses
|
||||
.Xr su 1 .
|
||||
Only supported after
|
||||
.Pa /usr
|
||||
is mounted.
|
||||
.It Sy ${name}_group
|
||||
Group to run the chrooted
|
||||
.Sy command
|
||||
as.
|
||||
.It Sy ${name}_groups
|
||||
Comma separated list of supplementary groups to run the chrooted
|
||||
.Sy command
|
||||
with.
|
||||
.It Sy ${name}_systrace
|
||||
Flags passed to
|
||||
.Xr systrace 1 ,
|
||||
if it is used.
|
||||
Setting this variable enables systracing
|
||||
of the given program. The use of
|
||||
.Sq -a
|
||||
is
|
||||
recommended so that the boot process is not
|
||||
stalled. In order to pass no flags to
|
||||
systrace, set this variable to
|
||||
.Sq -- .
|
||||
.It Ar argument Ns Sy _cmd
|
||||
Shell commands which override the default method for
|
||||
.Ar argument .
|
||||
.It Ar argument Ns Sy _precmd
|
||||
Shell commands to run just before running
|
||||
.Ar argument Ns Sy _cmd
|
||||
or the default method for
|
||||
.Ar argument .
|
||||
If this returns a non-zero exit code, the main method is not performed.
|
||||
If the default method is being executed, this check is performed after
|
||||
the
|
||||
.Sy required_*
|
||||
checks and process (non-)existence checks.
|
||||
.It Ar argument Ns Sy _postcmd
|
||||
Shell commands to run if running
|
||||
.Ar argument Ns Sy _cmd
|
||||
or the default method for
|
||||
.Ar argument
|
||||
returned a zero exit code.
|
||||
.It Sy sig_stop
|
||||
Signal to send the processes to stop in the default
|
||||
.Sy stop
|
||||
method.
|
||||
Defaults to
|
||||
.Dv SIGTERM .
|
||||
.It Sy sig_reload
|
||||
Signal to send the processes to reload in the default
|
||||
.Sy reload
|
||||
method.
|
||||
Defaults to
|
||||
.Dv SIGHUP .
|
||||
.El
|
||||
.Pp
|
||||
For a given method
|
||||
.Ar argument ,
|
||||
if
|
||||
.Ar argument Ns Sy _cmd
|
||||
is not defined, then a default method is provided by
|
||||
.Sy run_rc_command :
|
||||
.Bl -tag -width "argument" -offset indent
|
||||
.It Sy Argument
|
||||
.Sy Default method
|
||||
.It Sy start
|
||||
If
|
||||
.Sy command
|
||||
is not running and
|
||||
.Ic checkyesno Sy rcvar
|
||||
succeeds, start
|
||||
.Sy command .
|
||||
.It Sy stop
|
||||
Determine the PIDs of
|
||||
.Sy command
|
||||
with
|
||||
.Ic check_pidfile
|
||||
or
|
||||
.Ic check_process
|
||||
(as appropriate),
|
||||
.Ic kill Sy sig_stop
|
||||
those PIDs, and run
|
||||
.Ic wait_for_pids
|
||||
on those PIDs.
|
||||
.It Sy reload
|
||||
Similar to
|
||||
.Sy stop ,
|
||||
except that it uses
|
||||
.Sy sig_reload
|
||||
instead, and doesn't run
|
||||
.Ic wait_for_pids .
|
||||
.It Sy restart
|
||||
Runs the
|
||||
.Sy stop
|
||||
method, then the
|
||||
.Sy start
|
||||
method.
|
||||
.It Sy status
|
||||
Show the PID of
|
||||
.Sy command ,
|
||||
or some other script specific status operation.
|
||||
.It Sy poll
|
||||
Wait for
|
||||
.Sy command
|
||||
to exit.
|
||||
.It Sy rcvar
|
||||
Display which
|
||||
.Xr rc.conf 5
|
||||
variable is used (if any).
|
||||
This method always works, even if the appropriate
|
||||
.Xr rc.conf 5
|
||||
variable is set to
|
||||
.Sq NO .
|
||||
.El
|
||||
.Pp
|
||||
The following variables are available to the methods
|
||||
(such as
|
||||
.Ar argument Ns Sy _cmd )
|
||||
as well as after
|
||||
.Ic run_rc_command
|
||||
has completed:
|
||||
.Bl -tag -width "rc_flags" -offset indent
|
||||
.It Sy rc_arg
|
||||
Argument provided to
|
||||
.Sy run_rc_command ,
|
||||
after fast and force processing has been performed.
|
||||
.It Sy rc_flags
|
||||
Flasg to start the default command with.
|
||||
Defaults to
|
||||
.Sy ${name}_flags ,
|
||||
unless overridden by the environment variable
|
||||
.Sq Ev flags .
|
||||
This variable may be changed by the
|
||||
.Ar argument Ns Sy _precmd
|
||||
method.
|
||||
.It Sy rc_pid
|
||||
PID of
|
||||
.Sy command
|
||||
(if appropriate).
|
||||
.It Sy rc_fast
|
||||
Not empty if
|
||||
.Dq fast
|
||||
prefix was used.
|
||||
.It Sy rc_force
|
||||
Not empty if
|
||||
.Dq force
|
||||
prefix was used.
|
||||
.El
|
||||
.It Ic run_rc_script Ar file Ar argument
|
||||
Start the script
|
||||
.Ar file
|
||||
with an argument of
|
||||
.Ar argument ,
|
||||
and handle the return value from the script.
|
||||
.Pp
|
||||
Various shell variables are unset before
|
||||
.Ar file
|
||||
is started:
|
||||
.Bd -ragged -offset indent
|
||||
.Sy name ,
|
||||
.Sy command ,
|
||||
.Sy command_args ,
|
||||
.Sy command_interpreter ,
|
||||
.Sy extra_commands ,
|
||||
.Sy pidfile ,
|
||||
.Sy rcvar ,
|
||||
.Sy required_dirs ,
|
||||
.Sy required_files ,
|
||||
.Sy required_vars ,
|
||||
.Ar argument Ns Sy _cmd ,
|
||||
.Ar argument Ns Sy _precmd .
|
||||
.Ar argument Ns Sy _postcmd .
|
||||
.Ed
|
||||
.Pp
|
||||
The startup behaviour of
|
||||
.Ar file
|
||||
depends upon the following checks:
|
||||
.Bl -enum
|
||||
.It
|
||||
If
|
||||
.Ar file
|
||||
ends in
|
||||
.Pa .sh ,
|
||||
it is sourced into the current shell.
|
||||
.It
|
||||
If
|
||||
.Ar file
|
||||
appears to be a backup or scratch file
|
||||
(e.g., with a suffix of
|
||||
.Sq ~ ,
|
||||
.Sq # ,
|
||||
.Sq .OLD ,
|
||||
or
|
||||
.Sq .orig ) ,
|
||||
ignore it.
|
||||
.It
|
||||
If
|
||||
.Ar file
|
||||
is not executable, ignore it.
|
||||
.It
|
||||
If the
|
||||
.Xr rc.conf 5
|
||||
variable
|
||||
.Sy rc_fast_and_loose
|
||||
is empty,
|
||||
source
|
||||
.Ar file
|
||||
in a sub shell,
|
||||
otherwise source
|
||||
.Ar file
|
||||
into the current shell.
|
||||
.El
|
||||
.It Ic set_rcvar Op Ar base
|
||||
Set the variable name required to start a service. In
|
||||
.Fx
|
||||
a daemon is usually controlled by an
|
||||
.Xr rc.conf 5
|
||||
variable consisting of a daemon's name postfixed by the string
|
||||
.Sy "_enable" .
|
||||
This is not the case in
|
||||
.Nx .
|
||||
When the following line is included in a script
|
||||
.Pp
|
||||
.Dl rcvar=`set_rcvar`
|
||||
.Pp
|
||||
This function will use the value of the
|
||||
.Sy $name
|
||||
variable, which should be defined by the calling script, to construct the appropriate
|
||||
.Xr rc.conf 5
|
||||
knob. If the
|
||||
.Ar base
|
||||
argument is set it will use
|
||||
.Ar base
|
||||
instead of
|
||||
.Sy $name .
|
||||
.It Ic wait_for_pids Op Ar pid Op Ar ...
|
||||
Wait until all of the provided
|
||||
.Ar pids
|
||||
don't exist any more, printing the list of outstanding
|
||||
.Ar pids
|
||||
every two seconds.
|
||||
.It Ic warn Ar message
|
||||
Display a warning message to
|
||||
.Em stderr
|
||||
and log it to the system log
|
||||
using
|
||||
.Xr logger 1 .
|
||||
The warning message consists of the script name
|
||||
(from
|
||||
.Sy $0 ) ,
|
||||
followed by
|
||||
.Dq ": WARNING: " ,
|
||||
and then
|
||||
.Ar message .
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/rc.subr -compact
|
||||
.It Pa /etc/rc.subr
|
||||
The
|
||||
.Nm
|
||||
file resides in
|
||||
.Pa /etc .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr rc.conf 5 ,
|
||||
.Xr rc 8
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
appeared in
|
||||
.Nx 1.3 .
|
||||
The
|
||||
.Xr rc.d 8
|
||||
support functions appeared in
|
||||
.Nx 1.5 .
|
||||
.Nm
|
||||
first appeared in
|
||||
.Fx 5.0 .
|
Loading…
Reference in a new issue