debuggers.hg

changeset 21965:20540b8fe4b6

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>
author Gianni Tedesco <gianni.tedesco@citrix.com>
date Wed Aug 04 14:43:46 2010 +0100 (2010-08-04)
parents 9c720d64160b
children eea7a2d7efab
files tools/libxl/libxl.c tools/libxl/libxl_device.c tools/libxl/libxl_internal.h tools/libxl/libxl_pci.c
line diff
     1.1 --- a/tools/libxl/libxl.c	Wed Aug 04 14:43:00 2010 +0100
     1.2 +++ b/tools/libxl/libxl.c	Wed Aug 04 14:43:46 2010 +0100
     1.3 @@ -1420,12 +1420,12 @@ int libxl_detach_device_model(libxl_ctx 
     1.4  int libxl_confirm_device_model_startup(libxl_ctx *ctx,
     1.5                                         libxl_device_model_starting *starting)
     1.6  {
     1.7 -    int problem = libxl_wait_for_device_model(ctx, starting->domid, "running",
     1.8 -                                              libxl_spawn_check,
     1.9 -                                              starting->for_spawn);
    1.10 -    int detach = libxl_detach_device_model(ctx, starting);
    1.11 +    int problem = libxl_wait_for_device_model(ctx, starting->domid, "running", NULL, NULL);
    1.12 +    int detach;
    1.13 +    if ( !problem )
    1.14 +        problem = libxl_spawn_check(ctx, starting->for_spawn);
    1.15 +    detach = libxl_detach_device_model(ctx, starting);
    1.16      return problem ? problem : detach;
    1.17 -    return 0;
    1.18  }
    1.19  
    1.20  
     2.1 --- a/tools/libxl/libxl_device.c	Wed Aug 04 14:43:00 2010 +0100
     2.2 +++ b/tools/libxl/libxl_device.c	Wed Aug 04 14:43:46 2010 +0100
     2.3 @@ -380,6 +380,8 @@ int libxl_device_del(libxl_ctx *ctx, lib
     2.4  int libxl_wait_for_device_model(libxl_ctx *ctx,
     2.5                                  uint32_t domid, char *state,
     2.6                                  int (*check_callback)(libxl_ctx *ctx,
     2.7 +                                                      uint32_t domid,
     2.8 +                                                      const char *state,
     2.9                                                        void *userdata),
    2.10                                  void *check_callback_userdata)
    2.11  {
    2.12 @@ -402,18 +404,24 @@ int libxl_wait_for_device_model(libxl_ct
    2.13      nfds = xs_fileno(xsh) + 1;
    2.14      while (rc > 0 || (!rc && tv.tv_sec > 0)) {
    2.15          p = xs_read(xsh, XBT_NULL, path, &len);
    2.16 -        if (p && (!state || !strcmp(state, p))) {
    2.17 -            free(p);
    2.18 -            xs_unwatch(xsh, path, path);
    2.19 -            xs_daemon_close(xsh);
    2.20 -            if (check_callback) {
    2.21 -                rc = check_callback(ctx, check_callback_userdata);
    2.22 -                if (rc) return rc;
    2.23 -            }
    2.24 -            return 0;
    2.25 +        if ( NULL == p )
    2.26 +            goto again;
    2.27 +
    2.28 +        if ( NULL != state && strcmp(p, state) )
    2.29 +            goto again;
    2.30 +
    2.31 +        if ( NULL != check_callback ) {
    2.32 +            rc = (*check_callback)(ctx, domid, p, check_callback_userdata);
    2.33 +            if ( rc > 0 )
    2.34 +                goto again;
    2.35          }
    2.36 +
    2.37          free(p);
    2.38 +        xs_unwatch(xsh, path, path);
    2.39 +        xs_daemon_close(xsh);
    2.40 +        return rc;
    2.41  again:
    2.42 +        free(p);
    2.43          FD_ZERO(&rfds);
    2.44          FD_SET(xs_fileno(xsh), &rfds);
    2.45          rc = select(nfds, &rfds, NULL, NULL, &tv);
     3.1 --- a/tools/libxl/libxl_internal.h	Wed Aug 04 14:43:00 2010 +0100
     3.2 +++ b/tools/libxl/libxl_internal.h	Wed Aug 04 14:43:46 2010 +0100
     3.3 @@ -162,6 +162,8 @@ int libxl_devices_destroy(libxl_ctx *ctx
     3.4  int libxl_wait_for_device_model(libxl_ctx *ctx,
     3.5                                  uint32_t domid, char *state,
     3.6                                  int (*check_callback)(libxl_ctx *ctx,
     3.7 +                                                      uint32_t domid,
     3.8 +                                                      const char *state,
     3.9                                                        void *userdata),
    3.10                                  void *check_callback_userdata);
    3.11  int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state);
     4.1 --- a/tools/libxl/libxl_pci.c	Wed Aug 04 14:43:00 2010 +0100
     4.2 +++ b/tools/libxl/libxl_pci.c	Wed Aug 04 14:43:46 2010 +0100
     4.3 @@ -531,6 +531,20 @@ int libxl_device_pci_list_assignable(lib
     4.4      return 0;
     4.5  }
     4.6  
     4.7 +static int pci_ins_check(libxl_ctx *ctx, uint32_t domid, const char *state, void *priv)
     4.8 +{
     4.9 +    char *orig_state = priv;
    4.10 +
    4.11 +    if ( !strcmp(state, "pci-insert-failed") )
    4.12 +        return -1;
    4.13 +    if ( !strcmp(state, "pci-inserted") )
    4.14 +        return 0;
    4.15 +    if ( !strcmp(state, orig_state) )
    4.16 +        return 1;
    4.17 +
    4.18 +    return 1;
    4.19 +}
    4.20 + 
    4.21  static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
    4.22  {
    4.23      char *path;
    4.24 @@ -553,13 +567,17 @@ static int do_pci_add(libxl_ctx *ctx, ui
    4.25                             pcidev->bus, pcidev->dev, pcidev->func);
    4.26          path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid);
    4.27          xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins"));
    4.28 -        if (libxl_wait_for_device_model(ctx, domid, "pci-inserted", NULL, NULL) < 0)
    4.29 -            XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time");
    4.30 +        rc = libxl_wait_for_device_model(ctx, domid, NULL, pci_ins_check, state);
    4.31          path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid);
    4.32          vdevfn = libxl_xs_read(ctx, XBT_NULL, path);
    4.33 -        sscanf(vdevfn + 2, "%x", &pcidev->vdevfn);
    4.34          path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid);
    4.35 +        if ( rc < 0 )
    4.36 +            XL_LOG(ctx, XL_LOG_ERROR, "qemu refused to add device: %s", vdevfn);
    4.37 +        else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 )
    4.38 +            rc = -1;
    4.39          xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
    4.40 +        if ( rc )
    4.41 +            return ERROR_FAIL;
    4.42      } else {
    4.43          char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
    4.44                                           pcidev->bus, pcidev->dev, pcidev->func);