From: Hailiang Zhang <zhang.zhanghailiang@huawei.com>
To: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: lizhijian@cn.fujitsu.com, quintela@redhat.com,
yunhong.jiang@intel.com, eddie.dong@intel.com,
peter.huangpeng@huawei.com, qemu-devel@nongnu.org,
arei.gonglei@huawei.com, stefanha@redhat.com,
amit.shah@redhat.com, hongyang.yang@easystack.cn
Subject: Re: [Qemu-devel] [PATCH COLO-Frame v11 23/39] COLO: Implement failover work for Primary VM
Date: Fri, 11 Dec 2015 15:54:46 +0800 [thread overview]
Message-ID: <566A8146.6010700@huawei.com> (raw)
In-Reply-To: <20151210183457.GJ2570@work-vm>
On 2015/12/11 2:34, Dr. David Alan Gilbert wrote:
> * zhanghailiang (zhang.zhanghailiang@huawei.com) wrote:
>> For PVM, if there is failover request from users.
>> The colo thread will exit the loop while the failover BH does the
>> cleanup work and resumes VM.
>>
>> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
>> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
>> ---
>> v11:
>> - Don't call migration_end() in primary_vm_do_failover(),
>> The cleanup work will be done in migration_thread().
>> - Remove vm_start() in primary_vm_do_failover() which also been done
>> in migraiton_thread()
>> v10:
>> - Call migration_end() in primary_vm_do_failover()
>> ---
>> include/migration/colo.h | 3 +++
>> include/migration/failover.h | 1 +
>> migration/colo-failover.c | 7 +++++-
>> migration/colo.c | 56 ++++++++++++++++++++++++++++++++++++++++++--
>> 4 files changed, 64 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/migration/colo.h b/include/migration/colo.h
>> index ba27719..0b02e95 100644
>> --- a/include/migration/colo.h
>> +++ b/include/migration/colo.h
>> @@ -32,4 +32,7 @@ void *colo_process_incoming_thread(void *opaque);
>> bool migration_incoming_in_colo_state(void);
>>
>> COLOMode get_colo_mode(void);
>> +
>> +/* failover */
>> +void colo_do_failover(MigrationState *s);
>> #endif
>> diff --git a/include/migration/failover.h b/include/migration/failover.h
>> index 882c625..fba3931 100644
>> --- a/include/migration/failover.h
>> +++ b/include/migration/failover.h
>> @@ -26,5 +26,6 @@ void failover_init_state(void);
>> int failover_set_state(int old_state, int new_state);
>> int failover_get_state(void);
>> void failover_request_active(Error **errp);
>> +bool failover_request_is_active(void);
>>
>> #endif
>> diff --git a/migration/colo-failover.c b/migration/colo-failover.c
>> index 1b1be24..0c525da 100644
>> --- a/migration/colo-failover.c
>> +++ b/migration/colo-failover.c
>> @@ -32,7 +32,7 @@ static void colo_failover_bh(void *opaque)
>> error_report("Unkown error for failover, old_state=%d", old_state);
>> return;
>> }
>> - /*TODO: Do failover work */
>> + colo_do_failover(NULL);
>> }
>>
>> void failover_request_active(Error **errp)
>> @@ -67,6 +67,11 @@ int failover_get_state(void)
>> return atomic_read(&failover_state);
>> }
>>
>> +bool failover_request_is_active(void)
>> +{
>> + return ((failover_get_state() != FAILOVER_STATUS_NONE));
>> +}
>> +
>> void qmp_x_colo_lost_heartbeat(Error **errp)
>> {
>> if (get_colo_mode() == COLO_MODE_UNKNOWN) {
>> diff --git a/migration/colo.c b/migration/colo.c
>> index cedfc63..7a42fc6 100644
>> --- a/migration/colo.c
>> +++ b/migration/colo.c
>> @@ -41,6 +41,42 @@ bool migration_incoming_in_colo_state(void)
>> return mis && (mis->state == MIGRATION_STATUS_COLO);
>> }
>>
>> +static bool colo_runstate_is_stopped(void)
>> +{
>> + return runstate_check(RUN_STATE_COLO) || !runstate_is_running();
>> +}
>> +
>> +static void primary_vm_do_failover(void)
>> +{
>> + MigrationState *s = migrate_get_current();
>> + int old_state;
>> +
>> + if (s->state != MIGRATION_STATUS_FAILED) {
>> + migrate_set_state(&s->state, MIGRATION_STATUS_COLO,
>> + MIGRATION_STATUS_COMPLETED);
>> + }
>
> That's a little odd; it will only move to completed if the current
> state is MIGRATION_STATUS_COLO, but you only do it if the state isn't
> FAILED. You could remove the if and just call migrate_set_state
> like that and it would be safe as long as you really only expect
> to have to deal with MIGRATION_STATUS_COLO.
>
Yes, you are right, i will remove the judgement, and set the state directly.
>> + old_state = failover_set_state(FAILOVER_STATUS_HANDLING,
>> + FAILOVER_STATUS_COMPLETED);
>> + if (old_state != FAILOVER_STATUS_HANDLING) {
>> + error_report("Serious error while do failover for Primary VM,"
>> + "old_state: %d", old_state);
>
> It's generally better to state the reason rather than say it's 'serious';
> so something like:
> 'Incorrect state (%d) while doing failover for Primary VM'
> tells you more, and looks less scary!
>
Ha, OK, i will fix it.
>> + return;
>> + }
>> +}
>> +
>> +void colo_do_failover(MigrationState *s)
>> +{
>> + /* Make sure vm stopped while failover */
>> + if (!colo_runstate_is_stopped()) {
>> + vm_stop_force_state(RUN_STATE_COLO);
>> + }
>
> That feels like a race? couldn't we be just at the end
> of taking a checkpoint and about to restart when you do
> the if, so it reads that it's currently stopped but
> then it restarts it by the time you have a chance to
> do anything?
Do you mean, after we stopped VM in failover() but before done the failover work,
the migration (checkpoint) thread may starts VM just in the middle time ?
The colo_do_failover() is in the context of BH, it holds
the __lock__, so checkpoint thread has no chance to execute vm_start().
> I see in patch 13 (Save PVM....) you have:
> qemu_mutex_lock_iothread();
> vm_start();
> qemu_mutex_unlock_iothread();
>
> So maybe if that code is executed just before the
> failover, then it would stop at the _lock_, we would
> run here but then as soon as we finish wouldn't it vm_start
> there?
>
But it seems that, we don't need to stop VM to do the failover work.
I'm not so sure, i will investigate if we can do it without stopping VM.
>> + if (get_colo_mode() == COLO_MODE_PRIMARY) {
>> + primary_vm_do_failover();
>> + }
>> +}
>> +
>> /* colo checkpoint control helper */
>> static int colo_ctl_put(QEMUFile *f, uint32_t cmd, uint64_t value)
>> {
>> @@ -122,9 +158,22 @@ static int colo_do_checkpoint_transaction(MigrationState *s,
>> }
>>
>> qemu_mutex_lock_iothread();
>> + if (failover_request_is_active()) {
>> + qemu_mutex_unlock_iothread();
>> + ret = -1;
>> + goto out;
>> + }
>> vm_stop_force_state(RUN_STATE_COLO);
>> qemu_mutex_unlock_iothread();
>> trace_colo_vm_state_change("run", "stop");
>> + /*
>> + * failover request bh could be called after
>> + * vm_stop_force_state so we check failover_request_is_active() again.
>> + */
>> + if (failover_request_is_active()) {
>> + ret = -1;
>> + goto out;
>> + }
>
> I'm confused about why the check is needed specifically here;
> for example can't that happen at any point where we're ousite of the
> iothread lock? e.g. couldn't we set failover just a couple of
> lines lower, lets say just after the s->params.blk= 0 ?
>
Yes, you are right, failover could happen at any place where we are not
holding iothread lock. We should checkpoint the failover status after every
important steps. I'll add more check in next version ...
>> /* Disable block migration */
>> s->params.blk = 0;
>> @@ -221,6 +270,11 @@ static void colo_process_checkpoint(MigrationState *s)
>> trace_colo_vm_state_change("stop", "run");
>>
>> while (s->state == MIGRATION_STATUS_COLO) {
>> + if (failover_request_is_active()) {
>> + error_report("failover request");
>> + goto out;
>> + }
>> +
>> current_time = qemu_clock_get_ms(QEMU_CLOCK_HOST);
>> if (current_time - checkpoint_time <
>> s->parameters[MIGRATION_PARAMETER_CHECKPOINT_DELAY]) {
>> @@ -242,8 +296,6 @@ out:
>> if (ret < 0) {
>> error_report("%s: %s", __func__, strerror(-ret));
>> }
>> - migrate_set_state(&s->state, MIGRATION_STATUS_COLO,
>> - MIGRATION_STATUS_COMPLETED);
>
> I had to think about this; but yes, I guess the only way out is via the failover
> which does the completed above.
>
Yes, thanks.
Hailiang
> Dave
>
>> qsb_free(buffer);
>> buffer = NULL;
>> --
>> 1.8.3.1
>>
>>
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
>
> .
>
next prev parent reply other threads:[~2015-12-11 8:00 UTC|newest]
Thread overview: 95+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-24 9:25 [Qemu-devel] [PATCH COLO-Frame v11 00/39] COarse-grain LOck-stepping(COLO) Virtual Machines for Non-stop Service (FT) zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 01/39] configure: Add parameter for configure to enable/disable COLO support zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 02/39] migration: Introduce capability 'x-colo' to migration zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 03/39] COLO: migrate colo related info to secondary node zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 04/39] migration: Export migrate_set_state() zhanghailiang
2015-11-24 17:31 ` Dr. David Alan Gilbert
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 05/39] migration: Add state records for migration incoming zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 06/39] migration: Integrate COLO checkpoint process into migration zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 07/39] migration: Integrate COLO checkpoint process into loadvm zhanghailiang
2015-11-24 18:14 ` Dr. David Alan Gilbert
2015-11-25 6:39 ` zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 08/39] migration: Rename the'file' member of MigrationState zhanghailiang
2015-11-24 18:26 ` Dr. David Alan Gilbert
2015-11-25 6:48 ` zhanghailiang
2015-12-10 6:41 ` Wen Congyang
2015-12-11 3:40 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 09/39] COLO/migration: Create a new communication path from destination to source zhanghailiang
2015-11-24 18:40 ` Dr. David Alan Gilbert
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 10/39] COLO: Implement colo checkpoint protocol zhanghailiang
2015-11-24 19:00 ` Dr. David Alan Gilbert
2015-11-25 14:01 ` Eric Blake
2015-11-26 6:52 ` Hailiang Zhang
2015-11-26 7:12 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 11/39] COLO: Add a new RunState RUN_STATE_COLO zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 12/39] QEMUSizedBuffer: Introduce two help functions for qsb zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 13/39] COLO: Save PVM state to secondary side when do checkpoint zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 14/39] ram: Split host_from_stream_offset() into two helper functions zhanghailiang
2015-12-01 18:19 ` Dr. David Alan Gilbert
2015-12-03 7:19 ` Hailiang Zhang
2015-12-03 7:29 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 15/39] COLO: Load PVM's dirty pages into SVM's RAM cache temporarily zhanghailiang
2015-12-01 19:02 ` Dr. David Alan Gilbert
2015-12-03 8:25 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 16/39] ram/COLO: Record the dirty pages that SVM received zhanghailiang
2015-12-01 19:36 ` Dr. David Alan Gilbert
2015-12-03 8:29 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 17/39] COLO: Load VMState into qsb before restore it zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 18/39] COLO: Flush PVM's cached RAM into SVM's memory zhanghailiang
2015-11-27 5:29 ` Li Zhijian
2015-12-01 12:02 ` Hailiang Zhang
2015-12-01 20:06 ` Dr. David Alan Gilbert
2015-12-03 8:50 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 19/39] COLO: Add checkpoint-delay parameter for migrate-set-parameters zhanghailiang
2015-12-09 18:50 ` Dr. David Alan Gilbert
2015-12-11 3:20 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 20/39] COLO: synchronize PVM's state to SVM periodically zhanghailiang
2015-12-09 18:53 ` Dr. David Alan Gilbert
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 21/39] COLO failover: Introduce a new command to trigger a failover zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 22/39] COLO failover: Introduce state to record failover process zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 23/39] COLO: Implement failover work for Primary VM zhanghailiang
2015-12-10 18:34 ` Dr. David Alan Gilbert
2015-12-11 7:54 ` Hailiang Zhang [this message]
2015-12-11 9:22 ` Dr. David Alan Gilbert
2015-12-11 9:38 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 24/39] COLO: Implement failover work for Secondary VM zhanghailiang
2015-12-10 18:50 ` Dr. David Alan Gilbert
2015-12-11 8:27 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 25/39] COLO: implement default failover treatment zhanghailiang
2015-12-10 19:01 ` Dr. David Alan Gilbert
2015-12-11 9:48 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 26/39] qmp event: Add event notification for COLO error zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 27/39] COLO failover: Shutdown related socket fd when do failover zhanghailiang
2015-12-10 20:03 ` Dr. David Alan Gilbert
2015-12-11 8:57 ` Hailiang Zhang
2015-12-11 9:18 ` Dr. David Alan Gilbert
2015-12-11 9:29 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 28/39] COLO failover: Don't do failover during loading VM's state zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 29/39] COLO: Process shutdown command for VM in COLO state zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 30/39] COLO: Update the global runstate after going into colo state zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 31/39] savevm: Split load vm state function qemu_loadvm_state zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 32/39] COLO: Separate the process of saving/loading ram and device state zhanghailiang
2015-11-27 5:10 ` Li Zhijian
2015-12-01 12:07 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 33/39] COLO: Split qemu_savevm_state_begin out of checkpoint process zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 34/39] net/filter-buffer: Add default filter-buffer for each netdev zhanghailiang
2015-11-27 11:39 ` Yang Hongyang
2015-11-28 5:55 ` Hailiang Zhang
2015-11-30 1:19 ` Li Zhijian
2015-12-01 8:56 ` Hailiang Zhang
2015-12-03 1:17 ` Wen Congyang
2015-12-03 3:53 ` Hailiang Zhang
2015-12-03 6:25 ` Wen Congyang
2015-12-03 6:48 ` Hailiang Zhang
2015-12-03 7:21 ` Yang Hongyang
2015-12-03 8:37 ` Hailiang Zhang
2015-12-07 7:38 ` Hailiang Zhang
2015-12-08 1:49 ` Yang Hongyang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 35/39] filter-buffer: Accept zero interval zhanghailiang
2015-11-27 11:42 ` Yang Hongyang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 36/39] filter-buffer: Introduce a helper function to enable/disable default filter zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 37/39] filter-buffer: Introduce a helper function to release packets zhanghailiang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 38/39] colo: Use default buffer-filter to buffer and " zhanghailiang
2015-11-27 12:51 ` Yang Hongyang
2015-11-28 6:15 ` Hailiang Zhang
2015-11-24 9:25 ` [Qemu-devel] [PATCH COLO-Frame v11 39/39] COLO: Add block replication into colo process zhanghailiang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=566A8146.6010700@huawei.com \
--to=zhang.zhanghailiang@huawei.com \
--cc=amit.shah@redhat.com \
--cc=arei.gonglei@huawei.com \
--cc=dgilbert@redhat.com \
--cc=eddie.dong@intel.com \
--cc=hongyang.yang@easystack.cn \
--cc=lizhijian@cn.fujitsu.com \
--cc=peter.huangpeng@huawei.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=stefanha@redhat.com \
--cc=yunhong.jiang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).