xref: /OK3568_Linux_fs/yocto/scripts/sstate-cache-management.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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