
These changes add initial developmental support for persistent overlay
images to be used with livecds to facilitate saved state across reboots,
even across systems.

Much polishing and work remains.  Some 'user' documentation was added to
README, and lots of TODO documentation is in findoverlay.

This includes addidir/addsdir, as that is how I debug and install the
modified halt and functions scripts.
---
 Makefile                               |    1 +
 README                                 |   24 ++
 creator/etc_rc.d_init.d_functions      |  578 ++++++++++++++++++++++++++++++++
 creator/etc_rc.d_init.d_functions.orig |  577 +++++++++++++++++++++++++++++++
 creator/etc_rc.d_init.d_halt           |  237 +++++++++++++
 creator/etc_rc.d_init.d_halt.orig      |  222 ++++++++++++
 creator/findoverlay                    |  265 +++++++++++++++
 creator/livecd-creator                 |   66 ++++-
 creator/mayflower                      |   59 ++++-
 livecd-tools.spec                      |    5 +
 10 files changed, 2025 insertions(+), 9 deletions(-)
 create mode 100644 creator/etc_rc.d_init.d_functions
 create mode 100644 creator/etc_rc.d_init.d_functions.orig
 create mode 100644 creator/etc_rc.d_init.d_halt
 create mode 100644 creator/etc_rc.d_init.d_halt.orig
 create mode 100755 creator/findoverlay

diff --git a/Makefile b/Makefile
index e7af308..36e0e4f 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,7 @@ install:
 	$(INSTALL_PROGRAM) -D creator/livecd-creator $(DESTDIR)/usr/bin/livecd-creator
 	$(INSTALL_PROGRAM) -D creator/isotostick.sh $(DESTDIR)/usr/bin/livecd-iso-to-disk
 	$(INSTALL_PROGRAM) -D creator/mayflower $(DESTDIR)/usr/lib/livecd-creator/mayflower
+	$(INSTALL_PROGRAM) -D creator/findoverlay $(DESTDIR)/usr/lib/livecd-creator/findoverlay
 	$(INSTALL_DATA) -D AUTHORS $(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)/AUTHORS
 	$(INSTALL_DATA) -D COPYING $(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)/COPYING
 	$(INSTALL_DATA) -D README $(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)/README
diff --git a/README b/README
index 2b2c8cc..74ad485 100644
--- a/README
+++ b/README
@@ -161,3 +161,27 @@ Replace /dev/sdb1 with the (unmounted) partition where you wish to put
 the live image.  This is not a destructive process; any data you 
 currently have on your USB stick will be preserved.
 
+6. USING PERSISTENT OVERLAY FILES WITH LIVE IMAGES
+
+The ability to save system state across reboots, e.g. on USB media, is 
+a nice ability.
+
+The current persistence implementation is very immature, however, to
+use it-
+
+First, create a persistent overlay file, e.g. if your usb stick's vfat
+filesystem is mounted under /media/disk
+
+dd if=/dev/zero of=/media/disk/persistence bs=1k count=1 seek=$(( 512 * 1024 ))
+
+Then, reboot, adding the following to the kernel command line
+
+persistence=:/persistence
+
+If all goes well, you should be able to make changes to the system, e.g.
+install software, then shut down, boot with the same extra argument, and
+then see the changes persist across reboots.  Even if you have moved the
+LiveCD and USB stick to a different system.
+
+Much work, polishing, and documentation remains to be done on this feature.
+
diff --git a/creator/etc_rc.d_init.d_functions b/creator/etc_rc.d_init.d_functions
new file mode 100644
index 0000000..8962720
--- /dev/null
+++ b/creator/etc_rc.d_init.d_functions
@@ -0,0 +1,578 @@
+# -*-Shell-script-*-
+#
+# functions	This file contains functions to be used by most or all
+#		shell scripts in the /etc/init.d directory.
+#
+
+TEXTDOMAIN=initscripts
+
+# Make sure umask is sane
+umask 022
+
+# Set up a default search path.
+PATH="/sbin:/usr/sbin:/bin:/usr/bin"
+export PATH
+
+# Get a sane screen width
+[ -z "${COLUMNS:-}" ] && COLUMNS=80
+
+[ -z "${CONSOLETYPE:-}" ] && CONSOLETYPE="`/sbin/consoletype`"
+
+if [ -f /etc/sysconfig/i18n -a -z "${NOLOCALE:-}" ] ; then
+  . /etc/profile.d/lang.sh
+fi
+
+# Read in our configuration
+if [ -z "${BOOTUP:-}" ]; then
+  if [ -f /etc/sysconfig/init ]; then
+      . /etc/sysconfig/init
+  else
+    # This all seem confusing? Look in /etc/sysconfig/init,
+    # or in /usr/doc/initscripts-*/sysconfig.txt
+    BOOTUP=color
+    RES_COL=60
+    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
+    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
+    SETCOLOR_FAILURE="echo -en \\033[1;31m"
+    SETCOLOR_WARNING="echo -en \\033[1;33m"
+    SETCOLOR_NORMAL="echo -en \\033[0;39m"
+    LOGLEVEL=1
+  fi
+  if [ "$CONSOLETYPE" = "serial" ]; then
+      BOOTUP=serial
+      MOVE_TO_COL=
+      SETCOLOR_SUCCESS=
+      SETCOLOR_FAILURE=
+      SETCOLOR_WARNING=
+      SETCOLOR_NORMAL=
+  fi
+fi
+
+if [ "${BOOTUP:-}" != "verbose" ]; then
+   INITLOG_ARGS="-q"
+else
+   INITLOG_ARGS=
+fi
+
+# Interpret escape sequences in an fstab entry
+fstab_decode_str() {
+	fstab-decode echo "$1"
+}
+
+# Check if $pid (could be plural) are running
+checkpid() {
+	local i
+
+	for i in $* ; do
+		[ -d "/proc/$i" ] && return 0
+	done
+	return 1
+}
+
+# __umount_loop awk_program fstab_file first_msg retry_msg umount_args
+# awk_program should process fstab_file and return a list of fstab-encoded
+# paths; it doesn't have to handle comments in fstab_file.
+__umount_loop() {
+	local remaining sig=
+	local retry=3
+
+	remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | grep -v overlayfs | sort -r)
+	while [ -n "$remaining" -a "$retry" -gt 0 ]; do
+	        echo "DMC OVERLAY DEBUG: in __umount_loop remaining is $remaining"
+		if [ "$retry" -eq 3 ]; then
+			action "$3" fstab-decode umount $5 $remaining
+		else
+			action "$4" fstab-decode umount $5 $remaining
+		fi
+		sleep 2
+		remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | grep -v overlayfs | sort -r)
+		[ -z "$remaining" ] && break
+		fstab-decode /sbin/fuser -k -m $sig $remaining >/dev/null
+		sleep 5
+		retry=$(($retry -1))
+		sig=-9
+	done
+}
+
+# Similar to __umount loop above, specialized for loopback devices
+__umount_loopback_loop() {
+	local remaining devremaining sig=
+	local retry=3
+
+	remaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts)
+	devremaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}' /proc/mounts)
+	while [ -n "$remaining" -a "$retry" -gt 0 ]; do
+		if [ "$retry" -eq 3 ]; then
+			action $"Unmounting loopback filesystems: " \
+				fstab-decode umount $remaining
+		else
+			action $"Unmounting loopback filesystems (retry):" \
+				fstab-decode umount $remaining
+		fi
+		for dev in $devremaining ; do
+			losetup $dev > /dev/null 2>&1 && \
+				action $"Detaching loopback device $dev: " \
+				losetup -d $dev
+		done
+		remaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts)
+		devremaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}' /proc/mounts)
+		[ -z "$remaining" ] && break
+		fstab-decode /sbin/fuser -k -m $sig $remaining >/dev/null
+		sleep 5
+		retry=$(($retry -1))
+		sig=-9
+	done
+}
+
+# __proc_pids {program} [pidfile]
+# Set $pid to pids from /var/run* for {program}.  $pid should be declared
+# local in the caller.
+# Returns LSB exit code for the 'status' action.
+__pids_var_run() {
+	local base=${1##*/}
+	local pid_file=${2:-/var/run/$base.pid}
+
+	pid=
+	if [ -f "$pid_file" ] ; then
+	        local line p
+		read line < "$pid_file"
+		for p in $line ; do
+			[ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid $p"
+		done
+	        if [ -n "$pid" ]; then
+	                return 0
+	        fi
+		return 1 # "Program is dead and /var/run pid file exists"
+	fi
+	return 3 # "Program is not running"
+}
+
+# Output PIDs of matching processes, found using pidof
+__pids_pidof() {
+	pidof -c -o $$ -o $PPID -o %PPID -x "$1" || \
+		pidof -c -o $$ -o $PPID -o %PPID -x "${1##*/}"
+}
+
+
+# A function to start a program.
+daemon() {
+	# Test syntax.
+	local gotbase= force= nicelevel corelimit
+	local pid base= user= nice= bg= pid_file=
+	nicelevel=0
+	while [ "$1" != "${1##[-+]}" ]; do
+	  case $1 in
+	    '')    echo $"$0: Usage: daemon [+/-nicelevel] {program}"
+	           return 1;;
+	    --check)
+		   base=$2
+		   gotbase="yes"
+		   shift 2
+		   ;;
+	    --check=?*)
+	    	   base=${1#--check=}
+		   gotbase="yes"
+		   shift
+		   ;;
+	    --user)
+		   user=$2
+		   shift 2
+		   ;;
+	    --user=?*)
+	           user=${1#--user=}
+		   shift
+		   ;;
+	    --pidfile)
+		   pid_file=$2
+		   shift 2
+		   ;;
+	    --pidfile=?*)
+		   pid_file=${1#--pidfile=}
+		   shift
+		   ;;
+	    --force)
+	    	   force="force"
+		   shift
+		   ;;
+	    [-+][0-9]*)
+	    	   nice="nice -n $1"
+	           shift
+		   ;;
+	    *)     echo $"$0: Usage: daemon [+/-nicelevel] {program}"
+	           return 1;;
+	  esac
+	done
+
+        # Save basename.
+        [ -z "$gotbase" ] && base=${1##*/}
+
+        # See if it's already running. Look *only* at the pid file.
+	__pids_var_run "$base" "$pid_file"
+
+	[ -n "$pid" -a -z "$force" ] && return
+
+	# make sure it doesn't core dump anywhere unless requested
+	corelimit="ulimit -S -c ${DAEMON_COREFILE_LIMIT:-0}"
+	
+	# if they set NICELEVEL in /etc/sysconfig/foo, honor it
+	[ -n "${NICELEVEL:-}" ] && nice="nice -n $NICELEVEL"
+	
+	# Echo daemon
+        [ "${BOOTUP:-}" = "verbose" -a -z "${LSB:-}" ] && echo -n " $base"
+
+	# And start it up.
+	if [ -z "$user" ]; then
+	   $nice /bin/bash -c "$corelimit >/dev/null 2>&1 ; $*"
+	else
+	   $nice runuser -s /bin/bash - $user -c "$corelimit >/dev/null 2>&1 ; $*"
+	fi
+	[ "$?" -eq 0 ] && success $"$base startup" || failure $"$base startup"
+}
+
+# A function to stop a program.
+killproc() {
+	local RC killlevel= base pid pid_file= delay
+
+	RC=0; delay=3
+	# Test syntax.
+	if [ "$#" -eq 0 ]; then
+		echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
+		return 1
+	fi
+	if [ "$1" = "-p" ]; then
+		pid_file=$2
+		shift 2
+	fi
+	if [ "$1" = "-d" ]; then
+		delay=$2
+		shift 2
+	fi
+        
+
+	# check for second arg to be kill level
+	[ -n "${2:-}" ] && killlevel=$2
+
+        # Save basename.
+        base=${1##*/}
+
+        # Find pid.
+	__pids_var_run "$1" "$pid_file"
+	if [ -z "$pid_file" -a -z "$pid" ]; then
+		pid="$(__pids_pidof "$1")"
+	fi
+
+        # Kill it.
+        if [ -n "$pid" ] ; then
+                [ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
+		if [ -z "$killlevel" ] ; then
+		       if checkpid $pid 2>&1; then
+			   # TERM first, then KILL if not dead
+			   kill -TERM $pid >/dev/null 2>&1
+			   usleep 100000
+			   if checkpid $pid && sleep 1 &&
+			      checkpid $pid && sleep $delay &&
+			      checkpid $pid ; then
+                                kill -KILL $pid >/dev/null 2>&1
+				usleep 100000
+			   fi
+		        fi
+			checkpid $pid
+			RC=$?
+			[ "$RC" -eq 0 ] && failure $"$base shutdown" || success $"$base shutdown"
+			RC=$((! $RC))
+		# use specified level only
+		else
+		        if checkpid $pid; then
+	                	kill $killlevel $pid >/dev/null 2>&1
+				RC=$?
+				[ "$RC" -eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
+			elif [ -n "${LSB:-}" ]; then
+				RC=7 # Program is not running
+			fi
+		fi
+	else
+		if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
+			RC=7 # Program is not running
+		else
+			failure $"$base shutdown"
+			RC=0
+		fi
+	fi
+
+        # Remove pid file if any.
+	if [ -z "$killlevel" ]; then
+            rm -f "${pid_file:-/var/run/$base.pid}"
+	fi
+	return $RC
+}
+
+# A function to find the pid of a program. Looks *only* at the pidfile
+pidfileofproc() {
+	local pid
+
+	# Test syntax.
+	if [ "$#" = 0 ] ; then
+		echo $"Usage: pidfileofproc {program}"
+		return 1
+	fi
+
+	__pids_var_run "$1"
+	[ -n "$pid" ] && echo $pid
+	return 0
+}
+
+# A function to find the pid of a program.
+pidofproc() {
+	local RC pid pid_file=
+
+	# Test syntax.
+	if [ "$#" = 0 ]; then
+		echo $"Usage: pidofproc [-p pidfile] {program}"
+		return 1
+	fi
+	if [ "$1" = "-p" ]; then
+		pid_file=$2
+		shift 2
+	fi
+	fail_code=3 # "Program is not running"
+
+	# First try "/var/run/*.pid" files
+	__pids_var_run "$1" "$pid_file"
+	RC=$?
+	if [ -n "$pid" ]; then
+		echo $pid
+		return 0
+	fi
+
+	[ -n "$pid_file" ] && return $RC
+	__pids_pidof "$1" || return $RC
+}
+
+status() {
+	local base pid pid_file=
+
+	# Test syntax.
+	if [ "$#" = 0 ] ; then
+		echo $"Usage: status [-p pidfile] {program}"
+		return 1
+	fi
+	if [ "$1" = "-p" ]; then
+		pid_file=$2
+		shift 2
+	fi
+	base=${1##*/}
+
+	# First try "pidof"
+	pid="$(__pids_pidof "$1")"
+	if [ -n "$pid" ]; then
+	        echo $"${base} (pid $pid) is running..."
+	        return 0
+	fi
+
+	# Next try "/var/run/*.pid" files
+	__pids_var_run "$1" "$pid_file"
+	case "$?" in
+		0)
+			echo $"${base} (pid $pid) is running..."
+			return 0
+			;;
+		1)
+	                echo $"${base} dead but pid file exists"
+	                return 1
+			;;
+	esac
+	# See if /var/lock/subsys/${base} exists
+	if [ -f /var/lock/subsys/${base} ]; then
+		echo $"${base} dead but subsys locked"
+		return 2
+	fi
+	echo $"${base} is stopped"
+	return 3
+}
+
+echo_success() {
+  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+  echo -n "["
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
+  echo -n $"  OK  "
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+  echo -n "]"
+  echo -ne "\r"
+  return 0
+}
+
+echo_failure() {
+  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+  echo -n "["
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
+  echo -n $"FAILED"
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+  echo -n "]"
+  echo -ne "\r"
+  return 1
+}
+
+echo_passed() {
+  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+  echo -n "["
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
+  echo -n $"PASSED"
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+  echo -n "]"
+  echo -ne "\r"
+  return 1
+}
+
+echo_warning() {
+  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+  echo -n "["
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
+  echo -n $"WARNING"
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+  echo -n "]"
+  echo -ne "\r"
+  return 1
+}
+
+# Inform the graphical boot of our current state
+update_boot_stage() {
+  if [ "$GRAPHICAL" = "yes" -a -x /usr/bin/rhgb-client ]; then
+    /usr/bin/rhgb-client --update="$1"
+  fi
+  return 0
+}
+
+# Log that something succeeded
+success() {
+  #if [ -z "${IN_INITLOG:-}" ]; then
+  #   initlog $INITLOG_ARGS -n $0 -s "$1" -e 1
+  #fi
+  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_success
+  return 0
+}
+
+# Log that something failed
+failure() {
+  local rc=$?
+  #if [ -z "${IN_INITLOG:-}" ]; then
+  #   initlog $INITLOG_ARGS -n $0 -s "$1" -e 2
+  #fi
+  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_failure
+  [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=yes
+  return $rc
+}
+
+# Log that something passed, but may have had errors. Useful for fsck
+passed() {
+  local rc=$?
+  #if [ -z "${IN_INITLOG:-}" ]; then
+  #   initlog $INITLOG_ARGS -n $0 -s "$1" -e 1
+  #fi
+  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_passed
+  return $rc
+}  
+
+# Log a warning
+warning() {
+  local rc=$?
+  #if [ -z "${IN_INITLOG:-}" ]; then
+  #   initlog $INITLOG_ARGS -n $0 -s "$1" -e 1
+  #fi
+  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_warning
+  return $rc
+}  
+
+# Run some action. Log its output.
+action() {
+  local STRING rc
+
+  STRING=$1
+  echo -n "$STRING "
+  if [ "${RHGB_STARTED:-}" != "" -a -w /etc/rhgb/temp/rhgb-console ]; then
+      echo -n "$STRING " > /etc/rhgb/temp/rhgb-console
+  fi
+  shift
+  "$@" && success $"$STRING" || failure $"$STRING"
+  rc=$?
+  echo
+  if [ "${RHGB_STARTED:-}" != "" -a -w /etc/rhgb/temp/rhgb-console ]; then
+      if [ "$rc" = "0" ]; then
+      	echo_success > /etc/rhgb/temp/rhgb-console
+      else
+        echo_failure > /etc/rhgb/temp/rhgb-console
+	[ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=yes
+      fi
+      echo > /etc/rhgb/temp/rhgb-console
+  fi
+  return $rc
+}
+
+# returns OK if $1 contains $2
+strstr() {
+  [ "${1#*$2*}" = "$1" ] && return 1
+  return 0
+}
+
+# Confirm whether we really want to run this service
+confirm() {
+  [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=yes
+  while : ; do 
+      echo -n $"Start service $1 (Y)es/(N)o/(C)ontinue? [Y] "
+      read answer
+      if strstr $"yY" "$answer" || [ "$answer" = "" ] ; then
+         return 0
+      elif strstr $"cC" "$answer" ; then
+	 rm -f /var/run/confirm
+	 [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=no
+         return 2
+      elif strstr $"nN" "$answer" ; then
+         return 1
+      fi
+  done
+}
+
+# resolve a device node to its major:minor numbers in decimal or hex
+get_numeric_dev() {
+(
+    fmt="%d:%d"
+    if [ "$1" == "hex" ]; then
+        fmt="%x:%x"
+    fi
+    ls -lH "$2" | awk '{ sub(/,/, "", $5); printf("'"$fmt"'", $5, $6); }'
+) 2>/dev/null
+}
+
+# find the working name for a running dm device with the same table as one
+# that dmraid would create
+resolve_dm_name() {
+(
+    name="$1"
+
+    line=$(/sbin/dmraid -ay -t --ignorelocking | \
+        egrep -iv "no block devices found|No RAID disks" | \
+        awk -F ':' "{ if (\$1 ~ /^$name$/) { print \$2; }}")
+    for x in $line ; do
+        if [[ "$x" =~ "^/dev/" ]] ; then
+            majmin=$(get_numeric_dev dec $x)
+            line=$(echo "$line" | sed -e "s,$x\( \|$\),$majmin\1,g")
+        fi
+    done
+    line=$(echo "$line" | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//' \
+               -e 's/ core [12] [[:digit:]]\+ / core [12] [[:digit:]]\\+ /')
+    /sbin/dmsetup table | \
+        sed -n -e "s/.*\(no block devices found\|No devices found\).*//" \
+               -e "s/\(^[^:]\+\): $line\( \+$\|$\)/\1/p"
+) 2>/dev/null
+}
+
+# Check whether file $1 is a backup or rpm-generated file and should be ignored
+is_ignored_file() {
+    case "$1" in
+	*~ | *.bak | *.orig | *.rpmnew | *.rpmorig | *.rpmsave)
+	    return 0
+	    ;;
+    esac
+    return 1
+}
+# A sed expression to filter out the files that is_ignored_file recognizes
+__sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
diff --git a/creator/etc_rc.d_init.d_functions.orig b/creator/etc_rc.d_init.d_functions.orig
new file mode 100644
index 0000000..580216d
--- /dev/null
+++ b/creator/etc_rc.d_init.d_functions.orig
@@ -0,0 +1,577 @@
+# -*-Shell-script-*-
+#
+# functions	This file contains functions to be used by most or all
+#		shell scripts in the /etc/init.d directory.
+#
+
+TEXTDOMAIN=initscripts
+
+# Make sure umask is sane
+umask 022
+
+# Set up a default search path.
+PATH="/sbin:/usr/sbin:/bin:/usr/bin"
+export PATH
+
+# Get a sane screen width
+[ -z "${COLUMNS:-}" ] && COLUMNS=80
+
+[ -z "${CONSOLETYPE:-}" ] && CONSOLETYPE="`/sbin/consoletype`"
+
+if [ -f /etc/sysconfig/i18n -a -z "${NOLOCALE:-}" ] ; then
+  . /etc/profile.d/lang.sh
+fi
+
+# Read in our configuration
+if [ -z "${BOOTUP:-}" ]; then
+  if [ -f /etc/sysconfig/init ]; then
+      . /etc/sysconfig/init
+  else
+    # This all seem confusing? Look in /etc/sysconfig/init,
+    # or in /usr/doc/initscripts-*/sysconfig.txt
+    BOOTUP=color
+    RES_COL=60
+    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
+    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
+    SETCOLOR_FAILURE="echo -en \\033[1;31m"
+    SETCOLOR_WARNING="echo -en \\033[1;33m"
+    SETCOLOR_NORMAL="echo -en \\033[0;39m"
+    LOGLEVEL=1
+  fi
+  if [ "$CONSOLETYPE" = "serial" ]; then
+      BOOTUP=serial
+      MOVE_TO_COL=
+      SETCOLOR_SUCCESS=
+      SETCOLOR_FAILURE=
+      SETCOLOR_WARNING=
+      SETCOLOR_NORMAL=
+  fi
+fi
+
+if [ "${BOOTUP:-}" != "verbose" ]; then
+   INITLOG_ARGS="-q"
+else
+   INITLOG_ARGS=
+fi
+
+# Interpret escape sequences in an fstab entry
+fstab_decode_str() {
+	fstab-decode echo "$1"
+}
+
+# Check if $pid (could be plural) are running
+checkpid() {
+	local i
+
+	for i in $* ; do
+		[ -d "/proc/$i" ] && return 0
+	done
+	return 1
+}
+
+# __umount_loop awk_program fstab_file first_msg retry_msg umount_args
+# awk_program should process fstab_file and return a list of fstab-encoded
+# paths; it doesn't have to handle comments in fstab_file.
+__umount_loop() {
+	local remaining sig=
+	local retry=3
+
+	remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | sort -r)
+	while [ -n "$remaining" -a "$retry" -gt 0 ]; do
+		if [ "$retry" -eq 3 ]; then
+			action "$3" fstab-decode umount $5 $remaining
+		else
+			action "$4" fstab-decode umount $5 $remaining
+		fi
+		sleep 2
+		remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | sort -r)
+		[ -z "$remaining" ] && break
+		fstab-decode /sbin/fuser -k -m $sig $remaining >/dev/null
+		sleep 5
+		retry=$(($retry -1))
+		sig=-9
+	done
+}
+
+# Similar to __umount loop above, specialized for loopback devices
+__umount_loopback_loop() {
+	local remaining devremaining sig=
+	local retry=3
+
+	remaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts)
+	devremaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}' /proc/mounts)
+	while [ -n "$remaining" -a "$retry" -gt 0 ]; do
+		if [ "$retry" -eq 3 ]; then
+			action $"Unmounting loopback filesystems: " \
+				fstab-decode umount $remaining
+		else
+			action $"Unmounting loopback filesystems (retry):" \
+				fstab-decode umount $remaining
+		fi
+		for dev in $devremaining ; do
+			losetup $dev > /dev/null 2>&1 && \
+				action $"Detaching loopback device $dev: " \
+				losetup -d $dev
+		done
+		remaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts)
+		devremaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}' /proc/mounts)
+		[ -z "$remaining" ] && break
+		fstab-decode /sbin/fuser -k -m $sig $remaining >/dev/null
+		sleep 5
+		retry=$(($retry -1))
+		sig=-9
+	done
+}
+
+# __proc_pids {program} [pidfile]
+# Set $pid to pids from /var/run* for {program}.  $pid should be declared
+# local in the caller.
+# Returns LSB exit code for the 'status' action.
+__pids_var_run() {
+	local base=${1##*/}
+	local pid_file=${2:-/var/run/$base.pid}
+
+	pid=
+	if [ -f "$pid_file" ] ; then
+	        local line p
+		read line < "$pid_file"
+		for p in $line ; do
+			[ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid $p"
+		done
+	        if [ -n "$pid" ]; then
+	                return 0
+	        fi
+		return 1 # "Program is dead and /var/run pid file exists"
+	fi
+	return 3 # "Program is not running"
+}
+
+# Output PIDs of matching processes, found using pidof
+__pids_pidof() {
+	pidof -c -o $$ -o $PPID -o %PPID -x "$1" || \
+		pidof -c -o $$ -o $PPID -o %PPID -x "${1##*/}"
+}
+
+
+# A function to start a program.
+daemon() {
+	# Test syntax.
+	local gotbase= force= nicelevel corelimit
+	local pid base= user= nice= bg= pid_file=
+	nicelevel=0
+	while [ "$1" != "${1##[-+]}" ]; do
+	  case $1 in
+	    '')    echo $"$0: Usage: daemon [+/-nicelevel] {program}"
+	           return 1;;
+	    --check)
+		   base=$2
+		   gotbase="yes"
+		   shift 2
+		   ;;
+	    --check=?*)
+	    	   base=${1#--check=}
+		   gotbase="yes"
+		   shift
+		   ;;
+	    --user)
+		   user=$2
+		   shift 2
+		   ;;
+	    --user=?*)
+	           user=${1#--user=}
+		   shift
+		   ;;
+	    --pidfile)
+		   pid_file=$2
+		   shift 2
+		   ;;
+	    --pidfile=?*)
+		   pid_file=${1#--pidfile=}
+		   shift
+		   ;;
+	    --force)
+	    	   force="force"
+		   shift
+		   ;;
+	    [-+][0-9]*)
+	    	   nice="nice -n $1"
+	           shift
+		   ;;
+	    *)     echo $"$0: Usage: daemon [+/-nicelevel] {program}"
+	           return 1;;
+	  esac
+	done
+
+        # Save basename.
+        [ -z "$gotbase" ] && base=${1##*/}
+
+        # See if it's already running. Look *only* at the pid file.
+	__pids_var_run "$base" "$pid_file"
+
+	[ -n "$pid" -a -z "$force" ] && return
+
+	# make sure it doesn't core dump anywhere unless requested
+	corelimit="ulimit -S -c ${DAEMON_COREFILE_LIMIT:-0}"
+	
+	# if they set NICELEVEL in /etc/sysconfig/foo, honor it
+	[ -n "${NICELEVEL:-}" ] && nice="nice -n $NICELEVEL"
+	
+	# Echo daemon
+        [ "${BOOTUP:-}" = "verbose" -a -z "${LSB:-}" ] && echo -n " $base"
+
+	# And start it up.
+	if [ -z "$user" ]; then
+	   $nice /bin/bash -c "$corelimit >/dev/null 2>&1 ; $*"
+	else
+	   $nice runuser -s /bin/bash - $user -c "$corelimit >/dev/null 2>&1 ; $*"
+	fi
+	[ "$?" -eq 0 ] && success $"$base startup" || failure $"$base startup"
+}
+
+# A function to stop a program.
+killproc() {
+	local RC killlevel= base pid pid_file= delay
+
+	RC=0; delay=3
+	# Test syntax.
+	if [ "$#" -eq 0 ]; then
+		echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
+		return 1
+	fi
+	if [ "$1" = "-p" ]; then
+		pid_file=$2
+		shift 2
+	fi
+	if [ "$1" = "-d" ]; then
+		delay=$2
+		shift 2
+	fi
+        
+
+	# check for second arg to be kill level
+	[ -n "${2:-}" ] && killlevel=$2
+
+        # Save basename.
+        base=${1##*/}
+
+        # Find pid.
+	__pids_var_run "$1" "$pid_file"
+	if [ -z "$pid_file" -a -z "$pid" ]; then
+		pid="$(__pids_pidof "$1")"
+	fi
+
+        # Kill it.
+        if [ -n "$pid" ] ; then
+                [ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
+		if [ -z "$killlevel" ] ; then
+		       if checkpid $pid 2>&1; then
+			   # TERM first, then KILL if not dead
+			   kill -TERM $pid >/dev/null 2>&1
+			   usleep 100000
+			   if checkpid $pid && sleep 1 &&
+			      checkpid $pid && sleep $delay &&
+			      checkpid $pid ; then
+                                kill -KILL $pid >/dev/null 2>&1
+				usleep 100000
+			   fi
+		        fi
+			checkpid $pid
+			RC=$?
+			[ "$RC" -eq 0 ] && failure $"$base shutdown" || success $"$base shutdown"
+			RC=$((! $RC))
+		# use specified level only
+		else
+		        if checkpid $pid; then
+	                	kill $killlevel $pid >/dev/null 2>&1
+				RC=$?
+				[ "$RC" -eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
+			elif [ -n "${LSB:-}" ]; then
+				RC=7 # Program is not running
+			fi
+		fi
+	else
+		if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
+			RC=7 # Program is not running
+		else
+			failure $"$base shutdown"
+			RC=0
+		fi
+	fi
+
+        # Remove pid file if any.
+	if [ -z "$killlevel" ]; then
+            rm -f "${pid_file:-/var/run/$base.pid}"
+	fi
+	return $RC
+}
+
+# A function to find the pid of a program. Looks *only* at the pidfile
+pidfileofproc() {
+	local pid
+
+	# Test syntax.
+	if [ "$#" = 0 ] ; then
+		echo $"Usage: pidfileofproc {program}"
+		return 1
+	fi
+
+	__pids_var_run "$1"
+	[ -n "$pid" ] && echo $pid
+	return 0
+}
+
+# A function to find the pid of a program.
+pidofproc() {
+	local RC pid pid_file=
+
+	# Test syntax.
+	if [ "$#" = 0 ]; then
+		echo $"Usage: pidofproc [-p pidfile] {program}"
+		return 1
+	fi
+	if [ "$1" = "-p" ]; then
+		pid_file=$2
+		shift 2
+	fi
+	fail_code=3 # "Program is not running"
+
+	# First try "/var/run/*.pid" files
+	__pids_var_run "$1" "$pid_file"
+	RC=$?
+	if [ -n "$pid" ]; then
+		echo $pid
+		return 0
+	fi
+
+	[ -n "$pid_file" ] && return $RC
+	__pids_pidof "$1" || return $RC
+}
+
+status() {
+	local base pid pid_file=
+
+	# Test syntax.
+	if [ "$#" = 0 ] ; then
+		echo $"Usage: status [-p pidfile] {program}"
+		return 1
+	fi
+	if [ "$1" = "-p" ]; then
+		pid_file=$2
+		shift 2
+	fi
+	base=${1##*/}
+
+	# First try "pidof"
+	pid="$(__pids_pidof "$1")"
+	if [ -n "$pid" ]; then
+	        echo $"${base} (pid $pid) is running..."
+	        return 0
+	fi
+
+	# Next try "/var/run/*.pid" files
+	__pids_var_run "$1" "$pid_file"
+	case "$?" in
+		0)
+			echo $"${base} (pid $pid) is running..."
+			return 0
+			;;
+		1)
+	                echo $"${base} dead but pid file exists"
+	                return 1
+			;;
+	esac
+	# See if /var/lock/subsys/${base} exists
+	if [ -f /var/lock/subsys/${base} ]; then
+		echo $"${base} dead but subsys locked"
+		return 2
+	fi
+	echo $"${base} is stopped"
+	return 3
+}
+
+echo_success() {
+  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+  echo -n "["
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
+  echo -n $"  OK  "
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+  echo -n "]"
+  echo -ne "\r"
+  return 0
+}
+
+echo_failure() {
+  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+  echo -n "["
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
+  echo -n $"FAILED"
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+  echo -n "]"
+  echo -ne "\r"
+  return 1
+}
+
+echo_passed() {
+  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+  echo -n "["
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
+  echo -n $"PASSED"
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+  echo -n "]"
+  echo -ne "\r"
+  return 1
+}
+
+echo_warning() {
+  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+  echo -n "["
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
+  echo -n $"WARNING"
+  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+  echo -n "]"
+  echo -ne "\r"
+  return 1
+}
+
+# Inform the graphical boot of our current state
+update_boot_stage() {
+  if [ "$GRAPHICAL" = "yes" -a -x /usr/bin/rhgb-client ]; then
+    /usr/bin/rhgb-client --update="$1"
+  fi
+  return 0
+}
+
+# Log that something succeeded
+success() {
+  #if [ -z "${IN_INITLOG:-}" ]; then
+  #   initlog $INITLOG_ARGS -n $0 -s "$1" -e 1
+  #fi
+  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_success
+  return 0
+}
+
+# Log that something failed
+failure() {
+  local rc=$?
+  #if [ -z "${IN_INITLOG:-}" ]; then
+  #   initlog $INITLOG_ARGS -n $0 -s "$1" -e 2
+  #fi
+  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_failure
+  [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=yes
+  return $rc
+}
+
+# Log that something passed, but may have had errors. Useful for fsck
+passed() {
+  local rc=$?
+  #if [ -z "${IN_INITLOG:-}" ]; then
+  #   initlog $INITLOG_ARGS -n $0 -s "$1" -e 1
+  #fi
+  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_passed
+  return $rc
+}  
+
+# Log a warning
+warning() {
+  local rc=$?
+  #if [ -z "${IN_INITLOG:-}" ]; then
+  #   initlog $INITLOG_ARGS -n $0 -s "$1" -e 1
+  #fi
+  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_warning
+  return $rc
+}  
+
+# Run some action. Log its output.
+action() {
+  local STRING rc
+
+  STRING=$1
+  echo -n "$STRING "
+  if [ "${RHGB_STARTED:-}" != "" -a -w /etc/rhgb/temp/rhgb-console ]; then
+      echo -n "$STRING " > /etc/rhgb/temp/rhgb-console
+  fi
+  shift
+  "$@" && success $"$STRING" || failure $"$STRING"
+  rc=$?
+  echo
+  if [ "${RHGB_STARTED:-}" != "" -a -w /etc/rhgb/temp/rhgb-console ]; then
+      if [ "$rc" = "0" ]; then
+      	echo_success > /etc/rhgb/temp/rhgb-console
+      else
+        echo_failure > /etc/rhgb/temp/rhgb-console
+	[ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=yes
+      fi
+      echo > /etc/rhgb/temp/rhgb-console
+  fi
+  return $rc
+}
+
+# returns OK if $1 contains $2
+strstr() {
+  [ "${1#*$2*}" = "$1" ] && return 1
+  return 0
+}
+
+# Confirm whether we really want to run this service
+confirm() {
+  [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=yes
+  while : ; do 
+      echo -n $"Start service $1 (Y)es/(N)o/(C)ontinue? [Y] "
+      read answer
+      if strstr $"yY" "$answer" || [ "$answer" = "" ] ; then
+         return 0
+      elif strstr $"cC" "$answer" ; then
+	 rm -f /var/run/confirm
+	 [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=no
+         return 2
+      elif strstr $"nN" "$answer" ; then
+         return 1
+      fi
+  done
+}
+
+# resolve a device node to its major:minor numbers in decimal or hex
+get_numeric_dev() {
+(
+    fmt="%d:%d"
+    if [ "$1" == "hex" ]; then
+        fmt="%x:%x"
+    fi
+    ls -lH "$2" | awk '{ sub(/,/, "", $5); printf("'"$fmt"'", $5, $6); }'
+) 2>/dev/null
+}
+
+# find the working name for a running dm device with the same table as one
+# that dmraid would create
+resolve_dm_name() {
+(
+    name="$1"
+
+    line=$(/sbin/dmraid -ay -t --ignorelocking | \
+        egrep -iv "no block devices found|No RAID disks" | \
+        awk -F ':' "{ if (\$1 ~ /^$name$/) { print \$2; }}")
+    for x in $line ; do
+        if [[ "$x" =~ "^/dev/" ]] ; then
+            majmin=$(get_numeric_dev dec $x)
+            line=$(echo "$line" | sed -e "s,$x\( \|$\),$majmin\1,g")
+        fi
+    done
+    line=$(echo "$line" | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//' \
+               -e 's/ core [12] [[:digit:]]\+ / core [12] [[:digit:]]\\+ /')
+    /sbin/dmsetup table | \
+        sed -n -e "s/.*\(no block devices found\|No devices found\).*//" \
+               -e "s/\(^[^:]\+\): $line\( \+$\|$\)/\1/p"
+) 2>/dev/null
+}
+
+# Check whether file $1 is a backup or rpm-generated file and should be ignored
+is_ignored_file() {
+    case "$1" in
+	*~ | *.bak | *.orig | *.rpmnew | *.rpmorig | *.rpmsave)
+	    return 0
+	    ;;
+    esac
+    return 1
+}
+# A sed expression to filter out the files that is_ignored_file recognizes
+__sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
diff --git a/creator/etc_rc.d_init.d_halt b/creator/etc_rc.d_init.d_halt
new file mode 100644
index 0000000..1dc0e38
--- /dev/null
+++ b/creator/etc_rc.d_init.d_halt
@@ -0,0 +1,237 @@
+#!/bin/bash
+#
+# halt          This file is executed by init when it goes into runlevel
+#               0 (halt) or runlevel 6 (reboot). It kills all processes,
+#               unmounts file systems and then either halts or reboots.
+#
+# Author:       Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
+#               Modified for RHS Linux by Damien Neil
+#
+
+NOLOCALE=1
+. /etc/init.d/functions
+
+action() {
+   echo -n "$1 "
+   shift
+   if [ "$BOOTUP" = "color" ]; then
+      "$@" && echo_success || echo_failure
+   else
+      "$@"
+   fi
+   echo
+}
+
+halt_crypto() {
+    fnval=0
+    while read dst src key; do
+	[ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue
+        if [ -b "/dev/mapper/$dst" ]; then
+            if /sbin/dmsetup info "$dst" | grep -q '^Open count: *0$'; then
+                /sbin/cryptsetup remove "$dst"
+            else
+                fnval=1
+            fi
+        fi
+    done < /etc/crypttab
+    return $fnval
+}
+
+# See how we were called.
+case "$0" in
+   *halt)
+	message=$"Halting system..."
+	command="/sbin/halt"
+	;;
+   *reboot)
+	message=$"Please stand by while rebooting the system..."
+	command="/sbin/reboot"
+	kexec_command="/sbin/kexec"
+	;;
+   *)
+	echo $"$0: call me as 'halt' or 'reboot' please!"
+	exit 1
+	;;
+esac
+case "$1" in
+   *start)
+   	;;
+   *)
+	echo $"Usage: $0 {start}"
+	exit 1
+	;;
+esac
+
+# Kill all processes.
+[ "${BASH+bash}" = bash ] && enable kill
+
+action $"Sending all processes the TERM signal..." /sbin/killall5 -15
+sleep 5
+action $"Sending all processes the KILL signal..."  /sbin/killall5 -9
+
+# Write to wtmp file before unmounting /var
+/sbin/halt -w
+
+# Save mixer settings, here for lack of a better place.
+grep -q "\(alsa\)" /proc/devices
+if [ $? = 0 -a -x /sbin/salsa ]; then
+   action $"Saving mixer settings" /sbin/salsa -s
+fi
+
+# Save random seed
+touch /var/lib/random-seed
+chmod 600 /var/lib/random-seed
+action $"Saving random seed: " dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=512 2>/dev/null
+
+# Sync the system clock.
+ARC=0
+SRM=0
+UTC=0
+
+if [ -f /etc/sysconfig/clock ]; then
+   . /etc/sysconfig/clock
+
+   # convert old style clock config to new values
+   if [ "${CLOCKMODE}" = "GMT" ]; then
+      UTC=true
+   elif [ "${CLOCKMODE}" = "ARC" ]; then
+      ARC=true
+   fi
+fi
+
+CLOCKDEF=""
+CLOCKFLAGS="$CLOCKFLAGS --systohc"
+
+case "$UTC" in
+   yes|true)
+	CLOCKFLAGS="$CLOCKFLAGS -u";
+	CLOCKDEF="$CLOCKDEF (utc)";
+	;;
+   no|false)
+	CLOCKFLAGS="$CLOCKFLAGS --localtime";
+	CLOCKDEF="$CLOCKDEF (localtime)";
+	;;
+esac
+
+case "$ARC" in
+   yes|true)
+	CLOCKFLAGS="$CLOCKFLAGS -A";
+	CLOCKDEF="$CLOCKDEF (arc)";
+	;;
+esac
+case "$SRM" in
+   yes|true)
+	CLOCKFLAGS="$CLOCKFLAGS -S";
+	CLOCKDEF="$CLOCKDEF (srm)";
+	;;
+esac
+
+[ -x /sbin/hwclock ] && action $"Syncing hardware clock to system time" /sbin/hwclock $CLOCKFLAGS
+
+# Try to unmount tmpfs filesystems to avoid swapping them in.  Ignore failures.
+tmpfs=$(awk '$2 ~ /^\/($|proc|dev)/ { next; }
+	     $3 == "tmpfs" { print $2; }' /proc/mounts | grep -v overlayfs | sort -r)
+[ -n "$tmpfs" ] && fstab-decode umount $tmpfs 2>/dev/null
+
+# Turn off swap, then unmount file systems.
+[ -f /proc/swaps ] && SWAPS=`awk '! /^Filename/ { print $1 }' /proc/swaps`
+if [ -n "$SWAPS" ]; then
+    action $"Turning off swap: " swapoff $SWAPS
+    for dst in $SWAPS; do
+	if [[ "$dst" =~ "^/dev/mapper" ]] \
+	    && [ "$(dmsetup status "$dst" | cut -d ' ' -f 3)" = crypt ]; then
+	    backdev=$(/sbin/cryptsetup status "$dst" \
+		| awk '$1 == "device:" { print $2 }')
+	    /sbin/cryptsetup remove "$dst"
+	    # Leave partition with a blank plain-text swap
+	    mkswap "$backdev" > /dev/null
+	fi
+    done
+fi
+
+[ -x /sbin/quotaoff ] && action $"Turning off quotas: " /sbin/quotaoff -aug
+
+# Unmount file systems, killing processes if we have to.
+# Unmount loopback stuff first
+__umount_loopback_loop
+
+# Unmount RPC pipe file systems
+__umount_loop '$3 ~ /^rpc_pipefs$/ || $3 ~ /^rpc_svc_gss_pipefs$/ {print $2}' \
+    /proc/mounts \
+    $"Unmounting pipe file systems: " \
+    $"Unmounting pipe file systems (retry): " \
+    -f
+
+LANG=C __umount_loop '$2 ~ /^\/$|^\/proc|^\/dev/{next}
+	$3 == "tmpfs" || $3 == "proc" {print $2 ; next}
+	/(loopfs|autofs|nfs|cifs|smbfs|ncpfs|sysfs|^none|^\/dev\/ram|^\/dev\/root$)/ {next}
+	{print $2}' /proc/mounts \
+	$"Unmounting file systems: " \
+	$"Unmounting file systems (retry): " \
+	-f
+
+[ -f /proc/bus/usb/devices ] && umount /proc/bus/usb
+
+[ -f /etc/crypttab ] && \
+    LANG=C action $"Stopping disk encryption: " halt_crypto
+
+# remove the crash indicator flag
+rm -f /.autofsck
+
+# Try all file systems other than root, essential filesystems and RAM disks,
+# one last time.
+awk '$2 !~ /\/(|dev|proc|selinux)$/ && $1 !~ /^\/dev\/ram/ { print $2 }' \
+    /proc/mounts | grep -v overlayfs | sort -r | \
+  while read line; do
+    fstab-decode umount -f $line
+done
+
+if [ -x /sbin/halt.local ]; then
+   /sbin/halt.local
+fi
+
+# Remount read only anything that's left mounted.
+# echo $"Remounting remaining filesystems readonly"
+mount | awk '{ print $3 }' | while read line; do
+    fstab-decode mount -n -o ro,remount $line
+done
+
+if [ -f /var/tmp/.overlay.info.dontdeleteme ]; then
+    overlay_inuse_file=$( < /var/tmp/.overlay.info.dontdeleteme )
+    source $overlay_inuse_file
+    # this is readonly now.  perhaps just remount rw, delete, then ro?
+    #rm -f /var/tmp/.overlay.info.dontdeleteme 
+    echo "0 $( blockdev --getsize /dev/loop121 ) linear /dev/loop121 0" | /sbin/dmsetup reload live-rw
+    /sbin/dmsetup resume live-rw
+    overlayfile=$( /sbin/losetup /dev/loop119 | awk '{print $3}' | sed -e 's/^(//' | sed -e 's/)$//' )
+    /sbin/losetup -d /dev/loop119
+    echo "OVERLAY DEBUG: about to remove overlay_inuse_file $overlay_inuse_file"
+    rm -v -f $overlay_inuse_file
+    # TODO: support ntfs (-n -t aren't valid)
+    mount -n -t ${overlayfs_fstype} -o remount,ro ${overlayfs_dev} /mnt/overlayfs
+fi
+
+# Now halt or reboot.
+echo $"$message"
+if [ -f /fastboot ]; then
+ echo $"On the next boot fsck will be skipped."
+elif [ -f /forcefsck ]; then
+ echo $"On the next boot fsck will be forced."
+fi
+
+if [ "$command" = /sbin/halt -a -r /etc/ups/upsmon.conf -a -f /etc/killpower -a -f /etc/sysconfig/ups ] ; then
+	. /etc/sysconfig/ups
+	if [ "$SERVER" = "yes" -a "$MODEL" = "upsdrvctl" ] ; then
+		/sbin/upsdrvctl shutdown
+	elif [ "$SERVER" = "yes" -a "$MODEL" != "NONE" -a -n "$MODEL" -a -n "$DEVICE" ] ; then
+		$MODEL $OPTIONS_HALT -k $DEVICE
+	fi
+fi
+
+# First, try kexec. If that fails, fall back to rebooting the old way.
+[ -n "$kexec_command" ] && $kexec_command -e -x >& /dev/null
+
+HALTARGS="-d"
+[ -f /poweroff -o ! -f /halt ] && HALTARGS="$HALTARGS -p"
+
+exec $command $HALTARGS
diff --git a/creator/etc_rc.d_init.d_halt.orig b/creator/etc_rc.d_init.d_halt.orig
new file mode 100644
index 0000000..74bcb63
--- /dev/null
+++ b/creator/etc_rc.d_init.d_halt.orig
@@ -0,0 +1,222 @@
+#!/bin/bash
+#
+# halt          This file is executed by init when it goes into runlevel
+#               0 (halt) or runlevel 6 (reboot). It kills all processes,
+#               unmounts file systems and then either halts or reboots.
+#
+# Author:       Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
+#               Modified for RHS Linux by Damien Neil
+#
+
+NOLOCALE=1
+. /etc/init.d/functions
+
+action() {
+   echo -n "$1 "
+   shift
+   if [ "$BOOTUP" = "color" ]; then
+      "$@" && echo_success || echo_failure
+   else
+      "$@"
+   fi
+   echo
+}
+
+halt_crypto() {
+    fnval=0
+    while read dst src key; do
+	[ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue
+        if [ -b "/dev/mapper/$dst" ]; then
+            if /sbin/dmsetup info "$dst" | grep -q '^Open count: *0$'; then
+                /sbin/cryptsetup remove "$dst"
+            else
+                fnval=1
+            fi
+        fi
+    done < /etc/crypttab
+    return $fnval
+}
+
+# See how we were called.
+case "$0" in
+   *halt)
+	message=$"Halting system..."
+	command="/sbin/halt"
+	;;
+   *reboot)
+	message=$"Please stand by while rebooting the system..."
+	command="/sbin/reboot"
+	kexec_command="/sbin/kexec"
+	;;
+   *)
+	echo $"$0: call me as 'halt' or 'reboot' please!"
+	exit 1
+	;;
+esac
+case "$1" in
+   *start)
+   	;;
+   *)
+	echo $"Usage: $0 {start}"
+	exit 1
+	;;
+esac
+
+# Kill all processes.
+[ "${BASH+bash}" = bash ] && enable kill
+
+action $"Sending all processes the TERM signal..." /sbin/killall5 -15
+sleep 5
+action $"Sending all processes the KILL signal..."  /sbin/killall5 -9
+
+# Write to wtmp file before unmounting /var
+/sbin/halt -w
+
+# Save mixer settings, here for lack of a better place.
+grep -q "\(alsa\)" /proc/devices
+if [ $? = 0 -a -x /sbin/salsa ]; then
+   action $"Saving mixer settings" /sbin/salsa -s
+fi
+
+# Save random seed
+touch /var/lib/random-seed
+chmod 600 /var/lib/random-seed
+action $"Saving random seed: " dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=512 2>/dev/null
+
+# Sync the system clock.
+ARC=0
+SRM=0
+UTC=0
+
+if [ -f /etc/sysconfig/clock ]; then
+   . /etc/sysconfig/clock
+
+   # convert old style clock config to new values
+   if [ "${CLOCKMODE}" = "GMT" ]; then
+      UTC=true
+   elif [ "${CLOCKMODE}" = "ARC" ]; then
+      ARC=true
+   fi
+fi
+
+CLOCKDEF=""
+CLOCKFLAGS="$CLOCKFLAGS --systohc"
+
+case "$UTC" in
+   yes|true)
+	CLOCKFLAGS="$CLOCKFLAGS -u";
+	CLOCKDEF="$CLOCKDEF (utc)";
+	;;
+   no|false)
+	CLOCKFLAGS="$CLOCKFLAGS --localtime";
+	CLOCKDEF="$CLOCKDEF (localtime)";
+	;;
+esac
+
+case "$ARC" in
+   yes|true)
+	CLOCKFLAGS="$CLOCKFLAGS -A";
+	CLOCKDEF="$CLOCKDEF (arc)";
+	;;
+esac
+case "$SRM" in
+   yes|true)
+	CLOCKFLAGS="$CLOCKFLAGS -S";
+	CLOCKDEF="$CLOCKDEF (srm)";
+	;;
+esac
+
+[ -x /sbin/hwclock ] && action $"Syncing hardware clock to system time" /sbin/hwclock $CLOCKFLAGS
+
+# Try to unmount tmpfs filesystems to avoid swapping them in.  Ignore failures.
+tmpfs=$(awk '$2 ~ /^\/($|proc|dev)/ { next; }
+	     $3 == "tmpfs" { print $2; }' /proc/mounts | sort -r)
+[ -n "$tmpfs" ] && fstab-decode umount $tmpfs 2>/dev/null
+
+# Turn off swap, then unmount file systems.
+[ -f /proc/swaps ] && SWAPS=`awk '! /^Filename/ { print $1 }' /proc/swaps`
+if [ -n "$SWAPS" ]; then
+    action $"Turning off swap: " swapoff $SWAPS
+    for dst in $SWAPS; do
+	if [[ "$dst" =~ "^/dev/mapper" ]] \
+	    && [ "$(dmsetup status "$dst" | cut -d ' ' -f 3)" = crypt ]; then
+	    backdev=$(/sbin/cryptsetup status "$dst" \
+		| awk '$1 == "device:" { print $2 }')
+	    /sbin/cryptsetup remove "$dst"
+	    # Leave partition with a blank plain-text swap
+	    mkswap "$backdev" > /dev/null
+	fi
+    done
+fi
+
+[ -x /sbin/quotaoff ] && action $"Turning off quotas: " /sbin/quotaoff -aug
+
+# Unmount file systems, killing processes if we have to.
+# Unmount loopback stuff first
+__umount_loopback_loop
+
+# Unmount RPC pipe file systems
+__umount_loop '$3 ~ /^rpc_pipefs$/ || $3 ~ /^rpc_svc_gss_pipefs$/ {print $2}' \
+    /proc/mounts \
+    $"Unmounting pipe file systems: " \
+    $"Unmounting pipe file systems (retry): " \
+    -f
+
+LANG=C __umount_loop '$2 ~ /^\/$|^\/proc|^\/dev/{next}
+	$3 == "tmpfs" || $3 == "proc" {print $2 ; next}
+	/(loopfs|autofs|nfs|cifs|smbfs|ncpfs|sysfs|^none|^\/dev\/ram|^\/dev\/root$)/ {next}
+	{print $2}' /proc/mounts \
+	$"Unmounting file systems: " \
+	$"Unmounting file systems (retry): " \
+	-f
+
+[ -f /proc/bus/usb/devices ] && umount /proc/bus/usb
+
+[ -f /etc/crypttab ] && \
+    LANG=C action $"Stopping disk encryption: " halt_crypto
+
+# remove the crash indicator flag
+rm -f /.autofsck
+
+# Try all file systems other than root, essential filesystems and RAM disks,
+# one last time.
+awk '$2 !~ /\/(|dev|proc|selinux)$/ && $1 !~ /^\/dev\/ram/ { print $2 }' \
+    /proc/mounts | sort -r | \
+  while read line; do
+    fstab-decode umount -f $line
+done
+
+if [ -x /sbin/halt.local ]; then
+   /sbin/halt.local
+fi
+
+# Remount read only anything that's left mounted.
+# echo $"Remounting remaining filesystems readonly"
+mount | awk '{ print $3 }' | while read line; do
+    fstab-decode mount -n -o ro,remount $line
+done
+
+# Now halt or reboot.
+echo $"$message"
+if [ -f /fastboot ]; then
+ echo $"On the next boot fsck will be skipped."
+elif [ -f /forcefsck ]; then
+ echo $"On the next boot fsck will be forced."
+fi
+
+if [ "$command" = /sbin/halt -a -r /etc/ups/upsmon.conf -a -f /etc/killpower -a -f /etc/sysconfig/ups ] ; then
+	. /etc/sysconfig/ups
+	if [ "$SERVER" = "yes" -a "$MODEL" = "upsdrvctl" ] ; then
+		/sbin/upsdrvctl shutdown
+	elif [ "$SERVER" = "yes" -a "$MODEL" != "NONE" -a -n "$MODEL" -a -n "$DEVICE" ] ; then
+		$MODEL $OPTIONS_HALT -k $DEVICE
+	fi
+fi
+
+# First, try kexec. If that fails, fall back to rebooting the old way.
+[ -n "$kexec_command" ] && $kexec_command -e -x >& /dev/null
+
+HALTARGS="-d"
+[ -f /poweroff -o ! -f /halt ] && HALTARGS="$HALTARGS -p"
+
+exec $command $HALTARGS
diff --git a/creator/findoverlay b/creator/findoverlay
new file mode 100755
index 0000000..e0674cc
--- /dev/null
+++ b/creator/findoverlay
@@ -0,0 +1,265 @@
+#!/bin/bash
+#
+# findoverlay - set up persistence overlay (/dev/loop119) device
+#
+# Copyright 2007 Douglas McClendon <douglas@mcclendon.org>
+#
+# Licensed under the GPLv2. See the file COPYING for details. 
+#
+
+# WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING 
+# WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING 
+# WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING 
+#
+#           Note: this is still alpha quality software, i.e.
+#
+#             !!!NOT RESPONSIBLE IF THIS EATS YOUR DATA!!!
+#
+# WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING 
+# WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING 
+# WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING 
+
+#set -o verbose
+
+# the overlay option value is pulled by init's parsing of /proc/cmdline
+overlay=$1
+
+echo "findoverlay: starting..."
+
+# get the (safe)label and uuid of the live media
+# /dev/root is still the cdrom/usb at this point in time
+LIVEOS_SAFELABEL=$( vol_id -l /dev/root )
+LIVEOS_UUID=$( vol_id -u /dev/root )
+
+echo "findoverlay: DEBUG: LiveOS SAFELABEL-UUID is ${LIVEOS_SAFELABEL}-${LIVEOS_UUID}"
+
+# calculate pathspec from overlay option, i.e. stuff following the ':'
+if ( echo $overlay | grep -q ":" ); then
+    # pathspec specified, extract
+    pathspec=$( echo $overlay | sed -e 's/^.*://' )
+else
+    # no pathspec specified, set default
+    pathspec="/LiveOS/Persistence-${LIVEOS_SAFELABEL}-${LIVEOS_UUID}"
+fi
+
+# handle special formats of pathspec
+if [ "x${pathspec}" == "x" -o "${pathspec}" == "auto" ]; then
+    # empty or auto pathspec specified, set to default
+    pathspec="/LiveOS/Persistence-${LIVEOS_SAFELABEL}-${LIVEOS_UUID}"
+elif ( echo $pathspec | grep -v -q "/" ); then
+    # no leading slash implies prepending of default
+    pathspec="/LiveOS/Persistence-${LIVEOS_SAFELABEL}-${LIVEOS_UUID}-${pathspec}"
+fi
+
+echo "findoverlay: DEBUG: calculated pathspec is ${pathspec}"
+
+# calculate devspec from overlay option, i.e. stuff preceding the ':'
+devspec=$( echo $overlay | sed -e 's/:.*$//' )
+if [ ! -n "$devspec" ]; then
+    # no devspec, revert to default of auto
+    devspec="auto"
+fi
+
+echo "findoverlay: DEBUG: calculated devspec is ${devspec}"
+
+# load filesystem modules that may be required for overlay
+# TODO: only load these conditionally if vol_id detects a fs that needs them
+
+# for typical vfat on usbstick
+modprobe vfat
+# for typical ntfs on usbstick or host disk
+modprobe fuse
+# for typical ext3
+# assumption: ext3 is already loaded
+
+# IMPORTANT TODO: while mount scanning find a way to determine if the 
+#                 filesystem was not cleanly unmounted.  If so, IGNORE IT,
+#                 as it may be part of a hibernated OS !!!!!!!
+#
+# CAVEAT: If the overlay file has a kin file with the suffix .inuse, this
+#         is evidence that that the overlay device was not unmounted cleanly.
+#         In _this_ case, look at the filesystem(???) and determine whether
+#         or not the most recent mount of the filesystem is more recent than
+#         the inuse file.  *If and only if* NOT, then it is safe to assume
+#         that the filesystem is not part of a hibernated OS, and rather was
+#         most recently used as a persistence device that failed to be
+#         shutdown cleanly, thus it is safe to fsck the overlayfs, and then 
+#         fsck the overlay-rootfs
+
+# IMPORTANT TODO: since ext3 is such a pain (possible?) to mount readonly,
+#                 and since similar issues may exist in other fs (ntfs???),
+#                 I think it would be good to have a function called
+#                 really_mount_readonly() which does a blockdev --setro, then
+#                 does a devicemapper snapshot to ram, then does a mount of
+#                 the snapshotted device, then checks for existence of 
+#                 overlay and .inuse files.
+#
+# RELATED: Given the above function, if a persistence file is detected,
+#          but the above above inuse/recent-mount-stamp test fails, give
+#          the user a 30-60 second timeout option to force an fsck and mount
+#          of the uncleanly mounted overlayfs, defaulting to not using it.
+
+# TODO: All this multiple candidate code hasn't been tested recently (can't
+#       remember if it ever really did work).  Though I have tested the 
+#       typical auto case where one overlay is found and used.
+
+# TODO: verify that filesystems other than ext3 work.  I know this will 
+#       probably mean some interesting special case code.
+
+# TODO: handle nfs/network(fuse-httpfs?) persistence devices.  This will
+#       require the ability to set up the network here, which is probably
+#       not trivial.
+
+# TODO: handle fsck'ing the rootfs if need be correctly?  Or does the right
+#       thing just happen.  I know that trying to use a persistence file
+#       from something that got unmounted uncleanly, seems to cause problems
+#       VERY quickly.  This may be a fatal flaw...  (or at least require
+#       some work)
+
+# check if devspec is auto
+numcandidates=0
+candidates=""
+if [ "$devspec" == "auto" ]; then
+    devices="$( find /dev -name "sd*" -print 2> /dev/null ) $( find /dev -name "scd*" -print 2> /dev/null ) $( find /dev -name "sr*" -print 2> /dev/null)"
+    echo "findoverlay: DEBUG: found devices are $devices"
+    mkdir /testmount
+    for device in $devices; do
+	echo "findoverlay: DEBUG: about to test readonly on device $device"
+	devro=$( blockdev --getro $device 2> /dev/null )
+	if (($?)); then
+	    devusable=0
+	else
+	    if (( $devro )); then
+		devusable=0
+	    else
+		devusable=1
+	    fi
+	fi
+	if (( $devusable )); then 
+	    blockdev --setro $device
+	    echo "findoverlay: DEBUG: about to test mount device $device"
+	    fstype=$( vol_id -t $device )
+	    if [ "$fstype" == "ntfs" ]; then
+		mountcom="mount.ntfs-3g -t ntfs -o ro"
+	    elif  [ "$fstype" == "vfat" ]; then
+		mountcom="mount -n -t vfat -o ro"
+	    elif  [ "$fstype" == "ext3" ]; then
+		mountcom="mount -n -t ext3 -o ro"
+	    else
+		echo "findoverlay: DEBUG: unsupported filesystem found, trying auto"
+		mountcom="mount -n -t auto -o ro"
+	    fi
+	    if ( $mountcom $device /testmount ); then
+		echo "findoverlay: DEBUG: about to look for /testmount/${pathspec} on $device"
+		if [ -f /testmount/${pathspec} ]; then
+		    echo "findoverlay: DEBUG: found /testmount/${pathspec} on $device"
+		    numcandidates=$(( $numcandidates + 1 ))
+		    candidates="$candidates $device"
+		    echo "findoverlay: DEBUG: numcandidates is now $numcandidates"
+		    echo "findoverlay: DEBUG: candidates is now $candidates"
+		fi
+		echo "findoverlay: DEBUG: about to unmount device $device"
+		umount /testmount
+	    fi
+	    blockdev --setrw $device
+	fi
+    done
+    rmdir /testmount
+    
+    if [ $numcandidates -gt 1 ]; then
+	xdone=0
+	while (( ! $xdone )); do
+	    echo -en "\n\n\nfindoverlay: multiple images found, plese select one:\n\n\n"
+	    echo -en "choices:\n\n"
+	    echo -en "0: ignore overlay images, create fresh overlay in ram\n"
+	    candidatenum=1
+	    for candidate in $candidates; do
+		cfslabel="$( /sbin/vol_id -L $candidate )"
+		cuuid="$( /sbin/vol_id -u $candidate )"
+		cfstype="$( /sbin/vol_id -t $candidate )"
+		echo -en "${candidatenum}: ${candidate} LABEL=${cfslabel} FSTYPE=${cfstype} UUID=${cuuid}\n"
+		candidatenum=$(( $candidatenum + 1 ))
+	    done
+	    echo -en "\n\nchoice? (60 second timeout)"
+	    read -t 60 choice
+
+	    # yes, this is horrendously ugly
+	    candidatenum=1
+	    for candidate in $candidates; do
+		if [ $choice -eq $candidatenum ]; then
+		    pdev=$candidate
+		fi
+		candidatenum=$(( $candidatenum + 1 ))
+	    done
+
+	    if (( ! $choice )); then
+		pdev=tmpfs
+		xdone=1
+	    elif ( blockdev $pdev > /dev/null 2>&1 ); then
+		xdone=1
+	    else
+		echo -en "\n\nInvalid Choice - Please Choose Again\n\n"
+	    fi
+	done
+    elif [ $numcandidates -eq 0 ]; then
+	pdev=""
+    else
+	pdev=$candidates
+    fi
+else
+    # specific devspec given
+    
+    # normalize devicename
+    #
+    # devspec may be of the following forms:
+    #
+    # /dev/sda1             # normalized form
+    # sda1
+    # LABEL=MyLABEL
+    # UUID=MyUUID
+    if ( echo $devspec | grep -q "^UUID=" ); then
+	cuuid=$( echo $devspec | sed -e 's/^UUID=//' )
+	pdev=$( findfs UUID=${cuuid} )
+    elif ( echo $devspec | grep -q "^LABEL=" ); then
+	clabel=$( echo $devspec | sed -e 's/^LABEL=//' )
+	pdev=$( findfs LABEL=${clabel} )
+    elif ( echo $devspec | grep -q '/' ); then
+	pdev=$devspec
+    else
+	pdev="/dev/${devspec}"
+    fi
+fi
+
+# now that we have the normalized reference to the persistence device
+# set it up
+echo "findoverlay: DEBUG: pdev is xx $pdev xx"
+pdev=$( echo $pdev | sed -e 's/^\s*//' | sed -e 's/\s*$//' )
+echo "findoverlay: DEBUG: now pdev is xx $pdev xx"
+mkdir -p /mnt/overlayfs
+pmounted=0
+if ( blockdev $pdev > /dev/null 2>&1 ); then
+    echo "findoverlay: DEBUG: about to mount persistence device $pdev"
+    mount -n -t auto $pdev /mnt/overlayfs
+    ofstype="$( /sbin/vol_id -t $pdev )"
+    pmounted=1
+fi
+
+if [ -w "/mnt/overlayfs${pathspec}" ]; then
+    echo "findoverlay: DEBUG: setting up overlay file"
+    losetup /dev/loop119 /mnt/overlayfs${pathspec}
+    echo "overlayfs_dev=${pdev}" > /mnt/overlayfs${pathspec}.inuse
+    echo "overlayfs_fstype=${ofstype}" >> /mnt/overlayfs${pathspec}.inuse
+    echo "overlayfs_path=${pathspec}" >> /mnt/overlayfs${pathspec}.inuse
+    echo "/mnt/overlayfs${pathspec}.inuse" > /overlay.info
+else
+    echo "findoverlay: DEBUG: aborting persistence file, setting up ram"
+    mkdir -p /mnt/overlayfs
+    mount -n -t tmpfs -o mode=0755 none /mnt/overlayfs  
+    dd if=/dev/null of=/mnt/overlayfs/overlay bs=1024 count=1 seek=$((512*1024)) 2> /dev/null
+    losetup /dev/loop119 /mnt/overlayfs/overlay
+    echo "overlayfs_dev=tmpfs" > /mnt/overlayfs/overlay.inuse
+    echo "overlayfs_fstype=tmpfs" >>  /mnt/overlayfs/overlay.inuse
+    echo "overlayfs_path=/overlay" >>  /mnt/overlayfs/overlay.inuse
+    echo "/mnt/overlayfs/overlay.inuse" > /overlay.info
+fi
+
diff --git a/creator/livecd-creator b/creator/livecd-creator
index 0d18896..8538ad5 100755
--- a/creator/livecd-creator
+++ b/creator/livecd-creator
@@ -315,12 +315,14 @@ class LiveCDYum(yum.YumBase):
         return self.runTransaction(cb)
 
 class ImageCreator(object):
-    def __init__(self, repos, packages, epackages, groups, fs_label, skip_compression, tmpdir):
+    def __init__(self, repos, packages, epackages, groups, addsdirs, addidirs, fs_label, skip_compression, tmpdir):
         self.ayum = None
         self.repos = repos
         self.packages = packages
         self.epackages = epackages
         self.groups = groups
+        self.addsdirs = addsdirs
+        self.addidirs = addidirs
         self.fs_label = fs_label
         self.skip_compression = skip_compression
         self.tmpdir = tmpdir
@@ -824,6 +826,21 @@ class ImageCreator(object):
                                     "/usr/lib/livecd-creator/mayflower not found")
         shutil.copy("/usr/lib/livecd-creator/mayflower",
                         "%s/install_root/sbin/mayflower" %(self.build_dir,))
+
+        #
+        # dmc-overlay: copy findoverlay and live tool to target
+        #
+        if not os.path.isfile("/usr/lib/livecd-creator/findoverlay"):
+            raise InstallationError("livecd-creator not correctly installed : "+
+                                    "/usr/lib/livecd-creator/findoverlay not found")
+        shutil.copy("/usr/lib/livecd-creator/findoverlay",
+                        "%s/install_root/sbin/findoverlay" %(self.build_dir,))
+        if not os.path.isfile("/usr/lib/livecd-creator/live"):
+            raise InstallationError("livecd-creator not correctly installed : "+
+                                    "/usr/lib/livecd-creator/live not found")
+        shutil.copy("/usr/lib/livecd-creator/live",
+                        "%s/install_root/sbin/live" %(self.build_dir,))
+        
         # modules needed for booting (this is butt ugly and we need to retrieve this from elsewhere, e.g. the kernel)
         mayflowerconf = open(self.build_dir + "/install_root/etc/mayflower.conf", "w")
         mayflowerconf.write('MODULES+="cdrom ide-cd ahci loop dm_snapshot squashfs ext3 ext2 ehci_hcd uhci_hcd ohci_hcd usb_storage sd_mod sr_mod usbhid ata_piix vfat msdos "\n')
@@ -832,14 +849,28 @@ class ImageCreator(object):
         mayflowerconf.write('MODULES+="sata_promise sata_sil sata_sx4 sata_vsc "\n')
         mayflowerconf.write('MODULES+="ata_generic pata_ali pata_amd pata_artop pata_atiixp pata_cmd640 pata_cmd64x pata_cs5520 pata_cs5530 pata_cs5535 pata_cypress pata_efar pata_hpt366 pata_hpt37x pata_hpt3x2n pata_hpt3x3 pata_isapnp pata_it8213 pata_it821x pata_jmicron pata_marvell pata_mpiix pata_netcell pata_ns87410 pata_oldpiix pata_optidma pata_opti pata_pcmcia pata_pdc2027x pata_pdc202xx_old pata_qdi pata_serverworks pata_sil680 pata_sis pata_sl82c105 pata_triflex pata_via pdc_adma pata_mpc52xx "\n')
         mayflowerconf.write('MODULES+="sym53c8xx aic7xxx "\n')        
+        # overlay: modules to support overlay storage filesystems
+        #              currently- ntfs(fuse), vfat, in addition to ext3
+        mayflowerconf.write('MODULES+="fuse vfat "\n')        
         mayflowerconf.close()
 
         subprocess.call(["/sbin/mayflower", "-f", "/boot/livecd-initramfs.img",
                         self.get_kernel_version()],
                         preexec_fn=self.run_in_root)
-        for f in ("/sbin/mayflower", "/etc/mayflower.conf"):
+        for f in ("/sbin/mayflower", "/etc/mayflower.conf",
+                  "/sbin/findoverlay"):
             os.unlink("%s/install_root/%s" %(self.build_dir, f))
 
+    def addUserSystemDirs(self):
+        for dir in self.addsdirs:
+            if not os.path.isdir(dir):
+                raise InstallationError("User addsdir=%s not found" %(dir,))
+            for name in os.listdir(dir):
+                rc = subprocess.call(["/bin/cp", "-av", dir + "/" + name,
+                                      "%s/install_root/" %(self.build_dir,)])
+                if rc != 0:
+                    raise InstallationError("User addsdir=%s entry %s failed to copy" %(dir,name))            
+
     def relabelSystem(self):
         # finally relabel all files
         if self.ksparser.handler.selinux.selinux:
@@ -861,10 +892,21 @@ class ImageCreator(object):
         except Exception, e: #FIXME: we should be a little bit more fine-grained
             raise InstallationError("Error configuring live image: %s" %(e,))
         self.configureNetwork()
+        self.addUserSystemDirs()
         self.relabelSystem()
         self.createInitramfs()
         self.configureBootloader()
-
+        
+    def addUserIsoDirs(self):
+        for dir in self.addidirs:
+            if not os.path.isdir(dir):
+                raise InstallationError("User addidir=%s not found" %(dir,))
+            for name in os.listdir(dir):
+                rc = subprocess.call(["/bin/cp", "-av", dir + "/" + name,
+                                      "%s/out/" %(self.build_dir,)])
+                if rc != 0:
+                    raise InstallationError("User addidir=%s entry %s failed to copy" %(dir,name))
+                
     def configureBootloader(self):
         raise InstallationError("Bootloader configuration is arch-specific, but not implemented for this arch!")
 
@@ -954,6 +996,7 @@ class ImageCreator(object):
         if os.path.exists("%s/install_root/usr/lib/anaconda-runtime/checkisomd5" %(self.build_dir,)):        
             self._checkIsoMD5 = True
         self.createSquashFS()
+        self.addUserIsoDirs()
         self.createIso()
         self.implantIsoMD5()
 
@@ -1212,12 +1255,12 @@ image=/ppc/ppc32/vmlinuz
         ret.extend(ImageCreator._getRequiredPackages(self))
         return ret
 
-def getImageCreator(repos, packages, epackages, groups, fs_label, skip_compression, tmpdir):
+def getImageCreator(repos, packages, epackages, groups, addsdirs, addidirs, fs_label, skip_compression, tmpdir):
     arch = rpmUtils.arch.getBaseArch()
     if arch in ("i386", "x86_64"):
-        return x86ImageCreator(repos, packages, epackages, groups, fs_label, skip_compression, tmpdir)
+        return x86ImageCreator(repos, packages, epackages, groups, addsdirs, addidirs, fs_label, skip_compression, tmpdir)
     elif arch in ("ppc", "ppc64"):
-        return ppcImageCreator(repos, packages, epackages, groups, fs_label, skip_compression, tmpdir)
+        return ppcImageCreator(repos, packages, epackages, groups, addsdirs, addidirs, fs_label, skip_compression, tmpdir)
 
     raise InstallationError("Architecture not supported!")
 
@@ -1252,7 +1295,10 @@ def parse_options(args):
                       help="Don't compress the image.")
     parser.add_option("", "--ignore-deleted", action="store_true", dest="ignore_deleted",
                       help="Don't run resize2fs to clean up wasted blocks")
-
+    parser.add_option("", "--addsdir", type="string", action="append",
+                      dest="addsdirs", help="Add the contents of a directory to the target sysrootfs")
+    parser.add_option("", "--addidir", type="string", action="append",
+                      dest="addidirs", help="Add the contents of a directory to the target isofs")
 
     # debug options that will be going away real soon now.
     parser.add_option("-r", "--repo", type="string", action="append",
@@ -1295,6 +1341,10 @@ def parse_options(args):
     options.groups = groups
     if options.epackages is None:
         options.epackages = []
+    if options.addsdirs is None:
+        options.addsdirs = []
+    if options.addidirs is None:
+        options.addidirs = []
 
     if not options.kscfg and not (options.packages or options.groups):
         raise Usage("No packages or groups specified")
@@ -1349,6 +1399,8 @@ def main():
                              options.packages,
                              options.epackages,
                              options.groups,
+                             options.addsdirs,
+                             options.addidirs,
                              fs_label,
                              options.skip_compression,
                              options.tmpdir)
diff --git a/creator/mayflower b/creator/mayflower
index c1c5258..29cc8ec 100755
--- a/creator/mayflower
+++ b/creator/mayflower
@@ -79,6 +79,26 @@ cp /sbin/blockdev sbin
 cp /sbin/dmsetup sbin
 cp /bin/dd bin
 
+#
+# dmc overlay: tools needed by findoverlay
+#
+cp /sbin/findoverlay sbin
+cp /lib/udev/vol_id sbin
+cp /sbin/findfs sbin
+cp /usr/bin/find bin
+
+# is mount.fuse needed by mount.ntfs-3g?
+cp /sbin/mount.fuse sbin
+cp /sbin/mount.ntfs-3g sbin
+cp /usr/bin/fusermount bin
+
+# probably rmdir isn't worth the initramfs bloat, i.e. just leave tmpdirs
+cp /bin/rmdir bin
+cp /bin/sed bin
+cp /bin/mv bin
+cp /bin/touch bin
+# end dmc overlay stuff
+
 MODULES=
 
 if [ -e /etc/mayflower.conf ] ; then
@@ -239,6 +259,8 @@ eshell=0
 live_ram=0
 check_iso=0
 live_locale=""
+# dmc overlay
+overlay=""
 
 # Parse kernel commandline options
 #
@@ -268,6 +290,21 @@ for o in \`cat /proc/cmdline\` ; do
     live_locale=*)
         live_locale=\${o#live_locale=}
         ;;
+    #
+    # dmc overlay: aesthetics, undecided about name persistence vs overlay
+    #
+    persistence)
+        overlay=auto
+        ;;
+    persistence=*)
+        overlay=\${o#persistence=}
+        ;;
+    overlay)
+        overlay=auto
+        ;;
+    overlay=*)
+        overlay=\${o#overlay=}
+        ;;
     check)
         check_iso=1
         ;;
@@ -557,8 +594,19 @@ fi
 # live cd helper function
 do_live_from_loop121() {
     # create a sparse file for the overlay
-    dd if=/dev/null of=/overlay bs=1024 count=1 seek=$((512*1024)) 2> /dev/null
-    losetup /dev/loop119 /overlay
+    # dmc overlay: if non-ram overlay searching is desired, do it,
+    #              otherwise, create overlay in ram as usual
+    if [ "x\${overlay}" != "x" ]; then
+        /sbin/findoverlay "\$overlay"
+    else
+        mkdir -p /mnt/overlayfs
+        mount -n -t tmpfs -o mode=0755 none /mnt/overlayfs
+        dd if=/dev/null of=/mnt/overlayfs/overlay bs=1024 count=1 seek=$((512*1024)) 2> /dev/null
+        losetup /dev/loop119 /mnt/overlayfs/overlay
+        echo "overlayfs_dev=tmpfs" > /mnt/overlayfs/overlay.inuse
+        echo "overlayfs_fstype=tmpfs" >> /mnt/overlayfs/overlay.inuse
+        echo "/mnt/overlayfs/overlay.inuse" > /overlay.info
+    fi
 
     # set up the snapshot
     echo 0 \`blockdev --getsize /dev/loop121\` snapshot /dev/loop121 /dev/loop119 p 8 | dmsetup create live-rw
@@ -568,6 +616,9 @@ do_live_from_loop121() {
     ln -s /dev/mapper/live-rw /dev/root
 
     mount -n -t ext3 /dev/mapper/live-rw /sysroot
+
+    /bin/mv /overlay.info /sysroot/var/tmp/.overlay.info.dontdeleteme
+
     # here you can modify the rw ext3 fs for testing if you don't want to
     # respin the entire rootfs (which takes ages). Example
     #
@@ -602,6 +653,10 @@ do_live_from_loop121() {
     echo "KERNEL==\"loop120\" SYMLINK+=\"live-squashed\"" >> /sysroot/etc/udev/rules.d/50-udev*
     echo "KERNEL==\"loop121\" SYMLINK+=\"live-osimg\"" >> /sysroot/etc/udev/rules.d/50-udev*
 
+    # move overlay mount
+    mkdir -p /sysroot/mnt/overlayfs
+    mount -n --move /mnt/overlayfs /sysroot/mnt/overlayfs
+
     mount -n -o ro,remount /sysroot
 }
 
diff --git a/livecd-tools.spec b/livecd-tools.spec
index 13cf3e5..43e06f6 100644
--- a/livecd-tools.spec
+++ b/livecd-tools.spec
@@ -44,10 +44,15 @@ rm -rf $RPM_BUILD_ROOT
 %{_bindir}/livecd-iso-to-disk
 %dir /usr/lib/livecd-creator
 /usr/lib/livecd-creator/mayflower
+/usr/lib/livecd-creator/findoverlay
 %dir %{_datadir}/livecd-tools
 %{_datadir}/livecd-tools/*
 
 %changelog
+* Mon Aug 20 2007 Douglas McClendon <dmc@filteredperception.org> - 010-1overlay
+- implement persistence
+
+%changelog
 * Wed Jul 25 2007 Jeremy Katz <katzj@redhat.com> - 010-1
 - Separate out configs used for Fedora 7
 - Add patch from Douglas McClendon to make images smaller
-- 
1.5.2.2


