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

Re: On-the-fly module inserting and removing



On Sun, 23 Nov 2008 21:38:54 +0100, Daniel Baumann wrote:

>> script updated. latest version available upon request.
> 
> if you don't post it, nobody will discuss it.

OK, here it is, enclosed below.

> apart from that, i'm not sure if anyone has the time to look at this
> (especially not if it's not precise patches against git). . . 

Hmm, it is a brand new script, not against any existing file. Moreover, 
as explained before, IMHO, it shouldn't go into any exiting packages, 
including live-initramfs. So I don't know how should I precisely patch 
against git. Please elaborate.

Here is revision 1.8:

------------------------------------------------
#!/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
echogreen()
{
   echo -ne "\033[1;32m""$@""\033[0;39m"
}

# echoyellow will echo $@ in yellow color
echoyellow()
{
   echo -ne "\033[1;33m""$@""\033[0;39m"
}

# echored will echo $@ in red color
echored()
{
   echo -ne "\033[1;31m""$@""\033[0;39m"
}

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

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

# prog_abort
# $@ = text to show and to write to /var/log/messages
prog_abort()
{
   if [ ${1:+T} ]; then
      echored "x "
      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
    prog_abort "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 prog_abort "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
    prog_abort "Unknown file system type on ${backdev} (${image})"; exit 3
  fi

  mkdir -p "${croot}/${imagename}"
  prog_info "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}"

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

  if [ $? -ne 0 ]; then 
    prog_abort "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() {
  prog_warning "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 
    ;;
  *) 
    prog_abort "Internal getopt error!" ; exit 1
    ;;
  esac
  shift
done

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

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

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

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

allow_only_root

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

[ -e "$image" ] || {
  prog_abort "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 
  prog_abort "Missing the operation." 
  parameter_error
fi

prog_info "Done."
exit 0

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

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


Reply to: