debuggers.hg

changeset 21971:8992134dcfd0

Merge
author Keir Fraser <keir.fraser@citrix.com>
date Wed Aug 04 19:24:17 2010 +0100 (2010-08-04)
parents 49254cab8465 d627f6b581b4
children 6f07d9ac1e7c
files
line diff
     1.1 --- a/tools/libxc/xc_private.c	Wed Aug 04 17:10:46 2010 +0100
     1.2 +++ b/tools/libxc/xc_private.c	Wed Aug 04 19:24:17 2010 +0100
     1.3 @@ -57,8 +57,6 @@ xc_interface *xc_interface_open(xentooll
     1.4      return 0;
     1.5  }
     1.6  
     1.7 -static void xc_clean_hcall_buf(void);
     1.8 -
     1.9  int xc_interface_close(xc_interface *xch)
    1.10  {
    1.11      int rc = 0;
    1.12 @@ -70,9 +68,6 @@ int xc_interface_close(xc_interface *xch
    1.13          rc = xc_interface_close_core(xch, xch->fd);
    1.14          if (rc) PERROR("Could not close hypervisor interface");
    1.15      }
    1.16 -
    1.17 -    xc_clean_hcall_buf();
    1.18 -
    1.19      free(xch);
    1.20      return rc;
    1.21  }
    1.22 @@ -185,8 +180,6 @@ void unlock_pages(void *addr, size_t len
    1.23  int hcall_buf_prep(void **addr, size_t len) { return 0; }
    1.24  void hcall_buf_release(void **addr, size_t len) { }
    1.25  
    1.26 -static void xc_clean_hcall_buf(void) { }
    1.27 -
    1.28  #else /* !__sun__ */
    1.29  
    1.30  int lock_pages(void *addr, size_t len)
    1.31 @@ -232,14 +225,6 @@ static void _xc_clean_hcall_buf(void *m)
    1.32      pthread_setspecific(hcall_buf_pkey, NULL);
    1.33  }
    1.34  
    1.35 -static void xc_clean_hcall_buf(void)
    1.36 -{
    1.37 -    void *hcall_buf = pthread_getspecific(hcall_buf_pkey);
    1.38 -
    1.39 -    if (hcall_buf)
    1.40 -        _xc_clean_hcall_buf(hcall_buf);
    1.41 -}
    1.42 -
    1.43  static void _xc_init_hcall_buf(void)
    1.44  {
    1.45      pthread_key_create(&hcall_buf_pkey, _xc_clean_hcall_buf);
     2.1 --- a/tools/libxl/libxl.c	Wed Aug 04 17:10:46 2010 +0100
     2.2 +++ b/tools/libxl/libxl.c	Wed Aug 04 19:24:17 2010 +0100
     2.3 @@ -410,7 +410,7 @@ int libxl_domain_resume(libxl_ctx *ctx, 
     2.4   * Does not modify info so that it may be reused.
     2.5   */
     2.6  int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid,
     2.7 -                          libxl_domain_create_info *info, const char *name_suffix, uint8_t new_uuid[16])
     2.8 +                          libxl_domain_create_info *info, const char *name_suffix, libxl_uuid new_uuid)
     2.9  {
    2.10      struct xs_permissions roperm[2];
    2.11      xs_transaction_t t;
    2.12 @@ -1420,12 +1420,12 @@ int libxl_detach_device_model(libxl_ctx 
    2.13  int libxl_confirm_device_model_startup(libxl_ctx *ctx,
    2.14                                         libxl_device_model_starting *starting)
    2.15  {
    2.16 -    int problem = libxl_wait_for_device_model(ctx, starting->domid, "running",
    2.17 -                                              libxl_spawn_check,
    2.18 -                                              starting->for_spawn);
    2.19 -    int detach = libxl_detach_device_model(ctx, starting);
    2.20 +    int problem = libxl_wait_for_device_model(ctx, starting->domid, "running", NULL, NULL);
    2.21 +    int detach;
    2.22 +    if ( !problem )
    2.23 +        problem = libxl_spawn_check(ctx, starting->for_spawn);
    2.24 +    detach = libxl_detach_device_model(ctx, starting);
    2.25      return problem ? problem : detach;
    2.26 -    return 0;
    2.27  }
    2.28  
    2.29  
     3.1 --- a/tools/libxl/libxl.h	Wed Aug 04 17:10:46 2010 +0100
     3.2 +++ b/tools/libxl/libxl.h	Wed Aug 04 19:24:17 2010 +0100
     3.3 @@ -22,8 +22,12 @@
     3.4  #include <xs.h>
     3.5  #include <sys/wait.h> /* for pid_t */
     3.6  
     3.7 +typedef uint8_t libxl_uuid[16];
     3.8 +
     3.9 +typedef uint8_t libxl_mac[6];
    3.10 +
    3.11  typedef struct {
    3.12 -    uint8_t uuid[16];
    3.13 +    libxl_uuid uuid;
    3.14      uint32_t domid;
    3.15      uint8_t running:1;
    3.16      uint8_t blocked:1;
    3.17 @@ -50,7 +54,7 @@ typedef struct {
    3.18  } libxl_poolinfo;
    3.19  
    3.20  typedef struct {
    3.21 -    uint8_t uuid[16];
    3.22 +    libxl_uuid uuid;
    3.23      uint32_t domid;
    3.24  } libxl_vminfo;
    3.25  
    3.26 @@ -93,7 +97,7 @@ typedef struct {
    3.27      bool oos;
    3.28      int ssidref;
    3.29      char *name;
    3.30 -    uint8_t uuid[16];
    3.31 +    libxl_uuid uuid;
    3.32      char **xsdata;
    3.33      char **platformdata;
    3.34      uint32_t poolid;
    3.35 @@ -173,7 +177,7 @@ typedef enum {
    3.36  
    3.37  typedef struct {
    3.38      int domid;
    3.39 -    uint8_t uuid[16]; /* this is use only with stubdom, and must be different from the domain uuid */
    3.40 +    libxl_uuid uuid; /* this is use only with stubdom, and must be different from the domain uuid */
    3.41      char *dom_name;
    3.42      char *device_model;
    3.43      char *saved_state;
    3.44 @@ -268,7 +272,7 @@ typedef struct {
    3.45      int devid;
    3.46      int mtu;
    3.47      char *model;
    3.48 -    uint8_t mac[6];
    3.49 +    libxl_mac mac;
    3.50      struct in_addr ip;
    3.51      char *bridge;
    3.52      char *ifname;
    3.53 @@ -278,8 +282,8 @@ typedef struct {
    3.54  
    3.55  typedef struct {
    3.56      int devid;
    3.57 -    uint8_t front_mac[6];
    3.58 -    uint8_t back_mac[6];
    3.59 +    libxl_mac front_mac;
    3.60 +    libxl_mac back_mac;
    3.61      uint32_t backend_domid;
    3.62      uint32_t domid;
    3.63      uint32_t trusted:1;
    3.64 @@ -338,7 +342,7 @@ int libxl_domain_suspend(libxl_ctx *ctx,
    3.65  int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid);
    3.66  int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid, int req);
    3.67  int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force);
    3.68 -int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, libxl_domain_create_info *info, const char *name_suffix, uint8_t new_uuid[16]);
    3.69 +int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, libxl_domain_create_info *info, const char *name_suffix, libxl_uuid new_uuid);
    3.70  
    3.71  int libxl_file_reference_map(libxl_ctx *ctx, libxl_file_reference *f);
    3.72  int libxl_file_reference_unmap(libxl_ctx *ctx, libxl_file_reference *f);
    3.73 @@ -360,7 +364,7 @@ int libxl_run_bootloader(libxl_ctx *ctx,
    3.74                           libxl_device_disk *disk,
    3.75                           uint32_t domid);
    3.76  
    3.77 -char *libxl_uuid2string(libxl_ctx *ctx, const uint8_t uuid[16]);
    3.78 +char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid);
    3.79    /* 0 means ERROR_ENOMEM, which we have logged */
    3.80  
    3.81  /* events handling */
    3.82 @@ -496,7 +500,7 @@ typedef struct {
    3.83      int devid;
    3.84      int state;
    3.85      char *script;
    3.86 -    uint8_t mac[6];
    3.87 +    libxl_mac mac;
    3.88      int evtch;
    3.89      int rref_tx;
    3.90      int rref_rx;
    3.91 @@ -516,16 +520,12 @@ int libxl_device_vfb_add(libxl_ctx *ctx,
    3.92  int libxl_device_vfb_clean_shutdown(libxl_ctx *ctx, uint32_t domid);
    3.93  int libxl_device_vfb_hard_shutdown(libxl_ctx *ctx, uint32_t domid);
    3.94  
    3.95 -#define PCI_BDF                "%04x:%02x:%02x.%01x"
    3.96 -#define PCI_BDF_VDEVFN         "%04x:%02x:%02x.%01x@%02x"
    3.97  int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev);
    3.98  int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev);
    3.99  int libxl_device_pci_shutdown(libxl_ctx *ctx, uint32_t domid);
   3.100  int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint32_t domid, int *num);
   3.101  int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, int *num);
   3.102 -int libxl_device_pci_init(libxl_device_pci *pcidev, unsigned int domain,
   3.103 -                          unsigned int bus, unsigned int dev,
   3.104 -                          unsigned int func, unsigned int vdevfn);
   3.105 +int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const char *str);
   3.106  
   3.107  /*
   3.108   * Functions for allowing users of libxl to store private data
   3.109 @@ -652,9 +652,9 @@ typedef struct {
   3.110      uint32_t frontend_id;
   3.111      int devid;
   3.112      int state;
   3.113 -    uint8_t mac[6];
   3.114 +    libxl_mac mac;
   3.115      int trusted;
   3.116 -    uint8_t back_mac[6];
   3.117 +    libxl_mac back_mac;
   3.118      int filter_mac;
   3.119  } libxl_net2info;
   3.120  
     4.1 --- a/tools/libxl/libxl_device.c	Wed Aug 04 17:10:46 2010 +0100
     4.2 +++ b/tools/libxl/libxl_device.c	Wed Aug 04 19:24:17 2010 +0100
     4.3 @@ -380,6 +380,8 @@ int libxl_device_del(libxl_ctx *ctx, lib
     4.4  int libxl_wait_for_device_model(libxl_ctx *ctx,
     4.5                                  uint32_t domid, char *state,
     4.6                                  int (*check_callback)(libxl_ctx *ctx,
     4.7 +                                                      uint32_t domid,
     4.8 +                                                      const char *state,
     4.9                                                        void *userdata),
    4.10                                  void *check_callback_userdata)
    4.11  {
    4.12 @@ -402,18 +404,24 @@ int libxl_wait_for_device_model(libxl_ct
    4.13      nfds = xs_fileno(xsh) + 1;
    4.14      while (rc > 0 || (!rc && tv.tv_sec > 0)) {
    4.15          p = xs_read(xsh, XBT_NULL, path, &len);
    4.16 -        if (p && (!state || !strcmp(state, p))) {
    4.17 -            free(p);
    4.18 -            xs_unwatch(xsh, path, path);
    4.19 -            xs_daemon_close(xsh);
    4.20 -            if (check_callback) {
    4.21 -                rc = check_callback(ctx, check_callback_userdata);
    4.22 -                if (rc) return rc;
    4.23 -            }
    4.24 -            return 0;
    4.25 +        if ( NULL == p )
    4.26 +            goto again;
    4.27 +
    4.28 +        if ( NULL != state && strcmp(p, state) )
    4.29 +            goto again;
    4.30 +
    4.31 +        if ( NULL != check_callback ) {
    4.32 +            rc = (*check_callback)(ctx, domid, p, check_callback_userdata);
    4.33 +            if ( rc > 0 )
    4.34 +                goto again;
    4.35          }
    4.36 +
    4.37          free(p);
    4.38 +        xs_unwatch(xsh, path, path);
    4.39 +        xs_daemon_close(xsh);
    4.40 +        return rc;
    4.41  again:
    4.42 +        free(p);
    4.43          FD_ZERO(&rfds);
    4.44          FD_SET(xs_fileno(xsh), &rfds);
    4.45          rc = select(nfds, &rfds, NULL, NULL, &tv);
     5.1 --- a/tools/libxl/libxl_dom.c	Wed Aug 04 17:10:46 2010 +0100
     5.2 +++ b/tools/libxl/libxl_dom.c	Wed Aug 04 19:24:17 2010 +0100
     5.3 @@ -427,7 +427,7 @@ int save_device_model(libxl_ctx *ctx, ui
     5.4      return 0;
     5.5  }
     5.6  
     5.7 -char *libxl_uuid2string(libxl_ctx *ctx, const uint8_t uuid[16]) {
     5.8 +char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid) {
     5.9      char *s = string_of_uuid(ctx, uuid);
    5.10      if (!s) XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate for uuid");
    5.11      return s;
     6.1 --- a/tools/libxl/libxl_internal.h	Wed Aug 04 17:10:46 2010 +0100
     6.2 +++ b/tools/libxl/libxl_internal.h	Wed Aug 04 19:24:17 2010 +0100
     6.3 @@ -162,6 +162,8 @@ int libxl_devices_destroy(libxl_ctx *ctx
     6.4  int libxl_wait_for_device_model(libxl_ctx *ctx,
     6.5                                  uint32_t domid, char *state,
     6.6                                  int (*check_callback)(libxl_ctx *ctx,
     6.7 +                                                      uint32_t domid,
     6.8 +                                                      const char *state,
     6.9                                                        void *userdata),
    6.10                                  void *check_callback_userdata);
    6.11  int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state);
     7.1 --- a/tools/libxl/libxl_pci.c	Wed Aug 04 17:10:46 2010 +0100
     7.2 +++ b/tools/libxl/libxl_pci.c	Wed Aug 04 19:24:17 2010 +0100
     7.3 @@ -36,6 +36,161 @@
     7.4  #include "libxl_internal.h"
     7.5  #include "flexarray.h"
     7.6  
     7.7 +#define PCI_BDF                "%04x:%02x:%02x.%01x"
     7.8 +#define PCI_BDF_SHORT          "%02x:%02x.%01x"
     7.9 +#define PCI_BDF_VDEVFN         "%04x:%02x:%02x.%01x@%02x"
    7.10 +
    7.11 +static int pcidev_init(libxl_device_pci *pcidev, unsigned int domain,
    7.12 +                          unsigned int bus, unsigned int dev,
    7.13 +                          unsigned int func, unsigned int vdevfn)
    7.14 +{
    7.15 +    pcidev->domain = domain;
    7.16 +    pcidev->bus = bus;
    7.17 +    pcidev->dev = dev;
    7.18 +    pcidev->func = func;
    7.19 +    pcidev->vdevfn = vdevfn;
    7.20 +    return 0;
    7.21 +}
    7.22 +
    7.23 +static int hex_convert(const char *str, unsigned int *val, unsigned int mask)
    7.24 +{
    7.25 +    unsigned long ret;
    7.26 +    char *end;
    7.27 +
    7.28 +    ret = strtoul(str, &end, 16);
    7.29 +    if ( end == str || *end != '\0' )
    7.30 +        return -1;
    7.31 +    if ( ret & ~mask )
    7.32 +        return -1;
    7.33 +    *val = (unsigned int)ret & mask;
    7.34 +    return 0;
    7.35 +}
    7.36 +
    7.37 +#define STATE_DOMAIN    0
    7.38 +#define STATE_BUS       1
    7.39 +#define STATE_DEV       2
    7.40 +#define STATE_FUNC      3
    7.41 +#define STATE_VSLOT     4
    7.42 +#define STATE_OPTIONS_K 6
    7.43 +#define STATE_OPTIONS_V 7
    7.44 +#define STATE_TERMINAL  8
    7.45 +int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const char *str)
    7.46 +{
    7.47 +    unsigned state = STATE_DOMAIN;
    7.48 +    unsigned dom, bus, dev, func, vslot = 0;
    7.49 +    char *buf2, *tok, *ptr, *end, *optkey = NULL;
    7.50 +
    7.51 +    if ( NULL == (buf2 = ptr = strdup(str)) )
    7.52 +        return ERROR_NOMEM;
    7.53 +
    7.54 +    for(tok = ptr, end = ptr + strlen(ptr) + 1; ptr < end; ptr++) {
    7.55 +        switch(state) {
    7.56 +        case STATE_DOMAIN:
    7.57 +            if ( *ptr == ':' ) {
    7.58 +                state = STATE_BUS;
    7.59 +                *ptr = '\0';
    7.60 +                if ( hex_convert(tok, &dom, 0xffff) )
    7.61 +                    goto parse_error;
    7.62 +                tok = ptr + 1;
    7.63 +            }
    7.64 +            break;
    7.65 +        case STATE_BUS:
    7.66 +            if ( *ptr == ':' ) {
    7.67 +                state = STATE_DEV;
    7.68 +                *ptr = '\0';
    7.69 +                if ( hex_convert(tok, &bus, 0xff) )
    7.70 +                    goto parse_error;
    7.71 +                tok = ptr + 1;
    7.72 +            }else if ( *ptr == '.' ) {
    7.73 +                state = STATE_FUNC;
    7.74 +                *ptr = '\0';
    7.75 +                if ( dom & ~0xff )
    7.76 +                    goto parse_error;
    7.77 +                bus = dom;
    7.78 +                dom = 0;
    7.79 +                if ( hex_convert(tok, &dev, 0xff) )
    7.80 +                    goto parse_error;
    7.81 +                tok = ptr + 1;
    7.82 +            }
    7.83 +            break;
    7.84 +        case STATE_DEV:
    7.85 +            if ( *ptr == '.' ) {
    7.86 +                state = STATE_FUNC;
    7.87 +                *ptr = '\0';
    7.88 +                if ( hex_convert(tok, &dev, 0xff) )
    7.89 +                    goto parse_error;
    7.90 +                tok = ptr + 1;
    7.91 +            }
    7.92 +            break;
    7.93 +        case STATE_FUNC:
    7.94 +            if ( *ptr == '\0' || *ptr == '@' || *ptr == ',' ) {
    7.95 +                switch( *ptr ) {
    7.96 +                case '\0':
    7.97 +                    state = STATE_TERMINAL;
    7.98 +                    break;
    7.99 +                case '@':
   7.100 +                    state = STATE_VSLOT;
   7.101 +                    break;
   7.102 +                case ',':
   7.103 +                    state = STATE_OPTIONS_K;
   7.104 +                    break;
   7.105 +                }
   7.106 +                *ptr = '\0';
   7.107 +                if ( hex_convert(tok, &func, 0x7) )
   7.108 +                    goto parse_error;
   7.109 +                tok = ptr + 1;
   7.110 +            }
   7.111 +            break;
   7.112 +        case STATE_VSLOT:
   7.113 +            if ( *ptr == '\0' || *ptr == ',' ) {
   7.114 +                state = ( *ptr == ',' ) ? STATE_OPTIONS_K : STATE_TERMINAL;
   7.115 +                *ptr = '\0';
   7.116 +                if ( hex_convert(tok, &vslot, 0xff) )
   7.117 +                    goto parse_error;
   7.118 +                tok = ptr + 1;
   7.119 +            }
   7.120 +            break;
   7.121 +        case STATE_OPTIONS_K:
   7.122 +            if ( *ptr == '=' ) {
   7.123 +                state = STATE_OPTIONS_V;
   7.124 +                *ptr = '\0';
   7.125 +                optkey = tok;
   7.126 +                tok = ptr + 1;
   7.127 +            }
   7.128 +            break;
   7.129 +        case STATE_OPTIONS_V:
   7.130 +            if ( *ptr == ',' || *ptr == '\0' ) {
   7.131 +                state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL;
   7.132 +                *ptr = '\0';
   7.133 +                if ( !strcmp(optkey, "msitranslate") ) {
   7.134 +                    pcidev->msitranslate = atoi(tok);
   7.135 +                }else if ( !strcmp(optkey, "power_mgmt") ) {
   7.136 +                    pcidev->power_mgmt = atoi(tok);
   7.137 +                }else{
   7.138 +                    XL_LOG(ctx, XL_LOG_WARNING,
   7.139 +                           "Unknown PCI BDF option: %s", optkey);
   7.140 +                }
   7.141 +                tok = ptr + 1;
   7.142 +            }
   7.143 +        default:
   7.144 +            break;
   7.145 +        }
   7.146 +    }
   7.147 +
   7.148 +    free(buf2);
   7.149 +
   7.150 +    if ( tok != ptr || state != STATE_TERMINAL )
   7.151 +        goto parse_error;
   7.152 +
   7.153 +    pcidev_init(pcidev, dom, bus, dev, func, vslot << 3);
   7.154 +
   7.155 +    return 0;
   7.156 +
   7.157 +parse_error:
   7.158 +    printf("parse error: %s\n", str);
   7.159 +    return ERROR_INVAL;
   7.160 +}
   7.161 +
   7.162  static int libxl_create_pci_backend(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev, int num)
   7.163  {
   7.164      flexarray_t *front;
   7.165 @@ -288,7 +443,7 @@ static int get_all_assigned_devices(libx
   7.166                      if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
   7.167                          continue;
   7.168  
   7.169 -                    libxl_device_pci_init(pcidevs + *num, dom, bus, dev, func, 0);
   7.170 +                    pcidev_init(pcidevs + *num, dom, bus, dev, func, 0);
   7.171                      (*num)++;
   7.172                  }
   7.173              }
   7.174 @@ -325,6 +480,71 @@ static int is_assigned(libxl_device_pci 
   7.175      return 0;
   7.176  }
   7.177  
   7.178 +int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, int *num)
   7.179 +{
   7.180 +    libxl_device_pci *pcidevs = NULL, *new, *assigned;
   7.181 +    struct dirent *de;
   7.182 +    DIR *dir;
   7.183 +    int rc, num_assigned;
   7.184 +
   7.185 +    *num = 0;
   7.186 +    *list = NULL;
   7.187 +
   7.188 +    rc = get_all_assigned_devices(ctx, &assigned, &num_assigned);
   7.189 +    if ( rc )
   7.190 +        return rc;
   7.191 +
   7.192 +    dir = opendir(SYSFS_PCIBACK_DRIVER);
   7.193 +    if ( NULL == dir ) {
   7.194 +        if ( errno == ENOENT ) {
   7.195 +            XL_LOG(ctx, XL_LOG_ERROR, "Looks like pciback driver not loaded");
   7.196 +        }else{
   7.197 +            XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", SYSFS_PCIBACK_DRIVER);
   7.198 +        }
   7.199 +        free(assigned);
   7.200 +        return ERROR_FAIL;
   7.201 +    }
   7.202 +
   7.203 +    while( (de = readdir(dir)) ) {
   7.204 +        unsigned dom, bus, dev, func;
   7.205 +        if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
   7.206 +            continue;
   7.207 +
   7.208 +        if ( is_assigned(assigned, num_assigned, dom, bus, dev, func) )
   7.209 +            continue;
   7.210 +
   7.211 +        new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
   7.212 +        if ( NULL == new )
   7.213 +            continue;
   7.214 +
   7.215 +        pcidevs = new;
   7.216 +        new = pcidevs + *num;
   7.217 +
   7.218 +        memset(new, 0, sizeof(*new));
   7.219 +        pcidev_init(new, dom, bus, dev, func, 0);
   7.220 +        (*num)++;
   7.221 +    }
   7.222 +
   7.223 +    closedir(dir);
   7.224 +    free(assigned);
   7.225 +    *list = pcidevs;
   7.226 +    return 0;
   7.227 +}
   7.228 +
   7.229 +static int pci_ins_check(libxl_ctx *ctx, uint32_t domid, const char *state, void *priv)
   7.230 +{
   7.231 +    char *orig_state = priv;
   7.232 +
   7.233 +    if ( !strcmp(state, "pci-insert-failed") )
   7.234 +        return -1;
   7.235 +    if ( !strcmp(state, "pci-inserted") )
   7.236 +        return 0;
   7.237 +    if ( !strcmp(state, orig_state) )
   7.238 +        return 1;
   7.239 +
   7.240 +    return 1;
   7.241 +}
   7.242 + 
   7.243  static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
   7.244  {
   7.245      char *path;
   7.246 @@ -347,13 +567,17 @@ static int do_pci_add(libxl_ctx *ctx, ui
   7.247                             pcidev->bus, pcidev->dev, pcidev->func);
   7.248          path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid);
   7.249          xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins"));
   7.250 -        if (libxl_wait_for_device_model(ctx, domid, "pci-inserted", NULL, NULL) < 0)
   7.251 -            XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time");
   7.252 +        rc = libxl_wait_for_device_model(ctx, domid, NULL, pci_ins_check, state);
   7.253          path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid);
   7.254          vdevfn = libxl_xs_read(ctx, XBT_NULL, path);
   7.255 -        sscanf(vdevfn + 2, "%x", &pcidev->vdevfn);
   7.256          path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid);
   7.257 +        if ( rc < 0 )
   7.258 +            XL_LOG(ctx, XL_LOG_ERROR, "qemu refused to add device: %s", vdevfn);
   7.259 +        else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 )
   7.260 +            rc = -1;
   7.261          xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
   7.262 +        if ( rc )
   7.263 +            return ERROR_FAIL;
   7.264      } else {
   7.265          char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
   7.266                                           pcidev->bus, pcidev->dev, pcidev->func);
   7.267 @@ -460,12 +684,20 @@ int libxl_device_pci_add(libxl_ctx *ctx,
   7.268  
   7.269  int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
   7.270  {
   7.271 +    libxl_device_pci *assigned;
   7.272      char *path;
   7.273      char *state;
   7.274 -    int hvm, rc;
   7.275 +    int hvm, rc, num;
   7.276      int stubdomid = 0;
   7.277  
   7.278 -    /* TODO: check if the device can be detached */
   7.279 +    if ( !libxl_device_pci_list_assigned(ctx, &assigned, domid, &num) ) {
   7.280 +        if ( !is_assigned(assigned, num, pcidev->domain,
   7.281 +                         pcidev->bus, pcidev->dev, pcidev->func) ) {
   7.282 +            XL_LOG(ctx, XL_LOG_ERROR, "PCI device not attached to this domain");
   7.283 +            return ERROR_INVAL;
   7.284 +        }
   7.285 +    }
   7.286 +
   7.287      libxl_device_pci_remove_xenstore(ctx, domid, pcidev);
   7.288  
   7.289      hvm = is_hvm(ctx, domid);
   7.290 @@ -554,63 +786,6 @@ out:
   7.291      return 0;
   7.292  }
   7.293  
   7.294 -static libxl_device_pci *scan_sys_pcidir(libxl_device_pci *assigned,
   7.295 -                                         int num_assigned, const char *path, int *num)
   7.296 -{
   7.297 -    libxl_device_pci *pcidevs = NULL, *new;
   7.298 -    struct dirent *de;
   7.299 -    DIR *dir;
   7.300 -
   7.301 -    dir = opendir(path);
   7.302 -    if ( NULL == dir )
   7.303 -        return pcidevs;
   7.304 -
   7.305 -    while( (de = readdir(dir)) ) {
   7.306 -        unsigned dom, bus, dev, func;
   7.307 -        if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
   7.308 -            continue;
   7.309 -
   7.310 -        if ( is_assigned(assigned, num_assigned, dom, bus, dev, func) )
   7.311 -            continue;
   7.312 -
   7.313 -        new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
   7.314 -        if ( NULL == new )
   7.315 -            continue;
   7.316 -
   7.317 -        pcidevs = new;
   7.318 -        new = pcidevs + *num;
   7.319 -
   7.320 -        memset(new, 0, sizeof(*new));
   7.321 -        libxl_device_pci_init(new, dom, bus, dev, func, 0);
   7.322 -        (*num)++;
   7.323 -    }
   7.324 -
   7.325 -    closedir(dir);
   7.326 -    return pcidevs;
   7.327 -}
   7.328 -
   7.329 -int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, int *num)
   7.330 -{
   7.331 -    libxl_device_pci *pcidevs = NULL;
   7.332 -    libxl_device_pci *assigned;
   7.333 -    int num_assigned, rc;
   7.334 -
   7.335 -    *num = 0;
   7.336 -    *list = NULL;
   7.337 -
   7.338 -    rc = get_all_assigned_devices(ctx, &assigned, &num_assigned);
   7.339 -    if ( rc )
   7.340 -        return rc;
   7.341 -
   7.342 -    pcidevs = scan_sys_pcidir(assigned, num_assigned,
   7.343 -                              SYSFS_PCIBACK_DRIVER, num);
   7.344 -
   7.345 -    free(assigned);
   7.346 -    if ( *num )
   7.347 -        *list = pcidevs;
   7.348 -    return 0;
   7.349 -}
   7.350 -
   7.351  int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint32_t domid, int *num)
   7.352  {
   7.353      char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts;
   7.354 @@ -623,7 +798,7 @@ int libxl_device_pci_list_assigned(libxl
   7.355      if (!num_devs) {
   7.356          *num = 0;
   7.357          *list = NULL;
   7.358 -        return ERROR_FAIL;
   7.359 +        return 0;
   7.360      }
   7.361      n = atoi(num_devs);
   7.362      pcidevs = calloc(n, sizeof(libxl_device_pci));
   7.363 @@ -635,7 +810,7 @@ int libxl_device_pci_list_assigned(libxl
   7.364          xsvdevfn = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, i));
   7.365          if (xsvdevfn)
   7.366              vdevfn = strtol(xsvdevfn, (char **) NULL, 16);
   7.367 -        libxl_device_pci_init(pcidevs + i, domain, bus, dev, func, vdevfn);
   7.368 +        pcidev_init(pcidevs + i, domain, bus, dev, func, vdevfn);
   7.369          xsopts = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/opts-%d", be_path, i));
   7.370          if (xsopts) {
   7.371              char *saveptr;
   7.372 @@ -674,24 +849,13 @@ int libxl_device_pci_shutdown(libxl_ctx 
   7.373      return 0;
   7.374  }
   7.375  
   7.376 -int libxl_device_pci_init(libxl_device_pci *pcidev, unsigned int domain,
   7.377 -                          unsigned int bus, unsigned int dev,
   7.378 -                          unsigned int func, unsigned int vdevfn)
   7.379 -{
   7.380 -    pcidev->domain = domain;
   7.381 -    pcidev->bus = bus;
   7.382 -    pcidev->dev = dev;
   7.383 -    pcidev->func = func;
   7.384 -    pcidev->vdevfn = vdevfn;
   7.385 -    return 0;
   7.386 -}
   7.387 -
   7.388  int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int bus,
   7.389                           unsigned int dev, unsigned int func)
   7.390  {
   7.391 -    char *reset = "/sys/bus/pci/drivers/pciback/do_flr";
   7.392 +    char *reset;
   7.393      int fd, rc;
   7.394  
   7.395 +    reset = libxl_sprintf(ctx, "%s/pciback/do_flr", SYSFS_PCI_DEV);
   7.396      fd = open(reset, O_WRONLY);
   7.397      if (fd > 0) {
   7.398          char *buf = libxl_sprintf(ctx, PCI_BDF, domain, bus, dev, func);
   7.399 @@ -703,7 +867,7 @@ int libxl_device_pci_reset(libxl_ctx *ct
   7.400      }
   7.401      if (errno != ENOENT)
   7.402          XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", reset);
   7.403 -    reset = libxl_sprintf(ctx, "/sys/bus/pci/devices/"PCI_BDF"/reset", domain, bus, dev, func);
   7.404 +    reset = libxl_sprintf(ctx, "%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, dev, func);
   7.405      fd = open(reset, O_WRONLY);
   7.406      if (fd > 0) {
   7.407          rc = write(fd, "1", 1);
     8.1 --- a/tools/libxl/libxlu_cfg.c	Wed Aug 04 17:10:46 2010 +0100
     8.2 +++ b/tools/libxl/libxlu_cfg.c	Wed Aug 04 19:24:17 2010 +0100
     8.3 @@ -91,7 +91,11 @@ int xlu_cfg_readdata(XLU_Config *cfg, co
     8.4  }
     8.5  
     8.6  void xlu__cfg_set_free(XLU_ConfigSetting *set) {
     8.7 +    int i;
     8.8 +
     8.9      free(set->name);
    8.10 +    for (i=0; i<set->nvalues; i++)
    8.11 +        free(set->values[i]);
    8.12      free(set->values);
    8.13      free(set);
    8.14  }
     9.1 --- a/tools/libxl/xl_cmdimpl.c	Wed Aug 04 17:10:46 2010 +0100
     9.2 +++ b/tools/libxl/xl_cmdimpl.c	Wed Aug 04 19:24:17 2010 +0100
     9.3 @@ -265,11 +265,11 @@ static void init_build_info(libxl_domain
     9.4      }
     9.5  }
     9.6  
     9.7 -static void random_uuid(uint8_t *uuid)
     9.8 +static void random_uuid(libxl_uuid *uuid)
     9.9  {
    9.10      int i;
    9.11      for (i = 0; i < 16; i++)
    9.12 -        uuid[i] = rand();
    9.13 +        (*uuid)[i] = rand();
    9.14  }
    9.15  
    9.16  static void init_dm_info(libxl_device_model_info *dm_info,
    9.17 @@ -277,7 +277,7 @@ static void init_dm_info(libxl_device_mo
    9.18  {
    9.19      memset(dm_info, '\0', sizeof(*dm_info));
    9.20  
    9.21 -    random_uuid(&dm_info->uuid[0]);
    9.22 +    random_uuid(&dm_info->uuid);
    9.23  
    9.24      dm_info->dom_name = c_info->name;
    9.25      dm_info->device_model = "qemu-dm";
    9.26 @@ -495,7 +495,7 @@ static void printf_info(int domid,
    9.27      for (i = 0; i < d_config->num_pcidevs; i++) {
    9.28          printf("\t(device\n");
    9.29          printf("\t\t(pci\n");
    9.30 -        printf("\t\t\t(pci dev "PCI_BDF_VDEVFN")\n",
    9.31 +        printf("\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n",
    9.32                 d_config->pcidevs[i].domain, d_config->pcidevs[i].bus,
    9.33                 d_config->pcidevs[i].dev, d_config->pcidevs[i].func,
    9.34                 d_config->pcidevs[i].vdevfn);
    9.35 @@ -586,7 +586,7 @@ static void parse_config_data(const char
    9.36          c_info->name = strdup(buf);
    9.37      else
    9.38          c_info->name = "test";
    9.39 -    random_uuid(&c_info->uuid[0]);
    9.40 +    random_uuid(&c_info->uuid);
    9.41  
    9.42      if (!xlu_cfg_get_long(config, "oos", &l))
    9.43          c_info->oos = l;
    9.44 @@ -953,46 +953,20 @@ skip_vfb:
    9.45          pci_power_mgmt = l;
    9.46  
    9.47      if (!xlu_cfg_get_list (config, "pci", &pcis, 0)) {
    9.48 +        int i;
    9.49          d_config->num_pcidevs = 0;
    9.50          d_config->pcidevs = NULL;
    9.51 -        while ((buf = xlu_cfg_get_listitem (pcis, d_config->num_pcidevs)) != NULL) {
    9.52 +        for(i = 0; (buf = xlu_cfg_get_listitem (pcis, i)) != NULL; i++) {
    9.53              libxl_device_pci *pcidev;
    9.54 -            unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0;
    9.55 -            char *buf2 = strdup(buf);
    9.56 -            char *p;
    9.57  
    9.58              d_config->pcidevs = (libxl_device_pci *) realloc(d_config->pcidevs, sizeof (libxl_device_pci) * (d_config->num_pcidevs + 1));
    9.59              pcidev = d_config->pcidevs + d_config->num_pcidevs;
    9.60              memset(pcidev, 0x00, sizeof(libxl_device_pci));
    9.61  
    9.62 -            p = strtok(buf2, ",");
    9.63 -            if (!p)
    9.64 -                goto skip_pci;
    9.65 -            if (sscanf(p, PCI_BDF_VDEVFN, &domain, &bus, &dev, &func, &vdevfn) < 4) {
    9.66 -                domain = 0;
    9.67 -                if (sscanf(p, "%02x:%02x.%01x@%02x", &bus, &dev, &func, &vdevfn) < 3) {
    9.68 -                    fprintf(stderr,"xl: Unable to parse pci bdf (%s)\n", p);
    9.69 -                    goto skip_pci;
    9.70 -                }
    9.71 -            }
    9.72 -
    9.73 -            libxl_device_pci_init(pcidev, domain, bus, dev, func, vdevfn);
    9.74              pcidev->msitranslate = pci_msitranslate;
    9.75              pcidev->power_mgmt = pci_power_mgmt;
    9.76 -            while ((p = strtok(NULL, ",=")) != NULL) {
    9.77 -                while (*p == ' ')
    9.78 -                    p++;
    9.79 -                if (!strcmp(p, "msitranslate")) {
    9.80 -                    p = strtok(NULL, ",=");
    9.81 -                    pcidev->msitranslate = atoi(p);
    9.82 -                } else if (!strcmp(p, "power_mgmt")) {
    9.83 -                    p = strtok(NULL, ",=");
    9.84 -                    pcidev->power_mgmt = atoi(p);
    9.85 -                }
    9.86 -            }
    9.87 -            d_config->num_pcidevs++;
    9.88 -skip_pci:
    9.89 -            free(buf2);
    9.90 +            if (!libxl_device_pci_parse_bdf(&ctx, pcidev, buf))
    9.91 +                d_config->num_pcidevs++;
    9.92          }
    9.93      }
    9.94  
    9.95 @@ -1181,7 +1155,7 @@ static int preserve_domain(libxl_ctx *ct
    9.96      struct tm tm;
    9.97      char stime[24];
    9.98  
    9.99 -    uint8_t new_uuid[16];
   9.100 +    libxl_uuid new_uuid;
   9.101  
   9.102      int rc;
   9.103  
   9.104 @@ -1202,7 +1176,7 @@ static int preserve_domain(libxl_ctx *ct
   9.105          return 0;
   9.106      }
   9.107  
   9.108 -    random_uuid(&new_uuid[0]);
   9.109 +    random_uuid(&new_uuid);
   9.110  
   9.111      LOG("Preserving domain %d %s with suffix%s", domid, d_config->c_info.name, stime);
   9.112      rc = libxl_domain_preserve(ctx, domid, &d_config->c_info, stime, new_uuid);
   9.113 @@ -2019,16 +1993,14 @@ int main_pcilist(int argc, char **argv)
   9.114  void pcidetach(char *dom, char *bdf)
   9.115  {
   9.116      libxl_device_pci pcidev;
   9.117 -    unsigned int domain, bus, dev, func;
   9.118  
   9.119      find_domain(dom);
   9.120  
   9.121      memset(&pcidev, 0x00, sizeof(pcidev));
   9.122 -    if (sscanf(bdf, PCI_BDF, &domain, &bus, &dev, &func) != 4) {
   9.123 +    if (libxl_device_pci_parse_bdf(&ctx, &pcidev, bdf)) {
   9.124          fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", bdf);
   9.125          exit(2);
   9.126      }
   9.127 -    libxl_device_pci_init(&pcidev, domain, bus, dev, func, 0);
   9.128      libxl_device_pci_remove(&ctx, domid, &pcidev);
   9.129  }
   9.130  
   9.131 @@ -2061,16 +2033,14 @@ int main_pcidetach(int argc, char **argv
   9.132  void pciattach(char *dom, char *bdf, char *vs)
   9.133  {
   9.134      libxl_device_pci pcidev;
   9.135 -    unsigned int domain, bus, dev, func;
   9.136  
   9.137      find_domain(dom);
   9.138  
   9.139      memset(&pcidev, 0x00, sizeof(pcidev));
   9.140 -    if (sscanf(bdf, PCI_BDF, &domain, &bus, &dev, &func) != 4) {
   9.141 +    if (libxl_device_pci_parse_bdf(&ctx, &pcidev, bdf)) {
   9.142          fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf);
   9.143          exit(2);
   9.144      }
   9.145 -    libxl_device_pci_init(&pcidev, domain, bus, dev, func, 0);
   9.146      libxl_device_pci_add(&ctx, domid, &pcidev);
   9.147  }
   9.148