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

On-the-fly module inserting and removing



On Sat, 22 Nov 2008 20:47:36 +0000, T o n g wrote:

> I've done the preliminary testing. porting the bare-bone of the feature
> proved to be working fine. I was able to insert / remove modules to the
> aufs system.
> 
> I'll start adding the fleshes to make it not that hacky.

Done. Enclosed is the latest working copy. I can upload/send to somewhere/
someone if required, and the rcs,v file too if anyone care about the 
porting history. Current version is rev1.7.

Issues/todos:

- Currently the script depends that live-initramfs is installed. The 
better approach is to spin out a common library into a separate package, 
so that the script does not requires other irrelevant packages required 
by live-initramfs, ie, busybox, klibc-utils, libklibc, user-setup, etc.

- Need to 'ln -s /usr/share/initramfs-tools/scripts /' for the script to 
run.

- There are many spots that further porting is necessary. But those 
depends on bug 506591 to be fixed: http://bugs.debian.org/cgi-bin/
bugreport.cgi?bug=506591 . All such spots are marked with "FIXME:"

Please check it out. 

Thanks

tong

-----------------------------------------
#!/bin/sh
# Filename:      live-module
# Purpose:       Insert/remove live modules into root aufs
# Authors:       
#		 Initially ported from Slax to Debian by
#		  Tong Sun <http://xpt.sourceforge.net/>
#		 Original Slax Author:
#		  Tomas M. <http://www.linux-live.org>
# License:       This file is licensed under the GPL.
################################################################################

. /usr/share/initramfs-tools/scripts/functions
. /usr/share/initramfs-tools/scripts/live

# FIXME: move the functions from above line and the followings into a central lib file

# log
# store given text in /var/log/livedbg
log()
{
   echo "$@" 2>/dev/null >>/var/log/livedbg
}

debug_log()
{
   if [ "$DEBUG_IS_ENABLED" ]; then
      echo "- debug: $*" >&2
      log "- debug: $*"
   fi
}

# echogreen will echo $@ in green color
# $1 = text
#
echogreen()
{
   echo -ne """$@"""
}

# echolog
# $1 = text to show and to write to /var/log/messages
#
echolog()
{
   if [ "$1" != "" ]; then
      echogreen "* "
      log "LIVECD:" "$@" 
      echo "$@"
   fi
}

# test if the script is started by root user. If not, exit
allow_only_root()
{
  if [ "0$UID" -ne 0 ]; then
    echo "Only root can run $(basename $0)"; exit 1
  fi
}

# Insert a directory tree $2 to an union specified by $1
# Top-level read-write branch is specified by it's index 0
# Using =rr enables aufs to optimize real readonly branches
# $1 = union absolute path (starting with /)
# $2 = path to data directory
#
union_insert_dir()
{
  debug_log "union_insert_dir $*"
  mount -n -o remount,add:1:$2=rr aufs $1
  if [ $? -ne 0 ]; then echo "can't insert module to union" >&2; return 2; fi
}

mount_image ()
{
  image="${1}"

  if losetup --help 2>&1 | grep -q -- "-r\b"
    then
    backdev=$(get_backing_device "${image}" "-r")
  else
    backdev=$(get_backing_device "${image}")
  fi
  fstype=$(get_fstype "${backdev}")

  if [ "${fstype}" = "unknown" ]
    then
    panic "Unknown file system type on ${backdev} (${image})"
  fi

  mkdir -p "${croot}/${imagename}"
  log_begin_msg "Mounting \"${image}\" on \"${croot}${imagename}\" via \"${backdev}\""
  mount -n -t "${fstype}" -o ro,noatime "${backdev}" "${croot}/${imagename}" || panic "Can not mount ${backdev} (${image}) on ${croot}/${imagename}" && rofsstring="${croot}/${imagename}=${roopt}:${rofsstring}" && rofslist="${croot}/${imagename} ${rofslist}"
  log_end_msg

  union_insert_dir / "${croot}/${imagename}"

  if [ $? -ne 0 ]; then 
    echo "error inserting module to live filesystem" >&2; exit 3; 
  fi
}

try_remount()
{
   mount -t aufs -o remount,del:"${croot}/${imagename}" aufs / 2>/dev/null
}

# ############################################################## &cs ###
# :::::::::::::::::::::::::::::::::::::::::::::::: Subroutines begin :::

usage() {
  echo "
live-module - insert/remove live modules into root aufs

Usage: live-module [options] module

Options:
  
  -i, --ins      insert the module into root aufs
  -r, --rem      remove the module from root aufs
  -p, --plug     plug-in the module (synonym for insert)
  -u, --pull     pull-out the module (synonym for remove)

  -h, --help     Print usage information and exit
"
}
#  -V, --version  Show version information and exit

parameter_error() {
  echo "Try 'live-module --help' for more information."
  exit 1
}

# insert the module into root aufs
insert_module() {
  mount_image "$image"

  # FIXME: port the following after bug 506591 has been fixed: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506591
  # update ld cache if new ld.so.conf/cache exists in the module
  # 'invoke-rc.d daemon start' for all daemons within this module
}

# remove the module from root aufs
remove_module() {

  # Try to simply remove the dir first. If succeeds, finish
  rmdir "${croot}/${imagename}" 2>/dev/null && exit 0
  # OK the previous trick didn't work. So we have a real module here.

  # FIXME: port this after bug 506591 has been fixed: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506591
  # First, try to stop all daemons which may be started by this module
  #find_n_run_scripts ${croot}/${imagename} stop deactivate

  # detach it from aufs union. This may take a long time, remounting the
  # root directory is an expensive operation.
  try_remount


  # if we are here, the module has been successfuly removed from aufs union
  # so now we have to umount the module and then free the loop device
  LOOP=$(cat /proc/mounts | grep "${croot}/${imagename} " | cut -d " " -f 1)
  umount -n "${croot}/${imagename}" 2>/dev/null
  if [ $? -ne 0 ]; then
    exit 4
  fi
  losetup -d "$LOOP" 2>/dev/null # sometimes it's freed by umount automatically
  rmdir "${croot}/${imagename}" # if not empty or busy, a message will be shown
}

# ============================================================ &pclp ===
# .................................. process command line parameters ...

# @WARNING: 
# The following is use for the *command line logic* processing. It should be 
# as dumb as possible. I.e., it should NOT be more complicated than
# copy-paste-and-rename from existing code. All *business-logic* processing
# should be handled in main, where it belongs.
  
_opt_temp=`getopt --name live-module -o +irpuhV --long \
    ins,rem,plug,pull,help,version \
  -- "$@"`
if [ $? != 0 ]; then
  parameter_error
fi
eval set -- "$_opt_temp"
  
while :; do
  case "$1" in
  
  # == Options
  --ins|-i|--plug|-p)		# insert the module into root aufs
    _opt_plug=T
    ;;
  --rem|-r|--pull|-u)		# remove the module from root aufs
    _opt_pull=T
    ;;
  # 
  --help|-h)			# Print usage information and exit
    _opt_help=T
    ;;
  --version|-V)			# Show version information and exit
    _opt_version=T
    ;;
  --) 
    shift; break 
    ;;
  *) 
    echo "Internal getopt error!" ; exit 1
    ;;
  esac
  shift
done

[ "$_opt_help" ] && {
  usage
  exit 0
}

[ ${1:+T} ] || {
  echo "Missing the module file specification." 
  parameter_error
}

# ############################################################## &cs ###
# :::::::::::::::::::::::::::::::::::::::::::::::: Main script begin :::

allow_only_root

# are we even using aufs union?
if [ "$(grep '^aufs / ' /proc/mounts)" = "" ]; then
  echo "not in the live mode, can't continue."
  exit 4
fi

image="${1}"
imagename=$(basename "${image}")
croot=""

[ -e "$image" ] || {
  echo "The specified module file '$image' does not exist." 
  exit 4
}


# FIXME: port the following after bug 506591 has been fixed
# Test whether the module file is stored in union
# if yes, then we must move it somewhere else (to RAM) else it can't be added

# == Main dispatch

# business-logic for command line parameter-processing
if [ "$_opt_plug" ]; then 
  insert_module
elif [ "$_opt_pull" ]; then 
  remove_module
else 
  echo "Missing the operation." 
  parameter_error
fi

exit 0

# ============================================================== &ss ===
# :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: end :::

-----------------------------------------

-- 
Tong (remove underscore(s) to reply)
  http://xpt.sourceforge.net/techdocs/
  http://xpt.sourceforge.net/tools/


Reply to: