The klp-build script is currently very strict with input patches,
requiring them to apply cleanly via `git apply --recount`.  This
prevents the use of patches with minor contextual fuzz relative to the
target kernel sources.

To allow users to reuse a patch across similar kernel streams, switch to
using GNU patch and patchutils for intermediate patch manipulation.
Update the logic for applying, reverting, and regenerating patches:

- Use 'patch -p1' for better handling of context fuzz.
- Use 'recountdiff' to update line counts after FIX_PATCH_LINES.
- Drop git_refresh() and related git-specific logic.

Signed-off-by: Joe Lawrence <[email protected]>
---
 scripts/livepatch/klp-build | 50 +++++++++++--------------------------
 1 file changed, 14 insertions(+), 36 deletions(-)

I think this does simplify things, but:

  - introduces a dependency on patchutil's recountdiff
  - requires goofy epoch timestamp filtering as `diff -N` doesn't use
    the `git diff` /dev/null, but a localized beginining of time epoch
    that may be 1969 or 1970 depending on the local timezone
  - can be *really* chatty, for example:

  Validating patch(es)
  patching file fs/proc/cmdline.c
  Hunk #1 succeeded at 7 (offset 1 line).
  Fixing patch(es)
  patching file fs/proc/cmdline.c
  Hunk #1 succeeded at 7 (offset 1 line).
  patching file fs/proc/cmdline.c
  patching file fs/proc/cmdline.c
  Building patched kernel
  Copying patched object files
  Diffing objects
  vmlinux.o: changed function: override_release
  vmlinux.o: changed function: cmdline_proc_show
  Building patch module: livepatch-cmdline-string.ko
  SUCCESS

  My initial thought was that I'd only be interested in knowing about
  patch offset/fuzz during the validation phase.  And in the interest of
  clarifying some of the output messages, it would be nice to know the
  patch it was referring to, so how about a follow up patch
  pretty-formatting with some indentation like:

  Validating patch(es)
    cmdline-string.patch
      patching file fs/proc/cmdline.c
      Hunk #1 succeeded at 7 (offset 1 line).
  Fixing patch(es)
  Building patched kernel
  Copying patched object files
  Diffing objects
  vmlinux.o: changed function: override_release
  vmlinux.o: changed function: cmdline_proc_show
  Building patch module: livepatch-cmdline-string.ko
  SUCCESS

  That said, Song suggested using --silent across the board, so maybe
  tie that into the existing --verbose option?

diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 5a99ff4c4729..ee43a9caa107 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -96,7 +96,7 @@ restore_files() {
 
 cleanup() {
        set +o nounset
-       revert_patches "--recount"
+       revert_patches
        restore_files
        [[ "$KEEP_TMP" -eq 0 ]] && rm -rf "$TMP_DIR"
        return 0
@@ -285,7 +285,7 @@ set_module_name() {
 }
 
 # Hardcode the value printed by the localversion script to prevent patch
-# application from appending it with '+' due to a dirty git working tree.
+# application from appending it with '+' due to a dirty working tree.
 set_kernelversion() {
        local file="$SRC/scripts/setlocalversion"
        local localversion
@@ -303,8 +303,8 @@ get_patch_input_files() {
        local patch="$1"
 
        grep0 -E '^--- ' "$patch"                               \
+               | grep -v -e '/dev/null' -e '1969-12-31' -e '1970-01-01' \
                | gawk '{print $2}'                             \
-               | grep -v '^/dev/null$'                         \
                | sed 's|^[^/]*/||'                             \
                | sort -u
 }
@@ -313,8 +313,8 @@ get_patch_output_files() {
        local patch="$1"
 
        grep0 -E '^\+\+\+ ' "$patch"                            \
+               | grep -v -e '/dev/null' -e '1969-12-31' -e '1970-01-01' \
                | gawk '{print $2}'                             \
-               | grep -v '^/dev/null$'                         \
                | sed 's|^[^/]*/||'                             \
                | sort -u
 }
@@ -326,21 +326,6 @@ get_patch_files() {
                | sort -u
 }
 
-# Make sure git re-stats the changed files
-git_refresh() {
-       local patch="$1"
-       local files=()
-
-       [[ ! -e "$SRC/.git" ]] && return
-
-       get_patch_input_files "$patch" | mapfile -t files
-
-       (
-               cd "$SRC"
-               git update-index -q --refresh -- "${files[@]}"
-       )
-}
-
 check_unsupported_patches() {
        local patch
 
@@ -361,18 +346,14 @@ check_unsupported_patches() {
 
 apply_patch() {
        local patch="$1"
-       shift
-       local extra_args=("$@")
 
        [[ ! -f "$patch" ]] && die "$patch doesn't exist"
 
        (
                cd "$SRC"
-
-               # The sed strips the version signature from 'git format-patch',
-               # otherwise 'git apply --recount' warns.
-               sed -n '/^-- /q;p' "$patch" |
-                       git apply "${extra_args[@]}"
+               # The sed strips the version signature from 'git format-patch'.
+               sed -n '/^-- /q;p' "$patch" | \
+                       patch -p1 --no-backup-if-mismatch -r /dev/null
        )
 
        APPLIED_PATCHES+=("$patch")
@@ -380,17 +361,13 @@ apply_patch() {
 
 revert_patch() {
        local patch="$1"
-       shift
-       local extra_args=("$@")
        local tmp=()
 
        (
                cd "$SRC"
-
-               sed -n '/^-- /q;p' "$patch" |
-                       git apply --reverse "${extra_args[@]}"
+               sed -n '/^-- /q;p' "$patch" | \
+                       patch -p1 -R --silent --no-backup-if-mismatch -r 
/dev/null
        )
-       git_refresh "$patch"
 
        for p in "${APPLIED_PATCHES[@]}"; do
                [[ "$p" == "$patch" ]] && continue
@@ -437,6 +414,7 @@ do_init() {
        APPLIED_PATCHES=()
 
        [[ -x "$FIX_PATCH_LINES" ]] || die "can't find fix-patch-lines"
+       command -v recountdiff &>/dev/null || die "recountdiff not found 
(install patchutils)"
 
        validate_config
        set_module_name
@@ -462,12 +440,12 @@ refresh_patch() {
        ( cd "$SRC" && echo "${input_files[@]}" | xargs cp --parents 
--target-directory="$tmpdir/a" )
 
        # Copy patched source files to 'b'
-       apply_patch "$patch" --recount
+       apply_patch "$patch"
        ( cd "$SRC" && echo "${output_files[@]}" | xargs cp --parents 
--target-directory="$tmpdir/b" )
-       revert_patch "$patch" --recount
+       revert_patch "$patch"
 
        # Diff 'a' and 'b' to make a clean patch
-       ( cd "$tmpdir" && git diff --no-index --no-prefix a b > "$patch" ) || 
true
+       ( cd "$tmpdir" && diff -Nupr a b > "$patch" ) || true
 }
 
 # Copy the patches to a temporary directory, fix their lines so as not to
@@ -490,7 +468,7 @@ fix_patches() {
 
                cp -f "$old_patch" "$tmp_patch"
                refresh_patch "$tmp_patch"
-               "$FIX_PATCH_LINES" "$tmp_patch" > "$new_patch"
+               "$FIX_PATCH_LINES" "$tmp_patch" | recountdiff > "$new_patch"
                refresh_patch "$new_patch"
 
                PATCHES[i]="$new_patch"
-- 
2.52.0


Reply via email to