commit de8ef74e140ceba13e037f0d1dc8e6040e3232e3 Author: Richard Yao Date: Sat Jul 14 05:54:20 2012 -0400 Import encswap and jail init scripts from FreeBSD The FreeBSD init scripts have been adapted to function in OpenRC. Signed-off-by: Richard Yao diff --git a/init.d/Makefile b/init.d/Makefile index a34ee90..3b55e81 100644 --- a/init.d/Makefile +++ b/init.d/Makefile @@ -22,8 +22,8 @@ NET_LO-FreeBSD= net.lo0 SRCS-FreeBSD= hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \ rpcbind.in savecore.in syslogd.in # These are FreeBSD specific -SRCS-FreeBSD+= adjkerntz.in devd.in dumpon.in ipfw.in mixer.in nscd.in \ - powerd.in syscons.in +SRCS-FreeBSD+= adjkerntz.in devd.in dumpon.in encswap.in ipfw.in jail.in \ + mixer.in nscd.in powerd.in syscons.in NET_LO-Linux= net.lo SRCS-Linux= devfs.in dmesg.in hwclock.in consolefont.in keymaps.in \ diff --git a/init.d/encswap.in b/init.d/encswap.in new file mode 100755 index 0000000..a03fe58 --- /dev/null +++ b/init.d/encswap.in @@ -0,0 +1,46 @@ +#!@PREFIX@/sbin/runscript +# Copyright 1992-2012 FreeBSD Project +# Released under the 2-clause BSD license +# $Header: $ + +depend() { + before swap +} + +start() { + while read device mountpoint type options rest ; do + case ":${device}:${type}:${options}" in + :#*) + continue + ;; + *.bde:swap:sw) + passphrase=`dd if=/dev/random count=1 2>/dev/null | md5 -q` + device="${device%.bde}" + gbde init "${device}" -P "${passphrase}" || return 1 + gbde attach "${device}" -p "${passphrase}" || return 1 + ;; + *.eli:swap:sw) + device="${device%.eli}" + geli onetime ${geli_swap_flags} "${device}" || return 1 + ;; + esac + done < /etc/fstab +} + +stop() { + while read device mountpoint type options rest ; do + case ":${device}:${type}:${options}" in + :#*) + continue + ;; + *.bde:swap:sw) + device="${device%.bde}" + gbde detach "${device}" + ;; + *.eli:swap:sw) + # Nothing here, because geli swap devices should be + # created with the auto-detach-on-last-close option. + ;; + esac + done < /etc/fstab +} diff --git a/init.d/jail.in b/init.d/jail.in new file mode 100755 index 0000000..c7685bf --- /dev/null +++ b/init.d/jail.in @@ -0,0 +1,886 @@ +#!@PREFIX@/sbin/runscript +# Copyright 1992-2012 FreeBSD Project +# Released under the 2-clause BSD license +# $Header: $ + +debug() +{ + einfo $@ +} + +# devfs_rulesets_from_file file +# Reads a set of devfs commands from file, and creates +# the specified rulesets with their rules. Returns non-zero +# if there was an eerroror. +# +devfs_rulesets_from_file() +{ + local file _eerror _me + file="$1" + _me="devfs_rulesets_from_file" + _eerror=0 + + if [ -z "$file" ]; then + ewarn "$_me: you must specify a file" + return 1 + fi + if [ ! -e "$file" ]; then + debug "$_me: no such file ($file)" + return 0 + fi + debug "reading rulesets from file ($file)" + { while read line + do + case $line in + \#*) + continue + ;; + \[*\]*) + rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"` + if [ -z "$rulenum" ]; then + ewarn "$_me: cannot extract rule number ($line)" + _eerror=1 + break + fi + rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"` + if [ -z "$rulename" ]; then + ewarn "$_me: cannot extract rule name ($line)" + _eerror=1 + break; + fi + eval $rulename=\$rulenum + debug "found ruleset: $rulename=$rulenum" + if ! /sbin/devfs rule -s $rulenum delset; then + _eerror=1 + break + fi + ;; + *) + rulecmd="${line%%"\#*"}" + # evaluate the command incase it includes + # other rules + if [ -n "$rulecmd" ]; then + debug "adding rule ($rulecmd)" + if ! eval /sbin/devfs rule -s $rulenum $rulecmd + then + _eerror=1 + break + fi + fi + ;; + esac + if [ $_eerror -ne 0 ]; then + debug "eerroror in $_me" + break + fi + done } < $file + return $_eerror +} + +# devfs_init_rulesets +# Initializes rulesets from configuration files. Returns +# non-zero if there was an eerroror. +# +devfs_init_rulesets() +{ + local file _me + _me="devfs_init_rulesets" + + # Go through this only once + if [ -n "$devfs_rulesets_init" ]; then + debug "$_me: devfs rulesets already initialized" + return + fi + for file in $devfs_rulesets; do + if ! devfs_rulesets_from_file $file; then + ewarn "$_me: could not read rules from $file" + return 1 + fi + done + devfs_rulesets_init=1 + debug "$_me: devfs rulesets initialized" + return 0 +} + +# devfs_set_ruleset ruleset [dir] +# Sets the default ruleset of dir to ruleset. The ruleset argument +# must be a ruleset name as specified in devfs.rules(5) file. +# Returns non-zero if it could not set it successfully. +# +devfs_set_ruleset() +{ + local devdir rs _me + [ -n "$1" ] && eval rs=\$$1 || rs= + [ -n "$2" ] && devdir="-m "$2"" || devdir= + _me="devfs_set_ruleset" + + if [ -z "$rs" ]; then + ewarn "$_me: you must specify a ruleset number" + return 1 + fi + debug "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })" + if ! /sbin/devfs $devdir ruleset $rs; then + ewarn "$_me: unable to set ruleset $rs to ${devdir#-m }" + return 1 + fi + return 0 +} + +# devfs_domount dir [ruleset] +# Mount devfs on dir. If ruleset is specified it is set +# on the mount-point. It must also be a ruleset name as specified +# in a devfs.rules(5) file. Returns 0 on success. +# +devfs_domount() +{ + local devdir rs _me + devdir="$1" + [ -n "$2" ] && rs=$2 || rs= + _me="devfs_domount()" + + if [ -z "$devdir" ]; then + ewarn "$_me: you must specify a mount-point" + return 1 + fi + debug "$_me: mount-point is ($devdir), ruleset is ($rs)" + if ! mount -t devfs dev "$devdir"; then + ewarn "$_me: Unable to mount devfs on $devdir" + return 1 + fi + if [ -n "$rs" ]; then + devfs_init_rulesets + devfs_set_ruleset $rs $devdir + devfs -m $devdir rule applyset + fi + return 0 +} + +# devfs_mount_jail dir [ruleset] +# Mounts a devfs file system appropriate for jails +# on the directory dir. If ruleset is specified, the ruleset +# it names will be used instead. If present, ruleset must +# be the name of a ruleset as defined in a devfs.rules(5) file. +# This function returns non-zero if an eerroror occurs. +# +devfs_mount_jail() +{ + local jdev rs _me + jdev="$1" + [ -n "$2" ] && rs=$2 || rs="devfsrules_jail" + _me="devfs_mount_jail" + + devfs_init_rulesets + if ! devfs_domount "$jdev" $rs; then + ewarn "$_me: devfs was not mounted on $jdev" + return 1 + fi + return 0 +} + +# init_variables _j +# Initialize the various jail variables for jail _j. +# +init_variables() +{ + _j="$1" + + if [ -z "$_j" ]; then + ewarn "init_variables: you must specify a jail" + return + fi + + eval _rootdir=\"\$jail_${_j}_rootdir\" + _devdir="${_rootdir}/dev" + _fdescdir="${_devdir}/fd" + _procdir="${_rootdir}/proc" + eval _hostname=\"\$jail_${_j}_hostname\" + eval _ip=\"\$jail_${_j}_ip\" + eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\" + eval _exec=\"\$jail_${_j}_exec\" + + i=0 + while : ; do + eval _exec_prestart${i}=\"\${jail_${_j}_exec_prestart${i}:-\${jail_exec_prestart${i}}}\" + [ -z "$(eval echo \"\$_exec_prestart${i}\")" ] && break + i=$((i + 1)) + done + + eval _exec_start=\"\${jail_${_j}_exec_start:-${jail_exec_start}}\" + + i=1 + while : ; do + eval _exec_afterstart${i}=\"\${jail_${_j}_exec_afterstart${i}:-\${jail_exec_afterstart${i}}}\" + [ -z "$(eval echo \"\$_exec_afterstart${i}\")" ] && break + i=$((i + 1)) + done + + i=0 + while : ; do + eval _exec_poststart${i}=\"\${jail_${_j}_exec_poststart${i}:-\${jail_exec_poststart${i}}}\" + [ -z "$(eval echo \"\$_exec_poststart${i}\")" ] && break + i=$((i + 1)) + done + + i=0 + while : ; do + eval _exec_prestop${i}=\"\${jail_${_j}_exec_prestop${i}:-\${jail_exec_prestop${i}}}\" + [ -z "$(eval echo \"\$_exec_prestop${i}\")" ] && break + i=$((i + 1)) + done + + eval _exec_stop=\"\${jail_${_j}_exec_stop:-${jail_exec_stop}}\" + + i=0 + while : ; do + eval _exec_poststop${i}=\"\${jail_${_j}_exec_poststop${i}:-\${jail_exec_poststop${i}}}\" + [ -z "$(eval echo \"\$_exec_poststop${i}\")" ] && break + i=$((i + 1)) + done + + if [ -n "${_exec}" ]; then + # simple/backward-compatible execution + _exec_start="${_exec}" + _exec_stop="" + else + # flexible execution + if [ -z "${_exec_start}" ]; then + _exec_start="/bin/sh /etc/rc" + if [ -z "${_exec_stop}" ]; then + _exec_stop="/bin/sh /etc/rc.shutdown" + fi + fi + fi + + # The default jail ruleset will be used by rc.subr if none is specified. + eval _ruleset=\"\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}\" + eval _devfs=\"\${jail_${_j}_devfs_enable:-${jail_devfs_enable}}\" + [ -z "${_devfs}" ] && _devfs="NO" + eval _fdescfs=\"\${jail_${_j}_fdescfs_enable:-${jail_fdescfs_enable}}\" + [ -z "${_fdescfs}" ] && _fdescfs="NO" + eval _procfs=\"\${jail_${_j}_procfs_enable:-${jail_procfs_enable}}\" + [ -z "${_procfs}" ] && _procfs="NO" + + eval _mount=\"\${jail_${_j}_mount_enable:-${jail_mount_enable}}\" + [ -z "${_mount}" ] && _mount="NO" + # "/etc/fstab.${_j}" will be used for {,u}mount(8) if none is specified. + eval _fstab=\"\${jail_${_j}_fstab:-${jail_fstab}}\" + [ -z "${_fstab}" ] && _fstab="/etc/fstab.${_j}" + eval _flags=\"\${jail_${_j}_flags:-${jail_flags}}\" + [ -z "${_flags}" ] && _flags="-l -U root" + eval _consolelog=\"\${jail_${_j}_consolelog:-${jail_consolelog}}\" + [ -z "${_consolelog}" ] && _consolelog="/var/log/jail_${_j}_console.log" + eval _fib=\"\${jail_${_j}_fib:-${jail_fib}}\" + + # Debugging aid + # + debug "$_j devfs enable: $_devfs" + debug "$_j fdescfs enable: $_fdescfs" + debug "$_j procfs enable: $_procfs" + debug "$_j mount enable: $_mount" + debug "$_j hostname: $_hostname" + debug "$_j ip: $_ip" + jail_show_addresses ${_j} + debug "$_j interface: $_interface" + debug "$_j fib: $_fib" + debug "$_j root: $_rootdir" + debug "$_j devdir: $_devdir" + debug "$_j fdescdir: $_fdescdir" + debug "$_j procdir: $_procdir" + debug "$_j ruleset: $_ruleset" + debug "$_j fstab: $_fstab" + + i=0 + while : ; do + eval out=\"\${_exec_prestart${i}:-''}\" + if [ -z "$out" ]; then + break + fi + debug "$_j exec pre-start #${i}: ${out}" + i=$((i + 1)) + done + + debug "$_j exec start: $_exec_start" + + i=1 + while : ; do + eval out=\"\${_exec_afterstart${i}:-''}\" + + if [ -z "$out" ]; then + break; + fi + + debug "$_j exec after start #${i}: ${out}" + i=$((i + 1)) + done + + i=0 + while : ; do + eval out=\"\${_exec_poststart${i}:-''}\" + if [ -z "$out" ]; then + break + fi + debug "$_j exec post-start #${i}: ${out}" + i=$((i + 1)) + done + + i=0 + while : ; do + eval out=\"\${_exec_prestop${i}:-''}\" + if [ -z "$out" ]; then + break + fi + debug "$_j exec pre-stop #${i}: ${out}" + i=$((i + 1)) + done + + debug "$_j exec stop: $_exec_stop" + + i=0 + while : ; do + eval out=\"\${_exec_poststop${i}:-''}\" + if [ -z "$out" ]; then + break + fi + debug "$_j exec post-stop #${i}: ${out}" + i=$((i + 1)) + done + + debug "$_j flags: $_flags" + debug "$_j consolelog: $_consolelog" + + if [ -z "${_hostname}" ]; then + eerror 3 "$name: No hostname has been defined for ${_j}" + fi + if [ -z "${_rootdir}" ]; then + eerror 3 "$name: No root directory has been defined for ${_j}" + fi +} + +# set_sysctl rc_knob mib msg +# If the mib sysctl is set according to what rc_knob +# specifies, this function does nothing. However if +# rc_knob is set differently than mib, then the mib +# is set accordingly and msg is displayed followed by +# an '=" sign and the word 'YES' or 'NO'. +# +set_sysctl() +{ + _knob="$1" + _mib="$2" + _msg="$3" + + SYSCTL="@PREFIX@/sbin/sysctl" + _current=`${SYSCTL} -n $_mib 2>/dev/null` + if yesno $_knob ; then + if [ "$_current" -ne 1 ]; then + einfo "${_msg}=YES" + ${SYSCTL} 1>/dev/null ${_mib}=1 + fi + else + if [ "$_current" -ne 0 ]; then + einfo "${_msg}=NO" + ${SYSCTL} 1>/dev/null ${_mib}=0 + fi + fi +} + +# is_current_mountpoint() +# Is the directory mount point for a currently mounted file +# system? +# +is_current_mountpoint() +{ + local _dir _dir2 + + _dir=$1 + + _dir=`echo $_dir | sed -Ee 's#//+#/#g' -e 's#/$##'` + [ ! -d "${_dir}" ] && return 1 + _dir2=`df ${_dir} | tail +2 | awk '{ print $6 }'` + [ "${_dir}" = "${_dir2}" ] + return $? +} + +# is_symlinked_mountpoint() +# Is a mount point, or any of its parent directories, a symlink? +# +is_symlinked_mountpoint() +{ + local _dir + + _dir=$1 + + [ -L "$_dir" ] && return 0 + [ "$_dir" = "/" ] && return 1 + is_symlinked_mountpoint `dirname $_dir` + return $? +} + +# secure_umount +# Try to unmount a mount point without being vulnerable to +# symlink attacks. +# +secure_umount() +{ + local _dir + + _dir=$1 + + if is_current_mountpoint ${_dir}; then + umount -f ${_dir} >/dev/null 2>&1 + else + ewarn "Nothing mounted on ${_dir} - not unmounting" + fi +} + + +# jail_umount_fs +# This function unmounts certain special filesystems in the +# currently selected jail. The caller must call the init_variables() +# routine before calling this one. +# +jail_umount_fs() +{ + local _device _mountpt _rest + + if yesno _fdescfs; then + if [ -d "${_fdescdir}" ] ; then + secure_umount ${_fdescdir} + fi + fi + if yesno _devfs; then + if [ -d "${_devdir}" ] ; then + secure_umount ${_devdir} + fi + fi + if yesno _procfs; then + if [ -d "${_procdir}" ] ; then + secure_umount ${_procdir} + fi + fi + if yesno _mount; then + [ -f "${_fstab}" ] || ewarn "${_fstab} does not exist" + tail -r ${_fstab} | while read _device _mountpt _rest; do + case ":${_device}" in + :#* | :) + continue + ;; + esac + secure_umount ${_mountpt} + done + fi +} + +# jail_mount_fstab() +# Mount file systems from a per jail fstab while trying to +# secure against symlink attacks at the mount points. +# +# If we are certain we cannot secure against symlink attacks we +# do not mount all of the file systems (since we cannot just not +# mount the file system with the problematic mount point). +# +# The caller must call the init_variables() routine before +# calling this one. +# +jail_mount_fstab() +{ + local _device _mountpt _rest + + while read _device _mountpt _rest; do + case ":${_device}" in + :#* | :) + continue + ;; + esac + if is_symlinked_mountpoint ${_mountpt}; then + ewarn "${_mountpt} has symlink as parent - not mounting from ${_fstab}" + return + fi + done <${_fstab} + mount -a -F "${_fstab}" +} + +# jail_show_addresses jail +# Debug print the input for the given _multi aliases +# for a jail for init_variables(). +# +jail_show_addresses() +{ + local _j _type alias + _j="$1" + alias=0 + + if [ -z "${_j}" ]; then + ewarn "jail_show_addresses: you must specify a jail" + return + fi + + while : ; do + eval _addr=\"\$jail_${_j}_ip_multi${alias}\" + if [ -n "${_addr}" ]; then + debug "${_j} ip_multi${alias}: $_addr" + alias=$((${alias} + 1)) + else + break + fi + done +} + +# jail_extract_address argument +# The second argument is the string from one of the _ip +# or the _multi variables. In case of a comma separated list +# only one argument must be passed in at a time. +# The function alters the _type, _iface, _addr and _mask variables. +# +jail_extract_address() +{ + local _i + _i=$1 + + if [ -z ${_i}" ]; then + ewarn "jail_extract_address: called without input" + return + fi + + # Check if we have an interface prefix given and split into + # iFace and rest. + case "${_i}" in + *\|*) # ifN|.. prefix there + _iface=${_i%%|*} + _r=${_i##*|} + ;; + *) _iface="" + _r=${_i} + ;; + esac + + # In case the IP has no interface given, check if we have a global one. + _iface=${_iface:-${_interface}} + + # Set address, cut off any prefix/netmask/prefixlen. + _addr=${_r} + _addr=${_addr%%[/ ]*} + + # Theoretically we can return here if interface is not set, + # as we only care about the _mask if we call ifconfig. + # This is not done because we may want to santize IP addresses + # based on _type later, and optionally change the type as well. + + # Extract the prefix/netmask/prefixlen part by cutting off the address. + _mask=${_r} + _mask=`expr "${_mask}" : "${_addr}\(.*\)"` + + # Identify type {inet,inet6}. + case "${_addr}" in + *\.*\.*\.*) _type="inet" ;; + *:*) _type="inet6" ;; + *) ewarn "jail_extract_address: type not identified" + ;; + esac + + # Handle the special /netmask instead of /prefix or + # "netmask xxx" case for legacy IP. + # We do NOT support shortend class-full netmasks. + if [ "${_type}" = "inet" ]; then + case "${_mask}" in + /*\.*\.*\.*) _mask=" netmask ${_mask#/}" ;; + *) ;; + esac + + # In case _mask is still not set use /32. + _mask=${_mask:-/32} + + elif [ "${_type}" = "inet6" ]; then + # In case _maske is not set for IPv6, use /128. + _mask=${_mask:-/128} + fi +} + +# jail_handle_ips_option {add,del} input +# Handle a single argument imput which can be a comma separated +# list of addresses (theoretically with an option interface and +# prefix/netmask/prefixlen). +# +jail_handle_ips_option() +{ + local _x _action _type _i + _action=$1 + _x=$2 + + if [ -z "${_x}" ]; then + # No IP given. This can happen for the primary address + # of each address family. + return + fi + + # Loop, in case we find a comma separated list, we need to handle + # each argument on its own. + while [ ${#_x} -gt 0 ]; do + case "${_x}" in + *,*) # Extract the first argument and strip it off the list. + _i=`expr "${_x}" : '^\([^,]*\)'` + _x=`expr "${_x}" : "^[^,]*,\(.*\)"` + ;; + *) _i=${_x} + _x="" + ;; + esac + + _type="" + _iface="" + _addr="" + _mask="" + jail_extract_address "${_i}" + + # make sure we got an address. + case "${_addr}" in + "") continue ;; + *) ;; + esac + + # Append address to list of addresses for the jail command. + case "${_addrl}" in + "") _addrl="${_addr}" ;; + *) _addrl="${_addrl},${_addr}" ;; + esac + + # Configure interface alias if requested by a given interface + # and if we could correctly parse everything. + case "${_iface}" in + "") continue ;; + esac + case "${_type}" in + inet) ;; + inet6) ;; + *) ewarn "Could not determine address family. Not going" \ + "to ${_action} address '${_addr}' for ${_jail}." + continue + ;; + esac + case "${_action}" in + add) ifconfig ${_iface} ${_type} ${_addr}${_mask} alias + ;; + del) # When removing the IP, ignore the _mask. + ifconfig ${_iface} ${_type} ${_addr} -alias + ;; + esac + done +} + +# jail_ips {add,del} +# Extract the comma separated list of addresses and return them +# for the jail command. +# Handle more than one address via the _multi option as well. +# If an interface is given also add/remove an alias for the +# address with an optional netmask. +# +jail_ips() +{ + local _action + _action=$1 + + case "${_action}" in + add) ;; + del) ;; + *) ewarn "jail_ips: invalid action '${_action}'" + return + ;; + esac + + # Handle addresses. + jail_handle_ips_option ${_action} "${_ip}" + # Handle jail_xxx_ip_multi + alias=0 + while : ; do + eval _x=\"\$jail_${_jail}_ip_multi${alias}\" + case "${_x}" in + "") break ;; + *) jail_handle_ips_option ${_action} "${_x}" + alias=$((${alias} + 1)) + ;; + esac + done +} + +start_pre() +{ + if yesno jail_parallel_start; then + command_args='&' + fi +} + +start() +{ + ebegin 'Configuring jails:' + set_sysctl jail_set_hostname_allow security.jail.set_hostname_allowed \ + set_hostname_allow + set_sysctl jail_socket_unixiproute_only \ + security.jail.socket_unixiproute_only unixiproute_only + set_sysctl jail_sysvipc_allow security.jail.sysvipc_allowed \ + sysvipc_allow + eend + + ebegin 'Starting jails:' + _tmp_dir=`mktemp -d /tmp/jail.XXXXXXXX` || \ + eerror 3 "$name: Can't create temp dir, exiting..." + for _jail in ${jail_list} + do + init_variables $_jail + if [ -f /var/run/jail_${_jail}.id ]; then + ewarn " [${_hostname} already running (/var/run/jail_${_jail}.id exists)]" + continue; + fi + _addrl="" + jail_ips "add" + if [ -n "${_fib}" ]; then + _setfib="setfib -F '${_fib}'" + else + _setfib="" + fi + if yesno _mount; then + einfo "Mounting fstab for jail ${_jail} (${_fstab})" + if [ ! -f "${_fstab}" ]; then + eerror 3 "$name: ${_fstab} does not exist" + fi + jail_mount_fstab + fi + if yesno _devfs; then + # If devfs is already mounted here, skip it. + df -t devfs "${_devdir}" >/dev/null + if [ $? -ne 0 ]; then + if is_symlinked_mountpoint ${_devdir}; then + ewarn "${_devdir} has symlink as parent - not starting jail ${_jail}" + continue + fi + einfo "Mounting devfs on ${_devdir}" + devfs_mount_jail "${_devdir}" ${_ruleset} + # Transitional symlink for old binaries + if [ ! -L "${_devdir}/log" ]; then + __pwd="`pwd`" + cd "${_devdir}" + ln -sf ../var/run/log log + cd "$__pwd" + fi + fi + + # XXX - It seems symlinks don't work when there + # is a devfs(5) device of the same name. + # Jail console output + # __pwd="`pwd`" + # cd "${_devdir}" + # ln -sf ../var/log/console console + # cd "$__pwd" + fi + if yesno _fdescfs; then + if is_symlinked_mountpoint ${_fdescdir}; then + ewarn "${_fdescdir} has symlink as parent, not mounting" + else + einfo "Mounting fdescfs on ${_fdescdir}" + mount -t fdescfs fdesc "${_fdescdir}" + fi + fi + if yesno _procfs; then + if is_symlinked_mountpoint ${_procdir}; then + ewarn "${_procdir} has symlink as parent, not mounting" + else + einfo "Mounting procfs onto ${_procdir}" + if [ -d "${_procdir}" ] ; then + mount -t procfs proc "${_procdir}" + fi + fi + fi + _tmp_jail=${_tmp_dir}/jail.$$ + + i=0 + while : ; do + eval out=\"\${_exec_prestart${i}:-''}\" + [ -z "$out" ] && break + ${out} + i=$((i + 1)) + done + + eval ${_setfib} jail ${_flags} -i ${_rootdir} ${_hostname} \ + \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1 \ + ${_consolelog} + echo ${_jail_id} > /var/run/jail_${_jail}.id + + i=0 + while : ; do + eval out=\"\${_exec_poststart${i}:-''}\" + [ -z "$out" ] && break + ${out} + i=$((i + 1)) + done + else + jail_umount_fs + jail_ips "del" + eerror " cannot start jail \"${_jail}\": " + tail +2 ${_tmp_jail} + fi + rm -f ${_tmp_jail} + done + rmdir ${_tmp_dir} + eend +} + +stop() +{ + ebegin 'Stopping jails:' + for _jail in ${jail_list} + do + if [ -f "/var/run/jail_${_jail}.id" ]; then + _jail_id=$(cat /var/run/jail_${_jail}.id) + if [ ! -z "${_jail_id}" ]; then + init_variables $_jail + + i=0 + while : ; do + eval out=\"\${_exec_prestop${i}:-''}\" + [ -z "$out" ] && break + ${out} + i=$((i + 1)) + done + + if [ -n "${_exec_stop}" ]; then + eval env -i /usr/sbin/jexec ${_jail_id} ${_exec_stop} \ + >> ${_consolelog} 2>&1 + fi + killall -j ${_jail_id} -TERM > /dev/null 2>&1 + sleep 1 + killall -j ${_jail_id} -KILL > /dev/null 2>&1 + jail_umount_fs + einfo "Stopped $_hostname" + + i=0 + while : ; do + eval out=\"\${_exec_poststop${i}:-''}\" + [ -z "$out" ] && break + ${out} + i=$((i + 1)) + done + fi + jail_ips "del" + rm /var/run/jail_${_jail}.id + else + ewarn " cannot stop jail ${_jail}. No jail id in /var/run" + fi + done + eend +}