~ubuntu-branches/ubuntu/raring/libvirt/raring

« back to all changes in this revision

Viewing changes to src/qemu/qemu_migration.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-11-19 10:41:02 UTC
  • mfrom: (1.2.15) (223.1.2 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121119104102-l6ewdppikysbzztu
Tags: 1.0.0-0ubuntu2
debian/patches/add-armhf-sysinfo-infomration.patch: Disable
to fix FTBFS on arm.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
1
2
/*
2
3
 * qemu_migration.c: QEMU migration handling
3
4
 *
14
15
 * Lesser General Public License for more details.
15
16
 *
16
17
 * You should have received a copy of the GNU Lesser General Public
17
 
 * License along with this library; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 
18
 * License along with this library.  If not, see
 
19
 * <http://www.gnu.org/licenses/>.
19
20
 *
20
21
 */
21
22
 
70
71
    QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS,
71
72
    QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE,
72
73
    QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT,
 
74
    QEMU_MIGRATION_COOKIE_FLAG_NETWORK,
73
75
 
74
76
    QEMU_MIGRATION_COOKIE_FLAG_LAST
75
77
};
77
79
VIR_ENUM_DECL(qemuMigrationCookieFlag);
78
80
VIR_ENUM_IMPL(qemuMigrationCookieFlag,
79
81
              QEMU_MIGRATION_COOKIE_FLAG_LAST,
80
 
              "graphics", "lockstate", "persistent");
 
82
              "graphics", "lockstate", "persistent", "network");
81
83
 
82
84
enum qemuMigrationCookieFeatures {
83
85
    QEMU_MIGRATION_COOKIE_GRAPHICS  = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS),
84
86
    QEMU_MIGRATION_COOKIE_LOCKSTATE = (1 << QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE),
85
87
    QEMU_MIGRATION_COOKIE_PERSISTENT = (1 << QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT),
 
88
    QEMU_MIGRATION_COOKIE_NETWORK = (1 << QEMU_MIGRATION_COOKIE_FLAG_NETWORK),
86
89
};
87
90
 
88
91
typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
95
98
    char *tlsSubject;
96
99
};
97
100
 
 
101
typedef struct _qemuMigrationCookieNetData qemuMigrationCookieNetData;
 
102
typedef qemuMigrationCookieNetData *qemuMigrationCookieNetDataPtr;
 
103
struct _qemuMigrationCookieNetData {
 
104
    int vporttype; /* enum virNetDevVPortProfile */
 
105
 
 
106
    /*
 
107
     * Array of pointers to saved data. Each VIF will have it's own
 
108
     * data to transfer.
 
109
     */
 
110
    char *portdata;
 
111
};
 
112
 
 
113
typedef struct _qemuMigrationCookieNetwork qemuMigrationCookieNetwork;
 
114
typedef qemuMigrationCookieNetwork *qemuMigrationCookieNetworkPtr;
 
115
struct _qemuMigrationCookieNetwork {
 
116
    /* How many virtual NICs are we saving data for? */
 
117
    int nnets;
 
118
 
 
119
    qemuMigrationCookieNetDataPtr net;
 
120
};
 
121
 
98
122
typedef struct _qemuMigrationCookie qemuMigrationCookie;
99
123
typedef qemuMigrationCookie *qemuMigrationCookiePtr;
100
124
struct _qemuMigrationCookie {
120
144
 
121
145
    /* If (flags & QEMU_MIGRATION_COOKIE_PERSISTENT) */
122
146
    virDomainDefPtr persistent;
 
147
 
 
148
    /* If (flags & QEMU_MIGRATION_COOKIE_NETWORK) */
 
149
    qemuMigrationCookieNetworkPtr network;
123
150
};
124
151
 
125
152
static void qemuMigrationCookieGraphicsFree(qemuMigrationCookieGraphicsPtr grap)
132
159
}
133
160
 
134
161
 
 
162
static void
 
163
qemuMigrationCookieNetworkFree(qemuMigrationCookieNetworkPtr network)
 
164
{
 
165
    int i;
 
166
 
 
167
    if (!network)
 
168
        return;
 
169
 
 
170
    if (network->net) {
 
171
        for (i = 0; i < network->nnets; i++)
 
172
            VIR_FREE(network->net[i].portdata);
 
173
    }
 
174
    VIR_FREE(network->net);
 
175
    VIR_FREE(network);
 
176
}
 
177
 
 
178
 
135
179
static void qemuMigrationCookieFree(qemuMigrationCookiePtr mig)
136
180
{
137
181
    if (!mig)
140
184
    if (mig->flags & QEMU_MIGRATION_COOKIE_GRAPHICS)
141
185
        qemuMigrationCookieGraphicsFree(mig->graphics);
142
186
 
 
187
    if (mig->flags & QEMU_MIGRATION_COOKIE_NETWORK)
 
188
        qemuMigrationCookieNetworkFree(mig->network);
 
189
 
143
190
    VIR_FREE(mig->localHostname);
144
191
    VIR_FREE(mig->remoteHostname);
145
192
    VIR_FREE(mig->name);
164
211
        goto no_memory;
165
212
 
166
213
    if (virFileReadAll(certfile, 8192, &pemdata) < 0) {
167
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
168
 
                        _("unable to read server cert %s"), certfile);
 
214
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
215
                       _("unable to read server cert %s"), certfile);
169
216
        goto error;
170
217
    }
171
218
 
172
219
    ret = gnutls_x509_crt_init(&cert);
173
220
    if (ret < 0) {
174
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
175
 
                        _("cannot initialize cert object: %s"),
176
 
                        gnutls_strerror(ret));
 
221
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
222
                       _("cannot initialize cert object: %s"),
 
223
                       gnutls_strerror(ret));
177
224
        goto error;
178
225
    }
179
226
 
182
229
 
183
230
    ret = gnutls_x509_crt_import(cert, &pemdatum, GNUTLS_X509_FMT_PEM);
184
231
    if (ret < 0) {
185
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
186
 
                        _("cannot load cert data from %s: %s"),
187
 
                        certfile, gnutls_strerror(ret));
 
232
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
233
                       _("cannot load cert data from %s: %s"),
 
234
                       certfile, gnutls_strerror(ret));
188
235
        goto error;
189
236
    }
190
237
 
256
303
}
257
304
 
258
305
 
 
306
static qemuMigrationCookieNetworkPtr
 
307
qemuMigrationCookieNetworkAlloc(struct qemud_driver *driver ATTRIBUTE_UNUSED,
 
308
                                virDomainDefPtr def)
 
309
{
 
310
    qemuMigrationCookieNetworkPtr mig;
 
311
    int i;
 
312
 
 
313
    if (VIR_ALLOC(mig) < 0)
 
314
        goto no_memory;
 
315
 
 
316
    mig->nnets = def->nnets;
 
317
 
 
318
    if (VIR_ALLOC_N(mig->net, def->nnets) <0)
 
319
        goto no_memory;
 
320
 
 
321
    for (i = 0; i < def->nnets; i++) {
 
322
        virDomainNetDefPtr netptr;
 
323
        virNetDevVPortProfilePtr vport;
 
324
 
 
325
        netptr = def->nets[i];
 
326
        vport = virDomainNetGetActualVirtPortProfile(netptr);
 
327
 
 
328
        if (vport) {
 
329
            mig->net[i].vporttype = vport->virtPortType;
 
330
 
 
331
            switch (vport->virtPortType) {
 
332
            case VIR_NETDEV_VPORT_PROFILE_NONE:
 
333
            case VIR_NETDEV_VPORT_PROFILE_8021QBG:
 
334
            case VIR_NETDEV_VPORT_PROFILE_8021QBH:
 
335
               break;
 
336
            case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH:
 
337
                if (virNetDevOpenvswitchGetMigrateData(&mig->net[i].portdata,
 
338
                                                       netptr->ifname) != 0) {
 
339
                        virReportSystemError(VIR_ERR_INTERNAL_ERROR,
 
340
                                             _("Unable to run command to get OVS port data for "
 
341
                                             "interface %s"), netptr->ifname);
 
342
                        goto error;
 
343
                }
 
344
                break;
 
345
            default:
 
346
                break;
 
347
            }
 
348
        }
 
349
    }
 
350
    return mig;
 
351
 
 
352
no_memory:
 
353
    virReportOOMError();
 
354
error:
 
355
    qemuMigrationCookieNetworkFree(mig);
 
356
    return NULL;
 
357
}
 
358
 
259
359
static qemuMigrationCookiePtr
260
360
qemuMigrationCookieNew(virDomainObjPtr dom)
261
361
{
277
377
    if (!(mig->localHostname = virGetHostname(NULL)))
278
378
        goto error;
279
379
    if (virGetHostUUID(mig->localHostuuid) < 0) {
280
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
281
 
                        _("Unable to obtain host UUID"));
 
380
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
381
                       _("Unable to obtain host UUID"));
282
382
        goto error;
283
383
    }
284
384
 
298
398
                               virDomainObjPtr dom)
299
399
{
300
400
    if (mig->flags & QEMU_MIGRATION_COOKIE_GRAPHICS) {
301
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
302
 
                        _("Migration graphics data already present"));
 
401
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
402
                       _("Migration graphics data already present"));
303
403
        return -1;
304
404
    }
305
405
 
324
424
    qemuDomainObjPrivatePtr priv = dom->privateData;
325
425
 
326
426
    if (mig->flags & QEMU_MIGRATION_COOKIE_LOCKSTATE) {
327
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
328
 
                        _("Migration lockstate data already present"));
 
427
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
428
                       _("Migration lockstate data already present"));
329
429
        return -1;
330
430
    }
331
431
 
355
455
                                 virDomainObjPtr dom)
356
456
{
357
457
    if (mig->flags & QEMU_MIGRATION_COOKIE_PERSISTENT) {
358
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
359
 
                        _("Migration persistent data already present"));
 
458
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
459
                       _("Migration persistent data already present"));
360
460
        return -1;
361
461
    }
362
462
 
370
470
}
371
471
 
372
472
 
 
473
static int
 
474
qemuMigrationCookieAddNetwork(qemuMigrationCookiePtr mig,
 
475
                              struct qemud_driver *driver,
 
476
                              virDomainObjPtr dom)
 
477
{
 
478
    if (mig->flags & QEMU_MIGRATION_COOKIE_NETWORK) {
 
479
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
480
                       _("Network migration data already present"));
 
481
        return -1;
 
482
    }
 
483
 
 
484
    if (dom->def->nnets > 0) {
 
485
        mig->network = qemuMigrationCookieNetworkAlloc(driver, dom->def);
 
486
        if (!mig->network)
 
487
            return -1;
 
488
        mig->flags |= QEMU_MIGRATION_COOKIE_NETWORK;
 
489
    }
 
490
 
 
491
    return 0;
 
492
}
 
493
 
373
494
 
374
495
static void qemuMigrationCookieGraphicsXMLFormat(virBufferPtr buf,
375
496
                                                 qemuMigrationCookieGraphicsPtr grap)
389
510
}
390
511
 
391
512
 
 
513
static void
 
514
qemuMigrationCookieNetworkXMLFormat(virBufferPtr buf,
 
515
                                    qemuMigrationCookieNetworkPtr optr)
 
516
{
 
517
    int i;
 
518
    bool empty = true;
 
519
 
 
520
    for (i = 0; i < optr->nnets; i++) {
 
521
        /* If optr->net[i].vporttype is not set, there is nothing to transfer */
 
522
        if (optr->net[i].vporttype != VIR_NETDEV_VPORT_PROFILE_NONE) {
 
523
            if (empty) {
 
524
                virBufferAsprintf(buf, "  <network>\n");
 
525
                empty = false;
 
526
            }
 
527
            virBufferAsprintf(buf, "    <interface index='%d' vporttype='%s'",
 
528
                              i, virNetDevVPortTypeToString(optr->net[i].vporttype));
 
529
            if (optr->net[i].portdata) {
 
530
                virBufferAddLit(buf, ">\n");
 
531
                virBufferEscapeString(buf, "      <portdata>%s</portdata>\n",
 
532
                                      optr->net[i].portdata);
 
533
                virBufferAddLit(buf, "    </interface>\n");
 
534
            } else {
 
535
                virBufferAddLit(buf, "/>\n");
 
536
            }
 
537
        }
 
538
    }
 
539
    if (!empty)
 
540
        virBufferAddLit(buf, "  </network>\n");
 
541
}
 
542
 
 
543
 
392
544
static int
393
545
qemuMigrationCookieXMLFormat(struct qemud_driver *driver,
394
546
                             virBufferPtr buf,
432
584
        if (qemuDomainDefFormatBuf(driver,
433
585
                                   mig->persistent,
434
586
                                   VIR_DOMAIN_XML_INACTIVE |
435
 
                                   VIR_DOMAIN_XML_SECURE,
436
 
                                   true,
 
587
                                   VIR_DOMAIN_XML_SECURE |
 
588
                                   VIR_DOMAIN_XML_MIGRATABLE,
437
589
                                   buf) < 0)
438
590
            return -1;
439
591
        virBufferAdjustIndent(buf, -2);
440
592
    }
441
593
 
 
594
    if ((mig->flags & QEMU_MIGRATION_COOKIE_NETWORK) && mig->network)
 
595
        qemuMigrationCookieNetworkXMLFormat(buf, mig->network);
 
596
 
442
597
    virBufferAddLit(buf, "</qemu-migration>\n");
443
598
    return 0;
444
599
}
474
629
        goto no_memory;
475
630
 
476
631
    if (!(tmp = virXPathString("string(./graphics/@type)", ctxt))) {
477
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
478
 
                        "%s", _("missing type attribute in migration data"));
 
632
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
633
                       "%s", _("missing type attribute in migration data"));
479
634
        goto error;
480
635
    }
481
636
    if ((grap->type = virDomainGraphicsTypeFromString(tmp)) < 0) {
482
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
483
 
                        _("unknown graphics type %s"), tmp);
 
637
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
638
                       _("unknown graphics type %s"), tmp);
484
639
        VIR_FREE(tmp);
485
640
        goto error;
486
641
    }
487
642
    VIR_FREE(tmp);
488
643
    if (virXPathInt("string(./graphics/@port)", ctxt, &grap->port) < 0) {
489
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
490
 
                        "%s", _("missing port attribute in migration data"));
 
644
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
645
                       "%s", _("missing port attribute in migration data"));
491
646
        goto error;
492
647
    }
493
648
    if (grap->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
494
649
        if (virXPathInt("string(./graphics/@tlsPort)", ctxt, &grap->tlsPort) < 0) {
495
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
496
 
                            "%s", _("missing tlsPort attribute in migration data"));
 
650
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
651
                           "%s", _("missing tlsPort attribute in migration data"));
497
652
            goto error;
498
653
        }
499
654
    }
500
655
    if (!(grap->listen = virXPathString("string(./graphics/@listen)", ctxt))) {
501
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
502
 
                        "%s", _("missing listen attribute in migration data"));
 
656
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
657
                       "%s", _("missing listen attribute in migration data"));
503
658
        goto error;
504
659
    }
505
660
    /* Optional */
516
671
}
517
672
 
518
673
 
 
674
static qemuMigrationCookieNetworkPtr
 
675
qemuMigrationCookieNetworkXMLParse(xmlXPathContextPtr ctxt)
 
676
{
 
677
    qemuMigrationCookieNetworkPtr optr;
 
678
    int i;
 
679
    int n;
 
680
    xmlNodePtr *interfaces = NULL;
 
681
    char *vporttype;
 
682
    xmlNodePtr save_ctxt = ctxt->node;
 
683
 
 
684
    if (VIR_ALLOC(optr) < 0)
 
685
        goto no_memory;
 
686
 
 
687
    if ((n = virXPathNodeSet("./network/interface", ctxt, &interfaces)) < 0) {
 
688
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
689
                       "%s", _("missing interface information"));
 
690
        goto error;
 
691
    }
 
692
 
 
693
    optr->nnets = n;
 
694
    if (VIR_ALLOC_N(optr->net, optr->nnets) <0)
 
695
        goto no_memory;
 
696
 
 
697
    for (i = 0; i < n; i++) {
 
698
        /* portdata is optional, and may not exist */
 
699
        ctxt->node = interfaces[i];
 
700
        optr->net[i].portdata = virXPathString("string(./portdata[1])", ctxt);
 
701
 
 
702
        if (!(vporttype = virXMLPropString(interfaces[i], "vporttype"))) {
 
703
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
704
                           "%s", _("missing vporttype attribute in migration data"));
 
705
            goto error;
 
706
        }
 
707
        optr->net[i].vporttype = virNetDevVPortTypeFromString(vporttype);
 
708
    }
 
709
 
 
710
    VIR_FREE(interfaces);
 
711
 
 
712
cleanup:
 
713
    ctxt->node = save_ctxt;
 
714
    return optr;
 
715
 
 
716
no_memory:
 
717
    virReportOOMError();
 
718
error:
 
719
    VIR_FREE(interfaces);
 
720
    qemuMigrationCookieNetworkFree(optr);
 
721
    optr = NULL;
 
722
    goto cleanup;
 
723
}
 
724
 
 
725
 
519
726
static int
520
727
qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
521
728
                            struct qemud_driver *driver,
535
742
 
536
743
    /* Extract domain name */
537
744
    if (!(tmp = virXPathString("string(./name[1])", ctxt))) {
538
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
539
 
                        "%s", _("missing name element in migration data"));
 
745
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
746
                       "%s", _("missing name element in migration data"));
540
747
        goto error;
541
748
    }
542
749
    if (STRNEQ(tmp, mig->name)) {
543
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
544
 
                        _("Incoming cookie data had unexpected name %s vs %s"),
545
 
                        tmp, mig->name);
 
750
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
751
                       _("Incoming cookie data had unexpected name %s vs %s"),
 
752
                       tmp, mig->name);
546
753
        goto error;
547
754
    }
548
755
    VIR_FREE(tmp);
550
757
    /* Extract domain uuid */
551
758
    tmp = virXPathString("string(./uuid[1])", ctxt);
552
759
    if (!tmp) {
553
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
554
 
                        "%s", _("missing uuid element in migration data"));
 
760
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
761
                       "%s", _("missing uuid element in migration data"));
555
762
        goto error;
556
763
    }
557
764
    virUUIDFormat(mig->uuid, uuidstr);
558
765
    if (STRNEQ(tmp, uuidstr)) {
559
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
560
 
                        _("Incoming cookie data had unexpected UUID %s vs %s"),
561
 
                        tmp, uuidstr);
 
766
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
767
                       _("Incoming cookie data had unexpected UUID %s vs %s"),
 
768
                       tmp, uuidstr);
562
769
    }
563
770
    VIR_FREE(tmp);
564
771
 
565
772
    /* Check & forbid "localhost" migration */
566
773
    if (!(mig->remoteHostname = virXPathString("string(./hostname[1])", ctxt))) {
567
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
568
 
                        "%s", _("missing hostname element in migration data"));
 
774
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
775
                       "%s", _("missing hostname element in migration data"));
569
776
        goto error;
570
777
    }
571
778
    if (STREQ(mig->remoteHostname, mig->localHostname)) {
572
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
573
 
                        _("Attempt to migrate guest to the same host %s"),
574
 
                        mig->remoteHostname);
 
779
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
780
                       _("Attempt to migrate guest to the same host %s"),
 
781
                       mig->remoteHostname);
575
782
        goto error;
576
783
    }
577
784
 
578
785
    if (!(tmp = virXPathString("string(./hostuuid[1])", ctxt))) {
579
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
580
 
                        "%s", _("missing hostuuid element in migration data"));
 
786
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
787
                       "%s", _("missing hostuuid element in migration data"));
581
788
        goto error;
582
789
    }
583
790
    if (virUUIDParse(tmp, mig->remoteHostuuid) < 0) {
584
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
585
 
                        "%s", _("malformed hostuuid element in migration data"));
 
791
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
792
                       "%s", _("malformed hostuuid element in migration data"));
586
793
        goto error;
587
794
    }
588
795
    if (memcmp(mig->remoteHostuuid, mig->localHostuuid, VIR_UUID_BUFLEN) == 0) {
589
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
590
 
                        _("Attempt to migrate guest to the same host %s"),
591
 
                        tmp);
 
796
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
797
                       _("Attempt to migrate guest to the same host %s"),
 
798
                       tmp);
592
799
        goto error;
593
800
    }
594
801
    VIR_FREE(tmp);
602
809
        int val;
603
810
        char *str = virXMLPropString(nodes[i], "name");
604
811
        if (!str) {
605
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
606
 
                            "%s", _("missing feature name"));
 
812
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
813
                           "%s", _("missing feature name"));
607
814
            goto error;
608
815
        }
609
816
 
610
817
        if ((val = qemuMigrationCookieFlagTypeFromString(str)) < 0) {
611
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
612
 
                            _("Unknown migration cookie feature %s"),
613
 
                            str);
 
818
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
819
                           _("Unknown migration cookie feature %s"),
 
820
                           str);
614
821
            VIR_FREE(str);
615
822
            goto error;
616
823
        }
617
824
 
618
825
        if ((flags & (1 << val)) == 0) {
619
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
620
 
                            _("Unsupported migration cookie feature %s"),
621
 
                            str);
 
826
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
827
                           _("Unsupported migration cookie feature %s"),
 
828
                           str);
622
829
            VIR_FREE(str);
623
830
        }
624
831
        VIR_FREE(str);
634
841
        virXPathBoolean("count(./lockstate) > 0", ctxt)) {
635
842
        mig->lockDriver = virXPathString("string(./lockstate[1]/@driver)", ctxt);
636
843
        if (!mig->lockDriver) {
637
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
638
 
                            _("Missing lock driver name in migration cookie"));
 
844
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
845
                           _("Missing lock driver name in migration cookie"));
639
846
            goto error;
640
847
        }
641
848
        mig->lockState = virXPathString("string(./lockstate[1]/leases[1])", ctxt);
646
853
    if ((flags & QEMU_MIGRATION_COOKIE_PERSISTENT) &&
647
854
        virXPathBoolean("count(./domain) > 0", ctxt)) {
648
855
        if ((n = virXPathNodeSet("./domain", ctxt, &nodes)) > 1) {
649
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
650
 
                            _("Too many domain elements in "
651
 
                              "migration cookie: %d"),
652
 
                            n);
 
856
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
857
                           _("Too many domain elements in "
 
858
                             "migration cookie: %d"),
 
859
                           n);
653
860
            goto error;
654
861
        }
655
862
        mig->persistent = virDomainDefParseNode(driver->caps, doc, nodes[0],
662
869
        VIR_FREE(nodes);
663
870
    }
664
871
 
 
872
    if ((flags & QEMU_MIGRATION_COOKIE_NETWORK) &&
 
873
        virXPathBoolean("count(./network) > 0", ctxt) &&
 
874
        (!(mig->network = qemuMigrationCookieNetworkXMLParse(ctxt))))
 
875
        goto error;
 
876
 
665
877
    return 0;
666
878
 
667
879
error:
721
933
        qemuMigrationCookieAddPersistent(mig, dom) < 0)
722
934
        return -1;
723
935
 
 
936
    if (flags & QEMU_MIGRATION_COOKIE_NETWORK &&
 
937
        qemuMigrationCookieAddNetwork(mig, driver, dom) < 0) {
 
938
        return -1;
 
939
    }
 
940
 
724
941
    if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
725
942
        return -1;
726
943
 
744
961
    /* Parse & validate incoming cookie (if any) */
745
962
    if (cookiein && cookieinlen &&
746
963
        cookiein[cookieinlen-1] != '\0') {
747
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
748
 
                        _("Migration cookie was not NULL terminated"));
 
964
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
965
                       _("Migration cookie was not NULL terminated"));
749
966
        goto error;
750
967
    }
751
968
 
764
981
    if (mig->flags & QEMU_MIGRATION_COOKIE_LOCKSTATE) {
765
982
        if (!mig->lockDriver) {
766
983
            if (virLockManagerPluginUsesState(driver->lockManager)) {
767
 
                qemuReportError(VIR_ERR_INTERNAL_ERROR,
768
 
                                _("Missing %s lock state for migration cookie"),
769
 
                                virLockManagerPluginGetName(driver->lockManager));
 
984
                virReportError(VIR_ERR_INTERNAL_ERROR,
 
985
                               _("Missing %s lock state for migration cookie"),
 
986
                               virLockManagerPluginGetName(driver->lockManager));
770
987
                goto error;
771
988
            }
772
989
        } else if (STRNEQ(mig->lockDriver,
773
990
                          virLockManagerPluginGetName(driver->lockManager))) {
774
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
775
 
                            _("Source host lock driver %s different from target %s"),
776
 
                            mig->lockDriver,
777
 
                            virLockManagerPluginGetName(driver->lockManager));
 
991
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
992
                           _("Source host lock driver %s different from target %s"),
 
993
                           mig->lockDriver,
 
994
                           virLockManagerPluginGetName(driver->lockManager));
778
995
            goto error;
779
996
        }
780
997
    }
800
1017
                       virDomainDefPtr def)
801
1018
{
802
1019
    int nsnapshots;
 
1020
    bool forbid;
 
1021
    int i;
803
1022
 
804
1023
    if (vm) {
805
1024
        if (qemuProcessAutoDestroyActive(driver, vm)) {
806
 
            qemuReportError(VIR_ERR_OPERATION_INVALID,
807
 
                            "%s", _("domain is marked for auto destroy"));
 
1025
            virReportError(VIR_ERR_OPERATION_INVALID,
 
1026
                           "%s", _("domain is marked for auto destroy"));
808
1027
            return false;
809
1028
        }
810
 
        if ((nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, NULL,
 
1029
        if ((nsnapshots = virDomainSnapshotObjListNum(vm->snapshots, NULL,
811
1030
                                                      0))) {
812
 
            qemuReportError(VIR_ERR_OPERATION_INVALID,
813
 
                            _("cannot migrate domain with %d snapshots"),
814
 
                            nsnapshots);
 
1031
            virReportError(VIR_ERR_OPERATION_INVALID,
 
1032
                           _("cannot migrate domain with %d snapshots"),
 
1033
                           nsnapshots);
 
1034
            return false;
 
1035
        }
 
1036
        if (virDomainHasDiskMirror(vm)) {
 
1037
            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
 
1038
                           _("cannot migrate domain with active block job"));
815
1039
            return false;
816
1040
        }
817
1041
 
818
1042
        def = vm->def;
819
1043
    }
820
 
    if (def->nhostdevs > 0) {
821
 
        qemuReportError(VIR_ERR_OPERATION_INVALID,
822
 
            "%s", _("Domain with assigned host devices cannot be migrated"));
 
1044
 
 
1045
    /* Migration with USB host devices is allowed, all other devices are
 
1046
     * forbidden.
 
1047
     */
 
1048
    forbid = false;
 
1049
    for (i = 0; i < def->nhostdevs; i++) {
 
1050
        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
 
1051
        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
 
1052
            hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
 
1053
            forbid = true;
 
1054
            break;
 
1055
        }
 
1056
    }
 
1057
    if (forbid) {
 
1058
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
 
1059
                       _("Domain with assigned non-USB host devices "
 
1060
                         "cannot be migrated"));
823
1061
        return false;
824
1062
    }
825
1063
 
847
1085
                    continue;
848
1086
                else if (cfs < 0)
849
1087
                    return false;
 
1088
            } else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
 
1089
                       disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) {
 
1090
                continue;
850
1091
            }
851
1092
 
852
 
            qemuReportError(VIR_ERR_MIGRATE_UNSAFE, "%s",
853
 
                            _("Migration may lead to data corruption if disks"
854
 
                              " use cache != none"));
 
1093
            virReportError(VIR_ERR_MIGRATE_UNSAFE, "%s",
 
1094
                           _("Migration may lead to data corruption if disks"
 
1095
                             " use cache != none"));
855
1096
            return false;
856
1097
        }
857
1098
    }
893
1134
    qemuDomainObjPrivatePtr priv = vm->privateData;
894
1135
    int ret;
895
1136
    int status;
 
1137
    bool wait_for_spice = false;
 
1138
    bool spice_migrated = false;
896
1139
    unsigned long long memProcessed;
897
1140
    unsigned long long memRemaining;
898
1141
    unsigned long long memTotal;
899
1142
 
 
1143
    /* If guest uses SPICE and supports seamles_migration we have to hold up
 
1144
     * migration finish until SPICE server transfers its data */
 
1145
    if (vm->def->ngraphics == 1 &&
 
1146
        vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
 
1147
        qemuCapsGet(priv->caps, QEMU_CAPS_SEAMLESS_MIGRATION))
 
1148
        wait_for_spice = true;
 
1149
 
900
1150
    ret = qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob);
901
1151
    if (ret < 0) {
902
1152
        /* Guest already exited; nothing further to update.  */
907
1157
                                        &memProcessed,
908
1158
                                        &memRemaining,
909
1159
                                        &memTotal);
 
1160
 
 
1161
    /* If qemu says migrated, check spice */
 
1162
    if (wait_for_spice && (ret == 0) &&
 
1163
        (status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED))
 
1164
        ret = qemuMonitorGetSpiceMigrationStatus(priv->mon,
 
1165
                                                 &spice_migrated);
 
1166
 
910
1167
    qemuDomainObjExitMonitorWithDriver(driver, vm);
911
1168
 
912
1169
    if (ret < 0 || virTimeMillisNow(&priv->job.info.timeElapsed) < 0) {
919
1176
    switch (status) {
920
1177
    case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
921
1178
        priv->job.info.type = VIR_DOMAIN_JOB_NONE;
922
 
        qemuReportError(VIR_ERR_OPERATION_FAILED,
923
 
                        _("%s: %s"), job, _("is not active"));
 
1179
        virReportError(VIR_ERR_OPERATION_FAILED,
 
1180
                       _("%s: %s"), job, _("is not active"));
924
1181
        break;
925
1182
 
926
1183
    case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
936
1193
        break;
937
1194
 
938
1195
    case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
939
 
        priv->job.info.type = VIR_DOMAIN_JOB_COMPLETED;
 
1196
        if ((wait_for_spice && spice_migrated) || (!wait_for_spice))
 
1197
            priv->job.info.type = VIR_DOMAIN_JOB_COMPLETED;
940
1198
        ret = 0;
941
1199
        break;
942
1200
 
943
1201
    case QEMU_MONITOR_MIGRATION_STATUS_ERROR:
944
1202
        priv->job.info.type = VIR_DOMAIN_JOB_FAILED;
945
 
        qemuReportError(VIR_ERR_OPERATION_FAILED,
946
 
                        _("%s: %s"), job, _("unexpectedly failed"));
 
1203
        virReportError(VIR_ERR_OPERATION_FAILED,
 
1204
                       _("%s: %s"), job, _("unexpectedly failed"));
947
1205
        break;
948
1206
 
949
1207
    case QEMU_MONITOR_MIGRATION_STATUS_CANCELLED:
950
1208
        priv->job.info.type = VIR_DOMAIN_JOB_CANCELLED;
951
 
        qemuReportError(VIR_ERR_OPERATION_ABORTED,
952
 
                        _("%s: %s"), job, _("canceled by client"));
 
1209
        virReportError(VIR_ERR_OPERATION_ABORTED,
 
1210
                       _("%s: %s"), job, _("canceled by client"));
953
1211
        break;
954
1212
    }
955
1213
 
989
1247
            goto cleanup;
990
1248
 
991
1249
        if (dconn && virConnectIsAlive(dconn) <= 0) {
992
 
            qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
993
 
                            _("Lost connection to destination host"));
 
1250
            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
 
1251
                           _("Lost connection to destination host"));
994
1252
            goto cleanup;
995
1253
        }
996
1254
 
1047
1305
}
1048
1306
 
1049
1307
 
 
1308
static int
 
1309
qemuDomainMigrateOPDRelocate(struct qemud_driver *driver ATTRIBUTE_UNUSED,
 
1310
                             virDomainObjPtr vm,
 
1311
                             qemuMigrationCookiePtr cookie)
 
1312
{
 
1313
    virDomainNetDefPtr netptr;
 
1314
    int ret = -1;
 
1315
    int i;
 
1316
 
 
1317
    for (i = 0; i < cookie->network->nnets; i++) {
 
1318
        netptr = vm->def->nets[i];
 
1319
 
 
1320
        switch (cookie->network->net[i].vporttype) {
 
1321
        case VIR_NETDEV_VPORT_PROFILE_NONE:
 
1322
        case VIR_NETDEV_VPORT_PROFILE_8021QBG:
 
1323
        case VIR_NETDEV_VPORT_PROFILE_8021QBH:
 
1324
           break;
 
1325
        case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH:
 
1326
            if (virNetDevOpenvswitchSetMigrateData(cookie->network->net[i].portdata,
 
1327
                                                   netptr->ifname) != 0) {
 
1328
                virReportSystemError(VIR_ERR_INTERNAL_ERROR,
 
1329
                                     _("Unable to run command to set OVS port data for "
 
1330
                                     "interface %s"), netptr->ifname);
 
1331
                goto cleanup;
 
1332
            }
 
1333
            break;
 
1334
        default:
 
1335
            break;
 
1336
        }
 
1337
    }
 
1338
 
 
1339
    ret = 0;
 
1340
cleanup:
 
1341
    return ret;
 
1342
}
 
1343
 
 
1344
 
1050
1345
/* This is called for outgoing non-p2p migrations when a connection to the
1051
1346
 * client which initiated the migration was closed but we were waiting for it
1052
1347
 * to follow up with the next phase, that is, in between
1155
1450
            goto cleanup;
1156
1451
 
1157
1452
        if (STRNEQ(def->name, vm->def->name)) {
1158
 
            qemuReportError(VIR_ERR_INVALID_ARG, "%s",
1159
 
                            _("target domain name doesn't match source name"));
 
1453
            virReportError(VIR_ERR_INVALID_ARG, "%s",
 
1454
                           _("target domain name doesn't match source name"));
1160
1455
            goto cleanup;
1161
1456
        }
1162
1457
 
1244
1539
        int hookret;
1245
1540
 
1246
1541
        if (!(xml = qemuDomainDefFormatXML(driver, def,
1247
 
                                           VIR_DOMAIN_XML_SECURE, false)))
 
1542
                                           VIR_DOMAIN_XML_SECURE |
 
1543
                                           VIR_DOMAIN_XML_MIGRATABLE)))
1248
1544
            goto cleanup;
1249
1545
 
1250
1546
        hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
1366
1662
     * This prevents any other APIs being invoked while incoming
1367
1663
     * migration is taking place.
1368
1664
     */
1369
 
    if (qemuMigrationJobContinue(vm) == 0) {
 
1665
    if (!qemuMigrationJobContinue(vm)) {
1370
1666
        vm = NULL;
1371
 
        qemuReportError(VIR_ERR_OPERATION_FAILED,
1372
 
                        "%s", _("domain disappeared"));
 
1667
        virReportError(VIR_ERR_OPERATION_FAILED,
 
1668
                       "%s", _("domain disappeared"));
1373
1669
        goto cleanup;
1374
1670
    }
1375
1671
 
1393
1689
    return ret;
1394
1690
 
1395
1691
endjob:
1396
 
    if (qemuMigrationJobFinish(driver, vm) == 0) {
 
1692
    if (!qemuMigrationJobFinish(driver, vm)) {
1397
1693
        vm = NULL;
1398
1694
    }
1399
1695
    goto cleanup;
1477
1773
            goto cleanup;
1478
1774
 
1479
1775
        if (STRPREFIX(hostname, "localhost")) {
1480
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1481
 
                            _("hostname on destination resolved to localhost,"
1482
 
                              " but migration requires an FQDN"));
 
1776
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
1777
                           _("hostname on destination resolved to localhost,"
 
1778
                             " but migration requires an FQDN"));
1483
1779
            goto cleanup;
1484
1780
        }
1485
1781
 
1499
1795
         * characters in hostname part don't matter.
1500
1796
         */
1501
1797
        if (!STRPREFIX (uri_in, "tcp:")) {
1502
 
            qemuReportError(VIR_ERR_INVALID_ARG, "%s",
1503
 
                            _("only tcp URIs are supported for KVM/QEMU"
1504
 
                              " migrations"));
 
1798
            virReportError(VIR_ERR_INVALID_ARG, "%s",
 
1799
                           _("only tcp URIs are supported for KVM/QEMU"
 
1800
                             " migrations"));
1505
1801
            goto cleanup;
1506
1802
        }
1507
1803
 
1523
1819
            p++; /* definitely has a ':' in it, see above */
1524
1820
            this_port = virParseNumber (&p);
1525
1821
            if (this_port == -1 || p-uri_in != strlen (uri_in)) {
1526
 
                qemuReportError(VIR_ERR_INVALID_ARG,
1527
 
                                "%s", _("URI ended with incorrect ':port'"));
 
1822
                virReportError(VIR_ERR_INVALID_ARG,
 
1823
                               "%s", _("URI ended with incorrect ':port'"));
1528
1824
                goto cleanup;
1529
1825
            }
1530
1826
        }
1802
2098
        goto cleanup;
1803
2099
    if (virNetSocketNewConnectTCP(host, port, &sock) == 0) {
1804
2100
        spec->dest.fd.qemu = virNetSocketDupFD(sock, true);
1805
 
        virNetSocketFree(sock);
 
2101
        virObjectUnref(sock);
1806
2102
    }
1807
2103
    if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0 ||
1808
2104
        spec->dest.fd.qemu == -1)
1847
2143
 
1848
2144
    if (virLockManagerPluginUsesState(driver->lockManager) &&
1849
2145
        !cookieout) {
1850
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
1851
 
                        _("Migration with lock driver %s requires"
1852
 
                          " cookie support"),
1853
 
                        virLockManagerPluginGetName(driver->lockManager));
 
2146
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
2147
                       _("Migration with lock driver %s requires"
 
2148
                         " cookie support"),
 
2149
                       virLockManagerPluginGetName(driver->lockManager));
1854
2150
        return -1;
1855
2151
    }
1856
2152
 
1902
2198
        break;
1903
2199
 
1904
2200
    case MIGRATION_DEST_UNIX:
1905
 
        if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) {
 
2201
        if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) {
1906
2202
            ret = qemuMonitorMigrateToUnix(priv->mon, migrate_flags,
1907
2203
                                           spec->dest.unix_socket.file);
1908
2204
        } else {
1929
2225
    ret = -1;
1930
2226
 
1931
2227
    if (!virDomainObjIsActive(vm)) {
1932
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1933
 
                        _("guest unexpectedly quit"));
 
2228
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
2229
                       _("guest unexpectedly quit"));
1934
2230
        goto cleanup;
1935
2231
    }
1936
2232
 
1991
2287
 
1992
2288
    if (ret == 0 &&
1993
2289
        qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen,
1994
 
                                QEMU_MIGRATION_COOKIE_PERSISTENT ) < 0)
 
2290
                                QEMU_MIGRATION_COOKIE_PERSISTENT |
 
2291
                                QEMU_MIGRATION_COOKIE_NETWORK) < 0) {
1995
2292
        VIR_WARN("Unable to encode migration cookie");
 
2293
    }
1996
2294
 
1997
2295
    qemuMigrationCookieFree(mig);
1998
2296
 
2055
2353
    if (!uribits)
2056
2354
        return -1;
2057
2355
 
2058
 
    if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD))
 
2356
    if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD))
2059
2357
        spec.destType = MIGRATION_DEST_CONNECT_HOST;
2060
2358
    else
2061
2359
        spec.destType = MIGRATION_DEST_HOST;
2096
2394
              driver, vm, st, NULLSTR(cookiein), cookieinlen,
2097
2395
              cookieout, cookieoutlen, flags, resource);
2098
2396
 
2099
 
    if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
2100
 
        !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX) &&
2101
 
        !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) {
2102
 
        qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
2103
 
                        _("Source qemu is too old to support tunnelled migration"));
 
2397
    if (!qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
 
2398
        !qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_UNIX) &&
 
2399
        !qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) {
 
2400
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
 
2401
                       _("Source qemu is too old to support tunnelled migration"));
2104
2402
        return -1;
2105
2403
    }
2106
2404
 
2107
2405
    spec.fwdType = MIGRATION_FWD_STREAM;
2108
2406
    spec.fwd.stream = st;
2109
2407
 
2110
 
    if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) {
 
2408
    if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD)) {
2111
2409
        int fds[2];
2112
2410
 
2113
2411
        spec.destType = MIGRATION_DEST_FD;
2154
2452
        VIR_FORCE_CLOSE(spec.dest.fd.qemu);
2155
2453
        VIR_FORCE_CLOSE(spec.dest.fd.local);
2156
2454
    } else {
2157
 
        virNetSocketFree(sock);
 
2455
        virObjectUnref(sock);
2158
2456
        VIR_FREE(spec.dest.unix_socket.file);
2159
2457
    }
2160
2458
 
2193
2491
     * and pass it to Prepare2.
2194
2492
     */
2195
2493
    if (!(dom_xml = qemuDomainFormatXML(driver, vm,
2196
 
                                        VIR_DOMAIN_XML_SECURE |
2197
 
                                        VIR_DOMAIN_XML_UPDATE_CPU,
2198
 
                                        true)))
 
2494
                                        QEMU_DOMAIN_FORMAT_LIVE_FLAGS |
 
2495
                                        VIR_DOMAIN_XML_MIGRATABLE)))
2199
2496
        return -1;
2200
2497
 
2201
2498
    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
2230
2527
     * in qemuDomainObjEnterRemoteWithDriver, so check again
2231
2528
     */
2232
2529
    if (!virDomainObjIsActive(vm)) {
2233
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2234
 
                        _("guest unexpectedly quit"));
 
2530
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
2531
                       _("guest unexpectedly quit"));
2235
2532
        goto cleanup;
2236
2533
    }
2237
2534
 
2238
2535
    if (!(flags & VIR_MIGRATE_TUNNELLED) &&
2239
2536
        (uri_out == NULL)) {
2240
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
2241
 
                        _("domainMigratePrepare2 did not set uri"));
 
2537
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
2538
                       _("domainMigratePrepare2 did not set uri"));
2242
2539
        cancelled = 1;
2243
2540
        goto finish;
2244
2541
    }
2282
2579
 
2283
2580
cleanup:
2284
2581
    if (ddomain) {
2285
 
        virUnrefDomain(ddomain);
 
2582
        virObjectUnref(ddomain);
2286
2583
        ret = 0;
2287
2584
    } else {
2288
2585
        ret = -1;
2289
2586
    }
2290
2587
 
2291
 
    if (st)
2292
 
        virUnrefStream(st);
 
2588
    virObjectUnref(st);
2293
2589
 
2294
2590
    if (orig_err) {
2295
2591
        virSetError(orig_err);
2375
2671
 
2376
2672
    if (!(flags & VIR_MIGRATE_TUNNELLED) &&
2377
2673
        (uri_out == NULL)) {
2378
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
2379
 
                        _("domainMigratePrepare3 did not set uri"));
 
2674
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
2675
                       _("domainMigratePrepare3 did not set uri"));
2380
2676
        cancelled = 1;
2381
2677
        goto finish;
2382
2678
    }
2457
2753
     * If cancelled, then src VM will be restarted, else
2458
2754
     * it will be killed
2459
2755
     */
2460
 
    VIR_DEBUG("Confirm3 %p ret=%d vm=%p", sconn, ret, vm);
 
2756
    VIR_DEBUG("Confirm3 %p cancelled=%d vm=%p", sconn, cancelled, vm);
2461
2757
    VIR_FREE(cookiein);
2462
2758
    cookiein = cookieout;
2463
2759
    cookieinlen = cookieoutlen;
2476
2772
 
2477
2773
 cleanup:
2478
2774
    if (ddomain) {
2479
 
        virUnrefDomain(ddomain);
 
2775
        virObjectUnref(ddomain);
2480
2776
        ret = 0;
2481
2777
    } else {
2482
2778
        ret = -1;
2483
2779
    }
2484
2780
 
2485
 
    if (st)
2486
 
        virUnrefStream(st);
 
2781
    virObjectUnref(st);
2487
2782
 
2488
2783
    if (orig_err) {
2489
2784
        virSetError(orig_err);
2526
2821
    dconn = virConnectOpen(dconnuri);
2527
2822
    qemuDomainObjExitRemoteWithDriver(driver, vm);
2528
2823
    if (dconn == NULL) {
2529
 
        qemuReportError(VIR_ERR_OPERATION_FAILED,
2530
 
                        _("Failed to connect to remote libvirt URI %s"), dconnuri);
 
2824
        virReportError(VIR_ERR_OPERATION_FAILED,
 
2825
                       _("Failed to connect to remote libvirt URI %s"), dconnuri);
2531
2826
        return -1;
2532
2827
    }
2533
2828
 
2547
2842
    qemuDomainObjExitRemoteWithDriver(driver, vm);
2548
2843
 
2549
2844
    if (!p2p) {
2550
 
        qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
2551
 
                        _("Destination libvirt does not support peer-to-peer migration protocol"));
 
2845
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
 
2846
                       _("Destination libvirt does not support peer-to-peer migration protocol"));
2552
2847
        goto cleanup;
2553
2848
    }
2554
2849
 
2555
2850
    /* domain may have been stopped while we were talking to remote daemon */
2556
2851
    if (!virDomainObjIsActive(vm)) {
2557
 
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2558
 
                        _("guest unexpectedly quit"));
 
2852
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
2853
                       _("guest unexpectedly quit"));
2559
2854
        goto cleanup;
2560
2855
    }
2561
2856
 
2617
2912
        goto cleanup;
2618
2913
 
2619
2914
    if (!virDomainObjIsActive(vm)) {
2620
 
        qemuReportError(VIR_ERR_OPERATION_INVALID,
2621
 
                        "%s", _("domain is not running"));
 
2915
        virReportError(VIR_ERR_OPERATION_INVALID,
 
2916
                       "%s", _("domain is not running"));
2622
2917
        goto endjob;
2623
2918
    }
2624
2919
 
2625
2920
    if (!qemuMigrationIsAllowed(driver, vm, NULL))
2626
 
        goto cleanup;
 
2921
        goto endjob;
2627
2922
 
2628
2923
    if (!(flags & VIR_MIGRATE_UNSAFE) && !qemuMigrationIsSafe(vm->def))
2629
 
        goto cleanup;
 
2924
        goto endjob;
2630
2925
 
2631
2926
    resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING;
2632
2927
 
2679
2974
                                         VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
2680
2975
    }
2681
2976
 
2682
 
    if (qemuMigrationJobFinish(driver, vm) == 0) {
 
2977
    if (!qemuMigrationJobFinish(driver, vm)) {
2683
2978
        vm = NULL;
2684
2979
    } else if (!virDomainObjIsActive(vm) &&
2685
2980
               (!vm->persistent ||
2721
3016
    virDomainEventPtr event = NULL;
2722
3017
    int ret = -1;
2723
3018
    bool resume;
2724
 
    int refs;
 
3019
    bool hasrefs;
2725
3020
 
2726
3021
    /* If we didn't start the job in the begin phase, start it now. */
2727
3022
    if (!(flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
2769
3064
 
2770
3065
endjob:
2771
3066
    if (ret < 0)
2772
 
        refs = qemuMigrationJobFinish(driver, vm);
 
3067
        hasrefs = qemuMigrationJobFinish(driver, vm);
2773
3068
    else
2774
 
        refs = qemuMigrationJobContinue(vm);
2775
 
    if (refs == 0) {
 
3069
        hasrefs = qemuMigrationJobContinue(vm);
 
3070
    if (!hasrefs) {
2776
3071
        vm = NULL;
2777
3072
    } else if (!virDomainObjIsActive(vm) && !vm->persistent) {
2778
3073
        qemuDomainRemoveInactive(driver, vm);
2813
3108
 
2814
3109
    if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) {
2815
3110
        if (cookieinlen) {
2816
 
            qemuReportError(VIR_ERR_OPERATION_INVALID,
2817
 
                            "%s", _("received unexpected cookie with P2P migration"));
 
3111
            virReportError(VIR_ERR_OPERATION_INVALID,
 
3112
                           "%s", _("received unexpected cookie with P2P migration"));
2818
3113
            return -1;
2819
3114
        }
2820
3115
 
2824
3119
                                       v3proto);
2825
3120
    } else {
2826
3121
        if (dconnuri) {
2827
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
2828
 
                            "%s", _("Unexpected dconnuri parameter with non-peer2peer migration"));
 
3122
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
3123
                           "%s", _("Unexpected dconnuri parameter with non-peer2peer migration"));
2829
3124
            return -1;
2830
3125
        }
2831
3126
 
2854
3149
        if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
2855
3150
            if (virNetDevVPortProfileAssociate(net->ifname,
2856
3151
                                               virDomainNetGetActualVirtPortProfile(net),
2857
 
                                               net->mac,
 
3152
                                               &net->mac,
2858
3153
                                               virDomainNetGetActualDirectDev(net),
2859
3154
                                               -1,
2860
3155
                                               def->uuid,
2861
3156
                                               VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH,
2862
3157
                                               false) < 0) {
2863
 
                qemuReportError(VIR_ERR_OPERATION_FAILED,
2864
 
                                _("Port profile Associate failed for %s"),
2865
 
                                net->ifname);
 
3158
                virReportError(VIR_ERR_OPERATION_FAILED,
 
3159
                               _("Port profile Associate failed for %s"),
 
3160
                               net->ifname);
2866
3161
                goto err_exit;
2867
3162
            }
2868
3163
            VIR_DEBUG("Port profile Associate succeeded for %s", net->ifname);
2869
3164
 
2870
 
            if (virNetDevMacVLanVPortProfileRegisterCallback(net->ifname, net->mac,
 
3165
            if (virNetDevMacVLanVPortProfileRegisterCallback(net->ifname, &net->mac,
2871
3166
                                                             virDomainNetGetActualDirectDev(net), def->uuid,
2872
3167
                                                             virDomainNetGetActualVirtPortProfile(net),
2873
3168
                                                             VIR_NETDEV_VPORT_PROFILE_OP_CREATE))
2884
3179
        if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
2885
3180
            ignore_value(virNetDevVPortProfileDisassociate(net->ifname,
2886
3181
                                                           virDomainNetGetActualVirtPortProfile(net),
2887
 
                                                           net->mac,
 
3182
                                                           &net->mac,
2888
3183
                                                           virDomainNetGetActualDirectDev(net),
2889
3184
                                                           -1,
2890
3185
                                                           VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH));
2928
3223
 
2929
3224
    qemuDomainCleanupRemove(vm, qemuMigrationPrepareCleanup);
2930
3225
 
 
3226
    cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK;
2931
3227
    if (flags & VIR_MIGRATE_PERSIST_DEST)
2932
3228
        cookie_flags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
2933
3229
 
2940
3236
     */
2941
3237
    if (retcode == 0) {
2942
3238
        if (!virDomainObjIsActive(vm)) {
2943
 
            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2944
 
                            _("guest unexpectedly quit"));
 
3239
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
3240
                           _("guest unexpectedly quit"));
2945
3241
            goto endjob;
2946
3242
        }
2947
3243
 
2955
3251
            goto endjob;
2956
3252
        }
2957
3253
 
 
3254
        if (mig->network)
 
3255
            if (qemuDomainMigrateOPDRelocate(driver, vm, mig) < 0)
 
3256
                VIR_WARN("unable to provide network data for relocation");
 
3257
 
2958
3258
        if (flags & VIR_MIGRATE_PERSIST_DEST) {
2959
3259
            virDomainDefPtr vmdef;
2960
3260
            if (vm->persistent)
2987
3287
                        vm->persistent = 0;
2988
3288
                }
2989
3289
                if (!vmdef)
2990
 
                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2991
 
                                    _("can't get vmdef"));
 
3290
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
3291
                                   _("can't get vmdef"));
2992
3292
                goto endjob;
2993
3293
            }
2994
3294
 
3011
3311
                                     VIR_DOMAIN_RUNNING_MIGRATED,
3012
3312
                                     QEMU_ASYNC_JOB_MIGRATION_IN) < 0) {
3013
3313
                if (virGetLastError() == NULL)
3014
 
                    qemuReportError(VIR_ERR_INTERNAL_ERROR,
3015
 
                                    "%s", _("resume operation failed"));
 
3314
                    virReportError(VIR_ERR_INTERNAL_ERROR,
 
3315
                                   "%s", _("resume operation failed"));
3016
3316
                /* Need to save the current error, in case shutting
3017
3317
                 * down the process overwrites it
3018
3318
                 */
3141
3441
                                 VIR_DOMAIN_RUNNING_MIGRATED,
3142
3442
                                 QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) {
3143
3443
            if (virGetLastError() == NULL)
3144
 
                qemuReportError(VIR_ERR_INTERNAL_ERROR,
3145
 
                                "%s", _("resume operation failed"));
 
3444
                virReportError(VIR_ERR_INTERNAL_ERROR,
 
3445
                               "%s", _("resume operation failed"));
3146
3446
            goto cleanup;
3147
3447
        }
3148
3448
 
3186
3486
     * Failure to change migration speed is not fatal. */
3187
3487
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
3188
3488
        qemuMonitorSetMigrationSpeed(priv->mon,
3189
 
                                     QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX);
3190
 
        priv->migMaxBandwidth = QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX;
 
3489
                                     QEMU_DOMAIN_MIG_BANDWIDTH_MAX);
 
3490
        priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
3191
3491
        qemuDomainObjExitMonitorWithDriver(driver, vm);
3192
3492
    }
3193
3493
 
3194
 
    if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
 
3494
    if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
3195
3495
        (!compressor || pipe(pipeFD) == 0)) {
3196
3496
        /* All right! We can use fd migration, which means that qemu
3197
3497
         * doesn't have to open() the file, so while we still have to
3211
3511
                                       VIR_CGROUP_CONTROLLER_DEVICES)) {
3212
3512
            if (virCgroupForDomain(driver->cgroup, vm->def->name,
3213
3513
                                   &cgroup, 0) != 0) {
3214
 
                qemuReportError(VIR_ERR_INTERNAL_ERROR,
3215
 
                                _("Unable to find cgroup for %s"),
3216
 
                                vm->def->name);
 
3514
                virReportError(VIR_ERR_INTERNAL_ERROR,
 
3515
                               _("Unable to find cgroup for %s"),
 
3516
                               vm->def->name);
3217
3517
                goto cleanup;
3218
3518
            }
3219
3519
            rc = virCgroupAllowDevicePath(cgroup, path,
3242
3542
    if (!compressor) {
3243
3543
        const char *args[] = { "cat", NULL };
3244
3544
 
3245
 
        if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
 
3545
        if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
3246
3546
            priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX) {
3247
3547
            rc = qemuMonitorMigrateToFd(priv->mon,
3248
3548
                                        QEMU_MONITOR_MIGRATE_BACKGROUND,
3373
3673
                           virDomainObjPtr vm,
3374
3674
                           enum qemuMigrationJobPhase phase)
3375
3675
{
3376
 
    virDomainObjRef(vm);
 
3676
    virObjectRef(vm);
3377
3677
    qemuMigrationJobSetPhase(driver, vm, phase);
3378
3678
}
3379
3679
 
3380
 
int
 
3680
bool
3381
3681
qemuMigrationJobContinue(virDomainObjPtr vm)
3382
3682
{
3383
3683
    qemuDomainObjReleaseAsyncJob(vm);
3384
 
    return virDomainObjUnref(vm);
 
3684
    return virObjectUnref(vm);
3385
3685
}
3386
3686
 
3387
3687
bool
3398
3698
        else
3399
3699
            msg = _("domain '%s' is not being migrated");
3400
3700
 
3401
 
        qemuReportError(VIR_ERR_OPERATION_INVALID, msg, vm->def->name);
 
3701
        virReportError(VIR_ERR_OPERATION_INVALID, msg, vm->def->name);
3402
3702
        return false;
3403
3703
    }
3404
3704
    return true;
3405
3705
}
3406
3706
 
3407
 
int
 
3707
bool
3408
3708
qemuMigrationJobFinish(struct qemud_driver *driver, virDomainObjPtr vm)
3409
3709
{
3410
3710
    return qemuDomainObjEndAsyncJob(driver, vm);