Add APIs for sending 'usb_add' command for host devices

One API adds an exact device based on bus+dev, the other adds
any device matching vendor+product

* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorAddUSBDeviceExact() and qemuMonitorAddUSBDeviceMatch()
  commands.
* src/qemu/qemu_driver.c: Switch over to using the new
    qemuMonitorAddUSBDeviceExact() and qemuMonitorAddUSBDeviceMatch()
This commit is contained in:
Daniel P. Berrange 2009-09-23 16:04:55 +01:00
parent f566c5924a
commit 61ea9c89c5
3 changed files with 89 additions and 34 deletions

View File

@ -4984,7 +4984,6 @@ static int qemudDomainAttachHostUsbDevice(virConnectPtr conn,
virDomainDeviceDefPtr dev)
{
int ret;
char *cmd, *reply;
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
virReportOOMError(conn);
@ -4992,43 +4991,19 @@ static int qemudDomainAttachHostUsbDevice(virConnectPtr conn,
}
if (dev->data.hostdev->source.subsys.u.usb.vendor) {
ret = virAsprintf(&cmd, "usb_add host:%.4x:%.4x",
dev->data.hostdev->source.subsys.u.usb.vendor,
dev->data.hostdev->source.subsys.u.usb.product);
ret = qemuMonitorAddUSBDeviceMatch(vm,
dev->data.hostdev->source.subsys.u.usb.vendor,
dev->data.hostdev->source.subsys.u.usb.product);
} else {
ret = virAsprintf(&cmd, "usb_add host:%.3d.%.3d",
dev->data.hostdev->source.subsys.u.usb.bus,
dev->data.hostdev->source.subsys.u.usb.device);
}
if (ret == -1) {
virReportOOMError(conn);
return -1;
ret = qemuMonitorAddUSBDeviceExact(vm,
dev->data.hostdev->source.subsys.u.usb.bus,
dev->data.hostdev->source.subsys.u.usb.device);
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("cannot attach usb device"));
VIR_FREE(cmd);
return -1;
}
if (ret != -1)
vm->def->hostdevs[vm->def->nhostdevs++] = dev->data.hostdev;
DEBUG ("%s: attach_usb reply: %s", vm->def->name, reply);
/* If the command failed qemu prints:
* Could not add ... */
if (strstr(reply, "Could not add ")) {
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s",
_("adding usb device failed"));
VIR_FREE(reply);
VIR_FREE(cmd);
return -1;
}
vm->def->hostdevs[vm->def->nhostdevs++] = dev->data.hostdev;
VIR_FREE(reply);
VIR_FREE(cmd);
return 0;
return ret;
}
static int qemudDomainAttachHostDevice(virConnectPtr conn,

View File

@ -1242,3 +1242,76 @@ cleanup:
VIR_FREE(safepath);
return ret;
}
static int qemuMonitorAddUSBDevice(const virDomainObjPtr vm,
const char *addr)
{
char *cmd;
char *reply = NULL;
int ret = -1;
if (virAsprintf(&cmd, "usb_add %s", addr) < 0) {
virReportOOMError(NULL);
return -1;
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("cannot attach usb device"));
goto cleanup;
}
DEBUG ("%s: attach_usb reply: %s", vm->def->name, reply);
/* If the command failed qemu prints:
* Could not add ... */
if (strstr(reply, "Could not add ")) {
qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("adding usb device failed"));
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(cmd);
VIR_FREE(reply);
return ret;
}
int qemuMonitorAddUSBDeviceExact(const virDomainObjPtr vm,
int bus,
int dev)
{
int ret;
char *addr;
if (virAsprintf(&addr, "host:%.3d.%.3d", bus, dev) < 0) {
virReportOOMError(NULL);
return -1;
}
ret = qemuMonitorAddUSBDevice(vm, addr);
VIR_FREE(addr);
return ret;
}
int qemuMonitorAddUSBDeviceMatch(const virDomainObjPtr vm,
int vendor,
int product)
{
int ret;
char *addr;
if (virAsprintf(&addr, "host:%.4x:%.4x", vendor, product) < 0) {
virReportOOMError(NULL);
return -1;
}
ret = qemuMonitorAddUSBDevice(vm, addr);
VIR_FREE(addr);
return ret;
}

View File

@ -140,4 +140,11 @@ int qemuMonitorMigrateToCommand(const virDomainObjPtr vm,
int qemuMonitorAddUSBDisk(const virDomainObjPtr vm,
const char *path);
int qemuMonitorAddUSBDeviceExact(const virDomainObjPtr vm,
int bus,
int dev);
int qemuMonitorAddUSBDeviceMatch(const virDomainObjPtr vm,
int vendor,
int product);
#endif /* QEMU_MONITOR_TEXT_H */