提交 d57485f7 编写于 作者: J Jiri Denemark

qemu: Forbid migration with cache != none

Migrating domains with disks using cache != none is unsafe unless the
disk images are stored on coherent clustered filesystem. Thus we forbid
migrating such domains unless VIR_MIGRATE_UNSAFE flags is used.
上级 5fadb154
...@@ -8767,7 +8767,8 @@ qemuDomainMigrateBegin3(virDomainPtr domain, ...@@ -8767,7 +8767,8 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
goto endjob; goto endjob;
if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname, if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname,
cookieout, cookieoutlen))) cookieout, cookieoutlen,
flags)))
goto endjob; goto endjob;
if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "virtime.h" #include "virtime.h"
#include "locking/domain_lock.h" #include "locking/domain_lock.h"
#include "rpc/virnetsocket.h" #include "rpc/virnetsocket.h"
#include "storage_file.h"
#define VIR_FROM_THIS VIR_FROM_QEMU #define VIR_FROM_THIS VIR_FROM_QEMU
...@@ -817,6 +818,34 @@ qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm, ...@@ -817,6 +818,34 @@ qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm,
return true; return true;
} }
static bool
qemuMigrationIsSafe(virDomainDefPtr def)
{
int i;
for (i = 0 ; i < def->ndisks ; i++) {
virDomainDiskDefPtr disk = def->disks[i];
/* shared && !readonly implies cache=none */
if (disk->src &&
disk->cachemode != VIR_DOMAIN_DISK_CACHE_DISABLE &&
(disk->cachemode || !disk->shared || disk->readonly)) {
int cfs;
if ((cfs = virStorageFileIsClusterFS(disk->src)) == 1)
continue;
else if (cfs < 0)
return false;
qemuReportError(VIR_ERR_MIGRATE_UNSAFE, "%s",
_("Migration may lead to data corruption if disks"
" use cache != none"));
return false;
}
}
return true;
}
/** qemuMigrationSetOffline /** qemuMigrationSetOffline
* Pause domain for non-live migration. * Pause domain for non-live migration.
*/ */
...@@ -1010,7 +1039,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver, ...@@ -1010,7 +1039,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
const char *xmlin, const char *xmlin,
const char *dname, const char *dname,
char **cookieout, char **cookieout,
int *cookieoutlen) int *cookieoutlen,
unsigned long flags)
{ {
char *rv = NULL; char *rv = NULL;
qemuMigrationCookiePtr mig = NULL; qemuMigrationCookiePtr mig = NULL;
...@@ -1018,9 +1048,9 @@ char *qemuMigrationBegin(struct qemud_driver *driver, ...@@ -1018,9 +1048,9 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s," VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s,"
" cookieout=%p, cookieoutlen=%p", " cookieout=%p, cookieoutlen=%p, flags=%lx",
driver, vm, NULLSTR(xmlin), NULLSTR(dname), driver, vm, NULLSTR(xmlin), NULLSTR(dname),
cookieout, cookieoutlen); cookieout, cookieoutlen, flags);
/* Only set the phase if we are inside QEMU_ASYNC_JOB_MIGRATION_OUT. /* 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 * Otherwise we will start the async job later in the perform phase losing
...@@ -1032,6 +1062,9 @@ char *qemuMigrationBegin(struct qemud_driver *driver, ...@@ -1032,6 +1062,9 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
if (!qemuMigrationIsAllowed(driver, vm, NULL)) if (!qemuMigrationIsAllowed(driver, vm, NULL))
goto cleanup; goto cleanup;
if (!(flags & VIR_MIGRATE_UNSAFE) && !qemuMigrationIsSafe(vm->def))
goto cleanup;
if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0))) if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
goto cleanup; goto cleanup;
...@@ -2070,7 +2103,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver, ...@@ -2070,7 +2103,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
* a single job. */ * a single job. */
dom_xml = qemuMigrationBegin(driver, vm, xmlin, dname, dom_xml = qemuMigrationBegin(driver, vm, xmlin, dname,
&cookieout, &cookieoutlen); &cookieout, &cookieoutlen, flags);
if (!dom_xml) if (!dom_xml)
goto cleanup; goto cleanup;
...@@ -2354,6 +2387,9 @@ qemuMigrationPerformJob(struct qemud_driver *driver, ...@@ -2354,6 +2387,9 @@ qemuMigrationPerformJob(struct qemud_driver *driver,
if (!qemuMigrationIsAllowed(driver, vm, NULL)) if (!qemuMigrationIsAllowed(driver, vm, NULL))
goto cleanup; goto cleanup;
if (!(flags & VIR_MIGRATE_UNSAFE) && !qemuMigrationIsSafe(vm->def))
goto cleanup;
resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING; resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING;
if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) { if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) {
......
...@@ -35,7 +35,8 @@ ...@@ -35,7 +35,8 @@
VIR_MIGRATE_PAUSED | \ VIR_MIGRATE_PAUSED | \
VIR_MIGRATE_NON_SHARED_DISK | \ VIR_MIGRATE_NON_SHARED_DISK | \
VIR_MIGRATE_NON_SHARED_INC | \ VIR_MIGRATE_NON_SHARED_INC | \
VIR_MIGRATE_CHANGE_PROTECTION) VIR_MIGRATE_CHANGE_PROTECTION | \
VIR_MIGRATE_UNSAFE)
enum qemuMigrationJobPhase { enum qemuMigrationJobPhase {
QEMU_MIGRATION_PHASE_NONE = 0, QEMU_MIGRATION_PHASE_NONE = 0,
...@@ -81,7 +82,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver, ...@@ -81,7 +82,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
const char *xmlin, const char *xmlin,
const char *dname, const char *dname,
char **cookieout, char **cookieout,
int *cookieoutlen); int *cookieoutlen,
unsigned long flags);
int qemuMigrationPrepareTunnel(struct qemud_driver *driver, int qemuMigrationPrepareTunnel(struct qemud_driver *driver,
virConnectPtr dconn, virConnectPtr dconn,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册