Commit 5c90308f authored by Thomas Huth's avatar Thomas Huth Committed by Juan Quintela
Browse files

migration: Fix return code of ram_save_iterate()



qemu_savevm_state_iterate() expects the iterators to return 1
when they are done, and 0 if there is still something left to do.
However, ram_save_iterate() does not obey this rule and returns
the number of saved pages instead. This causes a fatal hang with
ppc64 guests when you run QEMU like this (also works with TCG):

 qemu-img create -f qcow2  /tmp/test.qcow2 1M
 qemu-system-ppc64 -nographic -nodefaults -m 256 \
                   -hda /tmp/test.qcow2 -serial mon:stdio

... then switch to the monitor by pressing CTRL-a c and try to
save a snapshot with "savevm test1" for example.

After the first iteration, ram_save_iterate() always returns 0 here,
so that qemu_savevm_state_iterate() hangs in an endless loop and you
can only "kill -9" the QEMU process.
Fix it by using proper return values in ram_save_iterate().

Signed-off-by: default avatarThomas Huth <thuth@redhat.com>
Reviewed-by: default avatarJuan Quintela <quintela@redhat.com>
Signed-off-by: default avatarJuan Quintela <quintela@redhat.com>
parent 8cc49f03
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1987,7 +1987,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
    int ret;
    int i;
    int64_t t0;
    int pages_sent = 0;
    int done = 0;

    rcu_read_lock();
    if (ram_list.version != last_version) {
@@ -2007,9 +2007,9 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
        pages = ram_find_and_save_block(f, false, &bytes_transferred);
        /* no more pages to sent */
        if (pages == 0) {
            done = 1;
            break;
        }
        pages_sent += pages;
        acct_info.iterations++;

        /* we want to check in the 1st loop, just in case it was the 1st time
@@ -2044,7 +2044,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
        return ret;
    }

    return pages_sent;
    return done;
}

/* Called with iothread lock */