X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=scripts%2Flive;h=96ab63a044df0261739a8080648a0d3ee21003c2;hb=088e23d8225c53f92bc12125d95a11e165869a9a;hp=a174cdd19067e1637dca30479eea5f40b4cc7e49;hpb=bac2a1816f3d8688a21866d3205274c592d32b2f;p=live-boot-grml.git diff --git a/scripts/live b/scripts/live index a174cdd..96ab63a 100755 --- a/scripts/live +++ b/scripts/live @@ -21,6 +21,17 @@ HOSTNAME="host" mkdir -p "${mountpoint}" +# Create /etc/mtab for debug purpose and future syncs +if [ ! -d /etc ] +then + mkdir /etc/ +fi + +if [ ! -f /etc/mtab ] +then + touch /etc/mtab +fi + [ -f /etc/live.conf ] && . /etc/live.conf export USERNAME USERFULLNAME HOSTNAME @@ -38,6 +49,35 @@ Arguments () for ARGUMENT in $(cat /proc/cmdline) do case "${ARGUMENT}" in + skipconfig) + NOACCESSIBILITY="Yes" + NOAPPARMOR="Yes" + NOAPTCDROM="Yes" + NOAUTOLOGIN="Yes" + NOCONSOLEKEYBOARD="Yes" + NOFASTBOOT="Yes" + NOFSTAB="Yes" + NOGNOMEPANEL="Yes" + NOHOSTS="Yes" + NOJOCKEY="Yes" + NOKPERSONALIZER="Yes" + NOLANGUAGESELECTOR="Yes" + NOLOCALES="Yes" + NONETWORKING="Yes" + NOPOLKITCONF="Yes" + NOPOWERMANAGEMENT="Yes" + NOPROGRAMCRASHES="Yes" + NOSUDO="Yes" + NOTIMEZONE="Yes" + NOUPDATENOTIFIER="Yes" + NOUSER="Yes" + NOXAUTOCONFIG="Yes" + NOXAUTOLOGIN="Yes" + NOXSCREENSAVER="Yes" + + export NOACCESSIBILITY NOAPPARMOR NOAPTCDROM NOAUTOLOGIN NOCONSOLEKEYBOARD NOFASTBOOT NOFSTAB NOGNOMEPANEL NOHOSTS NOJOCKEY NOKPERSONALIZER NOLANGUAGESELECTOR NOLOCALES NONETWORKING NOPOLKITCONF NOPOWERMANAGEMENT NOPROGRAMCRASHES NOSUDO NOTIMEZONE NOUPDATENOTIFIER NOUSER NOXAUTOCONFIG NOXAUTOLOGIN NOXSCREENSAVER + ;; + access=*) ACCESS="${ARGUMENT#access=}" export ACCESS @@ -55,22 +95,47 @@ Arguments () set -x ;; + ethdevice=*) + DEVICE="${ARGUMENT#ethdevice=}" + export DEVICE + ;; + fetch=*) FETCH="${ARGUMENT#fetch=}" export FETCH ;; + forcepersistentfsck) + FORCEPERSISTENTFSCK="Yes" + export FORCEPERSISTENTFSCK + ;; + hook=*) HOOK="${ARGUMENT#hook=}" export HOOK ;; + ftpfs=*) + FTPFS="${ARGUMENT#ftpfs=}" + export FTPFS + ;; + + httpfs=*) + HTTPFS="${ARGUMENT#httpfs=}" + export HTTPFS + ;; + hostname=*) HOSTNAME="${ARGUMENT#hostname=}" LIVECONF="changed" export HOSTNAME LIVECONF ;; + isofrom=*|fromiso=*) + FROMISO="${ARGUMENT#*=}" + export FROMISO + ;; + username=*) USERNAME="${ARGUMENT#username=}" LIVECONF="changed" @@ -88,6 +153,11 @@ Arguments () export IGNORE_UUID ;; + integrity-check) + INTEGRITY_CHECK="Yes" + export INTEGRITY_CHECK + ;; + ip=*) STATICIP="${ARGUMENT#ip=}" @@ -154,6 +224,12 @@ Arguments () export LIVE_MEDIA_TIMEOUT ;; + language=*|debian-installer/language=*) + language=${x#debian-installer/language=} + locale="$(lang2locale "$language")" + set_locale="true" + ;; + locale=*|debian-installer/locale=*) LOCALE="${ARGUMENT#*=}" export LOCALE @@ -259,9 +335,9 @@ Arguments () export NOPROGRAMCRASHES ;; - norestrictedmanager) - NORESTRICTEDMANAGER="Yes" - export NORESTRICTEDMANAGER + nojockey) + NOJOCKEY="Yes" + export NOJOCKEY ;; nosudo) @@ -269,9 +345,9 @@ Arguments () export NOSUDO ;; - noswap) - NOSWAP="Yes" - export NOSWAP + swapon) + SWAPON="Yes" + export SWAPON ;; noupdatenotifier) @@ -299,11 +375,37 @@ Arguments () export PERSISTENT ;; + persistent=*) + PERSISTENT="${ARGUMENT#persistent=}" + if [ -z "${PERSISTENT}" ] + then + PERSISTENT="Yes" + fi + export PERSISTENT + ;; + + persistent-path=*) + PERSISTENT_PATH="${ARGUMENT#persistent-path=}" + export PERSISTENT_PATH + ;; + + persistent-subtext=*) + root_persistence="${root_persistence}-${ARGUMENT#persistent-subtext=}" + home_persistence="${home_persistence}-${ARGUMENT#persistent-subtext=}" + root_snapshot_label="${root_snapshot_label}-${ARGUMENT#persistent-subtext=}" + home_snapshot_label="${home_snapshot_label}-${ARGUMENT#persistent-subtext=}" + ;; + nopersistent) NOPERSISTENT="Yes" export NOPERSISTENT ;; + quickusbmodules) + QUICKUSBMODULES="Yes" + export QUICKUSBMODULES + ;; + preseed/file=*|file=*) LOCATION="${ARGUMENT#*=}" export LOCATION @@ -317,14 +419,14 @@ Arguments () url=*) location="${ARGUMENT#url=}" - mount -n -o bind /sys /root/sys - mount -n -o bind /proc /root/proc - mount -n -o bind /dev /root/dev + mount -o bind /sys /root/sys + mount -o bind /proc /root/proc + mount -o bind /dev /root/dev mkdir -p /root/var/run/network - chroot /root dhclient eth0 + [ "${NETBOOT}" ] || chroot /root dhclient eth0 chroot /root wget -P /tmp "${location}" - chroot /root ifconfig eth0 down + [ "${NETBOOT}" ] || chroot /root ifconfig eth0 down umount /root/sys umount /root/proc @@ -345,6 +447,11 @@ Arguments () export SHOWMOUNTS ;; + silent) + SILENT="Yes" + export SILENT + ;; + textonly) TEXTONLY="Yes" export TEXTONLY @@ -386,6 +493,11 @@ Arguments () export PLAIN_ROOT ;; + skipunion) + SKIP_UNION_MOUNTS="Yes" + export SKIP_UNION_MOUNTS + ;; + root=*) ROOT="${ARGUMENT#root=}" export ROOT @@ -440,7 +552,7 @@ Arguments () if [ -z "${UNIONTYPE}" ] then - UNIONTYPE="unionfs" + UNIONTYPE="aufs" export UNIONTYPE fi } @@ -451,7 +563,7 @@ is_live_path () if [ -d "${DIRECTORY}"/"${LIVE_MEDIA_PATH}" ] then - for FILESYSTEM in squashfs ext2 ext3 xfs dir jffs2 + for FILESYSTEM in squashfs ext2 ext3 ext4 xfs dir jffs2 do if [ "$(echo ${DIRECTORY}/${LIVE_MEDIA_PATH}/*.${FILESYSTEM})" != "${DIRECTORY}/${LIVE_MEDIA_PATH}/*.${FILESYSTEM}" ] then @@ -473,7 +585,7 @@ matches_uuid () path="${1}" uuid="$(cat /conf/uuid.conf)" - for try_uuid_file in "${mountpoint}/.disk/casper-uuid"* + for try_uuid_file in "${path}/.disk/live-uuid"* do [ -e "${try_uuid_file}" ] || continue @@ -491,8 +603,8 @@ matches_uuid () get_backing_device () { case "${1}" in - *.squashfs|*.ext2|*.ext3|*.jffs2) - echo $(setup_loop "${1}" "loop" "/sys/block/loop*" '0' "${LIVE_MEDIA_ENCRYPTION}") + *.squashfs|*.ext2|*.ext3|*.ext4|*.jffs2) + echo $(setup_loop "${1}" "loop" "/sys/block/loop*" '0' "${LIVE_MEDIA_ENCRYPTION}" "${2}") ;; *.dir) @@ -522,19 +634,20 @@ mount_images_in_directory () { directory="${1}" rootmnt="${2}" - mac="${3}" + mac="${3}" if match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.squashfs" || match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext2" || match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext3" || + match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext4" || match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.jffs2" || match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.dir" then [ -n "${mac}" ] && adddirectory="${directory}/${LIVE_MEDIA_PATH}/${mac}" setup_unionfs "${directory}/${LIVE_MEDIA_PATH}" "${rootmnt}" "${adddirectory}" else - : + panic "No supported filesystem images found at /${LIVE_MEDIA_PATH}." fi } @@ -542,7 +655,10 @@ is_nice_device () { sysfs_path="${1#/sys}" - if /lib/udev/path_id "${sysfs_path}" | grep -E -q "ID_PATH=(usb|pci-[^-]*-[ide|scsi|usb])" + if /lib/udev/path_id "${sysfs_path}" | grep -E -q "ID_PATH=(usb|pci-|platform-mmc)" + then + return 0 + elif echo "${sysfs_path}" | grep -q '^/block/vd[a-z]$' then return 0 fi @@ -550,20 +666,6 @@ is_nice_device () return 1 } -is_supported_fs () -{ - # FIXME: do something better like the scan of supported filesystems - fstype="${1}" - - case ${fstype} in - vfat|iso9660|udf|ext2|ext3|ntfs|jffs2) - return 0 - ;; - esac - - return 1 -} - copy_live_to () { copyfrom="${1}" @@ -572,7 +674,7 @@ copy_live_to () if [ -z "${MODULETORAM}" ] then - size=$(fs_size "" ${copyfrom} "used") + size=$(fs_size "" ${copyfrom}/${LIVE_MEDIA_PATH} "used") else MODULETORAMFILE="${copyfrom}/${LIVE_MEDIA_PATH}/${MODULETORAM}" @@ -588,7 +690,7 @@ copy_live_to () if [ "${copytodev}" = "ram" ] then # copying to ram: - freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - ) ) + freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( awk '/\/dev/console + rsync -a --progress ${MODULETORAMFILE} ${copyto} 1>/dev/console # copy only the filesystem module + else + cp ${MODULETORAMFILE} ${copyto} # copy only the filesystem module + fi else - cp -a ${copyfrom}/* ${copyto} # "cp -a" from busybox also copies hidden files + if [ -x /bin/rsync ] + then + echo " * Copying whole medium to RAM" 1>/dev/console + rsync -a --progress ${copyfrom}/* ${copyto} 1>/dev/console # "cp -a" from busybox also copies hidden files + else + mkdir -p ${copyto}/${LIVE_MEDIA_PATH} + cp -a ${copyfrom}/${LIVE_MEDIA_PATH}/* ${copyto}/${LIVE_MEDIA_PATH} # "cp -a" from busybox also copies hidden files + fi fi - livefs_root umount ${copyfrom} - mount -r --move ${copyto} ${copyfrom} + mount -r -o move ${copyto} ${copyfrom} fi rmdir ${copyto} @@ -648,8 +762,8 @@ do_netmount () modprobe -q af_packet # For DHCP - udevtrigger - udevsettle + udevadm trigger + udevadm settle ipconfig ${DEVICE} | tee /netboot.config @@ -659,12 +773,21 @@ do_netmount () [ -z ${HOSTNAME} ] && HOSTNAME=${OLDHOSTNAME} export HOSTNAME + # Check if we have a network device at all + if ! ls /sys/class/net/eth0 > /dev/null 2>&1 && \ + ! ls /sys/class/net/wlan0 > /dev/null 2>&1 && \ + ! ls /sys/class/net/ath0 > /dev/null 2>&1 && \ + ! ls /sys/class/net/ra0 > /dev/null 2>&1 + then + panic "No supported network device found, maybe a non-mainline driver is required." + fi + if [ "${NFSROOT}" = "auto" ] then NFSROOT=${ROOTSERVER}:${ROOTPATH} fi - if [ -n "${FETCH}" ] && do_httpmount + if ( [ -n "${FETCH}" ] || [ -n "${HTTPFS}" ] || [ -n "${FTPFS}" ] ) && do_httpmount then rc=0 return ${rc} @@ -675,7 +798,7 @@ do_netmount () NFSROOT=${ROOTSERVER}:${NFSROOT} fi - [ "${quiet}" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}" + log_begin_msg "Trying netboot from ${NFSROOT}" if [ "${NETBOOT}" != "nfs" ] && do_cifsmount then @@ -687,27 +810,70 @@ do_netmount () rc=0 fi - [ "${quiet}" != "y" ] && log_end_msg + log_end_msg return ${rc} } do_httpmount () { rc=1 - extension=$(echo "${FETCH}" | sed 's/\(.*\)\.\(.*\)/\2/') - - case "${extension}" in - squashfs|tgz|tar) - [ "${quiet}" != "y" ] && log_begin_msg "Trying wget ${FETCH} -O ${mountpoint}/$(basename ${FETCH})" - mkdir -p "${mountpoint}/${LIVE_MEDIA_PATH}" - wget "${FETCH}" -O "${mountpoint}/${LIVE_MEDIA_PATH}/$(basename ${FETCH})" - [ ${?} -eq 0 ] && rc=0 - [ "${extension}" = "tgz" ] && live_dest="ram" - ;; + dest="${mountpoint}/${LIVE_MEDIA_PATH}" + mount -t ramfs ram "${mountpoint}" + mkdir -p "${dest}" - *) - [ "${quiet}" != "y" ] && log_begin_msg "Unrecognized archive extension for ${FETCH}" - esac + for webfile in HTTPFS FTPFS FETCH + do + url="$(eval echo \"\$\{${webfile}\}\")" + extension="$(echo "${url}" | sed 's/\(.*\)\.\(.*\)/\2/')" + + if [ -n "$url" ] + then + case "${extension}" in + squashfs|tgz|tar) + if [ "${webfile}" = "FETCH" ] + then + case "$url" in + tftp*) + ip="$(dirname $url | sed -e 's|tftp://||g' -e 's|/.*$||g')" + rfile="$(echo $url | sed -e "s|tftp://$ip||g")" + lfile="$(basename $url)" + log_begin_msg "Trying tftp -g -b 10240 -r $rfile -l ${dest}/$lfile $ip" + tftp -g -b 10240 -r $rfile -l ${dest}/$lfile $ip + ;; + + *) + log_begin_msg "Trying wget ${url} -O ${dest}/$(basename ${url})" + wget "${url}" -O "${dest}/$(basename ${url})" + ;; + esac + else + log_begin_msg "Trying to mount ${url} on ${dest}/$(basename ${url})" + if [ "${webfile}" = "FTPFS" ] + then + FUSE_MOUNT="curlftpfs" + url="$(dirname ${url})" + else + FUSE_MOUNT="httpfs" + fi + modprobe fuse + $FUSE_MOUNT "${url}" "${dest}" + fi + [ ${?} -eq 0 ] && rc=0 + [ "${extension}" = "tgz" ] && live_dest="ram" + break + ;; + + *) + log_begin_msg "Unrecognized archive extension for ${url}" + ;; + esac + fi + done + + if [ ${rc} != 0 ] + then + umount "${mountpoint}" + fi return ${rc} } @@ -723,13 +889,15 @@ do_nfsmount () NFSOPTS="" fi - [ "${quiet}" != "y" ] && log_begin_msg "Trying nfsmount -o nolock -o ro ${NFSOPTS} ${NFSROOT} ${mountpoint}" + log_begin_msg "Trying nfsmount -o nolock -o ro ${NFSOPTS} ${NFSROOT} ${mountpoint}" - # FIXME: This for loop is an ugly HACK round an nfs bug - for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 + # FIXME: This while loop is an ugly HACK round an nfs bug + i=0 + while [ "$i" -lt 60 ] do nfsmount -o nolock -o ro ${NFSOPTS} "${NFSROOT}" "${mountpoint}" && rc=0 && break sleep 1 + i="$(($i + 1))" done return ${rc} @@ -748,7 +916,7 @@ do_cifsmount () CIFSOPTS="${NFSOPTS}" fi - [ "${quiet}" != "y" ] && log_begin_msg "Trying mount.cifs ${NFSROOT} ${mountpoint} ${CIFSOPTS}" + log_begin_msg "Trying mount.cifs ${NFSROOT} ${mountpoint} ${CIFSOPTS}" modprobe -q cifs if mount.cifs "${NFSROOT}" "${mountpoint}" "${CIFSOPTS}" @@ -772,10 +940,10 @@ do_snap_copy () # look for free mem 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}') + todev=$(awk -v pat="$(base_path ${todir})" '$2 == pat { print $1 }' /proc/mounts) + freespace=$(df -k | awk '/'${todev}'/{print $4}') else - freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - )) + freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( awk '/\/dev/null) + cd "${snap_mount}" + zcat "${snapback}/${snapfile}" | /bin/cpio --extract --preserve-modification-time --no-absolute-filenames --sparse --unconditional --make-directories > /dev/null 2>&1 + RES=$? + if [ "${RES}" != "0" ] then - log_warning_msg "Impossible to include the ${snapfile} Snapshot" - return 1 + log_warning_msg "failure to \"zcat ${snapback}/${snapfile} | /bin/cpio --extract --preserve-modification-time --no-absolute-filenames --sparse --unconditional --make-directories\"" fi + cd "${OLDPWD}" fi - umount "${snapback}" - else - dev=$(find_cow_device "${snap_label}") + umount "${snapback}" || log_warning_msg "failure to \"umount ${snapback}\"" - if [ -b ${dev} ] + if [ "${RES}" != "0" ] 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 + log_warning_msg "Impossible to include the ${snapfile} Snapshot file" + 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 + elif [ -b "${snapdata}" ] + then + # Try to find if it could be a snapshot partition + dev="${snapdata}" + log_success_msg "found snapshot ${snap_type} device on ${dev}" + if echo "${dev}" | grep -qs loop + then + # strange things happens, user confused? + snaploop=$( losetup ${dev} | awk '{print $3}' | tr -d '()' ) + snapfile=$(basename ${snaploop}) + snapdev=$(awk -v pat="$( dirname ${snaploop})" '$2 == pat { print $1 }' /proc/mounts) else - log_warning_msg "Impossible to include the ${snap_label} Snapshot" + snapdev="${dev}" + fi + + if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}" + then + log_warning_msg "Impossible to include the ${snap_type} 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_type} Snapshot" + return 1 fi echo "export ${snap_type}SNAP="${snap_mount}":${snapdev}:${snapfile}" >> /etc/live.conf # for resync on reboot/halt @@ -901,50 +1098,34 @@ setup_unionfs () # Let's just mount the read-only file systems first rofsstring="" rofslist="" - minor_kernel_version=$(uname -r|cut -c 5-|sed 's/[^0-9].*//') - if [ "${NETBOOT}" = "nfs" ] && [ "${minor_kernel_version}" -lt 22 ] + if [ "${UNIONTYPE}" = "aufs" ] then - # go aroung a bug in nfs-unionfs locking for unionfs <= 1.4 - roopt="nfsro" - elif [ "${UNIONTYPE}" = "aufs" ] - then - roopt="rr" + roopt="rr,noxino" else roopt="ro" fi - # Read image names from ${MODULE}.module if it exists - if [ -e "${image_directory}/filesystem.${MODULE}.module" ] + if [ -z "${PLAIN_ROOT}" ] then - for IMAGE in $(cat ${image_directory}/filesystem.${MODULE}.module) - do - image_string="${image_string} ${image_directory}/${IMAGE}" - done - elif [ -e "${image_directory}/${MODULE}.module" ] - then - for IMAGE in $(cat ${image_directory}/${MODULE}.module) - do - image_string="${image_string} ${image_directory}/${IMAGE}" - done - else - # ${MODULE}.module does not exist, create a list of images - for FILESYSTEM in squashfs ext2 ext3 xfs jffs2 dir - do - for IMAGE in "${image_directory}"/*."${FILESYSTEM}" + # Read image names from ${MODULE}.module if it exists + if [ -e "${image_directory}/filesystem.${MODULE}.module" ] + then + for IMAGE in $(cat ${image_directory}/filesystem.${MODULE}.module) do - if [ -e "${IMAGE}" ] - then - image_string="${image_string} ${IMAGE}" - fi + image_string="${image_string} ${image_directory}/${IMAGE}" done - done - - if [ -n "${addimage_directory}" ] && [ -d "${addimage_directory}" ] + elif [ -e "${image_directory}/${MODULE}.module" ] then - for FILESYSTEM in squashfs ext2 ext3 xfs jffs2 dir + for IMAGE in $(cat ${image_directory}/${MODULE}.module) + do + image_string="${image_string} ${image_directory}/${IMAGE}" + done + else + # ${MODULE}.module does not exist, create a list of images + for FILESYSTEM in squashfs ext2 ext3 ext4 xfs jffs2 dir do - for IMAGE in "${addimage_directory}"/*."${FILESYSTEM}" + for IMAGE in "${image_directory}"/*."${FILESYSTEM}" do if [ -e "${IMAGE}" ] then @@ -952,40 +1133,80 @@ setup_unionfs () fi done done - fi - # Now sort the list - image_string="$(echo ${image_string} | sed -e 's/ /\n/g' | sort )" - fi + if [ -n "${addimage_directory}" ] && [ -d "${addimage_directory}" ] + then + for FILESYSTEM in squashfs ext2 ext3 ext4 xfs jffs2 dir + do + for IMAGE in "${addimage_directory}"/*."${FILESYSTEM}" + do + if [ -e "${IMAGE}" ] + then + image_string="${image_string} ${IMAGE}" + fi + done + done + fi + + # Now sort the list + image_string="$(echo ${image_string} | sed -e 's/ /\n/g' | sort )" + fi [ -n "${MODULETORAMFILE}" ] && image_string="${image_directory}/$(basename ${MODULETORAMFILE})" - mkdir -p "${croot}" + mkdir -p "${croot}" - for image in ${image_string} - do - imagename=$(basename "${image}") + for image in ${image_string} + do + imagename=$(basename "${image}") - if [ -d "${image}" ] - then - # it is a plain directory: do nothing - rofsstring="${image}=${roopt}:${rofsstring}" - rofslist="${image} ${rofslist}" - elif [ -f "${image}" ] - then - backdev=$(get_backing_device "${image}") - fstype=$(get_fstype "${backdev}") + export image devname + maybe_break live-realpremount + log_begin_msg "Running /scripts/live-realpremount" + run_scripts /scripts/live-realpremount + log_end_msg - if [ "${fstype}" = "unknown" ] + if [ -d "${image}" ] then - panic "Unknown file system type on ${backdev} (${image})" - fi + # it is a plain directory: do nothing + rofsstring="${image}=${roopt}:${rofsstring}" + rofslist="${image} ${rofslist}" + elif [ -f "${image}" ] + then + 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}") - mkdir -p "${croot}/${imagename}" - echo "debug: Can not mount backdev ${backdev} (image = ${image}) on croot/imagename ${croot}/${imagename}" - mount -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}" - fi - done + if [ "${fstype}" = "unknown" ] + then + panic "Unknown file system type on ${backdev} (${image})" + fi + + if [ -z "${fstype}" ] + then + fstype="${imagename##*.}" + log_warning_msg "Unknown file system type on ${backdev} (${image}), assuming ${fstype}." + fi + + mkdir -p "${croot}/${imagename}" + log_begin_msg "Mounting \"${image}\" on \"${croot}${imagename}\" via \"${backdev}\"" + mount -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 + fi + done + else + # we have a plain root system + mkdir -p "${croot}/filesystem" + log_begin_msg "Mounting \"${image_directory}\" on \"${croot}/filesystem\"" + mount -t $(get_fstype "${image_directory}") -o ro,noatime "${image_directory}" "${croot}/filesystem" || panic "Can not mount ${image_directory} on ${croot}/filesystem" && rofsstring="${croot}/filesystem=${roopt}:${rofsstring}" && rofslist="${croot}/filesystem ${rofslist}" + # probably broken: + mount -o bind ${croot}/filesystem $mountpoint + log_end_msg + fi rofsstring=${rofsstring%:} @@ -994,40 +1215,73 @@ setup_unionfs () # Looking for "${root_persistence}" device or file if [ -n "${PERSISTENT}" ] && [ -z "${NOPERSISTENT}" ] then - # Load USB modules - num_block=$(ls -l /sys/block | wc -l) - for module in sd_mod uhci-hcd ehci-hcd ohci-hcd usb-storage - do - modprobe -q -b ${module} - done + if [ -z "${QUICKUSBMODULES}" ] + then + # Load USB modules + num_block=$(ls -l /sys/block | wc -l) + for module in sd_mod uhci-hcd ehci-hcd ohci-hcd usb-storage + do + modprobe -q -b ${module} + done - udevtrigger - udevsettle + udevadm trigger + udevadm settle - # For some reason, udevsettle does not block in this scenario, - # so we sleep for a little while. - # - # See https://bugs.launchpad.net/ubuntu/+source/casper/+bug/84591 - for timeout in 5 4 3 2 1 - do - sleep 1 + # For some reason, udevsettle does not block in this scenario, + # so we sleep for a little while. + # + # See https://bugs.launchpad.net/ubuntu/+source/casper/+bug/84591 + for timeout in 5 4 3 2 1 + do + sleep 1 - if [ $(ls -l /sys/block | wc -l) -gt ${num_block} ] - then - break - fi - done + if [ $(ls -l /sys/block | wc -l) -gt ${num_block} ] + then + break + fi + done + fi + # search for label and files (this could be hugely optimized) cowprobe=$(find_cow_device "${root_persistence}") + if [ -b "${cowprobe}" ] + then + # Blacklist /cow device, to avoid inconsistent setups for overlapping snapshots + # makes sense to have both persistence for /cow and /home mounted, maybe also with + # snapshots to be sure to really store some e.g key config files, + # but not on the same media + blacklistdev="${cowprobe}" + PERSISTENCE_IS_ON="1" + export PERSISTENCE_IS_ON + fi + # homecow just mount something on /home, this should be generalized some way + homecow=$(find_cow_device "${home_persistence}" "${blacklistdev}") + if [ -b "${homecow}" ] + then + PERSISTENCE_IS_ON="1" + export PERSISTENCE_IS_ON + fi + root_snapdata=$(find_snap "${root_snapshot_label}" "${blacklistdev}") + # This second type should be removed when snapshot will get smarter, + # hence when "/etc/live-snapshot*list" will be supported also by + # ext2|ext3|ext4|jffs2 snapshot types. + home_snapdata=$(find_snap "${home_snapshot_label}" "${blacklistdev}") if [ -b "${cowprobe}" ] then cowdevice=${cowprobe} cow_fstype=$(get_fstype "${cowprobe}") + cow_mountopt="rw,noatime" + + if [ "${FORCEPERSISTENTFSCK}" = "Yes" ] + then + fsck -y ${cowdevice} + fi else - [ "${quiet}" != "y" ] && log_warning_msg "Unable to find the persistent medium" + log_warning_msg "Unable to find the persistent medium" cowdevice="tmpfs" cow_fstype="tmpfs" + cow_mountopt="rw,noatime,mode=755" fi elif [ -n "${NFS_COW}" ] && [ -z "${NOPERSISTENT}" ] then @@ -1051,17 +1305,18 @@ setup_unionfs () else cowdevice="tmpfs" cow_fstype="tmpfs" + cow_mountopt="rw,noatime,mode=755" fi if [ "${cow_fstype}" = "nfs" ] then - [ "${quiet}" != "y" ] && log_begin_msg \ + log_begin_msg \ "Trying nfsmount ${nfs_cow_opts} ${cowdevice} /cow" nfsmount ${nfs_cow_opts} ${cowdevice} /cow || \ - panic "Can not mount ${cowdevice} on /cow" + panic "Can not mount ${cowdevice} (n: ${cow_fstype}) on /cow" else - mount -t ${cow_fstype} -o rw,noatime ${cowdevice} /cow || \ - panic "Can not mount ${cowdevice} on /cow" + mount -t ${cow_fstype} -o ${cow_mountopt} ${cowdevice} /cow || \ + panic "Can not mount ${cowdevice} (o: ${cow_fstype}) on /cow" fi rofscount=$(echo ${rofslist} |wc -w) @@ -1077,8 +1332,12 @@ setup_unionfs () mount --bind ${exposedrootfs} ${rootmnt} || \ panic "bind mount of ${exposedrootfs} failed" - cow_dirs='/var/tmp /var/lock /var/run /var/log /var/spool - /home /var/lib/live' + if [ -z "${SKIP_UNION_MOUNTS}" ] + then + cow_dirs='/var/tmp /var/lock /var/run /var/log /var/spool /home /var/lib/live' + else + cow_dirs='' + fi for dir in ${cow_dirs}; do mkdir -p /cow${dir} @@ -1094,7 +1353,11 @@ setup_unionfs () ${rootmnt} failed with option noatime,dirs=/cow=rw:${rofsstring}" fi + # Correct the permissions of /: + chmod 0755 "${rootmnt}" + # tmpfs file systems + touch /etc/fstab mkdir -p "${rootmnt}/live" mount -t tmpfs tmpfs ${rootmnt}/live @@ -1103,19 +1366,19 @@ setup_unionfs () 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,noatime "${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" + 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" + try_snap "${root_snapdata}" "${rootmnt}" "ROOT" + # This second type should be removed when snapshot grow smarter + try_snap "${home_snapdata}" "${rootmnt}/home" "HOME" fi if [ -n "${SHOWMOUNTS}" ] @@ -1130,7 +1393,7 @@ setup_unionfs () ;; *) - mount --move "${d}" "${rootmnt}/live/${d##*/}" + mount -o move "${d}" "${rootmnt}/live/${d##*/}" ;; esac done @@ -1138,7 +1401,7 @@ setup_unionfs () # shows cow fs on /cow for use by live-snapshot mkdir -p "${rootmnt}/live/cow" - mount -o move /cow "${rootmnt}/live/cow" + mount -o move /cow "${rootmnt}/live/cow" >/dev/null 2>&1 || mount -o bind /cow "${rootmnt}/live/cow" || log_warning_msg "Unable to move or bind /cow to ${rootmnt}/live/cow" } check_dev () @@ -1147,11 +1410,35 @@ check_dev () devname="${2}" skip_uuid_check="${3}" + # support for fromiso=.../isofrom=.... + if [ -n "$FROMISO" ] + then + mkdir /isofrom + ISO_DEVICE="$(echo $FROMISO | sed 's|\(/dev/[a-z]*[0-9]*\).*|\1|')" + mount "$ISO_DEVICE" /isofrom + ISO_NAME="$(echo $FROMISO | sed 's|/dev/[a-z]*[0-9]*/||')" + loopdevname=$(setup_loop "/isofrom/${ISO_NAME}" "loop" "/sys/block/loop*" "" '') + devname="${loopdevname}" + fi + if [ -z "${devname}" ] then devname=$(sys2dev "${sysdev}") fi + if [ -d "${devname}" ] + then + mount -o bind "${devname}" $mountpoint || continue + + if is_live_path $mountpoint + then + echo $mountpoint + return 0 + else + umount $mountpoint + fi + fi + if [ -n "${LIVE_MEDIA_OFFSET}" ] then loopdevname=$(setup_loop "${devname}" "loop" "/sys/block/loop*" "${LIVE_MEDIA_OFFSET}" '') @@ -1186,15 +1473,6 @@ find_livefs () { timeout="${1}" - # first look at the one specified in the command line - if [ ! -z "${LIVE_MEDIA}" ] - then - if check_dev "null" "${LIVE_MEDIA}" "skip_uuid_check" - then - return 0 - fi - fi - # don't start autodetection before timeout has expired if [ -n "${LIVE_MEDIA_TIMEOUT}" ] then @@ -1204,8 +1482,59 @@ find_livefs () fi fi + # first look at the one specified in the command line + case "${LIVE_MEDIA}" in + removable-usb) + for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -vE "/(loop|ram|dm-|fd)") + do + if [ "$(cat ${sysblock}/removable)" = "1" ] + then + if readlink ${sysblock} | grep -q usb || + readlink ${sysblock}/device | grep -q usb # linux < 2.6.29 + then + for dev in $(subdevices "${sysblock}") + do + if check_dev "${dev}" + then + return 0 + fi + done + fi + fi + done + return 1 + ;; + + removable) + for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -vE "/(loop|ram|dm-|fd)") + do + if [ "$(cat ${sysblock}/removable)" = "1" ] + then + for dev in $(subdevices "${sysblock}") + do + if check_dev "${dev}" + then + return 0 + fi + done + fi + done + return 1 + ;; + + *) + if [ ! -z "${LIVE_MEDIA}" ] + then + if check_dev "null" "${LIVE_MEDIA}" "skip_uuid_check" + then + return 0 + fi + fi + ;; + esac + # or do the scan of block devices - for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram | grep -v 'dm-') + for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -vE "/(loop|ram|dm-|fd)") do devname=$(sys2dev "${sysblock}") fstype=$(get_fstype "${devname}") @@ -1228,6 +1557,7 @@ find_livefs () elif [ "${fstype}" = "squashfs" -o \ "${fstype}" = "ext2" -o \ "${fstype}" = "ext3" -o \ + "${fstype}" = "ext4" -o \ "${fstype}" = "jffs2" ] then # This is an ugly hack situation, the block device has @@ -1247,12 +1577,39 @@ set_usplash_timeout () if [ -x /sbin/usplash_write ] then /sbin/usplash_write "TIMEOUT 120" + else if [ -x /sbin/splashy_update ] ; then + /sbin/splashy_update "TIMEOUT 120" + fi ; fi +} + +integrity_check () +{ + media_mountpoint="${1}" + + log_begin_msg "Checking media integrity" + + cd ${media_mountpoint} + /bin/md5sum -c md5sum.txt < /dev/tty8 > /dev/tty8 + RC="${?}" + + log_end_msg + + if [ "${RC}" -eq 0 ] + then + log_success_msg "Everything ok, will reboot in 10 seconds." + sleep 10 + cd / + umount ${media_mountpoint} + sync + echo u > /proc/sysrq-trigger + echo b > /proc/sysrq-trigger + else + panic "Not ok, a media defect is likely, switch to VT8 for details." fi } mountroot () { - if [ -x /scripts/local-top/cryptroot ]; then /scripts/local-top/cryptroot fi @@ -1261,20 +1618,27 @@ mountroot () exec 7>&2 exec > live.log exec 2>&1 + tail -f live.log >&7 & + tailpid="${!}" + + # Ensure 'panic' function is overridden + . /scripts/live-functions Arguments set_usplash_timeout - [ "${quiet}" != "y" ] && log_begin_msg "Running /scripts/live-premount" + + maybe_break live-premount + log_begin_msg "Running /scripts/live-premount" run_scripts /scripts/live-premount - [ "${quiet}" != "y" ] && log_end_msg + log_end_msg # Needed here too because some things (*cough* udev *cough*) # changes the timeout set_usplash_timeout - if [ ! -z "${NETBOOT}" ] || [ ! -z "${FETCH}" ] + if [ ! -z "${NETBOOT}" ] || [ ! -z "${FETCH}" ] || [ ! -z "${HTTPFS}" ] || [ ! -z "${FTPFS}" ] then if do_netmount then @@ -1289,7 +1653,8 @@ mountroot () livefs_root=${ROOT} else # Scan local devices for the image - for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 + i=0 + while [ "$i" -lt 60 ] do livefs_root=$(find_livefs ${i}) @@ -1299,6 +1664,7 @@ mountroot () fi sleep 1 + i="$(($i + 1))" done fi fi @@ -1308,6 +1674,11 @@ mountroot () panic "Unable to find a medium containing a live file system" fi + if [ "${INTEGRITY_CHECK}" ] + then + integrity_check "${livefs_root}" + fi + if [ "${TORAM}" ] then live_dest="ram" @@ -1323,7 +1694,16 @@ mountroot () log_end_msg fi - if [ -n "${MODULETORAMFILE}" ] + # if we do not unmount the ISO we can't run "fsck /dev/ice" later on + # because the mountpoint is left behind in /proc/mounts, so let's get + # rid of it when running from RAM + if [ -n "$FROMISO" ] && [ "${TORAM}" ] + then + losetup -d /dev/loop0 + grep -q /isofrom /proc/mounts && umount /isofrom + fi + + if [ -n "${MODULETORAMFILE}" ] || [ -n "${PLAIN_ROOT}" ] then setup_unionfs "${livefs_root}" "${rootmnt}" else @@ -1335,12 +1715,13 @@ mountroot () log_end_msg maybe_break live-bottom - [ "${quiet}" != "y" ] && log_begin_msg "Running /scripts/live-bottom" + log_begin_msg "Running /scripts/live-bottom\n" run_scripts /scripts/live-bottom - [ "${quiet}" != "y" ] && log_end_msg + log_end_msg exec 1>&6 6>&- exec 2>&7 7>&- - cp live.log "${rootmnt}/var/log/" + kill ${tailpid} + [ -w "${rootmnt}/var/log/" ] && cp live.log "${rootmnt}/var/log/" 2>/dev/null }