Module Name: src Committed By: apb Date: Fri Sep 11 18:17:04 UTC 2009
Modified Files: src/doc: CHANGES src/etc: rc rc.subr src/etc/defaults: rc.conf src/share/man/man5: rc.conf.5 src/share/man/man8: rc.8 rc.subr.8 Log Message: Add a postprocessor to /etc/rc, which logs messages to /var/run/rc.log, and which can suppress output in silent mode. Silent mode is enabled via the new rc_silent variable, which defaults to a value that depends on the kern.boothowto sysctl. Part of the /etc/rc silent changes requested in PR 41946 and proposed in tech-userlevel. To generate a diff of this commit: cvs rdiff -u -r1.1287 -r1.1288 src/doc/CHANGES cvs rdiff -u -r1.163 -r1.164 src/etc/rc cvs rdiff -u -r1.77 -r1.78 src/etc/rc.subr cvs rdiff -u -r1.104 -r1.105 src/etc/defaults/rc.conf cvs rdiff -u -r1.132 -r1.133 src/share/man/man5/rc.conf.5 cvs rdiff -u -r1.31 -r1.32 src/share/man/man8/rc.8 cvs rdiff -u -r1.22 -r1.23 src/share/man/man8/rc.subr.8 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/doc/CHANGES diff -u src/doc/CHANGES:1.1287 src/doc/CHANGES:1.1288 --- src/doc/CHANGES:1.1287 Fri Sep 11 18:14:58 2009 +++ src/doc/CHANGES Fri Sep 11 18:17:04 2009 @@ -1,4 +1,4 @@ -# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1287 $> +# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1288 $> # # # [Note: This file does not mention every change made to the NetBSD source tree. @@ -389,3 +389,6 @@ build.sh: Add a modules operation which builds kernel modules and installs them into DESTDIR. [jnemeth 20090907] sysctl(7): Add kern.boothowto variable. [apb 20090911] + rc(8): Output is now logged to /var/run/rc.log. A new rc_silent + option, enabled if the kernel is booted in silent mode, + suppresses output to the console. [apb 20090911] Index: src/etc/rc diff -u src/etc/rc:1.163 src/etc/rc:1.164 --- src/etc/rc:1.163 Fri Apr 10 16:18:04 2009 +++ src/etc/rc Fri Sep 11 18:17:04 2009 @@ -1,9 +1,10 @@ #!/bin/sh # -# $NetBSD: rc,v 1.163 2009/04/10 16:18:04 joerg Exp $ +# $NetBSD: rc,v 1.164 2009/09/11 18:17:04 apb Exp $ # # rc -- -# Run the scripts in /etc/rc.d with rcorder. +# Run the scripts in /etc/rc.d with rcorder, and log output +# to /var/run/rc.log. # System startup script run by init(8) on autoboot or after single-user. # Output and error are redirected to console by init, and the console @@ -13,10 +14,16 @@ export PATH=/sbin:/bin:/usr/sbin:/usr/bin umask 022 -. /etc/rc.subr +if [ -e ./rc.subr ] ; then + . ./rc.subr # for testing +else + . /etc/rc.subr +fi . /etc/rc.conf _rc_conf_loaded=true +: ${RC_LOG_FILE:="/var/run/rc.log"} + if ! checkyesno rc_configured; then echo "/etc/rc.conf is not configured. Multiuser boot aborted." exit 1 @@ -27,24 +34,363 @@ rc_fast=yes # run_rc_command(): do fast booting fi -stty status '^T' +# +# Completely ignore INT and QUIT at the outer level. The rc_real_work() +# function should do something different. +# +trap '' INT QUIT -# Set shell to ignore SIGINT, but not children; -# shell catches SIGQUIT and returns to single user. # -trap : INT -trap "echo 'Boot interrupted.'; exit 1" QUIT +# This string will be used to mark lines of meta-data sent over the pipe +# from the rc_real_work() function to the rc_postprocess() function. Lines +# not so marked are assumed to be output from rc.d scripts. +# +# This string is long and unique to ensure that it does not accidentally +# appear in output from any rc.d script. It must not contain any +# characters that are special to glob expansion ('*', '?', '[', or ']'). +# +rc_metadata_prefix="$0:$$:metadata:"; -date +# Child scripts may sometimes want to print directly to the original +# stdout and stderr, bypassing the pipe to the postprocessor. These +# _rc_*_fd variables are private, shared with /etc/rc.subr, but not +# intended to be used directly by child scripts. (Child scripts +# may use rc.subr's no_rc_postprocess function.) +# +_rc_original_stdout_fd=7; export _rc_original_stdout_fd +_rc_original_stderr_fd=8; export _rc_original_stderr_fd +eval "exec ${_rc_original_stdout_fd}>&1" +eval "exec ${_rc_original_stderr_fd}>&2" -scripts=$(for rcd in ${rc_directories:-/etc/rc.d}; do - test -d ${rcd} && echo ${rcd}/*; -done) -files=$(rcorder -s nostart ${rc_rcorder_flags} ${scripts}) +# +# rc_real_work +# Do the real work. Output from this function will be piped into +# rc_postprocess(), and some of the output will be marked as +# metadata. +# +# The body of this function is defined using (...), not {...}, to force +# it to run in a subshell. +# +rc_real_work() +( + stty status '^T' + + # print_rc_metadata() wants to be able to print to the pipe + # that goes to our postprocessor, even if its in a context + # with redirected output. + # + _rc_postprocessor_fd=9 ; export _rc_postprocessor_fd + eval "exec ${_rc_postprocessor_fd}>&1" + + # Print a metadata line when we exit + # + trap 'es=$?; print_rc_metadata "exit:$es"; trap "" 0; exit $es' 0 + + # Set shell to ignore SIGINT, but children will not ignore it. + # Shell catches SIGQUIT and returns to single user. + # + trap : INT + trap '_msg="Boot interrupted at $(date)"; + print_rc_metadata "interrupted:${_msg}"; + exit 1' QUIT + + print_rc_metadata "start:$(date)" + + # + # The stop_boot() function in rc.subr may kill $RC_PID. We want + # it to kill the subshell running this rc_real_work() function, + # rather than killing the parent shell, because we want the + # rc_postprocess() function to be able to log the error + # without being killed itself. + # + # "$$" is the pid of the top-level shell, not the pid of the + # subshell that's executing this function. The command below + # tentatively assumes that the parent of the "/bin/sh -c ..." + # process will be the current subshell, and then uses "kill -0 + # ..." to check the result. If the "/bin/sh -c ..." process + # fails, or returns the pid of an ephemeral process that exits + # before the "kill" command, then we fall back to using "$$". + # + RC_PID=$(/bin/sh -c 'ps -p $$ -o ppid=') || RC_PID=$$ + kill -0 $RC_PID >/dev/null 2>&1 || RC_PID=$$ + + # + # Get a list of all rc.d scripts, and use rcorder to choose + # what order to execute them. + # + # For testing, allow RC_FILES_OVERRIDE from the environment to + # override this. + # + print_rc_metadata "cmd-name:rcorder" + scripts=$(for rcd in ${rc_directories:-/etc/rc.d}; do + test -d ${rcd} && echo ${rcd}/*; + done) + files=$(rcorder -s nostart ${rc_rcorder_flags} ${scripts}) + print_rc_metadata "cmd-status:rcorder:$?" + + if [ -n "${RC_FILES_OVERRIDE}" ]; then + files="${RC_FILES_OVERRIDE}" + fi + + # + # Run the scripts in order. + # + for _rc_elem in $files; do + print_rc_metadata "cmd-name:$_rc_elem" + run_rc_script $_rc_elem start + print_rc_metadata "cmd-status:$_rc_elem:$?" + done + + print_rc_metadata "end:$(date)" + exit 0 +) -for _rc_elem in $files; do - run_rc_script $_rc_elem start -done +# +# rc_postprocess +# Post-process the output from the rc_real_work() function. For +# each line of input, we have to decide whether to print the line +# to the console, print a twiddle on the console, print a line to +# the log, or some combination of these. +# +# If rc_silent is true, then suppress most output, instead running +# rc_silent_cmd (typically "twiddle") for each line. +# +# The body of this function is defined using (...), not {...}, to force +# it to run in a subshell. +# +# We have to deal with the following constraints: +# +# * There may be no writable file systems early in the boot, so +# any use of temporary files would be problematic. +# +# * Scripts run during the boot may clear /tmp and/var/run, so even +# if they are writable, using those directories too early may be +# problematic. We assume that it's safe to write to our log file +# after the mountcritlocal script has run. +# +# * /usr/bin/tee cannot be used because the /usr file system may not +# be mounted early in the boot. +# +# * All calls to the rc_log_message and rc_log_flush functions must be +# from the same subshell, otherwise the use of a shell variable to +# buffer log messages will fail. +# +rc_postprocess() +( + local line + local before after + local IFS='' + + # Try quite hard to flush the log to disk when we exit. + trap 'es=$?; rc_log_flush FORCE; trap "" 0; exit $es' 0 + + yesno_to_truefalse rc_silent 2>/dev/null + + while read -r line ; do + case "$line" in + "${rc_metadata_prefix}"*) + after="${line#*"${rc_metadata_prefix}"}" + rc_postprocess_metadata "${after}" + ;; + *"${rc_metadata_prefix}"*) + # magic string is present, but not at the start of + # the line. Treat it like two separate lines. + before="${line%"${rc_metadata_prefix}"*}" + rc_postprocess_plain_line "${before}" + after="${line#*"${rc_metadata_prefix}"}" + rc_postprocess_metadata "${after}" + ;; + *) + rc_postprocess_plain_line "${line}" + ;; + esac + done + + # If we get here, then the rc_real_work() function must have + # exited uncleanly. A clean exit would have been accompanied by + # a line of metadata that would have prevented us from getting + # here. + # + exit 1 +) + +# +# rc_postprocess_plain_line string +# $1 is a string representing a line of output from one of the +# rc.d scripts. Append the line to the log, and also either +# display the line on the console, or run $rc_silent_cmd, +# depending on the value of $rc_silent. +# +rc_postprocess_plain_line() +{ + local line="$1" + rc_log_message "${line}" + if $rc_silent; then + eval "$rc_silent_cmd" + else + printf "%s\n" "${line}" + fi +} + +# +# rc_postprocess_metadata string +# $1 is a string containing metadata from the rc_real_work() +# function. The rc_metadata_prefix marker should already +# have been removed before the string is passed to this function. +# Take appropriate action depending on the content of the string. +# +rc_postprocess_metadata() +{ + local metadata="$1" + local keyword args + local msg + local IFS=':' + + # given metadata="bleep:foo bar:baz", + # set keyword="bleep", args="foo bar:baz", + # $1="foo bar", $2="baz" + # + keyword="${metadata%%:*}" + args="${metadata#*:}" + set -- $args + + case "$keyword" in + start) + # $args contains a date/time + rc_log_message "[$0 starting at $args]" + if ! $rc_silent; then + printf "%s\n" "$args" + fi + ;; + cmd-name) + rc_log_message "[running $1]" + ;; + cmd-status) + # $1 is a command name, $2 is the command's exit status. + # If the command failed, report it, and add it to a list. + if [ "$2" != 0 ]; then + rc_failures="${rc_failures}${rc_failures:+ }$1" + msg="$1 reported failure status $2" + rc_log_message "$msg" + if ! $rc_silent; then + printf "%s\n" "$msg" + fi + fi + # After the mountcritlocal script has finished, it's + # OK to flush the log to disk + case "$1" in + */mountcritlocal) + rc_log_flush OK + ;; + esac + ;; + note) + rc_log_message "[NOTE: $args]" + ;; + end) + # + # If any scripts (or other commands) failed, report them. + # + if [ -n "$rc_failures" ]; then + rc_log_message "[failures]" + msg="The following components reported failures:" + msg="${msg}${nl}$( echo " ${rc_failures}" | fmt )" + msg="${msg}${nl}See ${RC_LOG_FILE} for more information." + rc_log_message "${msg}" + printf "%s\n" "${msg}" + fi + # + # Report the end date/time, even in silent mode + # + rc_log_message "[$0 finished at $args]" + printf "%s\n" "$args" + ;; + exit) + rc_log_message "[$0 exiting with status $1]" + exit $1 + ;; + interrupted) + # $args is a human-readable message + rc_log_message "$args" + printf "%s\n" "$args" + ;; + *) + # an unrecognised line of metadata + rc_log_message "[metadata:${metadata}]" + ;; + esac +} + +# +# rc_log_message string [...] +# write a message to the log file, or buffer it for later. +# +rc_log_message() +{ + _rc_log_buffer="${_rc_log_buffer}${*}${nl}" + rc_log_flush +} -date -exit 0 +# +# rc_log_flush [OK|FORCE] +# save outstanding messages from $_rc_log_buffer to $RC_LOG_FILE. +# +# The log file is expected to reside in the /var/run directory, which +# may not be writable very early in the boot sequence, and which is +# erased a little later in the boot sequence. We therefore avoid +# writing to the file until we believe it's safe to do so. We also +# assume that it's reasonable to always append to the file, never +# truncating it. +# +# Optional argument $1 may be "OK" to report that writing to the log +# file is expected to be safe from now on, or "FORCE" to force writing +# to the log file even if it may be unsafe. +# +# Returns a non-zero status if messages could not be written to the +# file. +# +rc_log_flush() +{ + # + # If $_rc_log_flush_ok is false, then it's probably too early to + # write to the log file, so don't do it, unless $1 is "FORCE". + # + : ${_rc_log_flush_ok=false} + case "$1:$_rc_log_flush_ok" in + OK:*) + _rc_log_flush_ok=true + ;; + FORCE:*) + : OK just this once + ;; + *:true) + : OK + ;; + *) + # it's too early in the boot sequence, so don't flush + return 1 + ;; + esac + + # + # Now append the buffer to the file. The buffer should already + # contain a trailing newline, so don't add an extra newline. + # + if [ -n "$_rc_log_buffer" ]; then + if { printf "%s" "${_rc_log_buffer}" >>"${RC_LOG_FILE}" ; } \ + 2>/dev/null + then + _rc_log_buffer="" + else + return 1 + fi + fi + return 0 +} + +# +# Most of the action is in the rc_real_work() and rc_postprocess() +# functions. +# +rc_real_work "$@" 2>&1 | rc_postprocess +exit $? Index: src/etc/rc.subr diff -u src/etc/rc.subr:1.77 src/etc/rc.subr:1.78 --- src/etc/rc.subr:1.77 Sat Sep 5 16:45:33 2009 +++ src/etc/rc.subr Fri Sep 11 18:17:04 2009 @@ -1,4 +1,4 @@ -# $NetBSD: rc.subr,v 1.77 2009/09/05 16:45:33 apb Exp $ +# $NetBSD: rc.subr,v 1.78 2009/09/11 18:17:04 apb Exp $ # # Copyright (c) 1997-2004 The NetBSD Foundation, Inc. # All rights reserved. @@ -33,6 +33,8 @@ : ${rcvar_manpage:='rc.conf(5)'} : ${RC_PID:=$$} ; export RC_PID +nl=' +' # a literal newline # # functions @@ -65,6 +67,23 @@ } # +# yesno_to_truefalse var +# Convert the value of a variable from any of the values +# understood by checkyesno() to "true" or "false". +# +yesno_to_truefalse() +{ + local var=$1 + if checkyesno $var; then + eval $var=true + return 0 + else + eval $var=false + return 1 + fi +} + +# # reverse_list list # print the list in reverse order # @@ -723,6 +742,13 @@ # a backup or scratch file, ignore it. Otherwise if it's # executable run as a child process. # +# If `file' contains "KEYWORD: interactive" and if we are +# running inside /etc/rc with postprocessing (as signified by +# _rc_postprocessor_fd being defined) then the script's stdout +# and stderr are redirected to $_rc_original_stdout_fd and +# $_rc_original_stderr_fd, so the output will be displayed on the +# console but not intercepted by /etc/rc's postprocessor. +# run_rc_script() { _file=$1 @@ -738,20 +764,43 @@ rcvar required_dirs required_files required_vars eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd + _must_redirect=false + if ! [ -n "${_rc_postprocessor_fd}" ] \ + && _has_rcorder_keyword interactive $_file + then + _must_redirect=true + fi + case "$_file" in *.sh) # run in current shell - set $_arg ; . $_file + if $_must_redirect; then + print_rc_metadata \ + "note:Output from ${_file} is not logged" + set $_arg ; no_rc_postprocess . $_file + else + set $_arg ; . $_file + fi ;; *[~#]|*.OLD|*.orig|*,v) # scratch file; skip warn "Ignoring scratch file $_file" ;; *) # run in subshell - if [ -x $_file ]; then + if [ -x $_file ] && $_must_redirect; then + print_rc_metadata \ + "note:Output from ${_file} is not logged" + if [ -n "$rc_fast_and_loose" ]; then + set $_arg ; no_rc_postprocess . $_file + else + ( set $_arg ; no_rc_postprocess . $_file ) + fi + elif [ -x $_file ]; then if [ -n "$rc_fast_and_loose" ]; then set $_arg ; . $_file else ( set $_arg ; . $_file ) fi + else + warn "Ignoring non-executable file $_file" fi ;; esac @@ -961,4 +1010,124 @@ stop_boot } +# +# _has_rcorder_keyword word file +# Check whether a file contains a "# KEYWORD:" comment with a +# specified keyword in the style used by rcorder(8). +# +_has_rcorder_keyword() +{ + local word="$1" + local file="$2" + local line + + [ -r "$file" ] || return 1 + while read line; do + case "${line} " in + "# KEYWORD:"*[\ \ ]"${word}"[\ \ ]*) + return 0 + ;; + "#"*) + continue + ;; + *[A-Za-z0-9]*) + # give up at the first non-empty non-comment line + return 1 + ;; + esac + done <"$file" + return 1 +} + +# +# print_rc_metadata string +# Print the specified string in such a way that the post-processor +# inside /etc/rc will treat it as meta-data. +# +# If we are not running inside /etc/rc, do nothing. +# +# For public use by any rc.d script, the string must begin with +# "note:", followed by arbitrary text. The intent is that the text +# will appear in a log file but not on the console. +# +# For private use within /etc/rc, the string must contain a +# keyword recognised by the rc_postprocess_metadata() function +# defined in /etc/rc, followed by a colon, followed by one or more +# colon-separated arguments associated with the keyword. +# +print_rc_metadata() +{ + # _rc_postprocessor fd, if defined, is the fd to which we must + # print, prefixing the output with $_rc_metadata_prefix. + # + if [ -n "$_rc_postprocessor_fd" ]; then + printf "%s%s\n" "$rc_metadata_prefix" "$1" \ + >&${_rc_postprocessor_fd} + fi +} + +# +# print_rc_normal string +# Print the specified string in such way that it is treated as +# normal output, regardless of whether or not we are running +# inside /etc/rc with post-processing. +# +# Ths intent is that a script that is run via the +# no_rc_postprocess() function (so its output would ordinarily be +# invisible to the post-processor) can nevertheless arrange for +# the post-processor to see things printed with print_rc_normal(). +# +print_rc_normal() +{ + # If _rc_postprocessor_fd is defined, then it is the fd + # to shich we must print; otherwise print to stdout. + # + printf "%s\n" "$1" >&${_rc_postprocessor_fd:-1} +} + +# +# no_rc_postprocess cmd... +# Execute the specified command in such a way that its output +# bypasses the post-processor that handles the output from +# most commands that are run inside /etc/rc. If we are not +# inside /etc/rc, then just execute the command without special +# treatment. +# +# The intent is that interactive commands can be run via +# no_rc_postprocess(), and their output will apear immediately +# on the console instead of being hidden or delayed by the +# post-processor. An unfortunate consequence of the output +# bypassing the post-processor is that the output will not be +# logged. +# +no_rc_postprocess() +{ + if [ -n "${_rc_postprocessor_fd}" ]; then + "$@" >&${_rc_original_stdout_fd} 2>&${_rc_original_stderr_fd} + else + "$@" + fi +} + +# +# twiddle +# On each call, print a different one of "/", "-", "\\", "|", +# followed by a backspace. The most recently printed value is +# saved in $_twiddle_state. +# +# Output is to /dev/tty, so this function may be useful even inside +# a script whose output is redirected. +# +twiddle() +{ + case "$_twiddle_state" in + '/') _next='-' ;; + '-') _next='\' ;; + '\') _next='|' ;; + *) _next='/' ;; + esac + printf "%s\b" "$_next" >/dev/tty + _twiddle_state="$_next" +} + _rc_subr_loaded=: Index: src/etc/defaults/rc.conf diff -u src/etc/defaults/rc.conf:1.104 src/etc/defaults/rc.conf:1.105 --- src/etc/defaults/rc.conf:1.104 Sat Jul 25 16:20:10 2009 +++ src/etc/defaults/rc.conf Fri Sep 11 18:17:04 2009 @@ -1,4 +1,4 @@ -# $NetBSD: rc.conf,v 1.104 2009/07/25 16:20:10 mbalmer Exp $ +# $NetBSD: rc.conf,v 1.105 2009/09/11 18:17:04 apb Exp $ # # /etc/defaults/rc.conf -- # default configuration of /etc/rc.conf @@ -26,6 +26,17 @@ # #rc_fast_and_loose=YES +# If rc_silent is true then /etc/rc will suppress most output to +# the console. The default is taken from the AB_SILENT flag passed +# from the boot loader to the kernel in the boothowto(9) variable. +# +# rc_silent_cmd is executed once for each suppressed line of output. +# Useful values are ":" and "twiddle". +# +rc_silent=$( [ "$(( $(/sbin/sysctl -n kern.boothowto 2>/dev/null || echo 0) \ + & 0x40000 ))" != 0 ] && echo true || echo false ) +rc_silent_cmd=twiddle + # Additional flags to the rcorder(8) that's run by /etc/rc. # rc_rcorder_flags="" Index: src/share/man/man5/rc.conf.5 diff -u src/share/man/man5/rc.conf.5:1.132 src/share/man/man5/rc.conf.5:1.133 --- src/share/man/man5/rc.conf.5:1.132 Thu Sep 3 20:06:39 2009 +++ src/share/man/man5/rc.conf.5 Fri Sep 11 18:17:04 2009 @@ -1,4 +1,4 @@ -.\" $NetBSD: rc.conf.5,v 1.132 2009/09/03 20:06:39 apb Exp $ +.\" $NetBSD: rc.conf.5,v 1.133 2009/09/11 18:17:04 apb Exp $ .\" .\" Copyright (c) 1996 Matthew R. Green .\" All rights reserved. @@ -195,6 +195,34 @@ .Ev rc_directories must be located in the root filesystem, otherwise they will be silently skipped. +.It Sy rc_silent +Boolean value. +If true then the usual output is suppresses, and +.Xr rc 8 +invokes the command specified in the +.Va rc_silent_cmd +variable once for each line of suppressed output. +The default value of +.Va rc_silent +is set from the +.Dv AB_SILENT +flag in the kernel's +.Va boothowto +variable (see +.Xr boot 8 , +.Xr reboot 2 ) . +.It Sy rc_silent_cmd +A command to be executed once per line of suppressed output, when +.Va rc_silent +is true. +The default value of +.Va rc_silent_cmd +is +.Dq twiddle , +which will display a spinning symbol instead of each line of output. +Another useful value is +.Dq \&: , +which will display nothing at all. .El .Ss Basic network configuration .Bl -tag -width net_interfaces Index: src/share/man/man8/rc.8 diff -u src/share/man/man8/rc.8:1.31 src/share/man/man8/rc.8:1.32 --- src/share/man/man8/rc.8:1.31 Wed Apr 30 13:10:57 2008 +++ src/share/man/man8/rc.8 Fri Sep 11 18:17:04 2009 @@ -1,4 +1,4 @@ -.\" $NetBSD: rc.8,v 1.31 2008/04/30 13:10:57 martin Exp $ +.\" $NetBSD: rc.8,v 1.32 2009/09/11 18:17:04 apb Exp $ .\" .\" Copyright (c) 2000-2004 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -116,6 +116,27 @@ If the script has a .Sq .sh suffix then it is sourced directly into the current shell. +.It +The output from the above steps is sent to a post-processor. +If +.Sy rc_silent +is false, then the post-processor displays the output. +If +.Sy rc_silent +is true, then the post-processor invokes the command specified in +.Va rc_silent_cmd +once for each line, without otherwise displaying the output. +Useful values for +.Va rc_silent_cmd +include +.Dq \&: +to display nothing at all, and +.Dq twiddle +to display a spinning symbol on the console. +Regardless of the value of +.Sy rc_silent , +the post-processor saves the output in +.Pa /var/run/rc.log . .El .Ss Operation of rc.shutdown .Bl -enum @@ -311,6 +332,9 @@ functions used by various scripts. .It Pa /etc/rc.conf System startup configuration file. +.It Pa /var/run/rc.log +Log file created by +.Nm . .El .Sh SEE ALSO .Xr rc.conf 5 , @@ -331,3 +355,9 @@ by .An Luke Mewburn .Aq lu...@netbsd.org . +The post-processor, support for +.Va rc_silent , +and saving output to a file, was implemented in +.Nx 6.0 +by +.An Alan Barrett . Index: src/share/man/man8/rc.subr.8 diff -u src/share/man/man8/rc.subr.8:1.22 src/share/man/man8/rc.subr.8:1.23 --- src/share/man/man8/rc.subr.8:1.22 Thu Apr 9 04:01:06 2009 +++ src/share/man/man8/rc.subr.8 Fri Sep 11 18:17:04 2009 @@ -1,4 +1,4 @@ -.\" $NetBSD: rc.subr.8,v 1.22 2009/04/09 04:01:06 joerg Exp $ +.\" $NetBSD: rc.subr.8,v 1.23 2009/09/11 18:17:04 apb Exp $ .\" .\" Copyright (c) 2002-2004 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -54,6 +54,12 @@ .It .Ic mount_critical_filesystems Ar type .It +.Ic no_rc_postprocess Ar command Op Ar arguments +.It +.Ic print_rc_metadata Ar string +.It +.Ic print_rc_normal Ar string +.It .Ic rc_usage Ar command Op Ar ... .It .Ic reverse_list Ar item Op Ar ... @@ -64,9 +70,13 @@ .It .Ic stop_boot .It +.Ic twiddle +.It .Ic wait_for_pids Op Ar pid Op Ar ... .It .Ic warn Ar message +.It +.Ic yesno_to_truefalse Ar var .El .Sh DESCRIPTION .Nm @@ -251,6 +261,71 @@ .Sy critical_filesystems_ Ns Ar type , mounting each one that is not currently mounted. +.It Ic no_rc_postprocess Ar command Op Ar arguments +Execute the specified command with the specified arguments, +in such a way that its output bypasses the post-processor that +.Xr rc 8 +uses for most commands. +This implies that the output will not appear in the +.Pa /var/run/rc.log +file, and will appear on the console regardless of the +value of +.Va rc_silent. +This is expected to be useful for interactive commands, +and this mechanism is automatically used by +.Ic run_rc_command +when a script contains the +.Xr rcorder 8 +keyword +.Dq interactive . +.Pp +If invoked from a context that does not appear to be under the control of +.Xr rc 8 , +then the command is executed without special treatment. +.It Ic print_rc_metadata Ar string +Print the specified +.Ar string +in such a way that it should be handled as meta-data by the +.Xr rc 8 +post-processor. +If invoked from a context that does not appear to be under the control of +.Xr rc 8 , +then the +.Ar string +is discarded. +.Pp +Any +.Xr rc.d 8 +script may invoke this function with an argument that begins with +.Dq note: , +followed by one line of arbitrary text; +the text will be logged by +.Xr rc 8 +but will not be displayed on the console. +.Pp +The use of arguments that do not begin with +.Dq note: +is reserved for internal use by +.Xr rc 8 +and +.Xr rc.subr 8 . +.It Ic print_rc_normal Ar string +Print the specified +.Ar string +in such a way that it should be handled as normal output by the +.Xr rc 8 +post-processor. +If invoked from a context that does not appear to be under the control of +.Xr rc 8 , +then the +.Ar string +is printed to standard output. +.Pp +Ths intent is that a script that is run via the +.Fn no_rc_postprocess +function (so its output would ordinarily be invisible to the post-processor) +can nevertheless arrange for the post-processor to see things printed with +.Fn print_rc_normal. .It Ic rc_usage Ar command Op Ar ... Print a usage message for .Sy $0 , @@ -663,6 +738,15 @@ otherwise source .Ar file into the current shell. +.It +If +.Ar file +contains the +.Xr rcorder 8 +keyword +.Dq interactive , +then the command is executed using +.Ic no_rc_postprocess . .El .It Ic stop_boot Prevent booting to multiuser mode. @@ -677,6 +761,16 @@ .Xr rc 8 ) . Otherwise, the shell exits with status .Li 1 . +.It Ic twiddle +Display one of the characters +.Sq \&/ , \&- , \&\e , \&| , +followed by a backspace. +Repeated calls to this function will create the appearance of a spinning +symbol, as a different character is displayed on each call. +Output is to +.Pa /dev/tty , +so this function may be useful even inside a script whose output +has been redirected. .It Ic wait_for_pids Op Ar pid Op Ar ... Wait until all of the provided .Ar pids @@ -696,6 +790,14 @@ .Dq ": WARNING: " , and then .Ar message . +.It Ic yesno_to_truefalse Ar var +Change the value of the specified variable from any of the +forms acceptable to the +.Is checkyesno +function, to +.Dq true +or +.Dq false . .El .Sh FILES .Bl -tag -width /etc/rc.subr -compact @@ -716,3 +818,7 @@ .Xr rc.d 8 support functions appeared in .Nx 1.5 . +Support for the +.Xr rc 8 +post-processor appeared in +.Nx 6.0 .