diff options
author | Gianni Tedesco <gianni.tedesco@citrix.com> | 2010-08-04 14:43:46 +0100 |
---|---|---|
committer | Gianni Tedesco <gianni.tedesco@citrix.com> | 2010-08-04 14:43:46 +0100 |
commit | 072186cf673d593478aced4614be65d19f459818 (patch) | |
tree | 70e6abc97b305b221a8b76e63ed5528a6ec99216 /tools/libxl/libxl_pci.c | |
parent | d6353658b26249c50f8ae5c3b9861693f64e3446 (diff) | |
download | xen-072186cf673d593478aced4614be65d19f459818.tar.gz xen-072186cf673d593478aced4614be65d19f459818.tar.bz2 xen-072186cf673d593478aced4614be65d19f459818.zip |
xl: detect pci-insert-failed dm status on pci-passthrough
NOTE: This functionality depends on a corresponding qemu-dm patch to work as
expected. Should be safe to use with an un-patched qemu-dm as before.
libxl_wait_for_device_model can only wait for one status value, re-work the
API so that a callback function can chose between several different possible
status values for qemu-dm and fix up all callers appropriately.
In the case of PCI device insert we succeed if qemu-dm reports
"pci-device-inserted" and error out instead of hanging forever if it fails
since qemu-dm now reports a status of "pci-insert-failed".
Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'tools/libxl/libxl_pci.c')
-rw-r--r-- | tools/libxl/libxl_pci.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c index 20f4a00218..c4dc0e4146 100644 --- a/tools/libxl/libxl_pci.c +++ b/tools/libxl/libxl_pci.c @@ -531,6 +531,20 @@ int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, in return 0; } +static int pci_ins_check(libxl_ctx *ctx, uint32_t domid, const char *state, void *priv) +{ + char *orig_state = priv; + + if ( !strcmp(state, "pci-insert-failed") ) + return -1; + if ( !strcmp(state, "pci-inserted") ) + return 0; + if ( !strcmp(state, orig_state) ) + return 1; + + return 1; +} + static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) { char *path; @@ -553,13 +567,17 @@ static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) pcidev->bus, pcidev->dev, pcidev->func); path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid); xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins")); - if (libxl_wait_for_device_model(ctx, domid, "pci-inserted", NULL, NULL) < 0) - XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time"); + rc = libxl_wait_for_device_model(ctx, domid, NULL, pci_ins_check, state); path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid); vdevfn = libxl_xs_read(ctx, XBT_NULL, path); - sscanf(vdevfn + 2, "%x", &pcidev->vdevfn); path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); + if ( rc < 0 ) + XL_LOG(ctx, XL_LOG_ERROR, "qemu refused to add device: %s", vdevfn); + else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 ) + rc = -1; xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state)); + if ( rc ) + return ERROR_FAIL; } else { char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); |