+ dev_ok=
+ if [ "$(cat ${sysblock}/removable)" = "1" ]
+ then
+ if [ -z "${want_usb}" ]
+ then
+ dev_ok="yes"
+ else
+ if readlink ${sysblock} | grep -q usb
+ then
+ dev_ok="yes"
+ fi
+ fi
+ fi
+
+ if [ "${dev_ok}" = "yes" ]
+ then
+ case "${output_format}" in
+ sys)
+ ret="${ret} ${sysblock}"
+ ;;
+ *)
+ devname=$(sys2dev "${sysblock}")
+ ret="${ret} ${devname}"
+ ;;
+ esac
+ fi
+ done
+
+ echo "${ret}"
+}
+
+removable_usb_dev ()
+{
+ output_format="${1}"
+
+ removable_dev "${output_format}" "want_usb"
+}
+
+non_removable_dev ()
+{
+ output_format="${1}"
+ ret=
+
+ for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -vE "/(loop|ram|dm-|fd)")
+ do
+ if [ "$(cat ${sysblock}/removable)" = "0" ]
+ then
+ case "${output_format}" in
+ sys)
+ ret="${ret} ${sysblock}"
+ ;;
+ *)
+ devname=$(sys2dev "${sysblock}")
+ ret="${ret} ${devname}"
+ ;;
+ esac
+ fi
+ done
+
+ echo "${ret}"
+}
+
+link_files ()
+{
+ # create source's directory structure in dest, and recursively
+ # create symlinks in dest to to all files in source. if mask
+ # is non-empty, remove mask from all source paths when
+ # creating links (will be necessary if we change root, which
+ # live-boot normally does (into $rootmnt)).
+
+ # remove multiple /:s and ensure ending on /
+ local src_dir="$(echo "${1}"/ | sed -e 's|/\+|/|g')"
+ local dest_dir="$(echo "${2}"/ | sed -e 's|/\+|/|g')"
+ local src_mask="${3}"
+
+ # This check can only trigger on the inital, non-recursive call since
+ # we create the destination before recursive calls
+ if [ ! -d "${dest_dir}" ];
+ then
+ log_warning_msg "Must link_files into a directory"
+ return
+ fi
+
+ find "${src_dir}" -mindepth 1 -maxdepth 1 | while read x; do
+ local src="${x}"
+ local dest="${dest_dir}$(basename "${x}")"
+ if [ -d "${src}" ];
+ then
+ if [ -z "$(ls -A "${src}")" ];
+ then
+ continue
+ fi
+ if [ ! -d "${dest}" ];
+ then
+ mkdir -p "${dest}"
+ prev="$(dirname "${dest}")"
+ chown $(stat -c %u:%g "${prev}") "${dest}"
+ chmod $(stat -c %a "${prev}") "${dest}"
+ fi
+ link_files "${src}" "${dest}" "${src_mask}"
+ else
+ if [ -n "${src_mask}" ]
+ then
+ src="$(echo ${src} | sed "s|^${src_mask}||")"
+ fi
+ rm -rf "${dest}" 2> /dev/null
+ ln -s "${src}" "${dest}"
+ fi
+ done
+}
+
+do_union () {
+ local unionmountpoint="${1}" # directory where the union is mounted
+ local unionrw="${2}" # branch where the union changes are stored
+ local unionro1="${3}" # first underlying read-only branch (optional)
+ local unionro2="${4}" # second underlying read-only branch (optional)
+
+ if [ "${UNIONTYPE}" = "aufs" ]
+ then
+ rw_opt="rw"
+ ro_opt="rr+wh"
+ noxino_opt="noxino"
+ elif [ "${UNIONTYPE}" = "unionfs-fuse" ]
+ then
+ rw_opt="RW"
+ ro_opt="RO"
+ else
+ rw_opt="rw"
+ ro_opt="ro"
+ fi
+
+ case "${UNIONTYPE}" in
+ unionfs-fuse)
+ unionmountopts="-o cow -o noinitgroups -o default_permissions -o allow_other -o use_ino -o suid"
+ unionmountopts="${unionmountopts} ${unionrw}=${rw_opt}"
+ if [ -n "${unionro1}" ]
+ then
+ unionmountopts="${unionmountopts}:${unionro1}=${ro_opt}"
+ fi
+ if [ -n "${unionro2}" ]
+ then
+ unionmountopts="${unionmountopts}:${unionro2}=${ro_opt}"
+ fi
+ ( sysctl -w fs.file-max=391524 ; ulimit -HSn 16384
+ unionfs-fuse ${unionmountopts} "${unionmountpoint}" ) && \
+ ( mkdir -p /run/sendsigs.omit.d
+ pidof unionfs-fuse >> /run/sendsigs.omit.d/unionfs-fuse || true )
+ ;;
+
+ overlayfs)
+ # XXX: can unionro2 be used? (overlayfs only handles two dirs, but perhaps they can be chained?)
+ # XXX: and can unionro1 be optional? i.e. can overlayfs skip lowerdir?
+ unionmountopts="-o noatime,lowerdir=${unionro1},upperdir=${unionrw}"
+ mount -t ${UNIONTYPE} ${unionmountopts} ${UNIONTYPE} "${unionmountpoint}"
+ ;;
+
+ *)
+ unionmountopts="-o noatime,${noxino_opt},dirs=${unionrw}=${rw_opt}"
+ if [ -n "${unionro1}" ]
+ then
+ unionmountopts="${unionmountopts}:${unionro1}=${ro_opt}"
+ fi
+ if [ -n "${unionro2}" ]
+ then
+ unionmountopts="${unionmountopts}:${unionro2}=${ro_opt}"
+ fi
+ mount -t ${UNIONTYPE} ${unionmountopts} ${UNIONTYPE} "${unionmountpoint}"
+ ;;
+ esac
+}
+
+get_custom_mounts () {
+ # Side-effect: leaves $devices with live.persist mounted in ${rootmnt}/live/persistent
+ # Side-effect: prints info to file $custom_mounts
+
+ local devices="${1}"
+ local custom_mounts="${2}" # print result to this file
+ local rootmnt="${3}" # should be set empty post-live-boot
+
+ local bindings="/bindings.list"
+ local links="/links.list"
+ rm -rf ${bindings} ${links} 2> /dev/null
+ local persistent_backing="${rootmnt}/live/persistent"
+
+ for device in ${devices}
+ do
+ if [ ! -b "${device}" ]
+ 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}" ]
+ then
+ device_mount_opts="rw,noatime"
+ else
+ device_mount_opts="ro,noatime"
+ 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}"
+ continue
+ fi
+
+ [ "${DEBUG}" = "Yes" ] && cp ${include_list} ${persistent_backing}/${persistence_list}.${device_name}
+ while read source dest options # < ${include_list}