Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Apr 2002 22:53:42 +0200 (CEST)
From:      Helge Oldach <jails@oldach.net>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   conf/37611: proposed /etc/rc.jails for jail(8) management (with patch)
Message-ID:  <200204302053.g3UKrgeC006728@sep.oldach.net>

next in thread | raw e-mail | index | archive | help

>Number:         37611
>Category:       conf
>Synopsis:       proposed /etc/rc.jails for jail(8) management (with patch)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Apr 30 14:00:02 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Helge Oldach
>Release:        FreeBSD 4.5-STABLE i386
>Organization:
>Environment:
System: FreeBSD sep.oldach.net 4.5-STABLE FreeBSD 4.5-STABLE #0: Fri Apr 26 15:55:27 CEST 2002 toor@sep.oldach.net:/usr/obj/usr/src/sys/GENERIC i386


	
>Description:

Jails are currently lacking decent management tools. Every now and then
such tools are a topic of discussion on freebsd-stable. I have hacked
together a new /etc/rc.jails script that is driven by /etc/rc.conf
variables in the standard fashion.

The idea is that any jail has a proper and unique name (similar to
the name of an interface) that is used access the appropriate rc.conf
variables. Actually much of the logic was stolen from rc.network.

For example, a jail called "alcatraz" would be represented by the
variables

jail_alcatraz_hostname		fully qualified hostname
jail_alcatraz_address		IP address
jail_alcatraz_root		root directory
jail_alcatraz_interface		interface to be used for adding the IP address
jail_alcatraz_mount{$x}		additional mount points

All variables have decent default values (derived at execution time)
which makes jail management pretty easy. See below for an example.
Additional mount points are specified in numerical order, similar to the
ifconfig_${ifname}_alias${x} mechanism. The defaults are as follows:

	jail_${jailname}_hostname
	fully qualified hostname according to name resolution

	jail_${jailname}_address
	same, but IP address

	jail_${jailname}_root
	/jail/${jailname}

	jail_${jailname}_interface
	name of first non-loopback interface with state UP found

	jail_${jailname}_mount0
	will default to "-t procfs proc ./proc"

Note that the mounts (and unmounts, which just use the last part of
the jail_${jailname}_mount${x} variable) take place in the jail's root
directory, hence the mount points are relative to the jail's root.

The jails affected are driven by the "jails" variable specified in
/etc/rc.conf. The default is empty, meaning jails are not used. For
consistency a line to /etc/defaults/rc.conf should be added.

Within /etc/rc.conf the ${jails} variable should be defined as

	test ${jails:=alcatraz andersonville salisbury elmira}

which would allow override of $jails as in

	jails="alcatraz" sh /etc/rc.jails stop

>How-To-Repeat:
	
>Fix:

This is the /etc/rc.jails script, and an example /etc/rc.conf which
makes use of this facility and provides some more information.

--- /dev/null	Tue Apr 30 22:40:01 2002
+++ /etc/rc.jails	Tue Apr 30 22:13:57 2002
@@ -0,0 +1,94 @@
+#!/bin/sh
+
+if [ -r /etc/defaults/rc.conf ]; then
+	. /etc/defaults/rc.conf
+	source_rc_confs
+elif [ -r /etc/rc.conf ]; then
+	. /etc/rc.conf
+fi
+
+prog=$(realpath $0) || exit 1
+dir=${prog%/*}
+PREFIX=${dir%/etc/rc.d}
+
+if [ ."$dir" = ."$prog" -o ."$PREFIX" = ."$dir" ]
+then
+	echo "$0: Cannot determine the PREFIX" >&2
+	exit 1
+fi
+
+arg=$1
+
+for jail in $jails
+do
+	jail_name=$jail
+	set -- $(host -t a ${jail_name} 2>/dev/null)
+	if [ $# -ne 4 -a "$2" != "has" -a "$3" != "address" ]
+	then
+		echo "No such jail ${jail}"
+		continue
+	fi
+	default_hostname=$1
+	default_address=$4
+	default_root="/jail/$jail"
+	default_interface=$(ifconfig -lu | sed 's/lo0//' | sed 's/ .*//')
+
+	for what in hostname address root interface
+	do
+		eval ${what}=\$jail_${jail}_${what}
+		if [ -z "$(eval echo -n \$${what})" ]
+		then
+			eval ${what}=\$default_${what}
+		fi
+	done
+
+	eval jail_${jail}_mount0=\${jail_${jail}_mount0:--t procfs proc ./proc}
+
+	case "$arg" in
+	start | shell)
+		echo "Starting jail ${hostname}"
+		ifconfig ${interface} inet ${address} netmask 255.255.255.255 alias
+		mount=0
+		while :
+		do
+			eval mount_args=\$jail_${jail_name}_mount${mount}
+			test -z "${mount_args}" && break
+			(cd ${root}; mount ${mount_args})
+			mount=$((${mount} + 1))
+		done
+		test "$arg" = "start" && script="/etc/rc"
+		jail ${root} ${hostname} ${address} /bin/sh ${script}
+		;;
+
+	list)
+		echo "Jail ${hostname} (${address}) in ${root}"
+		echo "PIDs: $(fgrep ${hostname} /proc/*/status | awk -F/ '{print $3}')"
+		;;
+
+	stop)
+		echo "Stopping jail ${hostname}"
+		kill -TERM $(fgrep ${hostname} /proc/*/status | /usr/bin/awk -F/ '{print $3}')
+		mount=0
+		while :
+		do
+			eval mount_args=\$jail_${jail_name}_mount${mount}
+			mount_args=${mount_args##* }
+			test -z "${mount_args}" && break
+			(cd ${root}; umount ${mount_args})
+			mount=$((${mount} + 1))
+		done
+		ifconfig ${interface} inet ${address} netmask 255.255.255.255 -alias
+		;;
+
+	restart)
+		/bin/sh $0 stop
+		sleep 1
+		/bin/sh $0 start
+		;;
+
+	*)
+		echo "Usage: $(basename $0) {start|stop|restart|shell|list}" >&2
+		;;
+	esac
+
+done
--- /dev/null	Tue Apr 30 22:40:01 2002
+++ /etc/rc.conf	Tue Apr 30 22:16:35 2002
@@ -0,0 +1,42 @@
+# jail definitions
+# jails: list of all our jails
+# Keep it as it is if already defined - this will allow:
+#	jails="alcatraz" /usr/local/etc/rc.d/rc.jails start
+test ${jails:=saiph sabik}
+
+# jail_${jailname}_hostname
+# will default to the fully qualified hostname according to name resolution
+# otherwise
+#	jail_alcatraz_hostname="alcatraz.dom.ain"
+
+# jail_${jailname}_address
+# same, but IP address
+#	jail_alcatraz_address="1.2.3.4"
+
+# jail_${jailname}_root
+# root directory of the jail
+# defaults to /jail/${jailname}
+# otherwise
+#	jail_alcatraz_root="/home/where/ever"
+
+# jail_${jailname}_interface
+# interface name to use for ifconfig
+# defaults to the first non-loopback interface with state UP found
+# otherwise
+#	jail_alcatraz_interface="fxp0"
+
+# jail_${jailname}_mount${number}
+# commands for mount(8) to mount file systems into the jail, and to unmount them# mounts and unmounts take place in the jail's root directory
+# jail_${jailname}_mount0 defaults to
+#	jail_${jailname}_mount0="-t procfs proc ./proc"
+# which will execute into
+#	cd ${jail_alcatraz_root}; mount -t procfs proc ./proc
+# additional file systems can be specified using jail_${jailname}_mount1 etc.
+# for unmounting the last component will be taken, i.e. the default mount0
+# will result in execution of
+#	cd ${jail_alcatraz_root}; umount ./proc
+
+jail_saiph_mount1="-t kernfs kern ./kern"
+jail_saiph_mount2="-t union -o rw,noclusterw,-b /usr/ports ./usr/ports"
+jail_sabik_mount1="-t kernfs kern ./kern"
+jail_sabik_mount2="-t union -o rw,noclusterw,-b /usr/ports ./usr/ports"
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200204302053.g3UKrgeC006728>