libxl: fix disk detach when <driver> not specified

When a user does not explicitly set a <driver> in the disk config,
libvirt defers selection of a default to libxl. This approach works
fine when starting a domain with such configuration or attaching a
disk to a running domain. But when detaching such a disk, libxl
will fail with "unrecognized disk backend type: 0". libxl makes no
attempt to recalculate a default backend (driver) on detach and
simply fails when uninitialized.

This patch updates the libvirt disk config with the backend selected
by libxl when starting a domain or attaching a disk to a running
domain. Another benefit of this approach is that the live XML is
also updated with the backend driver selected by libxl.
This commit is contained in:
Jim Fehlig 2017-02-07 12:05:15 -07:00
parent 321a28c6ae
commit bd1168101a
4 changed files with 62 additions and 0 deletions

View File

@ -907,6 +907,38 @@ libxlMakeDiskList(virDomainDefPtr def, libxl_domain_config *d_config)
return -1;
}
/*
* Update libvirt disk config with libxl disk config.
*
* This function can be used to update the libvirt disk config with default
* values selected by libxl. Currently only the backend type is selected by
* libxl when not explicitly specified by the user.
*/
void
libxlUpdateDiskDef(virDomainDiskDefPtr l_disk, libxl_device_disk *x_disk)
{
const char *driver = NULL;
if (virDomainDiskGetDriver(l_disk))
return;
switch (x_disk->backend) {
case LIBXL_DISK_BACKEND_QDISK:
driver = "qemu";
break;
case LIBXL_DISK_BACKEND_TAP:
driver = "tap";
break;
case LIBXL_DISK_BACKEND_PHY:
driver = "phy";
break;
case LIBXL_DISK_BACKEND_UNKNOWN:
break;
}
if (driver)
ignore_value(virDomainDiskSetDriver(l_disk, driver));
}
int
libxlMakeNic(virDomainDefPtr def,
virDomainNetDefPtr l_nic,

View File

@ -175,6 +175,10 @@ int libxlDriverConfigLoadFile(libxlDriverConfigPtr cfg,
int
libxlMakeDisk(virDomainDiskDefPtr l_dev, libxl_device_disk *x_dev);
void
libxlUpdateDiskDef(virDomainDiskDefPtr l_dev, libxl_device_disk *x_dev);
int
libxlMakeNic(virDomainDefPtr def,
virDomainNetDefPtr l_nic,

View File

@ -1072,6 +1072,30 @@ libxlDomainCreateIfaceNames(virDomainDefPtr def, libxl_domain_config *d_config)
}
}
static void
libxlDomainUpdateDiskParams(virDomainDefPtr def, libxl_ctx *ctx)
{
libxl_device_disk *disks;
int num_disks = 0;
size_t i;
int idx;
disks = libxl_device_disk_list(ctx, def->id, &num_disks);
if (!disks)
return;
for (i = 0; i < num_disks; i++) {
if ((idx = virDomainDiskIndexByName(def, disks[i].vdev, false)) < 0)
continue;
libxlUpdateDiskDef(def->disks[idx], &disks[i]);
}
for (i = 0; i < num_disks; i++)
libxl_device_disk_dispose(&disks[i]);
VIR_FREE(disks);
}
#ifdef LIBXL_HAVE_DEVICE_CHANNEL
static void
libxlDomainCreateChannelPTY(virDomainDefPtr def, libxl_ctx *ctx)
@ -1315,6 +1339,7 @@ libxlDomainStart(libxlDriverPrivatePtr driver,
goto destroy_dom;
libxlDomainCreateIfaceNames(vm->def, &d_config);
libxlDomainUpdateDiskParams(vm->def, cfg->ctx);
#ifdef LIBXL_HAVE_DEVICE_CHANNEL
if (vm->def->nchannels > 0)

View File

@ -3028,6 +3028,7 @@ libxlDomainAttachDeviceDiskLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev)
goto cleanup;
}
libxlUpdateDiskDef(l_disk, &x_disk);
virDomainDiskInsertPreAlloced(vm->def, l_disk);
} else {