[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ezjail] Starting jails early



A more complete solution to starting jails very early. Typically, this is useful for a jail running a DNS server. That jail can be brought up early enough to be used as a DNS server on the jail host.

A second script is added, /usr/local/etc/rc.d/ezjail-earlyjails. This script looks for an rc.conf variable called ezjails_earlyjails that lists the jails to start early, and starts them right after networking has come up.

The other change is to filter out the names of already-running jails from the list passed to /usr/local/etc/rc.d/ezjail. There is probably a better way to do this. This particular script has surprised me several times.

Without the patch, /etc/rc.d/jail sees an error trying to start a jail that is already running and deletes /var/run/jail_jailname.id. The jail still starts, but ezjail-admin does not think it is running.

This is all experimental, not very well tested, and not guaranteed to work. To try it, apply the patches, modifying ezjail and creating ezjail-earlyjails in /usr/local/etc/rc.d/. Remember to chmod +x.
Then set

  ezjail_earlyjails="myjailname"

in rc.conf with the name of the jail to start early.

Besides a better patch to the ezjail script, it would be nice for the earlyjails script to start the early jails synchronously, pausing host startup until those jails have all completed their own startup. I don't know if that can be easily accomplished.

Comments and suggestions welcome.
--- ezjail.orig	2014-08-18 15:42:44.000000000 -0600
+++ ezjail	2014-08-18 18:11:22.000000000 -0600
@@ -100,6 +100,18 @@
     ezjail_pass="${ezjail_pass} ${ezjail}"
   done
 
+  # if starting, remove names of jails already running
+  if [ "start" = "${action}" ]; then
+    for j in ${ezjail_pass}; do
+      if jls name | grep -x -q ${j}; then
+	echo -n " ${j} is already running "
+      else
+	jlist="${jlist} ${j}"
+      fi
+    done
+    ezjail_pass="${jlist}"
+  fi
+
   # Pass control to jail script which does the actual work
   [ "${ezjail_pass}" ] && sh /etc/rc.d/jail one${action%crypto} ${ezjail_pass}
 
--- /dev/null	2014-08-18 15:44:00.000000000 -0600
+++ ezjail-earlyjails	2014-08-17 16:38:38.000000000 -0600
@@ -0,0 +1,40 @@
+#!/bin/sh
+# $FreeBSD$
+#
+# PROVIDE: ezjail-earlyjails
+# REQUIRE: NETWORKING netwait
+# KEYWORD: nojail
+# BEFORE:  mountcritremote
+#
+# To start some ezjails early during boot, list them in this
+# variable in /etc/rc.conf:
+#
+# ezjail_earlyjails=""
+ezjail_prefix=/usr/local
+
+. /etc/rc.subr
+
+name=ezjail
+rcvar=${name}_enable
+load_rc_config ${name}
+
+ezjail_enable=${ezjail_enable:-"NO"}
+
+start_cmd="do_cmd start"
+
+do_cmd() {
+  action=$1
+  case ${action} in
+    start)
+      if [ -n "${ezjail_earlyjails}" ]; then
+	echo -n "ezjail-earlystart: "
+	for j in ${ezjail_earlyjails}; do
+	  echo "${j}"
+	  ${ezjail_prefix}/etc/rc.d/ezjail start ${j}
+	done
+      fi
+      ;;
+  esac
+}
+
+run_rc_command $*