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: