qemu: process: detect if dimm aliases are broken on reconnect

Detect on reconnect to a running qemu VM whether the alias of a
hotpluggable memory device (dimm) does not match the dimm slot number
where it's connected to. This is necessary as qemu is actually
considering the alias as machine ABI used to connect the backend object
to the dimm device.

This will require us to keep them consistent so that we can reliably
restore them on migration. In some situations it was currently possible
to create a mismatched configuration and qemu would refuse to restore
the migration stream.

To avoid breaking existing VMs we'll need to keep the old algorithm
though.
This commit is contained in:
Peter Krempa 2016-10-31 16:49:49 +01:00
parent 810e9a8061
commit 93d9ff3da0
2 changed files with 28 additions and 0 deletions

View File

@ -232,6 +232,9 @@ struct _qemuDomainObjPrivate {
/* private XML) - need to restore at process reconnect */ /* private XML) - need to restore at process reconnect */
uint8_t *masterKey; uint8_t *masterKey;
size_t masterKeyLen; size_t masterKeyLen;
/* note whether memory device alias does not correspond to slot number */
bool memAliasOrderMismatch;
}; };
# define QEMU_DOMAIN_PRIVATE(vm) \ # define QEMU_DOMAIN_PRIVATE(vm) \

View File

@ -3205,6 +3205,29 @@ qemuDomainPerfRestart(virDomainObjPtr vm)
return 0; return 0;
} }
static void
qemuProcessReconnectCheckMemAliasOrderMismatch(virDomainObjPtr vm)
{
size_t i;
int aliasidx;
virDomainDefPtr def = vm->def;
qemuDomainObjPrivatePtr priv = vm->privateData;
if (!virDomainDefHasMemoryHotplug(def) || def->nmems == 0)
return;
for (i = 0; i < def->nmems; i++) {
aliasidx = qemuDomainDeviceAliasIndex(&def->mems[i]->info, "dimm");
if (def->mems[i]->info.addr.dimm.slot != aliasidx) {
priv->memAliasOrderMismatch = true;
break;
}
}
}
struct qemuProcessReconnectData { struct qemuProcessReconnectData {
virConnectPtr conn; virConnectPtr conn;
virQEMUDriverPtr driver; virQEMUDriverPtr driver;
@ -3389,6 +3412,8 @@ qemuProcessReconnect(void *opaque)
if (qemuProcessUpdateDevices(driver, obj) < 0) if (qemuProcessUpdateDevices(driver, obj) < 0)
goto error; goto error;
qemuProcessReconnectCheckMemAliasOrderMismatch(obj);
/* Failure to connect to agent shouldn't be fatal */ /* Failure to connect to agent shouldn't be fatal */
if ((ret = qemuConnectAgent(driver, obj)) < 0) { if ((ret = qemuConnectAgent(driver, obj)) < 0) {
if (ret == -2) if (ret == -2)