Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion pve/vm-core.func
Original file line number Diff line number Diff line change
Expand Up @@ -2641,7 +2641,16 @@ vm_import_disk() {
before="$(qm config "$vmid" 2>/dev/null | sed -n 's/^unused[0-9]*: //p')" || before=""

msg_info "Importing $(basename "$file") to ${storage}"
if ! out="$("${cmd[@]}" "$vmid" "$file" "$storage" "${opts[@]}" 2>&1)"; then
# A freshly extracted image still has writes pending; on ZFS the volume create
# then waited behind them and failed with "got timeout".
sync -f "$file" 2>/dev/null || sync
local attempt rc
for attempt in 1 2 3; do
out="$("${cmd[@]}" "$vmid" "$file" "$storage" "${opts[@]}" 2>&1)" && rc=0 || rc=$?
[[ $rc -ne 0 && "$out" == *"got timeout"* && $attempt -lt 3 ]] || break
sleep $((attempt * 10))
done
if [[ $rc -ne 0 ]]; then
msg_error "Importing $(basename "$file") into VM ${vmid} failed"
# Into the log too: the failure trace is read from there.
printf '%s\n' "$out" | tail -n 5 | tee -a "$(get_active_logfile)" >&2 || true
Expand Down
19 changes: 19 additions & 0 deletions tests/vm-helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,17 @@ QM_CONFIG_BEFORE=""
QM_CONFIG_AFTER=""
# A file, not a variable: the import runs inside a command substitution.
QM_IMPORTED_FLAG="$TEST_DIR/qm-imported"
QM_TIMEOUTS_FILE="$TEST_DIR/qm-timeouts"
qm() {
printf 'qm %s\n' "$*" >>"$LOG"
case "$1 ${2:-}" in
"disk import")
if [[ "${3:-}" == --help ]]; then [[ "$QM_MODERN" == yes ]]; return; fi
if [[ -s "$QM_TIMEOUTS_FILE" && "$(cat "$QM_TIMEOUTS_FILE")" -gt 0 ]]; then
echo $(($(cat "$QM_TIMEOUTS_FILE") - 1)) >"$QM_TIMEOUTS_FILE"
echo "command 'zfs create -s -V 33554432k rpool/data/vm-100-disk-0' failed: got timeout"
return 255
fi
: >"$QM_IMPORTED_FLAG"
printf '%s\n' "$QM_IMPORT_OUT"
return "$QM_IMPORT_RC"
Expand Down Expand Up @@ -256,6 +262,19 @@ assert_eq "$VM_IMPORTED_DISK" "local-lvm:vm-100-disk-1" "volume from qm's report
assert_contains "$LOG" "qm disk import 100 $IMAGE local-lvm --format raw"
ok "vm_import_disk uses qm disk import and the reported volume"

import_case
echo 1 >"$QM_TIMEOUTS_FILE"
vm_import_disk 100 "$IMAGE" local-lvm || fail "import after a zfs timeout"
assert_eq "$(grep -c 'qm disk import 100' "$LOG")" 2 "one timeout, one retry"
ok "vm_import_disk retries after a ZFS got timeout"

import_case
echo 9 >"$QM_TIMEOUTS_FILE"
vm_import_disk 100 "$IMAGE" local-lvm 2>/dev/null && fail "three timeouts still fail"
assert_eq "$(grep -c 'qm disk import 100' "$LOG")" 3 "gives up after three attempts"
: >"$QM_TIMEOUTS_FILE"
ok "vm_import_disk gives up after three timeouts"

import_case
QM_MODERN=no
vm_import_disk 100 "$IMAGE" local-lvm qcow2 || fail "legacy import"
Expand Down
Loading