#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) . /etc/profile . /etc/os-release ### Vars UPDATE_ROOT="/storage/.update" MOUNT_GAMES=$(get_setting system.automount) GAMES_DEVICE=$(get_setting system.gamesdevice) MS_PATH="/storage/roms" function unmount() { log $0 "Unmount ${1}." umount -f "${1}" 2>/dev/null ||: } function add_readme() { cat </storage/roms/README Use the \`Create Game Directories\` option in \`System Settings\` to create your game directories. EOF } function start_ms() { ### Entrypoint will be either games card found (external), or not found (internal). MOUNT_PATH="/storage/games-${1}" MS_DEVICE=$(get_setting system.merged.device) ### If the merge target isn't defined and we have an external microsd, we should use the external card by default. if [ -z "${MS_DEVICE}" ] && \ [ "${1}" = "external" ] then set_setting system.merged.device external fi ### Determine if internal or external is the primary target by configuration. case ${MS_DEVICE} in internal) LOWER="external" UPPER="internal" ;; *) LOWER="internal" UPPER="external" ;; esac for GAME_PATH in internal external do if [ ! -d "/storage/games-${GAME_PATH}/roms" ] then log $0 "Create /storage/games-${GAME_PATH}/roms." mkdir -p "/storage/games-${GAME_PATH}/roms" fi done MS_ENABLED=$(get_setting system.merged.storage) if [ -e "/storage/.ms_unsupported" ] || \ [ ! "${MS_ENABLED}" = 1 ] then log $0 "Executing bind mount of ${MOUNT_PATH} to ${MS_PATH}" mount --bind ${MOUNT_PATH}/roms ${MS_PATH} else log $0 "Enabling merged storage of /storage/games-${LOWER} and /storage/games-${UPPER} to ${MS_PATH}." for DIR in /storage/games-${UPPER}/.tmp/games-workdir /storage/games-${LOWER}/roms /storage/games-${UPPER}/roms do if [ ! -d "${DIR}" ] then mkdir -p "${DIR}" fi done mount overlay -t overlay -o lowerdir=/storage/games-${LOWER}/roms,upperdir=/storage/games-${UPPER}/roms,workdir=/storage/games-${UPPER}/.tmp/games-workdir ${MS_PATH} fi } if [[ ! "${MOUNT_GAMES}" =~ [0-9] ]] then set_setting system.automount 1 elif [[ "${MOUNT_GAMES}" == "0" ]] then start_ms internal add_readme exit 0 fi function load_modules() { for MODULE in exfat vfat do lsmod | grep ${MODULE} >/dev/null 2>&1 if [ ! $? = 0 ] then log $0 "Loading ${MODULE}." modprobe ${MODULE} >/dev/null 2>&1 fi done } function mount_games() { MOUNT_PATH="/storage/games-external" FSTYPE=$(blkid -o export ${1} | awk 'BEGIN {FS="="} /TYPE/ {print $2}') case ${FSTYPE} in ext4) log $0 "Found supported partition for overlayfs." if [ -e "/storage/.ms_unsupported" ] then rm -f /storage/.ms_unsupported fi touch /storage/.ms_supported ;; *) log $0 "Partition does not support overlayfs, disabling." if [ -e "/storage/.ms_supported" ] then rm -f /storage/.ms_supported fi touch /storage/.ms_unsupported ;; esac if [ ! -d "${MOUNT_PATH}" ] then log $0 "Create directory ${MOUNT_PATH}" /usr/bin/busybox mkdir -p ${MOUNT_PATH} >/dev/null 2>&1 fi NULL=$(cat /proc/mounts | grep -v -e "/var/media" 2>/dev/null | grep ${1}) if [ ! "$?" = "0" ] && \ [ -e "${1}" ] && \ [ ! -e "/storage/.please_resize_me" ] then ### Udevil shouldn't mount it this early, but just in-case. umount /var/media/* 2>/dev/null log $0 "Checking filesystem ${1}." fsck -Mly ${1} >/dev/null 2>&1 log $0 "Mounting ${1} on ${MOUNT_PATH}" /usr/bin/busybox mount ${1} ${MOUNT_PATH} >/dev/null 2>&1 fi start_ms external add_readme exit 0 } function find_games() { if /usr/bin/busybox mountpoint -q /storage then for DEV in $(for dev in mmcblk[0-9] sd[a-z] nvme[0-9]; do blkid | grep ${dev} | awk 'BEGIN {FS=":"}; /ext4/ || /fat/ {print $1}' | sort -r; done) do ROOTDEV=$(echo ${DEV} | sed -e "s#^/.*/##g" -e "s#p[0-9].*\$##g") log $0 "Inspecting ${DEV}." SIZE=$(awk '/'${ROOTDEV}'$/ {print $3}' /proc/partitions) if (( ${SIZE} <= 8388608 )) then log $0 "Device ${ROOTDEV} is too small, ignoring." # We don't want to mount partitions smaller than ~8GB. continue fi if [ -L "/sys/class/block/${ROOTDEV}boot0" ] then log $0 "Device ${ROOTDEV} might be Android, ignoring." # Assume this is an android boot device and ignore it. continue fi ISMOUNTED="$(grep "${DEV}" /proc/mounts) >/dev/null 2>&1" if [ ! "$?" = 0 ] && \ [ -e "${DEV}" ] && \ [ ! -e "/storage/.please_resize_me" ] then GAMES_DEVICE=${DEV} log $0 "Found ${DEV} available to mount." mount_games "${DEV}" else log $0 "${DEV} not available." fi done log $0 "Could not find external card to mount, assume internal." MS_DEVICE=$(get_setting system.merged.device) ### If the merge target isn't defined and we do not have an external microsd, we should use the internal card by default. if [ -z "${MS_DEVICE}" ] then set_setting system.merged.device internal fi start_ms internal add_readme exit 0 fi } ## Main.. load_modules ### Unmount any existing storage before beginning operations. unmount /storage/games-external unmount /storage/roms if [ -e "${GAMES_DEVICE}" ] then mount_games ${GAMES_DEVICE} else find_games fi