mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 12:48:33 -10:00
syslogd_start() waits for the local log socket to appear before returning, to ensure that the daemon is ready to handle log messages. Some tests start two daemons, so by default the socket already exists when the second daemon is started, so syslogd_start() returns early. The test subsequently sends a message to this second daemon, which sometimes isn't ready. Define a separate log socket for the second daemon. Add a check to syslogd_start() to help catch this type of bug. Reviewed by: jlduran MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D54800
208 lines
4.8 KiB
Bash
208 lines
4.8 KiB
Bash
#-
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
#
|
|
# Copyright (c) 2021, 2023 The FreeBSD Foundation
|
|
#
|
|
# This software was developed by Mark Johnston under sponsorship from
|
|
# the FreeBSD Foundation.
|
|
#
|
|
# This software was developed by Jake Freeland under sponsorship from
|
|
# the FreeBSD Foundation.
|
|
#
|
|
|
|
readonly SYSLOGD_UDP_PORT="5140"
|
|
readonly SYSLOGD_CONFIG="${PWD}/syslog.conf"
|
|
readonly SYSLOGD_LOCAL_SOCKET="${PWD}/log.sock"
|
|
readonly SYSLOGD_PIDFILE="${PWD}/syslogd.pid"
|
|
readonly SYSLOGD_LOCAL_PRIVSOCKET="${PWD}/logpriv.sock"
|
|
readonly SYSLOGD_LOGFILE="${PWD}/log"
|
|
|
|
# Start a private syslogd instance.
|
|
syslogd_start()
|
|
{
|
|
local jail bind_arg conf_file pid_file socket privsocket
|
|
local opt next other_args
|
|
|
|
OPTIND=1
|
|
while getopts ":b:f:j:P:p:S:" opt; do
|
|
case "${opt}" in
|
|
b)
|
|
bind_arg="${bind_arg} -b ${OPTARG}"
|
|
;;
|
|
f)
|
|
conf_file="${OPTARG}"
|
|
;;
|
|
j)
|
|
jail="jexec ${OPTARG}"
|
|
;;
|
|
P)
|
|
pid_file="${OPTARG}"
|
|
;;
|
|
p)
|
|
socket="${OPTARG}"
|
|
;;
|
|
S)
|
|
privsocket="${OPTARG}"
|
|
;;
|
|
?)
|
|
opt="${OPTARG}"
|
|
next="$(eval echo \${${OPTIND}})"
|
|
|
|
case "${next}" in
|
|
-* | "")
|
|
other_args="${other_args} -${opt}"
|
|
shift $((OPTIND - 1))
|
|
;;
|
|
*)
|
|
other_args="${other_args} -${opt} ${next}"
|
|
shift ${OPTIND}
|
|
;;
|
|
esac
|
|
|
|
# Tell getopts to continue parsing.
|
|
OPTIND=1
|
|
;;
|
|
:)
|
|
atf_fail "The -${OPTARG} flag requires an argument"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
socket=${socket:-${SYSLOGD_LOCAL_SOCKET}}
|
|
if [ -S "${socket}" ]; then
|
|
atf_fail "socket ${socket} already exists"
|
|
fi
|
|
|
|
# Setup loopback so we can deliver messages to ourself.
|
|
if [ $($jail sysctl -n security.jail.vnet) -ne 0 ]; then
|
|
atf_check $jail ifconfig lo0 inet 127.0.0.1/8
|
|
fi
|
|
|
|
$jail syslogd \
|
|
${bind_arg:--b :${SYSLOGD_UDP_PORT}} \
|
|
-C \
|
|
-d \
|
|
-f "${conf_file:-${SYSLOGD_CONFIG}}" \
|
|
-H \
|
|
-P "${pid_file:-${SYSLOGD_PIDFILE}}" \
|
|
-p "${socket}" \
|
|
-S "${privsocket:-${SYSLOGD_LOCAL_PRIVSOCKET}}" \
|
|
${other_args} \
|
|
&
|
|
|
|
# Give syslogd a bit of time to spin up.
|
|
if grep -q "[[:space:]]${SYSLOGD_LOGFILE}$" "${conf_file:-${SYSLOGD_CONFIG}}"; then
|
|
while [ ! -f "${SYSLOGD_LOGFILE}" ]; do
|
|
sleep 0.1
|
|
done
|
|
fi
|
|
while [ "$((i+=1))" -le 20 ]; do
|
|
[ -S "${socket}" ] && return
|
|
sleep 0.1
|
|
done
|
|
atf_fail "timed out waiting for syslogd to start"
|
|
}
|
|
|
|
# Simple logger(1) wrapper.
|
|
syslogd_log()
|
|
{
|
|
atf_check -s exit:0 -o empty -e empty logger $*
|
|
}
|
|
|
|
syslogd_log_jail()
|
|
{
|
|
local jailname=$1
|
|
shift
|
|
atf_check -s exit:0 -o empty -e empty jexec ${jailname} logger $*
|
|
}
|
|
|
|
# Make syslogd reload its configuration file.
|
|
syslogd_reload()
|
|
{
|
|
atf_check truncate -s 0 ${SYSLOGD_LOGFILE}
|
|
atf_check pkill -HUP -F "${1:-${SYSLOGD_PIDFILE}}"
|
|
sleep 0.1
|
|
}
|
|
|
|
# Stop a private syslogd instance.
|
|
syslogd_stop()
|
|
{
|
|
local pid_file="${1:-${SYSLOGD_PIDFILE}}"
|
|
local socket_file="${2:-${SYSLOGD_LOCAL_SOCKET}}"
|
|
local privsocket_file="${3:-${SYSLOGD_LOCAL_PRIVSOCKET}}"
|
|
|
|
pid=$(cat "${pid_file}")
|
|
if pkill -F "${pid_file}"; then
|
|
wait "${pid}"
|
|
rm -f "${pid_file}" "${socket_file}" "${privsocket_file}"
|
|
fi
|
|
}
|
|
|
|
# Check required kernel module.
|
|
syslogd_check_req()
|
|
{
|
|
type=$1
|
|
|
|
if kldstat -q -n if_${type}.ko; then
|
|
return
|
|
fi
|
|
|
|
if ! kldload -n -q if_${type}; then
|
|
atf_skip "if_${type}.ko is required to run this test."
|
|
return
|
|
fi
|
|
}
|
|
|
|
# Make a jail and save its name to the created_jails.lst file.
|
|
# Accepts a name and optional arguments.
|
|
syslogd_mkjail()
|
|
{
|
|
jailname=$1
|
|
shift
|
|
args=$*
|
|
|
|
atf_check jail -c name=${jailname} ${args} persist
|
|
|
|
echo $jailname >> created_jails.lst
|
|
}
|
|
|
|
# Remove epair interfaces and jails.
|
|
syslogd_cleanup()
|
|
{
|
|
if [ -f created_jails.lst ]; then
|
|
while read jailname; do
|
|
jail -r ${jailname}
|
|
done < created_jails.lst
|
|
rm created_jails.lst
|
|
fi
|
|
|
|
if [ -f epair ]; then
|
|
ifconfig $(cat epair) destroy
|
|
fi
|
|
}
|
|
|
|
# Check the last entry in the log file for a given message.
|
|
syslogd_check_log_nopoll()
|
|
{
|
|
local msg=$1
|
|
|
|
atf_check -o match:"${msg}" tail -n 1 "${SYSLOGD_LOGFILE}"
|
|
}
|
|
|
|
# Same as above, but first wait for syslogd to write to the log file.
|
|
syslogd_check_log()
|
|
{
|
|
local msg=$1
|
|
|
|
atf_check -r 10 -o match:"${msg}" tail -n 1 "${SYSLOGD_LOGFILE}"
|
|
}
|
|
|
|
# Make sure no log entry matching the given message exists.
|
|
syslogd_check_log_nomatch()
|
|
{
|
|
local msg=$1
|
|
|
|
sleep 0.5
|
|
atf_check -o not-match:"${msg}" cat "${SYSLOGD_LOGFILE}"
|
|
}
|