# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
# Date 1280929426 -3600
# Node ID 20540b8fe4b6d32daa87cf9becb425da548c1f02
# Parent 9c720d64160b5e98f3b44b37a23de630c96c085f
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@xxxxxxxxxx>
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
tools/libxl/libxl.c | 10 +++++-----
tools/libxl/libxl_device.c | 28 ++++++++++++++++++----------
tools/libxl/libxl_internal.h | 2 ++
tools/libxl/libxl_pci.c | 24 +++++++++++++++++++++---
4 files changed, 46 insertions(+), 18 deletions(-)
diff -r 9c720d64160b -r 20540b8fe4b6 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c Wed Aug 04 14:43:00 2010 +0100
+++ b/tools/libxl/libxl.c Wed Aug 04 14:43:46 2010 +0100
@@ -1420,12 +1420,12 @@ int libxl_confirm_device_model_startup(l
int libxl_confirm_device_model_startup(libxl_ctx *ctx,
libxl_device_model_starting *starting)
{
- int problem = libxl_wait_for_device_model(ctx, starting->domid, "running",
- libxl_spawn_check,
- starting->for_spawn);
- int detach = libxl_detach_device_model(ctx, starting);
+ int problem = libxl_wait_for_device_model(ctx, starting->domid, "running",
NULL, NULL);
+ int detach;
+ if ( !problem )
+ problem = libxl_spawn_check(ctx, starting->for_spawn);
+ detach = libxl_detach_device_model(ctx, starting);
return problem ? problem : detach;
- return 0;
}
diff -r 9c720d64160b -r 20540b8fe4b6 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c Wed Aug 04 14:43:00 2010 +0100
+++ b/tools/libxl/libxl_device.c Wed Aug 04 14:43:46 2010 +0100
@@ -380,6 +380,8 @@ int libxl_wait_for_device_model(libxl_ct
int libxl_wait_for_device_model(libxl_ctx *ctx,
uint32_t domid, char *state,
int (*check_callback)(libxl_ctx *ctx,
+ uint32_t domid,
+ const char *state,
void *userdata),
void *check_callback_userdata)
{
@@ -402,18 +404,24 @@ int libxl_wait_for_device_model(libxl_ct
nfds = xs_fileno(xsh) + 1;
while (rc > 0 || (!rc && tv.tv_sec > 0)) {
p = xs_read(xsh, XBT_NULL, path, &len);
- if (p && (!state || !strcmp(state, p))) {
- free(p);
- xs_unwatch(xsh, path, path);
- xs_daemon_close(xsh);
- if (check_callback) {
- rc = check_callback(ctx, check_callback_userdata);
- if (rc) return rc;
- }
- return 0;
- }
+ if ( NULL == p )
+ goto again;
+
+ if ( NULL != state && strcmp(p, state) )
+ goto again;
+
+ if ( NULL != check_callback ) {
+ rc = (*check_callback)(ctx, domid, p, check_callback_userdata);
+ if ( rc > 0 )
+ goto again;
+ }
+
free(p);
+ xs_unwatch(xsh, path, path);
+ xs_daemon_close(xsh);
+ return rc;
again:
+ free(p);
FD_ZERO(&rfds);
FD_SET(xs_fileno(xsh), &rfds);
rc = select(nfds, &rfds, NULL, NULL, &tv);
diff -r 9c720d64160b -r 20540b8fe4b6 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h Wed Aug 04 14:43:00 2010 +0100
+++ b/tools/libxl/libxl_internal.h Wed Aug 04 14:43:46 2010 +0100
@@ -162,6 +162,8 @@ int libxl_wait_for_device_model(libxl_ct
int libxl_wait_for_device_model(libxl_ctx *ctx,
uint32_t domid, char *state,
int (*check_callback)(libxl_ctx *ctx,
+ uint32_t domid,
+ const char *state,
void *userdata),
void *check_callback_userdata);
int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state);
diff -r 9c720d64160b -r 20540b8fe4b6 tools/libxl/libxl_pci.c
--- a/tools/libxl/libxl_pci.c Wed Aug 04 14:43:00 2010 +0100
+++ b/tools/libxl/libxl_pci.c Wed Aug 04 14:43:46 2010 +0100
@@ -531,6 +531,20 @@ int libxl_device_pci_list_assignable(lib
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, ui
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);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|