9         if [ -d "${DIRECTORY}"/"${LIVE_MEDIA_PATH}" ]
 
  11                 for FILESYSTEM in squashfs ext2 ext3 ext4 xfs dir jffs2
 
  13                         if [ "$(echo ${DIRECTORY}/${LIVE_MEDIA_PATH}/*.${FILESYSTEM})" != "${DIRECTORY}/${LIVE_MEDIA_PATH}/*.${FILESYSTEM}" ]
 
  25         if [ "${IGNORE_UUID}" ] || [ ! -e /conf/uuid.conf ]
 
  31         uuid="$(cat /conf/uuid.conf)"
 
  33         for try_uuid_file in "${path}/.disk/live-uuid"*
 
  35                 [ -e "${try_uuid_file}" ] || continue
 
  37                 try_uuid="$(cat "${try_uuid_file}")"
 
  39                 if [ "${uuid}" = "${try_uuid}" ]
 
  51                 *.squashfs|*.ext2|*.ext3|*.ext4|*.jffs2)
 
  52                         echo $(setup_loop "${1}" "loop" "/sys/block/loop*" '0' "${LIVE_MEDIA_ENCRYPTION}" "${2}")
 
  60                         panic "Unrecognized live filesystem: ${1}"
 
  67         # Does any files match pattern ${1} ?
 
  71         if [ "$(echo ${pattern})" != "${pattern}" ]
 
  79 mount_images_in_directory ()
 
  85         if match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.squashfs" ||
 
  86                 match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext2" ||
 
  87                 match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext3" ||
 
  88                 match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext4" ||
 
  89                 match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.jffs2" ||
 
  90                 match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.dir"
 
  92                 [ -n "${mac}" ] && adddirectory="${directory}/${LIVE_MEDIA_PATH}/${mac}"
 
  93                 setup_unionfs "${directory}/${LIVE_MEDIA_PATH}" "${rootmnt}" "${adddirectory}"
 
  95                 panic "No supported filesystem images found at /${LIVE_MEDIA_PATH}."
 
 101         sysfs_path="${1#/sys}"
 
 103         if [ -e /lib/udev/path_id ]
 
 106                 PATH_ID="/lib/udev/path_id"
 
 108                 # wheezy/sid (udev >= 174)
 
 109                 PATH_ID="/sbin/udevadm test-builtin path_id"
 
 112         if ${PATH_ID} "${sysfs_path}" | egrep -q "ID_PATH=(usb|pci-[^-]*-(ide|sas|scsi|usb|virtio)|platform-sata_mv|platform-orion-ehci|platform-mmc|platform-mxsdhci)"
 
 115         elif echo "${sysfs_path}" | grep -q '^/block/vd[a-z]$'
 
 118         elif echo ${sysfs_path} | grep -q "^/block/dm-"
 
 121         elif echo ${sysfs_path} | grep -q "^/block/mtdblock"
 
 133         skip_uuid_check="${3}"
 
 135         # support for fromiso=.../isofrom=....
 
 138                 ISO_DEVICE=$(dirname $FROMISO)
 
 139                 if ! [ -b $ISO_DEVICE ]
 
 141                         # to support unusual device names like /dev/cciss/c0d0p1
 
 142                         # as well we have to identify the block device name, let's
 
 143                         # do that for up to 15 levels
 
 145                         while [ -n "$ISO_DEVICE" ] && [ "$i" -gt 0 ]
 
 147                                 ISO_DEVICE=$(dirname ${ISO_DEVICE})
 
 148                                 [ -b "$ISO_DEVICE" ] && break
 
 153                 if [ "$ISO_DEVICE" = "/" ]
 
 155                         echo "Warning: device for bootoption fromiso= ($FROMISO) not found.">>/boot.log
 
 157                         fs_type=$(get_fstype "${ISO_DEVICE}")
 
 158                         if is_supported_fs ${fs_type}
 
 161                                 mount -t $fs_type "$ISO_DEVICE" /live/fromiso
 
 162                                 ISO_NAME="$(echo $FROMISO | sed "s|$ISO_DEVICE||")"
 
 163                                 loopdevname=$(setup_loop "/live/fromiso/${ISO_NAME}" "loop" "/sys/block/loop*" "" '')
 
 164                                 devname="${loopdevname}"
 
 166                                 echo "Warning: unable to mount $ISO_DEVICE." >>/boot.log
 
 171         if [ -z "${devname}" ]
 
 173                 devname=$(sys2dev "${sysdev}")
 
 176         if [ -d "${devname}" ]
 
 178                 mount -o bind "${devname}" $mountpoint || continue
 
 180                 if is_live_path $mountpoint
 
 190         for device in ${devname}
 
 195                                 if [ -x /scripts/local-top/lvm2 ]
 
 197                                         ROOT="$device" resume="" /scripts/local-top/lvm2
 
 202                                 # Adding raid support
 
 203                                 if [ -x /scripts/local-top/mdadm ]
 
 205                                         cp /conf/conf.d/md /conf/conf.d/md.orig
 
 206                                         echo "MD_DEVS=$device " >> /conf/conf.d/md
 
 207                                         /scripts/local-top/mdadm
 
 208                                         mv /conf/conf.d/md.orig /conf/conf.d/md
 
 215         [ -n "$device" ] && devname="$device"
 
 217         [ -e "$devname" ] || continue
 
 219         if [ -n "${LIVE_MEDIA_OFFSET}" ]
 
 221                 loopdevname=$(setup_loop "${devname}" "loop" "/sys/block/loop*" "${LIVE_MEDIA_OFFSET}" '')
 
 222                 devname="${loopdevname}"
 
 225         fstype=$(get_fstype "${devname}")
 
 227         if is_supported_fs ${fstype}
 
 229                 devuid=$(blkid -o value -s UUID "$devname")
 
 230                 [ -n "$devuid" ] && grep -qs "\<$devuid\>" $tried && continue
 
 231                 mount -t ${fstype} -o ro,noatime "${devname}" ${mountpoint} || continue
 
 232                 [ -n "$devuid" ] && echo "$devuid" >> $tried
 
 234                 if [ -n "${FINDISO}" ]
 
 236                         if [ -f ${mountpoint}/${FINDISO} ]
 
 239                                 mkdir -p /live/findiso
 
 240                                 mount -t ${fstype} -o ro,noatime "${devname}" /live/findiso
 
 241                                 loopdevname=$(setup_loop "/live/findiso/${FINDISO}" "loop" "/sys/block/loop*" 0 "")
 
 242                                 devname="${loopdevname}"
 
 243                                 mount -t iso9660 -o ro,noatime "${devname}" ${mountpoint}
 
 249                 if is_live_path ${mountpoint} && \
 
 250                         ([ "${skip_uuid_check}" ] || matches_uuid ${mountpoint})
 
 255                         umount ${mountpoint} 2>/dev/null
 
 259         if [ -n "${LIVE_MEDIA_OFFSET}" ]
 
 261                 losetup -d "${loopdevname}"
 
 271         # don't start autodetection before timeout has expired
 
 272         if [ -n "${LIVE_MEDIA_TIMEOUT}" ]
 
 274                 if [ "${timeout}" -lt "${LIVE_MEDIA_TIMEOUT}" ]
 
 280         # first look at the one specified in the command line
 
 281         case "${LIVE_MEDIA}" in
 
 283                         for sysblock in $(removable_usb_dev "sys")
 
 285                                 for dev in $(subdevices "${sysblock}")
 
 287                                         if check_dev "${dev}"
 
 297                         for sysblock in $(removable_dev "sys")
 
 299                                 for dev in $(subdevices "${sysblock}")
 
 301                                         if check_dev "${dev}"
 
 311                         if [ ! -z "${LIVE_MEDIA}" ]
 
 313                                 if check_dev "null" "${LIVE_MEDIA}" "skip_uuid_check"
 
 321         # or do the scan of block devices
 
 322         # prefer removable devices over non-removable devices, so scan them first
 
 323         devices_to_scan="$(removable_dev 'sys') $(non_removable_dev 'sys')"
 
 325         for sysblock in $devices_to_scan
 
 327                 devname=$(sys2dev "${sysblock}")
 
 328                 [ -e "$devname" ] || continue
 
 329                 fstype=$(get_fstype "${devname}")
 
 331                 if /lib/udev/cdrom_id ${devname} > /dev/null
 
 333                         if check_dev "null" "${devname}"
 
 337                 elif is_nice_device "${sysblock}"
 
 339                         for dev in $(subdevices "${sysblock}")
 
 341                                 if check_dev "${dev}"
 
 346                 elif [ "${fstype}" = "squashfs" -o \
 
 347                         "${fstype}" = "btrfs" -o \
 
 348                         "${fstype}" = "ext2" -o \
 
 349                         "${fstype}" = "ext3" -o \
 
 350                         "${fstype}" = "ext4" -o \
 
 351                         "${fstype}" = "jffs2" ]
 
 353                         # This is an ugly hack situation, the block device has
 
 354                         # an image directly on it.  It's hopefully
 
 355                         # live-boot, so take it and run with it.
 
 356                         ln -s "${devname}" "${devname}.${fstype}"
 
 357                         echo "${devname}.${fstype}"
 
 368         VALUE="$(eval echo -n \${$STRING})"
 
 370         if [ -f /live.vars ] && grep -sq "export ${STRING}" /live.vars
 
 372                 sed -i -e 's/\('${STRING}'=\).*$/\1'${VALUE}'/' /live.vars
 
 374                 echo "export ${STRING}=\"${VALUE}\"" >> /live.vars
 
 377         eval export "${STRING}"="${VALUE}"
 
 380 is_in_list_separator_helper ()
 
 382         local sep element list
 
 388         echo ${list} | grep -qe "^\(.*${sep}\)\?${element}\(${sep}.*\)\?$"
 
 391 is_in_space_sep_list ()
 
 396         is_in_list_separator_helper "[[:space:]]" "${element}" "${*}"
 
 399 is_in_comma_sep_list ()
 
 404         is_in_list_separator_helper "," "${element}" "${*}"
 
 410         echo "/dev/$($udevinfo -q name -p ${sysdev} 2>/dev/null|| echo ${sysdev##*/})"
 
 418         for dev in "${sysblock}"/* "${sysblock}"
 
 420                 if [ -e "${dev}/dev" ]
 
 431         black_listed_devices="${1}"
 
 432         white_listed_devices="${2}"
 
 434         for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -vE "loop|ram|fd")
 
 436                 fulldevname=$(sys2dev "${sysblock}")
 
 438                 if is_in_space_sep_list ${fulldevname} ${black_listed_devices} || \
 
 439                         [ -n "${white_listed_devices}" ] && \
 
 440                         ! is_in_space_sep_list ${fulldevname} ${white_listed_devices}
 
 442                         # skip this device entirely
 
 446                 for dev in $(subdevices "${sysblock}")
 
 448                         devname=$(sys2dev "${dev}")
 
 450                         if is_in_space_sep_list ${devname} ${black_listed_devices}
 
 452                                 # skip this subdevice
 
 465         # Validate input first
 
 466         if [ -z "${fstype}" ]
 
 471         # Try to look if it is already supported by the kernel
 
 472         if grep -q ${fstype} /proc/filesystems
 
 476                 # Then try to add support for it the gentle way using the initramfs capabilities
 
 478                 if grep -q ${fstype} /proc/filesystems
 
 481                 # Then try the hard way if /root is already reachable
 
 483                         kmodule="/root/lib/modules/`uname -r`/${fstype}/${fstype}.ko"
 
 484                         if [ -e "${kmodule}" ]
 
 487                                 if grep -q ${fstype} /proc/filesystems
 
 500         /sbin/blkid -s TYPE -o value $1 2>/dev/null
 
 507         grep -m1 "^${device} " /proc/mounts | cut -f2 -d ' '
 
 512         # remove all unnecessary /:s in the path, including last one (except
 
 513         # if path is just "/")
 
 514         echo ${1} | sed 's|//\+|/|g' | sed 's|^\(.*[^/]\)/$|\1|'
 
 517 what_is_mounted_on ()
 
 520         dir="$(trim_path ${1})"
 
 521         grep -m1 "^[^ ]\+ ${dir} " /proc/mounts | cut -d' ' -f1
 
 526         local reference targets owner
 
 530         owner=$(stat -c %u:%g "${reference}")
 
 531         chown -h ${owner} ${targets}
 
 536         local reference targets rights
 
 540         rights=$(stat -c %a "${reference}")
 
 541         chmod ${rights} ${targets}
 
 557         mounts="$(awk '{print $2}' /proc/mounts)"
 
 558         testpath="$(busybox realpath ${testpath})"
 
 562                 if echo "${mounts}" | grep -qs "^${testpath}"
 
 564                         set -- $(echo "${mounts}" | grep "^${testpath}" | lastline)
 
 568                         testpath=$(dirname $testpath)
 
 575         # Returns used/free fs kbytes + 5% more
 
 576         # You could pass a block device as ${1} or the mount point as ${2}
 
 582         if [ -z "${mountp}" ]
 
 584                 mountp="$(where_is_mounted ${dev})"
 
 586                 if [ -z "${mountp}" ]
 
 588                         mountp="/mnt/tmp_fs_size"
 
 591                         mount -t $(get_fstype "${dev}") -o ro "${dev}" "${mountp}" || log_warning_msg "cannot mount -t $(get_fstype ${dev}) -o ro ${dev} ${mountp}"
 
 597         if [ "${used}" = "used" ]
 
 599                 size=$(du -ks ${mountp} | cut -f1)
 
 600                 size=$(expr ${size} + ${size} / 20 ) # FIXME: 5% more to be sure
 
 603                 size="$(df -kP | grep -s ${mountp} | awk '{print $4}')"
 
 606         if [ -n "${doumount}" ]
 
 608                 umount "${mountp}" || log_warning_msg "cannot umount ${mountp}"
 
 618         if [ -x /bin/loadkeys -a -r /etc/boottime.kmap.gz ]
 
 620                 loadkeys -q /etc/boottime.kmap.gz
 
 626         local fspath module pattern offset encryption readonly
 
 634         # the output of setup_loop is evaluated in other functions,
 
 635         # modprobe leaks kernel options like "libata.dma=0"
 
 636         # as "options libata dma=0" on stdout, causing serious
 
 637         # problems therefor, so instead always avoid output to stdout
 
 638         modprobe -q -b "${module}" 1>/dev/null
 
 642         for loopdev in ${pattern}
 
 644                 if [ "$(cat ${loopdev}/size)" -eq 0 ]
 
 646                         dev=$(sys2dev "${loopdev}")
 
 649                         if [ -n "${readonly}" ]
 
 651                                 if losetup --help 2>&1 | grep -q -- "-r\b"
 
 653                                         options="${options} -r"
 
 657                         if [ -n "${offset}" ] && [ 0 -lt "${offset}" ]
 
 659                                 options="${options} -o ${offset}"
 
 662                         if [ -z "${encryption}" ]
 
 664                                 losetup ${options} "${dev}" "${fspath}"
 
 666                                 # Loop AES encryption
 
 671                                         echo -n "Enter passphrase for root filesystem: " >&6
 
 673                                         echo "${passphrase}" > /tmp/passphrase
 
 675                                         exec 9</tmp/passphrase
 
 676                                         /sbin/losetup ${options} -e "${encryption}" -p 9 "${dev}" "${fspath}"
 
 679                                         rm -f /tmp/passphrase
 
 681                                         if [ 0 -eq ${error} ]
 
 688                                         echo -n "There was an error decrypting the root filesystem ... Retry? [Y/n] " >&6
 
 691                                         if [ "$(echo "${answer}" | cut -b1 | tr A-Z a-z)" = "n" ]
 
 704         panic "No loop devices available"
 
 714         old_mountp="$(where_is_mounted ${dev})"
 
 716         if [ -n "${old_mountp}" ]
 
 718                 if [ "${opts}" != "ro" ]
 
 720                         mount -o remount,"${opts}" "${dev}" "${old_mountp}" || panic "Remounting ${dev} ${opts} on ${old_mountp} failed"
 
 723                 mount -o bind "${old_mountp}" "${mountp}" || panic "Cannot bind-mount ${old_mountp} on ${mountp}"
 
 725                 if [ -z "${fstype}" ]
 
 727                         fstype=$(get_fstype "${dev}")
 
 729                 mount -t "${fstype}" -o "${opts}" "${dev}" "${mountp}" || \
 
 730                 ( echo "SKIPPING: Cannot mount ${dev} on ${mountp}, fstype=${fstype}, options=${opts}" > boot.log && return 0 )
 
 734 # Try to mount $device to the place expected by live-boot. If $device
 
 735 # is already mounted somewhere, move it to the expected place. If
 
 736 # we're only probing $device (to check if it has custom persistence)
 
 737 # $probe should be set, which suppresses warnings upon failure. On
 
 738 # success, print the mount point for $device.
 
 739 mount_persistence_media ()
 
 741         local device probe backing old_backing fstype mount_opts
 
 745         backing="/live/persistence/$(basename ${device})"
 
 747         mkdir -p "${backing}"
 
 748         old_backing="$(where_is_mounted ${device})"
 
 749         if [ -z "${old_backing}" ]
 
 751                 fstype="$(get_fstype ${device})"
 
 752                 mount_opts="rw,noatime"
 
 753                 if [ -n "${PERSISTENCE_READONLY}" ]
 
 755                         mount_opts="ro,noatime"
 
 757                 if mount -t "${fstype}" -o "${mount_opts}" "${device}" "${backing}" >/dev/null
 
 762                         [ -z "${probe}" ] && log_warning_msg "Failed to mount persistence media ${device}"
 
 766         elif [ "${backing}" != "${old_backing}" ]
 
 768                 if mount --move ${old_backing} ${backing} >/dev/null
 
 773                         [ -z "${probe}" ] && log_warning_msg "Failed to move persistence media ${device}"
 
 778                 # This means that $device has already been mounted on
 
 779                 # the place expected by live-boot, so we're done.
 
 785 close_persistence_media ()
 
 789         backing="$(where_is_mounted ${device})"
 
 791         if [ -d "${backing}" ]
 
 793                 umount "${backing}" >/dev/null 2>&1
 
 794                 rmdir "${backing}" >/dev/null 2>&1
 
 797         if is_active_luks_mapping ${device}
 
 799                 /sbin/cryptsetup luksClose ${device}
 
 806         name="$(basename ${dev})"
 
 808         if [ -n "${PERSISTENCE_READONLY}" ]
 
 810                 opts="${opts} --readonly"
 
 813         if /sbin/cryptsetup status "${name}" >/dev/null 2>&1
 
 815                 re="^[[:space:]]*device:[[:space:]]*\([^[:space:]]*\)$"
 
 816                 opened_dev=$(cryptsetup status ${name} 2>/dev/null | grep "${re}" | sed "s|${re}|\1|")
 
 817                 if [ "${opened_dev}" = "${dev}" ]
 
 819                         luks_device="/dev/mapper/${name}"
 
 823                         log_warning_msg "Cannot open luks device ${dev} since ${opened_dev} already is opened with its name"
 
 832                 /lib/cryptsetup/askpass "Enter passphrase for ${dev}: " | \
 
 833                         /sbin/cryptsetup -T 1 luksOpen ${dev} ${name} ${opts}
 
 837                         luks_device="/dev/mapper/${name}"
 
 843                 echo -n "There was an error decrypting ${dev} ... Retry? [Y/n] " >&6
 
 846                 if [ "$(echo "${answer}" | cut -b1 | tr A-Z a-z)" = "n" ]
 
 857     /sbin/blkid -s PART_ENTRY_NAME -p -o value ${dev} 2>/dev/null
 
 864     [ "$(/sbin/blkid -s PART_ENTRY_SCHEME -p -o value ${dev} 2>/dev/null)" = "gpt" ]
 
 867 probe_for_gpt_name ()
 
 869         local overlays dev gpt_dev gpt_name
 
 874         if is_active_luks_mapping ${dev}
 
 876                 # if $dev is an opened luks device, we need to check
 
 877                 # GPT stuff on the backing device
 
 878                 gpt_dev=$(get_luks_backing_device "${dev}")
 
 881         if ! is_gpt_device ${gpt_dev}
 
 886         gpt_name=$(get_gpt_name ${gpt_dev})
 
 887         for label in ${overlays}
 
 889                 if [ "${gpt_name}" = "${label}" ]
 
 891                         echo "${label}=${dev}"
 
 896 probe_for_fs_label ()
 
 902         for label in ${overlays}
 
 904                 if [ "$(/sbin/blkid -s LABEL -o value $dev 2>/dev/null)" = "${label}" ]
 
 906                         echo "${label}=${dev}"
 
 911 probe_for_file_name ()
 
 913         local overlays dev ret backing
 
 918         backing="$(mount_persistence_media ${dev} probe)"
 
 919         if [ -z "${backing}" ]
 
 924         for label in ${overlays}
 
 926                 path=${backing}/${PERSISTENCE_PATH}${label}
 
 930                         loopdev=$(setup_loop "${path}" "loop" "/sys/block/loop*")
 
 931                         ret="${ret} ${label}=${loopdev}"
 
 939                 # unmount and remove mountpoint
 
 940                 umount ${backing} > /dev/null 2>&1 || true
 
 941                 rmdir ${backing} > /dev/null 2>&1 || true
 
 945 find_persistence_media ()
 
 947         # Scans devices for overlays, and returns a whitespace
 
 948         # separated list of how to use them. Only overlays with a partition
 
 949         # label or file name in ${overlays} are returned.
 
 951         # When scanning a LUKS device, the user will be asked to enter the
 
 952         # passphrase; on failure to enter it, or if no persistence partitions
 
 953         # or files were found, the LUKS device is closed.
 
 955         # For all other cases (overlay partition and overlay file) the
 
 956         # return value is "${label}=${device}", where ${device} a device that
 
 957         # can mount the content. In the case of an overlay file, the device
 
 958         # containing the file will remain mounted as a side-effect.
 
 960         # No devices in ${black_listed_devices} will be scanned, and if
 
 961         # ${white_list_devices} is non-empty, only devices in it will be
 
 964         local overlays white_listed_devices ret black_listed_devices
 
 966         white_listed_devices="${2}"
 
 969         black_listed_devices="$(what_is_mounted_on /live/medium)"
 
 971         for dev in $(storage_devices "${black_listed_devices}" "${white_listed_devices}")
 
 973                 local result luks_device
 
 977                 # Check if it's a luks device; we'll have to open the device
 
 978                 # in order to probe any filesystem it contains, like we do
 
 979                 # below. activate_custom_mounts() also depends on that any luks
 
 980                 # device already has been opened.
 
 981                 if is_in_comma_sep_list luks ${PERSISTENCE_ENCRYPTION} && is_luks_partition ${dev}
 
 983                         if luks_device=$(open_luks_device "${dev}")
 
 987                                 # skip $dev since we failed/chose not to open it
 
 990                 elif ! is_in_comma_sep_list none ${PERSISTENCE_ENCRYPTION}
 
 992                         # skip $dev since we don't allow unencrypted storage
 
 996                 # Probe for matching GPT partition names or filesystem labels
 
 997                 if is_in_comma_sep_list filesystem ${PERSISTENCE_STORAGE}
 
 999                         result=$(probe_for_gpt_name "${overlays}" ${dev})
 
1000                         if [ -n "${result}" ]
 
1002                                 ret="${ret} ${result}"
 
1006                         result=$(probe_for_fs_label "${overlays}" ${dev})
 
1007                         if [ -n "${result}" ]
 
1009                                 ret="${ret} ${result}"
 
1014                 # Probe for files with matching name on mounted partition
 
1015                 if is_in_comma_sep_list file ${PERSISTENCE_STORAGE}
 
1017                         result=$(probe_for_file_name "${overlays}" ${dev})
 
1018                         if [ -n "${result}" ]
 
1020                                 ret="${ret} ${result}"
 
1025                 # Close luks device if it isn't used
 
1026                 if [ -z "${result}" ] && [ -n "${luks_device}" ] && is_active_luks_mapping "${luks_device}"
 
1028                         /sbin/cryptsetup luksClose "${luks_device}"
 
1042         for adaptor in /sys/class/net/*
 
1044                 status="$(cat ${adaptor}/iflink)"
 
1046                 if [ "${status}" -eq 2 ]
 
1048                         mac="$(cat ${adaptor}/address)"
 
1049                         mac="$(echo ${mac} | sed 's/:/-/g' | tr '[a-z]' '[A-Z]')"
 
1056 is_luks_partition ()
 
1059         /sbin/cryptsetup isLuks "${device}" 1>/dev/null 2>&1
 
1062 is_active_luks_mapping ()
 
1065         /sbin/cryptsetup status "${device}" 1>/dev/null 2>&1
 
1068 get_luks_backing_device ()
 
1071         cryptsetup status ${device} 2> /dev/null | \
 
1072                 awk '{if ($1 == "device:") print $2}'
 
1077         output_format="${1}"
 
1081         for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -vE "/(loop|ram|dm-|fd)")
 
1084                 if [ "$(cat ${sysblock}/removable)" = "1" ]
 
1086                         if [ -z "${want_usb}" ]
 
1090                                 if readlink ${sysblock} | grep -q usb
 
1097                 if [ "${dev_ok}" = "true" ]
 
1099                         case "${output_format}" in
 
1101                                         ret="${ret} ${sysblock}"
 
1104                                         devname=$(sys2dev "${sysblock}")
 
1105                                         ret="${ret} ${devname}"
 
1114 removable_usb_dev ()
 
1116         output_format="${1}"
 
1118         removable_dev "${output_format}" "want_usb"
 
1121 non_removable_dev ()
 
1123         output_format="${1}"
 
1126         for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -vE "/(loop|ram|dm-|fd)")
 
1128                 if [ "$(cat ${sysblock}/removable)" = "0" ]
 
1130                         case "${output_format}" in
 
1132                                         ret="${ret} ${sysblock}"
 
1135                                         devname=$(sys2dev "${sysblock}")
 
1136                                         ret="${ret} ${devname}"
 
1147         # create source's directory structure in dest, and recursively
 
1148         # create symlinks in dest to to all files in source. if mask
 
1149         # is non-empty, remove mask from all source paths when
 
1150         # creating links (will be necessary if we change root, which
 
1151         # live-boot normally does (into $rootmnt)).
 
1152         local src_dir dest_dir src_mask
 
1154         # remove multiple /:s and ensure ending on /
 
1155         src_dir="$(trim_path ${1})/"
 
1156         dest_dir="$(trim_path ${2})/"
 
1159         # This check can only trigger on the inital, non-recursive call since
 
1160         # we create the destination before recursive calls
 
1161         if [ ! -d "${dest_dir}" ]
 
1163                 log_warning_msg "Must link_files into a directory"
 
1167         find "${src_dir}" -mindepth 1 -maxdepth 1 | \
 
1170                 local dest final_src
 
1171                 dest="${dest_dir}$(basename "${src}")"
 
1174                         if [ -z "$(ls -A "${src}")" ]
 
1178                         if [ ! -d "${dest}" ]
 
1181                                 chown_ref "${src}" "${dest}"
 
1182                                 chmod_ref "${src}" "${dest}"
 
1184                         link_files "${src}" "${dest}" "${src_mask}"
 
1187                         if [ -n "${src_mask}" ]
 
1189                                 final_src="$(echo ${final_src} | sed "s|^${src_mask}||")"
 
1191                         rm -rf "${dest}" 2> /dev/null
 
1192                         ln -s "${final_src}" "${dest}"
 
1193                         chown_ref "${src}" "${dest}"
 
1200         local unionmountpoint unionrw unionro
 
1201         unionmountpoint="${1}"  # directory where the union is mounted
 
1203         unionrw="${1}"          # branch where the union changes are stored
 
1205         unionro="${*}"          # space separated list of read-only branches (optional)
 
1207         case "${UNIONTYPE}" in
 
1225         case "${UNIONTYPE}" in
 
1227                         unionmountopts="-o cow -o noinitgroups -o default_permissions -o allow_other -o use_ino -o suid"
 
1228                         unionmountopts="${unionmountopts} ${unionrw}=${rw_opt}"
 
1229                         if [ -n "${unionro}" ]
 
1231                                 for rofs in ${unionro}
 
1233                                         unionmountopts="${unionmountopts}:${rofs}=${ro_opt}"
 
1236                         ( sysctl -w fs.file-max=391524 ; ulimit -HSn 16384
 
1237                         unionfs-fuse ${unionmountopts} "${unionmountpoint}" ) && \
 
1238                         ( mkdir -p /run/sendsigs.omit.d
 
1239                         pidof unionfs-fuse >> /run/sendsigs.omit.d/unionfs-fuse || true )
 
1243                         # XXX: can multiple unionro be used? (overlayfs only handles two dirs, but perhaps they can be chained?)
 
1244                         # XXX: and can unionro be optional? i.e. can overlayfs skip lowerdir?
 
1245                         if echo ${unionro} | grep -q " "
 
1247                                 panic "Multiple lower filesystems are currently not supported with overlayfs (unionro = ${unionro})."
 
1248                         elif [ -z "${unionro}"  ]
 
1250                                 panic "Overlayfs needs at least one lower filesystem (read-only branch)."
 
1252                         unionmountopts="-o noatime,lowerdir=${unionro},upperdir=${unionrw}"
 
1253                         mount -t ${UNIONTYPE} ${unionmountopts} ${UNIONTYPE} "${unionmountpoint}"
 
1257                         unionmountopts="-o noatime,${noxino_opt},dirs=${unionrw}=${rw_opt}"
 
1258                         if [ -n "${unionro}" ]
 
1260                                 for rofs in ${unionro}
 
1262                                         unionmountopts="${unionmountopts}:${rofs}=${ro_opt}"
 
1265                         mount -t ${UNIONTYPE} ${unionmountopts} ${UNIONTYPE} "${unionmountpoint}"
 
1270 get_custom_mounts ()
 
1272         # Side-effect: leaves $devices with persistence.conf mounted in /live/persistence
 
1273         # Side-effect: prints info to file $custom_mounts
 
1275         local custom_mounts devices bindings links
 
1280         bindings="/tmp/bindings.list"
 
1281         links="/tmp/links.list"
 
1282         rm -rf ${bindings} ${links} 2> /dev/null
 
1284         for device in ${devices}
 
1286                 if [ ! -b "${device}" ]
 
1291                 local device_name backing include_list
 
1292                 device_name="$(basename ${device})"
 
1293                 backing=$(mount_persistence_media ${device})
 
1294                 if [ -z "${backing}" ]
 
1299                 if [ -r "${backing}/${persistence_list}" ]
 
1301                         include_list="${backing}/${persistence_list}"
 
1302                 elif [ -r "${backing}/${old_persistence_list}" ]
 
1304                         include_list="${backing}/${old_persistence_list}"
 
1309                 if [ -n "${DEBUG}" ] && [ -e "${include_list}" ]
 
1311                         cp ${include_list} /live/persistence/${persistence_list}.${device_name}
 
1314                 while read dir options # < ${include_list}
 
1316                         if echo ${dir} | grep -qe "^[[:space:]]*\(#.*\)\?$"
 
1318                                 # skipping empty or commented lines
 
1322                         if trim_path ${dir} | grep -q -e "^[^/]" -e "^/lib" -e "^/lib/live\(/.*\)\?$" -e "^/\(.*/\)\?\.\.\?\(/.*\)\?$"
 
1324                                 log_warning_msg "Skipping unsafe custom mount ${dir}: must be an absolute path containing neither the \".\" nor \"..\" special dirs, and cannot be \"/lib\", or \"/lib/live\" or any of its sub-directories."
 
1328                         local opt_source opt_link source full_source full_dest
 
1331                         for opt in $(echo ${options} | tr ',' ' ');
 
1335                                                 opt_source=${opt#source=}
 
1343                                                 log_warning_msg "Skipping custom mount with unkown option: ${opt}"
 
1350                         if [ -n "${opt_source}" ]
 
1352                                 if echo ${opt_source} | grep -q -e "^/" -e "^\(.*/\)\?\.\.\?\(/.*\)\?$" && [ "${opt_source}" != "." ]
 
1354                                         log_warning_msg "Skipping unsafe custom mount with option source=${opt_source}: must be either \".\" (the media root) or a relative path w.r.t. the media root that contains neither comas, nor the special \".\" and \"..\" path components"
 
1357                                         source="${opt_source}"
 
1361                         full_source="$(trim_path ${backing}/${source})"
 
1362                         full_dest="$(trim_path ${rootmnt}/${dir})"
 
1363                         if [ -n "${opt_link}" ]
 
1365                                 echo "${device} ${full_source} ${full_dest} ${options}" >> ${links}
 
1367                                 echo "${device} ${full_source} ${full_dest} ${options}" >> ${bindings}
 
1369                 done < ${include_list}
 
1372         # We sort the list according to destination so we're sure that
 
1373         # we won't hide a previous mount. We also ignore duplicate
 
1374         # destinations in a more or less arbitrary way.
 
1375         [ -e "${bindings}" ] && sort -k3 -sbu ${bindings} >> ${custom_mounts} && rm ${bindings}
 
1377         # After all mounts are considered we add symlinks so they
 
1378         # won't be hidden by some mount.
 
1379         [ -e "${links}" ] && cat ${links} >> ${custom_mounts} && rm ${links}
 
1381         # We need to make sure that no two custom mounts have the same sources
 
1382         # or are nested; if that is the case, too much weird stuff can happen.
 
1383         local prev_source prev_dest
 
1384         prev_source="impossible source" # first iteration must not match
 
1386         # This sort will ensure that a source /a comes right before a source
 
1387         # /a/b so we only need to look at the previous source
 
1388         sort -k2 -b ${custom_mounts} |
 
1389         while read device source dest options
 
1391                 if echo ${source} | grep -qe "^${prev_source}\(/.*\)\?$"
 
1393                         panic "Two persistence mounts have the same or nested sources: ${source} on ${dest}, and ${prev_source} on ${prev_dest}"
 
1395                 prev_source=${source}
 
1400 activate_custom_mounts ()
 
1402         local custom_mounts used_devices
 
1403         custom_mounts="${1}" # the ouput from get_custom_mounts()
 
1406         while read device source dest options # < ${custom_mounts}
 
1408                 local opt_bind opt_link opt_union
 
1412                 for opt in $(echo ${options} | tr ',' ' ');
 
1417                                         unset opt_link opt_union
 
1421                                         unset opt_bind opt_union
 
1425                                         unset opt_bind opt_link
 
1430                 if [ -n "$(what_is_mounted_on "${dest}")" ]
 
1432                         if [ "${dest}" = "${rootmnt}" ]
 
1436                                 log_warning_msg "Skipping custom mount ${dest}: $(what_is_mounted_on "${dest}") is already mounted there"
 
1441                 if [ ! -d "${dest}" ]
 
1443                         # create the destination and delete existing files in
 
1444                         # its path that are in the way
 
1446                         for dir in $(echo ${dest} | sed -e 's|/\+| |g')
 
1448                                 path=$(trim_path ${path}/${dir})
 
1456                                         if echo ${path} | grep -qe "^${rootmnt}/*home/[^/]\+"
 
1458                                                 # if ${dest} is in /home try fixing proper ownership by assuming that the intended user is the first, which is usually the case
 
1459                                                 # FIXME: this should really be handled by live-config since we don't know for sure which uid a certain user has until then
 
1460                                                 chown 1000:1000 ${path}
 
1466                 # if ${source} doesn't exist on our persistence media
 
1467                 # we bootstrap it with $dest from the live filesystem.
 
1468                 # this both makes sense and is critical if we're
 
1469                 # dealing with /etc or other system dir.
 
1470                 if [ ! -d "${source}" ]
 
1472                         if [ -n "${PERSISTENCE_READONLY}" ]
 
1475                         elif [ -n "${opt_union}" ] || [ -n "${opt_link}" ]
 
1477                                 # unions and don't need to be bootstrapped
 
1478                                 # link dirs can't be bootstrapped in a sensible way
 
1479                                 mkdir -p "${source}"
 
1480                                 chown_ref "${dest}" "${source}"
 
1481                                 chmod_ref "${dest}" "${source}"
 
1482                         elif [ -n "${opt_bind}" ]
 
1484                                 # ensure that $dest is not copied *into* $source
 
1485                                 mkdir -p "$(dirname ${source})"
 
1486                                 cp -a "${dest}" "${source}"
 
1490                 # XXX: If CONFIG_AUFS_ROBR is added to the Debian kernel we can
 
1491                 # ignore the loop below and set rootfs_dest_backing=$dest
 
1492                 local rootfs_dest_backing
 
1493                 rootfs_dest_backing=""
 
1494                 if [ -n "${opt_link}"]
 
1496                         for d in /live/rootfs/*
 
1498                                 if [ -n "${rootmnt}" ]
 
1500                                         fs="${d}/$(echo ${dest} | sed -e "s|${rootmnt}||")"
 
1506                                         rootfs_dest_backing="${rootfs_dest_backing} ${fs}"
 
1511                 local cow_dir links_source
 
1512                 if [ -n "${opt_link}" ] && [ -z "${PERSISTENCE_READONLY}" ]
 
1514                         link_files ${source} ${dest} ${rootmnt}
 
1515                 elif [ -n "${opt_link}" ] && [ -n "${PERSISTENCE_READONLY}" ]
 
1517                         mkdir -p ${rootmnt}/lib/live/mount/persistence
 
1518                         links_source=$(mktemp -d ${rootmnt}/lib/live/mount/persistence/links-source-XXXXXX)
 
1519                         chown_ref ${source} ${links_source}
 
1520                         chmod_ref ${source} ${links_source}
 
1521                         # We put the cow dir in the below strange place to
 
1522                         # make it absolutely certain that the link source
 
1523                         # has its own directory and isn't nested with some
 
1524                         # other custom mount (if so that mount's files would
 
1525                         # be linked, causing breakage.
 
1526                         cow_dir="/live/overlay/lib/live/mount/persistence/$(basename ${links_source})"
 
1528                         chown_ref "${source}" "${cow_dir}"
 
1529                         chmod_ref "${source}" "${cow_dir}"
 
1530                         do_union ${links_source} ${cow_dir} ${source} ${rootfs_dest_backing}
 
1531                         link_files ${links_source} ${dest} ${rootmnt}
 
1532                 elif [ -n "${opt_union}" ] && [ -z "${PERSISTENCE_READONLY}" ]
 
1534                         do_union ${dest} ${source} ${rootfs_dest_backing}
 
1535                 elif [ -n "${opt_bind}" ] && [ -z "${PERSISTENCE_READONLY}" ]
 
1537                         mount --bind "${source}" "${dest}"
 
1538                 elif [ -n "${opt_bind}" -o -n "${opt_union}" ] && [ -n "${PERSISTENCE_READONLY}" ]
 
1540                         # bind-mount and union mount are handled the same
 
1541                         # in read-only mode, but note that rootfs_dest_backing
 
1542                         # is non-empty (and necessary) only for unions
 
1543                         cow_dir="/live/overlay/${dest}"
 
1544                         if [ -e "${cow_dir}" ] && [ -z "${opt_link}" ]
 
1546                                 # If an earlier custom mount has files here
 
1547                                 # it will "block" the current mount's files
 
1548                                 # which is undesirable
 
1552                         chown_ref "${source}" "${cow_dir}"
 
1553                         chmod_ref "${source}" "${cow_dir}"
 
1554                         do_union ${dest} ${cow_dir} ${source} ${rootfs_dest_backing}
 
1557                 PERSISTENCE_IS_ON="1"
 
1558                 export PERSISTENCE_IS_ON
 
1560                 if echo ${used_devices} | grep -qve "^\(.* \)\?${device}\( .*\)\?$"
 
1562                         used_devices="${used_devices} ${device}"
 
1564         done < ${custom_mounts}
 
1566         echo ${used_devices}
 
1569 fix_backwards_compatibility ()
 
1571         local device dir opt backing include_list
 
1576         if [ -n "${PERSISTENCE_READONLY}" ]
 
1581         backing="$(mount_persistence_media ${device})"
 
1582         if [ -z "${backing}" ]
 
1587         include_list="${backing}/${persistence_list}"
 
1588         if [ ! -r "${include_list}" ] && [ ! -r "${backing}/${old_persistence_list}" ]
 
1590                 echo "# persistence backwards compatibility:
 
1591 ${dir} ${opt},source=." > "${include_list}"
 
1599         [ $(stat -fc%d:%D "${directory}") != $(stat -fc%d:%D "${directory}/..") ]