qemu_migration.c 183.6 KB
Newer Older
1 2 3
/*
 * qemu_migration.c: QEMU migration handling
 *
4
 * Copyright (C) 2006-2015 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
19 20 21 22 23
 *
 */

#include <config.h>

J
Ján Tomko 已提交
24 25
#include <netdb.h>
#include <sys/socket.h>
26
#include <sys/time.h>
27
#include <fcntl.h>
28
#include <poll.h>
29 30

#include "qemu_migration.h"
31
#include "qemu_migration_cookie.h"
32
#include "qemu_migration_params.h"
33 34 35 36
#include "qemu_monitor.h"
#include "qemu_domain.h"
#include "qemu_process.h"
#include "qemu_capabilities.h"
37
#include "qemu_alias.h"
38
#include "qemu_cgroup.h"
39
#include "qemu_hotplug.h"
40
#include "qemu_blockjob.h"
41
#include "qemu_security.h"
42

43
#include "domain_audit.h"
44
#include "virlog.h"
45
#include "virerror.h"
46
#include "viralloc.h"
E
Eric Blake 已提交
47
#include "virfile.h"
48
#include "virnetdevopenvswitch.h"
49
#include "datatypes.h"
50
#include "virfdstream.h"
51
#include "viruuid.h"
52
#include "virtime.h"
53
#include "locking/domain_lock.h"
54
#include "rpc/virnetsocket.h"
55
#include "virstoragefile.h"
M
Martin Kletzander 已提交
56
#include "viruri.h"
57
#include "virhook.h"
58
#include "virstring.h"
59
#include "virtypedparam.h"
M
Michael R. Hines 已提交
60
#include "virprocess.h"
61
#include "nwfilter_conf.h"
62 63 64

#define VIR_FROM_THIS VIR_FROM_QEMU

65 66
VIR_LOG_INIT("qemu.qemu_migration");

67 68 69 70 71 72 73 74 75 76 77 78 79
VIR_ENUM_IMPL(qemuMigrationJobPhase, QEMU_MIGRATION_PHASE_LAST,
              "none",
              "perform2",
              "begin3",
              "perform3",
              "perform3_done",
              "confirm3_cancelled",
              "confirm3",
              "prepare",
              "finish2",
              "finish3",
);

80 81 82
static int
qemuMigrationJobStart(virQEMUDriverPtr driver,
                      virDomainObjPtr vm,
83 84
                      qemuDomainAsyncJob job,
                      unsigned long apiFlags)
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;

static void
qemuMigrationJobSetPhase(virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
                         qemuMigrationJobPhase phase)
    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);

static void
qemuMigrationJobStartPhase(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
                           qemuMigrationJobPhase phase)
    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);

static void
qemuMigrationJobContinue(virDomainObjPtr obj)
    ATTRIBUTE_NONNULL(1);

static bool
qemuMigrationJobIsActive(virDomainObjPtr vm,
                         qemuDomainAsyncJob job)
    ATTRIBUTE_NONNULL(1);

static void
qemuMigrationJobFinish(virQEMUDriverPtr driver,
                       virDomainObjPtr obj)
    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
112

113
static void
114
qemuMigrationSrcStoreDomainState(virDomainObjPtr vm)
115 116 117 118 119 120 121 122 123 124
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    priv->preMigrationState = virDomainObjGetState(vm, NULL);

    VIR_DEBUG("Storing pre-migration state=%d domain=%p",
              priv->preMigrationState, vm);
}

/* Returns true if the domain was resumed, false otherwise */
static bool
125
qemuMigrationSrcRestoreDomainState(virQEMUDriverPtr driver, virDomainObjPtr vm)
126 127
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
128 129
    int reason;
    virDomainState state = virDomainObjGetState(vm, &reason);
130 131
    bool ret = false;

132 133 134 135 136
    VIR_DEBUG("driver=%p, vm=%p, pre-mig-state=%s, state=%s, reason=%s",
              driver, vm,
              virDomainStateTypeToString(priv->preMigrationState),
              virDomainStateTypeToString(state),
              virDomainStateReasonToString(state, reason));
137

138 139 140 141 142
    if (state != VIR_DOMAIN_PAUSED ||
        reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED)
        goto cleanup;

    if (priv->preMigrationState == VIR_DOMAIN_RUNNING) {
143 144 145 146 147 148
        /* This is basically the only restore possibility that's safe
         * and we should attempt to do */

        VIR_DEBUG("Restoring pre-migration state due to migration error");

        /* we got here through some sort of failure; start the domain again */
149
        if (qemuProcessStartCPUs(driver, vm,
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
                                 VIR_DOMAIN_RUNNING_MIGRATION_CANCELED,
                                 QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) {
            /* Hm, we already know we are in error here.  We don't want to
             * overwrite the previous error, though, so we just throw something
             * to the logs and hope for the best */
            VIR_ERROR(_("Failed to resume guest %s after failure"), vm->def->name);
            goto cleanup;
        }
        ret = true;
    }

 cleanup:
    priv->preMigrationState = VIR_DOMAIN_NOSTATE;
    return ret;
}

166 167

static int
168 169 170
qemuMigrationDstPrecreateDisk(virConnectPtr conn,
                              virDomainDiskDefPtr disk,
                              unsigned long long capacity)
171 172 173 174 175 176 177 178 179 180 181 182
{
    int ret = -1;
    virStoragePoolPtr pool = NULL;
    virStorageVolPtr vol = NULL;
    char *volName = NULL, *basePath = NULL;
    char *volStr = NULL;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const char *format = NULL;
    unsigned int flags = 0;

    VIR_DEBUG("Precreate disk type=%s", virStorageTypeToString(disk->src->type));

183
    switch ((virStorageType)disk->src->type) {
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
    case VIR_STORAGE_TYPE_FILE:
        if (!virDomainDiskGetSource(disk)) {
            VIR_DEBUG("Dropping sourceless disk '%s'",
                      disk->dst);
            return 0;
        }

        if (VIR_STRDUP(basePath, disk->src->path) < 0)
            goto cleanup;

        if (!(volName = strrchr(basePath, '/'))) {
            virReportError(VIR_ERR_INVALID_ARG,
                           _("malformed disk path: %s"),
                           disk->src->path);
            goto cleanup;
        }

        *volName = '\0';
        volName++;

204
        if (!(pool = virStoragePoolLookupByTargetPath(conn, basePath)))
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
            goto cleanup;
        format = virStorageFileFormatTypeToString(disk->src->format);
        if (disk->src->format == VIR_STORAGE_FILE_QCOW2)
            flags |= VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA;
        break;

    case VIR_STORAGE_TYPE_VOLUME:
        if (!(pool = virStoragePoolLookupByName(conn, disk->src->srcpool->pool)))
            goto cleanup;
        format = virStorageFileFormatTypeToString(disk->src->format);
        volName = disk->src->srcpool->volume;
        if (disk->src->format == VIR_STORAGE_FILE_QCOW2)
            flags |= VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA;
        break;

220 221 222 223 224
    case VIR_STORAGE_TYPE_NETWORK:
        VIR_DEBUG("Skipping creation of network disk '%s'",
                  disk->dst);
        return 0;

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
    case VIR_STORAGE_TYPE_BLOCK:
    case VIR_STORAGE_TYPE_DIR:
    case VIR_STORAGE_TYPE_NONE:
    case VIR_STORAGE_TYPE_LAST:
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot precreate storage for disk type '%s'"),
                       virStorageTypeToString(disk->src->type));
        goto cleanup;
    }

    if ((vol = virStorageVolLookupByName(pool, volName))) {
        VIR_DEBUG("Skipping creation of already existing volume of name '%s'",
                  volName);
        ret = 0;
        goto cleanup;
    }

    virBufferAddLit(&buf, "<volume>\n");
    virBufferAdjustIndent(&buf, 2);
    virBufferEscapeString(&buf, "<name>%s</name>\n", volName);
    virBufferAsprintf(&buf, "<capacity>%llu</capacity>\n", capacity);
    virBufferAddLit(&buf, "<target>\n");
    virBufferAdjustIndent(&buf, 2);
    virBufferAsprintf(&buf, "<format type='%s'/>\n", format);
    virBufferAdjustIndent(&buf, -2);
    virBufferAddLit(&buf, "</target>\n");
    virBufferAdjustIndent(&buf, -2);
    virBufferAddLit(&buf, "</volume>\n");

    if (!(volStr = virBufferContentAndReset(&buf))) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("unable to create volume XML"));
        goto cleanup;
    }

    if (!(vol = virStorageVolCreateXML(pool, volStr, flags)))
        goto cleanup;

    ret = 0;
 cleanup:
    VIR_FREE(basePath);
    VIR_FREE(volStr);
    virObjectUnref(vol);
    virObjectUnref(pool);
    return ret;
}

272
static bool
273 274
qemuMigrationAnyCopyDisk(virDomainDiskDef const *disk,
                         size_t nmigrate_disks, const char **migrate_disks)
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
{
    size_t i;

    /* Check if the disk alias is in the list */
    if (nmigrate_disks) {
        for (i = 0; i < nmigrate_disks; i++) {
            if (STREQ(disk->dst, migrate_disks[i]))
                return true;
        }
        return false;
    }

    /* Default is to migrate only non-shared non-readonly disks
     * with source */
    return !disk->src->shared && !disk->src->readonly &&
290
           !virStorageSourceIsEmpty(disk->src);
291 292
}

293 294

static int
295 296 297 298 299
qemuMigrationDstPrecreateStorage(virDomainObjPtr vm,
                                 qemuMigrationCookieNBDPtr nbd,
                                 size_t nmigrate_disks,
                                 const char **migrate_disks,
                                 bool incremental)
300 301 302
{
    int ret = -1;
    size_t i = 0;
303
    virConnectPtr conn;
304 305 306 307

    if (!nbd || !nbd->ndisks)
        return 0;

308 309 310
    if (!(conn = virGetConnectStorage()))
        return -1;

311 312 313 314
    for (i = 0; i < nbd->ndisks; i++) {
        virDomainDiskDefPtr disk;
        const char *diskSrcPath;

315
        VIR_DEBUG("Looking up disk target '%s' (capacity=%llu)",
316 317
                  nbd->disks[i].target, nbd->disks[i].capacity);

318 319
        if (!(disk = virDomainDiskByName(vm->def, nbd->disks[i].target,
                                         false))) {
320 321 322 323 324 325 326 327
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unable to find disk by target: %s"),
                           nbd->disks[i].target);
            goto cleanup;
        }

        diskSrcPath = virDomainDiskGetSource(disk);

328
        /* Skip disks we don't want to migrate and already existing disks. */
329
        if (!qemuMigrationAnyCopyDisk(disk, nmigrate_disks, migrate_disks) ||
330 331 332 333
            (diskSrcPath && virFileExists(diskSrcPath))) {
            continue;
        }

334 335 336 337 338 339 340
        if (incremental) {
            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                           _("pre-creation of storage targets for incremental "
                             "storage migration is not supported"));
            goto cleanup;
        }

341 342
        VIR_DEBUG("Proceeding with disk source %s", NULLSTR(diskSrcPath));

343
        if (qemuMigrationDstPrecreateDisk(conn, disk, nbd->disks[i].capacity) < 0)
344 345 346 347 348
            goto cleanup;
    }

    ret = 0;
 cleanup:
349
    virObjectUnref(conn);
350 351 352 353
    return ret;
}


354
/**
355
 * qemuMigrationDstStartNBDServer:
356 357 358 359 360 361 362 363 364 365 366
 * @driver: qemu driver
 * @vm: domain
 *
 * Starts NBD server. This is a newer method to copy
 * storage during migration than using 'blk' and 'inc'
 * arguments in 'migrate' monitor command.
 * Error is reported here.
 *
 * Returns 0 on success, -1 otherwise.
 */
static int
367 368 369 370 371
qemuMigrationDstStartNBDServer(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
                               const char *listenAddr,
                               size_t nmigrate_disks,
                               const char **migrate_disks,
372 373
                               int nbdPort,
                               const char *tls_alias)
374 375 376 377 378 379 380
{
    int ret = -1;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    unsigned short port = 0;
    char *diskAlias = NULL;
    size_t i;

381 382 383 384 385 386
    if (nbdPort < 0 || nbdPort > USHRT_MAX) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("nbd port must be in range 0-65535"));
        return -1;
    }

387 388 389
    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];

390
        /* check whether disk should be migrated */
391
        if (!qemuMigrationAnyCopyDisk(disk, nmigrate_disks, migrate_disks))
392 393
            continue;

394
        if (disk->src->readonly || virStorageSourceIsEmpty(disk->src)) {
395
            virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
396 397
                           _("Cannot migrate empty or read-only disk %s"),
                           disk->dst);
398 399 400
            goto cleanup;
        }

401
        VIR_FREE(diskAlias);
402
        if (!(diskAlias = qemuAliasFromDisk(disk)))
403 404 405 406 407 408
            goto cleanup;

        if (qemuDomainObjEnterMonitorAsync(driver, vm,
                                           QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
            goto cleanup;

409 410 411 412 413 414
        if (port == 0) {
            if (nbdPort)
                port = nbdPort;
            else if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0)
                goto exit_monitor;

415
            if (qemuMonitorNBDServerStart(priv->mon, listenAddr, port, tls_alias) < 0)
416
                goto exit_monitor;
417 418
        }

419 420 421
        if (qemuMonitorNBDServerAdd(priv->mon, diskAlias, true) < 0)
            goto exit_monitor;
        if (qemuDomainObjExitMonitor(driver, vm) < 0)
422 423 424 425 426 427
            goto cleanup;
    }

    priv->nbdPort = port;
    ret = 0;

428
 cleanup:
429
    VIR_FREE(diskAlias);
430
    if (ret < 0 && nbdPort == 0)
431
        virPortAllocatorRelease(port);
432
    return ret;
433 434 435 436

 exit_monitor:
    ignore_value(qemuDomainObjExitMonitor(driver, vm));
    goto cleanup;
437 438
}

439 440

static int
441 442 443
qemuMigrationDstStopNBDServer(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              qemuMigrationCookiePtr mig)
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
{
    qemuDomainObjPrivatePtr priv = vm->privateData;

    if (!mig->nbd)
        return 0;

    if (qemuDomainObjEnterMonitorAsync(driver, vm,
                                       QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
        return -1;

    if (qemuMonitorNBDServerStop(priv->mon) < 0)
        VIR_WARN("Unable to stop NBD server");
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        return -1;

459
    virPortAllocatorRelease(priv->nbdPort);
460 461 462 463 464 465
    priv->nbdPort = 0;
    return 0;
}


/**
466
 * qemuMigrationSrcDriveMirrorReady:
467 468 469
 * @vm: domain
 *
 * Check the status of all drive-mirrors started by
470
 * qemuMigrationSrcDriveMirror. Any pending block job events
471 472 473 474 475 476 477
 * for the mirrored disks will be processed.
 *
 * Returns 1 if all mirrors are "ready",
 *         0 if some mirrors are still performing initial sync,
 *        -1 on error.
 */
static int
478
qemuMigrationSrcDriveMirrorReady(virDomainObjPtr vm,
479
                                 qemuDomainAsyncJob asyncJob)
480 481
{
    size_t i;
482 483
    size_t notReady = 0;
    int status;
484 485 486

    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
487
        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
488
        char *error = NULL;
489

490
        if (!diskPriv->migrating)
491 492
            continue;

493
        status = qemuBlockJobUpdate(vm, asyncJob, disk, &error);
494
        if (status == VIR_DOMAIN_BLOCK_JOB_FAILED) {
495 496 497 498 499 500 501 502 503
            if (error) {
                virReportError(VIR_ERR_OPERATION_FAILED,
                               _("migration of disk %s failed: %s"),
                               disk->dst, error);
                VIR_FREE(error);
            } else {
                virReportError(VIR_ERR_OPERATION_FAILED,
                               _("migration of disk %s failed"), disk->dst);
            }
504 505
            return -1;
        }
506
        VIR_FREE(error);
507 508 509

        if (disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_READY)
            notReady++;
510 511
    }

512 513 514 515 516 517 518
    if (notReady) {
        VIR_DEBUG("Waiting for %zu disk mirrors to get ready", notReady);
        return 0;
    } else {
        VIR_DEBUG("All disk mirrors are ready");
        return 1;
    }
519 520 521
}


522 523 524 525
/*
 * If @check is true, the function will report an error and return a different
 * code in case a block job fails. This way we can properly abort migration in
 * case some block jobs failed once all memory has already been transferred.
526
 *
527 528 529 530
 * Returns 1 if all mirrors are gone,
 *         0 if some mirrors are still active,
 *         -1 some mirrors failed but some are still active,
 *         -2 all mirrors are gone but some of them failed.
531 532
 */
static int
533
qemuMigrationDriveMirrorCancelled(virDomainObjPtr vm,
534
                                  qemuDomainAsyncJob asyncJob,
535
                                  bool check)
536
{
537 538
    size_t i;
    size_t active = 0;
539
    size_t completed = 0;
540 541
    int status;
    bool failed = false;
542

543
 retry:
544 545 546
    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
547
        char *error = NULL;
548

549 550
        if (!diskPriv->migrating)
            continue;
551

552
        status = qemuBlockJobUpdate(vm, asyncJob, disk, &error);
553 554 555
        switch (status) {
        case VIR_DOMAIN_BLOCK_JOB_FAILED:
            if (check) {
556 557 558 559 560 561 562 563
                if (error) {
                    virReportError(VIR_ERR_OPERATION_FAILED,
                                   _("migration of disk %s failed: %s"),
                                   disk->dst, error);
                } else {
                    virReportError(VIR_ERR_OPERATION_FAILED,
                                   _("migration of disk %s failed"), disk->dst);
                }
564
                failed = true;
565
            }
M
Marc Hartmayer 已提交
566
            ATTRIBUTE_FALLTHROUGH;
567 568
        case VIR_DOMAIN_BLOCK_JOB_CANCELED:
        case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
569
            qemuBlockJobSyncEnd(vm, asyncJob, disk);
570 571
            diskPriv->migrating = false;
            break;
572

573 574
        default:
            active++;
575
        }
576 577 578

        if (status == VIR_DOMAIN_BLOCK_JOB_COMPLETED)
            completed++;
579 580

        VIR_FREE(error);
581 582 583 584 585 586 587 588 589 590
    }

    /* Updating completed block job drops the lock thus we have to recheck
     * block jobs for disks that reside before the disk(s) with completed
     * block job.
     */
    if (completed > 0) {
        completed = 0;
        active = 0;
        goto retry;
591
    }
592

593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
    if (failed) {
        if (active) {
            VIR_DEBUG("Some disk mirrors failed; still waiting for %zu "
                      "disk mirrors to finish", active);
            return -1;
        } else {
            VIR_DEBUG("All disk mirrors are gone; some of them failed");
            return -2;
        }
    } else {
        if (active) {
            VIR_DEBUG("Waiting for %zu disk mirrors to finish", active);
            return 0;
        } else {
            VIR_DEBUG("All disk mirrors are gone");
            return 1;
609
        }
610
    }
611
}
612 613


614 615 616 617 618 619
/*
 * Returns 0 on success,
 *         1 when job is already completed or it failed and failNoJob is false,
 *         -1 on error or when job failed and failNoJob is true.
 */
static int
620 621 622 623 624
qemuMigrationSrcCancelOneDriveMirror(virQEMUDriverPtr driver,
                                     virDomainObjPtr vm,
                                     virDomainDiskDefPtr disk,
                                     bool failNoJob,
                                     qemuDomainAsyncJob asyncJob)
625 626 627
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    char *diskAlias = NULL;
628
    char *error = NULL;
629 630 631 632
    int ret = -1;
    int status;
    int rv;

633
    status = qemuBlockJobUpdate(vm, asyncJob, disk, &error);
634 635 636 637
    switch (status) {
    case VIR_DOMAIN_BLOCK_JOB_FAILED:
    case VIR_DOMAIN_BLOCK_JOB_CANCELED:
        if (failNoJob) {
638 639 640 641 642 643 644 645 646
            if (error) {
                virReportError(VIR_ERR_OPERATION_FAILED,
                               _("migration of disk %s failed: %s"),
                               disk->dst, error);
            } else {
                virReportError(VIR_ERR_OPERATION_FAILED,
                               _("migration of disk %s failed"), disk->dst);
            }
            goto cleanup;
647
        }
648
        ATTRIBUTE_FALLTHROUGH;
649
    case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
650 651
        ret = 1;
        goto cleanup;
652 653
    }

654
    if (!(diskAlias = qemuAliasFromDisk(disk)))
655 656
        return -1;

657
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
658 659
        goto cleanup;

660
    rv = qemuMonitorBlockJobCancel(priv->mon, diskAlias);
661 662 663 664 665

    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0)
        goto cleanup;

    ret = 0;
666 667 668

 cleanup:
    VIR_FREE(diskAlias);
669
    VIR_FREE(error);
670 671 672 673 674
    return ret;
}


/**
675
 * qemuMigrationSrcCancelDriveMirror:
676 677
 * @driver: qemu driver
 * @vm: domain
678
 * @check: if true report an error when some of the mirrors fails
679 680 681 682 683 684 685 686
 *
 * Cancel all drive-mirrors started by qemuMigrationDriveMirror.
 * Any pending block job events for the affected disks will be
 * processed.
 *
 * Returns 0 on success, -1 otherwise.
 */
static int
687 688 689 690 691
qemuMigrationSrcCancelDriveMirror(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
                                  bool check,
                                  qemuDomainAsyncJob asyncJob,
                                  virConnectPtr dconn)
692
{
693
    virErrorPtr err = NULL;
694
    int ret = -1;
695
    size_t i;
696 697 698 699
    int rv;
    bool failed = false;

    VIR_DEBUG("Cancelling drive mirrors for domain %s", vm->def->name);
700 701 702

    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
703
        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
704

705
        if (!diskPriv->migrating)
706 707
            continue;

708 709
        rv = qemuMigrationSrcCancelOneDriveMirror(driver, vm, disk,
                                                  check, asyncJob);
710 711 712 713 714 715
        if (rv != 0) {
            if (rv < 0) {
                if (!err)
                    err = virSaveLastError();
                failed = true;
            }
716
            qemuBlockJobSyncEnd(vm, asyncJob, disk);
717 718 719 720
            diskPriv->migrating = false;
        }
    }

721
    while ((rv = qemuMigrationDriveMirrorCancelled(vm, asyncJob,
722
                                                   check)) != 1) {
723 724 725 726 727 728 729
        if (check && !failed &&
            dconn && virConnectIsAlive(dconn) <= 0) {
            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                           _("Lost connection to destination host"));
            failed = true;
        }

730 731 732 733
        if (rv < 0) {
            failed = true;
            if (rv == -2)
                break;
734
        }
735

736 737 738 739 740
        if (failed && !err)
            err = virSaveLastError();

        if (virDomainObjWait(vm) < 0)
            goto cleanup;
741 742
    }

743 744 745
    ret = failed ? -1 : 0;

 cleanup:
746 747 748 749 750
    if (err) {
        virSetError(err);
        virFreeError(err);
    }
    return ret;
751 752 753
}


754 755 756 757 758 759
/**
 * qemuMigrationDriveMirror:
 * @driver: qemu driver
 * @vm: domain
 * @mig: migration cookie
 * @host: where are we migrating to
760
 * @speed: bandwidth limit in MiB/s
761 762 763 764
 * @migrate_flags: migrate monitor command flags
 *
 * Run drive-mirror to feed NBD server running on dst and wait
 * till the process switches into another phase where writes go
765 766 767
 * simultaneously to both source and destination. On success,
 * update @migrate_flags so we don't tell 'migrate' command
 * to do the very same operation. On failure, the caller is
768
 * expected to call qemuMigrationSrcCancelDriveMirror to stop all
769
 * running mirrors.
770 771 772 773 774
 *
 * Returns 0 on success (@migrate_flags updated),
 *        -1 otherwise.
 */
static int
775 776 777 778 779 780 781 782 783
qemuMigrationSrcDriveMirror(virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
                            qemuMigrationCookiePtr mig,
                            const char *host,
                            unsigned long speed,
                            unsigned int *migrate_flags,
                            size_t nmigrate_disks,
                            const char **migrate_disks,
                            virConnectPtr dconn)
784 785 786 787
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int ret = -1;
    int port;
788
    size_t i;
789 790
    char *diskAlias = NULL;
    char *nbd_dest = NULL;
791
    char *hoststr = NULL;
792
    unsigned long long mirror_speed = speed;
793
    unsigned int mirror_flags = VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT;
794
    int rv;
795
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
796 797

    VIR_DEBUG("Starting drive mirrors for domain %s", vm->def->name);
798

799 800 801 802 803 804 805 806
    if (mirror_speed > LLONG_MAX >> 20) {
        virReportError(VIR_ERR_OVERFLOW,
                       _("bandwidth must be less than %llu"),
                       LLONG_MAX >> 20);
        goto cleanup;
    }
    mirror_speed <<= 20;

807 808 809 810
    /* steal NBD port and thus prevent its propagation back to destination */
    port = mig->nbd->port;
    mig->nbd->port = 0;

811 812
    /* escape literal IPv6 address */
    if (strchr(host, ':')) {
813
        if (virAsprintf(&hoststr, "[%s]", host) < 0)
814
            goto cleanup;
815
    } else if (VIR_STRDUP(hoststr, host) < 0) {
816
        goto cleanup;
817 818
    }

819 820 821 822 823
    if (*migrate_flags & QEMU_MONITOR_MIGRATE_NON_SHARED_INC)
        mirror_flags |= VIR_DOMAIN_BLOCK_REBASE_SHALLOW;

    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
824
        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
825
        int mon_ret;
826

827
        /* check whether disk should be migrated */
828
        if (!qemuMigrationAnyCopyDisk(disk, nmigrate_disks, migrate_disks))
829 830
            continue;

831
        if (!(diskAlias = qemuAliasFromDisk(disk)) ||
832
            (virAsprintf(&nbd_dest, "nbd:%s:%d:exportname=%s",
833
                         hoststr, port, diskAlias) < 0))
834 835
            goto cleanup;

836
        if (qemuDomainObjEnterMonitorAsync(driver, vm,
837
                                           QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
838 839
            goto cleanup;

840
        qemuBlockJobSyncBegin(disk);
841
        /* Force "raw" format for NBD export */
842
        mon_ret = qemuMonitorDriveMirror(priv->mon, diskAlias, nbd_dest,
843
                                         "raw", mirror_speed, 0, 0, mirror_flags);
844 845
        VIR_FREE(diskAlias);
        VIR_FREE(nbd_dest);
846

847
        if (qemuDomainObjExitMonitor(driver, vm) < 0 || mon_ret < 0) {
848
            qemuBlockJobSyncEnd(vm, QEMU_ASYNC_JOB_MIGRATION_OUT, disk);
849 850
            goto cleanup;
        }
851
        diskPriv->migrating = true;
852

853
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
854 855 856
            VIR_WARN("Failed to save status on vm %s", vm->def->name);
            goto cleanup;
        }
857
    }
858

859
    while ((rv = qemuMigrationSrcDriveMirrorReady(vm,
860
                                                  QEMU_ASYNC_JOB_MIGRATION_OUT)) != 1) {
861 862
        if (rv < 0)
            goto cleanup;
863

864
        if (priv->job.abortJob) {
865
            priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
866 867 868 869
            virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
                           qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
                           _("canceled by client"));
            goto cleanup;
870
        }
871

872 873 874 875 876 877
        if (dconn && virConnectIsAlive(dconn) <= 0) {
            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                           _("Lost connection to destination host"));
            goto cleanup;
        }

878
        if (virDomainObjWait(vm) < 0)
879
            goto cleanup;
880 881
    }

882 883
    qemuMigrationSrcFetchMirrorStats(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
                                     priv->job.current);
884

885
    /* Okay, all disks are ready. Modify migrate_flags */
886 887 888 889
    *migrate_flags &= ~(QEMU_MONITOR_MIGRATE_NON_SHARED_DISK |
                        QEMU_MONITOR_MIGRATE_NON_SHARED_INC);
    ret = 0;

890
 cleanup:
891
    virObjectUnref(cfg);
892 893
    VIR_FREE(diskAlias);
    VIR_FREE(nbd_dest);
894
    VIR_FREE(hoststr);
895 896
    return ret;
}
897

898

899
/**
900
 * qemuMigrationSrcIsAllowedHostdev:
901 902 903 904 905 906
 * @def: domain definition
 *
 * Checks that @def does not contain any host devices unsupported accross
 * migrations. Returns true if the vm is allowed to migrate.
 */
static bool
907
qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def)
908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926
{
    size_t i;

    /* Migration with USB host devices is allowed, all other devices are
     * forbidden. */
    for (i = 0; i < def->nhostdevs; i++) {
        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
            hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                           _("domain has assigned non-USB host devices"));
            return false;
        }
    }

    return true;
}


927
/**
928
 * qemuMigrationSrcIsAllowed:
929 930 931 932 933 934 935 936 937 938 939 940
 * @driver: qemu driver struct
 * @vm: domain object
 * @remote: migration is remote
 * @flags: migration flags (see struct virDomainMigrateFlags)
 *
 * Validates that the configuration of @vm can be migrated in various
 * situations. If @remote is true, the migration happens to remote host. @flags
 * is used to check various special migration types according to the request.
 *
 * Returns true if migration is supported. Reports libvirt error and returns
 * false otherwise.
 */
941
bool
942 943 944 945
qemuMigrationSrcIsAllowed(virQEMUDriverPtr driver,
                          virDomainObjPtr vm,
                          bool remote,
                          unsigned int flags)
946
{
947
    int nsnapshots;
948
    int pauseReason;
949
    size_t i;
950

951 952 953 954 955
    /* perform these checks only when migrating to remote hosts */
    if (remote) {
        nsnapshots = virDomainSnapshotObjListNum(vm->snapshots, NULL, 0);
        if (nsnapshots < 0)
            return false;
956

957 958 959 960 961
        if (nsnapshots > 0) {
            virReportError(VIR_ERR_OPERATION_INVALID,
                           _("cannot migrate domain with %d snapshots"),
                           nsnapshots);
            return false;
962
        }
963

964
        /* cancel migration if disk I/O error is emitted while migrating */
965
        if (flags & VIR_MIGRATE_ABORT_ON_ERROR &&
966
            !(flags & VIR_MIGRATE_OFFLINE) &&
967 968
            virDomainObjGetState(vm, &pauseReason) == VIR_DOMAIN_PAUSED &&
            pauseReason == VIR_DOMAIN_PAUSED_IOERROR) {
E
Eric Blake 已提交
969
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
970
                           _("cannot migrate domain with I/O error"));
E
Eric Blake 已提交
971 972
            return false;
        }
973 974

    }
975

976 977 978 979 980 981 982
    /* following checks don't make sense for offline migration */
    if (!(flags & VIR_MIGRATE_OFFLINE)) {
        if (qemuProcessAutoDestroyActive(driver, vm)) {
            virReportError(VIR_ERR_OPERATION_INVALID,
                           "%s", _("domain is marked for auto destroy"));
            return false;
        }
983

984

985 986
        if (qemuDomainHasBlockjob(vm, false)) {
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
987
                           _("domain has active block job"));
988 989 990
            return false;
        }

991
        if (!qemuMigrationSrcIsAllowedHostdev(vm->def))
992 993
            return false;

994
        if (vm->def->cpu) {
995 996 997
            /* QEMU blocks migration and save with invariant TSC enabled
             * unless TSC frequency is explicitly set.
             */
998 999
            if (virCPUCheckFeature(vm->def->os.arch, vm->def->cpu,
                                   "invtsc") == 1) {
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
                bool block = true;

                for (i = 0; i < vm->def->clock.ntimers; i++) {
                    virDomainTimerDefPtr timer = vm->def->clock.timers[i];

                    if (timer->name == VIR_DOMAIN_TIMER_NAME_TSC &&
                        timer->frequency > 0) {
                        block = false;
                        break;
                    }
                }

                if (block) {
                    virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                                   _("domain has 'invtsc' CPU feature but "
                                     "TSC frequency is not specified"));
                    return false;
                }
1018
            }
J
Ján Tomko 已提交
1019 1020
        }

1021 1022 1023
        /* Verify that memory device config can be transferred reliably */
        for (i = 0; i < vm->def->nmems; i++) {
            virDomainMemoryDefPtr mem = vm->def->mems[i];
1024

1025 1026 1027 1028 1029
            if (mem->model == VIR_DOMAIN_MEMORY_MODEL_DIMM &&
                mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                               _("domain's dimm info lacks slot ID "
                                 "or base address"));
1030

1031 1032
                return false;
            }
1033
        }
1034 1035 1036 1037 1038 1039

        if (vm->def->nshmems) {
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                           _("migration with shmem device is not supported"));
            return false;
        }
1040 1041
    }

1042 1043 1044
    return true;
}

1045
static bool
1046 1047 1048 1049
qemuMigrationSrcIsSafe(virDomainDefPtr def,
                       size_t nmigrate_disks,
                       const char **migrate_disks,
                       unsigned int flags)
1050

1051
{
1052 1053
    bool storagemigration = flags & (VIR_MIGRATE_NON_SHARED_DISK |
                                     VIR_MIGRATE_NON_SHARED_INC);
1054
    size_t i;
1055
    int rc;
1056

1057
    for (i = 0; i < def->ndisks; i++) {
1058
        virDomainDiskDefPtr disk = def->disks[i];
1059
        const char *src = virDomainDiskGetSource(disk);
1060

1061 1062
        /* Disks without any source (i.e. floppies and CD-ROMs)
         * OR readonly are safe. */
1063
        if (virStorageSourceIsEmpty(disk->src) ||
1064
            disk->src->readonly)
1065
            continue;
1066

1067
        /* Disks which are migrated by qemu are safe too. */
1068
        if (storagemigration &&
1069
            qemuMigrationAnyCopyDisk(disk, nmigrate_disks, migrate_disks))
1070
            continue;
1071

1072
        /* However, disks on local FS (e.g. ext4) are not safe. */
1073
        if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_FILE) {
1074
            if ((rc = virFileIsSharedFS(src)) < 0) {
1075
                return false;
1076 1077 1078 1079 1080
            } else if (rc == 0) {
                virReportError(VIR_ERR_MIGRATE_UNSAFE, "%s",
                               _("Migration without shared storage is unsafe"));
                return false;
            }
1081 1082 1083 1084 1085 1086 1087
            if ((rc = virStorageFileIsClusterFS(src)) < 0)
                return false;
            else if (rc == 1)
                continue;
        } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK &&
                   disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
            continue;
1088
        }
1089

1090 1091 1092 1093 1094 1095 1096
        /* Our code elsewhere guarantees shared disks are either readonly (in
         * which case cache mode doesn't matter) or used with cache=none or used with cache=directsync */
        if (disk->src->shared ||
            disk->cachemode == VIR_DOMAIN_DISK_CACHE_DISABLE ||
            disk->cachemode == VIR_DOMAIN_DISK_CACHE_DIRECTSYNC)
            continue;

1097 1098
        virReportError(VIR_ERR_MIGRATE_UNSAFE, "%s",
                       _("Migration may lead to data corruption if disks"
1099
                         " use cache != none or cache != directsync"));
1100
        return false;
1101 1102 1103 1104 1105
    }

    return true;
}

1106
/** qemuMigrationSrcSetOffline
1107 1108 1109
 * Pause domain for non-live migration.
 */
int
1110 1111
qemuMigrationSrcSetOffline(virQEMUDriverPtr driver,
                           virDomainObjPtr vm)
1112 1113
{
    int ret;
1114
    VIR_DEBUG("driver=%p vm=%p", driver, vm);
1115 1116
    ret = qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_MIGRATION,
                              QEMU_ASYNC_JOB_MIGRATION_OUT);
1117
    if (ret == 0) {
1118
        virObjectEventPtr event;
1119

1120
        event = virDomainEventLifecycleNewFromObj(vm,
1121 1122
                                         VIR_DOMAIN_EVENT_SUSPENDED,
                                         VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED);
1123
        qemuDomainEventQueue(driver, event);
1124 1125 1126 1127 1128
    }

    return ret;
}

1129 1130

void
1131 1132
qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver,
                               virDomainObjPtr vm)
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
{
    virDomainState state;
    int reason;

    state = virDomainObjGetState(vm, &reason);

    if (state != VIR_DOMAIN_PAUSED &&
        state != VIR_DOMAIN_RUNNING)
        return;

    if (state == VIR_DOMAIN_PAUSED &&
        reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED)
        return;

    VIR_WARN("Migration of domain %s failed during post-copy; "
             "leaving the domain paused", vm->def->name);

    if (state == VIR_DOMAIN_RUNNING) {
        virObjectEventPtr event;

        if (qemuProcessStopCPUs(driver, vm,
                                VIR_DOMAIN_PAUSED_POSTCOPY_FAILED,
                                QEMU_ASYNC_JOB_MIGRATION_IN) < 0) {
            VIR_WARN("Unable to pause guest CPUs for %s", vm->def->name);
            return;
        }

        event = virDomainEventLifecycleNewFromObj(vm,
                                VIR_DOMAIN_EVENT_SUSPENDED,
                                VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED);
        qemuDomainEventQueue(driver, event);
    } else {
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
                             VIR_DOMAIN_PAUSED_POSTCOPY_FAILED);
    }
}


1171
static int
1172
qemuMigrationSrcWaitForSpice(virDomainObjPtr vm)
1173 1174 1175
{
    qemuDomainObjPrivatePtr priv = vm->privateData;

1176 1177
    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION) ||
        !priv->job.spiceMigration)
1178 1179
        return 0;

1180
    VIR_DEBUG("Waiting for SPICE to finish migration");
1181 1182
    while (!priv->job.spiceMigrated && !priv->job.abortJob) {
        if (virDomainObjWait(vm) < 0)
1183 1184 1185 1186
            return -1;
    }
    return 0;
}
1187

1188 1189 1190 1191

static void
qemuMigrationUpdateJobType(qemuDomainJobInfoPtr jobInfo)
{
1192
    switch ((qemuMonitorMigrationStatus) jobInfo->stats.mig.status) {
1193 1194 1195 1196
    case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY:
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_POSTCOPY;
        break;

1197
    case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
1198
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED;
1199 1200 1201
        break;

    case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
1202
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_NONE;
1203 1204 1205
        break;

    case QEMU_MONITOR_MIGRATION_STATUS_ERROR:
1206
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
1207 1208 1209
        break;

    case QEMU_MONITOR_MIGRATION_STATUS_CANCELLED:
1210
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
1211 1212
        break;

1213 1214 1215 1216 1217 1218 1219 1220
    case QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER:
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_PAUSED;
        break;

    case QEMU_MONITOR_MIGRATION_STATUS_DEVICE:
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_MIGRATING;
        break;

1221 1222 1223
    case QEMU_MONITOR_MIGRATION_STATUS_SETUP:
    case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
    case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING:
1224
    case QEMU_MONITOR_MIGRATION_STATUS_LAST:
1225 1226 1227 1228 1229 1230
        break;
    }
}


int
1231 1232 1233 1234 1235
qemuMigrationAnyFetchStats(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
                           qemuDomainAsyncJob asyncJob,
                           qemuDomainJobInfoPtr jobInfo,
                           char **error)
1236 1237
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
1238
    qemuMonitorMigrationStats stats;
1239 1240 1241 1242 1243
    int rv;

    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        return -1;

1244
    rv = qemuMonitorGetMigrationStats(priv->mon, &stats, error);
1245 1246 1247 1248

    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0)
        return -1;

1249
    jobInfo->stats.mig = stats;
1250 1251

    return 0;
1252 1253 1254
}


1255 1256 1257 1258 1259 1260 1261
static const char *
qemuMigrationJobName(virDomainObjPtr vm)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;

    switch (priv->job.asyncJob) {
    case QEMU_ASYNC_JOB_MIGRATION_OUT:
1262
        return _("migration out job");
1263 1264 1265 1266
    case QEMU_ASYNC_JOB_SAVE:
        return _("domain save job");
    case QEMU_ASYNC_JOB_DUMP:
        return _("domain core dump job");
1267 1268 1269 1270 1271 1272 1273 1274 1275
    case QEMU_ASYNC_JOB_NONE:
        return _("undefined");
    case QEMU_ASYNC_JOB_MIGRATION_IN:
        return _("migration in job");
    case QEMU_ASYNC_JOB_SNAPSHOT:
        return _("snapshot job");
    case QEMU_ASYNC_JOB_START:
        return _("start job");
    case QEMU_ASYNC_JOB_LAST:
1276 1277 1278 1279 1280 1281
    default:
        return _("job");
    }
}


1282
static int
1283
qemuMigrationJobCheckStatus(virQEMUDriverPtr driver,
1284
                            virDomainObjPtr vm,
1285
                            qemuDomainAsyncJob asyncJob)
1286 1287 1288
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    qemuDomainJobInfoPtr jobInfo = priv->job.current;
1289
    char *error = NULL;
1290
    bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
1291
    int ret = -1;
1292

1293
    if (!events ||
1294
        jobInfo->stats.mig.status == QEMU_MONITOR_MIGRATION_STATUS_ERROR) {
1295
        if (qemuMigrationAnyFetchStats(driver, vm, asyncJob, jobInfo, &error) < 0)
1296 1297
            return -1;
    }
1298

1299 1300
    qemuMigrationUpdateJobType(jobInfo);

1301 1302
    switch (jobInfo->status) {
    case QEMU_DOMAIN_JOB_STATUS_NONE:
1303 1304
        virReportError(VIR_ERR_OPERATION_FAILED, _("%s: %s"),
                       qemuMigrationJobName(vm), _("is not active"));
1305
        goto cleanup;
1306

1307
    case QEMU_DOMAIN_JOB_STATUS_FAILED:
1308
        virReportError(VIR_ERR_OPERATION_FAILED, _("%s: %s"),
1309 1310 1311
                       qemuMigrationJobName(vm),
                       error ? error : _("unexpectedly failed"));
        goto cleanup;
1312

1313
    case QEMU_DOMAIN_JOB_STATUS_CANCELED:
1314 1315
        virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
                       qemuMigrationJobName(vm), _("canceled by client"));
1316
        goto cleanup;
1317

1318 1319
    case QEMU_DOMAIN_JOB_STATUS_COMPLETED:
    case QEMU_DOMAIN_JOB_STATUS_ACTIVE:
1320
    case QEMU_DOMAIN_JOB_STATUS_MIGRATING:
1321
    case QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED:
1322
    case QEMU_DOMAIN_JOB_STATUS_POSTCOPY:
1323
    case QEMU_DOMAIN_JOB_STATUS_PAUSED:
1324 1325
        break;
    }
1326 1327 1328 1329 1330 1331

    ret = 0;

 cleanup:
    VIR_FREE(error);
    return ret;
1332 1333 1334
}


1335 1336
enum qemuMigrationCompletedFlags {
    QEMU_MIGRATION_COMPLETED_ABORT_ON_ERROR = (1 << 0),
1337
    /* This flag should only be set when run on src host */
1338
    QEMU_MIGRATION_COMPLETED_CHECK_STORAGE  = (1 << 1),
1339
    QEMU_MIGRATION_COMPLETED_POSTCOPY       = (1 << 2),
1340
    QEMU_MIGRATION_COMPLETED_PRE_SWITCHOVER = (1 << 3),
1341 1342
};

1343

1344 1345 1346 1347 1348 1349 1350
/**
 * Returns 1 if migration completed successfully,
 *         0 if the domain is still being migrated,
 *         -1 migration failed,
 *         -2 something else failed, we need to cancel migration.
 */
static int
1351 1352 1353 1354 1355
qemuMigrationAnyCompleted(virQEMUDriverPtr driver,
                          virDomainObjPtr vm,
                          qemuDomainAsyncJob asyncJob,
                          virConnectPtr dconn,
                          unsigned int flags)
1356 1357 1358 1359 1360
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    qemuDomainJobInfoPtr jobInfo = priv->job.current;
    int pauseReason;

1361
    if (qemuMigrationJobCheckStatus(driver, vm, asyncJob) < 0)
1362 1363
        goto error;

1364
    /* This flag should only be set when run on src host */
1365
    if (flags & QEMU_MIGRATION_COMPLETED_CHECK_STORAGE &&
1366
        qemuMigrationSrcDriveMirrorReady(vm, asyncJob) < 0)
1367 1368
        goto error;

1369
    if (flags & QEMU_MIGRATION_COMPLETED_ABORT_ON_ERROR &&
1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
        virDomainObjGetState(vm, &pauseReason) == VIR_DOMAIN_PAUSED &&
        pauseReason == VIR_DOMAIN_PAUSED_IOERROR) {
        virReportError(VIR_ERR_OPERATION_FAILED, _("%s: %s"),
                       qemuMigrationJobName(vm), _("failed due to I/O error"));
        goto error;
    }

    if (dconn && virConnectIsAlive(dconn) <= 0) {
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                       _("Lost connection to destination host"));
        goto error;
    }

1383 1384 1385 1386 1387 1388 1389 1390 1391 1392
    /* Migration was paused before serializing device state, let's return to
     * the caller so that it can finish all block jobs, resume migration, and
     * wait again for the real end of the migration.
     */
    if (flags & QEMU_MIGRATION_COMPLETED_PRE_SWITCHOVER &&
        jobInfo->status == QEMU_DOMAIN_JOB_STATUS_PAUSED) {
        VIR_DEBUG("Migration paused before switchover");
        return 1;
    }

1393 1394 1395 1396 1397
    /* In case of postcopy the source considers migration completed at the
     * moment it switched from active to postcopy-active state. The destination
     * will continue waiting until the migrate state changes to completed.
     */
    if (flags & QEMU_MIGRATION_COMPLETED_POSTCOPY &&
1398
        jobInfo->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY) {
1399 1400 1401 1402
        VIR_DEBUG("Migration switched to post-copy");
        return 1;
    }

1403
    if (jobInfo->status == QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED)
1404 1405 1406 1407 1408
        return 1;
    else
        return 0;

 error:
1409 1410 1411
    switch (jobInfo->status) {
    case QEMU_DOMAIN_JOB_STATUS_MIGRATING:
    case QEMU_DOMAIN_JOB_STATUS_POSTCOPY:
1412
    case QEMU_DOMAIN_JOB_STATUS_PAUSED:
1413
        /* The migration was aborted by us rather than QEMU itself. */
1414
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
1415
        return -2;
1416 1417 1418

    case QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED:
        /* Something failed after QEMU already finished the migration. */
1419
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
1420
        return -1;
1421 1422 1423 1424

    case QEMU_DOMAIN_JOB_STATUS_FAILED:
    case QEMU_DOMAIN_JOB_STATUS_CANCELED:
        /* QEMU aborted the migration. */
1425
        return -1;
1426 1427 1428 1429 1430 1431

    case QEMU_DOMAIN_JOB_STATUS_ACTIVE:
    case QEMU_DOMAIN_JOB_STATUS_COMPLETED:
    case QEMU_DOMAIN_JOB_STATUS_NONE:
        /* Impossible. */
        break;
1432
    }
1433 1434

    return -1;
1435 1436 1437
}


1438 1439 1440
/* Returns 0 on success, -2 when migration needs to be cancelled, or -1 when
 * QEMU reports failed migration.
 */
1441
static int
1442 1443 1444 1445 1446
qemuMigrationSrcWaitForCompletion(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
                                  qemuDomainAsyncJob asyncJob,
                                  virConnectPtr dconn,
                                  unsigned int flags)
1447
{
1448
    qemuDomainObjPrivatePtr priv = vm->privateData;
J
Jiri Denemark 已提交
1449
    qemuDomainJobInfoPtr jobInfo = priv->job.current;
1450
    bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
1451
    int rv;
1452

1453 1454
    jobInfo->status = QEMU_DOMAIN_JOB_STATUS_MIGRATING;

1455 1456
    while ((rv = qemuMigrationAnyCompleted(driver, vm, asyncJob,
                                           dconn, flags)) != 1) {
1457 1458
        if (rv < 0)
            return rv;
1459

1460 1461
        if (events) {
            if (virDomainObjWait(vm) < 0) {
1462
                jobInfo->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
1463 1464 1465 1466 1467 1468 1469 1470 1471 1472
                return -2;
            }
        } else {
            /* Poll every 50ms for progress & to allow cancellation */
            struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };

            virObjectUnlock(vm);
            nanosleep(&ts, NULL);
            virObjectLock(vm);
        }
1473 1474
    }

1475
    if (events)
1476
        ignore_value(qemuMigrationAnyFetchStats(driver, vm, asyncJob, jobInfo, NULL));
1477

1478
    qemuDomainJobInfoUpdateTime(jobInfo);
1479 1480
    qemuDomainJobInfoUpdateDowntime(jobInfo);
    VIR_FREE(priv->job.completed);
1481
    if (VIR_ALLOC(priv->job.completed) == 0) {
1482
        *priv->job.completed = *jobInfo;
1483 1484
        priv->job.completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
    }
1485

1486 1487 1488 1489
    if (asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT &&
        jobInfo->status == QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED)
        jobInfo->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;

1490
    return 0;
1491 1492 1493
}


1494
static int
1495 1496 1497 1498
qemuMigrationDstWaitForCompletion(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
                                  qemuDomainAsyncJob asyncJob,
                                  bool postcopy)
1499 1500
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
1501
    unsigned int flags = 0;
1502 1503 1504 1505 1506 1507 1508
    int rv;

    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT))
        return 0;

    VIR_DEBUG("Waiting for incoming migration to complete");

1509 1510 1511
    if (postcopy)
        flags = QEMU_MIGRATION_COMPLETED_POSTCOPY;

1512 1513
    while ((rv = qemuMigrationAnyCompleted(driver, vm, asyncJob,
                                           NULL, flags)) != 1) {
1514 1515 1516 1517 1518 1519 1520 1521
        if (rv < 0 || virDomainObjWait(vm) < 0)
            return -1;
    }

    return 0;
}


1522
static int
1523 1524 1525 1526
qemuMigrationSrcGraphicsRelocate(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
                                 qemuMigrationCookiePtr cookie,
                                 const char *graphicsuri)
1527 1528
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
1529 1530
    int ret = -1;
    const char *listenAddress = NULL;
1531
    virSocketAddr addr;
1532 1533 1534 1535 1536
    virURIPtr uri = NULL;
    int type = -1;
    int port = -1;
    int tlsPort = -1;
    const char *tlsSubject = NULL;
1537

1538
    if (!cookie || (!cookie->graphics && !graphicsuri))
1539 1540
        return 0;

1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
    if (graphicsuri && !(uri = virURIParse(graphicsuri)))
        goto cleanup;

    if (cookie->graphics) {
        type = cookie->graphics->type;

        listenAddress = cookie->graphics->listen;

        if (!listenAddress ||
            (virSocketAddrParse(&addr, listenAddress, AF_UNSPEC) > 0 &&
             virSocketAddrIsWildcard(&addr)))
            listenAddress = cookie->remoteHostname;

        port = cookie->graphics->port;
        tlsPort = cookie->graphics->tlsPort;
        tlsSubject = cookie->graphics->tlsSubject;
    }

    if (uri) {
1560
        size_t i;
1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587

        if ((type = virDomainGraphicsTypeFromString(uri->scheme)) < 0) {
            virReportError(VIR_ERR_INVALID_ARG,
                           _("unknown graphics type %s"), uri->scheme);
            goto cleanup;
        }

        if (uri->server)
            listenAddress = uri->server;
        if (uri->port > 0)
            port = uri->port;

        for (i = 0; i < uri->paramsCount; i++) {
            virURIParamPtr param = uri->params + i;

            if (STRCASEEQ(param->name, "tlsPort")) {
                if (virStrToLong_i(param->value, NULL, 10, &tlsPort) < 0) {
                    virReportError(VIR_ERR_INVALID_ARG,
                                   _("invalid tlsPort number: %s"),
                                   param->value);
                    goto cleanup;
                }
            } else if (STRCASEEQ(param->name, "tlsSubject")) {
                tlsSubject = param->value;
            }
        }
    }
1588 1589 1590 1591

    /* QEMU doesn't support VNC relocation yet, so
     * skip it to avoid generating an error
     */
1592 1593 1594 1595
    if (type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
        ret = 0;
        goto cleanup;
    }
1596

1597 1598 1599 1600 1601 1602 1603 1604 1605
    /* Older libvirt sends port == 0 for listen type='none' graphics. It's
     * safe to ignore such requests since relocation to unknown port does
     * not make sense in general.
     */
    if (port <= 0 && tlsPort <= 0) {
        ret = 0;
        goto cleanup;
    }

1606 1607 1608 1609
    if (qemuDomainObjEnterMonitorAsync(driver, vm,
                                       QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
        ret = qemuMonitorGraphicsRelocate(priv->mon, type, listenAddress,
                                          port, tlsPort, tlsSubject);
1610
        priv->job.spiceMigration = !ret;
1611 1612
        if (qemuDomainObjExitMonitor(driver, vm) < 0)
            ret = -1;
1613
    }
1614

1615
 cleanup:
1616
    virURIFree(uri);
1617 1618 1619 1620
    return ret;
}


1621
static int
1622 1623 1624
qemuMigrationDstOPDRelocate(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
                            virDomainObjPtr vm,
                            qemuMigrationCookiePtr cookie)
1625
{
1626 1627
    virDomainNetDefPtr netptr;
    int ret = -1;
1628
    size_t i;
1629 1630 1631 1632 1633 1634 1635 1636

    for (i = 0; i < cookie->network->nnets; i++) {
        netptr = vm->def->nets[i];

        switch (cookie->network->net[i].vporttype) {
        case VIR_NETDEV_VPORT_PROFILE_NONE:
        case VIR_NETDEV_VPORT_PROFILE_8021QBG:
        case VIR_NETDEV_VPORT_PROFILE_8021QBH:
1637
           break;
1638
        case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH:
1639 1640
            if (virNetDevOpenvswitchSetMigrateData(cookie->network->net[i].portdata,
                                                   netptr->ifname) != 0) {
J
Jiri Denemark 已提交
1641 1642 1643
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Unable to run command to set OVS port data for "
                                 "interface %s"), netptr->ifname);
1644 1645 1646
                goto cleanup;
            }
            break;
1647 1648 1649 1650 1651
        default:
            break;
        }
    }

1652
    ret = 0;
1653
 cleanup:
1654 1655 1656 1657
    return ret;
}


1658
int
1659 1660
qemuMigrationDstCheckProtocol(virQEMUCapsPtr qemuCaps,
                              const char *migrateFrom)
1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683
{
    if (STRPREFIX(migrateFrom, "rdma")) {
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_RDMA)) {
            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                           _("incoming RDMA migration is not supported "
                             "with this QEMU binary"));
            return -1;
        }
    } else if (!STRPREFIX(migrateFrom, "tcp") &&
               !STRPREFIX(migrateFrom, "exec") &&
               !STRPREFIX(migrateFrom, "fd") &&
               !STRPREFIX(migrateFrom, "unix") &&
               STRNEQ(migrateFrom, "stdio")) {
        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                       _("unknown migration protocol"));
        return -1;
    }

    return 0;
}


char *
1684 1685
qemuMigrationDstGetURI(const char *migrateFrom,
                       int migrateFd)
1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697
{
    char *uri = NULL;

    if (STREQ(migrateFrom, "stdio"))
        ignore_value(virAsprintf(&uri, "fd:%d", migrateFd));
    else
        ignore_value(VIR_STRDUP(uri, migrateFrom));

    return uri;
}


1698
int
1699 1700 1701 1702
qemuMigrationDstRun(virQEMUDriverPtr driver,
                    virDomainObjPtr vm,
                    const char *uri,
                    qemuDomainAsyncJob asyncJob)
1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int ret = -1;
    int rv;

    VIR_DEBUG("Setting up incoming migration with URI %s", uri);

    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        return -1;

    rv = qemuMonitorMigrateIncoming(priv->mon, uri);

    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0)
        goto cleanup;

    if (asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN) {
1719
        /* qemuMigrationDstWaitForCompletion is called from the Finish phase */
1720 1721 1722 1723
        ret = 0;
        goto cleanup;
    }

1724
    if (qemuMigrationDstWaitForCompletion(driver, vm, asyncJob, false) < 0)
1725 1726 1727 1728 1729 1730 1731 1732 1733
        goto cleanup;

    ret = 0;

 cleanup:
    return ret;
}


1734 1735 1736 1737 1738 1739
/* This is called for outgoing non-p2p migrations when a connection to the
 * client which initiated the migration was closed but we were waiting for it
 * to follow up with the next phase, that is, in between
 * qemuDomainMigrateBegin3 and qemuDomainMigratePerform3 or
 * qemuDomainMigratePerform3 and qemuDomainMigrateConfirm3.
 */
1740
static void
1741 1742 1743
qemuMigrationSrcCleanup(virDomainObjPtr vm,
                        virConnectPtr conn,
                        void *opaque)
1744
{
1745
    virQEMUDriverPtr driver = opaque;
1746 1747 1748 1749 1750 1751 1752 1753 1754
    qemuDomainObjPrivatePtr priv = vm->privateData;

    VIR_DEBUG("vm=%s, conn=%p, asyncJob=%s, phase=%s",
              vm->def->name, conn,
              qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
              qemuDomainAsyncJobPhaseToString(priv->job.asyncJob,
                                              priv->job.phase));

    if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT))
1755
        return;
1756 1757 1758 1759 1760

    VIR_DEBUG("The connection which started outgoing migration of domain %s"
              " was closed; canceling the migration",
              vm->def->name);

1761
    switch ((qemuMigrationJobPhase) priv->job.phase) {
1762 1763 1764 1765 1766 1767 1768 1769 1770
    case QEMU_MIGRATION_PHASE_BEGIN3:
        /* just forget we were about to migrate */
        qemuDomainObjDiscardAsyncJob(driver, vm);
        break;

    case QEMU_MIGRATION_PHASE_PERFORM3_DONE:
        VIR_WARN("Migration of domain %s finished but we don't know if the"
                 " domain was successfully started on destination or not",
                 vm->def->name);
1771
        qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
1772
                                 priv->job.migParams, priv->job.apiFlags);
1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794
        /* clear the job and let higher levels decide what to do */
        qemuDomainObjDiscardAsyncJob(driver, vm);
        break;

    case QEMU_MIGRATION_PHASE_PERFORM3:
        /* cannot be seen without an active migration API; unreachable */
    case QEMU_MIGRATION_PHASE_CONFIRM3:
    case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED:
        /* all done; unreachable */
    case QEMU_MIGRATION_PHASE_PREPARE:
    case QEMU_MIGRATION_PHASE_FINISH2:
    case QEMU_MIGRATION_PHASE_FINISH3:
        /* incoming migration; unreachable */
    case QEMU_MIGRATION_PHASE_PERFORM2:
        /* single phase outgoing migration; unreachable */
    case QEMU_MIGRATION_PHASE_NONE:
    case QEMU_MIGRATION_PHASE_LAST:
        /* unreachable */
        ;
    }
}

1795

1796
/* The caller is supposed to lock the vm and start a migration job. */
1797
static char *
1798 1799 1800 1801 1802 1803 1804 1805 1806
qemuMigrationSrcBeginPhase(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
                           const char *xmlin,
                           const char *dname,
                           char **cookieout,
                           int *cookieoutlen,
                           size_t nmigrate_disks,
                           const char **migrate_disks,
                           unsigned long flags)
1807 1808 1809
{
    char *rv = NULL;
    qemuMigrationCookiePtr mig = NULL;
1810
    virDomainDefPtr def = NULL;
1811
    qemuDomainObjPrivatePtr priv = vm->privateData;
1812
    virCapsPtr caps = NULL;
1813
    unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_LOCKSTATE;
1814

1815
    VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s,"
1816
              " cookieout=%p, cookieoutlen=%p,"
1817
              " nmigrate_disks=%zu, migrate_disks=%p, flags=0x%lx",
1818
              driver, vm, NULLSTR(xmlin), NULLSTR(dname),
1819 1820
              cookieout, cookieoutlen, nmigrate_disks,
              migrate_disks, flags);
1821

1822 1823 1824
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto cleanup;

1825 1826 1827 1828 1829 1830
    /* Only set the phase if we are inside QEMU_ASYNC_JOB_MIGRATION_OUT.
     * Otherwise we will start the async job later in the perform phase losing
     * change protection.
     */
    if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT)
        qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_BEGIN3);
1831

1832
    if (!qemuMigrationSrcIsAllowed(driver, vm, true, flags))
1833 1834
        goto cleanup;

1835
    if (!(flags & (VIR_MIGRATE_UNSAFE | VIR_MIGRATE_OFFLINE)) &&
1836
        !qemuMigrationSrcIsSafe(vm->def, nmigrate_disks, migrate_disks, flags))
1837 1838
        goto cleanup;

1839 1840 1841 1842 1843 1844 1845 1846 1847
    if (flags & VIR_MIGRATE_POSTCOPY &&
        (!(flags & VIR_MIGRATE_LIVE) ||
         flags & VIR_MIGRATE_PAUSED)) {
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("post-copy migration is not supported with non-live "
                         "or paused migration"));
        goto cleanup;
    }

1848 1849 1850 1851 1852 1853
    if (flags & VIR_MIGRATE_POSTCOPY && flags & VIR_MIGRATE_TUNNELLED) {
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("post-copy is not supported with tunnelled migration"));
        goto cleanup;
    }

1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896
    if (flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)) {
        bool has_drive_mirror =  virQEMUCapsGet(priv->qemuCaps,
                                                QEMU_CAPS_DRIVE_MIRROR);

        if (nmigrate_disks) {
            if (has_drive_mirror) {
                size_t i, j;
                /* Check user requested only known disk targets. */
                for (i = 0; i < nmigrate_disks; i++) {
                    for (j = 0; j < vm->def->ndisks; j++) {
                        if (STREQ(vm->def->disks[j]->dst, migrate_disks[i]))
                            break;
                    }

                    if (j == vm->def->ndisks) {
                        virReportError(VIR_ERR_INVALID_ARG,
                                       _("disk target %s not found"),
                                       migrate_disks[i]);
                        goto cleanup;
                    }
                }

                if (flags & VIR_MIGRATE_TUNNELLED) {
                    virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                                   _("Selecting disks to migrate is not "
                                     "implemented for tunnelled migration"));
                    goto cleanup;
                }
            } else {
                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                               _("qemu does not support drive-mirror command"));
                goto cleanup;
            }
        }

        if (has_drive_mirror) {
            /* TODO support NBD for TUNNELLED migration */
            if (flags & VIR_MIGRATE_TUNNELLED) {
                VIR_WARN("NBD in tunnelled migration is currently not supported");
            } else {
                cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
                priv->nbdPort = 0;
            }
1897 1898 1899
        }
    }

1900
    if (virDomainDefHasMemoryHotplug(vm->def) ||
1901
        ((flags & VIR_MIGRATE_PERSIST_DEST) &&
1902
         vm->newDef && virDomainDefHasMemoryHotplug(vm->newDef)))
1903 1904
        cookieFlags |= QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG;

1905 1906 1907 1908 1909
    if (!qemuDomainVcpuHotplugIsInOrder(vm->def) ||
        ((flags & VIR_MIGRATE_PERSIST_DEST) &&
         vm->newDef && !qemuDomainVcpuHotplugIsInOrder(vm->newDef)))
        cookieFlags |= QEMU_MIGRATION_COOKIE_CPU_HOTPLUG;

1910 1911 1912
    if (priv->origCPU)
        cookieFlags |= QEMU_MIGRATION_COOKIE_CPU;

1913 1914
    cookieFlags |= QEMU_MIGRATION_COOKIE_ALLOW_REBOOT;

1915 1916 1917
    if (!(flags & VIR_MIGRATE_OFFLINE))
        cookieFlags |= QEMU_MIGRATION_COOKIE_CAPS;

1918
    if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
1919 1920 1921
        goto cleanup;

    if (qemuMigrationBakeCookie(mig, driver, vm,
1922
                                QEMU_MIGRATION_SOURCE,
1923
                                cookieout, cookieoutlen,
1924
                                cookieFlags) < 0)
1925 1926
        goto cleanup;

L
liguang 已提交
1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948
    if (flags & VIR_MIGRATE_OFFLINE) {
        if (flags & (VIR_MIGRATE_NON_SHARED_DISK |
                     VIR_MIGRATE_NON_SHARED_INC)) {
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                           _("offline migration cannot handle "
                             "non-shared storage"));
            goto cleanup;
        }
        if (!(flags & VIR_MIGRATE_PERSIST_DEST)) {
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                           _("offline migration must be specified with "
                             "the persistent flag set"));
            goto cleanup;
        }
        if (flags & VIR_MIGRATE_TUNNELLED) {
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                           _("tunnelled offline migration does not "
                             "make sense"));
            goto cleanup;
        }
    }

1949
    if (xmlin) {
1950
        if (!(def = virDomainDefParseString(xmlin, caps, driver->xmlopt, priv->qemuCaps,
1951 1952
                                            VIR_DOMAIN_DEF_PARSE_INACTIVE |
                                            VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
1953 1954
            goto cleanup;

1955
        if (!qemuDomainCheckABIStability(driver, vm, def))
1956 1957
            goto cleanup;

1958
        rv = qemuDomainDefFormatLive(driver, def, NULL, false, true);
1959
    } else {
1960 1961
        rv = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU,
                                     false, true);
1962
    }
1963

1964
 cleanup:
1965
    qemuMigrationCookieFree(mig);
1966
    virObjectUnref(caps);
1967
    virDomainDefFree(def);
1968 1969 1970
    return rv;
}

1971
char *
1972 1973 1974 1975 1976 1977 1978 1979 1980
qemuMigrationSrcBegin(virConnectPtr conn,
                      virDomainObjPtr vm,
                      const char *xmlin,
                      const char *dname,
                      char **cookieout,
                      int *cookieoutlen,
                      size_t nmigrate_disks,
                      const char **migrate_disks,
                      unsigned long flags)
1981 1982 1983
{
    virQEMUDriverPtr driver = conn->privateData;
    char *xml = NULL;
1984
    qemuDomainAsyncJob asyncJob;
1985 1986

    if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
1987 1988
        if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
                                  flags) < 0)
1989 1990 1991 1992 1993 1994 1995 1996
            goto cleanup;
        asyncJob = QEMU_ASYNC_JOB_MIGRATION_OUT;
    } else {
        if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
            goto cleanup;
        asyncJob = QEMU_ASYNC_JOB_NONE;
    }

1997
    qemuMigrationSrcStoreDomainState(vm);
1998

1999 2000 2001 2002 2003 2004 2005 2006 2007 2008
    if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       "%s", _("domain is not running"));
        goto endjob;
    }

    /* Check if there is any ejected media.
     * We don't want to require them on the destination.
     */
    if (!(flags & VIR_MIGRATE_OFFLINE) &&
2009
        qemuProcessRefreshDisks(driver, vm, asyncJob) < 0)
2010 2011
        goto endjob;

2012 2013 2014
    if (!(xml = qemuMigrationSrcBeginPhase(driver, vm, xmlin, dname,
                                           cookieout, cookieoutlen,
                                           nmigrate_disks, migrate_disks, flags)))
2015 2016 2017 2018 2019 2020 2021
        goto endjob;

    if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
        /* We keep the job active across API calls until the confirm() call.
         * This prevents any other APIs being invoked while migration is taking
         * place.
         */
2022
        if (virCloseCallbacksSet(driver->closeCallbacks, vm, conn,
2023
                                 qemuMigrationSrcCleanup) < 0) {
2024
            VIR_FREE(xml);
2025
            goto endjob;
2026
        }
2027
        qemuMigrationJobContinue(vm);
2028 2029 2030 2031
    } else {
        goto endjob;
    }

2032
 cleanup:
M
Michal Privoznik 已提交
2033
    virDomainObjEndAPI(&vm);
2034 2035
    return xml;

2036
 endjob:
2037 2038 2039 2040
    if (flags & VIR_MIGRATE_CHANGE_PROTECTION)
        qemuMigrationJobFinish(driver, vm);
    else
        qemuDomainObjEndJob(driver, vm);
2041 2042 2043
    goto cleanup;
}

2044

2045 2046
/* Prepare is the first step, and it runs on the destination host.
 */
2047

2048
static void
2049 2050
qemuMigrationDstPrepareCleanup(virQEMUDriverPtr driver,
                               virDomainObjPtr vm)
2051 2052 2053 2054 2055 2056 2057 2058 2059
{
    qemuDomainObjPrivatePtr priv = vm->privateData;

    VIR_DEBUG("driver=%p, vm=%s, job=%s, asyncJob=%s",
              driver,
              vm->def->name,
              qemuDomainJobTypeToString(priv->job.active),
              qemuDomainAsyncJobTypeToString(priv->job.asyncJob));

2060
    virPortAllocatorRelease(priv->migrationPort);
2061 2062
    priv->migrationPort = 0;

2063 2064 2065 2066 2067
    if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_IN))
        return;
    qemuDomainObjDiscardAsyncJob(driver, vm);
}

2068
static qemuProcessIncomingDefPtr
2069 2070 2071 2072 2073 2074
qemuMigrationDstPrepare(virDomainObjPtr vm,
                        bool tunnel,
                        const char *protocol,
                        const char *listenAddress,
                        unsigned short port,
                        int fd)
2075 2076
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
2077
    qemuProcessIncomingDefPtr inc = NULL;
2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107
    char *migrateFrom = NULL;

    if (tunnel) {
        if (VIR_STRDUP(migrateFrom, "stdio") < 0)
            goto cleanup;
    } else {
        bool encloseAddress = false;
        bool hostIPv6Capable = false;
        struct addrinfo *info = NULL;
        struct addrinfo hints = { .ai_flags = AI_ADDRCONFIG,
                                  .ai_socktype = SOCK_STREAM };
        const char *incFormat;

        if (getaddrinfo("::", NULL, &hints, &info) == 0) {
            freeaddrinfo(info);
            hostIPv6Capable = true;
        }

        if (listenAddress) {
            if (virSocketAddrNumericFamily(listenAddress) == AF_INET6) {
                if (!hostIPv6Capable) {
                    virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                                   _("host isn't capable of IPv6"));
                    goto cleanup;
                }
                /* IPv6 address must be escaped in brackets on the cmd line */
                encloseAddress = true;
            } else {
                /* listenAddress is a hostname or IPv4 */
            }
2108
        } else if (hostIPv6Capable) {
2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131
            /* Listen on :: instead of 0.0.0.0 if QEMU understands it
             * and there is at least one IPv6 address configured
             */
            listenAddress = "::";
            encloseAddress = true;
        } else {
            listenAddress = "0.0.0.0";
        }

        /* QEMU will be started with
         *   -incoming protocol:[<IPv6 addr>]:port,
         *   -incoming protocol:<IPv4 addr>:port, or
         *   -incoming protocol:<hostname>:port
         */
        if (encloseAddress)
            incFormat = "%s:[%s]:%d";
        else
            incFormat = "%s:%s:%d";
        if (virAsprintf(&migrateFrom, incFormat,
                        protocol, listenAddress, port) < 0)
            goto cleanup;
    }

2132 2133
    inc = qemuProcessIncomingDefNew(priv->qemuCaps, listenAddress,
                                    migrateFrom, fd, NULL);
2134

2135
 cleanup:
2136 2137
    VIR_FREE(migrateFrom);
    return inc;
2138 2139
}

2140
static int
2141
qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
2142
                           virConnectPtr dconn,
2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156
                           const char *cookiein,
                           int cookieinlen,
                           char **cookieout,
                           int *cookieoutlen,
                           virDomainDefPtr *def,
                           const char *origname,
                           virStreamPtr st,
                           const char *protocol,
                           unsigned short port,
                           bool autoPort,
                           const char *listenAddress,
                           size_t nmigrate_disks,
                           const char **migrate_disks,
                           int nbdPort,
2157
                           qemuMigrationParamsPtr migParams,
2158
                           unsigned long flags)
2159 2160
{
    virDomainObjPtr vm = NULL;
2161
    virObjectEventPtr event = NULL;
2162
    int ret = -1;
2163
    int dataFD[2] = { -1, -1 };
2164
    qemuDomainObjPrivatePtr priv = NULL;
2165
    qemuMigrationCookiePtr mig = NULL;
2166
    bool tunnel = !!st;
J
Jiri Denemark 已提交
2167
    char *xmlout = NULL;
L
liguang 已提交
2168
    unsigned int cookieFlags;
2169
    unsigned int startFlags;
2170
    virCapsPtr caps = NULL;
2171
    qemuProcessIncomingDefPtr incoming = NULL;
2172
    bool taint_hook = false;
2173 2174 2175
    bool stopProcess = false;
    bool relabel = false;
    int rv;
2176 2177
    char *tlsAlias = NULL;
    char *secAlias = NULL;
2178

2179 2180
    virNWFilterReadLockFilterUpdates();

L
liguang 已提交
2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200
    if (flags & VIR_MIGRATE_OFFLINE) {
        if (flags & (VIR_MIGRATE_NON_SHARED_DISK |
                     VIR_MIGRATE_NON_SHARED_INC)) {
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                           _("offline migration cannot handle "
                             "non-shared storage"));
            goto cleanup;
        }
        if (!(flags & VIR_MIGRATE_PERSIST_DEST)) {
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                           _("offline migration must be specified with "
                             "the persistent flag set"));
            goto cleanup;
        }
        if (tunnel) {
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                           _("tunnelled offline migration does not "
                             "make sense"));
            goto cleanup;
        }
2201 2202
        cookieFlags = 0;
    } else {
2203 2204
        cookieFlags = QEMU_MIGRATION_COOKIE_GRAPHICS |
                      QEMU_MIGRATION_COOKIE_CAPS;
L
liguang 已提交
2205 2206
    }

2207 2208 2209 2210 2211 2212 2213 2214 2215
    if (flags & VIR_MIGRATE_POSTCOPY &&
        (!(flags & VIR_MIGRATE_LIVE) ||
         flags & VIR_MIGRATE_PAUSED)) {
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("post-copy migration is not supported with non-live "
                         "or paused migration"));
        goto cleanup;
    }

2216 2217 2218 2219 2220 2221
    if (flags & VIR_MIGRATE_POSTCOPY && flags & VIR_MIGRATE_TUNNELLED) {
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("post-copy is not supported with tunnelled migration"));
        goto cleanup;
    }

2222 2223 2224
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto cleanup;

2225
    if (!qemuMigrationSrcIsAllowedHostdev(*def))
2226 2227
        goto cleanup;

J
Jiri Denemark 已提交
2228 2229 2230 2231 2232
    /* Let migration hook filter domain XML */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
        char *xml;
        int hookret;

2233
        if (!(xml = qemuDomainDefFormatXML(driver, *def,
2234 2235
                                           VIR_DOMAIN_XML_SECURE |
                                           VIR_DOMAIN_XML_MIGRATABLE)))
J
Jiri Denemark 已提交
2236 2237
            goto cleanup;

2238
        hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, (*def)->name,
J
Jiri Denemark 已提交
2239 2240 2241 2242 2243 2244 2245
                              VIR_HOOK_QEMU_OP_MIGRATE, VIR_HOOK_SUBOP_BEGIN,
                              NULL, xml, &xmlout);
        VIR_FREE(xml);

        if (hookret < 0) {
            goto cleanup;
        } else if (hookret == 0) {
2246
            if (virStringIsEmpty(xmlout)) {
J
Jiri Denemark 已提交
2247 2248 2249 2250 2251 2252
                VIR_DEBUG("Migrate hook filter returned nothing; using the"
                          " original XML");
            } else {
                virDomainDefPtr newdef;

                VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
2253
                newdef = virDomainDefParseString(xmlout, caps, driver->xmlopt, NULL,
2254 2255
                                                 VIR_DOMAIN_DEF_PARSE_INACTIVE |
                                                 VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE);
J
Jiri Denemark 已提交
2256 2257 2258
                if (!newdef)
                    goto cleanup;

2259
                if (!qemuDomainDefCheckABIStability(driver, *def, newdef)) {
J
Jiri Denemark 已提交
2260 2261 2262 2263
                    virDomainDefFree(newdef);
                    goto cleanup;
                }

2264 2265
                virDomainDefFree(*def);
                *def = newdef;
2266 2267 2268 2269
                /* We should taint the domain here. However, @vm and therefore
                 * privateData too are still NULL, so just notice the fact and
                 * taint it later. */
                taint_hook = true;
J
Jiri Denemark 已提交
2270 2271 2272 2273
            }
        }
    }

2274
    if (!(vm = virDomainObjListAdd(driver->domains, *def,
2275
                                   driver->xmlopt,
2276 2277 2278
                                   VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
                                   NULL)))
2279
        goto cleanup;
2280
    *def = NULL;
2281

2282
    priv = vm->privateData;
2283 2284
    if (VIR_STRDUP(priv->origname, origname) < 0)
        goto cleanup;
2285

2286 2287 2288 2289 2290
    if (taint_hook) {
        /* Domain XML has been altered by a hook script. */
        priv->hookRun = true;
    }

2291
    if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
2292
                                       QEMU_MIGRATION_COOKIE_LOCKSTATE |
2293
                                       QEMU_MIGRATION_COOKIE_NBD |
2294
                                       QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG |
2295
                                       QEMU_MIGRATION_COOKIE_CPU_HOTPLUG |
2296
                                       QEMU_MIGRATION_COOKIE_CPU |
2297 2298
                                       QEMU_MIGRATION_COOKIE_ALLOW_REBOOT |
                                       QEMU_MIGRATION_COOKIE_CAPS)))
2299 2300
        goto cleanup;

2301 2302
    if (STREQ_NULLABLE(protocol, "rdma") &&
        !virMemoryLimitIsSet(vm->def->mem.hard_limit)) {
M
Michael R. Hines 已提交
2303 2304 2305 2306 2307 2308
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("cannot start RDMA migration with no memory hard "
                         "limit set"));
        goto cleanup;
    }

2309 2310 2311
    if (qemuMigrationDstPrecreateStorage(vm, mig->nbd,
                                         nmigrate_disks, migrate_disks,
                                         !!(flags & VIR_MIGRATE_NON_SHARED_INC)) < 0)
2312 2313
        goto cleanup;

2314 2315
    if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
                              flags) < 0)
2316
        goto cleanup;
2317
    qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PREPARE);
2318 2319 2320 2321

    /* Domain starts inactive, even if the domain XML had an id field. */
    vm->def->id = -1;

L
liguang 已提交
2322 2323 2324
    if (flags & VIR_MIGRATE_OFFLINE)
        goto done;

2325 2326
    if (tunnel &&
        (pipe(dataFD) < 0 || virSetCloseExec(dataFD[1]) < 0)) {
2327 2328
        virReportSystemError(errno, "%s",
                             _("cannot create pipe for tunnelled migration"));
2329
        goto stopjob;
2330 2331
    }

2332 2333
    startFlags = VIR_QEMU_PROCESS_START_AUTODESTROY;

2334
    if (qemuProcessInit(driver, vm, mig->cpu, QEMU_ASYNC_JOB_MIGRATION_IN,
2335
                        true, startFlags) < 0)
2336
        goto stopjob;
2337
    stopProcess = true;
2338

2339 2340
    priv->allowReboot = mig->allowReboot;

2341 2342 2343
    if (!(incoming = qemuMigrationDstPrepare(vm, tunnel, protocol,
                                             listenAddress, port,
                                             dataFD[0])))
2344
        goto stopjob;
2345

2346
    if (qemuProcessPrepareDomain(driver, vm, startFlags) < 0)
2347 2348
        goto stopjob;

2349
    if (qemuProcessPrepareHost(driver, vm, startFlags) < 0)
2350 2351
        goto stopjob;

2352
    rv = qemuProcessLaunch(dconn, driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
2353 2354
                           incoming, NULL,
                           VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START,
2355
                           startFlags);
2356 2357 2358
    if (rv < 0) {
        if (rv == -2)
            relabel = true;
2359
        goto stopjob;
2360
    }
2361
    relabel = true;
2362

2363 2364 2365 2366
    if (tunnel) {
        if (virFDStreamOpen(st, dataFD[1]) < 0) {
            virReportSystemError(errno, "%s",
                                 _("cannot pass pipe for tunnelled migration"));
2367
            goto stopjob;
2368
        }
2369
        dataFD[1] = -1; /* 'st' owns the FD now & will close it */
2370 2371
    }

2372
    if (STREQ_NULLABLE(protocol, "rdma") &&
M
Michael R. Hines 已提交
2373
        virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) {
2374
        goto stopjob;
M
Michael R. Hines 已提交
2375 2376
    }

2377
    if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
2378
                                 migParams, mig->caps->automatic) < 0)
2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393
        goto stopjob;

    /* Migrations using TLS need to add the "tls-creds-x509" object and
     * set the migration TLS parameters */
    if (flags & VIR_MIGRATE_TLS) {
        if (qemuMigrationParamsEnableTLS(driver, vm, true,
                                         QEMU_ASYNC_JOB_MIGRATION_IN,
                                         &tlsAlias, &secAlias, NULL,
                                         migParams) < 0)
            goto stopjob;
    } else {
        if (qemuMigrationParamsDisableTLS(vm, migParams) < 0)
            goto stopjob;
    }

2394 2395
    if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
                                 migParams) < 0)
2396 2397
        goto stopjob;

2398 2399 2400
    if (mig->nbd &&
        flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC) &&
        virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_SERVER)) {
2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412
        const char *nbdTLSAlias = NULL;

        if (flags & VIR_MIGRATE_TLS) {
            if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) {
                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                               _("QEMU NBD server does not support TLS transport"));
                goto stopjob;
            }

            nbdTLSAlias = tlsAlias;
        }

2413 2414
        if (qemuMigrationDstStartNBDServer(driver, vm, incoming->address,
                                           nmigrate_disks, migrate_disks,
2415
                                           nbdPort, nbdTLSAlias) < 0) {
2416
            goto stopjob;
2417
        }
2418
        cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
2419 2420
    }

2421 2422 2423 2424 2425 2426 2427 2428 2429
    if (mig->lockState) {
        VIR_DEBUG("Received lockstate %s", mig->lockState);
        VIR_FREE(priv->lockState);
        priv->lockState = mig->lockState;
        mig->lockState = NULL;
    } else {
        VIR_DEBUG("Received no lockstate");
    }

2430
    if (incoming->deferredURI &&
2431 2432
        qemuMigrationDstRun(driver, vm, incoming->deferredURI,
                            QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
2433 2434
        goto stopjob;

2435
    if (qemuProcessFinishStartup(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
2436 2437 2438
                                 false, VIR_DOMAIN_PAUSED_MIGRATION) < 0)
        goto stopjob;

2439
 done:
2440 2441 2442
    if (qemuMigrationBakeCookie(mig, driver, vm,
                                QEMU_MIGRATION_DESTINATION,
                                cookieout, cookieoutlen, cookieFlags) < 0) {
2443 2444 2445 2446 2447 2448 2449
        /* We could tear down the whole guest here, but
         * cookie data is (so far) non-critical, so that
         * seems a little harsh. We'll just warn for now.
         */
        VIR_WARN("Unable to encode migration cookie");
    }

2450
    if (qemuDomainCleanupAdd(vm, qemuMigrationDstPrepareCleanup) < 0)
2451
        goto stopjob;
2452

L
liguang 已提交
2453 2454
    if (!(flags & VIR_MIGRATE_OFFLINE)) {
        virDomainAuditStart(vm, "migrated", true);
2455
        event = virDomainEventLifecycleNewFromObj(vm,
L
liguang 已提交
2456 2457 2458
                                         VIR_DOMAIN_EVENT_STARTED,
                                         VIR_DOMAIN_EVENT_STARTED_MIGRATED);
    }
2459

2460 2461 2462 2463
    /* We keep the job active across API calls until the finish() call.
     * This prevents any other APIs being invoked while incoming
     * migration is taking place.
     */
2464
    qemuMigrationJobContinue(vm);
2465

2466 2467
    if (autoPort)
        priv->migrationPort = port;
2468 2469 2470 2471 2472
    /* in this case port is not auto selected and we don't need to manage it
     * anymore after cookie is baked
     */
    if (nbdPort != 0)
        priv->nbdPort = 0;
2473
    ret = 0;
2474

2475
 cleanup:
2476 2477
    VIR_FREE(tlsAlias);
    VIR_FREE(secAlias);
2478
    qemuProcessIncomingDefFree(incoming);
J
Jiri Denemark 已提交
2479
    VIR_FREE(xmlout);
2480 2481
    VIR_FORCE_CLOSE(dataFD[0]);
    VIR_FORCE_CLOSE(dataFD[1]);
2482 2483 2484
    if (ret < 0 && priv) {
        /* priv is set right after vm is added to the list of domains
         * and there is no 'goto cleanup;' in the middle of those */
2485
        VIR_FREE(priv->origname);
2486 2487 2488 2489
        /* release if port is auto selected which is not the case if
         * it is given in parameters
         */
        if (nbdPort == 0)
2490
            virPortAllocatorRelease(priv->nbdPort);
2491
        priv->nbdPort = 0;
2492
        virDomainObjRemoveTransientDef(vm);
2493
        qemuDomainRemoveInactiveJob(driver, vm);
2494
    }
M
Michal Privoznik 已提交
2495
    virDomainObjEndAPI(&vm);
2496
    qemuDomainEventQueue(driver, event);
2497
    qemuMigrationCookieFree(mig);
2498
    virObjectUnref(caps);
2499
    virNWFilterUnlockFilterUpdates();
2500
    return ret;
2501

2502
 stopjob:
2503
    qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
2504
                             priv->job.migParams, priv->job.apiFlags);
2505

2506 2507 2508 2509
    if (stopProcess) {
        unsigned int stopFlags = VIR_QEMU_PROCESS_STOP_MIGRATED;
        if (!relabel)
            stopFlags |= VIR_QEMU_PROCESS_STOP_NO_RELABEL;
2510
        virDomainAuditStart(vm, "migrated", false);
2511 2512
        qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED,
                        QEMU_ASYNC_JOB_MIGRATION_IN, stopFlags);
2513
    }
2514

2515
    qemuMigrationJobFinish(driver, vm);
2516
    goto cleanup;
2517 2518 2519
}


2520 2521 2522 2523 2524
/*
 * This version starts an empty VM listening on a localhost TCP port, and
 * sets up the corresponding virStream to handle the incoming data.
 */
int
2525
qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver,
2526
                              virConnectPtr dconn,
2527 2528 2529 2530 2531 2532 2533
                              const char *cookiein,
                              int cookieinlen,
                              char **cookieout,
                              int *cookieoutlen,
                              virStreamPtr st,
                              virDomainDefPtr *def,
                              const char *origname,
2534
                              qemuMigrationParamsPtr migParams,
2535
                              unsigned long flags)
2536
{
2537
    VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, "
2538
              "cookieout=%p, cookieoutlen=%p, st=%p, def=%p, "
2539
              "origname=%s, flags=0x%lx",
2540
              driver, dconn, NULLSTR(cookiein), cookieinlen,
2541
              cookieout, cookieoutlen, st, *def, origname, flags);
2542

2543 2544 2545 2546 2547 2548
    if (st == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("tunnelled migration requested but NULL stream passed"));
        return -1;
    }

2549 2550 2551
    return qemuMigrationDstPrepareAny(driver, dconn, cookiein, cookieinlen,
                                      cookieout, cookieoutlen, def, origname,
                                      st, NULL, 0, false, NULL, 0, NULL, 0,
2552
                                      migParams, flags);
2553 2554 2555
}


2556
static virURIPtr
2557
qemuMigrationAnyParseURI(const char *uri, bool *wellFormed)
2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578
{
    char *tmp = NULL;
    virURIPtr parsed;

    /* For compatibility reasons tcp://... URIs are sent as tcp:...
     * We need to transform them to a well-formed URI before parsing. */
    if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri + 4, "//")) {
        if (virAsprintf(&tmp, "tcp://%s", uri + 4) < 0)
            return NULL;
        uri = tmp;
    }

    parsed = virURIParse(uri);
    if (parsed && wellFormed)
        *wellFormed = !tmp;
    VIR_FREE(tmp);

    return parsed;
}


2579
int
2580
qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver,
2581
                              virConnectPtr dconn,
2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593
                              const char *cookiein,
                              int cookieinlen,
                              char **cookieout,
                              int *cookieoutlen,
                              const char *uri_in,
                              char **uri_out,
                              virDomainDefPtr *def,
                              const char *origname,
                              const char *listenAddress,
                              size_t nmigrate_disks,
                              const char **migrate_disks,
                              int nbdPort,
2594
                              qemuMigrationParamsPtr migParams,
2595
                              unsigned long flags)
2596
{
2597 2598
    unsigned short port = 0;
    bool autoPort = true;
2599 2600
    char *hostname = NULL;
    int ret = -1;
2601
    virURIPtr uri = NULL;
2602 2603
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
    const char *migrateHost = cfg->migrateHost;
J
Jiri Denemark 已提交
2604

2605
    VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, "
2606
              "cookieout=%p, cookieoutlen=%p, uri_in=%s, uri_out=%p, "
2607
              "def=%p, origname=%s, listenAddress=%s, "
2608
              "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, flags=0x%lx",
2609
              driver, dconn, NULLSTR(cookiein), cookieinlen,
2610
              cookieout, cookieoutlen, NULLSTR(uri_in), uri_out,
2611
              *def, origname, NULLSTR(listenAddress),
2612
              nmigrate_disks, migrate_disks, nbdPort, flags);
2613

2614 2615
    *uri_out = NULL;

2616 2617 2618
    /* The URI passed in may be NULL or a string "tcp://somehostname:port".
     *
     * If the URI passed in is NULL then we allocate a port number
2619 2620 2621
     * from our pool of port numbers, and if the migrateHost is configured,
     * we return a URI of "tcp://migrateHost:port", otherwise return a URI
     * of "tcp://ourhostname:port".
2622 2623 2624 2625 2626 2627
     *
     * If the URI passed in is not NULL then we try to parse out the
     * port number and use that (note that the hostname is assumed
     * to be a correct hostname which refers to the target machine).
     */
    if (uri_in == NULL) {
2628 2629 2630
        bool encloseAddress = false;
        const char *incFormat;

2631
        if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0)
2632
            goto cleanup;
2633

2634
        if (migrateHost != NULL) {
2635 2636
            if (virSocketAddrNumericFamily(migrateHost) == AF_INET6)
                encloseAddress = true;
2637

2638
            if (VIR_STRDUP(hostname, migrateHost) < 0)
2639 2640 2641 2642 2643
                goto cleanup;
        } else {
            if ((hostname = virGetHostname()) == NULL)
                goto cleanup;
        }
2644 2645

        if (STRPREFIX(hostname, "localhost")) {
2646 2647 2648
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("hostname on destination resolved to localhost,"
                             " but migration requires an FQDN"));
2649 2650 2651 2652 2653
            goto cleanup;
        }

        /* XXX this really should have been a properly well-formed
         * URI, but we can't add in tcp:// now without breaking
2654
         * compatibility with old targets. We at least make the
2655 2656
         * new targets accept both syntaxes though.
         */
2657 2658 2659 2660 2661 2662
        if (encloseAddress)
            incFormat = "%s:[%s]:%d";
        else
            incFormat = "%s:%s:%d";

        if (virAsprintf(uri_out, incFormat, "tcp", hostname, port) < 0)
2663 2664
            goto cleanup;
    } else {
2665
        bool well_formed_uri;
J
Ján Tomko 已提交
2666

2667
        if (!(uri = qemuMigrationAnyParseURI(uri_in, &well_formed_uri)))
2668
            goto cleanup;
J
Ján Tomko 已提交
2669

2670 2671 2672 2673 2674 2675 2676
        if (uri->scheme == NULL) {
            virReportError(VIR_ERR_INVALID_ARG,
                           _("missing scheme in migration URI: %s"),
                           uri_in);
            goto cleanup;
        }

M
Michael R. Hines 已提交
2677 2678
        if (STRNEQ(uri->scheme, "tcp") &&
            STRNEQ(uri->scheme, "rdma")) {
2679 2680 2681
            virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
                           _("unsupported scheme %s in migration URI %s"),
                           uri->scheme, uri_in);
J
Ján Tomko 已提交
2682 2683 2684 2685 2686 2687 2688 2689 2690 2691
            goto cleanup;
        }

        if (uri->server == NULL) {
            virReportError(VIR_ERR_INVALID_ARG, _("missing host in migration"
                                                  " URI: %s"), uri_in);
            goto cleanup;
        }

        if (uri->port == 0) {
2692
            if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0)
2693
                goto cleanup;
2694

2695
            /* Send well-formed URI only if uri_in was well-formed */
2696 2697 2698 2699 2700 2701 2702 2703
            if (well_formed_uri) {
                uri->port = port;
                if (!(*uri_out = virURIFormat(uri)))
                    goto cleanup;
            } else {
                if (virAsprintf(uri_out, "%s:%d", uri_in, port) < 0)
                    goto cleanup;
            }
2704
        } else {
2705 2706
            port = uri->port;
            autoPort = false;
2707 2708 2709 2710 2711 2712
        }
    }

    if (*uri_out)
        VIR_DEBUG("Generated uri_out=%s", *uri_out);

2713
    ret = qemuMigrationDstPrepareAny(driver, dconn, cookiein, cookieinlen,
2714 2715 2716 2717
                                     cookieout, cookieoutlen, def, origname,
                                     NULL, uri ? uri->scheme : "tcp",
                                     port, autoPort, listenAddress,
                                     nmigrate_disks, migrate_disks, nbdPort,
2718
                                     migParams, flags);
2719
 cleanup:
2720
    virURIFree(uri);
2721
    VIR_FREE(hostname);
2722
    virObjectUnref(cfg);
2723
    if (ret != 0) {
2724
        VIR_FREE(*uri_out);
2725
        if (autoPort)
2726
            virPortAllocatorRelease(port);
2727
    }
2728 2729 2730 2731
    return ret;
}


2732
virDomainDefPtr
2733 2734 2735 2736
qemuMigrationAnyPrepareDef(virQEMUDriverPtr driver,
                           const char *dom_xml,
                           const char *dname,
                           char **origname)
2737 2738 2739
{
    virCapsPtr caps = NULL;
    virDomainDefPtr def;
2740
    char *name = NULL;
2741 2742 2743 2744 2745 2746 2747 2748 2749 2750

    if (!dom_xml) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("no domain XML passed"));
        return NULL;
    }

    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        return NULL;

2751
    if (!(def = virDomainDefParseString(dom_xml, caps, driver->xmlopt, NULL,
2752 2753
                                        VIR_DOMAIN_DEF_PARSE_INACTIVE |
                                        VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
2754 2755 2756
        goto cleanup;

    if (dname) {
2757
        name = def->name;
2758 2759 2760 2761 2762 2763
        if (VIR_STRDUP(def->name, dname) < 0) {
            virDomainDefFree(def);
            def = NULL;
        }
    }

2764
 cleanup:
2765
    virObjectUnref(caps);
2766 2767 2768 2769
    if (def && origname)
        *origname = name;
    else
        VIR_FREE(name);
2770 2771 2772 2773
    return def;
}


2774
static int
2775 2776 2777 2778 2779 2780
qemuMigrationSrcConfirmPhase(virQEMUDriverPtr driver,
                             virDomainObjPtr vm,
                             const char *cookiein,
                             int cookieinlen,
                             unsigned int flags,
                             int retcode)
2781 2782
{
    qemuMigrationCookiePtr mig;
2783
    virObjectEventPtr event;
2784 2785
    int rv = -1;
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2786 2787
    qemuDomainObjPrivatePtr priv = vm->privateData;
    qemuDomainJobInfoPtr jobInfo = NULL;
2788

2789
    VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
2790
              "flags=0x%x, retcode=%d",
2791
              driver, vm, NULLSTR(cookiein), cookieinlen,
2792 2793 2794 2795 2796 2797 2798 2799 2800
              flags, retcode);

    virCheckFlags(QEMU_MIGRATION_FLAGS, -1);

    qemuMigrationJobSetPhase(driver, vm,
                             retcode == 0
                             ? QEMU_MIGRATION_PHASE_CONFIRM3
                             : QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED);

2801 2802
    if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
                                       QEMU_MIGRATION_COOKIE_STATS)))
2803 2804
        goto cleanup;

2805 2806 2807
    if (retcode == 0)
        jobInfo = priv->job.completed;
    else
2808
        VIR_FREE(priv->job.completed);
2809 2810 2811

    /* Update times with the values sent by the destination daemon */
    if (mig->jobInfo && jobInfo) {
2812 2813 2814 2815 2816 2817 2818 2819
        int reason;

        /* We need to refresh migration statistics after a completed post-copy
         * migration since priv->job.completed contains obsolete data from the
         * time we switched to post-copy mode.
         */
        if (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED &&
            reason == VIR_DOMAIN_PAUSED_POSTCOPY &&
2820 2821
            qemuMigrationAnyFetchStats(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
                                       jobInfo, NULL) < 0)
2822 2823
            VIR_WARN("Could not refresh migration statistics");

2824 2825 2826
        qemuDomainJobInfoUpdateTime(jobInfo);
        jobInfo->timeDeltaSet = mig->jobInfo->timeDeltaSet;
        jobInfo->timeDelta = mig->jobInfo->timeDelta;
2827 2828
        jobInfo->stats.mig.downtime_set = mig->jobInfo->stats.mig.downtime_set;
        jobInfo->stats.mig.downtime = mig->jobInfo->stats.mig.downtime;
2829 2830
    }

2831 2832 2833
    if (flags & VIR_MIGRATE_OFFLINE)
        goto done;

2834 2835
    /* Did the migration go as planned?  If yes, kill off the domain object.
     * If something failed, resume CPUs, but only if we didn't use post-copy.
2836 2837 2838 2839
     */
    if (retcode == 0) {
        /* If guest uses SPICE and supports seamless migration we have to hold
         * up domain shutdown until SPICE server transfers its data */
2840
        qemuMigrationSrcWaitForSpice(vm);
2841 2842

        qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_MIGRATED,
2843
                        QEMU_ASYNC_JOB_MIGRATION_OUT,
2844 2845 2846
                        VIR_QEMU_PROCESS_STOP_MIGRATED);
        virDomainAuditStop(vm, "migrated");

2847
        event = virDomainEventLifecycleNewFromObj(vm,
2848 2849
                                         VIR_DOMAIN_EVENT_STOPPED,
                                         VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
2850 2851
        qemuDomainEventQueue(driver, event);
        qemuDomainEventEmitJobCompleted(driver, vm);
2852
    } else {
2853
        virErrorPtr orig_err = virSaveLastError();
2854
        int reason;
2855 2856

        /* cancel any outstanding NBD jobs */
2857 2858
        qemuMigrationSrcCancelDriveMirror(driver, vm, false,
                                          QEMU_ASYNC_JOB_MIGRATION_OUT, NULL);
2859 2860 2861

        virSetError(orig_err);
        virFreeError(orig_err);
2862

2863 2864
        if (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED &&
            reason == VIR_DOMAIN_PAUSED_POSTCOPY) {
2865 2866
            qemuMigrationAnyPostcopyFailed(driver, vm);
        } else if (qemuMigrationSrcRestoreDomainState(driver, vm)) {
2867 2868 2869
            event = virDomainEventLifecycleNewFromObj(vm,
                                                      VIR_DOMAIN_EVENT_RESUMED,
                                                      VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
2870
            qemuDomainEventQueue(driver, event);
2871 2872
        }

2873
        qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
2874
                                 priv->job.migParams, priv->job.apiFlags);
2875

2876
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
2877 2878 2879
            VIR_WARN("Failed to save status on vm %s", vm->def->name);
    }

2880
 done:
2881 2882 2883
    qemuMigrationCookieFree(mig);
    rv = 0;

2884
 cleanup:
2885 2886 2887 2888 2889
    virObjectUnref(cfg);
    return rv;
}

int
2890 2891 2892 2893 2894 2895
qemuMigrationSrcConfirm(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
                        const char *cookiein,
                        int cookieinlen,
                        unsigned int flags,
                        int cancelled)
2896
{
2897
    qemuMigrationJobPhase phase;
2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911
    virQEMUDriverConfigPtr cfg = NULL;
    int ret = -1;

    cfg = virQEMUDriverGetConfig(driver);

    if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT))
        goto cleanup;

    if (cancelled)
        phase = QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED;
    else
        phase = QEMU_MIGRATION_PHASE_CONFIRM3;

    qemuMigrationJobStartPhase(driver, vm, phase);
2912
    virCloseCallbacksUnset(driver->closeCallbacks, vm,
2913
                           qemuMigrationSrcCleanup);
2914

2915 2916 2917
    ret = qemuMigrationSrcConfirmPhase(driver, vm,
                                       cookiein, cookieinlen,
                                       flags, cancelled);
2918

2919
    qemuMigrationJobFinish(driver, vm);
2920
    if (!virDomainObjIsActive(vm)) {
2921
        if (flags & VIR_MIGRATE_UNDEFINE_SOURCE) {
2922
            virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
2923 2924
            vm->persistent = 0;
        }
2925
        qemuDomainRemoveInactiveJob(driver, vm);
2926 2927
    }

2928
 cleanup:
M
Michal Privoznik 已提交
2929
    virDomainObjEndAPI(&vm);
2930 2931 2932 2933 2934
    virObjectUnref(cfg);
    return ret;
}


2935 2936
enum qemuMigrationDestinationType {
    MIGRATION_DEST_HOST,
2937
    MIGRATION_DEST_CONNECT_HOST,
2938
    MIGRATION_DEST_FD,
2939
};
2940

2941 2942 2943 2944
enum qemuMigrationForwardType {
    MIGRATION_FWD_DIRECT,
    MIGRATION_FWD_STREAM,
};
2945

2946 2947 2948 2949 2950 2951
typedef struct _qemuMigrationSpec qemuMigrationSpec;
typedef qemuMigrationSpec *qemuMigrationSpecPtr;
struct _qemuMigrationSpec {
    enum qemuMigrationDestinationType destType;
    union {
        struct {
2952
            const char *protocol;
2953 2954 2955 2956
            const char *name;
            int port;
        } host;

2957 2958 2959 2960
        struct {
            int qemu;
            int local;
        } fd;
2961 2962 2963 2964 2965 2966 2967
    } dest;

    enum qemuMigrationForwardType fwdType;
    union {
        virStreamPtr stream;
    } fwd;
};
2968 2969 2970

#define TUNNEL_SEND_BUF_SIZE 65536

2971 2972 2973 2974 2975 2976 2977
typedef struct _qemuMigrationIOThread qemuMigrationIOThread;
typedef qemuMigrationIOThread *qemuMigrationIOThreadPtr;
struct _qemuMigrationIOThread {
    virThread thread;
    virStreamPtr st;
    int sock;
    virError err;
2978 2979
    int wakeupRecvFD;
    int wakeupSendFD;
2980 2981
};

2982
static void qemuMigrationSrcIOFunc(void *arg)
2983
{
2984
    qemuMigrationIOThreadPtr data = arg;
2985 2986 2987 2988 2989 2990 2991
    char *buffer = NULL;
    struct pollfd fds[2];
    int timeout = -1;
    virErrorPtr err = NULL;

    VIR_DEBUG("Running migration tunnel; stream=%p, sock=%d",
              data->st, data->sock);
2992

2993
    if (VIR_ALLOC_N(buffer, TUNNEL_SEND_BUF_SIZE) < 0)
2994
        goto abrt;
2995

2996 2997 2998
    fds[0].fd = data->sock;
    fds[1].fd = data->wakeupRecvFD;

2999
    for (;;) {
3000 3001 3002 3003 3004 3005 3006 3007 3008 3009
        int ret;

        fds[0].events = fds[1].events = POLLIN;
        fds[0].revents = fds[1].revents = 0;

        ret = poll(fds, ARRAY_CARDINALITY(fds), timeout);

        if (ret < 0) {
            if (errno == EAGAIN || errno == EINTR)
                continue;
3010
            virReportSystemError(errno, "%s",
3011 3012
                                 _("poll failed in migration tunnel"));
            goto abrt;
3013
        }
3014 3015 3016 3017 3018 3019 3020

        if (ret == 0) {
            /* We were asked to gracefully stop but reading would block. This
             * can only happen if qemu told us migration finished but didn't
             * close the migration fd. We handle this in the same way as EOF.
             */
            VIR_DEBUG("QEMU forgot to close migration fd");
3021
            break;
3022
        }
3023

3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039
        if (fds[1].revents & (POLLIN | POLLERR | POLLHUP)) {
            char stop = 0;

            if (saferead(data->wakeupRecvFD, &stop, 1) != 1) {
                virReportSystemError(errno, "%s",
                                     _("failed to read from wakeup fd"));
                goto abrt;
            }

            VIR_DEBUG("Migration tunnel was asked to %s",
                      stop ? "abort" : "finish");
            if (stop) {
                goto abrt;
            } else {
                timeout = 0;
            }
3040 3041
        }

3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058
        if (fds[0].revents & (POLLIN | POLLERR | POLLHUP)) {
            int nbytes;

            nbytes = saferead(data->sock, buffer, TUNNEL_SEND_BUF_SIZE);
            if (nbytes > 0) {
                if (virStreamSend(data->st, buffer, nbytes) < 0)
                    goto error;
            } else if (nbytes < 0) {
                virReportSystemError(errno, "%s",
                        _("tunnelled migration failed to read from qemu"));
                goto abrt;
            } else {
                /* EOF; get out of here */
                break;
            }
        }
    }
3059

3060 3061
    if (virStreamFinish(data->st) < 0)
        goto error;
3062

3063
    VIR_FORCE_CLOSE(data->sock);
3064 3065
    VIR_FREE(buffer);

3066 3067
    return;

3068
 abrt:
3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079
    err = virSaveLastError();
    if (err && err->code == VIR_ERR_OK) {
        virFreeError(err);
        err = NULL;
    }
    virStreamAbort(data->st);
    if (err) {
        virSetError(err);
        virFreeError(err);
    }

3080
 error:
3081 3082 3083 3084 3085
    /* Let the source qemu know that the transfer cant continue anymore.
     * Don't copy the error for EPIPE as destination has the actual error. */
    VIR_FORCE_CLOSE(data->sock);
    if (!virLastErrorIsSystemErrno(EPIPE))
        virCopyLastError(&data->err);
3086
    virResetLastError();
3087
    VIR_FREE(buffer);
3088 3089 3090 3091
}


static qemuMigrationIOThreadPtr
3092 3093
qemuMigrationSrcStartTunnel(virStreamPtr st,
                            int sock)
3094
{
3095 3096
    qemuMigrationIOThreadPtr io = NULL;
    int wakeupFD[2] = { -1, -1 };
3097

3098 3099 3100 3101
    if (pipe2(wakeupFD, O_CLOEXEC) < 0) {
        virReportSystemError(errno, "%s",
                             _("Unable to make pipe"));
        goto error;
3102 3103
    }

3104
    if (VIR_ALLOC(io) < 0)
3105
        goto error;
3106

3107 3108
    io->st = st;
    io->sock = sock;
3109 3110
    io->wakeupRecvFD = wakeupFD[0];
    io->wakeupSendFD = wakeupFD[1];
3111 3112

    if (virThreadCreate(&io->thread, true,
3113
                        qemuMigrationSrcIOFunc,
3114 3115 3116
                        io) < 0) {
        virReportSystemError(errno, "%s",
                             _("Unable to create migration thread"));
3117
        goto error;
3118 3119 3120
    }

    return io;
3121

3122
 error:
3123 3124 3125 3126
    VIR_FORCE_CLOSE(wakeupFD[0]);
    VIR_FORCE_CLOSE(wakeupFD[1]);
    VIR_FREE(io);
    return NULL;
3127 3128 3129
}

static int
3130
qemuMigrationSrcStopTunnel(qemuMigrationIOThreadPtr io, bool error)
3131 3132
{
    int rv = -1;
3133 3134 3135 3136 3137 3138 3139 3140 3141
    char stop = error ? 1 : 0;

    /* make sure the thread finishes its job and is joinable */
    if (safewrite(io->wakeupSendFD, &stop, 1) != 1) {
        virReportSystemError(errno, "%s",
                             _("failed to wakeup migration tunnel"));
        goto cleanup;
    }

3142 3143 3144 3145
    virThreadJoin(&io->thread);

    /* Forward error from the IO thread, to this thread */
    if (io->err.code != VIR_ERR_OK) {
3146 3147 3148 3149
        if (error)
            rv = 0;
        else
            virSetError(&io->err);
3150 3151 3152 3153 3154 3155
        virResetError(&io->err);
        goto cleanup;
    }

    rv = 0;

3156
 cleanup:
3157 3158
    VIR_FORCE_CLOSE(io->wakeupSendFD);
    VIR_FORCE_CLOSE(io->wakeupRecvFD);
3159 3160
    VIR_FREE(io);
    return rv;
3161 3162
}

3163
static int
3164 3165 3166
qemuMigrationSrcConnect(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
                        qemuMigrationSpecPtr spec)
3167 3168 3169 3170 3171 3172 3173
{
    virNetSocketPtr sock;
    const char *host;
    char *port = NULL;
    int ret = -1;

    host = spec->dest.host.name;
3174
    if (virAsprintf(&port, "%d", spec->dest.host.port) < 0)
3175 3176 3177 3178 3179
        return -1;

    spec->destType = MIGRATION_DEST_FD;
    spec->dest.fd.qemu = -1;

3180
    if (qemuSecuritySetSocketLabel(driver->securityManager, vm->def) < 0)
3181
        goto cleanup;
3182 3183 3184
    if (virNetSocketNewConnectTCP(host, port,
                                  AF_UNSPEC,
                                  &sock) == 0) {
3185
        spec->dest.fd.qemu = virNetSocketDupFD(sock, true);
3186
        virObjectUnref(sock);
3187
    }
3188
    if (qemuSecurityClearSocketLabel(driver->securityManager, vm->def) < 0 ||
3189 3190 3191
        spec->dest.fd.qemu == -1)
        goto cleanup;

3192 3193 3194 3195 3196 3197 3198
    /* Migration expects a blocking FD */
    if (virSetBlocking(spec->dest.fd.qemu, true) < 0) {
        virReportSystemError(errno, _("Unable to set FD %d blocking"),
                             spec->dest.fd.qemu);
        goto cleanup;
    }

3199 3200
    ret = 0;

3201
 cleanup:
3202 3203 3204 3205 3206 3207
    VIR_FREE(port);
    if (ret < 0)
        VIR_FORCE_CLOSE(spec->dest.fd.qemu);
    return ret;
}

3208 3209

static int
3210 3211 3212 3213
qemuMigrationSrcContinue(virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
                         qemuMonitorMigrationStatus status,
                         qemuDomainAsyncJob asyncJob)
3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int ret;

    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        return -1;

    ret = qemuMonitorMigrateContinue(priv->mon, status);

    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;

    return ret;
}


3230
static int
3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244
qemuMigrationSrcRun(virQEMUDriverPtr driver,
                    virDomainObjPtr vm,
                    const char *persist_xml,
                    const char *cookiein,
                    int cookieinlen,
                    char **cookieout,
                    int *cookieoutlen,
                    unsigned long flags,
                    unsigned long resource,
                    qemuMigrationSpecPtr spec,
                    virConnectPtr dconn,
                    const char *graphicsuri,
                    size_t nmigrate_disks,
                    const char **migrate_disks,
3245
                    qemuMigrationParamsPtr migParams)
3246
{
3247
    int ret = -1;
3248 3249
    unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND;
    qemuDomainObjPrivatePtr priv = vm->privateData;
3250
    qemuMigrationCookiePtr mig = NULL;
3251 3252
    char *tlsAlias = NULL;
    char *secAlias = NULL;
3253
    qemuMigrationIOThreadPtr iothread = NULL;
3254
    int fd = -1;
3255
    unsigned long migrate_speed = resource ? resource : priv->migMaxBandwidth;
3256
    virErrorPtr orig_err = NULL;
3257
    unsigned int cookieFlags = 0;
3258
    bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
3259
    bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
3260
    bool cancel = false;
3261
    unsigned int waitFlags;
3262
    virDomainDefPtr persistDef = NULL;
3263
    char *timestamp;
3264
    int rc;
3265 3266

    VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
3267
              "cookieout=%p, cookieoutlen=%p, flags=0x%lx, resource=%lu, "
3268 3269
              "spec=%p (dest=%d, fwd=%d), dconn=%p, graphicsuri=%s, "
              "nmigrate_disks=%zu, migrate_disks=%p",
3270 3271
              driver, vm, NULLSTR(cookiein), cookieinlen,
              cookieout, cookieoutlen, flags, resource,
3272
              spec, spec->destType, spec->fwdType, dconn,
3273
              NULLSTR(graphicsuri), nmigrate_disks, migrate_disks);
3274

3275 3276 3277 3278 3279 3280 3281 3282 3283 3284
    if (flags & VIR_MIGRATE_NON_SHARED_DISK) {
        migrate_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_DISK;
        cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
    }

    if (flags & VIR_MIGRATE_NON_SHARED_INC) {
        migrate_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_INC;
        cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
    }

3285 3286
    if (virLockManagerPluginUsesState(driver->lockManager) &&
        !cookieout) {
3287 3288 3289 3290
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Migration with lock driver %s requires"
                         " cookie support"),
                       virLockManagerPluginGetName(driver->lockManager));
3291 3292 3293
        return -1;
    }

3294 3295 3296
    if (events)
        priv->signalIOError = abort_on_error;

3297 3298
    if (flags & VIR_MIGRATE_PERSIST_DEST) {
        if (persist_xml) {
3299 3300
            if (!(persistDef = qemuMigrationAnyPrepareDef(driver, persist_xml,
                                                          NULL, NULL)))
3301
                goto error;
3302 3303 3304
        } else {
            virDomainDefPtr def = vm->newDef ? vm->newDef : vm->def;
            if (!(persistDef = qemuDomainDefCopy(driver, def,
3305 3306
                                                 VIR_DOMAIN_XML_SECURE |
                                                 VIR_DOMAIN_XML_MIGRATABLE)))
3307
                goto error;
3308 3309 3310
        }
    }

3311
    mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
3312 3313 3314
                                 cookieFlags |
                                 QEMU_MIGRATION_COOKIE_GRAPHICS |
                                 QEMU_MIGRATION_COOKIE_CAPS);
3315
    if (!mig)
3316
        goto error;
3317

3318
    if (qemuMigrationSrcGraphicsRelocate(driver, vm, mig, graphicsuri) < 0)
3319 3320
        VIR_WARN("unable to provide data for graphics client relocation");

3321
    if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
3322
                                 migParams, mig->caps->automatic) < 0)
3323 3324
        goto error;

3325
    if (flags & VIR_MIGRATE_TLS) {
3326
        const char *hostname = NULL;
3327 3328 3329 3330

        /* We need to add tls-hostname whenever QEMU itself does not
         * connect directly to the destination. */
        if (spec->destType == MIGRATION_DEST_CONNECT_HOST ||
3331 3332 3333
            spec->destType == MIGRATION_DEST_FD)
            hostname = spec->dest.host.name;

3334
        if (qemuMigrationParamsEnableTLS(driver, vm, false,
3335 3336 3337 3338
                                         QEMU_ASYNC_JOB_MIGRATION_OUT,
                                         &tlsAlias, &secAlias, hostname,
                                         migParams) < 0)
            goto error;
3339
    } else {
3340
        if (qemuMigrationParamsDisableTLS(vm, migParams) < 0)
3341
            goto error;
3342 3343
    }

3344 3345 3346 3347
    if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
                                 migParams) < 0)
        goto error;

3348 3349 3350
    if (migrate_flags & (QEMU_MONITOR_MIGRATE_NON_SHARED_DISK |
                         QEMU_MONITOR_MIGRATE_NON_SHARED_INC)) {
        if (mig->nbd) {
3351 3352 3353 3354 3355 3356 3357 3358 3359 3360
            /* Currently libvirt does not support setting up of the NBD
             * non-shared storage migration with TLS. As we need to honour the
             * VIR_MIGRATE_TLS flag, we need to reject such migration until
             * we implement TLS for NBD. */
            if (flags & VIR_MIGRATE_TLS) {
                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                               _("NBD migration with TLS is not supported"));
                goto error;
            }

3361
            /* This will update migrate_flags on success */
3362 3363 3364 3365 3366 3367 3368
            if (qemuMigrationSrcDriveMirror(driver, vm, mig,
                                            spec->dest.host.name,
                                            migrate_speed,
                                            &migrate_flags,
                                            nmigrate_disks,
                                            migrate_disks,
                                            dconn) < 0) {
3369
                goto error;
3370 3371 3372 3373 3374 3375 3376
            }
        } else {
            /* Destination doesn't support NBD server.
             * Fall back to previous implementation. */
            VIR_DEBUG("Destination doesn't support NBD server "
                      "Falling back to previous implementation.");
        }
3377 3378
    }

3379
    /* Before EnterMonitor, since qemuMigrationSetOffline already does that */
3380 3381
    if (!(flags & VIR_MIGRATE_LIVE) &&
        virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
3382
        if (qemuMigrationSrcSetOffline(driver, vm) < 0)
3383
            goto error;
3384 3385
    }

3386 3387
    if (qemuDomainObjEnterMonitorAsync(driver, vm,
                                       QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
3388
        goto error;
3389

3390
    if (priv->job.abortJob) {
3391 3392
        /* explicitly do this *after* we entered the monitor,
         * as this is a critical section so we are guaranteed
3393
         * priv->job.abortJob will not change */
3394
        priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
3395 3396 3397
        virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
                       qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
                       _("canceled by client"));
3398
        goto exit_monitor;
3399 3400
    }

3401 3402
    if (qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0)
        goto exit_monitor;
3403

3404 3405
    /* connect to the destination qemu if needed */
    if (spec->destType == MIGRATION_DEST_CONNECT_HOST &&
3406
        qemuMigrationSrcConnect(driver, vm, spec) < 0) {
3407
        goto exit_monitor;
3408
    }
3409

3410 3411 3412 3413 3414 3415
    /* log start of migration */
    if ((timestamp = virTimeStringNow()) != NULL) {
        qemuDomainLogAppendMessage(driver, vm, "%s: initiating migration\n", timestamp);
        VIR_FREE(timestamp);
    }

3416
    rc = -1;
3417 3418
    switch (spec->destType) {
    case MIGRATION_DEST_HOST:
M
Michael R. Hines 已提交
3419 3420
        if (STREQ(spec->dest.host.protocol, "rdma") &&
            virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) {
3421
            goto exit_monitor;
M
Michael R. Hines 已提交
3422
        }
3423 3424 3425 3426
        rc = qemuMonitorMigrateToHost(priv->mon, migrate_flags,
                                      spec->dest.host.protocol,
                                      spec->dest.host.name,
                                      spec->dest.host.port);
3427 3428
        break;

3429 3430 3431 3432
    case MIGRATION_DEST_CONNECT_HOST:
        /* handled above and transformed into MIGRATION_DEST_FD */
        break;

3433
    case MIGRATION_DEST_FD:
3434
        if (spec->fwdType != MIGRATION_FWD_DIRECT) {
3435
            fd = spec->dest.fd.local;
3436 3437
            spec->dest.fd.local = -1;
        }
3438 3439
        rc = qemuMonitorMigrateToFd(priv->mon, migrate_flags,
                                    spec->dest.fd.qemu);
3440 3441
        VIR_FORCE_CLOSE(spec->dest.fd.qemu);
        break;
3442
    }
3443 3444

    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
3445
        goto error;
3446 3447 3448

    /* From this point onwards we *must* call cancel to abort the
     * migration on source if anything goes wrong */
3449
    cancel = true;
3450

3451
    if (spec->fwdType != MIGRATION_FWD_DIRECT) {
3452
        if (!(iothread = qemuMigrationSrcStartTunnel(spec->fwd.stream, fd)))
3453
            goto error;
3454 3455 3456 3457 3458
        /* If we've created a tunnel, then the 'fd' will be closed in the
         * qemuMigrationIOFunc as data->sock.
         */
        fd = -1;
    }
3459

3460
    waitFlags = QEMU_MIGRATION_COMPLETED_PRE_SWITCHOVER;
3461 3462 3463 3464 3465 3466 3467
    if (abort_on_error)
        waitFlags |= QEMU_MIGRATION_COMPLETED_ABORT_ON_ERROR;
    if (mig->nbd)
        waitFlags |= QEMU_MIGRATION_COMPLETED_CHECK_STORAGE;
    if (flags & VIR_MIGRATE_POSTCOPY)
        waitFlags |= QEMU_MIGRATION_COMPLETED_POSTCOPY;

3468 3469 3470
    rc = qemuMigrationSrcWaitForCompletion(driver, vm,
                                           QEMU_ASYNC_JOB_MIGRATION_OUT,
                                           dconn, waitFlags);
3471
    if (rc == -2) {
3472
        goto error;
3473 3474 3475 3476 3477
    } else if (rc == -1) {
        /* QEMU reported failed migration, nothing to cancel anymore */
        cancel = false;
        goto error;
    }
3478

3479 3480 3481
    /* When migration completed, QEMU will have paused the CPUs for us.
     * Wait for the STOP event to be processed or explicitly stop CPUs
     * (for old QEMU which does not send events) to release the lock state.
3482
     */
3483 3484 3485 3486 3487
    if (priv->monJSON) {
        while (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
            priv->signalStop = true;
            rc = virDomainObjWait(vm);
            priv->signalStop = false;
3488
            if (rc < 0)
3489
                goto error;
3490
        }
3491
    } else if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING &&
3492
               qemuMigrationSrcSetOffline(driver, vm) < 0) {
3493
        goto error;
3494
    }
3495

J
Ján Tomko 已提交
3496
    if (mig->nbd &&
3497 3498 3499
        qemuMigrationSrcCancelDriveMirror(driver, vm, true,
                                          QEMU_ASYNC_JOB_MIGRATION_OUT,
                                          dconn) < 0)
3500
        goto error;
3501

3502 3503 3504 3505 3506
    /* When migration was paused before serializing device state we need to
     * resume it now once we finished all block jobs and wait for the real
     * end of the migration.
     */
    if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_PAUSED) {
3507 3508 3509
        if (qemuMigrationSrcContinue(driver, vm,
                                     QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER,
                                     QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
3510 3511 3512 3513
            goto error;

        waitFlags ^= QEMU_MIGRATION_COMPLETED_PRE_SWITCHOVER;

3514 3515 3516
        rc = qemuMigrationSrcWaitForCompletion(driver, vm,
                                               QEMU_ASYNC_JOB_MIGRATION_OUT,
                                               dconn, waitFlags);
3517 3518 3519 3520 3521 3522 3523 3524 3525
        if (rc == -2) {
            goto error;
        } else if (rc == -1) {
            /* QEMU reported failed migration, nothing to cancel anymore */
            cancel = false;
            goto error;
        }
    }

3526 3527 3528 3529
    if (iothread) {
        qemuMigrationIOThreadPtr io;

        VIR_STEAL_PTR(io, iothread);
3530
        if (qemuMigrationSrcStopTunnel(io, false) < 0)
3531
            goto error;
3532 3533 3534
    }

    if (priv->job.completed) {
3535
        priv->job.completed->stopped = priv->job.current->stopped;
3536 3537 3538 3539 3540 3541 3542 3543 3544
        qemuDomainJobInfoUpdateTime(priv->job.completed);
        qemuDomainJobInfoUpdateDowntime(priv->job.completed);
        ignore_value(virTimeMillisNow(&priv->job.completed->sent));
    }

    cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK |
                   QEMU_MIGRATION_COOKIE_STATS;

    if (qemuMigrationCookieAddPersistent(mig, &persistDef) < 0 ||
3545 3546 3547
        qemuMigrationBakeCookie(mig, driver, vm,
                                QEMU_MIGRATION_SOURCE,
                                cookieout, cookieoutlen, cookieFlags) < 0) {
3548 3549
        VIR_WARN("Unable to encode migration cookie");
    }
3550

3551
    ret = 0;
3552

3553
 cleanup:
3554 3555
    VIR_FREE(tlsAlias);
    VIR_FREE(secAlias);
3556
    VIR_FORCE_CLOSE(fd);
3557
    virDomainDefFree(persistDef);
3558 3559
    qemuMigrationCookieFree(mig);

3560 3561 3562
    if (events)
        priv->signalIOError = false;

3563 3564 3565 3566 3567
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }

3568 3569
    return ret;

3570
 error:
3571 3572
    orig_err = virSaveLastError();

3573 3574 3575 3576 3577 3578 3579 3580
    if (virDomainObjIsActive(vm)) {
        if (cancel &&
            priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED &&
            qemuDomainObjEnterMonitorAsync(driver, vm,
                                           QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
            qemuMonitorMigrateCancel(priv->mon);
            ignore_value(qemuDomainObjExitMonitor(driver, vm));
        }
3581

3582 3583 3584 3585 3586 3587 3588 3589 3590
        /* cancel any outstanding NBD jobs */
        if (mig && mig->nbd)
            qemuMigrationSrcCancelDriveMirror(driver, vm, false,
                                              QEMU_ASYNC_JOB_MIGRATION_OUT,
                                              dconn);

        if (priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_CANCELED)
            priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
    }
3591 3592

    if (iothread)
3593
        qemuMigrationSrcStopTunnel(iothread, true);
3594 3595 3596

    goto cleanup;

3597 3598
 exit_monitor:
    ignore_value(qemuDomainObjExitMonitor(driver, vm));
3599
    goto error;
3600 3601
}

3602
/* Perform migration using QEMU's native migrate support,
3603 3604
 * not encrypted obviously
 */
3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619
static int
qemuMigrationSrcPerformNative(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              const char *persist_xml,
                              const char *uri,
                              const char *cookiein,
                              int cookieinlen,
                              char **cookieout,
                              int *cookieoutlen,
                              unsigned long flags,
                              unsigned long resource,
                              virConnectPtr dconn,
                              const char *graphicsuri,
                              size_t nmigrate_disks,
                              const char **migrate_disks,
3620
                              qemuMigrationParamsPtr migParams)
3621
{
3622
    qemuDomainObjPrivatePtr priv = vm->privateData;
M
Martin Kletzander 已提交
3623
    virURIPtr uribits = NULL;
3624
    int ret = -1;
3625 3626 3627
    qemuMigrationSpec spec;

    VIR_DEBUG("driver=%p, vm=%p, uri=%s, cookiein=%s, cookieinlen=%d, "
3628
              "cookieout=%p, cookieoutlen=%p, flags=0x%lx, resource=%lu, "
3629
              "graphicsuri=%s, nmigrate_disks=%zu migrate_disks=%p",
3630
              driver, vm, uri, NULLSTR(cookiein), cookieinlen,
3631
              cookieout, cookieoutlen, flags, resource,
3632
              NULLSTR(graphicsuri), nmigrate_disks, migrate_disks);
3633

3634
    if (!(uribits = qemuMigrationAnyParseURI(uri, NULL)))
3635 3636
        return -1;

3637 3638 3639 3640 3641 3642 3643
    if (uribits->scheme == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("missing scheme in migration URI: %s"),
                       uri);
        goto cleanup;
    }

M
Michael R. Hines 已提交
3644 3645 3646 3647 3648
    if (STREQ(uribits->scheme, "rdma")) {
        if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_RDMA)) {
            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                           _("outgoing RDMA migration is not supported "
                             "with this QEMU binary"));
3649
            goto cleanup;
M
Michael R. Hines 已提交
3650
        }
3651
        if (!virMemoryLimitIsSet(vm->def->mem.hard_limit)) {
M
Michael R. Hines 已提交
3652 3653 3654
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                           _("cannot start RDMA migration with no memory hard "
                             "limit set"));
3655
            goto cleanup;
M
Michael R. Hines 已提交
3656 3657 3658
        }
    }

3659
    if (STRNEQ(uribits->scheme, "rdma"))
3660 3661
        spec.destType = MIGRATION_DEST_CONNECT_HOST;
    else
3662
        spec.destType = MIGRATION_DEST_HOST;
3663
    spec.dest.host.protocol = uribits->scheme;
3664 3665 3666
    spec.dest.host.name = uribits->server;
    spec.dest.host.port = uribits->port;
    spec.fwdType = MIGRATION_FWD_DIRECT;
3667

3668 3669 3670
    ret = qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookieinlen, cookieout,
                              cookieoutlen, flags, resource, &spec, dconn,
                              graphicsuri, nmigrate_disks, migrate_disks,
3671
                              migParams);
3672 3673 3674 3675

    if (spec.destType == MIGRATION_DEST_FD)
        VIR_FORCE_CLOSE(spec.dest.fd.qemu);

3676
 cleanup:
3677
    virURIFree(uribits);
3678 3679 3680 3681 3682

    return ret;
}


3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697
static int
qemuMigrationSrcPerformTunnel(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              virStreamPtr st,
                              const char *persist_xml,
                              const char *cookiein,
                              int cookieinlen,
                              char **cookieout,
                              int *cookieoutlen,
                              unsigned long flags,
                              unsigned long resource,
                              virConnectPtr dconn,
                              const char *graphicsuri,
                              size_t nmigrate_disks,
                              const char **migrate_disks,
3698
                              qemuMigrationParamsPtr migParams)
3699 3700 3701
{
    int ret = -1;
    qemuMigrationSpec spec;
3702
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
3703
    int fds[2] = { -1, -1 };
3704 3705

    VIR_DEBUG("driver=%p, vm=%p, st=%p, cookiein=%s, cookieinlen=%d, "
3706
              "cookieout=%p, cookieoutlen=%p, flags=0x%lx, resource=%lu, "
3707
              "graphicsuri=%s, nmigrate_disks=%zu, migrate_disks=%p",
3708
              driver, vm, st, NULLSTR(cookiein), cookieinlen,
3709
              cookieout, cookieoutlen, flags, resource,
3710
              NULLSTR(graphicsuri), nmigrate_disks, migrate_disks);
3711 3712 3713 3714

    spec.fwdType = MIGRATION_FWD_STREAM;
    spec.fwd.stream = st;

3715

3716 3717 3718
    spec.destType = MIGRATION_DEST_FD;
    spec.dest.fd.qemu = -1;
    spec.dest.fd.local = -1;
3719

3720 3721 3722 3723 3724
    if (pipe2(fds, O_CLOEXEC) == 0) {
        spec.dest.fd.qemu = fds[1];
        spec.dest.fd.local = fds[0];
    }
    if (spec.dest.fd.qemu == -1 ||
3725 3726
        qemuSecuritySetImageFDLabel(driver->securityManager, vm->def,
                                    spec.dest.fd.qemu) < 0) {
3727 3728 3729
        virReportSystemError(errno, "%s",
                             _("cannot create pipe for tunnelled migration"));
        goto cleanup;
3730 3731
    }

3732 3733 3734
    ret = qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookieinlen,
                              cookieout, cookieoutlen, flags, resource, &spec,
                              dconn, graphicsuri, nmigrate_disks, migrate_disks,
3735
                              migParams);
3736

3737
 cleanup:
3738 3739
    VIR_FORCE_CLOSE(spec.dest.fd.qemu);
    VIR_FORCE_CLOSE(spec.dest.fd.local);
3740

3741
    virObjectUnref(cfg);
3742 3743 3744 3745
    return ret;
}


3746 3747 3748 3749
/* This is essentially a re-impl of virDomainMigrateVersion2
 * from libvirt.c, but running in source libvirtd context,
 * instead of client app context & also adding in tunnel
 * handling */
3750 3751 3752 3753 3754 3755 3756 3757
static int
qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver,
                                  virConnectPtr sconn,
                                  virConnectPtr dconn,
                                  virDomainObjPtr vm,
                                  const char *dconnuri,
                                  unsigned long flags,
                                  const char *dname,
3758 3759
                                  unsigned long resource,
                                  qemuMigrationParamsPtr migParams)
3760 3761 3762
{
    virDomainPtr ddomain = NULL;
    char *uri_out = NULL;
3763
    char *cookie = NULL;
3764 3765 3766
    char *dom_xml = NULL;
    int cookielen = 0, ret;
    virErrorPtr orig_err = NULL;
3767
    bool cancelled;
3768
    virStreamPtr st = NULL;
3769
    unsigned long destflags;
3770

3771
    VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, vm=%p, dconnuri=%s, "
3772
              "flags=0x%lx, dname=%s, resource=%lu",
3773 3774
              driver, sconn, dconn, vm, NULLSTR(dconnuri),
              flags, NULLSTR(dname), resource);
3775

3776 3777 3778 3779 3780
    /* In version 2 of the protocol, the prepare step is slightly
     * different.  We fetch the domain XML of the source domain
     * and pass it to Prepare2.
     */
    if (!(dom_xml = qemuDomainFormatXML(driver, vm,
3781 3782
                                        QEMU_DOMAIN_FORMAT_LIVE_FLAGS |
                                        VIR_DOMAIN_XML_MIGRATABLE)))
3783 3784 3785 3786 3787
        return -1;

    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
        flags |= VIR_MIGRATE_PAUSED;

3788 3789
    destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
                          VIR_MIGRATE_AUTO_CONVERGE);
3790

3791 3792 3793 3794 3795 3796 3797 3798 3799 3800
    VIR_DEBUG("Prepare2 %p", dconn);
    if (flags & VIR_MIGRATE_TUNNELLED) {
        /*
         * Tunnelled Migrate Version 2 does not support cookies
         * due to missing parameters in the prepareTunnel() API.
         */

        if (!(st = virStreamNew(dconn, 0)))
            goto cleanup;

3801
        qemuDomainObjEnterRemote(vm);
3802
        ret = dconn->driver->domainMigratePrepareTunnel
3803
            (dconn, st, destflags, dname, resource, dom_xml);
3804
        qemuDomainObjExitRemote(vm);
3805
    } else {
3806
        qemuDomainObjEnterRemote(vm);
3807 3808
        ret = dconn->driver->domainMigratePrepare2
            (dconn, &cookie, &cookielen, NULL, &uri_out,
3809
             destflags, dname, resource, dom_xml);
3810
        qemuDomainObjExitRemote(vm);
3811 3812 3813
    }
    VIR_FREE(dom_xml);
    if (ret == -1)
3814 3815 3816
        goto cleanup;

    /* the domain may have shutdown or crashed while we had the locks dropped
3817
     * in qemuDomainObjEnterRemote, so check again
3818 3819
     */
    if (!virDomainObjIsActive(vm)) {
3820 3821
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("guest unexpectedly quit"));
3822 3823 3824
        goto cleanup;
    }

3825 3826
    if (!(flags & VIR_MIGRATE_TUNNELLED) &&
        (uri_out == NULL)) {
3827 3828
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("domainMigratePrepare2 did not set uri"));
3829
        cancelled = true;
3830
        orig_err = virSaveLastError();
3831
        goto finish;
3832 3833
    }

3834 3835 3836 3837
    /* Perform the migration.  The driver isn't supposed to return
     * until the migration is complete.
     */
    VIR_DEBUG("Perform %p", sconn);
3838
    qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM2);
3839
    if (flags & VIR_MIGRATE_TUNNELLED)
3840 3841 3842
        ret = qemuMigrationSrcPerformTunnel(driver, vm, st, NULL,
                                            NULL, 0, NULL, NULL,
                                            flags, resource, dconn,
3843
                                            NULL, 0, NULL, migParams);
3844
    else
3845 3846 3847 3848
        ret = qemuMigrationSrcPerformNative(driver, vm, NULL, uri_out,
                                            cookie, cookielen,
                                            NULL, NULL, /* No out cookie with v2 migration */
                                            flags, resource, dconn, NULL, 0, NULL,
3849
                                            migParams);
3850 3851 3852 3853

    /* Perform failed. Make sure Finish doesn't overwrite the error */
    if (ret < 0)
        orig_err = virSaveLastError();
3854

3855 3856 3857
    /* If Perform returns < 0, then we need to cancel the VM
     * startup on the destination
     */
3858
    cancelled = ret < 0;
3859

3860
 finish:
3861 3862 3863 3864
    /* In version 2 of the migration protocol, we pass the
     * status code from the sender to the destination host,
     * so it can do any cleanup if the migration failed.
     */
3865
    dname = dname ? dname : vm->def->name;
3866
    VIR_DEBUG("Finish2 %p ret=%d", dconn, ret);
3867
    qemuDomainObjEnterRemote(vm);
3868
    ddomain = dconn->driver->domainMigrateFinish2
3869
        (dconn, dname, cookie, cookielen,
3870
         uri_out ? uri_out : dconnuri, destflags, cancelled);
3871
    qemuDomainObjExitRemote(vm);
3872 3873
    if (cancelled && ddomain)
        VIR_ERROR(_("finish step ignored that migration was cancelled"));
3874

3875
 cleanup:
3876
    if (ddomain) {
3877
        virObjectUnref(ddomain);
3878 3879 3880 3881
        ret = 0;
    } else {
        ret = -1;
    }
3882

3883
    virObjectUnref(st);
3884 3885 3886 3887 3888 3889

    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
    VIR_FREE(uri_out);
3890
    VIR_FREE(cookie);
3891 3892

    return ret;
3893 3894 3895
}


3896 3897 3898 3899
/* This is essentially a re-impl of virDomainMigrateVersion3
 * from libvirt.c, but running in source libvirtd context,
 * instead of client app context & also adding in tunnel
 * handling */
3900
static int
3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914
qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
                                  virConnectPtr sconn,
                                  virConnectPtr dconn,
                                  const char *dconnuri,
                                  virDomainObjPtr vm,
                                  const char *xmlin,
                                  const char *persist_xml,
                                  const char *dname,
                                  const char *uri,
                                  const char *graphicsuri,
                                  const char *listenAddress,
                                  size_t nmigrate_disks,
                                  const char **migrate_disks,
                                  int nbdPort,
3915
                                  qemuMigrationParamsPtr migParams,
3916 3917 3918
                                  unsigned long long bandwidth,
                                  bool useParams,
                                  unsigned long flags)
3919 3920 3921 3922 3923 3924 3925 3926 3927 3928
{
    virDomainPtr ddomain = NULL;
    char *uri_out = NULL;
    char *cookiein = NULL;
    char *cookieout = NULL;
    char *dom_xml = NULL;
    int cookieinlen = 0;
    int cookieoutlen = 0;
    int ret = -1;
    virErrorPtr orig_err = NULL;
3929
    bool cancelled = true;
3930
    virStreamPtr st = NULL;
3931
    unsigned long destflags;
3932 3933 3934
    virTypedParameterPtr params = NULL;
    int nparams = 0;
    int maxparams = 0;
3935
    size_t i;
3936 3937

    VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, dconnuri=%s, vm=%p, xmlin=%s, "
3938
              "dname=%s, uri=%s, graphicsuri=%s, listenAddress=%s, "
3939
              "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, "
3940
              "bandwidth=%llu, useParams=%d, flags=0x%lx",
3941
              driver, sconn, dconn, NULLSTR(dconnuri), vm, NULLSTR(xmlin),
3942
              NULLSTR(dname), NULLSTR(uri), NULLSTR(graphicsuri),
3943
              NULLSTR(listenAddress), nmigrate_disks, migrate_disks, nbdPort,
3944
              bandwidth, useParams, flags);
3945

3946 3947 3948 3949 3950
    /* Unlike the virDomainMigrateVersion3 counterpart, we don't need
     * to worry about auto-setting the VIR_MIGRATE_CHANGE_PROTECTION
     * bit here, because we are already running inside the context of
     * a single job.  */

3951 3952 3953
    dom_xml = qemuMigrationSrcBeginPhase(driver, vm, xmlin, dname,
                                         &cookieout, &cookieoutlen,
                                         nmigrate_disks, migrate_disks, flags);
3954 3955 3956
    if (!dom_xml)
        goto cleanup;

3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976
    if (useParams) {
        if (virTypedParamsAddString(&params, &nparams, &maxparams,
                                    VIR_MIGRATE_PARAM_DEST_XML, dom_xml) < 0)
            goto cleanup;

        if (dname &&
            virTypedParamsAddString(&params, &nparams, &maxparams,
                                    VIR_MIGRATE_PARAM_DEST_NAME, dname) < 0)
            goto cleanup;

        if (uri &&
            virTypedParamsAddString(&params, &nparams, &maxparams,
                                    VIR_MIGRATE_PARAM_URI, uri) < 0)
            goto cleanup;

        if (bandwidth &&
            virTypedParamsAddULLong(&params, &nparams, &maxparams,
                                    VIR_MIGRATE_PARAM_BANDWIDTH,
                                    bandwidth) < 0)
            goto cleanup;
3977 3978 3979 3980 3981 3982

        if (graphicsuri &&
            virTypedParamsAddString(&params, &nparams, &maxparams,
                                    VIR_MIGRATE_PARAM_GRAPHICS_URI,
                                    graphicsuri) < 0)
            goto cleanup;
3983 3984 3985 3986 3987
        if (listenAddress &&
            virTypedParamsAddString(&params, &nparams, &maxparams,
                                    VIR_MIGRATE_PARAM_LISTEN_ADDRESS,
                                    listenAddress) < 0)
            goto cleanup;
3988 3989 3990 3991 3992
        for (i = 0; i < nmigrate_disks; i++)
            if (virTypedParamsAddString(&params, &nparams, &maxparams,
                                        VIR_MIGRATE_PARAM_MIGRATE_DISKS,
                                        migrate_disks[i]) < 0)
                goto cleanup;
3993 3994 3995 3996 3997
        if (nbdPort &&
            virTypedParamsAddInt(&params, &nparams, &maxparams,
                                 VIR_MIGRATE_PARAM_DISKS_PORT,
                                 nbdPort) < 0)
            goto cleanup;
3998

3999 4000
        if (qemuMigrationParamsDump(migParams, &params, &nparams,
                                    &maxparams, &flags) < 0)
4001
            goto cleanup;
4002 4003
    }

4004 4005 4006
    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
        flags |= VIR_MIGRATE_PAUSED;

4007 4008
    destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
                          VIR_MIGRATE_AUTO_CONVERGE);
4009

4010 4011 4012 4013 4014 4015 4016 4017 4018
    VIR_DEBUG("Prepare3 %p", dconn);
    cookiein = cookieout;
    cookieinlen = cookieoutlen;
    cookieout = NULL;
    cookieoutlen = 0;
    if (flags & VIR_MIGRATE_TUNNELLED) {
        if (!(st = virStreamNew(dconn, 0)))
            goto cleanup;

4019
        qemuDomainObjEnterRemote(vm);
4020 4021 4022 4023 4024 4025 4026 4027 4028
        if (useParams) {
            ret = dconn->driver->domainMigratePrepareTunnel3Params
                (dconn, st, params, nparams, cookiein, cookieinlen,
                 &cookieout, &cookieoutlen, destflags);
        } else {
            ret = dconn->driver->domainMigratePrepareTunnel3
                (dconn, st, cookiein, cookieinlen, &cookieout, &cookieoutlen,
                 destflags, dname, bandwidth, dom_xml);
        }
4029
        qemuDomainObjExitRemote(vm);
4030
    } else {
4031
        qemuDomainObjEnterRemote(vm);
4032 4033 4034 4035 4036 4037 4038 4039 4040
        if (useParams) {
            ret = dconn->driver->domainMigratePrepare3Params
                (dconn, params, nparams, cookiein, cookieinlen,
                 &cookieout, &cookieoutlen, &uri_out, destflags);
        } else {
            ret = dconn->driver->domainMigratePrepare3
                (dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
                 uri, &uri_out, destflags, dname, bandwidth, dom_xml);
        }
4041
        qemuDomainObjExitRemote(vm);
4042 4043 4044 4045 4046
    }
    VIR_FREE(dom_xml);
    if (ret == -1)
        goto cleanup;

L
liguang 已提交
4047 4048 4049 4050
    if (flags & VIR_MIGRATE_OFFLINE) {
        VIR_DEBUG("Offline migration, skipping Perform phase");
        VIR_FREE(cookieout);
        cookieoutlen = 0;
4051
        cancelled = false;
L
liguang 已提交
4052 4053 4054
        goto finish;
    }

4055 4056 4057 4058
    if (uri_out) {
        uri = uri_out;
        if (useParams &&
            virTypedParamsReplaceString(&params, &nparams,
4059 4060
                                        VIR_MIGRATE_PARAM_URI, uri_out) < 0) {
            orig_err = virSaveLastError();
4061
            goto finish;
4062
        }
4063
    } else if (!uri && !(flags & VIR_MIGRATE_TUNNELLED)) {
4064 4065
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("domainMigratePrepare3 did not set uri"));
4066
        orig_err = virSaveLastError();
4067 4068 4069 4070 4071 4072 4073 4074
        goto finish;
    }

    /* Perform the migration.  The driver isn't supposed to return
     * until the migration is complete. The src VM should remain
     * running, but in paused state until the destination can
     * confirm migration completion.
     */
4075
    VIR_DEBUG("Perform3 %p uri=%s", sconn, NULLSTR(uri));
4076
    qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM3);
4077 4078 4079 4080 4081
    VIR_FREE(cookiein);
    cookiein = cookieout;
    cookieinlen = cookieoutlen;
    cookieout = NULL;
    cookieoutlen = 0;
4082
    if (flags & VIR_MIGRATE_TUNNELLED) {
4083 4084 4085 4086
        ret = qemuMigrationSrcPerformTunnel(driver, vm, st, persist_xml,
                                            cookiein, cookieinlen,
                                            &cookieout, &cookieoutlen,
                                            flags, bandwidth, dconn, graphicsuri,
4087
                                            nmigrate_disks, migrate_disks,
4088
                                            migParams);
4089
    } else {
4090 4091 4092 4093
        ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri,
                                            cookiein, cookieinlen,
                                            &cookieout, &cookieoutlen,
                                            flags, bandwidth, dconn, graphicsuri,
4094
                                            nmigrate_disks, migrate_disks,
4095
                                            migParams);
4096
    }
4097 4098

    /* Perform failed. Make sure Finish doesn't overwrite the error */
4099
    if (ret < 0) {
4100
        orig_err = virSaveLastError();
4101 4102 4103 4104
    } else {
        qemuMigrationJobSetPhase(driver, vm,
                                 QEMU_MIGRATION_PHASE_PERFORM3_DONE);
    }
4105 4106 4107 4108

    /* If Perform returns < 0, then we need to cancel the VM
     * startup on the destination
     */
4109
    cancelled = ret < 0;
4110

4111
 finish:
4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123
    /*
     * The status code from the source is passed to the destination.
     * The dest can cleanup in the source indicated it failed to
     * send all migration data. Returns NULL for ddomain if
     * the dest was unable to complete migration.
     */
    VIR_DEBUG("Finish3 %p ret=%d", dconn, ret);
    VIR_FREE(cookiein);
    cookiein = cookieout;
    cookieinlen = cookieoutlen;
    cookieout = NULL;
    cookieoutlen = 0;
4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146

    if (useParams) {
        if (virTypedParamsGetString(params, nparams,
                                    VIR_MIGRATE_PARAM_DEST_NAME, NULL) <= 0 &&
            virTypedParamsReplaceString(&params, &nparams,
                                        VIR_MIGRATE_PARAM_DEST_NAME,
                                        vm->def->name) < 0) {
            ddomain = NULL;
        } else {
            qemuDomainObjEnterRemote(vm);
            ddomain = dconn->driver->domainMigrateFinish3Params
                (dconn, params, nparams, cookiein, cookieinlen,
                 &cookieout, &cookieoutlen, destflags, cancelled);
            qemuDomainObjExitRemote(vm);
        }
    } else {
        dname = dname ? dname : vm->def->name;
        qemuDomainObjEnterRemote(vm);
        ddomain = dconn->driver->domainMigrateFinish3
            (dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
             dconnuri, uri, destflags, cancelled);
        qemuDomainObjExitRemote(vm);
    }
4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166

    if (cancelled) {
        if (ddomain) {
            VIR_ERROR(_("finish step ignored that migration was cancelled"));
        } else {
            /* If Finish reported a useful error, use it instead of the
             * original "migration unexpectedly failed" error.
             *
             * This is ugly but we can't do better with the APIs we have. We
             * only replace the error if Finish was called with cancelled == 1
             * and reported a real error (old libvirt would report an error
             * from RPC instead of MIGRATE_FINISH_OK), which only happens when
             * the domain died on destination. To further reduce a possibility
             * of false positives we also check that Perform returned
             * VIR_ERR_OPERATION_FAILED.
             */
            if (orig_err &&
                orig_err->domain == VIR_FROM_QEMU &&
                orig_err->code == VIR_ERR_OPERATION_FAILED) {
                virErrorPtr err = virGetLastError();
4167 4168
                if (err &&
                    err->domain == VIR_FROM_QEMU &&
4169 4170 4171 4172 4173 4174 4175
                    err->code != VIR_ERR_MIGRATE_FINISH_OK) {
                    virFreeError(orig_err);
                    orig_err = NULL;
                }
            }
        }
    }
4176

4177 4178 4179 4180 4181 4182 4183
    /* If ddomain is NULL, then we were unable to start
     * the guest on the target, and must restart on the
     * source. There is a small chance that the ddomain
     * is NULL due to an RPC failure, in which case
     * ddomain could in fact be running on the dest.
     * The lock manager plugins should take care of
     * safety in this scenario.
4184
     */
4185
    cancelled = ddomain == NULL;
4186

4187 4188 4189 4190 4191 4192
    /* If finish3 set an error, and we don't have an earlier
     * one we need to preserve it in case confirm3 overwrites
     */
    if (!orig_err)
        orig_err = virSaveLastError();

4193 4194 4195 4196
    /*
     * If cancelled, then src VM will be restarted, else
     * it will be killed
     */
4197
    VIR_DEBUG("Confirm3 %p cancelled=%d vm=%p", sconn, cancelled, vm);
4198 4199 4200 4201 4202
    VIR_FREE(cookiein);
    cookiein = cookieout;
    cookieinlen = cookieoutlen;
    cookieout = NULL;
    cookieoutlen = 0;
4203 4204 4205
    ret = qemuMigrationSrcConfirmPhase(driver, vm,
                                       cookiein, cookieinlen,
                                       flags, cancelled);
4206 4207 4208 4209
    /* If Confirm3 returns -1, there's nothing more we can
     * do, but fortunately worst case is that there is a
     * domain left in 'paused' state on source.
     */
4210 4211 4212
    if (ret < 0)
        VIR_WARN("Guest %s probably left in 'paused' state on source",
                 vm->def->name);
4213 4214 4215

 cleanup:
    if (ddomain) {
4216
        virObjectUnref(ddomain);
4217 4218 4219 4220 4221
        ret = 0;
    } else {
        ret = -1;
    }

4222
    virObjectUnref(st);
4223 4224 4225 4226 4227 4228 4229 4230

    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
    VIR_FREE(uri_out);
    VIR_FREE(cookiein);
    VIR_FREE(cookieout);
4231
    virTypedParamsFree(params, nparams);
4232 4233 4234 4235
    return ret;
}


4236
static void
4237 4238 4239
qemuMigrationSrcConnectionClosed(virConnectPtr conn,
                                 int reason,
                                 void *opaque)
4240 4241 4242 4243 4244 4245 4246 4247
{
    virDomainObjPtr vm = opaque;

    VIR_DEBUG("conn=%p, reason=%d, vm=%s", conn, reason, vm->def->name);
    virDomainObjBroadcast(vm);
}


4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259
static int virConnectCredType[] = {
    VIR_CRED_AUTHNAME,
    VIR_CRED_PASSPHRASE,
};


static virConnectAuth virConnectAuthConfig = {
    .credtype = virConnectCredType,
    .ncredtype = ARRAY_CARDINALITY(virConnectCredType),
};


4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272
static int
qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
                                 virConnectPtr sconn,
                                 virDomainObjPtr vm,
                                 const char *xmlin,
                                 const char *persist_xml,
                                 const char *dconnuri,
                                 const char *uri,
                                 const char *graphicsuri,
                                 const char *listenAddress,
                                 size_t nmigrate_disks,
                                 const char **migrate_disks,
                                 int nbdPort,
4273
                                 qemuMigrationParamsPtr migParams,
4274 4275 4276 4277
                                 unsigned long flags,
                                 const char *dname,
                                 unsigned long resource,
                                 bool *v3proto)
4278 4279 4280 4281
{
    int ret = -1;
    virConnectPtr dconn = NULL;
    bool p2p;
4282
    virErrorPtr orig_err = NULL;
4283
    bool offline = false;
4284
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4285
    bool useParams;
4286

4287 4288
    VIR_DEBUG("driver=%p, sconn=%p, vm=%p, xmlin=%s, dconnuri=%s, uri=%s, "
              "graphicsuri=%s, listenAddress=%s, nmigrate_disks=%zu, "
4289
              "migrate_disks=%p, nbdPort=%d, flags=0x%lx, dname=%s, "
4290
              "resource=%lu",
4291
              driver, sconn, vm, NULLSTR(xmlin), NULLSTR(dconnuri),
4292
              NULLSTR(uri), NULLSTR(graphicsuri), NULLSTR(listenAddress),
4293 4294
              nmigrate_disks, migrate_disks, nbdPort, flags, NULLSTR(dname),
              resource);
4295

4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309
    if (flags & VIR_MIGRATE_TUNNELLED && uri) {
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("migration URI is not supported by tunnelled "
                         "migration"));
        goto cleanup;
    }

    if (flags & VIR_MIGRATE_TUNNELLED && listenAddress) {
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("listen address is not supported by tunnelled "
                         "migration"));
        goto cleanup;
    }

4310 4311 4312 4313 4314 4315 4316
    if (flags & VIR_MIGRATE_TUNNELLED && nbdPort) {
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("disk port address is not supported by tunnelled "
                         "migration"));
        goto cleanup;
    }

4317 4318 4319 4320
    /* the order of operations is important here; we make sure the
     * destination side is completely setup before we touch the source
     */

4321
    qemuDomainObjEnterRemote(vm);
4322
    dconn = virConnectOpenAuth(dconnuri, &virConnectAuthConfig, 0);
4323
    qemuDomainObjExitRemote(vm);
4324
    if (dconn == NULL) {
4325
        virReportError(VIR_ERR_OPERATION_FAILED,
4326 4327
                       _("Failed to connect to remote libvirt URI %s: %s"),
                       dconnuri, virGetLastErrorMessage());
4328
        virObjectUnref(cfg);
4329 4330 4331
        return -1;
    }

4332 4333
    if (virConnectSetKeepAlive(dconn, cfg->keepAliveInterval,
                               cfg->keepAliveCount) < 0)
4334 4335
        goto cleanup;

4336
    if (virConnectRegisterCloseCallback(dconn, qemuMigrationSrcConnectionClosed,
4337 4338 4339 4340
                                        vm, NULL) < 0) {
        goto cleanup;
    }

4341
    qemuDomainObjEnterRemote(vm);
4342 4343
    p2p = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                   VIR_DRV_FEATURE_MIGRATION_P2P);
4344
        /* v3proto reflects whether the caller used Perform3, but with
4345
         * p2p migrate, regardless of whether Perform2 or Perform3
4346 4347 4348 4349
         * were used, we decide protocol based on what target supports
         */
    *v3proto = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                        VIR_DRV_FEATURE_MIGRATION_V3);
4350 4351
    useParams = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                         VIR_DRV_FEATURE_MIGRATION_PARAMS);
L
liguang 已提交
4352 4353 4354
    if (flags & VIR_MIGRATE_OFFLINE)
        offline = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                           VIR_DRV_FEATURE_MIGRATION_OFFLINE);
4355
    qemuDomainObjExitRemote(vm);
4356

4357
    if (!p2p) {
4358 4359
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                       _("Destination libvirt does not support peer-to-peer migration protocol"));
4360 4361 4362
        goto cleanup;
    }

4363 4364
    /* Only xmlin, dname, uri, and bandwidth parameters can be used with
     * old-style APIs. */
4365
    if (!useParams && (graphicsuri || listenAddress || nmigrate_disks)) {
4366 4367 4368 4369 4370 4371
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("Migration APIs with extensible parameters are not "
                         "supported but extended parameters were passed"));
        goto cleanup;
    }

L
liguang 已提交
4372 4373 4374 4375 4376 4377 4378
    if (flags & VIR_MIGRATE_OFFLINE && !offline) {
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("offline migration is not supported by "
                         "the destination host"));
        goto cleanup;
    }

4379
    /* domain may have been stopped while we were talking to remote daemon */
L
liguang 已提交
4380
    if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) {
4381 4382
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("guest unexpectedly quit"));
4383 4384 4385
        goto cleanup;
    }

4386 4387 4388 4389 4390 4391 4392
    /* Change protection is only required on the source side (us), and
     * only for v3 migration when begin and perform are separate jobs.
     * But peer-2-peer is already a single job, and we still want to
     * talk to older destinations that would reject the flag.
     * Therefore it is safe to clear the bit here.  */
    flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;

4393
    if (*v3proto) {
4394 4395 4396
        ret = qemuMigrationSrcPerformPeer2Peer3(driver, sconn, dconn, dconnuri, vm, xmlin,
                                                persist_xml, dname, uri, graphicsuri,
                                                listenAddress, nmigrate_disks, migrate_disks,
4397
                                                nbdPort, migParams, resource,
4398
                                                useParams, flags);
4399
    } else {
4400
        ret = qemuMigrationSrcPerformPeer2Peer2(driver, sconn, dconn, vm,
4401
                                                dconnuri, flags, dname, resource,
4402
                                                migParams);
4403
    }
4404

4405
 cleanup:
4406
    orig_err = virSaveLastError();
4407
    qemuDomainObjEnterRemote(vm);
4408
    virConnectUnregisterCloseCallback(dconn, qemuMigrationSrcConnectionClosed);
4409
    virObjectUnref(dconn);
4410
    qemuDomainObjExitRemote(vm);
4411 4412 4413 4414
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
4415
    virObjectUnref(cfg);
4416 4417 4418 4419
    return ret;
}


4420 4421 4422 4423 4424 4425
/*
 * This implements perform part of the migration protocol when migration job
 * does not need to be active across several APIs, i.e., peer2peer migration or
 * perform phase of v2 non-peer2peer migration.
 */
static int
4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437
qemuMigrationSrcPerformJob(virQEMUDriverPtr driver,
                           virConnectPtr conn,
                           virDomainObjPtr vm,
                           const char *xmlin,
                           const char *persist_xml,
                           const char *dconnuri,
                           const char *uri,
                           const char *graphicsuri,
                           const char *listenAddress,
                           size_t nmigrate_disks,
                           const char **migrate_disks,
                           int nbdPort,
4438
                           qemuMigrationParamsPtr migParams,
4439 4440 4441 4442 4443 4444 4445 4446
                           const char *cookiein,
                           int cookieinlen,
                           char **cookieout,
                           int *cookieoutlen,
                           unsigned long flags,
                           const char *dname,
                           unsigned long resource,
                           bool v3proto)
4447
{
4448
    virObjectEventPtr event = NULL;
4449
    int ret = -1;
4450
    virErrorPtr orig_err = NULL;
4451
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4452
    qemuDomainObjPrivatePtr priv = vm->privateData;
4453

4454 4455
    if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
                              flags) < 0)
4456 4457
        goto cleanup;

L
liguang 已提交
4458
    if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) {
4459 4460
        virReportError(VIR_ERR_OPERATION_INVALID,
                       "%s", _("domain is not running"));
4461 4462 4463
        goto endjob;
    }

4464
    if (!qemuMigrationSrcIsAllowed(driver, vm, true, flags))
4465
        goto endjob;
4466

4467
    if (!(flags & (VIR_MIGRATE_UNSAFE | VIR_MIGRATE_OFFLINE)) &&
4468
        !qemuMigrationSrcIsSafe(vm->def, nmigrate_disks, migrate_disks, flags))
4469
        goto endjob;
4470

4471
    qemuMigrationSrcStoreDomainState(vm);
4472 4473

    if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) {
4474 4475 4476
        ret = qemuMigrationSrcPerformPeer2Peer(driver, conn, vm, xmlin, persist_xml,
                                               dconnuri, uri, graphicsuri, listenAddress,
                                               nmigrate_disks, migrate_disks, nbdPort,
4477
                                               migParams, flags, dname, resource,
4478
                                               &v3proto);
4479
    } else {
4480
        qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM2);
4481 4482 4483
        ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen,
                                            cookieout, cookieoutlen,
                                            flags, resource, NULL, NULL, 0, NULL,
4484
                                            migParams);
4485
    }
4486 4487
    if (ret < 0)
        goto endjob;
4488

4489 4490 4491 4492
    /*
     * In v3 protocol, the source VM is not killed off until the
     * confirm step.
     */
4493
    if (!v3proto) {
4494
        qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_MIGRATED,
4495
                        QEMU_ASYNC_JOB_MIGRATION_OUT,
4496
                        VIR_QEMU_PROCESS_STOP_MIGRATED);
4497
        virDomainAuditStop(vm, "migrated");
4498
        event = virDomainEventLifecycleNewFromObj(vm,
4499 4500
                                         VIR_DOMAIN_EVENT_STOPPED,
                                         VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
4501 4502
    }

4503
 endjob:
4504 4505 4506
    if (ret < 0)
        orig_err = virSaveLastError();

4507 4508 4509 4510
    /* v2 proto has no confirm phase so we need to reset migration parameters
     * here
     */
    if (!v3proto && ret < 0)
4511
        qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
4512
                                 priv->job.migParams, priv->job.apiFlags);
4513

4514
    if (qemuMigrationSrcRestoreDomainState(driver, vm)) {
4515
        event = virDomainEventLifecycleNewFromObj(vm,
4516 4517 4518
                                         VIR_DOMAIN_EVENT_RESUMED,
                                         VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
    }
4519

4520
    qemuMigrationJobFinish(driver, vm);
4521
    if (!virDomainObjIsActive(vm) && ret == 0) {
4522
        if (flags & VIR_MIGRATE_UNDEFINE_SOURCE) {
4523
            virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
4524 4525
            vm->persistent = 0;
        }
4526
        qemuDomainRemoveInactiveJob(driver, vm);
4527 4528
    }

4529 4530 4531 4532 4533
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }

4534
 cleanup:
M
Michal Privoznik 已提交
4535
    virDomainObjEndAPI(&vm);
4536
    qemuDomainEventQueue(driver, event);
4537
    virObjectUnref(cfg);
4538 4539 4540 4541 4542 4543 4544
    return ret;
}

/*
 * This implements perform phase of v3 migration protocol.
 */
static int
4545 4546 4547 4548 4549 4550 4551 4552
qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver,
                             virConnectPtr conn,
                             virDomainObjPtr vm,
                             const char *persist_xml,
                             const char *uri,
                             const char *graphicsuri,
                             size_t nmigrate_disks,
                             const char **migrate_disks,
4553
                             qemuMigrationParamsPtr migParams,
4554 4555 4556 4557 4558 4559
                             const char *cookiein,
                             int cookieinlen,
                             char **cookieout,
                             int *cookieoutlen,
                             unsigned long flags,
                             unsigned long resource)
4560
{
4561
    qemuDomainObjPrivatePtr priv = vm->privateData;
4562
    virObjectEventPtr event = NULL;
4563 4564 4565 4566
    int ret = -1;

    /* If we didn't start the job in the begin phase, start it now. */
    if (!(flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
4567 4568
        if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
                                  flags) < 0)
4569 4570 4571 4572 4573 4574
            goto cleanup;
    } else if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT)) {
        goto cleanup;
    }

    qemuMigrationJobStartPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM3);
4575
    virCloseCallbacksUnset(driver->closeCallbacks, vm,
4576
                           qemuMigrationSrcCleanup);
4577

4578 4579 4580
    ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen,
                                        cookieout, cookieoutlen,
                                        flags, resource, NULL, graphicsuri,
4581
                                        nmigrate_disks, migrate_disks, migParams);
4582

4583
    if (ret < 0) {
4584
        if (qemuMigrationSrcRestoreDomainState(driver, vm)) {
4585 4586 4587
            event = virDomainEventLifecycleNewFromObj(vm,
                                                      VIR_DOMAIN_EVENT_RESUMED,
                                                      VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
4588
        }
4589
        goto endjob;
4590
    }
4591 4592 4593

    qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM3_DONE);

4594
    if (virCloseCallbacksSet(driver->closeCallbacks, vm, conn,
4595
                             qemuMigrationSrcCleanup) < 0)
4596 4597
        goto endjob;

4598
 endjob:
4599
    if (ret < 0) {
4600
        qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
4601
                                 priv->job.migParams, priv->job.apiFlags);
4602
        qemuMigrationJobFinish(driver, vm);
4603
    } else {
4604
        qemuMigrationJobContinue(vm);
4605 4606
    }

4607
    if (!virDomainObjIsActive(vm))
4608
        qemuDomainRemoveInactiveJob(driver, vm);
4609

4610
 cleanup:
M
Michal Privoznik 已提交
4611
    virDomainObjEndAPI(&vm);
4612
    qemuDomainEventQueue(driver, event);
4613 4614 4615
    return ret;
}

4616
int
4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628
qemuMigrationSrcPerform(virQEMUDriverPtr driver,
                        virConnectPtr conn,
                        virDomainObjPtr vm,
                        const char *xmlin,
                        const char *persist_xml,
                        const char *dconnuri,
                        const char *uri,
                        const char *graphicsuri,
                        const char *listenAddress,
                        size_t nmigrate_disks,
                        const char **migrate_disks,
                        int nbdPort,
4629
                        qemuMigrationParamsPtr migParams,
4630 4631 4632 4633 4634 4635 4636 4637
                        const char *cookiein,
                        int cookieinlen,
                        char **cookieout,
                        int *cookieoutlen,
                        unsigned long flags,
                        const char *dname,
                        unsigned long resource,
                        bool v3proto)
4638 4639
{
    VIR_DEBUG("driver=%p, conn=%p, vm=%p, xmlin=%s, dconnuri=%s, "
4640
              "uri=%s, graphicsuri=%s, listenAddress=%s, "
4641
              "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, "
4642
              "cookiein=%s, cookieinlen=%d, cookieout=%p, cookieoutlen=%p, "
4643
              "flags=0x%lx, dname=%s, resource=%lu, v3proto=%d",
4644
              driver, conn, vm, NULLSTR(xmlin), NULLSTR(dconnuri),
4645
              NULLSTR(uri), NULLSTR(graphicsuri), NULLSTR(listenAddress),
4646 4647 4648
              nmigrate_disks, migrate_disks, nbdPort,
              NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen,
              flags, NULLSTR(dname), resource, v3proto);
4649 4650 4651

    if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) {
        if (cookieinlen) {
4652 4653
            virReportError(VIR_ERR_OPERATION_INVALID,
                           "%s", _("received unexpected cookie with P2P migration"));
4654 4655 4656
            return -1;
        }

4657 4658 4659
        return qemuMigrationSrcPerformJob(driver, conn, vm, xmlin, persist_xml, dconnuri, uri,
                                          graphicsuri, listenAddress,
                                          nmigrate_disks, migrate_disks, nbdPort,
4660
                                          migParams,
4661 4662 4663
                                          cookiein, cookieinlen,
                                          cookieout, cookieoutlen,
                                          flags, dname, resource, v3proto);
4664 4665
    } else {
        if (dconnuri) {
4666 4667
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("Unexpected dconnuri parameter with non-peer2peer migration"));
4668 4669 4670 4671
            return -1;
        }

        if (v3proto) {
4672 4673 4674
            return qemuMigrationSrcPerformPhase(driver, conn, vm, persist_xml, uri,
                                                graphicsuri,
                                                nmigrate_disks, migrate_disks,
4675
                                                migParams,
4676 4677 4678
                                                cookiein, cookieinlen,
                                                cookieout, cookieoutlen,
                                                flags, resource);
4679
        } else {
4680 4681 4682
            return qemuMigrationSrcPerformJob(driver, conn, vm, xmlin, persist_xml, NULL,
                                              uri, graphicsuri, listenAddress,
                                              nmigrate_disks, migrate_disks, nbdPort,
4683
                                              migParams,
4684 4685 4686
                                              cookiein, cookieinlen,
                                              cookieout, cookieoutlen, flags,
                                              dname, resource, v3proto);
4687 4688 4689
        }
    }
}
4690

4691
static int
4692
qemuMigrationDstVPAssociatePortProfiles(virDomainDefPtr def)
4693
{
4694
    size_t i;
4695 4696 4697 4698 4699
    int last_good_net = -1;
    virDomainNetDefPtr net;

    for (i = 0; i < def->nnets; i++) {
        net = def->nets[i];
4700
        if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
4701
            if (virNetDevVPortProfileAssociate(net->ifname,
4702
                                               virDomainNetGetActualVirtPortProfile(net),
4703
                                               &net->mac,
4704
                                               virDomainNetGetActualDirectDev(net),
4705
                                               -1,
4706
                                               def->uuid,
4707 4708
                                               VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH,
                                               false) < 0) {
4709 4710 4711
                virReportError(VIR_ERR_OPERATION_FAILED,
                               _("Port profile Associate failed for %s"),
                               net->ifname);
4712
                goto err_exit;
4713
            }
4714
            last_good_net = i;
4715
            VIR_DEBUG("Port profile Associate succeeded for %s", net->ifname);
4716

4717
            if (virNetDevMacVLanVPortProfileRegisterCallback(net->ifname, &net->mac,
4718 4719 4720 4721
                                                             virDomainNetGetActualDirectDev(net), def->uuid,
                                                             virDomainNetGetActualVirtPortProfile(net),
                                                             VIR_NETDEV_VPORT_PROFILE_OP_CREATE))
                goto err_exit;
4722 4723 4724
        }
    }

4725
    return 0;
4726

4727
 err_exit:
4728
    for (i = 0; last_good_net != -1 && i <= last_good_net; i++) {
4729
        net = def->nets[i];
4730
        if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
4731
            ignore_value(virNetDevVPortProfileDisassociate(net->ifname,
4732
                                                           virDomainNetGetActualVirtPortProfile(net),
4733
                                                           &net->mac,
4734
                                                           virDomainNetGetActualDirectDev(net),
4735
                                                           -1,
4736
                                                           VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH));
4737 4738
        }
    }
4739
    return -1;
4740 4741 4742
}


J
Jiri Denemark 已提交
4743
static int
4744 4745 4746 4747
qemuMigrationDstPersist(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
                        qemuMigrationCookiePtr mig,
                        bool ignoreSaveError)
J
Jiri Denemark 已提交
4748 4749 4750 4751
{
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
    virCapsPtr caps = NULL;
    virDomainDefPtr vmdef;
4752 4753
    virDomainDefPtr oldDef = NULL;
    unsigned int oldPersist = vm->persistent;
J
Jiri Denemark 已提交
4754 4755 4756 4757 4758 4759 4760
    virObjectEventPtr event;
    int ret = -1;

    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto cleanup;

    vm->persistent = 1;
4761 4762
    oldDef = vm->newDef;
    vm->newDef = qemuMigrationCookieGetPersistent(mig);
J
Jiri Denemark 已提交
4763

4764 4765
    if (!(vmdef = virDomainObjGetPersistentDef(caps, driver->xmlopt, vm)))
        goto error;
J
Jiri Denemark 已提交
4766

4767 4768
    if (virDomainSaveConfig(cfg->configDir, driver->caps, vmdef) < 0 &&
        !ignoreSaveError)
4769
        goto error;
J
Jiri Denemark 已提交
4770 4771 4772

    event = virDomainEventLifecycleNewFromObj(vm,
                                              VIR_DOMAIN_EVENT_DEFINED,
4773 4774 4775
                                              oldPersist ?
                                              VIR_DOMAIN_EVENT_DEFINED_UPDATED :
                                              VIR_DOMAIN_EVENT_DEFINED_ADDED);
4776
    qemuDomainEventQueue(driver, event);
J
Jiri Denemark 已提交
4777 4778 4779 4780

    ret = 0;

 cleanup:
4781
    virDomainDefFree(oldDef);
J
Jiri Denemark 已提交
4782 4783 4784
    virObjectUnref(caps);
    virObjectUnref(cfg);
    return ret;
4785 4786 4787 4788 4789 4790 4791

 error:
    virDomainDefFree(vm->newDef);
    vm->persistent = oldPersist;
    vm->newDef = oldDef;
    oldDef = NULL;
    goto cleanup;
J
Jiri Denemark 已提交
4792 4793 4794
}


4795
virDomainPtr
4796 4797 4798 4799 4800 4801 4802 4803 4804 4805
qemuMigrationDstFinish(virQEMUDriverPtr driver,
                       virConnectPtr dconn,
                       virDomainObjPtr vm,
                       const char *cookiein,
                       int cookieinlen,
                       char **cookieout,
                       int *cookieoutlen,
                       unsigned long flags,
                       int retcode,
                       bool v3proto)
4806 4807
{
    virDomainPtr dom = NULL;
4808
    qemuMigrationCookiePtr mig = NULL;
4809
    virErrorPtr orig_err = NULL;
4810
    int cookie_flags = 0;
J
Jiri Denemark 已提交
4811
    qemuDomainObjPrivatePtr priv = vm->privateData;
4812
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4813
    unsigned short port;
4814 4815
    unsigned long long timeReceived = 0;
    virObjectEventPtr event;
4816
    qemuDomainJobInfoPtr jobInfo = NULL;
4817
    bool inPostCopy = false;
4818
    bool doKill = true;
4819

4820
    VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
4821
              "cookieout=%p, cookieoutlen=%p, flags=0x%lx, retcode=%d",
4822 4823
              driver, dconn, vm, NULLSTR(cookiein), cookieinlen,
              cookieout, cookieoutlen, flags, retcode);
4824

4825 4826 4827
    port = priv->migrationPort;
    priv->migrationPort = 0;

4828
    if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_IN)) {
4829
        qemuMigrationDstErrorReport(driver, vm->def->name);
4830
        goto cleanup;
4831
    }
4832

4833 4834
    ignore_value(virTimeMillisNow(&timeReceived));

4835 4836 4837
    qemuMigrationJobStartPhase(driver, vm,
                               v3proto ? QEMU_MIGRATION_PHASE_FINISH3
                                       : QEMU_MIGRATION_PHASE_FINISH2);
4838

4839
    qemuDomainCleanupRemove(vm, qemuMigrationDstPrepareCleanup);
4840
    VIR_FREE(priv->job.completed);
4841

4842
    cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK |
4843 4844
                   QEMU_MIGRATION_COOKIE_STATS |
                   QEMU_MIGRATION_COOKIE_NBD;
4845 4846 4847
    /* Some older versions of libvirt always send persistent XML in the cookie
     * even though VIR_MIGRATE_PERSIST_DEST was not used. */
    cookie_flags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
4848 4849 4850

    if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein,
                                       cookieinlen, cookie_flags)))
4851
        goto endjob;
4852

4853
    if (flags & VIR_MIGRATE_OFFLINE) {
4854
        if (retcode == 0 &&
4855
            qemuMigrationDstPersist(driver, vm, mig, false) == 0)
4856
            dom = virGetDomain(dconn, vm->def->name, vm->def->uuid, -1);
4857 4858
        goto endjob;
    }
4859

4860 4861 4862 4863
    if (retcode != 0) {
        /* Check for a possible error on the monitor in case Finish was called
         * earlier than monitor EOF handler got a chance to process the error
         */
4864
        qemuDomainCheckMonitor(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN);
4865 4866
        goto endjob;
    }
4867

4868 4869 4870
    if (!virDomainObjIsActive(vm)) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("guest unexpectedly quit"));
4871
        qemuMigrationDstErrorReport(driver, vm->def->name);
4872 4873
        goto endjob;
    }
4874

4875
    if (qemuMigrationDstVPAssociatePortProfiles(vm->def) < 0)
4876
        goto endjob;
4877

4878
    if (mig->network && qemuMigrationDstOPDRelocate(driver, vm, mig) < 0)
4879
        VIR_WARN("unable to provide network data for relocation");
4880

4881
    if (qemuMigrationDstStopNBDServer(driver, vm, mig) < 0)
4882
        goto endjob;
4883

4884 4885
    if (qemuRefreshVirtioChannelState(driver, vm,
                                      QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
4886 4887
        goto endjob;

4888 4889
    if (qemuConnectAgent(driver, vm) < 0)
        goto endjob;
4890

4891
    if (flags & VIR_MIGRATE_PERSIST_DEST) {
4892
        if (qemuMigrationDstPersist(driver, vm, mig, !v3proto) < 0) {
4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903
            /* Hmpf.  Migration was successful, but making it persistent
             * was not.  If we report successful, then when this domain
             * shuts down, management tools are in for a surprise.  On the
             * other hand, if we report failure, then the management tools
             * might try to restart the domain on the source side, even
             * though the domain is actually running on the destination.
             * Pretend success and hope that this is a rare situation and
             * management tools are smart.
             *
             * However, in v3 protocol, the source VM is still available
             * to restart during confirm() step, so we kill it off now.
4904 4905 4906
             */
            if (v3proto)
                goto endjob;
4907
        }
4908
    }
4909

4910 4911 4912
    /* We need to wait for QEMU to process all data sent by the source
     * before starting guest CPUs.
     */
4913 4914 4915
    if (qemuMigrationDstWaitForCompletion(driver, vm,
                                          QEMU_ASYNC_JOB_MIGRATION_IN,
                                          !!(flags & VIR_MIGRATE_POSTCOPY)) < 0) {
4916 4917 4918 4919 4920 4921
        /* There's not much we can do for v2 protocol since the
         * original domain on the source host is already gone.
         */
        if (v3proto)
            goto endjob;
    }
4922

4923 4924 4925 4926 4927 4928 4929 4930 4931
    /* Now that the state data was transferred we can refresh the actual state
     * of the devices */
    if (qemuProcessRefreshState(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) {
        /* Similarly to the case above v2 protocol will not be able to recover
         * from this. Let's ignore this and perhaps stuff will not break. */
        if (v3proto)
            goto endjob;
    }

4932
    if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
4933 4934
        inPostCopy = true;

4935 4936 4937 4938 4939
    if (!(flags & VIR_MIGRATE_PAUSED)) {
        /* run 'cont' on the destination, which allows migration on qemu
         * >= 0.10.6 to work properly.  This isn't strictly necessary on
         * older qemu's, but it also doesn't hurt anything there
         */
4940
        if (qemuProcessStartCPUs(driver, vm,
4941 4942
                                 inPostCopy ? VIR_DOMAIN_RUNNING_POSTCOPY
                                            : VIR_DOMAIN_RUNNING_MIGRATED,
4943 4944 4945 4946 4947 4948 4949 4950
                                 QEMU_ASYNC_JOB_MIGRATION_IN) < 0) {
            if (virGetLastError() == NULL)
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("resume operation failed"));
            /* Need to save the current error, in case shutting
             * down the process overwrites it
             */
            orig_err = virSaveLastError();
4951

4952 4953 4954 4955 4956 4957 4958 4959 4960 4961
            /*
             * In v3 protocol, the source VM is still available to
             * restart during confirm() step, so we kill it off
             * now.
             * In v2 protocol, the source is dead, so we leave
             * target in paused state, in case admin can fix
             * things up.
             */
            if (v3proto)
                goto endjob;
4962
        }
4963 4964

        if (inPostCopy) {
4965
            doKill = false;
4966 4967 4968 4969 4970
            event = virDomainEventLifecycleNewFromObj(vm,
                                        VIR_DOMAIN_EVENT_RESUMED,
                                        VIR_DOMAIN_EVENT_RESUMED_POSTCOPY);
            qemuDomainEventQueue(driver, event);
        }
4971
    }
4972

4973
    if (mig->jobInfo) {
4974
        jobInfo = mig->jobInfo;
4975 4976 4977 4978 4979 4980
        mig->jobInfo = NULL;

        if (jobInfo->sent && timeReceived) {
            jobInfo->timeDelta = timeReceived - jobInfo->sent;
            jobInfo->received = timeReceived;
            jobInfo->timeDeltaSet = true;
4981
        }
4982 4983
        qemuDomainJobInfoUpdateTime(jobInfo);
        qemuDomainJobInfoUpdateDowntime(jobInfo);
4984
    }
L
liguang 已提交
4985

4986
    if (inPostCopy) {
4987 4988 4989
        if (qemuMigrationDstWaitForCompletion(driver, vm,
                                              QEMU_ASYNC_JOB_MIGRATION_IN,
                                              false) < 0) {
4990 4991 4992 4993 4994 4995 4996 4997 4998
            goto endjob;
        }
        if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
            virDomainObjSetState(vm,
                                 VIR_DOMAIN_RUNNING,
                                 VIR_DOMAIN_RUNNING_MIGRATED);
        }
    }

4999
    dom = virGetDomain(dconn, vm->def->name, vm->def->uuid, vm->def->id);
5000

5001 5002 5003 5004
    event = virDomainEventLifecycleNewFromObj(vm,
                                              VIR_DOMAIN_EVENT_RESUMED,
                                              VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
    qemuDomainEventQueue(driver, event);
5005

5006 5007 5008 5009 5010 5011
    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER);
        event = virDomainEventLifecycleNewFromObj(vm,
                                                  VIR_DOMAIN_EVENT_SUSPENDED,
                                                  VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
        qemuDomainEventQueue(driver, event);
5012
    }
5013

5014
    if (virDomainObjIsActive(vm) &&
5015
        virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
5016 5017 5018 5019 5020
        VIR_WARN("Failed to save status on vm %s", vm->def->name);

    /* Guest is successfully running, so cancel previous auto destroy */
    qemuProcessAutoDestroyRemove(driver, vm);

5021
 endjob:
5022
    if (!dom &&
5023 5024
        !(flags & VIR_MIGRATE_OFFLINE) &&
        virDomainObjIsActive(vm)) {
5025
        if (doKill) {
5026 5027 5028 5029 5030 5031 5032 5033 5034
            qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED,
                            QEMU_ASYNC_JOB_MIGRATION_IN,
                            VIR_QEMU_PROCESS_STOP_MIGRATED);
            virDomainAuditStop(vm, "failed");
            event = virDomainEventLifecycleNewFromObj(vm,
                                VIR_DOMAIN_EVENT_STOPPED,
                                VIR_DOMAIN_EVENT_STOPPED_FAILED);
            qemuDomainEventQueue(driver, event);
        } else {
5035
            qemuMigrationAnyPostcopyFailed(driver, vm);
5036
        }
5037 5038
    }

5039
    if (dom) {
5040 5041 5042 5043
        if (jobInfo) {
            VIR_STEAL_PTR(priv->job.completed, jobInfo);
            priv->job.completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
        }
5044

5045 5046 5047
        if (qemuMigrationBakeCookie(mig, driver, vm,
                                    QEMU_MIGRATION_DESTINATION,
                                    cookieout, cookieoutlen,
5048 5049
                                    QEMU_MIGRATION_COOKIE_STATS) < 0)
            VIR_WARN("Unable to encode migration cookie");
5050 5051 5052 5053 5054 5055

        /* Remove completed stats for post-copy, everything but timing fields
         * is obsolete anyway.
         */
        if (inPostCopy)
            VIR_FREE(priv->job.completed);
5056
    }
5057

5058
    qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
5059
                             priv->job.migParams, priv->job.apiFlags);
5060

5061
    qemuMigrationJobFinish(driver, vm);
5062
    if (!virDomainObjIsActive(vm))
5063
        qemuDomainRemoveInactiveJob(driver, vm);
5064

5065
 cleanup:
5066
    VIR_FREE(jobInfo);
5067
    virPortAllocatorRelease(port);
5068
    if (priv->mon)
5069
        qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL);
5070
    VIR_FREE(priv->origname);
M
Michal Privoznik 已提交
5071
    virDomainObjEndAPI(&vm);
5072
    qemuMigrationCookieFree(mig);
5073 5074 5075 5076
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
5077
    virObjectUnref(cfg);
5078 5079 5080 5081 5082 5083

    /* Set a special error if Finish is expected to return NULL as a result of
     * successful call with retcode != 0
     */
    if (retcode != 0 && !dom && !virGetLastError())
        virReportError(VIR_ERR_MIGRATE_FINISH_OK, NULL);
5084 5085
    return dom;
}
5086

5087

5088
/* Helper function called while vm is active.  */
5089
int
5090 5091 5092 5093
qemuMigrationSrcToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
                       int fd,
                       const char *compressor,
                       qemuDomainAsyncJob asyncJob)
5094 5095 5096
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int rc;
5097
    int ret = -1;
5098 5099
    virCommandPtr cmd = NULL;
    int pipeFD[2] = { -1, -1 };
5100
    unsigned long saveMigBandwidth = priv->migMaxBandwidth;
5101
    char *errbuf = NULL;
5102
    virErrorPtr orig_err = NULL;
5103 5104 5105 5106 5107

    /* Increase migration bandwidth to unlimited since target is a file.
     * Failure to change migration speed is not fatal. */
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
        qemuMonitorSetMigrationSpeed(priv->mon,
5108 5109
                                     QEMU_DOMAIN_MIG_BANDWIDTH_MAX);
        priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
5110 5111
        if (qemuDomainObjExitMonitor(driver, vm) < 0)
            return -1;
5112
    }
5113

5114 5115 5116 5117 5118 5119 5120
    if (!virDomainObjIsActive(vm)) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("guest unexpectedly quit"));
        /* nothing to tear down */
        return -1;
    }

5121 5122 5123 5124
    if (compressor && pipe(pipeFD) < 0) {
        virReportSystemError(errno, "%s",
                             _("Failed to create pipe for migration"));
        return -1;
5125 5126
    }

5127 5128 5129 5130
    /* All right! We can use fd migration, which means that qemu
     * doesn't have to open() the file, so while we still have to
     * grant SELinux access, we can do it on fd and avoid cleanup
     * later, as well as skip futzing with cgroup.  */
5131 5132
    if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def,
                                    compressor ? pipeFD[1] : fd) < 0)
5133 5134
        goto cleanup;

5135
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
5136 5137
        goto cleanup;

5138
    if (!compressor) {
5139 5140 5141
        rc = qemuMonitorMigrateToFd(priv->mon,
                                    QEMU_MONITOR_MIGRATE_BACKGROUND,
                                    fd);
5142 5143 5144 5145 5146 5147 5148
    } else {
        const char *prog = compressor;
        const char *args[] = {
            prog,
            "-c",
            NULL
        };
5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159

        cmd = virCommandNewArgs(args);
        virCommandSetInputFD(cmd, pipeFD[0]);
        virCommandSetOutputFD(cmd, &fd);
        virCommandSetErrorBuffer(cmd, &errbuf);
        virCommandDoAsyncIO(cmd);
        if (virSetCloseExec(pipeFD[1]) < 0) {
            virReportSystemError(errno, "%s",
                                 _("Unable to set cloexec flag"));
            ignore_value(qemuDomainObjExitMonitor(driver, vm));
            goto cleanup;
5160
        }
5161 5162 5163 5164 5165 5166 5167 5168 5169 5170
        if (virCommandRunAsync(cmd, NULL) < 0) {
            ignore_value(qemuDomainObjExitMonitor(driver, vm));
            goto cleanup;
        }
        rc = qemuMonitorMigrateToFd(priv->mon,
                                    QEMU_MONITOR_MIGRATE_BACKGROUND,
                                    pipeFD[1]);
        if (VIR_CLOSE(pipeFD[0]) < 0 ||
            VIR_CLOSE(pipeFD[1]) < 0)
            VIR_WARN("failed to close intermediate pipe");
5171
    }
5172
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
5173
        goto cleanup;
5174 5175 5176
    if (rc < 0)
        goto cleanup;

5177
    rc = qemuMigrationSrcWaitForCompletion(driver, vm, asyncJob, NULL, 0);
5178

5179 5180 5181 5182
    if (rc < 0) {
        if (rc == -2) {
            orig_err = virSaveLastError();
            virCommandAbort(cmd);
5183 5184
            if (virDomainObjIsActive(vm) &&
                qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
5185
                qemuMonitorMigrateCancel(priv->mon);
5186
                ignore_value(qemuDomainObjExitMonitor(driver, vm));
5187 5188
            }
        }
5189
        goto cleanup;
5190
    }
5191

5192 5193 5194
    if (cmd && virCommandWait(cmd, NULL) < 0)
        goto cleanup;

5195
    qemuDomainEventEmitJobCompleted(driver, vm);
5196 5197
    ret = 0;

5198
 cleanup:
5199 5200 5201
    if (ret < 0 && !orig_err)
        orig_err = virSaveLastError();

5202
    /* Restore max migration bandwidth */
5203 5204
    if (virDomainObjIsActive(vm) &&
        qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
5205 5206
        qemuMonitorSetMigrationSpeed(priv->mon, saveMigBandwidth);
        priv->migMaxBandwidth = saveMigBandwidth;
5207
        ignore_value(qemuDomainObjExitMonitor(driver, vm));
5208 5209
    }

5210 5211
    VIR_FORCE_CLOSE(pipeFD[0]);
    VIR_FORCE_CLOSE(pipeFD[1]);
5212 5213 5214 5215 5216
    if (cmd) {
        VIR_DEBUG("Compression binary stderr: %s", NULLSTR(errbuf));
        VIR_FREE(errbuf);
        virCommandFree(cmd);
    }
5217 5218 5219 5220 5221 5222

    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }

5223 5224
    return ret;
}
5225

5226 5227

int
5228 5229
qemuMigrationSrcCancel(virQEMUDriverPtr driver,
                       virDomainObjPtr vm)
5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virHashTablePtr blockJobs = NULL;
    bool storage = false;
    size_t i;
    int ret = -1;

    VIR_DEBUG("Canceling unfinished outgoing migration of domain %s",
              vm->def->name);

    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
        if (QEMU_DOMAIN_DISK_PRIVATE(disk)->migrating) {
            qemuBlockJobSyncBegin(disk);
            storage = true;
        }
    }

    qemuDomainObjEnterMonitor(driver, vm);

    ignore_value(qemuMonitorMigrateCancel(priv->mon));
    if (storage)
        blockJobs = qemuMonitorGetAllBlockJobInfo(priv->mon);

    if (qemuDomainObjExitMonitor(driver, vm) < 0 || (storage && !blockJobs))
        goto endsyncjob;

    if (!storage) {
        ret = 0;
        goto cleanup;
    }

    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);

        if (!diskPriv->migrating)
            continue;

        if (virHashLookup(blockJobs, disk->info.alias)) {
            VIR_DEBUG("Drive mirror on disk %s is still running", disk->dst);
        } else {
            VIR_DEBUG("Drive mirror on disk %s is gone", disk->dst);
5273
            qemuBlockJobSyncEnd(vm, QEMU_ASYNC_JOB_NONE, disk);
5274 5275 5276 5277
            diskPriv->migrating = false;
        }
    }

5278 5279
    if (qemuMigrationSrcCancelDriveMirror(driver, vm, false,
                                          QEMU_ASYNC_JOB_NONE, NULL) < 0)
5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294
        goto endsyncjob;

    ret = 0;

 cleanup:
    virHashFree(blockJobs);
    return ret;

 endsyncjob:
    if (storage) {
        for (i = 0; i < vm->def->ndisks; i++) {
            virDomainDiskDefPtr disk = vm->def->disks[i];
            qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);

            if (diskPriv->migrating) {
5295
                qemuBlockJobSyncEnd(vm, QEMU_ASYNC_JOB_NONE, disk);
5296 5297 5298 5299 5300 5301 5302 5303
                diskPriv->migrating = false;
            }
        }
    }
    goto cleanup;
}


5304
static int
5305
qemuMigrationJobStart(virQEMUDriverPtr driver,
5306
                      virDomainObjPtr vm,
5307 5308
                      qemuDomainAsyncJob job,
                      unsigned long apiFlags)
5309
{
5310
    qemuDomainObjPrivatePtr priv = vm->privateData;
5311 5312
    virDomainJobOperation op;
    unsigned long long mask;
5313

5314
    if (job == QEMU_ASYNC_JOB_MIGRATION_IN) {
5315 5316
        op = VIR_DOMAIN_JOB_OPERATION_MIGRATION_IN;
        mask = QEMU_JOB_NONE;
5317
    } else {
5318 5319 5320 5321
        op = VIR_DOMAIN_JOB_OPERATION_MIGRATION_OUT;
        mask = QEMU_JOB_DEFAULT_MASK |
               JOB_MASK(QEMU_JOB_SUSPEND) |
               JOB_MASK(QEMU_JOB_MIGRATION_OP);
5322
    }
5323

5324
    if (qemuDomainObjBeginAsyncJob(driver, vm, job, op, apiFlags) < 0)
5325 5326
        return -1;

5327 5328
    priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION;

5329
    qemuDomainObjSetAsyncJobMask(vm, mask);
5330 5331 5332
    return 0;
}

5333
static void
5334
qemuMigrationJobSetPhase(virQEMUDriverPtr driver,
5335
                         virDomainObjPtr vm,
5336
                         qemuMigrationJobPhase phase)
5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349
{
    qemuDomainObjPrivatePtr priv = vm->privateData;

    if (phase < priv->job.phase) {
        VIR_ERROR(_("migration protocol going backwards %s => %s"),
                  qemuMigrationJobPhaseTypeToString(priv->job.phase),
                  qemuMigrationJobPhaseTypeToString(phase));
        return;
    }

    qemuDomainObjSetJobPhase(driver, vm, phase);
}

5350
static void
5351
qemuMigrationJobStartPhase(virQEMUDriverPtr driver,
5352
                           virDomainObjPtr vm,
5353
                           qemuMigrationJobPhase phase)
5354 5355 5356 5357
{
    qemuMigrationJobSetPhase(driver, vm, phase);
}

5358
static void
5359 5360
qemuMigrationJobContinue(virDomainObjPtr vm)
{
5361
    qemuDomainObjReleaseAsyncJob(vm);
5362 5363
}

5364
static bool
5365
qemuMigrationJobIsActive(virDomainObjPtr vm,
5366
                         qemuDomainAsyncJob job)
5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377
{
    qemuDomainObjPrivatePtr priv = vm->privateData;

    if (priv->job.asyncJob != job) {
        const char *msg;

        if (job == QEMU_ASYNC_JOB_MIGRATION_IN)
            msg = _("domain '%s' is not processing incoming migration");
        else
            msg = _("domain '%s' is not being migrated");

5378
        virReportError(VIR_ERR_OPERATION_INVALID, msg, vm->def->name);
5379 5380 5381 5382 5383
        return false;
    }
    return true;
}

5384
static void
5385
qemuMigrationJobFinish(virQEMUDriverPtr driver, virDomainObjPtr vm)
5386
{
5387
    qemuDomainObjEndAsyncJob(driver, vm);
5388
}
5389 5390 5391


static void
5392
qemuMigrationDstErrorFree(void *data,
5393 5394 5395 5396 5397 5398 5399
                       const void *name ATTRIBUTE_UNUSED)
{
    virErrorPtr err = data;
    virFreeError(err);
}

int
5400
qemuMigrationDstErrorInit(virQEMUDriverPtr driver)
5401
{
5402
    driver->migrationErrors = virHashAtomicNew(64, qemuMigrationDstErrorFree);
5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413
    if (driver->migrationErrors)
        return 0;
    else
        return -1;
}

/**
 * This function consumes @err; the caller should consider the @err pointer
 * invalid after calling this function.
 */
void
5414 5415 5416
qemuMigrationDstErrorSave(virQEMUDriverPtr driver,
                          const char *name,
                          virErrorPtr err)
5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429
{
    if (!err)
        return;

    VIR_DEBUG("Saving incoming migration error for domain %s: %s",
              name, err->message);
    if (virHashAtomicUpdate(driver->migrationErrors, name, err) < 0) {
        VIR_WARN("Failed to save migration error for domain '%s'", name);
        virFreeError(err);
    }
}

void
5430 5431
qemuMigrationDstErrorReport(virQEMUDriverPtr driver,
                            const char *name)
5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442
{
    virErrorPtr err;

    if (!(err = virHashAtomicSteal(driver->migrationErrors, name)))
        return;

    VIR_DEBUG("Restoring saved incoming migration error for domain %s: %s",
              name, err->message);
    virSetError(err);
    virFreeError(err);
}
5443 5444


5445
int
5446 5447 5448 5449
qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
                                 qemuDomainAsyncJob asyncJob,
                                 qemuDomainJobInfoPtr jobInfo)
5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493
{
    size_t i;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    bool nbd = false;
    virHashTablePtr blockinfo = NULL;
    qemuDomainMirrorStatsPtr stats = &jobInfo->mirrorStats;

    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
        if (QEMU_DOMAIN_DISK_PRIVATE(disk)->migrating) {
            nbd = true;
            break;
        }
    }

    if (!nbd)
        return 0;

    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        return -1;

    blockinfo = qemuMonitorGetAllBlockJobInfo(priv->mon);

    if (qemuDomainObjExitMonitor(driver, vm) < 0 || !blockinfo)
        return -1;

    memset(stats, 0, sizeof(*stats));

    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
        qemuMonitorBlockJobInfoPtr data;

        if (!diskPriv->migrating ||
            !(data = virHashLookup(blockinfo, disk->info.alias)))
            continue;

        stats->transferred += data->cur;
        stats->total += data->end;
    }

    virHashFree(blockinfo);
    return 0;
}