Revision 51cf4c1a

b/migration.c
40 40
    MIG_STATE_ERROR = -1,
41 41
    MIG_STATE_NONE,
42 42
    MIG_STATE_SETUP,
43
    MIG_STATE_CANCELLING,
43 44
    MIG_STATE_CANCELLED,
44 45
    MIG_STATE_ACTIVE,
45 46
    MIG_STATE_COMPLETED,
......
196 197
        info->has_total_time = false;
197 198
        break;
198 199
    case MIG_STATE_ACTIVE:
200
    case MIG_STATE_CANCELLING:
199 201
        info->has_status = true;
200 202
        info->status = g_strdup("active");
201 203
        info->has_total_time = true;
......
282 284

  
283 285
/* shared migration helpers */
284 286

  
287
static void migrate_set_state(MigrationState *s, int old_state, int new_state)
288
{
289
    if (atomic_cmpxchg(&s->state, old_state, new_state) == new_state) {
290
        trace_migrate_set_state(new_state);
291
    }
292
}
293

  
285 294
static void migrate_fd_cleanup(void *opaque)
286 295
{
287 296
    MigrationState *s = opaque;
......
303 312

  
304 313
    if (s->state != MIG_STATE_COMPLETED) {
305 314
        qemu_savevm_state_cancel();
315
        if (s->state == MIG_STATE_CANCELLING) {
316
            migrate_set_state(s, MIG_STATE_CANCELLING, MIG_STATE_CANCELLED);
317
        }
306 318
    }
307 319

  
308 320
    notifier_list_notify(&migration_state_notifiers, s);
309 321
}
310 322

  
311
static void migrate_set_state(MigrationState *s, int old_state, int new_state)
312
{
313
    if (atomic_cmpxchg(&s->state, old_state, new_state) == new_state) {
314
        trace_migrate_set_state(new_state);
315
    }
316
}
317

  
318 323
void migrate_fd_error(MigrationState *s)
319 324
{
320 325
    DPRINTF("setting error state\n");
......
334 339
        if (old_state != MIG_STATE_SETUP && old_state != MIG_STATE_ACTIVE) {
335 340
            break;
336 341
        }
337
        migrate_set_state(s, old_state, MIG_STATE_CANCELLED);
338
    } while (s->state != MIG_STATE_CANCELLED);
342
        migrate_set_state(s, old_state, MIG_STATE_CANCELLING);
343
    } while (s->state != MIG_STATE_CANCELLING);
339 344
}
340 345

  
341 346
void add_migration_state_change_notifier(Notifier *notify)
......
412 417
    params.blk = has_blk && blk;
413 418
    params.shared = has_inc && inc;
414 419

  
415
    if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP) {
420
    if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP ||
421
        s->state == MIG_STATE_CANCELLING) {
416 422
        error_set(errp, QERR_MIGRATION_ACTIVE);
417 423
        return;
418 424
    }

Also available in: Unified diff