add virsh --suspend arg to migrate command

This adds a new flag, VIR_MIGRATE_PAUSED, that mandates pausing
the migrated VM before starting it.

* include/libvirt/libvirt.h.in (virDomainMigrateFlags): Add VIR_MIGRATE_PAUSED.
* src/qemu/qemu_driver.c (qemudDomainMigrateFinish2): Handle VIR_MIGRATE_PAUSED.
* tools/virsh.c (opts_migrate): Add --suspend. (cmdMigrate): Handle it.
* tools/virsh.pod (migrate): Document it.
This commit is contained in:
Paolo Bonzini 2009-12-11 10:00:44 +01:00 committed by Daniel Veillard
parent ba7d82c699
commit edc9e78b48
5 changed files with 32 additions and 17 deletions

View File

@ -341,6 +341,7 @@ typedef enum {
VIR_MIGRATE_TUNNELLED = (1 << 2), /* tunnel migration data over libvirtd connection */ VIR_MIGRATE_TUNNELLED = (1 << 2), /* tunnel migration data over libvirtd connection */
VIR_MIGRATE_PERSIST_DEST = (1 << 3), /* persist the VM on the destination */ VIR_MIGRATE_PERSIST_DEST = (1 << 3), /* persist the VM on the destination */
VIR_MIGRATE_UNDEFINE_SOURCE = (1 << 4), /* undefine the VM on the source */ VIR_MIGRATE_UNDEFINE_SOURCE = (1 << 4), /* undefine the VM on the source */
VIR_MIGRATE_PAUSED = (1 << 5), /* pause on remote side */
} virDomainMigrateFlags; } virDomainMigrateFlags;
/* Domain migration. */ /* Domain migration. */

View File

@ -3179,6 +3179,7 @@ virDomainMigrateDirect (virDomainPtr domain,
* on the destination host. * on the destination host.
* VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the * VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
* domain on the source host. * domain on the source host.
* VIR_MIGRATE_PAUSED Leave the domain suspended on the remote side.
* *
* VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set. * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
* Applications using the VIR_MIGRATE_PEER2PEER flag will probably * Applications using the VIR_MIGRATE_PEER2PEER flag will probably

View File

@ -7540,24 +7540,33 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
dom = virGetDomain (dconn, vm->def->name, vm->def->uuid); dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
/* run 'cont' on the destination, which allows migration on qemu if (!(flags & VIR_MIGRATE_PAUSED)) {
* >= 0.10.6 to work properly. This isn't strictly necessary on /* run 'cont' on the destination, which allows migration on qemu
* older qemu's, but it also doesn't hurt anything there * >= 0.10.6 to work properly. This isn't strictly necessary on
*/ * older qemu's, but it also doesn't hurt anything there
qemuDomainObjEnterMonitorWithDriver(driver, vm); */
if (qemuMonitorStartCPUs(priv->mon, dconn) < 0) { qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (virGetLastError() == NULL) if (qemuMonitorStartCPUs(priv->mon, dconn) < 0) {
qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, if (virGetLastError() == NULL)
"%s", _("resume operation failed")); qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("resume operation failed"));
qemuDomainObjExitMonitorWithDriver(driver, vm);
goto endjob;
}
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitorWithDriver(driver, vm);
goto endjob;
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
vm->state = VIR_DOMAIN_RUNNING; vm->state = VIR_DOMAIN_RUNNING;
}
event = virDomainEventNewFromObj(vm, event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED,
VIR_DOMAIN_EVENT_RESUMED_MIGRATED); VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
if (vm->state == VIR_DOMAIN_PAUSED) {
qemuDomainEventQueue(driver, event);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_SUSPENDED,
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
}
virDomainSaveStatus(dconn, driver->caps, driver->stateDir, vm); virDomainSaveStatus(dconn, driver->caps, driver->stateDir, vm);
} else { } else {
qemudShutdownVMDaemon (dconn, driver, vm); qemudShutdownVMDaemon (dconn, driver, vm);

View File

@ -2478,6 +2478,7 @@ static const vshCmdOptDef opts_migrate[] = {
{"tunnelled", VSH_OT_BOOL, 0, gettext_noop("tunnelled migration")}, {"tunnelled", VSH_OT_BOOL, 0, gettext_noop("tunnelled migration")},
{"persistent", VSH_OT_BOOL, 0, gettext_noop("persist VM on destination")}, {"persistent", VSH_OT_BOOL, 0, gettext_noop("persist VM on destination")},
{"undefinesource", VSH_OT_BOOL, 0, gettext_noop("undefine VM on source")}, {"undefinesource", VSH_OT_BOOL, 0, gettext_noop("undefine VM on source")},
{"suspend", VSH_OT_BOOL, 0, gettext_noop("do not restart the domain on the destination host")},
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
{"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("connection URI of the destination host")}, {"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("connection URI of the destination host")},
{"migrateuri", VSH_OT_DATA, 0, gettext_noop("migration URI, usually can be omitted")}, {"migrateuri", VSH_OT_DATA, 0, gettext_noop("migration URI, usually can be omitted")},
@ -2519,10 +2520,12 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool (cmd, "persistent")) if (vshCommandOptBool (cmd, "persistent"))
flags |= VIR_MIGRATE_PERSIST_DEST; flags |= VIR_MIGRATE_PERSIST_DEST;
if (vshCommandOptBool (cmd, "undefinesource")) if (vshCommandOptBool (cmd, "undefinesource"))
flags |= VIR_MIGRATE_UNDEFINE_SOURCE; flags |= VIR_MIGRATE_UNDEFINE_SOURCE;
if (vshCommandOptBool (cmd, "suspend"))
flags |= VIR_MIGRATE_PAUSED;
if ((flags & VIR_MIGRATE_PEER2PEER) || if ((flags & VIR_MIGRATE_PEER2PEER) ||
vshCommandOptBool (cmd, "direct")) { vshCommandOptBool (cmd, "direct")) {
/* For peer2peer migration or direct migration we only expect one URI /* For peer2peer migration or direct migration we only expect one URI

View File

@ -302,10 +302,11 @@ except that it does some error checking.
The editor used can be supplied by the C<$EDITOR> environment The editor used can be supplied by the C<$EDITOR> environment
variable, or if that is not defined defaults to C<vi>. variable, or if that is not defined defaults to C<vi>.
=item B<migrate> optional I<--live> I<domain-id> I<desturi> I<migrateuri> =item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi> I<migrateuri>
Migrate domain to another host. Add --live for live migration. The I<desturi> Migrate domain to another host. Add --live for live migration; --suspend
is the connection URI of the destination host, and I<migrateuri> is the leaves the domain paused on the destination host. The I<desturi> is the
connection URI of the destination host, and I<migrateuri> is the
migration URI, which usually can be omitted. migration URI, which usually can be omitted.
=item B<reboot> I<domain-id> =item B<reboot> I<domain-id>