xref: /aosp_15_r20/external/bpftool/scripts/sync-kernel.sh (revision 858ea5e570667251cdc31d3fe7b846b591105938)
1*858ea5e5SAndroid Build Coastguard Worker#!/usr/bin/env bash
2*858ea5e5SAndroid Build Coastguard Worker
3*858ea5e5SAndroid Build Coastguard Workerusage () {
4*858ea5e5SAndroid Build Coastguard Worker	echo "USAGE: ./sync-kernel.sh <bpftool-repo> <kernel-repo>"
5*858ea5e5SAndroid Build Coastguard Worker	echo ""
6*858ea5e5SAndroid Build Coastguard Worker	echo "This script synchronizes the mirror with upstream bpftool sources from the kernel repository."
7*858ea5e5SAndroid Build Coastguard Worker	echo "It performs the following steps:"
8*858ea5e5SAndroid Build Coastguard Worker	echo "  - Update the libbpf submodule, commit, and use its new checkpoints as target commits for bpftool."
9*858ea5e5SAndroid Build Coastguard Worker	echo "  - Cherry-pick commits from the bpf-next branch, up to the bpf-next target commit."
10*858ea5e5SAndroid Build Coastguard Worker	echo "  - Cherry-pick commits from the bpf branch, up to the bpf target commit."
11*858ea5e5SAndroid Build Coastguard Worker	echo "  - Create a new commit with the updated version and checkpoints."
12*858ea5e5SAndroid Build Coastguard Worker	echo "  - Check consistency."
13*858ea5e5SAndroid Build Coastguard Worker	echo ""
14*858ea5e5SAndroid Build Coastguard Worker	echo "Set BPF_NEXT_BASELINE to override bpf-next tree commit, otherwise read from <bpftool-repo>/CHECKPOINT-COMMIT."
15*858ea5e5SAndroid Build Coastguard Worker	echo "Set BPF_BASELINE to override bpf tree commit, otherwise read from <bpftool-repo>/BPF-CHECKPOINT-COMMIT."
16*858ea5e5SAndroid Build Coastguard Worker	echo "Set BPF_NEXT_TIP_COMMIT to override bpf-next tree target commit, otherwise read from <bpftool-repo>/libbpf/CHECKPOINT-COMMIT, after libbpf update."
17*858ea5e5SAndroid Build Coastguard Worker	echo "Set BPF_TIP_COMMIT to override bpf tree target commit, otherwise read from <bpftool-repo>/libbpf/BPF-CHECKPOINT-COMMIT, after libbpf update."
18*858ea5e5SAndroid Build Coastguard Worker	echo "Set SKIP_LIBBPF_UPDATE to 1 to avoid updating libbpf automatically."
19*858ea5e5SAndroid Build Coastguard Worker	echo "Set MANUAL_MODE to 1 to manually control every cherry-picked commit."
20*858ea5e5SAndroid Build Coastguard Worker	exit 1
21*858ea5e5SAndroid Build Coastguard Worker}
22*858ea5e5SAndroid Build Coastguard Worker
23*858ea5e5SAndroid Build Coastguard Workerset -eu
24*858ea5e5SAndroid Build Coastguard Worker
25*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_REPO=${1-""}
26*858ea5e5SAndroid Build Coastguard WorkerLINUX_REPO=${2-""}
27*858ea5e5SAndroid Build Coastguard Worker
28*858ea5e5SAndroid Build Coastguard Workerif [ -z "${BPFTOOL_REPO}" ] || [ -z "${LINUX_REPO}" ]; then
29*858ea5e5SAndroid Build Coastguard Worker	echo "Error: bpftool or linux repos are not specified"
30*858ea5e5SAndroid Build Coastguard Worker	usage
31*858ea5e5SAndroid Build Coastguard Workerfi
32*858ea5e5SAndroid Build Coastguard Worker
33*858ea5e5SAndroid Build Coastguard WorkerBASELINE_COMMIT=${BPF_NEXT_BASELINE:-$(cat "${BPFTOOL_REPO}"/CHECKPOINT-COMMIT)}
34*858ea5e5SAndroid Build Coastguard WorkerBPF_BASELINE_COMMIT=${BPF_BASELINE:-$(cat "${BPFTOOL_REPO}"/BPF-CHECKPOINT-COMMIT)}
35*858ea5e5SAndroid Build Coastguard Worker
36*858ea5e5SAndroid Build Coastguard Workerif [ -z "${BASELINE_COMMIT}" ] || [ -z "${BPF_BASELINE_COMMIT}" ]; then
37*858ea5e5SAndroid Build Coastguard Worker	echo "Error: bpf or bpf-next baseline commits are not provided"
38*858ea5e5SAndroid Build Coastguard Worker	usage
39*858ea5e5SAndroid Build Coastguard Workerfi
40*858ea5e5SAndroid Build Coastguard Worker
41*858ea5e5SAndroid Build Coastguard WorkerSUFFIX=$(date --utc +%Y-%m-%dT%H-%M-%S.%3NZ)
42*858ea5e5SAndroid Build Coastguard WorkerWORKDIR=$(pwd)
43*858ea5e5SAndroid Build Coastguard WorkerTMP_DIR=$(mktemp -d)
44*858ea5e5SAndroid Build Coastguard Worker
45*858ea5e5SAndroid Build Coastguard Worker# shellcheck disable=SC2064
46*858ea5e5SAndroid Build Coastguard Workertrap "cd ${WORKDIR}; exit" INT TERM EXIT
47*858ea5e5SAndroid Build Coastguard Worker
48*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_SRC_DIR="tools/bpf/bpftool"
49*858ea5e5SAndroid Build Coastguard Worker
50*858ea5e5SAndroid Build Coastguard Workerdeclare -A PATH_MAP
51*858ea5e5SAndroid Build Coastguard WorkerPATH_MAP=(									\
52*858ea5e5SAndroid Build Coastguard Worker	[${BPFTOOL_SRC_DIR}]=src						\
53*858ea5e5SAndroid Build Coastguard Worker	[${BPFTOOL_SRC_DIR}/bash-completion]=bash-completion			\
54*858ea5e5SAndroid Build Coastguard Worker	[${BPFTOOL_SRC_DIR}/Documentation]=docs					\
55*858ea5e5SAndroid Build Coastguard Worker	[kernel/bpf/disasm.c]=src/kernel/bpf/disasm.c				\
56*858ea5e5SAndroid Build Coastguard Worker	[kernel/bpf/disasm.h]=src/kernel/bpf/disasm.h				\
57*858ea5e5SAndroid Build Coastguard Worker	[tools/include/tools/dis-asm-compat.h]=include/tools/dis-asm-compat.h	\
58*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/asm-generic/bitsperlong.h]=include/uapi/asm-generic/bitsperlong.h	\
59*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/bpf_common.h]=include/uapi/linux/bpf_common.h	\
60*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/bpf.h]=include/uapi/linux/bpf.h		\
61*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/btf.h]=include/uapi/linux/btf.h		\
62*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/const.h]=include/uapi/linux/const.h		\
63*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/if_link.h]=include/uapi/linux/if_link.h	\
64*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/netlink.h]=include/uapi/linux/netlink.h	\
65*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/perf_event.h]=include/uapi/linux/perf_event.h	\
66*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/pkt_cls.h]=include/uapi/linux/pkt_cls.h	\
67*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/pkt_sched.h]=include/uapi/linux/pkt_sched.h	\
68*858ea5e5SAndroid Build Coastguard Worker	[tools/include/uapi/linux/tc_act/tc_bpf.h]=include/uapi/linux/tc_act/tc_bpf.h	\
69*858ea5e5SAndroid Build Coastguard Worker)
70*858ea5e5SAndroid Build Coastguard Worker
71*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_PATHS=( "${!PATH_MAP[@]}" )
72*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_VIEW_PATHS=( "${PATH_MAP[@]}" )
73*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_VIEW_EXCLUDE_REGEX='^(docs/\.gitignore|src/Makefile\.(feature|include))$'
74*858ea5e5SAndroid Build Coastguard WorkerLINUX_VIEW_EXCLUDE_REGEX='^$'
75*858ea5e5SAndroid Build Coastguard Worker
76*858ea5e5SAndroid Build Coastguard Worker# Deal with tools/bpf/bpftool first, because once we've mkdir-ed src/, command
77*858ea5e5SAndroid Build Coastguard Worker# "git mv" doesn't move bpftool _as_ src but _into_ src/.
78*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_TREE_FILTER="mkdir __bpftool && "$'\\\n'
79*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_TREE_FILTER+="git mv -kf ${BPFTOOL_SRC_DIR} __bpftool/${PATH_MAP[${BPFTOOL_SRC_DIR}]} && "$'\\\n'
80*858ea5e5SAndroid Build Coastguard Worker
81*858ea5e5SAndroid Build Coastguard Worker# Extract bash-completion and Documentation from src/.
82*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_TREE_FILTER+="git mv -kf __bpftool/src/bash-completion __bpftool/bash-completion && "$'\\\n'
83*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_TREE_FILTER+="git mv -kf __bpftool/src/Documentation __bpftool/docs && "$'\\\n'
84*858ea5e5SAndroid Build Coastguard Worker
85*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_TREE_FILTER+="mkdir -p __bpftool/include/tools __bpftool/include/uapi/asm-generic __bpftool/include/uapi/linux/tc_act __bpftool/src/kernel/bpf && "$'\\\n'
86*858ea5e5SAndroid Build Coastguard Workerfor p in "${!PATH_MAP[@]}"; do
87*858ea5e5SAndroid Build Coastguard Worker	case ${p} in
88*858ea5e5SAndroid Build Coastguard Worker		${BPFTOOL_SRC_DIR}*)
89*858ea5e5SAndroid Build Coastguard Worker			continue;;
90*858ea5e5SAndroid Build Coastguard Worker	esac
91*858ea5e5SAndroid Build Coastguard Worker	BPFTOOL_TREE_FILTER+="git mv -kf ${p} __bpftool/${PATH_MAP[${p}]} && "$'\\\n'
92*858ea5e5SAndroid Build Coastguard Workerdone
93*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_TREE_FILTER+="true >/dev/null"
94*858ea5e5SAndroid Build Coastguard Worker
95*858ea5e5SAndroid Build Coastguard Workercd_to()
96*858ea5e5SAndroid Build Coastguard Worker{
97*858ea5e5SAndroid Build Coastguard Worker	cd "${WORKDIR}" && cd "$1"
98*858ea5e5SAndroid Build Coastguard Worker}
99*858ea5e5SAndroid Build Coastguard Worker
100*858ea5e5SAndroid Build Coastguard Worker# Output brief single-line commit description
101*858ea5e5SAndroid Build Coastguard Worker# $1 - commit ref
102*858ea5e5SAndroid Build Coastguard Workercommit_desc()
103*858ea5e5SAndroid Build Coastguard Worker{
104*858ea5e5SAndroid Build Coastguard Worker	git log -n1 --pretty='%h ("%s")' "$1"
105*858ea5e5SAndroid Build Coastguard Worker}
106*858ea5e5SAndroid Build Coastguard Worker
107*858ea5e5SAndroid Build Coastguard Worker# Create commit single-line signature, which consists of:
108*858ea5e5SAndroid Build Coastguard Worker# - full commit subject
109*858ea5e5SAndroid Build Coastguard Worker# - author date in ISO8601 format
110*858ea5e5SAndroid Build Coastguard Worker# - full commit body with newlines replaced with vertical bars (|)
111*858ea5e5SAndroid Build Coastguard Worker# - shortstat appended at the end
112*858ea5e5SAndroid Build Coastguard Worker# The idea is that this single-line signature is good enough to make final
113*858ea5e5SAndroid Build Coastguard Worker# decision about whether two commits are the same, across different repos.
114*858ea5e5SAndroid Build Coastguard Worker# $1 - commit ref
115*858ea5e5SAndroid Build Coastguard Worker# $2 - paths filter
116*858ea5e5SAndroid Build Coastguard Workercommit_signature()
117*858ea5e5SAndroid Build Coastguard Worker{
118*858ea5e5SAndroid Build Coastguard Worker	# shellcheck disable=SC2086
119*858ea5e5SAndroid Build Coastguard Worker	git show --pretty='("%s")|%aI|%b' --shortstat "$1" -- ${2-.} | tr '\n' '|'
120*858ea5e5SAndroid Build Coastguard Worker}
121*858ea5e5SAndroid Build Coastguard Worker
122*858ea5e5SAndroid Build Coastguard Worker# Cherry-pick commits touching bpftool-related files
123*858ea5e5SAndroid Build Coastguard Worker# $1 - baseline_tag
124*858ea5e5SAndroid Build Coastguard Worker# $2 - tip_tag
125*858ea5e5SAndroid Build Coastguard Workercherry_pick_commits()
126*858ea5e5SAndroid Build Coastguard Worker{
127*858ea5e5SAndroid Build Coastguard Worker	local manual_mode=${MANUAL_MODE:-0}
128*858ea5e5SAndroid Build Coastguard Worker	local baseline_tag=$1
129*858ea5e5SAndroid Build Coastguard Worker	local tip_tag=$2
130*858ea5e5SAndroid Build Coastguard Worker	local new_commits
131*858ea5e5SAndroid Build Coastguard Worker	local signature
132*858ea5e5SAndroid Build Coastguard Worker	local should_skip
133*858ea5e5SAndroid Build Coastguard Worker	local synced_cnt
134*858ea5e5SAndroid Build Coastguard Worker	local manual_check
135*858ea5e5SAndroid Build Coastguard Worker	local bpftool_conflict_cnt
136*858ea5e5SAndroid Build Coastguard Worker	local desc
137*858ea5e5SAndroid Build Coastguard Worker
138*858ea5e5SAndroid Build Coastguard Worker	# shellcheck disable=SC2068
139*858ea5e5SAndroid Build Coastguard Worker	new_commits=$(git rev-list --no-merges --topo-order --reverse "${baseline_tag}".."${tip_tag}" ${BPFTOOL_PATHS[@]})
140*858ea5e5SAndroid Build Coastguard Worker	for new_commit in ${new_commits}; do
141*858ea5e5SAndroid Build Coastguard Worker		if [[ "${baseline_tag}" == "${BPF_BASELINE_TAG}" ]]; then
142*858ea5e5SAndroid Build Coastguard Worker			if git merge-base --is-ancestor "${new_commit}" "${BASELINE_COMMIT}"; then
143*858ea5e5SAndroid Build Coastguard Worker				echo "Commit ${new_commit::12} from bpf is already in bpf-next branch, skipping."
144*858ea5e5SAndroid Build Coastguard Worker				continue
145*858ea5e5SAndroid Build Coastguard Worker			fi
146*858ea5e5SAndroid Build Coastguard Worker		fi
147*858ea5e5SAndroid Build Coastguard Worker		desc="$(commit_desc "${new_commit}")"
148*858ea5e5SAndroid Build Coastguard Worker		signature="$(commit_signature "${new_commit}" "${BPFTOOL_PATHS[*]}")"
149*858ea5e5SAndroid Build Coastguard Worker		# shellcheck disable=SC2126
150*858ea5e5SAndroid Build Coastguard Worker		synced_cnt=$(grep -F "${signature}" "${TMP_DIR}"/bpftool_commits.txt | wc -l)
151*858ea5e5SAndroid Build Coastguard Worker		manual_check=0
152*858ea5e5SAndroid Build Coastguard Worker		if (("${synced_cnt}" > 0)); then
153*858ea5e5SAndroid Build Coastguard Worker			# commit with the same subject is already in bpftool, but it's
154*858ea5e5SAndroid Build Coastguard Worker			# not 100% the same commit, so check with user
155*858ea5e5SAndroid Build Coastguard Worker			echo "Commit '${desc}' is synced into bpftool as:"
156*858ea5e5SAndroid Build Coastguard Worker			grep -F "${signature}" "${TMP_DIR}"/bpftool_commits.txt | \
157*858ea5e5SAndroid Build Coastguard Worker				cut -d'|' -f1 | sed -e 's/^/- /'
158*858ea5e5SAndroid Build Coastguard Worker			if (("${manual_mode}" != 1 && "${synced_cnt}" == 1)); then
159*858ea5e5SAndroid Build Coastguard Worker				echo "Skipping '${desc}' due to unique match..."
160*858ea5e5SAndroid Build Coastguard Worker				continue
161*858ea5e5SAndroid Build Coastguard Worker			fi
162*858ea5e5SAndroid Build Coastguard Worker			if (("${synced_cnt}" > 1)); then
163*858ea5e5SAndroid Build Coastguard Worker				echo "'${desc} matches multiple commits, please, double-check!"
164*858ea5e5SAndroid Build Coastguard Worker				manual_check=1
165*858ea5e5SAndroid Build Coastguard Worker			fi
166*858ea5e5SAndroid Build Coastguard Worker		fi
167*858ea5e5SAndroid Build Coastguard Worker		if (("${manual_mode}" == 1 || "${manual_check}" == 1)); then
168*858ea5e5SAndroid Build Coastguard Worker			read -rp "Do you want to skip '${desc}'? [y/N]: " should_skip
169*858ea5e5SAndroid Build Coastguard Worker			case "${should_skip}" in
170*858ea5e5SAndroid Build Coastguard Worker				"y" | "Y")
171*858ea5e5SAndroid Build Coastguard Worker					echo "Skipping '${desc}'..."
172*858ea5e5SAndroid Build Coastguard Worker					continue
173*858ea5e5SAndroid Build Coastguard Worker					;;
174*858ea5e5SAndroid Build Coastguard Worker			esac
175*858ea5e5SAndroid Build Coastguard Worker		fi
176*858ea5e5SAndroid Build Coastguard Worker		# commit hasn't been synced into bpftool yet
177*858ea5e5SAndroid Build Coastguard Worker		echo "Picking '${desc}'..."
178*858ea5e5SAndroid Build Coastguard Worker		if ! git cherry-pick "${new_commit}" &>/dev/null; then
179*858ea5e5SAndroid Build Coastguard Worker			echo "Warning! Cherry-picking '${desc} failed, checking if it's non-bpftool files causing problems..."
180*858ea5e5SAndroid Build Coastguard Worker			# shellcheck disable=SC2068
181*858ea5e5SAndroid Build Coastguard Worker			bpftool_conflict_cnt=$(git diff --name-only --diff-filter=U -- ${BPFTOOL_PATHS[@]} | wc -l)
182*858ea5e5SAndroid Build Coastguard Worker			conflict_cnt=$(git diff --name-only | wc -l)
183*858ea5e5SAndroid Build Coastguard Worker			prompt_resolution=1
184*858ea5e5SAndroid Build Coastguard Worker
185*858ea5e5SAndroid Build Coastguard Worker			if (("${bpftool_conflict_cnt}" == 0)); then
186*858ea5e5SAndroid Build Coastguard Worker				echo "Looks like only non-bpftool files have conflicts, ignoring..."
187*858ea5e5SAndroid Build Coastguard Worker				if (("${conflict_cnt}" == 0)); then
188*858ea5e5SAndroid Build Coastguard Worker					echo "Empty cherry-pick, skipping it..."
189*858ea5e5SAndroid Build Coastguard Worker					git cherry-pick --abort
190*858ea5e5SAndroid Build Coastguard Worker					continue
191*858ea5e5SAndroid Build Coastguard Worker				fi
192*858ea5e5SAndroid Build Coastguard Worker
193*858ea5e5SAndroid Build Coastguard Worker				git add .
194*858ea5e5SAndroid Build Coastguard Worker				# GIT_EDITOR=true to avoid editor popping up to edit commit message
195*858ea5e5SAndroid Build Coastguard Worker				if ! GIT_EDITOR=true git cherry-pick --continue &>/dev/null; then
196*858ea5e5SAndroid Build Coastguard Worker					echo "Error! That still failed! Please resolve manually."
197*858ea5e5SAndroid Build Coastguard Worker				else
198*858ea5e5SAndroid Build Coastguard Worker					echo "Success! All cherry-pick conflicts were resolved for '${desc}'!"
199*858ea5e5SAndroid Build Coastguard Worker					prompt_resolution=0
200*858ea5e5SAndroid Build Coastguard Worker				fi
201*858ea5e5SAndroid Build Coastguard Worker			fi
202*858ea5e5SAndroid Build Coastguard Worker
203*858ea5e5SAndroid Build Coastguard Worker			if (("${prompt_resolution}" == 1)); then
204*858ea5e5SAndroid Build Coastguard Worker				read -rp "Error! Cherry-picking '${desc}' failed, please fix manually and press <return> to proceed..."
205*858ea5e5SAndroid Build Coastguard Worker			fi
206*858ea5e5SAndroid Build Coastguard Worker		fi
207*858ea5e5SAndroid Build Coastguard Worker		# Append signature of just cherry-picked commit to avoid
208*858ea5e5SAndroid Build Coastguard Worker		# potentially cherry-picking the same commit twice later when
209*858ea5e5SAndroid Build Coastguard Worker		# processing bpf tree commits. At this point we don't know yet
210*858ea5e5SAndroid Build Coastguard Worker		# the final commit sha in bpftool repo, so we record Linux SHA
211*858ea5e5SAndroid Build Coastguard Worker		# instead as LINUX_<sha>.
212*858ea5e5SAndroid Build Coastguard Worker		echo "LINUX_$(git log --pretty='%h' -n1) ${signature}" >> "${TMP_DIR}"/bpftool_commits.txt
213*858ea5e5SAndroid Build Coastguard Worker	done
214*858ea5e5SAndroid Build Coastguard Worker}
215*858ea5e5SAndroid Build Coastguard Worker
216*858ea5e5SAndroid Build Coastguard Workercleanup()
217*858ea5e5SAndroid Build Coastguard Worker{
218*858ea5e5SAndroid Build Coastguard Worker	echo "Cleaning up..."
219*858ea5e5SAndroid Build Coastguard Worker	rm -r -- "${TMP_DIR}"
220*858ea5e5SAndroid Build Coastguard Worker	cd_to "${LINUX_REPO}"
221*858ea5e5SAndroid Build Coastguard Worker	git checkout "${TIP_SYM_REF}"
222*858ea5e5SAndroid Build Coastguard Worker	git branch -D "${BASELINE_TAG}" "${TIP_TAG}" "${BPF_BASELINE_TAG}" "${BPF_TIP_TAG}" \
223*858ea5e5SAndroid Build Coastguard Worker		      "${SQUASH_BASE_TAG}" "${SQUASH_TIP_TAG}" || true
224*858ea5e5SAndroid Build Coastguard Worker	# shellcheck disable=SC2015
225*858ea5e5SAndroid Build Coastguard Worker	git show-ref --verify --quiet refs/heads/"${VIEW_TAG}" && \
226*858ea5e5SAndroid Build Coastguard Worker		git branch -D "${VIEW_TAG}" || true
227*858ea5e5SAndroid Build Coastguard Worker
228*858ea5e5SAndroid Build Coastguard Worker	cd_to .
229*858ea5e5SAndroid Build Coastguard Worker	echo "DONE."
230*858ea5e5SAndroid Build Coastguard Worker}
231*858ea5e5SAndroid Build Coastguard Worker
232*858ea5e5SAndroid Build Coastguard Workercd_to "${BPFTOOL_REPO}"
233*858ea5e5SAndroid Build Coastguard WorkerBPFTOOL_SYNC_TAG="bpftool-sync-${SUFFIX}"
234*858ea5e5SAndroid Build Coastguard Workergit checkout -b "${BPFTOOL_SYNC_TAG}"
235*858ea5e5SAndroid Build Coastguard Worker
236*858ea5e5SAndroid Build Coastguard Worker# Update libbpf
237*858ea5e5SAndroid Build Coastguard Workerif [[ "${SKIP_LIBBPF_UPDATE:-0}" -ne 1 ]]; then
238*858ea5e5SAndroid Build Coastguard Worker	cd_to "${BPFTOOL_REPO}"/libbpf
239*858ea5e5SAndroid Build Coastguard Worker	git pull origin master
240*858ea5e5SAndroid Build Coastguard Worker	LIBBPF_VERSION=$(grep -oE '^LIBBPF_([0-9.]+)' src/libbpf.map | sort -rV | head -n1 | cut -d'_' -f2)
241*858ea5e5SAndroid Build Coastguard Worker	LIBBPF_COMMIT=$(git rev-parse HEAD)
242*858ea5e5SAndroid Build Coastguard Worker	cd_to "${BPFTOOL_REPO}"
243*858ea5e5SAndroid Build Coastguard Worker	if [[ -n "$(git status --porcelain --untracked-files=no)" ]]; then
244*858ea5e5SAndroid Build Coastguard Worker		git add libbpf
245*858ea5e5SAndroid Build Coastguard Worker		git commit --signoff -m 'sync: Update libbpf submodule' \
246*858ea5e5SAndroid Build Coastguard Worker			-m "\
247*858ea5e5SAndroid Build Coastguard WorkerPull latest libbpf from mirror.
248*858ea5e5SAndroid Build Coastguard WorkerLibbpf version: ${LIBBPF_VERSION}
249*858ea5e5SAndroid Build Coastguard WorkerLibbpf commit:  ${LIBBPF_COMMIT}" \
250*858ea5e5SAndroid Build Coastguard Worker			-- libbpf
251*858ea5e5SAndroid Build Coastguard Worker	fi
252*858ea5e5SAndroid Build Coastguard Workerfi
253*858ea5e5SAndroid Build Coastguard Worker
254*858ea5e5SAndroid Build Coastguard Worker# Use libbpf's new checkpoints as tips
255*858ea5e5SAndroid Build Coastguard WorkerTIP_COMMIT=${BPF_NEXT_TIP_COMMIT:-$(cat "${BPFTOOL_REPO}"/libbpf/CHECKPOINT-COMMIT)}
256*858ea5e5SAndroid Build Coastguard WorkerBPF_TIP_COMMIT=${BPF_TIP_COMMIT:-$(cat "${BPFTOOL_REPO}"/libbpf/BPF-CHECKPOINT-COMMIT)}
257*858ea5e5SAndroid Build Coastguard Workerif [ -z "${TIP_COMMIT}" ] || [ -z "${BPF_TIP_COMMIT}" ]; then
258*858ea5e5SAndroid Build Coastguard Worker	echo "Error: bpf or bpf-next tip commits are not provided"
259*858ea5e5SAndroid Build Coastguard Worker	usage
260*858ea5e5SAndroid Build Coastguard Workerfi
261*858ea5e5SAndroid Build Coastguard Worker
262*858ea5e5SAndroid Build Coastguard Workercd_to "${BPFTOOL_REPO}"
263*858ea5e5SAndroid Build Coastguard WorkerGITHUB_ABS_DIR=$(pwd)
264*858ea5e5SAndroid Build Coastguard Workerecho "Dumping existing bpftool commit signatures..."
265*858ea5e5SAndroid Build Coastguard Workerfor h in $(git log --pretty='%h' -n500); do
266*858ea5e5SAndroid Build Coastguard Worker	echo "$h" "$(commit_signature "$h")" >> "${TMP_DIR}"/bpftool_commits.txt
267*858ea5e5SAndroid Build Coastguard Workerdone
268*858ea5e5SAndroid Build Coastguard Worker
269*858ea5e5SAndroid Build Coastguard Worker# Use current kernel repo HEAD as a source of patches
270*858ea5e5SAndroid Build Coastguard Workercd_to "${LINUX_REPO}"
271*858ea5e5SAndroid Build Coastguard WorkerLINUX_ABS_DIR=$(pwd)
272*858ea5e5SAndroid Build Coastguard WorkerTIP_SYM_REF=$(git symbolic-ref -q --short HEAD || git rev-parse HEAD)
273*858ea5e5SAndroid Build Coastguard WorkerBASELINE_TAG="bpftool-baseline-${SUFFIX}"
274*858ea5e5SAndroid Build Coastguard WorkerTIP_TAG="bpftool-tip-${SUFFIX}"
275*858ea5e5SAndroid Build Coastguard WorkerBPF_BASELINE_TAG="bpftool-bpf-baseline-${SUFFIX}"
276*858ea5e5SAndroid Build Coastguard WorkerBPF_TIP_TAG="bpftool-bpf-tip-${SUFFIX}"
277*858ea5e5SAndroid Build Coastguard WorkerVIEW_TAG="bpftool-view-${SUFFIX}"
278*858ea5e5SAndroid Build Coastguard Worker
279*858ea5e5SAndroid Build Coastguard Worker# Squash state of kernel repo at baseline into single commit
280*858ea5e5SAndroid Build Coastguard WorkerSQUASH_BASE_TAG="bpftool-squash-base-${SUFFIX}"
281*858ea5e5SAndroid Build Coastguard WorkerSQUASH_TIP_TAG="bpftool-squash-tip-${SUFFIX}"
282*858ea5e5SAndroid Build Coastguard WorkerSQUASH_COMMIT=$(git commit-tree "${BASELINE_COMMIT}^{tree}" -m "BASELINE SQUASH ${BASELINE_COMMIT}")
283*858ea5e5SAndroid Build Coastguard Worker
284*858ea5e5SAndroid Build Coastguard Workerecho "WORKDIR:          ${WORKDIR}"
285*858ea5e5SAndroid Build Coastguard Workerecho "LINUX REPO:       ${LINUX_REPO}"
286*858ea5e5SAndroid Build Coastguard Workerecho "BPFTOOL REPO:     ${BPFTOOL_REPO}"
287*858ea5e5SAndroid Build Coastguard Workerecho "TEMP DIR:         ${TMP_DIR}"
288*858ea5e5SAndroid Build Coastguard Workerecho "SUFFIX:           ${SUFFIX}"
289*858ea5e5SAndroid Build Coastguard Workerecho "BASE COMMIT:      '$(commit_desc "${BASELINE_COMMIT}")'"
290*858ea5e5SAndroid Build Coastguard Workerecho "TIP COMMIT:       '$(commit_desc "${TIP_COMMIT}")'"
291*858ea5e5SAndroid Build Coastguard Workerecho "BPF BASE COMMIT:  '$(commit_desc "${BPF_BASELINE_COMMIT}")'"
292*858ea5e5SAndroid Build Coastguard Workerecho "BPF TIP COMMIT:   '$(commit_desc "${BPF_TIP_COMMIT}")'"
293*858ea5e5SAndroid Build Coastguard Workerecho "SQUASH COMMIT:    ${SQUASH_COMMIT}"
294*858ea5e5SAndroid Build Coastguard Workerecho "BASELINE TAG:     ${BASELINE_TAG}"
295*858ea5e5SAndroid Build Coastguard Workerecho "TIP TAG:          ${TIP_TAG}"
296*858ea5e5SAndroid Build Coastguard Workerecho "BPF BASELINE TAG: ${BPF_BASELINE_TAG}"
297*858ea5e5SAndroid Build Coastguard Workerecho "BPF TIP TAG:      ${BPF_TIP_TAG}"
298*858ea5e5SAndroid Build Coastguard Workerecho "SQUASH BASE TAG:  ${SQUASH_BASE_TAG}"
299*858ea5e5SAndroid Build Coastguard Workerecho "SQUASH TIP TAG:   ${SQUASH_TIP_TAG}"
300*858ea5e5SAndroid Build Coastguard Workerecho "VIEW TAG:         ${VIEW_TAG}"
301*858ea5e5SAndroid Build Coastguard Workerecho "BPFTOOL SYNC TAG: ${BPFTOOL_SYNC_TAG}"
302*858ea5e5SAndroid Build Coastguard Workerecho "PATCHES:          ${TMP_DIR}/patches"
303*858ea5e5SAndroid Build Coastguard Worker
304*858ea5e5SAndroid Build Coastguard Workergit branch "${BASELINE_TAG}" "${BASELINE_COMMIT}"
305*858ea5e5SAndroid Build Coastguard Workergit branch "${TIP_TAG}" "${TIP_COMMIT}"
306*858ea5e5SAndroid Build Coastguard Workergit branch "${BPF_BASELINE_TAG}" "${BPF_BASELINE_COMMIT}"
307*858ea5e5SAndroid Build Coastguard Workergit branch "${BPF_TIP_TAG}" "${BPF_TIP_COMMIT}"
308*858ea5e5SAndroid Build Coastguard Workergit branch "${SQUASH_BASE_TAG}" "${SQUASH_COMMIT}"
309*858ea5e5SAndroid Build Coastguard Workergit checkout -b "${SQUASH_TIP_TAG}" "${SQUASH_COMMIT}"
310*858ea5e5SAndroid Build Coastguard Worker
311*858ea5e5SAndroid Build Coastguard Worker# Cherry-pick new commits onto squashed baseline commit
312*858ea5e5SAndroid Build Coastguard Workerecho "Cherry-pick for bpf-next..."
313*858ea5e5SAndroid Build Coastguard Workercherry_pick_commits "${BASELINE_TAG}" "${TIP_TAG}"
314*858ea5e5SAndroid Build Coastguard Workerecho "Cherry-pick for bpf..."
315*858ea5e5SAndroid Build Coastguard Workercherry_pick_commits "${BPF_BASELINE_TAG}" "${BPF_TIP_TAG}"
316*858ea5e5SAndroid Build Coastguard Worker
317*858ea5e5SAndroid Build Coastguard Worker# Move all bpftool files into __bpftool directory.
318*858ea5e5SAndroid Build Coastguard WorkerFILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --prune-empty -f --tree-filter "${BPFTOOL_TREE_FILTER}" "${SQUASH_TIP_TAG}" "${SQUASH_BASE_TAG}"
319*858ea5e5SAndroid Build Coastguard Worker# Make __bpftool a new root directory
320*858ea5e5SAndroid Build Coastguard WorkerFILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --prune-empty -f --subdirectory-filter __bpftool "${SQUASH_TIP_TAG}" "${SQUASH_BASE_TAG}"
321*858ea5e5SAndroid Build Coastguard Worker
322*858ea5e5SAndroid Build Coastguard Worker# If there are no new commits with  bpftool-related changes, bail out
323*858ea5e5SAndroid Build Coastguard WorkerCOMMIT_CNT=$(git rev-list --count "${SQUASH_BASE_TAG}".."${SQUASH_TIP_TAG}")
324*858ea5e5SAndroid Build Coastguard Workerif (("${COMMIT_CNT}" <= 0)); then
325*858ea5e5SAndroid Build Coastguard Worker	echo "No new changes to apply, we are done!"
326*858ea5e5SAndroid Build Coastguard Worker	cleanup
327*858ea5e5SAndroid Build Coastguard Worker	exit 2
328*858ea5e5SAndroid Build Coastguard Workerfi
329*858ea5e5SAndroid Build Coastguard Worker
330*858ea5e5SAndroid Build Coastguard Worker# Exclude baseline commit and generate nice cover letter with summary
331*858ea5e5SAndroid Build Coastguard Workergit format-patch --no-signature "${SQUASH_BASE_TAG}".."${SQUASH_TIP_TAG}" --cover-letter -o "${TMP_DIR}"/patches
332*858ea5e5SAndroid Build Coastguard Worker
333*858ea5e5SAndroid Build Coastguard Worker# Now is time to re-apply bpftool-related linux patches to bpftool repo
334*858ea5e5SAndroid Build Coastguard Workercd_to "${BPFTOOL_REPO}"
335*858ea5e5SAndroid Build Coastguard Worker
336*858ea5e5SAndroid Build Coastguard Worker# shellcheck disable=SC2012
337*858ea5e5SAndroid Build Coastguard Workerfor patch in $(ls -1 "${TMP_DIR}"/patches | tail -n +2); do
338*858ea5e5SAndroid Build Coastguard Worker	if ! git am --3way --committer-date-is-author-date "${TMP_DIR}/patches/${patch}"; then
339*858ea5e5SAndroid Build Coastguard Worker		read -rp "Applying ${TMP_DIR}/patches/${patch} failed, please resolve manually and press <return> to proceed..."
340*858ea5e5SAndroid Build Coastguard Worker	fi
341*858ea5e5SAndroid Build Coastguard Workerdone
342*858ea5e5SAndroid Build Coastguard Worker
343*858ea5e5SAndroid Build Coastguard Worker# Use generated cover-letter as a template for "sync commit" with
344*858ea5e5SAndroid Build Coastguard Worker# baseline and checkpoint commits from kernel repo (and leave summary
345*858ea5e5SAndroid Build Coastguard Worker# from cover letter intact, of course)
346*858ea5e5SAndroid Build Coastguard Workerecho "${TIP_COMMIT}" > CHECKPOINT-COMMIT &&					      \
347*858ea5e5SAndroid Build Coastguard Workerecho "${BPF_TIP_COMMIT}" > BPF-CHECKPOINT-COMMIT &&				      \
348*858ea5e5SAndroid Build Coastguard Workergit add CHECKPOINT-COMMIT &&							      \
349*858ea5e5SAndroid Build Coastguard Workergit add BPF-CHECKPOINT-COMMIT &&						      \
350*858ea5e5SAndroid Build Coastguard Workerawk '/\*\*\* BLURB HERE \*\*\*/ {p=1} p' "${TMP_DIR}"/patches/0000-cover-letter.patch | \
351*858ea5e5SAndroid Build Coastguard Workersed "s/\*\*\* BLURB HERE \*\*\*/\
352*858ea5e5SAndroid Build Coastguard Workersync: Pull latest bpftool changes from kernel\n\
353*858ea5e5SAndroid Build Coastguard Worker\n\
354*858ea5e5SAndroid Build Coastguard WorkerSyncing latest bpftool commits from kernel repository.\n\
355*858ea5e5SAndroid Build Coastguard WorkerBaseline bpf-next commit:   ${BASELINE_COMMIT}\n\
356*858ea5e5SAndroid Build Coastguard WorkerCheckpoint bpf-next commit: ${TIP_COMMIT}\n\
357*858ea5e5SAndroid Build Coastguard WorkerBaseline bpf commit:        ${BPF_BASELINE_COMMIT}\n\
358*858ea5e5SAndroid Build Coastguard WorkerCheckpoint bpf commit:      ${BPF_TIP_COMMIT}/" |				      \
359*858ea5e5SAndroid Build Coastguard Workergit commit --signoff --file=-
360*858ea5e5SAndroid Build Coastguard Worker
361*858ea5e5SAndroid Build Coastguard Workerecho "SUCCESS! ${COMMIT_CNT} commits synced."
362*858ea5e5SAndroid Build Coastguard Worker
363*858ea5e5SAndroid Build Coastguard Workerecho "Verifying Linux's and Github's bpftool state"
364*858ea5e5SAndroid Build Coastguard Worker
365*858ea5e5SAndroid Build Coastguard Workercd_to "${LINUX_REPO}"
366*858ea5e5SAndroid Build Coastguard Workergit checkout -b "${VIEW_TAG}" "${TIP_COMMIT}"
367*858ea5e5SAndroid Build Coastguard WorkerFILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --tree-filter "${BPFTOOL_TREE_FILTER}" "${VIEW_TAG}"^.."${VIEW_TAG}"
368*858ea5e5SAndroid Build Coastguard WorkerFILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --subdirectory-filter __bpftool "${VIEW_TAG}"^.."${VIEW_TAG}"
369*858ea5e5SAndroid Build Coastguard Worker# shellcheck disable=SC2068
370*858ea5e5SAndroid Build Coastguard Workergit ls-files -- ${BPFTOOL_VIEW_PATHS[@]} | grep -v -E "${LINUX_VIEW_EXCLUDE_REGEX}" > "${TMP_DIR}"/linux-view.ls
371*858ea5e5SAndroid Build Coastguard Worker# Before we compare each file, try to apply to the mirror a patch containing the
372*858ea5e5SAndroid Build Coastguard Worker# expected differences between the two repositories; this is to avoid checking
373*858ea5e5SAndroid Build Coastguard Worker# "known" differences visually and taking the risk of missing a new, relevant
374*858ea5e5SAndroid Build Coastguard Worker# differences.
375*858ea5e5SAndroid Build Coastguard Workerecho "Patching to account for expected differences..."
376*858ea5e5SAndroid Build Coastguard Workerpatch -d "${LINUX_ABS_DIR}" -p0 -f --reject-file=- --no-backup-if-mismatch < "${GITHUB_ABS_DIR}/scripts/sync-kernel-expected-diff.patch" || true
377*858ea5e5SAndroid Build Coastguard Workergit add -u
378*858ea5e5SAndroid Build Coastguard Workergit commit -m 'tmp: apply expected differences to compare github/kernel repos' || true
379*858ea5e5SAndroid Build Coastguard Worker
380*858ea5e5SAndroid Build Coastguard Workercd_to "${BPFTOOL_REPO}"
381*858ea5e5SAndroid Build Coastguard Worker# shellcheck disable=SC2068
382*858ea5e5SAndroid Build Coastguard Workergit ls-files -- ${BPFTOOL_VIEW_PATHS[@]} | grep -v -E "${BPFTOOL_VIEW_EXCLUDE_REGEX}" > "${TMP_DIR}"/github-view.ls
383*858ea5e5SAndroid Build Coastguard Worker
384*858ea5e5SAndroid Build Coastguard Workerecho "Comparing list of files..."
385*858ea5e5SAndroid Build Coastguard Workerdiff -u "${TMP_DIR}"/linux-view.ls "${TMP_DIR}"/github-view.ls
386*858ea5e5SAndroid Build Coastguard Workerecho "Comparing file contents..."
387*858ea5e5SAndroid Build Coastguard WorkerCONSISTENT=1
388*858ea5e5SAndroid Build Coastguard Workerwhile IFS= read -r F; do
389*858ea5e5SAndroid Build Coastguard Worker	if ! diff -u --color "${LINUX_ABS_DIR}/${F}" "${GITHUB_ABS_DIR}/${F}"; then
390*858ea5e5SAndroid Build Coastguard Worker		echo "${LINUX_ABS_DIR}/${F} and ${GITHUB_ABS_DIR}/${F} are different!"
391*858ea5e5SAndroid Build Coastguard Worker		CONSISTENT=0
392*858ea5e5SAndroid Build Coastguard Worker	fi
393*858ea5e5SAndroid Build Coastguard Workerdone < "${TMP_DIR}"/linux-view.ls
394*858ea5e5SAndroid Build Coastguard Workerecho ""
395*858ea5e5SAndroid Build Coastguard Workerif (("${CONSISTENT}" == 1)); then
396*858ea5e5SAndroid Build Coastguard Worker	echo "Great! Content is identical!"
397*858ea5e5SAndroid Build Coastguard Workerelse
398*858ea5e5SAndroid Build Coastguard Worker	ignore_inconsistency=n
399*858ea5e5SAndroid Build Coastguard Worker	echo "Unfortunately, there are some inconsistencies, please double check."
400*858ea5e5SAndroid Build Coastguard Worker	echo "Some of them may come from patches in bpf tree but absent from bpf-next."
401*858ea5e5SAndroid Build Coastguard Worker	echo "Note: I applied scripts/sync-kernel-expected-diff.patch before checking,"
402*858ea5e5SAndroid Build Coastguard Worker	echo "to account for expected changes. If this patch needs an update,"
403*858ea5e5SAndroid Build Coastguard Worker	echo "you can do it now with:"
404*858ea5e5SAndroid Build Coastguard Worker	echo "------"
405*858ea5e5SAndroid Build Coastguard Worker	echo "    (cd \"${LINUX_ABS_DIR}\" && git -c advice.detachedHead=false checkout HEAD~)"
406*858ea5e5SAndroid Build Coastguard Worker	echo "    for f in \$(cat \"${TMP_DIR}/linux-view.ls\"); do"
407*858ea5e5SAndroid Build Coastguard Worker	echo "        diff -u --label \"\${f}\" --label \"\${f}\" \\"
408*858ea5e5SAndroid Build Coastguard Worker	echo "            \"${LINUX_ABS_DIR}/\${f}\" \\"
409*858ea5e5SAndroid Build Coastguard Worker	echo "            \"${GITHUB_ABS_DIR}/\${f}\""
410*858ea5e5SAndroid Build Coastguard Worker	echo "    done > \"${GITHUB_ABS_DIR}/scripts/sync-kernel-expected-diff.patch\""
411*858ea5e5SAndroid Build Coastguard Worker	echo "------"
412*858ea5e5SAndroid Build Coastguard Worker	read -rp "Does everything look good? [y/N]: " ignore_inconsistency
413*858ea5e5SAndroid Build Coastguard Worker	case "${ignore_inconsistency}" in
414*858ea5e5SAndroid Build Coastguard Worker		"y" | "Y")
415*858ea5e5SAndroid Build Coastguard Worker			echo "Ok, proceeding..."
416*858ea5e5SAndroid Build Coastguard Worker			;;
417*858ea5e5SAndroid Build Coastguard Worker		*)
418*858ea5e5SAndroid Build Coastguard Worker			echo "Oops, exiting with error..."
419*858ea5e5SAndroid Build Coastguard Worker			exit 4
420*858ea5e5SAndroid Build Coastguard Worker	esac
421*858ea5e5SAndroid Build Coastguard Workerfi
422*858ea5e5SAndroid Build Coastguard Worker
423*858ea5e5SAndroid Build Coastguard Workercleanup
424