From 112ee0e018e658f0c6dfb0bee32be19ae67ce00f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 23 Sep 2007 14:46:26 +0200 Subject: [PATCH] Adding casper 1.77+debian-2. --- bin/casper-snapshot | 165 +++++++++++------ casper.conf | 4 +- debian/casper.init | 44 ++--- debian/changelog | 21 +++ debian/control | 6 +- debian/control.debian | 6 +- debian/control.ubuntu | 2 +- debian/manpage/casper-snapshot.1 | 28 ++- debian/manpage/casper.7 | 10 +- hooks/casper | 9 +- scripts/casper | 312 +++++++++----------------------- scripts/casper-bottom/02etc_casper_conf | 10 +- scripts/casper-bottom/14locales | 20 +- scripts/casper-bottom/18hostname | 4 +- scripts/casper-bottom/19keyboard | 8 +- scripts/casper-helpers | 169 +++++++++++++++++ 16 files changed, 465 insertions(+), 353 deletions(-) create mode 100644 scripts/casper-helpers diff --git a/bin/casper-snapshot b/bin/casper-snapshot index f90e563..d2cb9e8 100644 --- a/bin/casper-snapshot +++ b/bin/casper-snapshot @@ -1,9 +1,10 @@ -#!/bin/sh +#!/bin/bash -# casper-snapshot - utility to do Debian Live systems snapshots +# casper-snapshot - utility to manage Debian Live systems snapshots # -# This program mount a /tmpfs under ~/Desktop and save the /cow -# filesystem in it for reusing in another session. +# This program mount a device (fallback to /tmpfs under /mnt/snapshot +# and save the /cow (or a different dir) filesystem in it for reusing +# in another casper session. Look at manpage for more info. # # Copyright (C) 2006 Marco Amadori # @@ -27,18 +28,45 @@ PROGRAM="`basename ${0}`" VERSION=0.0.1 + # Source casper conf if [ -e /etc/casper.conf ]; then . /etc/casper.conf else - USERNAME=`cat /etc/passwd | grep "999" | cut -f1 -d ':'` + USERNAME=$(cat /etc/passwd | grep "999" | cut -f1 -d ':') + HOSTNAME=$(hostname) + BUILD_SYSTEM="Debian" +fi + +export USERNAME USERFULLNAME HOSTNAME BUILD_SYSTEM + +# Source helper functions +helpers="/usr/share/initramfs-tools/scripts/casper-helpers" +if [ -e "${helpers}" ]; then + . "${helpers}" +else + echo "Error: I cannot found helper functions \"${helpers}\"." + exit 1 fi +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# Some defaults: +MOUNTP="/mnt/casper-snapshot" +COW="/cow" +DEV="" +DEST="${MOUNTP}/casper-sn.cpio.gz" +TYPE="cpio" +DESKTOP_LINK=/home/$USERNAME/Desktop/casper-snapshot + Header () { echo "${PROGRAM} - utility to do Debian Live snapshots" echo - echo "Usage: ${PROGRAM} [-c|--cow DIRECTORY] [-d|--dest DIRECTORY] [-o|--output FILE] [-t|--type TYPE]" + echo "Usage: ${PROGRAM} [-c|--cow DIRECTORY] [-d|--device DEVICE] [-o|--output FILE] [-t|--type TYPE]" + echo "Usage: ${PROGRAM} [-r|--resync-string STRING]" echo "Usage: ${PROGRAM} [-h|--help]" echo "Usage: ${PROGRAM} [-u|--usage]" echo "Usage: ${PROGRAM} [-v|--version]" @@ -66,7 +94,9 @@ Help () echo " -c, --cow: specifies the copy on write directory (default: /cow)." echo " -d, --destination: specifies the output snapshot directory (default: /home/\$USERNAME/Desktop/casper-snapshot)." echo " -o, --output: specifies the output image file (default: $type dependent)." + echo " -r, --resync-string: internally used to resync previous made snapshots." echo " -t,--type: specifies the snapshot type between \'squashfs\', \'ext2\' or \'cpio\'.gz archive (default: cpio)" + echo -e "\nLook at casper-snapshot(1) man page for more information." exit 0 } @@ -121,31 +151,6 @@ Do_snapshot () esac } -Lastline() -{ - while read lines ; do - line=${lines} - done - echo "${line}" -} - -Base_path () -{ - testpath="${1}" - mounts="`awk '{print $2}' /proc/mounts`" - testpath="`realpath ${testpath}`" - - while true ; do - if echo "${mounts}" | grep -qs "^${testpath}" ; then - set -- `echo "${mounts}" | grep "^${testpath}" | Lastline` - echo ${1} - break - else - testpath=`dirname $testpath` - fi - done -} - Is_same_mount () { dir1="`Base_path ${1}`" @@ -174,12 +179,14 @@ Parse_args () case "${1}" in -c|--cow) SNAP_COW="${2}"; shift 2 ;; - -d|--destination) - SNAP_DEST="${2}"; shift 2 ;; + -d|--device) + SNAP_DEV="${2}"; shift 2 ;; -o|--output) SNAP_OUTPUT="${2}"; shift 2 ;; -t|--type) SNAP_TYPE="${2}"; shift 2 ;; + -r|--resync-string) + SNAP_RSTRING="${2}"; break ;; -h|--help) Help; shift ;; -u|--usage) @@ -194,34 +201,85 @@ Parse_args () done } -Defaults () +Mount_device () { - DEF_COW="/cow" + dev="${1}" + + if [ ! -d "${MOUNTP}" ]; then + mkdir -p "${MOUNTP}" + fi + + if [ -n "${dev}" ]; then + # create a temp + mount -t tmpfs -o rw tmpfs "${MOUNTP}" + if [ ! -L /home/$USERNAME/Desktop/casper-snapshot ]; then + ln -s "${MOUNTP}" /home/$USERNAME/Desktop/casper-snapshot + fi + else + if [ -b "${dev}" ] ; then + try_mount "${dev}" "${MOUNTP}" rw + fi + fi +} - # Bad options handling - if [ -z "${SNAP_COW}" ]; then - COW="${DEF_COW}" +Defaults () +{ + if [ -n "${SNAP_RSTRING}" ]; then + COW=$(echo "${SNAP_RSTRING}" | cut -f1 -d ':') + DEV=$(echo "${SNAP_RSTRING}" | cut -f2 -d ':') + DEST=$(echo "${SNAP_RSTRING}" | cut -f3 -d ':') + + case "${DEST}" in + *.cpio.gz|*.cpz|*.gz) + TYPE="cpio" ;; + *.squashfs|*.squ}) + TYPE="squashfs" ;; + "") + TYPE="ext2" ;; + *.ext2|*.ext) + TYPE="ext2" ;; + *) + Usage "Unregognized String" ;; + esac else - COW="${SNAP_COW}" + DEF_COW="/cow" + # Bad options handling + if [ -z "${SNAP_COW}" ]; then + COW="${DEF_COW}" + else + COW="${SNAP_COW}" + fi + + case "${SNAP_TYPE}" in + "cpio"|"squashfs"|"ext2") + TYPE="${SNAP_TYPE}" + ;; + "") + TYPE="cpio" ;; + *) + Usage "Error: unrecognized snapshot type" + ;; + esac + #if [ -d + #if Is_same_mount fi + + Mount_device $DEV + DEST="${MOUNTP}/${DEST}" + + # check vars if [ ! -d "${COW}" ]; then Usage "Error: ${COW} is not a directory" fi +} - case "${SNAP_TYPE}" in - "cpio"|"squashfs"|"ext2") - TYPE="${SNAP_TYPE}" - ;; - "") - TYPE="cpio" ;; - *) - Usage "Error: unrecognized snapshot type" - ;; - esac - - #if [ -d - #if Is_same_mount - +Clean () +{ + if [ -n "$DEV" ]; then + umount "${MOUNTP}" + rmdir "${MOUNTP}" + rm + fi } Main () @@ -229,6 +287,7 @@ Main () Parse_args "${@}" Defaults Do_snapshot + Clean } Main "${@}" diff --git a/casper.conf b/casper.conf index ba5101c..7974b05 100644 --- a/casper.conf +++ b/casper.conf @@ -1,8 +1,8 @@ # This file should go in /etc/casper.conf # Supported variables are: -# USERNAME, USERFULLNAME, HOST, BUILD_SYSTEM +# USERNAME, USERFULLNAME, HOSTNAME, BUILD_SYSTEM export USERNAME="casper" export USERFULLNAME="Live session user" -export HOST="live" +export HOSTNAME="live" export BUILD_SYSTEM="Debian" diff --git a/debian/casper.init b/debian/casper.init index d6ec097..6817efd 100644 --- a/debian/casper.init +++ b/debian/casper.init @@ -8,7 +8,8 @@ # Default-Start: 1 2 3 4 5 # Default-Stop: 0 6 # Short-Description: Casper init script -# Description: Does the proper shutdown in a casper booted system. +# Description: Resyncs snapshots, evantually caches files in order +# to let remove the media. ### END INIT INFO # Author: Tollef Fog Heen @@ -16,7 +17,8 @@ # PATH=/usr/sbin:/usr/bin:/sbin:/bin NAME=casper -SCRIPTNAME=/etc/init.d/$NAME +SCRIPTNAME=/etc/init.d/${NAME} +DO_SNAPSHOT=/sbin/${NAME}-snapshot # Exit if system was not booted by casper grep -qs boot=casper /proc/cmdline || exit 0 @@ -50,34 +52,19 @@ cache_path() { fi } -do_sync () -{ - # copy the tmp media on the snapshot media - fromdir="${1}" - todev="${2}" - tmnt="/mnt/temp_snap" - - mkdir "${tmnt}" && \ - mount "${todev}" "${tmnt}" -o rw && \ - cd "${fromdir}" && \ - find . -print0 | cpio -pumd0 "${tmnt}" && \ - umount "${tmnt}" && \ - rmdir "${tmnt}" -} - do_stop () { - # check for netboot - if [ ! -z "${NETBOOT}" ] || grep -qs netboot /proc/cmdline || grep -qsi root=/dev/nfs /proc/cmdline || grep -qsi root=/dev/cifs /proc/cmdline ; then - return 0 - fi - if [ ! -z "${ROOTSNAP}" ]; then - do_sync "/cow" "${ROOTSNAP}" + $DO_SNAPSHOT --resync-string="${ROOTSNAP}" fi if [ ! -z "${HOMESNAP}" ]; then - do_sync "/home" "${HOMESNAP}" + $DO_SNAPSHOT --resync-string="${HOMESNAP}" + fi + + # check for netboot + if [ ! -z "${NETBOOT}" ] || grep -qs netboot /proc/cmdline || grep -qsi root=/dev/nfs /proc/cmdline || grep -qsi root=/dev/cifs /proc/cmdline ; then + return 0 fi for path in $(which halt) $(which reboot) /etc/rc?.d /etc/default; do @@ -89,9 +76,9 @@ do_stop () # XXX - i18n echo "Please remove the disc and close the tray (if any) then press ENTER: " if [ -x /sbin/usplash_write ]; then - /sbin/usplash_write "TIMEOUT 86400" - /sbin/usplash_write "TEXT-URGENT Please remove the disc, close the tray (if any)" - /sbin/usplash_write "TEXT-URGENT and press ENTER to continue" + /sbin/usplash_write "TIMEOUT 86400" + /sbin/usplash_write "TEXT-URGENT Please remove the disc, close the tray (if any)" + /sbin/usplash_write "TEXT-URGENT and press ENTER to continue" fi read x < /dev/console @@ -102,7 +89,7 @@ case "$1" in [ "$VERBOSE" != no ] && log_end_msg 0 ;; stop) - log_begin_msg "Caching reboot files..." + log_begin_msg "${NAME} is resyncing snapshots and caching reboot files..." do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; @@ -114,4 +101,3 @@ case "$1" in exit 3 ;; esac - diff --git a/debian/changelog b/debian/changelog index 6887ad3..c2ca6ca 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,24 @@ +casper (1.77+debian-2) unstable; urgency=medium + + [ Marco Amadori ] + * Improved snapshotting (but still experimental). + * Renamed "host=" boot parameter to "hostname=" and shell variable "HOST" to + "HOSTNAME" for consistence, with linux and with username/USERNAME, as + requested by many people. + * Fixed a "keyb=" typo. + * Added dependence on lsb-base (used by init-script and + casper-snapshot). + * Removed DM support (obsolete). + * Changed a bit locale and keyboard handling. + * Fixed locale generation. + * Urgency is set to medium to try reaching Etch with important + features/bugfixes. + + [ Otavio Salvador ] + * Really lowered usplash conflicts since Debian doesn't has 0.4. + + -- Marco Amadori Mon, 30 Oct 2006 17:06:48 +0100 + casper (1.77+debian-1) unstable; urgency=low * New upstream release. diff --git a/debian/control b/debian/control index 95a6edd..0ebb148 100644 --- a/debian/control +++ b/debian/control @@ -8,10 +8,10 @@ Standards-Version: 3.7.2 Package: casper Architecture: any -Depends: initramfs-tools (>= 0.40), user-setup, sudo -Conflicts: usplash (<< 0.4-0) +Depends: initramfs-tools (>= 0.40), user-setup, sudo, lsb-base (>= 3.0-6) +Conflicts: usplash (<< 0.3-0) Recommends: live-package -Suggests: dmsetup, squashft-tools, genext2fs +Suggests: squashfs-tools, genext2fs Tag: admin::boot, admin::filesystem, implemented-in::shell, protocol::smb, role::plugin, scope::utility, special::completely-tagged, works-with-format::iso9660 Description: Debian Live initramfs generator Casper provides an initramfs generator suited for booting a Debian Live systems diff --git a/debian/control.debian b/debian/control.debian index 95a6edd..0ebb148 100644 --- a/debian/control.debian +++ b/debian/control.debian @@ -8,10 +8,10 @@ Standards-Version: 3.7.2 Package: casper Architecture: any -Depends: initramfs-tools (>= 0.40), user-setup, sudo -Conflicts: usplash (<< 0.4-0) +Depends: initramfs-tools (>= 0.40), user-setup, sudo, lsb-base (>= 3.0-6) +Conflicts: usplash (<< 0.3-0) Recommends: live-package -Suggests: dmsetup, squashft-tools, genext2fs +Suggests: squashfs-tools, genext2fs Tag: admin::boot, admin::filesystem, implemented-in::shell, protocol::smb, role::plugin, scope::utility, special::completely-tagged, works-with-format::iso9660 Description: Debian Live initramfs generator Casper provides an initramfs generator suited for booting a Debian Live systems diff --git a/debian/control.ubuntu b/debian/control.ubuntu index 77c9cb2..88e4c09 100644 --- a/debian/control.ubuntu +++ b/debian/control.ubuntu @@ -9,7 +9,7 @@ Package: casper Architecture: any Section: misc Priority: extra -Depends: initramfs-tools (>= 0.40ubuntu11), dmsetup, user-setup, sudo +Depends: initramfs-tools (>= 0.40ubuntu11), user-setup, sudo Conflicts: usplash (<< 0.4-27) Tag: admin::boot, admin::filesystem, implemented-in::shell, protocol::smb, role::plugin, scope::utility, special::completely-tagged, works-with-format::iso9660 Description: Run a "live" preinstalled system from read-only media diff --git a/debian/manpage/casper-snapshot.1 b/debian/manpage/casper-snapshot.1 index 1e17251..3cd5309 100644 --- a/debian/manpage/casper-snapshot.1 +++ b/debian/manpage/casper-snapshot.1 @@ -7,24 +7,30 @@ casper-snapshot \- a simple script to ease persistence usage. .B casper-snapshot .RB [\| \-c \||\| \-\-cow .IR DIRECTORY \|] -.RB [\| \-d \||\| \-\-destination -.IR DIRECTORY \||\| FILE \|] +.RB [\| \-d \||\| \-\-device +.IR DEVICE \|] +.RB [\| \-e \||\| \-\-exclude\-list +.IR FILE \|] .RB [\| \-o \||\| \-\-output .IR FILE \|] .RB [\| \-t \||\| \-\-type .IR TYPE \|] .PP -.B make-live +.B casper-snapshot +.RB \-r \||\| \-\-resync\-string +.IR STRING +.br +.B casper-snapshot .RB \-h \||\| \-\-help .br -.B make-live +.B casper-snapshot .RB \-u \||\| \-\-usage .br -.B make-live +.B casper-snapshot .RB \-v \||\| \-\-version .SH DESCRIPTION -Casper-snapshot is a script useful to build the right types of persistent image files supported by casper. +Casper-snapshot is a script useful to build the right types of persistent image files supported by casper, it is also used on exit by the casper init script to resync the boot-found snapshots devices. .SH OPTIONS .TP @@ -32,9 +38,17 @@ Casper-snapshot is a script useful to build the right types of persistent image specifies the input directory to be cloned in the image file. This parameters often does not need to be specified as the default of "/cow" for it should be right for most uses, however it could be handy to specify "/home" and type ext2 for the type to prepare an image file suited to be directly mounted by casper as home. .TP -.BI "\-d, \-\-destination" DIRECTORY +.BI "\-d, \-\-device" DEVICE +the device on where the media which the snapshot/persistence file/partition will be put. If not specified a tmpfs will be used and linked on user's desktop to move it where he/her wants. If the device has not a filesystem on it, an ext2 fs will be created in it and labeled like --output options or with a sane default. +.TP +.BI "\-e, \-\-exclude\-list" FILE +you could pass a list of filenames/path that should not be saved. This exclude list will be remebered on the target snapshotting media for reuse. .TP .BI "\-o, \-\-output" FILE +the filename/label to be used for the output file/partition, if left blank it could search for a proper file on the device or use the whole partition. +.TP +.BI "\-r, \-\-resync\-string" STRING +internally used on resyncs. .TP .BI "\-t, \-\-type" TYPE diff --git a/debian/manpage/casper.7 b/debian/manpage/casper.7 index 89f1cf2..794ee0d 100644 --- a/debian/manpage/casper.7 +++ b/debian/manpage/casper.7 @@ -1,7 +1,7 @@ .TH CASPER 7 "Thu, 28 Sep 2006" "1.69" "Initramfs-tools hook" .SH NAME -casper \- an hook for initramfs-tools to boot live systems. +casper \- a hook for initramfs-tools to boot live systems. .SH SYNOPSIS .B BOOT=casper @@ -15,11 +15,11 @@ Casper is an hook for initramfs-tools used to generate initramfs able to boot li .B casper-getty This enable a special serial login shell (experimental). .TP -.BI "host=" HOSTNAME " , userfullname=" USERFULLNAME " , username=" USERNAME +.BI "hostname=" HOSTNAME " , userfullname=" USERFULLNAME " , username=" USERNAME Those parameters lets you override values read from the config file. .TP -.BI "keyb=" KEYBOARD " | kbd-chooser/method=" KEYBOARD "; console-setup/layoutcode=" LAYOUT ", console-setup/variantcode=" VARIANT -Configure the running keyboard as specified, if this one misses casper behave as "keyb=us" was specified. (It will be interfered from "locale=" somewhere in the future). You could also specify layout and variant (no defaults). +.BI "keyb=" KEYBOARD " | kbd-chooser/method=" KEYBOARD " ; console-setup/layoutcode=" LAYOUT " , console-setup/variantcode=" VARIANT " , console-setup/modelcode" CODE +Configure the running keyboard as specified, if this one misses casper behave as "keyb=us" was specified. It will be interfered from "locale=" if locale is only 2 lowecase letters as a special case. You could also specify layout, variant, and code (no defaults). .TP .BI ip= IFACE,ADDRESS,NETMASK,GATEWAY [ :IFACE,ADDRESS,NETMASK,GATEWAY "]*" Let you specify the name(s) and the options of the interface(s) that should be configured at boot time. Do not specify it if you want to use dhcp (default). @@ -28,7 +28,7 @@ Let you specify the name(s) and the options of the interface(s) that should be c This way dhcp and static configuration is just skipped and the system will use the (must be) media-preconfigured /etc/network/interfaces instead. .TP .BI "locale=" LOCALE " | debian-installer/locale=" LOCALE -Configure the running locale as specified, if not present the live-media rootfs configured locale will be used and if also this one misses casper behave as "locale=en_US.UTF-8" was specified. +Configure the running locale as specified, if not present the live-media rootfs configured locale will be used and if also this one misses casper behave as "locale=en_US.UTF-8" was specified. If only 2 lowercase letter are specified (like "it"), the "maybe wanted" locale is generated (like it:IT.UTF-8), in this case if also "keyb=" is unspecified is set with those 2 lowercase letters (keyb=it). .TP .BI live-media= DEVICE " | bootfrom=" DEVICE If you specify one of this two equivalent forms, casper will try first to look on this device for the "/casper" directory where it should lie the read-only root filesystem, if it did not find it, the normal scan for block devices will be performed. diff --git a/hooks/casper b/hooks/casper index 2ebd188..be7f959 100755 --- a/hooks/casper +++ b/hooks/casper @@ -27,14 +27,6 @@ if [ -e /etc/casper.conf ]; then cp /etc/casper.conf ${DESTDIR}/etc fi -# Needed for devmapper -if [ -e /sbin/dmsetup ]; then - manual_add_modules cloop - copy_exec /sbin/blockdev /sbin - copy_exec /sbin/dmsetup /sbin - manual_add_modules dm-snapshot -fi - # We need losetup copy_exec /sbin/losetup /sbin @@ -85,5 +77,6 @@ manual_add_modules ohci1394 copy_exec /usr/lib/casper/casper-md5check /bin cp /usr/share/initramfs-tools/scripts/casper-functions $DESTDIR/scripts +cp /usr/share/initramfs-tools/scripts/casper-helpers $DESTDIR/scripts auto_add_modules net diff --git a/scripts/casper b/scripts/casper index 3a5e0ca..558a29b 100644 --- a/scripts/casper +++ b/scripts/casper @@ -8,25 +8,20 @@ mountpoint=/live_media root_persistence="casper-rw" home_persistence="home-rw" -root_snapshot="casper-sn" -home_snapshot="home-sn" +root_snapshot_label="casper-sn" +home_snapshot_label="home-sn" USERNAME="casper" USERFULLNAME="Live session user" -HOST="live" +HOSTNAME="live" BUILD_SYSTEM="Debian" mkdir -p $mountpoint [ -f /etc/casper.conf ] && . /etc/casper.conf +export USERNAME USERFULLNAME HOSTNAME BUILD_SYSTEM -export USERNAME USERFULLNAME HOST BUILD_SYSTEM - -if [ "${BUILD_SYSTEM}" == "Ubuntu" ]; then - MP_QUIET="-Q" -else - MP_QUIET="-q" -fi +. /scripts/casper-helpers parse_cmdline () { @@ -37,8 +32,8 @@ parse_cmdline () export USERFULLNAME=${x#userfullname=} export CASPERCONF="changed" ;; - host=*) - export HOST=${x#host=} + hostname=*) + export HOSTNAME=${x#hostname=} export CASPERCONF="changed" ;; username=*) @@ -76,7 +71,7 @@ parse_cmdline () kbd-chooser/method=*) export KBD=${x#kbd-chooser/method=} ;; keyb=*) - export KBD=${x#kbd=} ;; + export KBD=${x#keyb=} ;; console-setup/layoutcode=*) export CSLAYOUT=${x#console-setup/layoutcode=} ;; console-setup/variantcode=*) @@ -101,8 +96,7 @@ parse_cmdline () is_casper_path() { path=$1 if [ -d "$path/casper" ]; then - if [ "$(echo $path/casper/*.cloop)" != "$path/casper/*.cloop" ] || - [ "$(echo $path/casper/*.squashfs)" != "$path/casper/*.squashfs" ] || + if [ "$(echo $path/casper/*.squashfs)" != "$path/casper/*.squashfs" ] || [ "$(echo $path/casper/*.ext2)" != "$path/casper/*.ext2" ] || [ "$(echo $path/casper/*.dir)" != "$path/casper/*.dir" ]; then return 0 @@ -111,22 +105,8 @@ is_casper_path() { return 1 } -subdevices() { - sysblock=$1 - r="" - for dev in "${sysblock}" "${sysblock}"/*; do - if [ -e "${dev}/dev" ]; then - r="${r} ${dev}" - fi - done - echo ${r} -} - get_backing_device() { case "$1" in - *.cloop) - echo $(setup_loop "$1" "cloop" "/sys/block/cloop*") - ;; *.squashfs|*.ext2) echo $(setup_loop "$1" "loop" "/sys/block/loop*") ;; @@ -152,10 +132,7 @@ match_files_in_dir() { mount_images_in_directory() { directory="$1" rootmnt="$2" - if match_files_in_dir "$directory/casper/*.cloop"; then - # Let's hope there's just one matching *.cloop... FIXME - setup_devmapper $(get_backing_device "$directory/casper/*.cloop") "$rootmnt" - elif match_files_in_dir "$directory/casper/*.squashfs" || + if match_files_in_dir "$directory/casper/*.squashfs" || match_files_in_dir "$directory/casper/*.ext2" || match_files_in_dir "$directory/casper/*.dir"; then setup_unionfs "$directory/casper" "$rootmnt" @@ -164,30 +141,6 @@ mount_images_in_directory() { fi } -sys2dev() { - sysdev=${1#/sys} - echo "/dev/$(udevinfo -q name -p ${sysdev} 2>/dev/null|| echo ${sysdev##*/})" -} - -setup_loop() { - local fspath=$1 - local module=$2 - local pattern=$3 - - modprobe "${MP_QUIET}" -b "$module" - udevsettle - - for loopdev in $pattern; do - if [ "$(cat $loopdev/size)" -eq 0 ]; then - dev=$(sys2dev "${loopdev}") - losetup "$dev" "$fspath" - echo "$dev" - return 0 - fi - done - panic "No loop devices available" -} - get_fstype() { local FSTYPE local FSSIZE @@ -199,36 +152,6 @@ get_fstype() { /lib/udev/vol_id -t $1 2>/dev/null } -setup_devmapper() { - backdev="$1" - rootmnt="$2" - - modprobe "${MP_QUIET}" -b dm-mod - COW_DEVICE=/dev/ram1 - COW_NAME="casper-cow" - - BACKING_FILE_SIZE=$(blockdev --getsize "$backdev") - MAX_COW_SIZE=$(blockdev --getsize "$COW_DEVICE") - CHUNK_SIZE=8 # sectors - - if [ -z "$COW_SIZE" -o "$COW_SIZE" -gt "$MAX_COW_SIZE" ]; then - COW_SIZE=$MAX_COW_SIZE - fi - - echo "0 $COW_SIZE linear $COW_DEVICE 0" | dmsetup create $COW_NAME - - echo "0 $BACKING_FILE_SIZE snapshot $backdev /dev/mapper/$COW_NAME p $CHUNK_SIZE" | \ - dmsetup create casper-snapshot - if [ "$(get_fstype $backdev)" = "unknown" ]; then - panic "Unknown file system type on $backdev" - fi - mount -t $(get_fstype "$backdev") /dev/mapper/casper-snapshot $rootmnt || panic "Can not mount /dev/mapper/casper/snapshot on $rootmnt" - - mkdir -p "$rootmnt/rofs" - echo "0 $BACKING_FILE_SIZE linear $backdev 0" | dmsetup create casper-backing - mount -t $(get_fstype "$backdev") /dev/mapper/casper-backing "$rootmnt/rofs" -} - is_nice_device() { sysfs_path="${1#/sys}" if /lib/udev/path_id "${sysfs_path}" | grep -E -q "ID_PATH=(usb|pci-[^-]*-[ide|scsi|usb])"; then @@ -249,45 +172,6 @@ is_supported_fs () return 1 } -where_is_mounted() { - device=$1 - if grep -q "^$device " /proc/mounts; then - grep "^$device " /proc/mounts | read d mountpoint rest - echo $mountpoint - return 0 - fi - return 1 -} - -used_fs_size () -{ - # Returns used fs kbytes + 5% more - # You could pass a block device as $1 or the mount point as $2 - - dev="${1}" - mountp="${2}" - - if [ -z "${mountp}" ]; then - mountp=$(where_is_mounted "${dev}") - if [ "$?" -gt 0 ]; then - mountp=/mnt/tmp_fs_size - mkdir -p "${mountp}" - mount -t $(get_fstype "${dev}") -o ro "${dev}" "${mountp}" - doumount=1 - fi - fi - - size=$(du -ks ${mountp} | cut -f1) - size=$(expr ${size} + ${size}/20 ) # FIXME: 5% more to be sure - needed_space=$(expr ${size} * 1024) - - if [ ! -z "${doumount}" ]; then - umount "${mountp}" - rmdir "${mountp}" - fi - echo "${needed_space}" -} - copy_live_to() { copyfrom="${1}" copytodev="${2}" @@ -331,68 +215,6 @@ copy_live_to() { return 0 } -try_mount () -{ - dev="${1}" - mountp="${2}" - opts="${3}" - - if where_is_mounted ${dev} > /dev/null; then - mount -o remount,"${opts}" ${dev} $(where_is_mounted ${dev}) || panic "Remounting failed" - mount -o bind $(where_is_mounted ${dev}) ${mountp} || panic "Cannot bind-mount" - else - mount -t $(get_fstype "${dev}") -o "${opts}" "${dev}" "${mountp}" || panic "Cannot mount ${dev} on ${mountp}" - fi -} - -find_cow_device() { - pers_label="${1}" - cow_backing="/${pers_label}-backing" - for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do - for dev in $(subdevices "${sysblock}"); do - devname=$(sys2dev "${dev}") - if [ "$(/lib/udev/vol_id -l $devname 2>/dev/null)" = "${pers_label}" ]; then - echo "$devname" - return - elif [ "$(get_fstype ${devname})" = "vfat" ]; then # FIXME: all supported block devices should be scanned - mkdir -p "${cow_backing}" - try_mount "${devname}" "${cow_backing}" "rw" - if [ -e "${cow_backing}/${pers_label}" ]; then - echo $(setup_loop "${cow_backing}/${pers_label}" "loop" "/sys/block/loop*") - return 0 - else - umount ${cow_backing} - fi - fi - done - done -} - -find_files() -# return the first of $filenames found on vfat and ext2 devices -# FIXME: merge with above function -{ - filenames="${1}" - snap_backing="/snap-backing" - for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do - for dev in $(subdevices "${sysblock}"); do - devname=$(sys2dev "${dev}") - devfstype="$(get_fstype ${devname})" - if [ "${devfstype}" = "vfat" ] || [ "${devfstype}" = "ext2" ] ; then # FIXME: all supported block devices should be scanned - mkdir -p "${snap_backing}" - try_mount "${devname}" "${snap_backing}" "ro" - for filename in ${filenames}; do - if [ -e "${snap_backing}/${filename}" ]; then - echo "${devname} ${snap_backing} ${filename}" - return 0 - fi - done - umount ${snap_backing} - fi - done - done -} - do_netmount() { rc=1 @@ -459,25 +281,36 @@ do_snap_copy () todir="${2}" snap_type="${3}" - size=$(used_fs_size "${fromdev}") + #size=$(used_fs_size "${fromdev}") if [ -b "${fromdev}" ]; then # look for free mem - if [ ! -z "${HOMEMOUNTED}" ] && [ "${snap_type}" = "HOME" ]; then - freespace="$(df -k ${copytodev} | grep -s ${copytodev} | awk '{print $4}')" + if [ -n "${HOMEMOUNTED}" -a "${snap_type}" = "HOME" ]; then + todev=$(cat /proc/mounts | grep -s " $(base_path ${todir}) " | awk '{print $1}' ) + freespace=$(df -k | grep -s ${todev} | awk '{print $4}') else freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - )) fi + tomount="/mnt/tmpsnap" - mkdir -p "${tomount}" - mount -t $(get_fstype "${fromdev}") -o ro "${fromdev}" "${tomount}" - cp -a "${tomount}"/* ${todir} - umount "${tomount}" + if [ ! -d "${tomount}" ] ; then + mkdir -p "${tomount}" + fi - if echo ${fromdev} | grep -qs loop; then - losetup -d "${fromdev}" + fstype=$(get_fstype "${fromdev}") + if [ -n "${fstype}" ]; then + # Copying stuff... + mount -t "${fstype}" -o ro "${fromdev}" "${tomount}" + cp -a "${tomount}"/* ${todir} + umount "${tomount}" + else + log_warning_msg "Unrecognized fstype: ${fstype} on ${fromdev}:${snap_type}" fi + rmdir "${tomount}" + if echo ${fromdev} | grep -qs loop; then + losetup -d "${fromdev}" + fi return 0 else return 1 @@ -487,56 +320,62 @@ do_snap_copy () try_snap () { + # Look for $snap_label.* in block devices and copy the contents to $snap_mount + # and remember the device and filename for resync on exit in casper.init + snap_label="${1}" snap_mount="${2}" snap_type="${3}" - snapdata=$(find_files "${snap_label}.squashfs ${snap_label}.cpio.gz ${snap_label}.cpz ${snap_label}.gz") + snapdata=$(find_files "${snap_label}.squashfs ${snap_label}.cpio.gz ${snap_label}.ext2") if [ ! -z "${snapdata}" ]; then - snapdev=$(echo ${snapdata} | cut -f1 -d ' ') - snapback=$(echo ${snapdata} | cut -f2 -d ' ') - snapfile=$(echo ${snapdata} | cut -f3 -d ' ') - if echo "${snapfile}" | grep -qs "squashfs" ; then - # squashfs snapshot - if ! do_snap_copy $( get_backing_device "${snapback}/${snapfile}" ) "${snap_mount}" "${snap_type}"; then + snapdev="$(echo ${snapdata} | cut -f1 -d ' ')" + snapback="$(echo ${snapdata} | cut -f2 -d ' ')" + snapfile="$(echo ${snapdata} | cut -f3 -d ' ')" + if echo "${snapfile}" | grep -qs '\(squashfs\|ext2\)'; then + # squashfs or ext2 snapshot + dev=$(get_backing_device "${snapback}/${snapfile}") + if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}"; then log_warning_msg "Impossible to include the ${snapfile} Snapshot" return 1 fi else # cpio.gz snapshot - if ! (cd "${snap_mount}" && zcat "${snapback}/${snapfile}" | cpio -i -u -d ) ; then + if ! (cd "${snap_mount}" && zcat "${snapback}/${snapfile}" | cpio -i -u -d 2>/dev/null) ; then log_warning_msg "Impossible to include the ${snapfile} Snapshot" return 1 fi fi umount "${snapback}" - else # try pure snapshot device better elif.. rework all that routine - if ! do_snap_copy $(find_cow_device "${snap_label}") "${snap_mount}" "${snap_type}"; then + else + dev=$(find_cow_device "${snap_label}") + if [ -b ${dev} ]; then + if echo "${dev}" | grep -qs loop; then + # strange things happens, user confused? + snaploop=$( losetup ${dev} | awk '{print $3}' | tr -d '()' ) + snapfile=$(basename ${snaploop}) + snapdev=$(cat /proc/mounts | awk '{print $2,$1}' | grep -es "^$( dirname ${snaploop} )" | cut -f2 -d ' ') + else + snapdev="${dev}" + fi + if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}" ; then + log_warning_msg "Impossible to include the ${snap_label} Snapshot" + return 1 + else + if [ -n "${snapfile}" ]; then + # it was a loop device, user confused + umount ${snapdev} + fi + fi + else log_warning_msg "Impossible to include the ${snap_label} Snapshot" return 1 fi fi - echo "export ${snap_type}SNAP=${snapdev}:${snapfile}" >> /etc/casper.conf # for resync on reboot/halt + echo "export ${snap_type}SNAP="${snap_mount}":${snapdev}:${snapfile}" >> /etc/casper.conf # for resync on reboot/halt return 0 } -do_others_persistences () -{ - # directly mount /home - # FIXME: add a custom mounts configurable system - homecow=$(find_cow_device "${home_persistence}" ) - if [ -b "${homecow}" ]; then - mount ${homecow} -t $(get_fstype "${homecow}") -o rw "${rootmnt}/home" - export HOMEMOUNTED=1 - else - [ "$quiet" != "y" ] && log_warning_msg "Unable to find the persistent home medium" - fi - - # Look for snapshots to copy in - try_snap "${root_snapshot}" "${rootmnt}" "ROOT" - try_snap "${home_snapshot}" "${rootmnt}/home" "HOME" -} - setup_unionfs() { image_directory="$1" rootmnt="$2" @@ -585,7 +424,7 @@ setup_unionfs() { cow_fstype="tmpfs" # Looking for "${root_persistence}" device or file - if [ ! -z "${PERSISTENT}" ]; then + if [ -n "${PERSISTENT}" ]; then cowprobe=$(find_cow_device "${root_persistence}") if [ -b "${cowprobe}" ]; then cowdevice=${cowprobe} @@ -600,11 +439,22 @@ setup_unionfs() { mount -t unionfs -o dirs=/cow=rw:$rofsstring unionfs "$rootmnt" || panic "Unionfs mount failed" # Adding other custom mounts - if [ ! -z "${PERSISTENT}" ]; then - do_others_persistences + if [ -n "${PERSISTENT}" ]; then + # directly mount /home + # FIXME: add a custom mounts configurable system + homecow=$(find_cow_device "${home_persistence}" ) + if [ -b "${homecow}" ]; then + mount -t $(get_fstype "${homecow}") -o rw "${homecow}" "${rootmnt}/home" + export HOMEMOUNTED=1 # used to proper calculate free space in do_snap_copy() + else + [ "$quiet" != "y" ] && log_warning_msg "Unable to find the persistent home medium" + fi + # Look for other snapshots to copy in + try_snap "${root_snapshot_label}" "${rootmnt}" "ROOT" + try_snap "${home_snapshot_label}" "${rootmnt}/home" "HOME" fi - if [ ! -z "${SHOWMOUNTS}" ]; then + if [ -n "${SHOWMOUNTS}" ]; then for d in ${rofslist}; do mkdir -p "${rootmnt}/casper/${d##*/}" case d in @@ -617,8 +467,8 @@ setup_unionfs() { fi # shows cow fs on /cow for use by casper-snapshot - mkdir -p "$rootmnt/cow" - mount -o bind /cow "$rootmnt/cow" + mkdir -p "${rootmnt}/cow" + mount -o bind /cow "${rootmnt}/cow" } check_dev () diff --git a/scripts/casper-bottom/02etc_casper_conf b/scripts/casper-bottom/02etc_casper_conf index 7c4d08d..9e6deff 100644 --- a/scripts/casper-bottom/02etc_casper_conf +++ b/scripts/casper-bottom/02etc_casper_conf @@ -1,6 +1,9 @@ #!/bin/sh PREREQ="" +DESCRIPTION="Copying config on real root fs..." + +. /scripts/casper-functions prereqs() { @@ -15,13 +18,14 @@ prereqs) ;; esac - +log_begin_msg "$DESCRIPTION" + if [ -f /etc/casper.conf ] ; then if [ ! -z "${CASPERCONF}" ]; then # Updating casper.conf sed -i -e 's/\(USERNAME="\).*"/\1'"${USERNAME}"'"/g' \ -e 's/\(USERFULLNAME="\).*"/\1'"${USERFULLNAME}"'"/g' \ - -e 's/\(HOST="\).*"/\1'"${HOST}"'"/g' /etc/casper.conf + -e 's/\(HOSTNAME="\).*"/\1'"${HOSTNAME}"'"/g' /etc/casper.conf fi cp -p /etc/casper.conf /root/etc/casper.conf @@ -29,7 +33,7 @@ else cat </root/etc/casper.conf export USERNAME="$USERNAME" export USERFULLNAME="$USERFULLNAME" -export HOST="$HOST" +export HOSTNAME="$HOSTNAME" EOF fi diff --git a/scripts/casper-bottom/14locales b/scripts/casper-bottom/14locales index 5080df6..12cfc4b 100755 --- a/scripts/casper-bottom/14locales +++ b/scripts/casper-bottom/14locales @@ -26,7 +26,7 @@ elif [ -e /root/etc/environment ]; then # Old locales policy grep_file=/root/etc/environment fi -if [ ! -z "${grep_file}" ]; then +if [ -n "${grep_file}" ]; then locale=$(grep -s 'LANG=' ${grep_file} | sed s/'LANG='// | tr -d '"' ) else grep_file=/root/etc/default/locale @@ -45,11 +45,27 @@ if [ -z "${locale}" ]; then fi if [ "${set_locale}" ]; then + if echo "${locale}" | grep -sqE '^[[:lower:]]{2}$' ; then + # input is like "locale=it", so we will convert and setup also the keyboard + if [ -z "${KBD}" ]; then + # FIXME: look if this keyb is supported + KBD="${locale}" + fi + uploc=$(echo "${locale}" | tr '[a-z]' '[A-Z]') + locale="${locale}_${uploc}.UTF-8" + fi LANG=$(grep "^${locale}" /root/usr/share/i18n/SUPPORTED | grep UTF-8 |sed -e 's, .*,,' -e q) - printf 'LANG="%s"\n' "${LANG}" >> "${grep_file}" + + if [ -z "${LANG}" ]; then + log_warning_message "Locale ${locale} is unsupported." + fi + if [ "${BUILD_SYSTEM}" == "Debian" ]; then + printf 'LANG=%s\n' "${LANG}" >> "${grep_file}" + printf '%s UTF-8\n' "${LANG}" >> /root/etc/locale.gen chroot /root /usr/sbin/locale-gen else + printf 'LANG="%s"\n' "${LANG}" > "${grep_file}" chroot /root /usr/sbin/locale-gen "${LANG}" fi fi diff --git a/scripts/casper-bottom/18hostname b/scripts/casper-bottom/18hostname index 19ac61f..a616488 100755 --- a/scripts/casper-bottom/18hostname +++ b/scripts/casper-bottom/18hostname @@ -20,10 +20,10 @@ esac log_begin_msg "$DESCRIPTION" -echo "$HOST" > /root/etc/hostname +echo "$HOSTNAME" > /root/etc/hostname cat > /root/etc/hosts </dev/null|| echo ${sysdev##*/})" +} + +subdevices() { + sysblock=$1 + r="" + for dev in "${sysblock}" "${sysblock}"/*; do + if [ -e "${dev}/dev" ]; then + r="${r} ${dev}" + fi + done + echo ${r} +} + +where_is_mounted() { + device=$1 + if grep -q "^$device " /proc/mounts; then + grep "^$device " /proc/mounts | read d mountpoint rest + echo $mountpoint + return 0 + fi + return 1 +} + +lastline() { + while read lines ; do + line=${lines} + done + echo "${line}" +} + +base_path () +{ + testpath="${1}" + mounts="$(awk '{print $2}' /proc/mounts)" + testpath="$(busybox realpath ${testpath})" + + while true ; do + if echo "${mounts}" | grep -qs "^${testpath}" ; then + set -- `echo "${mounts}" | grep "^${testpath}" | lastline` + echo ${1} + break + else + testpath=`dirname $testpath` + fi + done +} + +used_fs_size () +{ + # Returns used fs kbytes + 5% more + # You could pass a block device as $1 or the mount point as $2 + + dev="${1}" + mountp="${2}" + + if [ -z "${mountp}" ]; then + mountp=$(where_is_mounted "${dev}") + if [ "$?" -gt 0 ]; then + mountp=/mnt/tmp_fs_size + mkdir -p "${mountp}" + mount -t $(get_fstype "${dev}") -o ro "${dev}" "${mountp}" + doumount=1 + fi + fi + + size=$(du -ks ${mountp} | cut -f1) + size=$(expr ${size} + ${size}/20 ) # FIXME: 5% more to be sure + needed_space=$(expr ${size} * 1024) + + if [ ! -z "${doumount}" ]; then + umount "${mountp}" + rmdir "${mountp}" + fi + echo "${needed_space}" +} + +setup_loop() { + local fspath=$1 + local module=$2 + local pattern=$3 + + modprobe "${MP_QUIET}" -b "$module" + udevsettle + + for loopdev in $pattern; do + if [ "$(cat $loopdev/size)" -eq 0 ]; then + dev=$(sys2dev "${loopdev}") + losetup "$dev" "$fspath" + echo "$dev" + return 0 + fi + done + panic "No loop devices available" +} + +try_mount () +{ + dev="${1}" + mountp="${2}" + opts="${3}" + + if where_is_mounted ${dev} > /dev/null; then + mount -o remount,"${opts}" ${dev} $(where_is_mounted ${dev}) || panic "Remounting failed" + mount -o bind $(where_is_mounted ${dev}) ${mountp} || panic "Cannot bind-mount" + else + mount -t $(get_fstype "${dev}") -o "${opts}" "${dev}" "${mountp}" || panic "Cannot mount ${dev} on ${mountp}" + fi +} + +find_cow_device() { + pers_label="${1}" + cow_backing="/${pers_label}-backing" + for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do + for dev in $(subdevices "${sysblock}"); do + devname=$(sys2dev "${dev}") + if [ "$(/lib/udev/vol_id -l $devname 2>/dev/null)" = "${pers_label}" ]; then + echo "$devname" + return + elif [ "$(get_fstype ${devname})" = "vfat" ]; then # FIXME: all supported block devices should be scanned + mkdir -p "${cow_backing}" + try_mount "${devname}" "${cow_backing}" "rw" + if [ -e "${cow_backing}/${pers_label}" ]; then + echo $(setup_loop "${cow_backing}/${pers_label}" "loop" "/sys/block/loop*") + return 0 + else + umount ${cow_backing} + fi + fi + done + done +} + +find_files() +# return the first of $filenames found on vfat and ext2 devices +# FIXME: merge with above function +{ + filenames="${1}" + snap_backing="/snap-backing" + for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do + for dev in $(subdevices "${sysblock}"); do + devname=$(sys2dev "${dev}") + devfstype="$(get_fstype ${devname})" + if [ "${devfstype}" = "vfat" ] || [ "${devfstype}" = "ext2" ] ; then # FIXME: all supported block devices should be scanned + mkdir -p "${snap_backing}" + try_mount "${devname}" "${snap_backing}" "ro" + for filename in ${filenames}; do + if [ -e "${snap_backing}/${filename}" ]; then + echo "${devname} ${snap_backing} ${filename}" + return 0 + fi + done + umount ${snap_backing} + fi + done + done +} + + -- 2.1.4