sstate-cache-management.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. #!/bin/bash
  2. # Copyright (c) 2012 Wind River Systems, Inc.
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License version 2 as
  6. # published by the Free Software Foundation.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. # See the GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software
  15. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. #
  17. # Global vars
  18. cache_dir=
  19. confirm=
  20. fsym=
  21. total_deleted=0
  22. verbose=
  23. debug=0
  24. usage () {
  25. cat << EOF
  26. Welcome to sstate cache management utilities.
  27. sstate-cache-management.sh <OPTION>
  28. Options:
  29. -h, --help
  30. Display this help and exit.
  31. --cache-dir=<sstate cache dir>
  32. Specify sstate cache directory, will use the environment
  33. variable SSTATE_CACHE_DIR if it is not specified.
  34. --extra-layer=<layer1>,<layer2>...<layern>
  35. Specify the layer which will be used for searching the archs,
  36. it will search the meta and meta-* layers in the top dir by
  37. default, and will search meta, meta-*, <layer1>, <layer2>,
  38. ...<layern> when specified. Use "," as the separator.
  39. This is useless for --stamps-dir.
  40. -d, --remove-duplicated
  41. Remove the duplicated sstate cache files of one package, only
  42. the newest one will be kept. The duplicated sstate cache files
  43. of one package must have the same arch, which means sstate cache
  44. files with multiple archs are not considered duplicate.
  45. Conflicts with --stamps-dir.
  46. --stamps-dir=<dir1>,<dir2>...<dirn>
  47. Specify the build directory's stamps directories, the sstate
  48. cache file which IS USED by these build diretories will be KEPT,
  49. other sstate cache files in cache-dir will be removed. Use ","
  50. as the separator. For example:
  51. --stamps-dir=build1/tmp/stamps,build2/tmp/stamps
  52. Conflicts with --remove-duplicated.
  53. -L, --follow-symlink
  54. Rmove both the symbol link and the destination file, default: no.
  55. -y, --yes
  56. Automatic yes to prompts; assume "yes" as answer to all prompts
  57. and run non-interactively.
  58. -v, --verbose
  59. explain what is being done
  60. -D, --debug
  61. show debug info, repeat for more debug info
  62. EOF
  63. }
  64. if [ $# -lt 1 ]; then
  65. usage
  66. exit 0
  67. fi
  68. # Echo no files to remove
  69. no_files () {
  70. echo No files to remove
  71. }
  72. # Echo nothing to do
  73. do_nothing () {
  74. echo Nothing to do
  75. }
  76. # Read the input "y"
  77. read_confirm () {
  78. echo -n "$total_deleted files will be removed! "
  79. if [ "$confirm" != "y" ]; then
  80. echo -n "Do you want to continue (y/n)? "
  81. while read confirm; do
  82. [ "$confirm" = "Y" -o "$confirm" = "y" -o "$confirm" = "n" \
  83. -o "$confirm" = "N" ] && break
  84. echo -n "Invalid input \"$confirm\", please input 'y' or 'n': "
  85. done
  86. else
  87. echo
  88. fi
  89. }
  90. # Print error information and exit.
  91. echo_error () {
  92. echo "ERROR: $1" >&2
  93. exit 1
  94. }
  95. # Generate the remove list:
  96. #
  97. # * Add .done/.siginfo to the remove list
  98. # * Add destination of symlink to the remove list
  99. #
  100. # $1: output file, others: sstate cache file (.tgz)
  101. gen_rmlist (){
  102. local rmlist_file="$1"
  103. shift
  104. local files="$@"
  105. for i in $files; do
  106. echo $i >> $rmlist_file
  107. # Add the ".siginfo"
  108. if [ -e $i.siginfo ]; then
  109. echo $i.siginfo >> $rmlist_file
  110. fi
  111. # Add the destination of symlink
  112. if [ -L "$i" ]; then
  113. if [ "$fsym" = "y" ]; then
  114. dest="`readlink -e $i`"
  115. if [ -n "$dest" ]; then
  116. echo $dest >> $rmlist_file
  117. # Remove the .siginfo when .tgz is removed
  118. if [ -f "$dest.siginfo" ]; then
  119. echo $dest.siginfo >> $rmlist_file
  120. fi
  121. fi
  122. fi
  123. # Add the ".tgz.done" and ".siginfo.done" (may exist in the future)
  124. base_fn="${i##/*/}"
  125. t_fn="$base_fn.done"
  126. s_fn="$base_fn.siginfo.done"
  127. for d in $t_fn $s_fn; do
  128. if [ -f $cache_dir/$d ]; then
  129. echo $cache_dir/$d >> $rmlist_file
  130. fi
  131. done
  132. fi
  133. done
  134. }
  135. # Remove the duplicated cache files for the pkg, keep the newest one
  136. remove_duplicated () {
  137. local topdir
  138. local oe_core_dir
  139. local tunedirs
  140. local all_archs
  141. local all_machines
  142. local ava_archs
  143. local arch
  144. local file_names
  145. local sstate_list
  146. local fn_tmp
  147. local list_suffix=`mktemp` || exit 1
  148. # Find out the archs in all the layers
  149. echo -n "Figuring out the archs in the layers ... "
  150. oe_core_dir=$(dirname $(dirname $(readlink -e $0)))
  151. topdir=$(dirname $oe_core_dir)
  152. tunedirs="`find $topdir/meta* ${oe_core_dir}/meta* $layers -path '*/meta*/conf/machine/include' 2>/dev/null`"
  153. [ -n "$tunedirs" ] || echo_error "Can't find the tune directory"
  154. 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$//'`"
  155. all_archs=`grep -r -h "^AVAILTUNES .*=" $tunedirs | sed -e 's/.*=//' -e 's/\"//g'`
  156. # Add the qemu and native archs
  157. # Use the "_" to substitute "-", e.g., x86-64 to x86_64
  158. # Sort to remove the duplicated ones
  159. all_archs=$(echo $all_archs $all_machines $(uname -m) \
  160. | sed -e 's/-/_/g' -e 's/ /\n/g' | sort -u)
  161. echo "Done"
  162. # Save all the sstate files in a file
  163. sstate_list=`mktemp` || exit 1
  164. find $cache_dir -name 'sstate-*.tgz' >$sstate_list
  165. echo -n "Figuring out the suffixes in the sstate cache dir ... "
  166. sstate_suffixes="`sed 's/.*_\([^_]*\)\.tgz$/\1/g' $sstate_list | sort -u`"
  167. echo "Done"
  168. echo "The following suffixes have been found in the cache dir:"
  169. echo $sstate_suffixes
  170. echo -n "Figuring out the archs in the sstate cache dir ... "
  171. for arch in $all_archs; do
  172. grep -q "\-$arch-" $sstate_list
  173. [ $? -eq 0 ] && ava_archs="$ava_archs $arch"
  174. done
  175. echo "Done"
  176. echo "The following archs have been found in the cache dir:"
  177. echo $ava_archs
  178. echo ""
  179. # Save the file list which needs to be removed
  180. local remove_listdir=`mktemp -d` || exit 1
  181. for suffix in $sstate_suffixes; do
  182. # Save the file list to a file, some suffix's file may not exist
  183. grep "sstate-.*_$suffix.tgz" $sstate_list >$list_suffix 2>/dev/null
  184. local deleted=0
  185. echo -n "Figuring out the sstate-xxx_$suffix.tgz ... "
  186. # There are at list 6 dashes (-) after arch, use this to avoid the
  187. # greedy match of sed.
  188. file_names=`for arch in $ava_archs; do
  189. sed -ne 's#.*/\(sstate-.*\)-'"$arch"'-.*-.*-.*-.*-.*-.*#\1#p' $list_suffix
  190. done | sort -u`
  191. fn_tmp=`mktemp` || exit 1
  192. rm_list="$remove_listdir/sstate-xxx_$suffix"
  193. for fn in $file_names; do
  194. [ -z "$verbose" ] || echo "Analyzing $fn-xxx_$suffix.tgz"
  195. for arch in $ava_archs; do
  196. grep -h "/$fn-$arch-" $list_suffix >$fn_tmp
  197. if [ -s $fn_tmp ] ; then
  198. [ $debug -gt 1 ] && echo "Available files for $fn-$arch- with suffix $suffix:" && cat $fn_tmp
  199. # Use the modification time
  200. to_del=$(ls -t $(cat $fn_tmp) | sed -n '1!p')
  201. [ $debug -gt 2 ] && echo "Considering to delete: $to_del"
  202. # The sstate file which is downloaded from the SSTATE_MIRROR is
  203. # put in SSTATE_DIR, and there is a symlink in SSTATE_DIR/??/ to
  204. # it, so filter it out from the remove list if it should not be
  205. # removed.
  206. to_keep=$(ls -t $(cat $fn_tmp) | sed -n '1p')
  207. [ $debug -gt 2 ] && echo "Considering to keep: $to_keep"
  208. for k in $to_keep; do
  209. if [ -L "$k" ]; then
  210. # The symlink's destination
  211. k_dest="`readlink -e $k`"
  212. # Maybe it is the one in cache_dir
  213. k_maybe="$cache_dir/${k##/*/}"
  214. # Remove it from the remove list if they are the same.
  215. if [ "$k_dest" = "$k_maybe" ]; then
  216. to_del="`echo $to_del | sed 's#'\"$k_maybe\"'##g'`"
  217. fi
  218. fi
  219. done
  220. rm -f $fn_tmp
  221. [ $debug -gt 2 ] && echo "Decided to delete: $to_del"
  222. gen_rmlist $rm_list "$to_del"
  223. fi
  224. done
  225. done
  226. [ ! -s "$rm_list" ] || deleted=`cat $rm_list | wc -l`
  227. [ -s "$rm_list" -a $debug -gt 0 ] && cat $rm_list
  228. echo "($deleted files will be removed)"
  229. let total_deleted=$total_deleted+$deleted
  230. done
  231. rm -f $list_suffix
  232. rm -f $sstate_list
  233. if [ $total_deleted -gt 0 ]; then
  234. read_confirm
  235. if [ "$confirm" = "y" -o "$confirm" = "Y" ]; then
  236. for list in `ls $remove_listdir/`; do
  237. echo -n "Removing $list.tgz (`cat $remove_listdir/$list | wc -w` files) ... "
  238. # Remove them one by one to avoid the argument list too long error
  239. for i in `cat $remove_listdir/$list`; do
  240. rm -f $verbose $i
  241. done
  242. echo "Done"
  243. done
  244. echo "$total_deleted files have been removed!"
  245. else
  246. do_nothing
  247. fi
  248. else
  249. no_files
  250. fi
  251. [ -d $remove_listdir ] && rm -fr $remove_listdir
  252. }
  253. # Remove the sstate file by stamps dir, the file not used by the stamps dir
  254. # will be removed.
  255. rm_by_stamps (){
  256. local cache_list=`mktemp` || exit 1
  257. local keep_list=`mktemp` || exit 1
  258. local rm_list=`mktemp` || exit 1
  259. local suffixes
  260. local sums
  261. local all_sums
  262. suffixes="populate_sysroot populate_lic package_write_ipk \
  263. package_write_rpm package_write_deb package deploy"
  264. # Figure out all the md5sums in the stamps dir.
  265. echo -n "Figuring out all the md5sums in stamps dir ... "
  266. for i in $suffixes; do
  267. # There is no "\.sigdata" but "_setcene" when it is mirrored
  268. # from the SSTATE_MIRRORS, use them to figure out the sum.
  269. sums=`find $stamps -maxdepth 3 -name "*.do_$i.*" \
  270. -o -name "*.do_${i}_setscene.*" | \
  271. sed -ne 's#.*_setscene\.##p' -e 's#.*\.sigdata\.##p' | \
  272. sed -e 's#\..*##' | sort -u`
  273. all_sums="$all_sums $sums"
  274. done
  275. echo "Done"
  276. # Save all the state file list to a file
  277. find $cache_dir -name 'sstate-*.tgz' | sort -u -o $cache_list
  278. echo -n "Figuring out the files which will be removed ... "
  279. for i in $all_sums; do
  280. grep ".*-${i}_.*" $cache_list >>$keep_list
  281. done
  282. echo "Done"
  283. if [ -s $keep_list ]; then
  284. sort -u $keep_list -o $keep_list
  285. to_del=`comm -1 -3 $keep_list $cache_list`
  286. gen_rmlist $rm_list "$to_del"
  287. let total_deleted=(`cat $rm_list | wc -w`)
  288. if [ $total_deleted -gt 0 ]; then
  289. [ $debug -gt 0 ] && cat $rm_list
  290. read_confirm
  291. if [ "$confirm" = "y" -o "$confirm" = "Y" ]; then
  292. echo "Removing sstate cache files ... ($total_deleted files)"
  293. # Remove them one by one to avoid the argument list too long error
  294. for i in `cat $rm_list`; do
  295. rm -f $verbose $i
  296. done
  297. echo "$total_deleted files have been removed"
  298. else
  299. do_nothing
  300. fi
  301. else
  302. no_files
  303. fi
  304. else
  305. echo_error "All files in cache dir will be removed! Abort!"
  306. fi
  307. rm -f $cache_list
  308. rm -f $keep_list
  309. rm -f $rm_list
  310. }
  311. # Parse arguments
  312. while [ -n "$1" ]; do
  313. case $1 in
  314. --cache-dir=*)
  315. cache_dir=`echo $1 | sed -e 's#^--cache-dir=##' | xargs readlink -e`
  316. [ -d "$cache_dir" ] || echo_error "Invalid argument to --cache-dir"
  317. shift
  318. ;;
  319. --remove-duplicated|-d)
  320. rm_duplicated="y"
  321. shift
  322. ;;
  323. --yes|-y)
  324. confirm="y"
  325. shift
  326. ;;
  327. --follow-symlink|-L)
  328. fsym="y"
  329. shift
  330. ;;
  331. --extra-layer=*)
  332. extra_layers=`echo $1 | sed -e 's#^--extra-layer=##' -e 's#,# #g'`
  333. [ -n "$extra_layers" ] || echo_error "Invalid extra layer $i"
  334. for i in $extra_layers; do
  335. l=`readlink -e $i`
  336. if [ -d "$l" ]; then
  337. layers="$layers $l"
  338. else
  339. echo_error "Can't find layer $i"
  340. fi
  341. done
  342. shift
  343. ;;
  344. --stamps-dir=*)
  345. stamps=`echo $1 | sed -e 's#^--stamps-dir=##' -e 's#,# #g'`
  346. [ -n "$stamps" ] || echo_error "Invalid stamps dir $i"
  347. for i in $stamps; do
  348. [ -d "$i" ] || echo_error "Invalid stamps dir $i"
  349. done
  350. shift
  351. ;;
  352. --verbose|-v)
  353. verbose="-v"
  354. shift
  355. ;;
  356. --debug|-D)
  357. debug=`expr $debug + 1`
  358. echo "Debug level $debug"
  359. shift
  360. ;;
  361. --help|-h)
  362. usage
  363. exit 0
  364. ;;
  365. *)
  366. echo "Invalid arguments $*"
  367. echo_error "Try 'sstate-cache-management.sh -h' for more information."
  368. ;;
  369. esac
  370. done
  371. # sstate cache directory, use environment variable SSTATE_CACHE_DIR
  372. # if it was not specified, otherwise, error.
  373. [ -n "$cache_dir" ] || cache_dir=$SSTATE_CACHE_DIR
  374. [ -n "$cache_dir" ] || echo_error "No cache dir found!"
  375. [ -d "$cache_dir" ] || echo_error "Invalid cache directory \"$cache_dir\""
  376. [ -n "$rm_duplicated" -a -n "$stamps" ] && \
  377. echo_error "Can not use both --remove-duplicated and --stamps-dir"
  378. [ "$rm_duplicated" = "y" ] && remove_duplicated
  379. [ -n "$stamps" ] && rm_by_stamps
  380. [ -z "$rm_duplicated" -a -z "$stamps" ] && \
  381. echo "What do you want to do?"
  382. exit 0