Changeset 15592 in niluje


Ignore:
Timestamp:
Dec 11, 2018, 11:04:02 PM (5 months ago)
Author:
NiLuJe
Message:

MRPI:

  • Add some more sanity checks around the tmpfs size…
    • Make sure awk will always print it as an integer
    • Compute a fraction of available memory we can spare to resize the tmpfs at runtime, once the framework is down. This should ensure we'll never go OOM, which would be bad, because we don't have swap. Abort if we can't spare more than 32MB, which should be enough to avoid ENOSPC in most cases ;).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Configs/trunk/Kindle/KUAL/MRInstaller/extensions/MRInstaller/bin/mrinstaller.sh

    r15589 r15592  
    384384}
    385385
     386## Compute an estimate of the amount of available memory to resize our tmpfs
     387resize_mrpi_tmpfs()
     388{
     389        logmsg "I" "resize_mrpi_tmpfs" "" "checking available memory"
     390
     391        # We'll resort to a few different methods, because depending on the age of the Linux kernel,
     392        # we won't always have access to the easiest of them, which is relying on MemAvailable in /proc/meminfo...
     393        # c.f., https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
     394        if grep -q 'MemAvailable' /proc/meminfo ; then
     395                # We'll settle for 85% of available memory to leave a bit of breathing room
     396                tmpfs_size="$(awk '/MemAvailable/ {printf "%d", $2 * 0.85}' /proc/meminfo)"
     397        elif grep -q 'Inactive(file)' /proc/meminfo ; then
     398                # Basically try to emulate the kernel's computation, c.f., https://unix.stackexchange.com/q/261247
     399                # Again, 85% of available memory
     400                tmpfs_size="$(awk -v low=$(grep low /proc/zoneinfo | awk '{k+=$2}END{printf "%d", k}') \
     401                        '{a[$1]=$2}
     402                        END{
     403                                printf "%d", (a["MemFree:"]+a["Active(file):"]+a["Inactive(file):"]+a["SReclaimable:"]-(12*low))*0.85;
     404                        }' /proc/meminfo)"
     405        else
     406                # Ye olde crap workaround of Free + Buffers + Cache...
     407                # Take it with a grain of salt, and settle for 80% of that...
     408                tmpfs_size="$(awk \
     409                        '{a[$1]=$2}
     410                        END{
     411                                printf "%d", (a["MemFree:"]+a["Buffers:"]+a["Cached:"])*0.80;
     412                        }' /proc/meminfo)"
     413        fi
     414
     415        # Make sure we end up with a sane-ish fallback in case all this failed...
     416        is_integer "${tmpfs_size}" || tmpfs_size="81920"
     417
     418        # Log those computations
     419        logmsg "I" "resize_mrpi_tmpfs" "" "can spare $((${tmpfs_size} / 1024))MB for mrpi tmpfs"
     420
     421        # Check that we actually end up with enough free memory to be able to use it...
     422        if [ "${tmpfs_size}" -lt "$(( 32 * 1024 ))" ] ; then
     423                # If we can spare less than 32MB, abort!
     424                logmsg "E" "resize_mrpi_tmpfs" "" "not enough available memory (< 32MB) for mrpi tmpfs!"
     425                return 1
     426        fi
     427
     428        # Compare that with our ceiling, 62.5% of the total memory
     429        tmpfs_ceil="$(awk '/MemTotal/ {printf "%d", $2 * 0.625}' /proc/meminfo)"
     430        # With a fallback...
     431        is_integer "${tmpfs_ceil}" || tmpfs_ceil="81920"
     432
     433        # If our computed size is smaller than the ceiling value, resize the tmpfs
     434        if [ "${tmpfs_size}" -lt "${tmpfs_ceil}" ] ; then
     435                /bin/mount -t tmpfs tmpfs "${MRPI_TMPFS}" -o remount,defaults,size=${tmpfs_size}K,mode=1777,noatime
     436                if [ $? -ne 0 ] ; then
     437                        logmsg "E" "resize_mrpi_tmpfs" "" "failed to remount mrpi tmpfs!"
     438                        return 1
     439                fi
     440
     441                # Even if it appeared to work, double check...
     442                if ! is_mrpi_tmpfs_up ; then
     443                        logmsg "E" "resize_mrpi_tmpfs" "" "mrpi tmpfs is still not mounted!"
     444                        return 1
     445                fi
     446
     447                # Success!
     448                logmsg "I" "resize_mrpi_tmpfs" "" "resized mrpi tmpfs down to $((${tmpfs_size} / 1024))MB"
     449        fi
     450
     451        return 0
     452}
     453
    386454## To make things faster, we'll try to do as much work in RAM as possible
    387455## But since none of the existing tmpfs fit our needs, we'll create our own.
     
    401469        # Namely, the default ones tend to be small. So let's say we want one that's about 62.5% of the total RAM.
    402470        # That's usually close enough to the free RAM we get with the framework down, and should be more than enough ;).
    403         tmpfs_size="$(awk '/MemTotal/ {print $2 * 0.625}' /proc/meminfo)"
     471        tmpfs_size="$(awk '/MemTotal/ {printf "%d", $2 * 0.625}' /proc/meminfo)"
    404472        # Just in case the apocalypse hits, and our awk shenanigans fail, make sure we have sane defaults, even for 128MB of RAM
    405473        is_integer "${tmpfs_size}" || tmpfs_size="81920"
     
    422490
    423491        # Success!
    424         logmsg "I" "mount_mrpi_tmpfs" "" "created ${tmpfs_size}kB mrpi tmpfs"
     492        logmsg "I" "mount_mrpi_tmpfs" "" "created $((${tmpfs_size} / 1024))MB mrpi tmpfs"
    425493        return 0
    426494}
     
    575643        echo -e "\n\n**** **** **** ****" >> "${MRINSTALLER_BASEDIR}/log/mrinstaller.log"
    576644        echo -e "\n[$(date +'%F @ %T %z')] :: [MRPI r${MRPI_REV}] - Beginning the processing of package '${PKG_FILENAME}' (${PKG_NAME}) . . .\n" >> "${MRINSTALLER_BASEDIR}/log/mrinstaller.log"
     645
     646        # Now that the framework is down and we actually have a decent amount of free RAM, try to resize out tmpfs accordingly
     647        if ! resize_mrpi_tmpfs ; then
     648                eips_print_bottom_centered "Failed to resize MRPI tmpfs, waiting . . ." 1
     649                echo -e "\nFailed to resize MRPI tmpfs, waiting . . .\n" >> "${MRINSTALLER_BASEDIR}/log/mrinstaller.log"
     650                sleep 5
     651                # Try one final time...
     652                if ! resize_mrpi_tmpfs ; then
     653                        eips_print_bottom_centered "Really failed to resize MRPI tmpfs, skipping" 1
     654                        echo -e "\nReally failed to resize MRPI tmpfs, skipping ${PKG_NAME} . . . :(\n" >> "${MRINSTALLER_BASEDIR}/log/mrinstaller.log"
     655                        sleep 5
     656                        return 1
     657                fi
     658        fi
    577659
    578660        # Check if it's valid...
Note: See TracChangeset for help on using the changeset viewer.