Index: etc/rc.d/jail =================================================================== --- etc/rc.d/jail (revision 224494) +++ etc/rc.d/jail (working copy) @@ -43,6 +43,9 @@ eval _ip=\"\$jail_${_j}_ip\" eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\" eval _exec=\"\$jail_${_j}_exec\" + eval _params=\"\$jail_${_j}_params\" + eval _persist=\"\$jail_${_j}_persist\" + eval _zfs=\"\${jail_${_j}_zfs:-}\" i=0 while : ; do @@ -98,6 +101,9 @@ fi # The default jail ruleset will be used by rc.subr if none is specified. + if [ -n "jail_devfs_ruleset" -a -n "_zfs" ]; then + jail_devfs_ruleset="devfsrules_jail_zfs" + fi eval _ruleset=\"\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}\" eval _devfs=\"\${jail_${_j}_devfs_enable:-${jail_devfs_enable}}\" [ -z "${_devfs}" ] && _devfs="NO" @@ -345,6 +351,36 @@ mount -a -F "${_fstab}" } +# jail_zfs_jailin +# Make zfs datasets manageable from inside a jail +# the "jailed" dataset property must be set to "on" +jail_zfs_jailin() +{ + if [ -n "${_zfs}" ]; then + for _ds in ${_zfs}; do + _jailed=`zfs get -H jailed ${_ds} 2>/dev/null | awk '{ print $3 }'` + if [ "$_jailed" = "on" ]; then + zfs jail "${_jail_id}" ${_ds} 2>/dev/null + fi + done + fi +} + +# jail_zfs_jailout +# Unjail zfs datasets +# the "jailed" dataset property must be set to "on" +jail_zfs_jailout() +{ + if [ -n "${_zfs}" ]; then + for _ds in ${_zfs}; do + _jailed=`zfs get -H jailed ${_ds} 2>/dev/null | awk '{ print $3 }'` + if [ "$_jailed" = "on" ]; then + zfs unjail "${_jail_id}" ${_ds} 2>/dev/null + fi + done + fi +} + # jail_show_addresses jail # Debug print the input for the given _multi aliases # for a jail for init_variables(). @@ -483,10 +519,27 @@ *) ;; esac - # Append address to list of addresses for the jail command. - case "${_addrl}" in - "") _addrl="${_addr}" ;; - *) _addrl="${_addrl},${_addr}" ;; + case "${_type}" in + inet) + # Append address to list of ipv4 addresses for the + # jail command. + case "${_addrl}" in + "") _addrl="${_addr}" ;; + *) _addrl="${_addrl},${_addr}" ;; + esac + ;; + inet6) + # Append address to list of ipv6 addresses for the + # jail command. + case "${_addrl6}" in + "") _addrl6="${_addr}" ;; + *) _addrl6="${_addrl6},${_addr}" ;; + esac + ;; + *) warn "Could not determine address family. Not going" \ + "to set address '${_addr}' for ${_jail}." + continue + ;; esac # Configure interface alias if requested by a given interface @@ -494,14 +547,7 @@ case "${_iface}" in "") continue ;; esac - case "${_type}" in - inet) ;; - inet6) ;; - *) warn "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 ;; @@ -576,6 +622,7 @@ continue; fi _addrl="" + _addrl6="" jail_ips "add" if [ -n "${_fib}" ]; then _setfib="setfib -F '${_fib}'" @@ -644,42 +691,56 @@ i=$((i + 1)) done - eval ${_setfib} jail ${_flags} -i ${_rootdir} ${_hostname} \ - \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1 \ - ${_tmp_jail} 2>&1 \ + ${_consolelog} - echo ${_jail_id} > /var/run/jail_${_jail}.id + jexec "${_jail_id}" ${out} + i=$((i + 1)) + done - i=0 - while : ; do - eval out=\"\${_exec_poststart${i}:-''}\" - [ -z "$out" ] && break - ${out} - i=$((i + 1)) - done - else - jail_umount_fs - jail_ips "del" - echo " cannot start jail \"${_jail}\": " - tail +2 ${_tmp_jail} + echo -n " $_hostname" + tail +2 ${_tmp_jail} >${_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_zfs_jailout + jail -m jid="${_jail_id}" persist=0 + jail_umount_fs + jail_ips "del" + echo " cannot start jail \"${_jail}\": " + tail +2 ${_tmp_jail} + fi + rm -f ${_tmp_jail} fi - rm -f ${_tmp_jail} done rmdir ${_tmp_dir} echo '.' @@ -707,6 +768,7 @@ eval env -i /usr/sbin/jexec ${_jail_id} ${_exec_stop} \ >> ${_consolelog} 2>&1 fi + jail_zfs_jailout killall -j ${_jail_id} -TERM > /dev/null 2>&1 sleep 1 killall -j ${_jail_id} -KILL > /dev/null 2>&1 Index: etc/defaults/devfs.rules =================================================================== --- etc/defaults/devfs.rules (revision 224471) +++ etc/defaults/devfs.rules (working copy) @@ -83,3 +83,9 @@ add include $devfsrules_hide_all add include $devfsrules_unhide_basic add include $devfsrules_unhide_login + +# Jail with zfs support +# +[devfsrules_jail_zfs=5] +add include $devfsrules_jail +add path zfs unhide Index: etc/defaults/rc.conf =================================================================== --- etc/defaults/rc.conf (revision 224471) +++ etc/defaults/rc.conf (working copy) @@ -695,6 +695,15 @@ #jail_example_mount_enable="NO" # mount/umount jail's fs #jail_example_fstab="" # fstab(5) for mount/umount #jail_example_flags="-l -U root" # flags for jail(8) +#jail_example_persist="" # Set to 1 to create a persistent jail +#jail_example_params="" # Space-separated list of additional + # user-supplied parameters for jail(8) +#jail_example_zfs="" # Space-separated list of ZFS datasets to be + # managed from this jail. For proper operation, + # allow.mount=1 and enforce_statfs=1 (or 0) + # must be added to jail_example_params. + # The "jailed" property must be set to "on" + # on desired datasets before starting the jail. ############################################################## ### Define source_rc_confs, the mechanism used by /etc/rc.* ##