mirror of
https://github.com/dynup/kpatch
synced 2025-04-11 03:31:20 +00:00
If kpatch fails to disable a patch, retry a few times
This is similar to how loading of the patches works now. Needed mostly for the "old" kpatch, i.e. for the kernels that do not support livepatch. If the patched functions are currently used, loading of the patch fails with "Device or resource busy" error. kpatch script then retries the operation several times. In some cases, it could be convenient to do the same thing when unloading or simply disabling the patches. One of the use cases is when it is needed to replace a loaded cumulative patch with its previous version, esp. if the patches have patch/unpatch hooks. It is often more reliable to disable the loaded patches first and then load the new patch. Disable operation may fail due to activeness safety check - so let us retry it a few times. v2: As suggested in PR #790, disable_patch() no longer returns a value but rather calls die() at the point of error. Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
This commit is contained in:
parent
2d0fd42c64
commit
23f4e7554d
@ -348,19 +348,44 @@ load_module () {
|
||||
return 0
|
||||
}
|
||||
|
||||
disable_patch () {
|
||||
local modname="$1"
|
||||
|
||||
local enabled="$SYSFS/$modname/enabled"
|
||||
[[ -e "$enabled" ]] || die "patch module $1 is not loaded"
|
||||
|
||||
if [[ "$(cat "$enabled")" -eq 1 ]]; then
|
||||
echo "disabling patch module: $modname"
|
||||
local i=0
|
||||
while true; do
|
||||
out="$(export LC_ALL=C; sh -c "echo 0 > $enabled" 2>&1)"
|
||||
[[ -z "$out" ]] && break
|
||||
echo "$out" 1>&2
|
||||
if [[ ! "$out" =~ "Device or resource busy" ]]; then
|
||||
die "failed to disable module $modname"
|
||||
fi
|
||||
|
||||
# "Device or resource busy" means the activeness safety check
|
||||
# failed. Retry in a few seconds.
|
||||
i=$((i+1))
|
||||
if [[ $i = $MAX_LOAD_ATTEMPTS ]]; then
|
||||
die "failed to disable module $modname"
|
||||
else
|
||||
warn "retrying..."
|
||||
sleep $RETRY_INTERVAL
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if ! wait_for_patch_transition "$modname" ; then
|
||||
die "transition stalled for $modname"
|
||||
fi
|
||||
}
|
||||
|
||||
unload_module () {
|
||||
PATCH="${1//-/_}"
|
||||
PATCH="${PATCH%.ko}"
|
||||
ENABLED="$SYSFS/$PATCH/enabled"
|
||||
[[ -e "$ENABLED" ]] || die "patch module $1 is not loaded"
|
||||
if [[ "$(cat "$ENABLED")" -eq 1 ]]; then
|
||||
echo "disabling patch module: $PATCH"
|
||||
echo 0 > "$ENABLED" || die "can't disable $PATCH"
|
||||
fi
|
||||
|
||||
if ! wait_for_patch_transition "$PATCH" ; then
|
||||
die "error: failed to unload module $PATCH (transition stalled)"
|
||||
fi
|
||||
disable_patch "$PATCH"
|
||||
|
||||
echo "unloading patch module: $PATCH"
|
||||
# ignore any error here because rmmod can fail if the module used
|
||||
|
Loading…
Reference in New Issue
Block a user