1*4882a593Smuzhiyun#!/bin/bash 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun# Copyright (c) 2012 Wind River Systems, Inc. 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun# Global vars 9*4882a593Smuzhiyuncache_dir= 10*4882a593Smuzhiyunconfirm= 11*4882a593Smuzhiyunfsym= 12*4882a593Smuzhiyuntotal_deleted=0 13*4882a593Smuzhiyunverbose= 14*4882a593Smuzhiyundebug=0 15*4882a593Smuzhiyun 16*4882a593Smuzhiyunusage () { 17*4882a593Smuzhiyun cat << EOF 18*4882a593SmuzhiyunWelcome to sstate cache management utilities. 19*4882a593Smuzhiyunsstate-cache-management.sh <OPTION> 20*4882a593Smuzhiyun 21*4882a593SmuzhiyunOptions: 22*4882a593Smuzhiyun -h, --help 23*4882a593Smuzhiyun Display this help and exit. 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun --cache-dir=<sstate cache dir> 26*4882a593Smuzhiyun Specify sstate cache directory, will use the environment 27*4882a593Smuzhiyun variable SSTATE_CACHE_DIR if it is not specified. 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun --extra-archs=<arch1>,<arch2>...<archn> 30*4882a593Smuzhiyun Specify list of architectures which should be tested, this list 31*4882a593Smuzhiyun will be extended with native arch, allarch and empty arch. The 32*4882a593Smuzhiyun script won't be trying to generate list of available archs from 33*4882a593Smuzhiyun AVAILTUNES in tune files. 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun --extra-layer=<layer1>,<layer2>...<layern> 36*4882a593Smuzhiyun Specify the layer which will be used for searching the archs, 37*4882a593Smuzhiyun it will search the meta and meta-* layers in the top dir by 38*4882a593Smuzhiyun default, and will search meta, meta-*, <layer1>, <layer2>, 39*4882a593Smuzhiyun ...<layern> when specified. Use "," as the separator. 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun This is useless for --stamps-dir or when --extra-archs is used. 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun -d, --remove-duplicated 44*4882a593Smuzhiyun Remove the duplicated sstate cache files of one package, only 45*4882a593Smuzhiyun the newest one will be kept. The duplicated sstate cache files 46*4882a593Smuzhiyun of one package must have the same arch, which means sstate cache 47*4882a593Smuzhiyun files with multiple archs are not considered duplicate. 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun Conflicts with --stamps-dir. 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun --stamps-dir=<dir1>,<dir2>...<dirn> 52*4882a593Smuzhiyun Specify the build directory's stamps directories, the sstate 53*4882a593Smuzhiyun cache file which IS USED by these build diretories will be KEPT, 54*4882a593Smuzhiyun other sstate cache files in cache-dir will be removed. Use "," 55*4882a593Smuzhiyun as the separator. For example: 56*4882a593Smuzhiyun --stamps-dir=build1/tmp/stamps,build2/tmp/stamps 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun Conflicts with --remove-duplicated. 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun -L, --follow-symlink 61*4882a593Smuzhiyun Remove both the symbol link and the destination file, default: no. 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun -y, --yes 64*4882a593Smuzhiyun Automatic yes to prompts; assume "yes" as answer to all prompts 65*4882a593Smuzhiyun and run non-interactively. 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun -v, --verbose 68*4882a593Smuzhiyun Explain what is being done. 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun -D, --debug 71*4882a593Smuzhiyun Show debug info, repeat for more debug info. 72*4882a593Smuzhiyun 73*4882a593SmuzhiyunEOF 74*4882a593Smuzhiyun} 75*4882a593Smuzhiyun 76*4882a593Smuzhiyunif [ $# -lt 1 ]; then 77*4882a593Smuzhiyun usage 78*4882a593Smuzhiyun exit 0 79*4882a593Smuzhiyunfi 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun# Echo no files to remove 82*4882a593Smuzhiyunno_files () { 83*4882a593Smuzhiyun echo No files to remove 84*4882a593Smuzhiyun} 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun# Echo nothing to do 87*4882a593Smuzhiyundo_nothing () { 88*4882a593Smuzhiyun echo Nothing to do 89*4882a593Smuzhiyun} 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun# Read the input "y" 92*4882a593Smuzhiyunread_confirm () { 93*4882a593Smuzhiyun echo "$total_deleted out of $total_files files will be removed! " 94*4882a593Smuzhiyun if [ "$confirm" != "y" ]; then 95*4882a593Smuzhiyun echo "Do you want to continue (y/n)? " 96*4882a593Smuzhiyun while read confirm; do 97*4882a593Smuzhiyun [ "$confirm" = "Y" -o "$confirm" = "y" -o "$confirm" = "n" \ 98*4882a593Smuzhiyun -o "$confirm" = "N" ] && break 99*4882a593Smuzhiyun echo "Invalid input \"$confirm\", please input 'y' or 'n': " 100*4882a593Smuzhiyun done 101*4882a593Smuzhiyun else 102*4882a593Smuzhiyun echo 103*4882a593Smuzhiyun fi 104*4882a593Smuzhiyun} 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun# Print error information and exit. 107*4882a593Smuzhiyunecho_error () { 108*4882a593Smuzhiyun echo "ERROR: $1" >&2 109*4882a593Smuzhiyun exit 1 110*4882a593Smuzhiyun} 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun# Generate the remove list: 113*4882a593Smuzhiyun# 114*4882a593Smuzhiyun# * Add .done/.siginfo to the remove list 115*4882a593Smuzhiyun# * Add destination of symlink to the remove list 116*4882a593Smuzhiyun# 117*4882a593Smuzhiyun# $1: output file, others: sstate cache file (.tar.zst) 118*4882a593Smuzhiyungen_rmlist (){ 119*4882a593Smuzhiyun local rmlist_file="$1" 120*4882a593Smuzhiyun shift 121*4882a593Smuzhiyun local files="$@" 122*4882a593Smuzhiyun for i in $files; do 123*4882a593Smuzhiyun echo $i >> $rmlist_file 124*4882a593Smuzhiyun # Add the ".siginfo" 125*4882a593Smuzhiyun if [ -e $i.siginfo ]; then 126*4882a593Smuzhiyun echo $i.siginfo >> $rmlist_file 127*4882a593Smuzhiyun fi 128*4882a593Smuzhiyun # Add the destination of symlink 129*4882a593Smuzhiyun if [ -L "$i" ]; then 130*4882a593Smuzhiyun if [ "$fsym" = "y" ]; then 131*4882a593Smuzhiyun dest="`readlink -e $i`" 132*4882a593Smuzhiyun if [ -n "$dest" ]; then 133*4882a593Smuzhiyun echo $dest >> $rmlist_file 134*4882a593Smuzhiyun # Remove the .siginfo when .tar.zst is removed 135*4882a593Smuzhiyun if [ -f "$dest.siginfo" ]; then 136*4882a593Smuzhiyun echo $dest.siginfo >> $rmlist_file 137*4882a593Smuzhiyun fi 138*4882a593Smuzhiyun fi 139*4882a593Smuzhiyun fi 140*4882a593Smuzhiyun # Add the ".tar.zst.done" and ".siginfo.done" (may exist in the future) 141*4882a593Smuzhiyun base_fn="${i##/*/}" 142*4882a593Smuzhiyun t_fn="$base_fn.done" 143*4882a593Smuzhiyun s_fn="$base_fn.siginfo.done" 144*4882a593Smuzhiyun for d in $t_fn $s_fn; do 145*4882a593Smuzhiyun if [ -f $cache_dir/$d ]; then 146*4882a593Smuzhiyun echo $cache_dir/$d >> $rmlist_file 147*4882a593Smuzhiyun fi 148*4882a593Smuzhiyun done 149*4882a593Smuzhiyun fi 150*4882a593Smuzhiyun done 151*4882a593Smuzhiyun} 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun# Remove the duplicated cache files for the pkg, keep the newest one 154*4882a593Smuzhiyunremove_duplicated () { 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun local topdir 157*4882a593Smuzhiyun local oe_core_dir 158*4882a593Smuzhiyun local tunedirs 159*4882a593Smuzhiyun local all_archs 160*4882a593Smuzhiyun local all_machines 161*4882a593Smuzhiyun local ava_archs 162*4882a593Smuzhiyun local arch 163*4882a593Smuzhiyun local file_names 164*4882a593Smuzhiyun local sstate_files_list 165*4882a593Smuzhiyun local fn_tmp 166*4882a593Smuzhiyun local list_suffix=`mktemp` || exit 1 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun if [ -z "$extra_archs" ] ; then 169*4882a593Smuzhiyun # Find out the archs in all the layers 170*4882a593Smuzhiyun echo "Figuring out the archs in the layers ... " 171*4882a593Smuzhiyun oe_core_dir=$(dirname $(dirname $(readlink -e $0))) 172*4882a593Smuzhiyun topdir=$(dirname $oe_core_dir) 173*4882a593Smuzhiyun tunedirs="`find $topdir/meta* ${oe_core_dir}/meta* $layers -path '*/meta*/conf/machine/include' 2>/dev/null`" 174*4882a593Smuzhiyun [ -n "$tunedirs" ] || echo_error "Can't find the tune directory" 175*4882a593Smuzhiyun all_machines="`find $topdir/meta* ${oe_core_dir}/meta* $layers -path '*/meta*/conf/machine/*' -name '*.conf' 2>/dev/null | sed -e 's/.*\///' -e 's/.conf$//'`" 176*4882a593Smuzhiyun all_archs=`grep -r -h "^AVAILTUNES .*=" $tunedirs | sed -e 's/.*=//' -e 's/\"//g'` 177*4882a593Smuzhiyun fi 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun # Use the "_" to substitute "-", e.g., x86-64 to x86_64, but not for extra_archs which can be something like cortexa9t2-vfp-neon 180*4882a593Smuzhiyun # Sort to remove the duplicated ones 181*4882a593Smuzhiyun # Add allarch and builder arch (native) 182*4882a593Smuzhiyun builder_arch=$(uname -m) 183*4882a593Smuzhiyun all_archs="$(echo allarch $all_archs $all_machines $builder_arch \ 184*4882a593Smuzhiyun | sed -e 's/-/_/g' -e 's/ /\n/g' | sort -u) $extra_archs" 185*4882a593Smuzhiyun echo "Done" 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun # Total number of files including sstate-, .siginfo and .done files 188*4882a593Smuzhiyun total_files=`find $cache_dir -name 'sstate*' | wc -l` 189*4882a593Smuzhiyun # Save all the sstate files in a file 190*4882a593Smuzhiyun sstate_files_list=`mktemp` || exit 1 191*4882a593Smuzhiyun find $cache_dir -iname 'sstate:*:*:*:*:*:*:*.tar.zst*' >$sstate_files_list 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun echo "Figuring out the suffixes in the sstate cache dir ... " 194*4882a593Smuzhiyun sstate_suffixes="`sed 's%.*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^_]*_\([^:]*\)\.tar\.zst.*%\1%g' $sstate_files_list | sort -u`" 195*4882a593Smuzhiyun echo "Done" 196*4882a593Smuzhiyun echo "The following suffixes have been found in the cache dir:" 197*4882a593Smuzhiyun echo $sstate_suffixes 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun echo "Figuring out the archs in the sstate cache dir ... " 200*4882a593Smuzhiyun # Using this SSTATE_PKGSPEC definition it's 6th colon separated field 201*4882a593Smuzhiyun # SSTATE_PKGSPEC = "sstate:${PN}:${PACKAGE_ARCH}${TARGET_VENDOR}-${TARGET_OS}:${PV}:${PR}:${SSTATE_PKGARCH}:${SSTATE_VERSION}:" 202*4882a593Smuzhiyun for arch in $all_archs; do 203*4882a593Smuzhiyun grep -q ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:$arch:[^:]*:[^:]*\.tar\.zst$" $sstate_files_list 204*4882a593Smuzhiyun [ $? -eq 0 ] && ava_archs="$ava_archs $arch" 205*4882a593Smuzhiyun # ${builder_arch}_$arch used by toolchain sstate 206*4882a593Smuzhiyun grep -q ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:${builder_arch}_$arch:[^:]*:[^:]*\.tar\.zst$" $sstate_files_list 207*4882a593Smuzhiyun [ $? -eq 0 ] && ava_archs="$ava_archs ${builder_arch}_$arch" 208*4882a593Smuzhiyun done 209*4882a593Smuzhiyun echo "Done" 210*4882a593Smuzhiyun echo "The following archs have been found in the cache dir:" 211*4882a593Smuzhiyun echo $ava_archs 212*4882a593Smuzhiyun echo "" 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun # Save the file list which needs to be removed 215*4882a593Smuzhiyun local remove_listdir=`mktemp -d` || exit 1 216*4882a593Smuzhiyun for suffix in $sstate_suffixes; do 217*4882a593Smuzhiyun if [ "$suffix" = "populate_lic" ] ; then 218*4882a593Smuzhiyun echo "Skipping populate_lic, because removing duplicates doesn't work correctly for them (use --stamps-dir instead)" 219*4882a593Smuzhiyun continue 220*4882a593Smuzhiyun fi 221*4882a593Smuzhiyun # Total number of files including .siginfo and .done files 222*4882a593Smuzhiyun total_files_suffix=`grep ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:_]*_$suffix\.tar\.zst.*" $sstate_files_list | wc -l 2>/dev/null` 223*4882a593Smuzhiyun total_archive_suffix=`grep ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:_]*_$suffix\.tar\.zst$" $sstate_files_list | wc -l 2>/dev/null` 224*4882a593Smuzhiyun # Save the file list to a file, some suffix's file may not exist 225*4882a593Smuzhiyun grep ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:_]*_$suffix\.tar\.zst.*" $sstate_files_list >$list_suffix 2>/dev/null 226*4882a593Smuzhiyun local deleted_archives=0 227*4882a593Smuzhiyun local deleted_files=0 228*4882a593Smuzhiyun for ext in tar.zst tar.zst.siginfo tar.zst.done; do 229*4882a593Smuzhiyun echo "Figuring out the sstate:xxx_$suffix.$ext ... " 230*4882a593Smuzhiyun # Uniq BPNs 231*4882a593Smuzhiyun file_names=`for arch in $ava_archs ""; do 232*4882a593Smuzhiyun sed -ne "s%.*/sstate:\([^:]*\):[^:]*:[^:]*:[^:]*:$arch:[^:]*:[^:]*\.${ext}$%\1%p" $list_suffix 233*4882a593Smuzhiyun done | sort -u` 234*4882a593Smuzhiyun 235*4882a593Smuzhiyun fn_tmp=`mktemp` || exit 1 236*4882a593Smuzhiyun rm_list="$remove_listdir/sstate:xxx_$suffix" 237*4882a593Smuzhiyun for fn in $file_names; do 238*4882a593Smuzhiyun [ -z "$verbose" ] || echo "Analyzing sstate:$fn-xxx_$suffix.${ext}" 239*4882a593Smuzhiyun for arch in $ava_archs ""; do 240*4882a593Smuzhiyun grep -h ".*/sstate:$fn:[^:]*:[^:]*:[^:]*:$arch:[^:]*:[^:]*\.${ext}$" $list_suffix >$fn_tmp 241*4882a593Smuzhiyun if [ -s $fn_tmp ] ; then 242*4882a593Smuzhiyun [ $debug -gt 1 ] && echo "Available files for $fn-$arch- with suffix $suffix.${ext}:" && cat $fn_tmp 243*4882a593Smuzhiyun # Use the modification time 244*4882a593Smuzhiyun to_del=$(ls -t $(cat $fn_tmp) | sed -n '1!p') 245*4882a593Smuzhiyun [ $debug -gt 2 ] && echo "Considering to delete: $to_del" 246*4882a593Smuzhiyun # The sstate file which is downloaded from the SSTATE_MIRROR is 247*4882a593Smuzhiyun # put in SSTATE_DIR, and there is a symlink in SSTATE_DIR/??/ to 248*4882a593Smuzhiyun # it, so filter it out from the remove list if it should not be 249*4882a593Smuzhiyun # removed. 250*4882a593Smuzhiyun to_keep=$(ls -t $(cat $fn_tmp) | sed -n '1p') 251*4882a593Smuzhiyun [ $debug -gt 2 ] && echo "Considering to keep: $to_keep" 252*4882a593Smuzhiyun for k in $to_keep; do 253*4882a593Smuzhiyun if [ -L "$k" ]; then 254*4882a593Smuzhiyun # The symlink's destination 255*4882a593Smuzhiyun k_dest="`readlink -e $k`" 256*4882a593Smuzhiyun # Maybe it is the one in cache_dir 257*4882a593Smuzhiyun k_maybe="$cache_dir/${k##/*/}" 258*4882a593Smuzhiyun # Remove it from the remove list if they are the same. 259*4882a593Smuzhiyun if [ "$k_dest" = "$k_maybe" ]; then 260*4882a593Smuzhiyun to_del="`echo $to_del | sed 's#'\"$k_maybe\"'##g'`" 261*4882a593Smuzhiyun fi 262*4882a593Smuzhiyun fi 263*4882a593Smuzhiyun done 264*4882a593Smuzhiyun rm -f $fn_tmp 265*4882a593Smuzhiyun [ $debug -gt 2 ] && echo "Decided to delete: $to_del" 266*4882a593Smuzhiyun gen_rmlist $rm_list.$ext "$to_del" 267*4882a593Smuzhiyun fi 268*4882a593Smuzhiyun done 269*4882a593Smuzhiyun done 270*4882a593Smuzhiyun done 271*4882a593Smuzhiyun deleted_archives=`cat $rm_list.* 2>/dev/null | grep "\.tar\.zst$" | wc -l` 272*4882a593Smuzhiyun deleted_files=`cat $rm_list.* 2>/dev/null | wc -l` 273*4882a593Smuzhiyun [ "$deleted_files" -gt 0 -a $debug -gt 0 ] && cat $rm_list.* 274*4882a593Smuzhiyun echo "($deleted_archives out of $total_archives_suffix .tar.zst files for $suffix suffix will be removed or $deleted_files out of $total_files_suffix when counting also .siginfo and .done files)" 275*4882a593Smuzhiyun let total_deleted=$total_deleted+$deleted_files 276*4882a593Smuzhiyun done 277*4882a593Smuzhiyun deleted_archives=0 278*4882a593Smuzhiyun rm_old_list=$remove_listdir/sstate-old-filenames 279*4882a593Smuzhiyun find $cache_dir -name 'sstate-*.tar.zst' >$rm_old_list 280*4882a593Smuzhiyun [ -s "$rm_old_list" ] && deleted_archives=`cat $rm_old_list | grep "\.tar\.zst$" | wc -l` 281*4882a593Smuzhiyun [ -s "$rm_old_list" ] && deleted_files=`cat $rm_old_list | wc -l` 282*4882a593Smuzhiyun [ -s "$rm_old_list" -a $debug -gt 0 ] && cat $rm_old_list 283*4882a593Smuzhiyun echo "($deleted_archives or .tar.zst files with old sstate-* filenames will be removed or $deleted_files when counting also .siginfo and .done files)" 284*4882a593Smuzhiyun let total_deleted=$total_deleted+$deleted_files 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun rm -f $list_suffix 287*4882a593Smuzhiyun rm -f $sstate_files_list 288*4882a593Smuzhiyun if [ $total_deleted -gt 0 ]; then 289*4882a593Smuzhiyun read_confirm 290*4882a593Smuzhiyun if [ "$confirm" = "y" -o "$confirm" = "Y" ]; then 291*4882a593Smuzhiyun for list in `ls $remove_listdir/`; do 292*4882a593Smuzhiyun echo "Removing $list.tar.zst archive (`cat $remove_listdir/$list | wc -w` files) ... " 293*4882a593Smuzhiyun # Remove them one by one to avoid the argument list too long error 294*4882a593Smuzhiyun for i in `cat $remove_listdir/$list`; do 295*4882a593Smuzhiyun rm -f $verbose $i 296*4882a593Smuzhiyun done 297*4882a593Smuzhiyun echo "Done" 298*4882a593Smuzhiyun done 299*4882a593Smuzhiyun echo "$total_deleted files have been removed!" 300*4882a593Smuzhiyun else 301*4882a593Smuzhiyun do_nothing 302*4882a593Smuzhiyun fi 303*4882a593Smuzhiyun else 304*4882a593Smuzhiyun no_files 305*4882a593Smuzhiyun fi 306*4882a593Smuzhiyun [ -d $remove_listdir ] && rm -fr $remove_listdir 307*4882a593Smuzhiyun} 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun# Remove the sstate file by stamps dir, the file not used by the stamps dir 310*4882a593Smuzhiyun# will be removed. 311*4882a593Smuzhiyunrm_by_stamps (){ 312*4882a593Smuzhiyun 313*4882a593Smuzhiyun local cache_list=`mktemp` || exit 1 314*4882a593Smuzhiyun local keep_list=`mktemp` || exit 1 315*4882a593Smuzhiyun local rm_list=`mktemp` || exit 1 316*4882a593Smuzhiyun local sums 317*4882a593Smuzhiyun local all_sums 318*4882a593Smuzhiyun 319*4882a593Smuzhiyun # Total number of files including sstate-, .siginfo and .done files 320*4882a593Smuzhiyun total_files=`find $cache_dir -type f -name 'sstate*' | wc -l` 321*4882a593Smuzhiyun # Save all the state file list to a file 322*4882a593Smuzhiyun find $cache_dir -type f -name 'sstate*' | sort -u -o $cache_list 323*4882a593Smuzhiyun 324*4882a593Smuzhiyun echo "Figuring out the suffixes in the sstate cache dir ... " 325*4882a593Smuzhiyun local sstate_suffixes="`sed 's%.*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^_]*_\([^:]*\)\.tar\.zst.*%\1%g' $cache_list | sort -u`" 326*4882a593Smuzhiyun echo "Done" 327*4882a593Smuzhiyun echo "The following suffixes have been found in the cache dir:" 328*4882a593Smuzhiyun echo $sstate_suffixes 329*4882a593Smuzhiyun 330*4882a593Smuzhiyun # Figure out all the md5sums in the stamps dir. 331*4882a593Smuzhiyun echo "Figuring out all the md5sums in stamps dir ... " 332*4882a593Smuzhiyun for i in $sstate_suffixes; do 333*4882a593Smuzhiyun # There is no "\.sigdata" but "_setcene" when it is mirrored 334*4882a593Smuzhiyun # from the SSTATE_MIRRORS, use them to figure out the sum. 335*4882a593Smuzhiyun sums=`find $stamps -maxdepth 3 -name "*.do_$i.*" \ 336*4882a593Smuzhiyun -o -name "*.do_${i}_setscene.*" | \ 337*4882a593Smuzhiyun sed -ne 's#.*_setscene\.##p' -e 's#.*\.sigdata\.##p' | \ 338*4882a593Smuzhiyun sed -e 's#\..*##' | sort -u` 339*4882a593Smuzhiyun all_sums="$all_sums $sums" 340*4882a593Smuzhiyun done 341*4882a593Smuzhiyun echo "Done" 342*4882a593Smuzhiyun 343*4882a593Smuzhiyun echo "Figuring out the files which will be removed ... " 344*4882a593Smuzhiyun for i in $all_sums; do 345*4882a593Smuzhiyun grep ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:${i}_.*" $cache_list >>$keep_list 346*4882a593Smuzhiyun done 347*4882a593Smuzhiyun echo "Done" 348*4882a593Smuzhiyun 349*4882a593Smuzhiyun if [ -s $keep_list ]; then 350*4882a593Smuzhiyun sort -u $keep_list -o $keep_list 351*4882a593Smuzhiyun to_del=`comm -1 -3 $keep_list $cache_list` 352*4882a593Smuzhiyun gen_rmlist $rm_list "$to_del" 353*4882a593Smuzhiyun let total_deleted=`cat $rm_list | sort -u | wc -w` 354*4882a593Smuzhiyun if [ $total_deleted -gt 0 ]; then 355*4882a593Smuzhiyun [ $debug -gt 0 ] && cat $rm_list | sort -u 356*4882a593Smuzhiyun read_confirm 357*4882a593Smuzhiyun if [ "$confirm" = "y" -o "$confirm" = "Y" ]; then 358*4882a593Smuzhiyun echo "Removing sstate cache files ... ($total_deleted files)" 359*4882a593Smuzhiyun # Remove them one by one to avoid the argument list too long error 360*4882a593Smuzhiyun for i in `cat $rm_list | sort -u`; do 361*4882a593Smuzhiyun rm -f $verbose $i 362*4882a593Smuzhiyun done 363*4882a593Smuzhiyun echo "$total_deleted files have been removed" 364*4882a593Smuzhiyun else 365*4882a593Smuzhiyun do_nothing 366*4882a593Smuzhiyun fi 367*4882a593Smuzhiyun else 368*4882a593Smuzhiyun no_files 369*4882a593Smuzhiyun fi 370*4882a593Smuzhiyun else 371*4882a593Smuzhiyun echo_error "All files in cache dir will be removed! Abort!" 372*4882a593Smuzhiyun fi 373*4882a593Smuzhiyun 374*4882a593Smuzhiyun rm -f $cache_list 375*4882a593Smuzhiyun rm -f $keep_list 376*4882a593Smuzhiyun rm -f $rm_list 377*4882a593Smuzhiyun} 378*4882a593Smuzhiyun 379*4882a593Smuzhiyun# Parse arguments 380*4882a593Smuzhiyunwhile [ -n "$1" ]; do 381*4882a593Smuzhiyun case $1 in 382*4882a593Smuzhiyun --cache-dir=*) 383*4882a593Smuzhiyun cache_dir=`echo $1 | sed -e 's#^--cache-dir=##' | xargs readlink -e` 384*4882a593Smuzhiyun [ -d "$cache_dir" ] || echo_error "Invalid argument to --cache-dir" 385*4882a593Smuzhiyun shift 386*4882a593Smuzhiyun ;; 387*4882a593Smuzhiyun --remove-duplicated|-d) 388*4882a593Smuzhiyun rm_duplicated="y" 389*4882a593Smuzhiyun shift 390*4882a593Smuzhiyun ;; 391*4882a593Smuzhiyun --yes|-y) 392*4882a593Smuzhiyun confirm="y" 393*4882a593Smuzhiyun shift 394*4882a593Smuzhiyun ;; 395*4882a593Smuzhiyun --follow-symlink|-L) 396*4882a593Smuzhiyun fsym="y" 397*4882a593Smuzhiyun shift 398*4882a593Smuzhiyun ;; 399*4882a593Smuzhiyun --extra-archs=*) 400*4882a593Smuzhiyun extra_archs=`echo $1 | sed -e 's#^--extra-archs=##' -e 's#,# #g'` 401*4882a593Smuzhiyun [ -n "$extra_archs" ] || echo_error "Invalid extra arch parameter" 402*4882a593Smuzhiyun shift 403*4882a593Smuzhiyun ;; 404*4882a593Smuzhiyun --extra-layer=*) 405*4882a593Smuzhiyun extra_layers=`echo $1 | sed -e 's#^--extra-layer=##' -e 's#,# #g'` 406*4882a593Smuzhiyun [ -n "$extra_layers" ] || echo_error "Invalid extra layer parameter" 407*4882a593Smuzhiyun for i in $extra_layers; do 408*4882a593Smuzhiyun l=`readlink -e $i` 409*4882a593Smuzhiyun if [ -d "$l" ]; then 410*4882a593Smuzhiyun layers="$layers $l" 411*4882a593Smuzhiyun else 412*4882a593Smuzhiyun echo_error "Can't find layer $i" 413*4882a593Smuzhiyun fi 414*4882a593Smuzhiyun done 415*4882a593Smuzhiyun shift 416*4882a593Smuzhiyun ;; 417*4882a593Smuzhiyun --stamps-dir=*) 418*4882a593Smuzhiyun stamps=`echo $1 | sed -e 's#^--stamps-dir=##' -e 's#,# #g'` 419*4882a593Smuzhiyun [ -n "$stamps" ] || echo_error "Invalid stamps dir $i" 420*4882a593Smuzhiyun for i in $stamps; do 421*4882a593Smuzhiyun [ -d "$i" ] || echo_error "Invalid stamps dir $i" 422*4882a593Smuzhiyun done 423*4882a593Smuzhiyun shift 424*4882a593Smuzhiyun ;; 425*4882a593Smuzhiyun --verbose|-v) 426*4882a593Smuzhiyun verbose="-v" 427*4882a593Smuzhiyun shift 428*4882a593Smuzhiyun ;; 429*4882a593Smuzhiyun --debug|-D) 430*4882a593Smuzhiyun debug=`expr $debug + 1` 431*4882a593Smuzhiyun echo "Debug level $debug" 432*4882a593Smuzhiyun shift 433*4882a593Smuzhiyun ;; 434*4882a593Smuzhiyun --help|-h) 435*4882a593Smuzhiyun usage 436*4882a593Smuzhiyun exit 0 437*4882a593Smuzhiyun ;; 438*4882a593Smuzhiyun *) 439*4882a593Smuzhiyun echo "Invalid arguments $*" 440*4882a593Smuzhiyun echo_error "Try 'sstate-cache-management.sh -h' for more information." 441*4882a593Smuzhiyun ;; 442*4882a593Smuzhiyun esac 443*4882a593Smuzhiyundone 444*4882a593Smuzhiyun 445*4882a593Smuzhiyun# sstate cache directory, use environment variable SSTATE_CACHE_DIR 446*4882a593Smuzhiyun# if it was not specified, otherwise, error. 447*4882a593Smuzhiyun[ -n "$cache_dir" ] || cache_dir=$SSTATE_CACHE_DIR 448*4882a593Smuzhiyun[ -n "$cache_dir" ] || echo_error "No cache dir found!" 449*4882a593Smuzhiyun[ -d "$cache_dir" ] || echo_error "Invalid cache directory \"$cache_dir\"" 450*4882a593Smuzhiyun 451*4882a593Smuzhiyun[ -n "$rm_duplicated" -a -n "$stamps" ] && \ 452*4882a593Smuzhiyun echo_error "Can not use both --remove-duplicated and --stamps-dir" 453*4882a593Smuzhiyun 454*4882a593Smuzhiyun[ "$rm_duplicated" = "y" ] && remove_duplicated 455*4882a593Smuzhiyun[ -n "$stamps" ] && rm_by_stamps 456*4882a593Smuzhiyun[ -z "$rm_duplicated" -a -z "$stamps" ] && \ 457*4882a593Smuzhiyun echo "What do you want to do?" 458*4882a593Smuzhiyunexit 0 459