X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=scripts%2Flive-helpers;h=8822125e0242b290acbf3f31abba13b273a55222;hb=bb77d0efe779cd9e2e245e7f56f3abbd2baa7d72;hp=c1efeec149082728ae18a956fb5b6f77f017c464;hpb=931f580302ca3a121d3be602a49e732d5189b667;p=live-boot-grml.git diff --git a/scripts/live-helpers b/scripts/live-helpers index c1efeec..8822125 100644 --- a/scripts/live-helpers +++ b/scripts/live-helpers @@ -15,6 +15,406 @@ else udevinfo='udevinfo' fi +root_overlay_label="full-ov" +old_root_overlay_label="live-rw" +old_home_overlay_label="home-rw" +custom_overlay_label="custom-ov" +root_snapshot_label="live-sn" +old_root_snapshot_label="live-sn" +home_snapshot_label="home-sn" +persistence_list="live.persist" + +Arguments () +{ + PRESEEDS="" + LOCATIONS="" + + for ARGUMENT in $(cat /proc/cmdline) + do + case "${ARGUMENT}" in + skipconfig) + NOACCESSIBILITY="Yes" + NOFASTBOOT="Yes" + NOFSTAB="Yes" + NONETWORKING="Yes" + + export NOACCESSIBILITY NOFASTBOOT NOFSTAB NONETWORKING + ;; + + access=*) + ACCESS="${ARGUMENT#access=}" + export ACCESS + ;; + + console=*) + DEFCONSOLE="${ARGUMENT#*=}" + export DEFCONSOLE + ;; + + BOOTIF=*) + BOOTIF="${x#BOOTIF=}" + ;; + + debug) + DEBUG="Yes" + export DEBUG + + set -x + ;; + + dhcp) + # Force dhcp even while netbooting + # Use for debugging in case somebody works on fixing dhclient + DHCP="Force"; + export DHCP + ;; + + nodhcp) + unset DHCP + ;; + + ethdevice=*) + DEVICE="${ARGUMENT#ethdevice=}" + ETHDEVICE="${DEVICE}" + export DEVICE ETHDEVICE + ;; + + ethdevice-timeout=*) + ETHDEV_TIMEOUT="${ARGUMENT#ethdevice-timeout=}" + export ETHDEV_TIMEOUT + ;; + + fetch=*) + FETCH="${ARGUMENT#fetch=}" + export FETCH + ;; + + forcepersistentfsck) + FORCEPERSISTENTFSCK="Yes" + export FORCEPERSISTENTFSCK + ;; + + ftpfs=*) + FTPFS="${ARGUMENT#ftpfs=}" + export FTPFS + ;; + + httpfs=*) + HTTPFS="${ARGUMENT#httpfs=}" + export HTTPFS + ;; + + iscsi=*) + ISCSI="${ARGUMENT#iscsi=}" + #ip:port - separated by ; + ISCSI_PORTAL="${ISCSI%;*}" + if echo "${ISCSI_PORTAL}" | grep -q , ; then + ISCSI_SERVER="${ISCSI_PORTAL%,*}" + ISCSI_PORT="${ISCSI_PORTAL#*,}" + fi + #target name + ISCSI_TARGET="${ISCSI#*;}" + export ISCSI ISCSI_PORTAL ISCSI_TARGET ISCSI_SERVER ISCSI_PORT + ;; + + isofrom=*|fromiso=*) + FROMISO="${ARGUMENT#*=}" + export FROMISO + ;; + + ignore_uuid) + IGNORE_UUID="Yes" + export IGNORE_UUID + ;; + + integrity-check) + INTEGRITY_CHECK="Yes" + export INTEGRITY_CHECK + ;; + + ip=*) + STATICIP="${ARGUMENT#ip=}" + + if [ -z "${STATICIP}" ] + then + STATICIP="frommedia" + fi + + export STATICIP + ;; + + live-getty) + LIVE_GETTY="1" + export LIVE_GETTY + ;; + + live-media=*|bootfrom=*) + LIVE_MEDIA="${ARGUMENT#*=}" + export LIVE_MEDIA + ;; + + live-media-encryption=*|encryption=*) + LIVE_MEDIA_ENCRYPTION="${ARGUMENT#*=}" + export LIVE_MEDIA_ENCRYPTION + ;; + + live-media-offset=*) + LIVE_MEDIA_OFFSET="${ARGUMENT#live-media-offset=}" + export LIVE_MEDIA_OFFSET + ;; + + live-media-path=*) + LIVE_MEDIA_PATH="${ARGUMENT#live-media-path=}" + export LIVE_MEDIA_PATH + ;; + + live-media-timeout=*) + LIVE_MEDIA_TIMEOUT="${ARGUMENT#live-media-timeout=}" + export LIVE_MEDIA_TIMEOUT + ;; + + module=*) + MODULE="${ARGUMENT#module=}" + export MODULE + ;; + + netboot=*) + NETBOOT="${ARGUMENT#netboot=}" + export NETBOOT + ;; + + nfsopts=*) + NFSOPTS="${ARGUMENT#nfsopts=}" + export NFSOPTS + ;; + + nfscow=*) + NFS_COW="${ARGUMENT#nfscow=}" + export NFS_COW + ;; + + noaccessibility) + NOACCESSIBILITY="Yes" + export NOACCESSIBILITY + ;; + + nofastboot) + NOFASTBOOT="Yes" + export NOFASTBOOT + ;; + + nofstab) + NOFSTAB="Yes" + export NOFSTAB + ;; + + nonetworking) + NONETWORKING="Yes" + export NONETWORKING + ;; + + ramdisk-size=*) + ramdisk_size="${ARGUMENT#ramdisk-size=}" + ;; + + swapon) + SWAPON="Yes" + export SWAPON + ;; + + persistent) + PERSISTENT="Yes" + export PERSISTENT + ;; + + persistent-encryption=*) + PERSISTENT_ENCRYPTION="${ARGUMENT#*=}" + export PERSISTENT_ENCRYPTION + ;; + + persistent-media=*) + PERSISTENT_MEDIA="${ARGUMENT#*=}" + export PERSISTENT_MEDIA + ;; + persistent-method=*) + PERSISTENT_METHOD="${ARGUMENT#*=}" + export PERSISTENT_METHOD + ;; + + persistent-path=*) + PERSISTENT_PATH="${ARGUMENT#persistent-path=}" + export PERSISTENT_PATH + ;; + persistent-read-only) + PERSISTENT_READONLY="Yes" + export PERSISTENT_READONLY + ;; + + persistent-storage=*) + PERSISTENT_STORAGE="${ARGUMENT#persistent-storage=}" + export PERSISTENT_STORAGE + ;; + + persistent-subtext=*) + root_overlay_label="${root_overlay_label}-${ARGUMENT#persistent-subtext=}" + old_root_overlay_label="${old_root_overlay_label}-${ARGUMENT#persistent-subtext=}" + old_home_overlay_label="${old_home_overlay_label}-${ARGUMENT#persistent-subtext=}" + custom_overlay_label="${custom_overlay_label}-${ARGUMENT#persistent-subtext=}" + root_snapshot_label="${root_snapshot_label}-${ARGUMENT#persistent-subtext=}" + old_root_snapshot_label="${root_snapshot_label}-${ARGUMENT#persistent-subtext=}" + home_snapshot_label="${home_snapshot_label}-${ARGUMENT#persistent-subtext=}" + ;; + + nopersistent) + NOPERSISTENT="Yes" + export NOPERSISTENT + ;; + + noprompt) + NOPROMPT="Yes" + export NOPROMPT + ;; + + noprompt=*) + NOPROMPT="${ARGUMENT#noprompt=}" + export NOPROMPT + ;; + + quickusbmodules) + QUICKUSBMODULES="Yes" + export QUICKUSBMODULES + ;; + + preseed/file=*|file=*) + LOCATIONS="${ARGUMENT#*=} ${LOCATIONS}" + export LOCATIONS + ;; + + nopreseed) + NOPRESEED="Yes" + export NOPRESEED + ;; + + */*=*) + question="${ARGUMENT%%=*}" + value="${ARGUMENT#*=}" + PRESEEDS="${PRESEEDS}\"${question}=${value}\" " + export PRESEEDS + ;; + + showmounts) + SHOWMOUNTS="Yes" + export SHOWMOUNTS + ;; + + silent) + SILENT="Yes" + export SILENT + ;; + + todisk=*) + TODISK="${ARGUMENT#todisk=}" + export TODISK + ;; + + toram) + TORAM="Yes" + export TORAM + ;; + + toram=*) + TORAM="Yes" + MODULETORAM="${ARGUMENT#toram=}" + export TORAM MODULETORAM + ;; + + exposedroot) + EXPOSED_ROOT="Yes" + export EXPOSED_ROOT + ;; + + plainroot) + PLAIN_ROOT="Yes" + export PLAIN_ROOT + ;; + + skipunion) + SKIP_UNION_MOUNTS="Yes" + export SKIP_UNION_MOUNTS + ;; + + root=*) + ROOT="${ARGUMENT#root=}" + export ROOT + ;; + + union=*) + UNIONTYPE="${ARGUMENT#union=}" + export UNIONTYPE + ;; + esac + done + + # sort of compatibility with netboot.h from linux docs + if [ -z "${NETBOOT}" ] + then + if [ "${ROOT}" = "/dev/nfs" ] + then + NETBOOT="nfs" + export NETBOOT + elif [ "${ROOT}" = "/dev/cifs" ] + then + NETBOOT="cifs" + export NETBOOT + fi + fi + + if [ -z "${MODULE}" ] + then + MODULE="filesystem" + export MODULE + fi + + if [ -z "${UNIONTYPE}" ] + then + UNIONTYPE="aufs" + export UNIONTYPE + fi + + if [ -z "${PERSISTENT_ENCRYPTION}" ] + then + PERSISTENT_ENCRYPTION="none" + export PERSISTENT_ENCRYPTION + elif echo ${PERSISTENT_ENCRYPTION} | grep -qe "\" + then + if ! modprobe dm-crypt + then + log_warning_msg "Unable to load module dm-crypt" + PERSISTENT_ENCRYPTION=$(echo ${PERSISTENT_ENCRYPTION} | sed -e 's/\/dev/null 2>&1 + then + re="^[[:space:]]*device:[[:space:]]*\([^[:space:]]*\)$" + opened_dev=$(cryptsetup status ${name} 2>/dev/null | grep "${re}" | sed "s|${re}|\1|") + if [ "${opened_dev}" = "${dev}" ] + then + luks_device="/dev/mapper/${name}" + echo ${luks_device} + return 0 + else + log_warning_msg "Cannot open luks device ${dev} since ${opened_dev} already is opened with its name" + return 1 + fi + fi + load_keymap while true @@ -346,6 +761,92 @@ open_luks_device () done } +get_gpt_name () { + local dev="${1}" + /sbin/blkid -s PART_ENTRY_NAME -p -o value ${dev} 2>/dev/null +} + +is_gpt_device () { + local dev="${1}" + [ "$(/sbin/blkid -s PART_ENTRY_SCHEME -p -o value ${dev} 2>/dev/null)" = "gpt" ] +} + +probe_for_gpt_name () +{ + local overlays="${1}" + local snapshots="${2}" + local dev="${3}" + + if ! is_gpt_device ${dev} || \ + ( echo ${PERSISTENT_ENCRYPTION} | grep -qve "\" && \ + /sbin/cryptsetup isLuks ${dev} > /dev/null 2>&1 ) + then + return + fi + for label in ${overlays} ${snapshots} + do + if [ "$(get_gpt_name ${dev})" = "${label}" ] + then + echo "${label}=${dev}" + fi + done +} + +probe_for_fs_label () { + local overlays="${1}" + local snapshots="${2}" + local dev="${3}" + + for label in ${overlays} ${snapshots} + do + if [ "$(/sbin/blkid -s LABEL -o value $dev 2>/dev/null)" = "${label}" ] + then + echo "${label}=${dev}" + fi + done +} + +probe_for_file_name () { + local overlays="${1}" + local snapshots="${2}" + local dev="${3}" + + local devfstype="$(get_fstype ${dev})" + local backing="${rootmnt}/live/persistent/$(basename ${dev})" + local ret="" + if is_supported_fs ${devfstype} && mkdir -p "${backing}" && \ + try_mount "${dev}" "${backing}" "rw" "${devfstype}" + then + for label in ${overlays} + do + path=${backing}/${PERSISTENT_PATH}${label} + if [ -f "${path}" ] + then + local loopdev=$(setup_loop "${path}" "loop" "/sys/block/loop*") + ret="${ret} ${label}=${loopdev}" + fi + done + for label in ${snapshots} + do + for ext in squashfs cpio.gz ext2 ext3 ext4 jffs2 + do + path="${PERSISTENT_PATH}${label}.${ext}" + if [ -f "${backing}/${path}" ] + then + ret="${ret} ${label}=${dev}:${backing}:${path}" + fi + done + done + + if [ -n "${ret}" ] + then + echo ${ret} + else + umount ${backing} > /dev/null 2>&1 || true + fi + fi +} + find_persistent_media () { # Scans devices for overlays and snapshots, and returns a whitespace @@ -369,21 +870,27 @@ find_persistent_media () # ${white_list_devices} is non-empty, only devices in it will be # scanned. - overlays="${1}" - snapshots="${2}" - black_listed_devices="${3}" - white_listed_devices="${4}" + local overlays="${1}" + local snapshots="${2}" + local white_listed_devices="${3}" + local ret="" - for dev in $(storage_devices "${black_listed_devices}" "${white_listed_devices}") + for dev in $(storage_devices "" "${white_listed_devices}") do - luks_device="" - - # Checking for a luks device + local result="" + + local real_dev="" + local luks_device="" + # Check if it's a luks device; we'll have to open the device + # in order to probe any filesystem it contains, like we do + # below. do_custom_mounts() also depends on that any luks + # device already has been opened. if echo ${PERSISTENT_ENCRYPTION} | grep -qe "\" && \ - /sbin/cryptsetup isLuks ${dev} + /sbin/cryptsetup isLuks ${dev} >/dev/null 2>&1 then if luks_device=$(open_luks_device "${dev}") then + real_dev="${dev}" dev="${luks_device}" else # skip $dev since we failed/chose not to open it @@ -395,65 +902,55 @@ find_persistent_media () continue fi + # Probe for matching GPT partition names or filesystem labels if echo ${PERSISTENT_STORAGE} | grep -qe "\" then - for label in ${overlays} ${snapshots} - do - if [ "$(/sbin/blkid -s LABEL -o value $dev 2>/dev/null)" = "${label}" ] - then - overlays=$(echo ${overlays} | sed -e "s|\<${label}\>||") - snapshots=$(echo ${snapshots} | sed -e "s|\<${label}\>||") - echo "${label}=${dev}" - # skip to the next device - continue 2 - fi - done + local gpt_dev="${dev}" + if [ -n "${luks_device}" ] + then + # When we probe GPT partitions we need to look + # at the real device, not the virtual, opened + # luks device + gpt_dev="${real_dev}" + fi + result=$(probe_for_gpt_name "${overlays}" "${snapshots}" ${gpt_dev}) + if [ -n "${result}" ] + then + ret="${ret} ${result}" + continue + fi + + result=$(probe_for_fs_label "${overlays}" "${snapshots}" ${dev}) + if [ -n "${result}" ] + then + ret="${ret} ${result}" + continue + fi fi + # Probe for files with matching name on mounted partition if echo ${PERSISTENT_STORAGE} | grep -qe "\" then - devfstype="$(get_fstype ${dev})" - overlay_on_dev="" - snapshot_on_dev="" - backing="/$(basename ${dev})-backing" - mkdir -p "${backing}" - if is_supported_fs ${devfstype} && try_mount "${dev}" "${backing}" "rw" "${devfstype}" + result=$(probe_for_file_name "${overlays}" "${snapshots}" ${dev}) + if [ -n "${result}" ] then - for label in ${overlays} - do - path=${backing}/${PERSISTENT_PATH}${label} - if [ -f "${path}" ] - then - overlays=$(echo ${overlays} | sed -e "s|\<${label}\>||") - overlay_on_dev="yes" - echo "${label}=$(setup_loop "${path}" "loop" "/sys/block/loop*")" - fi - done - - for label in ${snapshots} - do - for ext in squashfs cpio.gz ext2 ext3 ext4 jffs2 - do - path="${PERSISTENT_PATH}${label}.${ext}" - if [ -f "${backing}/${path}" ] - then - snapshots=$(echo ${snapshots} | sed -e "s|\<${label}\>||") - snapshot_on_dev="yes" - echo "${label}=${dev}:${backing}:${path}" - fi - done - done - fi - if [ -z "${overlay_on_dev}" ] - then - umount ${backing} > /dev/null 2>&1 || true - if [ -z "${snapshot_on_dev}" ] && [ -n "${luks_device}" ] && /sbin/cryptsetup status "${luks_device}" 1> /dev/null - then - /sbin/cryptsetup luksClose "${luks_device}" - fi + ret="${ret} ${result}" + continue fi fi + + # Close luks device if it isn't used + if [ -z "${result}" ] && [ -n "${luks_device}" ] && \ + /sbin/cryptsetup status "${luks_device}" 1> /dev/null 2>&1 + then + /sbin/cryptsetup luksClose "${luks_device}" + fi done + + if [ -n "${ret}" ] + then + echo ${ret} + fi } get_mac () @@ -591,8 +1088,8 @@ link_files () then mkdir -p "${dest}" prev="$(dirname "${dest}")" - chown $(stat -c %u:%g "${prev}") "${dest}" - chmod $(stat -c %a "${prev}") "${dest}" + chown --reference "${prev}" "${dest}" + chmod --reference "${prev}" "${dest}" fi link_files "${src}" "${dest}" "${src_mask}" else @@ -685,23 +1182,38 @@ get_custom_mounts () { then continue fi + local device_name="$(basename ${device})" - local backing="${persistent_backing}/${device_name}" - mkdir -p "${backing}" - local device_fstype="$(get_fstype ${device})" - if [ -z "${PERSISTENT_READONLY}" ] + local device_used="" + # $device may already have been mounted by + # probe_for_file_name() in find_persistent_media() ... + local backing=$(where_is_mounted ${device}) + if [ -z "${backing}" ] then - device_mount_opts="rw,noatime" - else - device_mount_opts="ro,noatime" + # ... otherwise we mount it now + backing="${persistent_backing}/${device_name}" + mkdir -p "${backing}" + local device_fstype="$(get_fstype ${device})" + if [ -z "${PERSISTENT_READONLY}" ] + then + device_mount_opts="rw,noatime" + else + device_mount_opts="ro,noatime" + fi + if ! mount -t "${device_fstype}" -o "${device_mount_opts}" "${device}" "${backing}" >/dev/null 2>&1 + then + log_warning_msg "Could not mount persistent media ${device} (${device_fstype})" + fi fi - local device_used="" - mount -t "${device_fstype}" -o "${device_mount_opts}" "${device}" "${backing}" local include_list="${backing}/${persistence_list}" if [ ! -r "${include_list}" ] then - umount "${backing}" - rmdir "${backing}" + umount "${backing}" >/dev/null 2>&1 + rmdir "${backing}" >/dev/null 2>&1 + if /sbin/cryptsetup status ${device_name} >/dev/null 2>&1 + then + /sbin/cryptsetup luksClose "${device_name}" + fi continue fi @@ -775,16 +1287,11 @@ get_custom_mounts () { # We sort the list according to destination so we're sure that # we won't hide a previous mount. We also ignore duplicate # destinations in a more or less arbitrary way. - [ -e "${bindings}" ] && sort -k2 -sbu ${bindings} >> ${custom_mounts} - rm ${bindings} + [ -e "${bindings}" ] && sort -k2 -sbu ${bindings} >> ${custom_mounts} && rm ${bindings} # After all mounts are considered we add symlinks so they # won't be hidden by some mount. - [ -e "${links}" ] && sort -k2 -sbu ${links} >> ${custom_mounts} - rm ${links} - - rm -f ${bindings} ${links} 2> /dev/null - echo ${custom_mounts} + [ -e "${links}" ] && sort -k2 -sbu ${links} >> ${custom_mounts} && rm ${links} } do_custom_mounts () { @@ -918,3 +1425,32 @@ do_custom_mounts () { export PERSISTENCE_IS_ON done < ${custom_mounts} } + +fix_home_rw_compatibility () +{ + local device=${1} + + if [ -n "${PERSISTENT_READONLY}" ] + then + return + fi + + local backing="$(where_is_mounted ${device})" + if [ -z "${backing}" ] + then + backing="${rootmnt}/live/persistent/$(basename ${device})" + mkdir -p "${backing}" + local device_fstype="$(get_fstype ${device})" + local device_mount_opts="rw,noatime" + if ! mount -t "${device_fstype}" -o "${device_mount_opts}" "${device}" "${backing}" >/dev/null 2>&1 + then + return + fi + + local include_list="${backing}/${persistence_list}" + if [ ! -r "${include_list}" ] + then + echo "# home-rw backwards compatibility: +. /home" > "${include_list}" + fi +}