conf: Forbid device alias change on device-update

https://bugzilla.redhat.com/show_bug.cgi?id=1585108

When updating a live device users might pass different alias than
the one the device has. Currently, this is silently ignored which
goes against our behaviour for other parts of the device where we
explicitly allow only certain changes and error out loudly on
anything else.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Michal Privoznik 2018-06-12 16:05:10 +02:00
parent 5e9b150fe0
commit 4ad54a417a
6 changed files with 40 additions and 25 deletions

View File

@ -28206,7 +28206,8 @@ int
virDomainDefCompatibleDevice(virDomainDefPtr def, virDomainDefCompatibleDevice(virDomainDefPtr def,
virDomainDeviceDefPtr dev, virDomainDeviceDefPtr dev,
virDomainDeviceDefPtr oldDev, virDomainDeviceDefPtr oldDev,
virDomainDeviceAction action ATTRIBUTE_UNUSED) virDomainDeviceAction action,
bool live)
{ {
virDomainCompatibleDeviceData data = { virDomainCompatibleDeviceData data = {
.newInfo = virDomainDeviceGetInfo(dev), .newInfo = virDomainDeviceGetInfo(dev),
@ -28216,6 +28217,16 @@ virDomainDefCompatibleDevice(virDomainDefPtr def,
if (oldDev) if (oldDev)
data.oldInfo = virDomainDeviceGetInfo(oldDev); data.oldInfo = virDomainDeviceGetInfo(oldDev);
if (action == VIR_DOMAIN_DEVICE_ACTION_UPDATE &&
live &&
((!!data.newInfo != !!data.oldInfo) ||
(data.newInfo && data.oldInfo &&
STRNEQ_NULLABLE(data.newInfo->alias, data.oldInfo->alias)))) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("changing device alias is not allowed"));
return -1;
}
if (!virDomainDefHasUSB(def) && if (!virDomainDefHasUSB(def) &&
def->os.type != VIR_DOMAIN_OSTYPE_EXE && def->os.type != VIR_DOMAIN_OSTYPE_EXE &&
virDomainDeviceIsUSB(dev)) { virDomainDeviceIsUSB(dev)) {

View File

@ -3107,7 +3107,8 @@ typedef enum {
int virDomainDefCompatibleDevice(virDomainDefPtr def, int virDomainDefCompatibleDevice(virDomainDefPtr def,
virDomainDeviceDefPtr dev, virDomainDeviceDefPtr dev,
virDomainDeviceDefPtr oldDev, virDomainDeviceDefPtr oldDev,
virDomainDeviceAction action); virDomainDeviceAction action,
bool live);
void virDomainRNGDefFree(virDomainRNGDefPtr def); void virDomainRNGDefFree(virDomainRNGDefPtr def);

View File

@ -3522,7 +3522,8 @@ lxcDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
oldDev.data.net = vmdef->nets[idx]; oldDev.data.net = vmdef->nets[idx];
if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev, if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev,
VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0) VIR_DOMAIN_DEVICE_ACTION_UPDATE,
false) < 0)
return -1; return -1;
virDomainNetDefFree(vmdef->nets[idx]); virDomainNetDefFree(vmdef->nets[idx]);
@ -4759,7 +4760,8 @@ static int lxcDomainAttachDeviceFlags(virDomainPtr dom,
goto endjob; goto endjob;
if (virDomainDefCompatibleDevice(vmdef, dev, NULL, if (virDomainDefCompatibleDevice(vmdef, dev, NULL,
VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0) VIR_DOMAIN_DEVICE_ACTION_ATTACH,
false) < 0)
goto endjob; goto endjob;
if ((ret = lxcDomainAttachDeviceConfig(vmdef, dev)) < 0) if ((ret = lxcDomainAttachDeviceConfig(vmdef, dev)) < 0)
@ -4768,7 +4770,8 @@ static int lxcDomainAttachDeviceFlags(virDomainPtr dom,
if (flags & VIR_DOMAIN_AFFECT_LIVE) { if (flags & VIR_DOMAIN_AFFECT_LIVE) {
if (virDomainDefCompatibleDevice(vm->def, dev_copy, NULL, if (virDomainDefCompatibleDevice(vm->def, dev_copy, NULL,
VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0) VIR_DOMAIN_DEVICE_ACTION_ATTACH,
true) < 0)
goto endjob; goto endjob;
if ((ret = lxcDomainAttachDeviceLive(dom->conn, driver, vm, dev_copy)) < 0) if ((ret = lxcDomainAttachDeviceLive(dom->conn, driver, vm, dev_copy)) < 0)

View File

@ -8643,13 +8643,7 @@ qemuDomainDiskChangeSupported(virDomainDiskDefPtr disk,
return false; return false;
} }
if (disk->info.alias && /* device alias is checked already in virDomainDefCompatibleDevice */
STRNEQ_NULLABLE(disk->info.alias, orig_disk->info.alias)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("cannot modify field '%s' of the disk"),
"alias");
return false;
}
CHECK_EQ(info.bootIndex, "boot order", true); CHECK_EQ(info.bootIndex, "boot order", true);
CHECK_EQ(rawio, "rawio", true); CHECK_EQ(rawio, "rawio", true);

View File

@ -7861,7 +7861,8 @@ qemuDomainChangeDiskLive(virDomainObjPtr vm,
oldDev.data.disk = orig_disk; oldDev.data.disk = orig_disk;
if (virDomainDefCompatibleDevice(vm->def, dev, &oldDev, if (virDomainDefCompatibleDevice(vm->def, dev, &oldDev,
VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0) VIR_DOMAIN_DEVICE_ACTION_UPDATE,
true) < 0)
goto cleanup; goto cleanup;
if (!qemuDomainDiskChangeSupported(disk, orig_disk)) if (!qemuDomainDiskChangeSupported(disk, orig_disk))
@ -7920,7 +7921,8 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm,
if ((idx = qemuDomainFindGraphicsIndex(vm->def, dev->data.graphics)) >= 0) { if ((idx = qemuDomainFindGraphicsIndex(vm->def, dev->data.graphics)) >= 0) {
oldDev.data.graphics = vm->def->graphics[idx]; oldDev.data.graphics = vm->def->graphics[idx];
if (virDomainDefCompatibleDevice(vm->def, dev, &oldDev, if (virDomainDefCompatibleDevice(vm->def, dev, &oldDev,
VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0) VIR_DOMAIN_DEVICE_ACTION_UPDATE,
true) < 0)
return -1; return -1;
} }
@ -7931,7 +7933,8 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm,
if ((idx = virDomainNetFindIdx(vm->def, dev->data.net)) >= 0) { if ((idx = virDomainNetFindIdx(vm->def, dev->data.net)) >= 0) {
oldDev.data.net = vm->def->nets[idx]; oldDev.data.net = vm->def->nets[idx];
if (virDomainDefCompatibleDevice(vm->def, dev, &oldDev, if (virDomainDefCompatibleDevice(vm->def, dev, &oldDev,
VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0) VIR_DOMAIN_DEVICE_ACTION_UPDATE,
true) < 0)
return -1; return -1;
} }
@ -8385,7 +8388,8 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
oldDev.data.disk = vmdef->disks[pos]; oldDev.data.disk = vmdef->disks[pos];
if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev, if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev,
VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0) VIR_DOMAIN_DEVICE_ACTION_UPDATE,
false) < 0)
return -1; return -1;
virDomainDiskDefFree(vmdef->disks[pos]); virDomainDiskDefFree(vmdef->disks[pos]);
@ -8405,7 +8409,8 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
oldDev.data.graphics = vmdef->graphics[pos]; oldDev.data.graphics = vmdef->graphics[pos];
if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev, if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev,
VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0) VIR_DOMAIN_DEVICE_ACTION_UPDATE,
false) < 0)
return -1; return -1;
virDomainGraphicsDefFree(vmdef->graphics[pos]); virDomainGraphicsDefFree(vmdef->graphics[pos]);
@ -8420,7 +8425,8 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
oldDev.data.net = vmdef->nets[pos]; oldDev.data.net = vmdef->nets[pos];
if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev, if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev,
VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0) VIR_DOMAIN_DEVICE_ACTION_UPDATE,
false) < 0)
return -1; return -1;
virDomainNetDefFree(vmdef->nets[pos]); virDomainNetDefFree(vmdef->nets[pos]);
@ -8512,7 +8518,8 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
goto cleanup; goto cleanup;
if (virDomainDefCompatibleDevice(vmdef, dev, NULL, if (virDomainDefCompatibleDevice(vmdef, dev, NULL,
VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0) VIR_DOMAIN_DEVICE_ACTION_ATTACH,
false) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainAttachDeviceConfig(vmdef, dev, caps, if ((ret = qemuDomainAttachDeviceConfig(vmdef, dev, caps,
parse_flags, parse_flags,
@ -8522,7 +8529,8 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
if (flags & VIR_DOMAIN_AFFECT_LIVE) { if (flags & VIR_DOMAIN_AFFECT_LIVE) {
if (virDomainDefCompatibleDevice(vm->def, dev_copy, NULL, if (virDomainDefCompatibleDevice(vm->def, dev_copy, NULL,
VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0) VIR_DOMAIN_DEVICE_ACTION_ATTACH,
true) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainAttachDeviceLive(vm, dev_copy, driver)) < 0) if ((ret = qemuDomainAttachDeviceLive(vm, dev_copy, driver)) < 0)

View File

@ -3200,11 +3200,9 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
if (!newdev->info.alias && if (!newdev->info.alias &&
VIR_STRDUP(newdev->info.alias, olddev->info.alias) < 0) VIR_STRDUP(newdev->info.alias, olddev->info.alias) < 0)
goto cleanup; goto cleanup;
if (STRNEQ_NULLABLE(olddev->info.alias, newdev->info.alias)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", /* device alias is checked already in virDomainDefCompatibleDevice */
_("cannot modify network device alias"));
goto cleanup;
}
if (olddev->info.rombar != newdev->info.rombar) { if (olddev->info.rombar != newdev->info.rombar) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("cannot modify network device rom bar setting")); _("cannot modify network device rom bar setting"));