1*288bf522SAndroid Build Coastguard Worker#!/system/bin/sh 2*288bf522SAndroid Build Coastguard Worker 3*288bf522SAndroid Build Coastguard Worker# 4*288bf522SAndroid Build Coastguard Worker# Copyright (C) 2019 The Android Open Source Project 5*288bf522SAndroid Build Coastguard Worker# 6*288bf522SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 7*288bf522SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 8*288bf522SAndroid Build Coastguard Worker# You may obtain a copy of the License at 9*288bf522SAndroid Build Coastguard Worker# 10*288bf522SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 11*288bf522SAndroid Build Coastguard Worker# 12*288bf522SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 13*288bf522SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 14*288bf522SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15*288bf522SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 16*288bf522SAndroid Build Coastguard Worker# limitations under the License. 17*288bf522SAndroid Build Coastguard Worker# 18*288bf522SAndroid Build Coastguard Worker 19*288bf522SAndroid Build Coastguard Worker# This script will run as an pre-checkpointing cleanup for mounting f2fs 20*288bf522SAndroid Build Coastguard Worker# with checkpoint=disable, so that the first mount after the reboot will 21*288bf522SAndroid Build Coastguard Worker# be faster. It is unnecessary to run if the device does not use userdata 22*288bf522SAndroid Build Coastguard Worker# checkpointing on F2FS. 23*288bf522SAndroid Build Coastguard Worker 24*288bf522SAndroid Build Coastguard Worker# TARGET_SLOT="${1}" 25*288bf522SAndroid Build Coastguard WorkerSTATUS_FD="${2}" 26*288bf522SAndroid Build Coastguard Worker 27*288bf522SAndroid Build Coastguard WorkerSLEEP=5 28*288bf522SAndroid Build Coastguard WorkerTIME=0 29*288bf522SAndroid Build Coastguard WorkerMAX_TIME=1200 30*288bf522SAndroid Build Coastguard Worker 31*288bf522SAndroid Build Coastguard Worker# GC_URGENT_MID, will fall back to GC_URGENT_HIGH if unsupported 32*288bf522SAndroid Build Coastguard WorkerGC_TYPE=3 33*288bf522SAndroid Build Coastguard Worker 34*288bf522SAndroid Build Coastguard Worker# If we fall back, start off with less impactful GC 35*288bf522SAndroid Build Coastguard Worker# To avoid long wait time, ramp up over time 36*288bf522SAndroid Build Coastguard WorkerGC_SLEEP_MAX=150 37*288bf522SAndroid Build Coastguard WorkerGC_SLEEP_MIN=50 38*288bf522SAndroid Build Coastguard WorkerGC_SLEEP_STEP=5 39*288bf522SAndroid Build Coastguard Worker 40*288bf522SAndroid Build Coastguard Worker# We only need to run this if we're using f2fs 41*288bf522SAndroid Build Coastguard Workerif [ ! -f /dev/sys/fs/by-name/userdata/gc_urgent ]; then 42*288bf522SAndroid Build Coastguard Worker exit 0 43*288bf522SAndroid Build Coastguard Workerfi 44*288bf522SAndroid Build Coastguard Worker 45*288bf522SAndroid Build Coastguard Worker# If we have sufficient free segments, it doesn't matter how much extra 46*288bf522SAndroid Build Coastguard Worker# space is unusable, since we only need to make it to boot complete to 47*288bf522SAndroid Build Coastguard Worker# get that space back 48*288bf522SAndroid Build Coastguard WorkerMIN_FREE_SEGMENT=500 49*288bf522SAndroid Build Coastguard Worker 50*288bf522SAndroid Build Coastguard Worker# Ideally we want to track unusable, as it directly measures what we 51*288bf522SAndroid Build Coastguard Worker# care about. If it's not present, dirty_segments is the best proxy. 52*288bf522SAndroid Build Coastguard Workerif [ -f /dev/sys/fs/by-name/userdata/unusable ]; then 53*288bf522SAndroid Build Coastguard Worker UNUSABLE=1 54*288bf522SAndroid Build Coastguard Worker METRIC="unusable blocks" 55*288bf522SAndroid Build Coastguard Worker THRESHOLD=25000 56*288bf522SAndroid Build Coastguard Worker MAX_INCREASE=500 57*288bf522SAndroid Build Coastguard Worker read START < /dev/sys/fs/by-name/userdata/unusable 58*288bf522SAndroid Build Coastguard Workerelse 59*288bf522SAndroid Build Coastguard Worker METRIC="dirty segments" 60*288bf522SAndroid Build Coastguard Worker THRESHOLD=200 61*288bf522SAndroid Build Coastguard Worker MAX_INCREASE=5 62*288bf522SAndroid Build Coastguard Worker read START < /dev/sys/fs/by-name/userdata/dirty_segments 63*288bf522SAndroid Build Coastguard Workerfi 64*288bf522SAndroid Build Coastguard Worker 65*288bf522SAndroid Build Coastguard Workerlog -pi -t checkpoint_gc Turning on GC for userdata 66*288bf522SAndroid Build Coastguard Worker 67*288bf522SAndroid Build Coastguard Workerread OLD_SLEEP < /dev/sys/fs/by-name/userdata/gc_urgent_sleep_time || \ 68*288bf522SAndroid Build Coastguard Worker { log -pw -t checkpoint_gc Cannot read gc_urgent_sleep_time; exit 1; } 69*288bf522SAndroid Build Coastguard WorkerGC_SLEEP=${GC_SLEEP_MAX} 70*288bf522SAndroid Build Coastguard Workerecho ${GC_SLEEP} > /dev/sys/fs/by-name/userdata/gc_urgent_sleep_time || \ 71*288bf522SAndroid Build Coastguard Worker { log -pw -t checkpoint_gc Cannot set gc_urgent_sleep_time; exit 1; } 72*288bf522SAndroid Build Coastguard Worker 73*288bf522SAndroid Build Coastguard Worker 74*288bf522SAndroid Build Coastguard Workerecho ${GC_TYPE} > /dev/sys/fs/by-name/userdata/gc_urgent \ 75*288bf522SAndroid Build Coastguard Worker || { GC_TYPE=1; log -pi -t checkpoint_gc GC_URGENT_MID not supported, using GC_URGENT_HIGH; } 76*288bf522SAndroid Build Coastguard Worker 77*288bf522SAndroid Build Coastguard Workerif [ ${GC_TYPE} -eq 1 ]; then 78*288bf522SAndroid Build Coastguard Worker echo ${GC_TYPE} > /dev/sys/fs/by-name/userdata/gc_urgent || \ 79*288bf522SAndroid Build Coastguard Worker { echo ${OLD_SLEEP} > /dev/sys/fs/by-name/userdata/gc_urgent_sleep_time; \ 80*288bf522SAndroid Build Coastguard Worker log -pw -t checkpoint_gc Failed to set gc_urgent; exit 1; } 81*288bf522SAndroid Build Coastguard Workerelse 82*288bf522SAndroid Build Coastguard Worker # GC MID will wait for background I/O, so no need to start small 83*288bf522SAndroid Build Coastguard Worker GC_SLEEP=${GC_SLEEP_MIN} 84*288bf522SAndroid Build Coastguard Workerfi 85*288bf522SAndroid Build Coastguard Worker 86*288bf522SAndroid Build Coastguard Worker 87*288bf522SAndroid Build Coastguard WorkerCURRENT=${START} 88*288bf522SAndroid Build Coastguard WorkerTODO=$((${START}-${THRESHOLD})) 89*288bf522SAndroid Build Coastguard WorkerCUTOFF=$((${START} + ${MAX_INCREASE})) 90*288bf522SAndroid Build Coastguard Workerwhile [ ${CURRENT} -gt ${THRESHOLD} ]; do 91*288bf522SAndroid Build Coastguard Worker log -pi -t checkpoint_gc ${METRIC}:${CURRENT} \(threshold:${THRESHOLD}\) mode:${GC_TYPE} GC_SLEEP:${GC_SLEEP} 92*288bf522SAndroid Build Coastguard Worker PROGRESS=`echo "(${START}-${CURRENT})/${TODO}"|bc -l` 93*288bf522SAndroid Build Coastguard Worker if [[ $PROGRESS == -* ]]; then 94*288bf522SAndroid Build Coastguard Worker PROGRESS=0 95*288bf522SAndroid Build Coastguard Worker fi 96*288bf522SAndroid Build Coastguard Worker print -u${STATUS_FD} "global_progress ${PROGRESS}" 97*288bf522SAndroid Build Coastguard Worker if [ ${UNUSABLE} -eq 1 ]; then 98*288bf522SAndroid Build Coastguard Worker read CURRENT < /dev/sys/fs/by-name/userdata/unusable 99*288bf522SAndroid Build Coastguard Worker else 100*288bf522SAndroid Build Coastguard Worker read CURRENT < /dev/sys/fs/by-name/userdata/dirty_segments 101*288bf522SAndroid Build Coastguard Worker fi 102*288bf522SAndroid Build Coastguard Worker 103*288bf522SAndroid Build Coastguard Worker if [ ${CURRENT} -gt ${CUTOFF} ]; then 104*288bf522SAndroid Build Coastguard Worker log -pw -t checkpoint_gc Garbage Collection is making no progress. Aborting checkpoint_gc attempt \(initial ${METRIC}: ${START}, now: ${CURRENT}\) 105*288bf522SAndroid Build Coastguard Worker break 106*288bf522SAndroid Build Coastguard Worker fi 107*288bf522SAndroid Build Coastguard Worker 108*288bf522SAndroid Build Coastguard Worker read CURRENT_FREE_SEGMENTS < /dev/sys/fs/by-name/userdata/free_segments 109*288bf522SAndroid Build Coastguard Worker read CURRENT_OVP < /dev/sys/fs/by-name/userdata/ovp_segments 110*288bf522SAndroid Build Coastguard Worker CURRENT_FREE_SEG=$((${CURRENT_FREE_SEGMENTS}-${CURRENT_OVP})) 111*288bf522SAndroid Build Coastguard Worker if [ ${CURRENT_FREE_SEG} -gt ${MIN_FREE_SEGMENT} ]; then 112*288bf522SAndroid Build Coastguard Worker log -pi checkpoint_gc Sufficient free segments. Extra gc not needed. 113*288bf522SAndroid Build Coastguard Worker break 114*288bf522SAndroid Build Coastguard Worker fi 115*288bf522SAndroid Build Coastguard Worker 116*288bf522SAndroid Build Coastguard Worker sleep ${SLEEP} 117*288bf522SAndroid Build Coastguard Worker TIME=$((${TIME}+${SLEEP})) 118*288bf522SAndroid Build Coastguard Worker if [ ${TIME} -gt ${MAX_TIME} ]; then 119*288bf522SAndroid Build Coastguard Worker log -pw -t checkpoint_gc Timed out with gc threshold not met. 120*288bf522SAndroid Build Coastguard Worker break 121*288bf522SAndroid Build Coastguard Worker fi 122*288bf522SAndroid Build Coastguard Worker if [ ${GC_SLEEP} -gt ${GC_SLEEP_MIN} ]; then 123*288bf522SAndroid Build Coastguard Worker GC_SLEEP=$((${GC_SLEEP}-${GC_SLEEP_STEP})) 124*288bf522SAndroid Build Coastguard Worker fi 125*288bf522SAndroid Build Coastguard Worker # In case someone turns it off behind our back 126*288bf522SAndroid Build Coastguard Worker echo ${GC_SLEEP} > /dev/sys/fs/by-name/userdata/gc_urgent_sleep_time 127*288bf522SAndroid Build Coastguard Worker echo ${GC_TYPE} > /dev/sys/fs/by-name/userdata/gc_urgent 128*288bf522SAndroid Build Coastguard Workerdone 129*288bf522SAndroid Build Coastguard Worker 130*288bf522SAndroid Build Coastguard Worker# It could be a while before the system reboots for the update... 131*288bf522SAndroid Build Coastguard Worker# Leaving on low level GC can help ensure the boot for ota is faster 132*288bf522SAndroid Build Coastguard Worker# If powerhints decides to turn it off, we'll just rely on normal GC 133*288bf522SAndroid Build Coastguard Workerlog -pi -t checkpoint_gc Leaving on GC_URGENT_LOW for userdata 134*288bf522SAndroid Build Coastguard Workerecho ${OLD_SLEEP} > /dev/sys/fs/by-name/userdata/gc_urgent_sleep_time 135*288bf522SAndroid Build Coastguard Workerecho 2 > /dev/sys/fs/by-name/userdata/gc_urgent 136*288bf522SAndroid Build Coastguard Workersync 137*288bf522SAndroid Build Coastguard Worker 138*288bf522SAndroid Build Coastguard Workerprint -u${STATUS_FD} "global_progress 1.0" 139*288bf522SAndroid Build Coastguard Workerexit 0 140