5 export PATH=/root/usr/bin:/root/usr/sbin:/root/bin:/root/sbin:/usr/bin:/usr/sbin:/bin:/sbin
9 root_persistence="casper-rw"
10 home_persistence="home-rw"
11 root_snapshot="casper-sn"
12 home_snapshot="home-sn"
15 USERFULLNAME="Live session user"
21 [ -f /etc/casper.conf ] && . /etc/casper.conf
23 export USERNAME USERFULLNAME HOST BUILD_SYSTEM
25 if [ "${BUILD_SYSTEM}" == "Ubuntu" ]; then
33 # looking for casper specifics options as kernel parameters
34 for x in $(cat /proc/cmdline); do
37 export USERFULLNAME=${x#userfullname=}
38 export CASPERCONF="changed"
41 export HOST=${x#host=}
42 export CASPERCONF="changed"
45 export USERNAME=${x#username=}
46 export CASPERCONF="changed"
49 export NETBOOT=${x#netboot=} ;;
53 export TODISK=${x#todisk=} ;;
55 export SHOWMOUNTS=1 ;;
57 export PERSISTENT=1 ;;
60 if [ "${STATICIP}" == "" ]; then
65 export CASPERGETTY=1 ;;
67 export DEFCONSOLE=$(sed -e 's%.*console=%console=%' /proc/cmdline) ;;
69 export LIVEMEDIA=${x#bootfrom=} ;;
71 export LIVEMEDIA=${x#live-media=} ;;
72 debian-installer/locale=*)
73 export LOCALE=${x#debian-installer/locale=} ;;
75 export LOCALE=${x#locale=} ;;
77 export KBD=${x#kbd-chooser/method=} ;;
79 export KBD=${x#kbd=} ;;
80 console-setup/layoutcode=*)
81 export CSLAYOUT=${x#console-setup/layoutcode=} ;;
82 console-setup/variantcode=*)
83 export CSVARIANT=${x#console-setup/variantcode=} ;;
84 console-setup/modelcode=*)
85 export CSMODEL=${x#console-setup/modelcode=} ;;
89 # sort of compatibility with netboot.h from linux docs
90 if [ -z "${NETBOOT}" ]; then
91 if [ "${ROOT}" == "/dev/nfs" ]; then
94 elif [ "${ROOT}" == "/dev/cifs" ]; then
103 if [ -d "$path/casper" ]; then
104 if [ "$(echo $path/casper/*.cloop)" != "$path/casper/*.cloop" ] ||
105 [ "$(echo $path/casper/*.squashfs)" != "$path/casper/*.squashfs" ] ||
106 [ "$(echo $path/casper/*.ext2)" != "$path/casper/*.ext2" ] ||
107 [ "$(echo $path/casper/*.dir)" != "$path/casper/*.dir" ]; then
117 for dev in "${sysblock}" "${sysblock}"/*; do
118 if [ -e "${dev}/dev" ]; then
125 get_backing_device() {
128 echo $(setup_loop "$1" "cloop" "/sys/block/cloop*")
131 echo $(setup_loop "$1" "loop" "/sys/block/loop*")
137 panic "Unrecognized casper filesystem: $1"
142 match_files_in_dir() {
143 # Does any files match pattern $1 ?
146 if [ "$(echo $pattern)" != "$pattern" ]; then
152 mount_images_in_directory() {
155 if match_files_in_dir "$directory/casper/*.cloop"; then
156 # Let's hope there's just one matching *.cloop... FIXME
157 setup_devmapper $(get_backing_device "$directory/casper/*.cloop") "$rootmnt"
158 elif match_files_in_dir "$directory/casper/*.squashfs" ||
159 match_files_in_dir "$directory/casper/*.ext2" ||
160 match_files_in_dir "$directory/casper/*.dir"; then
161 setup_unionfs "$directory/casper" "$rootmnt"
169 echo "/dev/$(udevinfo -q name -p ${sysdev} 2>/dev/null|| echo ${sysdev##*/})"
177 modprobe "${MP_QUIET}" -b "$module"
180 for loopdev in $pattern; do
181 if [ "$(cat $loopdev/size)" -eq 0 ]; then
182 dev=$(sys2dev "${loopdev}")
183 losetup "$dev" "$fspath"
188 panic "No loop devices available"
195 if [ "$FSTYPE" != "unknown" ]; then
199 /lib/udev/vol_id -t $1 2>/dev/null
206 modprobe "${MP_QUIET}" -b dm-mod
208 COW_NAME="casper-cow"
210 BACKING_FILE_SIZE=$(blockdev --getsize "$backdev")
211 MAX_COW_SIZE=$(blockdev --getsize "$COW_DEVICE")
212 CHUNK_SIZE=8 # sectors
214 if [ -z "$COW_SIZE" -o "$COW_SIZE" -gt "$MAX_COW_SIZE" ]; then
215 COW_SIZE=$MAX_COW_SIZE
218 echo "0 $COW_SIZE linear $COW_DEVICE 0" | dmsetup create $COW_NAME
220 echo "0 $BACKING_FILE_SIZE snapshot $backdev /dev/mapper/$COW_NAME p $CHUNK_SIZE" | \
221 dmsetup create casper-snapshot
222 if [ "$(get_fstype $backdev)" = "unknown" ]; then
223 panic "Unknown file system type on $backdev"
225 mount -t $(get_fstype "$backdev") /dev/mapper/casper-snapshot $rootmnt || panic "Can not mount /dev/mapper/casper/snapshot on $rootmnt"
227 mkdir -p "$rootmnt/rofs"
228 echo "0 $BACKING_FILE_SIZE linear $backdev 0" | dmsetup create casper-backing
229 mount -t $(get_fstype "$backdev") /dev/mapper/casper-backing "$rootmnt/rofs"
233 sysfs_path="${1#/sys}"
234 if /lib/udev/path_id "${sysfs_path}" | grep -E -q "ID_PATH=(usb|pci-[^-]*-[ide|scsi|usb])"; then
242 # FIXME: do something better like the scan of supported filesystems
245 vfat|iso9660|udf|ext2|ext3|ntfs)
254 if grep -q "^$device " /proc/mounts; then
255 grep "^$device " /proc/mounts | read d mountpoint rest
264 # Returns used fs kbytes + 5% more
265 # You could pass a block device as $1 or the mount point as $2
270 if [ -z "${mountp}" ]; then
271 mountp=$(where_is_mounted "${dev}")
272 if [ "$?" -gt 0 ]; then
273 mountp=/mnt/tmp_fs_size
275 mount -t $(get_fstype "${dev}") -o ro "${dev}" "${mountp}"
280 size=$(du -ks ${mountp} | cut -f1)
281 size=$(expr ${size} + ${size}/20 ) # FIXME: 5% more to be sure
282 needed_space=$(expr ${size} * 1024)
284 if [ ! -z "${doumount}" ]; then
288 echo "${needed_space}"
294 copyto="${copyfrom}_swap"
296 size=$(used_fs_size "null" "${copyfrom}")
298 if [ "${copytodev}" = "ram" ]; then
300 freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - ) )
301 mount_options="-o size=${size}k"
306 # it should be a writable block device
307 if [ -b "${copytodev}" ]; then
309 freespace="$(df -k ${copytodev} | grep -s ${copytodev} | awk '{print $4}')"
310 fstype="$(get_fstype ${devname})"
316 if [ ! ${freespace} -lt ${size} ] ; then
317 [ "$quiet" != "y" ] && log_begin_msg "Not enough free ${free_string} to copy live media in ${copytodev}."
318 [ "$quiet" != "y" ] && log_end_msg
323 [ "$quiet" != "y" ] && log_begin_msg "Copying live media to ${copytodev}..."
325 mount -t "${fstype}" ${mount_options} "${dev}" "${copyto}"
326 cp -a ${copyfrom}/* ${copyto} # "cp -a" from busybox also copies hidden files
328 mount -r -o move ${copyto} ${copyfrom}
330 [ "$quiet" != "y" ] && log_end_msg
340 if where_is_mounted ${dev} > /dev/null; then
341 mount -o remount,"${opts}" ${dev} $(where_is_mounted ${dev}) || panic "Remounting failed"
342 mount -o bind $(where_is_mounted ${dev}) ${mountp} || panic "Cannot bind-mount"
344 mount -t $(get_fstype "${dev}") -o "${opts}" "${dev}" "${mountp}" || panic "Cannot mount ${dev} on ${mountp}"
350 cow_backing="/${pers_label}-backing"
351 for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do
352 for dev in $(subdevices "${sysblock}"); do
353 devname=$(sys2dev "${dev}")
354 if [ "$(/lib/udev/vol_id -l $devname 2>/dev/null)" = "${pers_label}" ]; then
357 elif [ "$(get_fstype ${devname})" = "vfat" ]; then # FIXME: all supported block devices should be scanned
358 mkdir -p "${cow_backing}"
359 try_mount "${devname}" "${cow_backing}" "rw"
360 if [ -e "${cow_backing}/${pers_label}" ]; then
361 echo $(setup_loop "${cow_backing}/${pers_label}" "loop" "/sys/block/loop*")
364 umount ${cow_backing}
372 # return the first of $filenames found on vfat and ext2 devices
373 # FIXME: merge with above function
376 snap_backing="/snap-backing"
377 for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do
378 for dev in $(subdevices "${sysblock}"); do
379 devname=$(sys2dev "${dev}")
380 devfstype="$(get_fstype ${devname})"
381 if [ "${devfstype}" = "vfat" ] || [ "${devfstype}" = "ext2" ] ; then # FIXME: all supported block devices should be scanned
382 mkdir -p "${snap_backing}"
383 try_mount "${devname}" "${snap_backing}" "ro"
384 for filename in ${filenames}; do
385 if [ -e "${snap_backing}/${filename}" ]; then
386 echo "${devname} ${snap_backing} ${filename}"
390 umount ${snap_backing}
399 modprobe "${MP_QUIET}" af_packet # For DHCP
401 ipconfig ${DEVICE} /tmp/net-${DEVICE}.conf
403 if [ "${NFSROOT}" = "auto" ]; then
404 NFSROOT=${ROOTSERVER}:${ROOTPATH}
407 [ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}"
409 if [ "${NETBOOT}" != "nfs" ] && do_cifsmount ; then
411 elif do_nfsmount ; then
417 [ "$quiet" != "y" ] && log_end_msg
423 modprobe "${MP_QUIET}" nfs
424 if [ -z "${NFSOPTS}" ]; then
428 [ "$quiet" != "y" ] && log_begin_msg "Trying nfsmount -o nolock -o ro ${NFSOPTS} ${NFSROOT} ${mountpoint}"
429 # FIXME: This for loop is an ugly HACK round an nfs bug
430 for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13; do
431 nfsmount -o nolock -o ro ${NFSOPTS} "${NFSROOT}" "${mountpoint}" && rc=0 && break
439 if [ -x "/sbin/mount.cifs" ]; then
440 if [ -z "${NFSOPTS}" ]; then
441 CIFSOPTS="-ouser=root,password="
443 CIFSOPTS="${NFSOPTS}"
446 [ "$quiet" != "y" ] && log_begin_msg "Trying mount.cifs ${NFSROOT} ${mountpoint} ${CIFSOPTS}"
447 modprobe "${MP_QUIET}" cifs
449 if mount.cifs "${NFSROOT}" "${mountpoint}" "${CIFSOPTS}" ; then
462 size=$(used_fs_size "${fromdev}")
464 if [ -b "${fromdev}" ]; then
466 if [ ! -z "${HOMEMOUNTED}" ] && [ "${snap_type}" = "HOME" ]; then
467 freespace="$(df -k ${copytodev} | grep -s ${copytodev} | awk '{print $4}')"
469 freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - ))
471 tomount="/mnt/tmpsnap"
472 mkdir -p "${tomount}"
473 mount -t $(get_fstype "${fromdev}") -o ro "${fromdev}" "${tomount}"
474 cp -a "${tomount}"/* ${todir}
477 if echo ${fromdev} | grep -qs loop; then
478 losetup -d "${fromdev}"
484 [ "$quiet" != "y" ] && log_warning_msg "Unable to find the snapshot ${snap_type} medium"
494 snapdata=$(find_files "${snap_label}.squashfs ${snap_label}.cpio.gz ${snap_label}.cpz ${snap_label}.gz")
495 if [ ! -z "${snapdata}" ]; then
496 snapdev=$(echo ${snapdata} | cut -f1 -d ' ')
497 snapback=$(echo ${snapdata} | cut -f2 -d ' ')
498 snapfile=$(echo ${snapdata} | cut -f3 -d ' ')
499 if echo "${snapfile}" | grep -qs "squashfs" ; then
501 if ! do_snap_copy $( get_backing_device "${snapback}/${snapfile}" ) "${snap_mount}" "${snap_type}"; then
502 log_warning_msg "Impossible to include the ${snapfile} Snapshot"
507 if ! (cd "${snap_mount}" && zcat "${snapback}/${snapfile}" | cpio -i -u -d ) ; then
508 log_warning_msg "Impossible to include the ${snapfile} Snapshot"
513 else # try pure snapshot device better elif.. rework all that routine
514 if ! do_snap_copy $(find_cow_device "${snap_label}") "${snap_mount}" "${snap_type}"; then
515 log_warning_msg "Impossible to include the ${snap_label} Snapshot"
519 echo "export ${snap_type}SNAP=${snapdev}:${snapfile}" >> /etc/casper.conf # for resync on reboot/halt
523 do_others_persistences ()
525 # directly mount /home
526 # FIXME: add a custom mounts configurable system
527 homecow=$(find_cow_device "${home_persistence}" )
528 if [ -b "${homecow}" ]; then
529 mount ${homecow} -t $(get_fstype "${homecow}") -o rw "${rootmnt}/home"
532 [ "$quiet" != "y" ] && log_warning_msg "Unable to find the persistent home medium"
535 # Look for snapshots to copy in
536 try_snap "${root_snapshot}" "${rootmnt}" "ROOT"
537 try_snap "${home_snapshot}" "${rootmnt}/home" "HOME"
544 modprobe "${MP_QUIET}" -b unionfs
546 # run-init can't deal with images in a subdir, but we're going to
547 # move all of these away before it runs anyway. No, we're not,
548 # put them in / since move-mounting them into / breaks mono and
553 # Let's just mount the read-only file systems first
556 if [ "${NETBOOT}" == "nfs" ] ; then
557 roopt="nfsro" # go aroung a bug in nfs-unionfs locking
563 for image_type in "ext2" "squashfs" "dir" ; do
564 for image in "${image_directory}"/*."${image_type}"; do
565 imagename=$(basename "${image}")
566 if [ -d "${image}" ]; then
567 # it is a plain directory: do nothing
568 rofsstring="${image}=${roopt}:${rofsstring}"
569 rofslist="${image} ${rofslist}"
570 elif [ -f "${image}" ]; then
571 backdev=$(get_backing_device "$image")
572 fstype=$(get_fstype "${backdev}")
573 if [ "${fstype}" = "unknown" ]; then
574 panic "Unknown file system type on ${backdev} (${image})"
576 mkdir -p "${croot}/${imagename}"
577 mount -t "${fstype}" -o ro "${backdev}" "${croot}/${imagename}" || panic "Can not mount $backdev ($image) on ${croot}/${imagename}" && rofsstring="${croot}/${imagename}=${roopt}:${rofsstring}" && rofslist="${croot}/${imagename} ${rofslist}"
581 rofsstring=${rofsstring%:}
587 # Looking for "${root_persistence}" device or file
588 if [ ! -z "${PERSISTENT}" ]; then
589 cowprobe=$(find_cow_device "${root_persistence}")
590 if [ -b "${cowprobe}" ]; then
591 cowdevice=${cowprobe}
592 cow_fstype=$(get_fstype "${cowprobe}")
594 [ "$quiet" != "y" ] && log_warning_msg "Unable to find the persistent medium"
598 mount ${cowdevice} -t ${cow_fstype} -o rw /cow || panic "Can not mount $cowdevice on /cow"
600 mount -t unionfs -o dirs=/cow=rw:$rofsstring unionfs "$rootmnt" || panic "Unionfs mount failed"
602 # Adding other custom mounts
603 if [ ! -z "${PERSISTENT}" ]; then
604 do_others_persistences
607 if [ ! -z "${SHOWMOUNTS}" ]; then
608 for d in ${rofslist}; do
609 mkdir -p "${rootmnt}/casper/${d##*/}"
611 *.dir) # do nothing # mount -o bind "${d}" "${rootmnt}/casper/${d##*/}"
613 *) mount -o move "${d}" "${rootmnt}/casper/${d##*/}"
619 # shows cow fs on /cow for use by casper-snapshot
620 mkdir -p "$rootmnt/cow"
621 mount -o bind /cow "$rootmnt/cow"
628 if [ -z "${devname}" ]; then
629 devname=$(sys2dev "${sysdev}")
631 fstype=$(get_fstype "${devname}")
632 if is_supported_fs ${fstype}; then
633 mount -t ${fstype} -o ro "${devname}" $mountpoint || continue
634 if is_casper_path $mountpoint; then
645 # first look at the one specified in the command line
646 if [ ! -z "${LIVEMEDIA}" ]; then
647 if check_dev "null" "${LIVEMEDIA}"; then
651 # or do the scan of block devices
652 for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram); do
653 devname=$(sys2dev "${sysblock}")
654 fstype=$(get_fstype "${devname}")
655 if /lib/udev/cdrom_id ${devname} > /dev/null; then
656 if check_dev "null" "${devname}" ; then
659 elif is_nice_device "${sysblock}" ; then
660 for dev in $(subdevices "${sysblock}"); do
661 if check_dev "${dev}" ; then
665 elif [ "${fstype}" = "squashfs" -o \
666 "${fstype}" = "ext3" ] -o \
667 "${fstype}" = "ext2" ]; then
668 # This is an ugly hack situation, the block device has
669 # an image directly on it. It's hopefully
670 # casper, so take it and run with it.
671 ln -s "${devname}" "${devname}.${fstype}"
672 echo "${devname}.${fstype}"
680 if [ -x /sbin/usplash_write ]; then
681 /sbin/usplash_write "PULSATE"
685 set_usplash_timeout() {
686 if [ -x /sbin/usplash_write ]; then
687 /sbin/usplash_write "TIMEOUT 120"
700 [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/casper-premount"
702 run_scripts /scripts/casper-premount
703 [ "$quiet" != "y" ] && log_end_msg
705 # Needed here too because some things (*cough* udev *cough*)
706 # changes the timeout
710 if [ ! -z "${NETBOOT}" ]; then
711 if do_netmount ; then
712 livefs_root="${mountpoint}"
714 panic "Unable to find a the network rootfs live file system"
717 # Scan local devices for the image
718 for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13; do
719 livefs_root=$(find_livefs)
720 if [ ! -z "${livefs_root}" ]; then
727 if [ -z "${livefs_root}" ]; then
728 panic "Unable to find a medium containing a live file system"
731 if [ ! -z "${TORAM}" ]; then
732 copy_live_to "${livefs_root}" "ram"
733 elif [ ! -z "${TODISK}" ]; then
734 copy_live_to "${livefs_root}" "${TODISK}"
737 mount_images_in_directory "${livefs_root}" "${rootmnt}"
741 maybe_break casper-bottom
742 [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/casper-bottom"
745 run_scripts /scripts/casper-bottom
746 [ "$quiet" != "y" ] && log_end_msg
750 cp casper.log "${rootmnt}/var/log/"