diff --git a/tools/README b/tools/README index 6035c03c2dca09f087af7bd3588ef582da6f9299..5e340a03d87e2606654fd9b51f288cbc70646582 100644 --- a/tools/README +++ b/tools/README @@ -3,6 +3,15 @@ which are used in building and validating the policy and others are available for help in auditing and analyzing policy. The tools are described further below. +build_policies.sh + A tool to build SELinux policy for multiple targets in parallel. + This is useful for quickly testing a new test or neverallow rule + on multiple targets. + + Usage: + ./build_policies.sh ~/android/master ~/tmp/build_policies + ./build_policies.sh ~/android/master ~/tmp/build_policies sailfish-eng walleye-eng + checkfc A utility for checking the validity of a file_contexts or a property_contexts configuration file. Used as part of the policy diff --git a/tools/build_policies.sh b/tools/build_policies.sh new file mode 100644 index 0000000000000000000000000000000000000000..77f0fc6ca3e4f96b6dd64760f1a499cc4549a6f1 --- /dev/null +++ b/tools/build_policies.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +# Ensure that GNU parallel is installed. +# We use this to build multiple targets at the same time. +if [[ -z $(command -v parallel) ]]; then + echo "Please install GNU Parallel." + exit +fi + +if [[ $# -lt 2 ]]; then + echo "Usage: $0 <Android root directory> <output directory> [specific targets to build]" + exit +fi + +android_root_dir=$1 +export out_dir=$2 +shift 2 +all_targets="$@" + +echo "Android tree: $android_root_dir" +echo "Output directory: $out_dir" + +mkdir -p $out_dir + +cd $android_root_dir +source build/envsetup.sh > /dev/null + +# Collect the list of targets by parsing the output of lunch. +# TODO: This misses some targets. +if [[ "$all_targets" = "" ]]; then + all_targets=`lunch 2>/dev/null <<< _ | grep "[0-9]" | sed 's/^.* //'` +fi + +# Clean up targets by replacing eng with userdebug using non-aosp variants. +declare -A targets_map +for target in $all_targets; do + targets_map[$target]=$target +done +targets="" +for target in $all_targets; do + clean_target=$(echo $target | sed 's/-eng/-userdebug/' | sed 's/aosp_//') + if [[ $clean_target != $target ]] && [[ ${targets_map[$clean_target]} == $clean_target ]]; then + echo "Ignoring $target in favor of $clean_target" + else + if [[ -z $targets ]]; then + targets=$target + else + targets="$targets $target" + fi + fi +done + +# Calculate the number of targets to build at once. +# This heuristic could probably be improved. +cores=$(nproc --all) +num_targets=$(echo "$targets" | sed 's/ /\n/g' | wc -l) +parallel_jobs=$(expr $cores / 2) +if [[ $num_targets -lt $parallel_jobs ]]; then + export mmma_jobs=$(expr $cores / $num_targets \* 2) +else + export mmma_jobs=4 +fi + +echo "$num_targets target(s): $(echo $targets | paste -sd' ')" + +compile_target () { + target=$1 + source build/envsetup.sh > /dev/null + lunch $target &> /dev/null + # Some targets can't lunch properly. + if [ $? -ne 0 ]; then + echo "$target cannot be lunched" + return 1 + fi + my_out_file="$out_dir/log.$target" + rm -f $my_out_file + # Build the policy. + OUT_DIR=$out_dir/out.$target mmma -j$mmma_jobs system/sepolicy &>> $my_out_file + if [ $? -ne 0 ]; then + echo "$target failed to build" + return 2 + fi + return 0 +} +export -f compile_target + +parallel --no-notice -j $parallel_jobs --bar --joblog $out_dir/joblog compile_target ::: $targets + +echo "Failed to lunch: $(grep "\s1\s0\scompile_target" $out_dir/joblog | sed 's/^.* //' | sort | paste -sd' ')" +echo "Failed to build: $(grep "\s2\s0\scompile_target" $out_dir/joblog | sed 's/^.* //' | sort | paste -sd' ')"