From f5731c1ac78d56ab01b9354d43bef0e7d209434c Mon Sep 17 00:00:00 2001 From: wangcichen Date: Thu, 12 May 2022 09:04:58 +0800 Subject: [PATCH] modify scripts/pkgbuild to make kpatch'es for the RPM-based packages 1.support specify patch-id, build-id and sanity check 2.simplify script and put it into libcare devel package (cherry picked from commit a5aa48f473e6f9edca99c0316798f2180055421a) --- libcareplus.spec | 12 +- ...o-make-kpatch-for-RPM-based-packages.patch | 459 ++++++++++++++++++ 2 files changed, 470 insertions(+), 1 deletion(-) create mode 100644 modify-pkgbuild-to-make-kpatch-for-RPM-based-packages.patch diff --git a/libcareplus.spec b/libcareplus.spec index e08347c..b0eba83 100644 --- a/libcareplus.spec +++ b/libcareplus.spec @@ -3,7 +3,7 @@ Version: 1.0.0 Name: libcareplus Summary: LibcarePlus tools -Release: 10 +Release: 11 Group: Applications/System License: GPLv2 Url: https://gitee.com/openeuler/libcareplus @@ -22,6 +22,7 @@ Patch0010: libcare-patch-make-fix-some-bugs.patch Patch0011: selinux-enable-libcare-ctl-to-mprotect-qemu-process.patch Patch0012: libcare-dump-change-the-return-value.patch Patch0013: gensrc-skip-vector-instruction-in-str_do_gotpcrel.patch +Patch0014: modify-pkgbuild-to-make-kpatch-for-RPM-based-packages.patch BuildRequires: elfutils-libelf-devel libunwind-devel gcc systemd @@ -88,6 +89,9 @@ make -C dist/selinux install \ install -m 0644 -D dist/libcare.preset %{buildroot}%{_presetdir}/90-libcare.preset +install -m 0500 scripts/pkgbuild %{buildroot}%{_bindir}/libcare-pkgbuild +install -m 0500 scripts/de-offset-syms.awk %{buildroot}%{_bindir}/de-offset-syms.awk +install -m 0644 -D scripts/example_info %{buildroot}/usr/share/libcareplus/qemu_example_info %pre /usr/sbin/groupadd libcare -r 2>/dev/null || : @@ -111,6 +115,9 @@ rm -rf $RPM_BUILD_ROOT %{_bindir}/kpatch_make %{_bindir}/libcare-server %{_bindir}/libcare-client +%{_bindir}/libcare-pkgbuild +%{_bindir}/de-offset-syms.awk +/usr/share/libcareplus/qemu_example_info %if 0%{with selinux} @@ -153,6 +160,9 @@ exit 0 %endif %changelog +* Wed May 11 2022 Cichen Wang 1.0.0-11 +- modify scripts/pkgbuild to make kpatch'es for the RPM-based packages + * Tue May 10 2022 yezengruan 1.0.0-10 - libcare-dump: change the return value - gensrc: skip vector instruction in str_do_gotpcrel diff --git a/modify-pkgbuild-to-make-kpatch-for-RPM-based-packages.patch b/modify-pkgbuild-to-make-kpatch-for-RPM-based-packages.patch new file mode 100644 index 0000000..9c5a7e7 --- /dev/null +++ b/modify-pkgbuild-to-make-kpatch-for-RPM-based-packages.patch @@ -0,0 +1,459 @@ +From 0c414638168e0c1a006827daaae10c2ea4a8fc08 Mon Sep 17 00:00:00 2001 +From: wangcichen +Date: Mon, 9 May 2022 16:27:09 +0800 +Subject: [PATCH] modify scripts/pkgbuild to make kpatch'es for the RPM-based + packages + +1.support specify patch-id, build-id and sanity check +2.simplify script and put it into libcare devel package +--- + scripts/example_info | 59 ++++++++++++++ + scripts/pkgbuild | 179 ++++++++++++++++++++++++------------------- + 2 files changed, 161 insertions(+), 77 deletions(-) + create mode 100644 scripts/example_info + +diff --git a/scripts/example_info b/scripts/example_info +new file mode 100644 +index 0000000..d848e33 +--- /dev/null ++++ b/scripts/example_info +@@ -0,0 +1,59 @@ ++#!/bin/bash ++ ++KP_PROJECT=qemu ++KP_PROJECT_FORMAT=rpm ++KP_PROJECT_BUILD_ROOT=/var/libcareplus/qemu/rpmbuild ++KP_PROJECT_ORIG_RPMS=/var/libcareplus/qemu/qemu-6.2.0-29.oe2203 ++KP_PROJECT_SPEC=qemu.spec ++ ++# we choose plist filename as patch-id, eg: 220411 here ++KP_PROJECT_PLIST_FILE=/var/libcareplus/qemu/patch001/220506.plist ++KP_PROJECT_DIR=$KP_PROJECT_BUILD_ROOT/BUILD/qemu-6.2.0 ++KP_PROJECT_BUILD_DIR=$KP_PROJECT_DIR/build/x86_64-softmmu ++KP_PROJECT_BUILD_ID=61fcf129b23f05a623e0bf696a03d3348f366348 ++KP_SANITY_CHECK_STRICTLY=no ++KP_PROJECT_SOURCE_URL= ++KP_PROJECT_SOURCE=qemu-6.2.0-29.oe2203.src.rpm ++KP_PROJECT_BINARY=qemu-6.2.0-29.oe2203.x86_64.rpm ++ ++KP_PROJECT_PREBUILT=build.orig-$KP_PROJECT_BINARY.tgz ++KP_PROJECT_PATCH=kpatch-${KP_PROJECT_BINARY%.*}.tgz ++KP_RPMBUILD_FLAGS="'--define=dist .oe2203'" ++#KP_RPM_REPOS="--enablerepo=base" ++ ++ ++KP_INSTALL_FILES=" ++/qemu-system-x86_64 /usr/libexec/qemu-kvm ++" ++ ++KPATCH_ASM_DIR=$KP_PROJECT_BUILD_ROOT/asmdir ++export KPATCH_ASM_DIR ++ ++KPCC_PATCH_ARGS="--force-gotpcrel;--os=rhel6;--ignore-changes=banner,compilation" ++export KPCC_PATCH_ARGS ++ ++KPCC_DBGFILTER_ARGS="--dbg-filter;--dbg-filter-eh-frame;--dbg-filter-gcc-except-table;--os=rhel6" ++export KPCC_DBGFILTER_ARGS ++ ++kp_prebuild_hook() { ++ if test -z "$(command -v tar)"; then ++ echo "No tar command, Please install it first" ++ exit 1 ++ fi ++ if test -z "$(command -v rpmbuild)"; then ++ echo "No rpmbuild command, Please install it first" ++ exit 1 ++ fi ++} ++ ++kp_build_hook() { ++ : ++} ++ ++kp_prepare_test_binaries() { ++ : ++} ++ ++kp_patch_test() { ++ : ++} +diff --git a/scripts/pkgbuild b/scripts/pkgbuild +index f91af57..1185cd9 100755 +--- a/scripts/pkgbuild ++++ b/scripts/pkgbuild +@@ -1,4 +1,8 @@ + #!/bin/bash ++# make kpatch'es for the RPM-based packages using spec file. ++# Each package contains the config file: info in their project directory, ++# like /var/libcareplus/qemu/info ++# + + echo '+ set -x' + set -x +@@ -15,10 +19,10 @@ die() { + } + + usage() { +- echo "Usage: build [--prebuild] [--help] [--arch ARCH] DIR" ++ echo "Makes kpatch'es for the RPM-based packages using spec file." ++ echo "Usage: libcare-pkgbuild [--prebuild] [--test] [--help] DIR" + echo " -p|--prebuild prebuild project for further use" + echo " -t|--test run unit and stress tests" +- echo " -a|--arch ARCH target architecture(x86_64 by default)" + echo " -h|--help print this message" + echo " DIR directory with project's info file and other resources" + } +@@ -26,7 +30,6 @@ usage() { + prepare() { + # Parse cmdline args + ACTION=build +- ARCH=x86_64 + PDIR= + while [ "$1" != "" ]; do + case $1 in +@@ -36,10 +39,6 @@ prepare() { + -t|--test) + ACTION=test + ;; +- -a|--arch) +- shift +- ARCH=$1 +- ;; + -h|--help) + usage + exit 0 +@@ -56,11 +55,8 @@ prepare() { + shift + done + +- # Export env vars that are needed during the build +- SCRIPTS="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" +- LIBCARE_DIR="${LIBCARE_DIR:-$SCRIPTS/..}" +- KPATCH_PATH="${KPATCH_PATH:-$LIBCARE_DIR/src}" +- export LIBCARE_DIR KPATCH_PATH ++ KPATCH_PATH="$(dirname "$( which libcare-cc )" )" ++ export KPATCH_PATH + export OLDPATH=$PATH + export KPATCH_PASSTHROUGH_ASM=1 + CPUS=`cat /proc/cpuinfo | grep ^processor | wc -l` +@@ -70,12 +66,13 @@ prepare() { + # Obtain information about the project + source $PDIR/info + +- mkdir -p /kcdata ++ ROOT_ORIGINAL=$PDIR/root.original ++ ROOT_PATCHED=$PDIR/root.patched + } + + clean_dirs() { + echo " cleaning up" +- rm -rf $KP_PROJECT_BUILD_ROOT /root/root.original /root/root.patched ++ rm -rf $KP_PROJECT_BUILD_ROOT $ROOT_ORIGINAL $ROOT_PATCHED + } + + kp_prepare_env_hook() { +@@ -86,17 +83,15 @@ kp_prepare_env_hook() { + kp_pack_prebuilt() { + echo " packing prebuilt $KP_PROJECT into $KP_PROJECT_PREBUILT" + pushd $KP_PROJECT_BUILD_ROOT +- tar -zcf /kcdata/$KP_PROJECT_PREBUILT \ ++ tar -zcf $PDIR/$KP_PROJECT_PREBUILT \ + $KP_PROJECT_BUILD_ROOT \ +- /root/root.original ++ $ROOT_ORIGINAL + popd + } + + kp_unpack_prebuilt() { + echo " unpacking prebuilt $KP_PROJECT into $KP_PROJECT_PREBUILT" +- tar -xf /kcdata/$KP_PROJECT_PREBUILT -C / +- +- yum-builddep -d 1 -y $KP_PROJECT_BUILD_ROOT/SPECS/$KP_PROJECT_SPEC ++ tar -xf $PDIR/$KP_PROJECT_PREBUILT -C / + } + + kp_prepare_source_raw() { +@@ -108,38 +103,32 @@ kp_prepare_source_raw() { + } + + kp_download_source_rpm() { +- mkdir -p /kcdata + if test -n "$KP_PROJECT_SOURCE_URL"; then +- curl $KP_PROJECT_SOURCE_URL -o /kcdata/$KP_PROJECT_SOURCE ++ curl $KP_PROJECT_SOURCE_URL -o $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE + else +- yumdownloader --source --destdir /kcdata ${KP_PROJECT_SOURCE%.src.rpm} ++ yumdownloader --source --destdir $KP_PROJECT_ORIG_RPMS ${KP_PROJECT_SOURCE%.src.rpm} + fi + } + + kp_prepare_source_rpm() { +- rm -rf $HOME/deps ++ rm -rf $PDIR/deps + eval yum-builddep -d 1 -y $KP_RPM_REPOS \ +- --downloadonly --downloaddir=$HOME/deps \ +- /kcdata/$KP_PROJECT_SOURCE ++ --downloadonly --downloaddir=$PDIR/deps \ ++ $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE + mkdir -p $KP_PROJECT_BUILD_ROOT + rpm -qa > $KP_PROJECT_BUILD_ROOT/all-packages.txt +- ls $HOME/deps > $KP_PROJECT_BUILD_ROOT/dependencies.txt +- eval yum-builddep -d 1 -y $KP_RPM_REPOS \ +- /kcdata/$KP_PROJECT_SOURCE ++ ls $PDIR/deps > $KP_PROJECT_BUILD_ROOT/dependencies.txt ++ eval yum-builddep -d 1 -y $KP_RPM_REPOS \ ++ $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE + + sed -i 's/.rpm$//g' $KP_PROJECT_BUILD_ROOT/dependencies.txt + +- rpm -ivh /kcdata/$KP_PROJECT_SOURCE \ ++ rpm -ivh $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE \ + --define "_topdir $KP_PROJECT_BUILD_ROOT" + } + +-kp_prepare_source_deb() { +- echo "deb support is not implemented yet" +- exit 1 +-} +- + kp_prepare_source() { +- if ! test -f /kcdata/$KP_PROJECT_SOURCE; then ++ if ! test -f $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE; then + echo " downloading source for $KP_PROJECT" + kp_download_source_$KP_PROJECT_FORMAT + fi +@@ -147,12 +136,60 @@ kp_prepare_source() { + kp_prepare_source_$KP_PROJECT_FORMAT + } + ++patch_list_apply() { ++ SRC_DIR=$(cd "$(dirname "$1")" && pwd)/$(basename "$1") ++ PATCH_DIR=$(cd "$(dirname "$KP_PROJECT_PLIST_FILE")" && pwd) ++ PLIST=$PATCH_DIR/$(basename "$KP_PROJECT_PLIST_FILE") ++ PATCH_ID=$(echo $(basename "$KP_PROJECT_PLIST_FILE") | awk -F. '{print $1}') ++ if test -z "$PATCH_ID"; then ++ echo "Failed to get patch-id. Please check plist filename: $KP_PROJECT_PLIST_FILE" ++ exit 1 ++ fi ++ TEMP_PLIST=/tmp/build.kpatch/tmpplist ++ ++ if [ ! -f $PLIST ]; then ++ echo "File $PLIST not found" ++ exit 1; ++ fi ++ ++ echo "patching $PWD with patches from $PLIST" ++ ++ pushd $SRC_DIR # go to the directory with sources to be patched ++ ++ #in case we don't have a newline in plist ++ cat $PLIST > $TEMP_PLIST ++ echo -e "\n" >> $TEMP_PLIST ++ ++ # iterate through patches in PLIST ++ while read NAME ++ do ++ COMMENT=`echo $NAME | cut -c1` ++ if [ "$COMMENT" == "#" ]; then ++ continue; ++ fi ++ ++ if [ -z "${NAME}" ]; then ++ continue; ++ fi ++ ++ echo "Applying patch $NAME" ++ patch -p1 -u --fuzz=0 --batch < $PATCH_DIR/$NAME ++ if [ $? != 0 ]; then ++ echo "Failed applying patch $NAME"; popd; rm $TEMP_PLIST; exit 1 ++ else ++ echo "Successfully applied patch $NAME" ++ fi ++ done < $TEMP_PLIST ++ rm $TEMP_PLIST ++ ++ popd ++} ++ + kp_patch_source() { + echo " patching project" +- PATCH_DIR=$LIBCARE_DIR/patches + #patch_list_apply requires this dir + mkdir -p /tmp/build.kpatch +- $SCRIPTS/patch_list_apply $KP_PROJECT_DIR $PDIR/plist $PATCH_DIR ++ patch_list_apply $KP_PROJECT_DIR + } + + kp_prebuild_rpm() { +@@ -170,25 +207,17 @@ kp_prebuild_rpm() { + } + + _kp_install_orig_rpm() { +- for rpmfile in $KP_ORIG_RPMS; do +- pkgname="$(basename $rpmfile)" +- pkgname="${pkgname%%.rpm}" +- eval yumdownloader --enablerepo=base-debuginfo $KP_RPM_REPOS \ +- --destdir=$HOME/rpms.orig $pkgname +- done +- +- rpm --force -i $HOME/rpms.orig/*.rpm \ +- --root=$HOME/root.original \ ++ rpm --force -i $1 \ ++ --root=$ROOT_ORIGINAL \ + --nodeps --noscripts + } + + kp_install_orig_rpm() { +- _kp_install_orig_rpm ++ for orig_rpm in $(ls $KP_PROJECT_ORIG_RPMS | grep -v $KP_PROJECT_SOURCE); do ++ _kp_install_orig_rpm $KP_PROJECT_ORIG_RPMS/$orig_rpm ++ done + } + +-kp_prebuild_hook() { +- : +-} + + kp_prebuild() { + echo " prebuilding $KP_PROJECT" +@@ -200,25 +229,25 @@ de_offset_syms() { + local binary=$1 + + readelf -WSs $binary > $binary.symlist 2>/dev/null +- $SCRIPTS/de-offset-syms.awk $binary.symlist > $binary.symlist.tmp ++ de-offset-syms.awk $binary.symlist > $binary.symlist.tmp + sort $binary.symlist.tmp > $binary.symlist + rm -f $binary.symlist.tmp + } + + kp_sanity_check() { +- pushd $HOME/root.patched ++ pushd $ROOT_PATCHED + local targets="$(find . -perm /0111 -type f)" + popd + + local failed="" + for target in $targets; do +- local original="$HOME/root.original/usr/lib/debug/$target.debug" +- local patched="$HOME/root.patched/$target" ++ local original=`ls $ROOT_ORIGINAL/usr/lib/debug/${target}*.debug` ++ local patched="$ROOT_PATCHED/$target" + local alloweddiff="$PDIR/$(basename "$target").symlist.diff" + + de_offset_syms $original + if test ! -s $original.symlist; then +- original="$HOME/root.original/$target" ++ original="$ROOT_ORIGINAL/$target" + de_offset_syms $original + fi + +@@ -241,7 +270,11 @@ kp_sanity_check() { + done + + if test -n "$failed"; then +- die "Failed sanity check for $failed" ++ if test "$KP_SANITY_CHECK_STRICTLY" == "yes"; then ++ die "Failed sanity check for $failed" ++ else ++ echo "[Warning] Failed sanity check for $failed" ++ fi + fi + } + +@@ -308,7 +341,7 @@ kp_check_missing_files() { + } + + kp_install_generic() { +- local root_patched="$HOME/root.patched" ++ local root_patched="$ROOT_PATCHED" + + kp_install_files $KP_PROJECT_BUILD_DIR \ + $root_patched \ +@@ -318,13 +351,9 @@ kp_install_generic() { + } + + kp_install_rpm() { +- kp_install_orig_rpm + kp_install_generic + } + +-kp_build_hook() { +- : +-} + + kp_build() { + echo " building $KP_PROJECT" +@@ -340,19 +369,22 @@ kp_build() { + kp_gen_kpatch() { + echo " generating kpatches" + +- pushd $HOME/root.patched ++ pushd $ROOT_PATCHED + targets=$(find . -perm /0111 -type f) + popd + +- rm -rf $HOME/${KP_PROJECT_PATCH%.*} +- mkdir $HOME/${KP_PROJECT_PATCH%.*} ++ rm -rf $PDIR/${KP_PROJECT_PATCH%.*} ++ mkdir $PDIR/${KP_PROJECT_PATCH%.*} + + local no_patches=1 + + for t in $targets; do +- local debug="$HOME/root.original/usr/lib/debug/$t.debug" +- local patched="$HOME/root.patched/$t" ++ local debug=`ls $ROOT_ORIGINAL/usr/lib/debug/${t}*.debug` ++ local patched="$ROOT_PATCHED/$t" + local buildid=$(eu-readelf -n $debug | sed -n '/Build ID:/ { s/.* //; p }') ++ if test -n "$KP_PROJECT_BUILD_ID"; then ++ buildid=$KP_PROJECT_BUILD_ID ++ fi + if test -z "$buildid"; then + continue + fi +@@ -363,7 +395,7 @@ kp_gen_kpatch() { + + chmod u+w $debug $patched + +- eu-unstrip "$HOME/root.original/$t" "$debug" ++ eu-unstrip "$ROOT_ORIGINAL/$t" "$debug" + + $KPATCH_PATH/kpatch_strip --strip $patched $patched.kpstripped + cp $patched.kpstripped $patched.relfixup +@@ -372,8 +404,8 @@ kp_gen_kpatch() { + /usr/bin/strip --strip-unneeded $patched.stripped + cp $patched.stripped $patched.undolink + $KPATCH_PATH/kpatch_strip --undo-link $debug $patched.undolink +- $KPATCH_PATH/kpatch_make -b "$buildid" $patched.undolink -o $patched.kpatch +- cp $patched.kpatch $HOME/${KP_PROJECT_PATCH%.*}/$buildid.kpatch ++ $KPATCH_PATH/kpatch_make -b "$buildid" -i "$PATCH_ID" $patched.undolink -o $patched.kpatch ++ cp $patched.kpatch $PDIR/${KP_PROJECT_PATCH%.*}/$buildid.kpatch + no_patches=0 + done + +@@ -384,9 +416,7 @@ kp_gen_kpatch() { + + kp_pack_patch() { + echo " packing patch for $KP_PROJECT into $KP_PROJECT_PATCH" +- pushd $KP_PROJECT_BUILD_DIR +- tar -zcf /kcdata/$KP_PROJECT_PATCH $HOME/${KP_PROJECT_PATCH%.*} +- popd ++ tar -zcf $PDIR/$KP_PROJECT_PATCH $PDIR/${KP_PROJECT_PATCH%.*} + } + + kp_unpack_patch() { +@@ -411,11 +441,6 @@ kp_unpack_patch() { + + rm -fr $tmpdir + } +- +-kp_mark_tests_fail() { +- touch /kcdata/Tests-FAIL +-} +- + overwrite_utils() { + TMPBIN=$(mktemp -d --tmpdir) + +-- +2.24.1.windows.2 +