mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Merge
This commit is contained in:
commit
4cc1d7b7fa
9 files changed
+303
-170
No files matched your search
@@ -57,8 +57,6 @@ xc_interface *xc_interface_open(xentoollog_logger *logger,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xc_clean_hcall_buf(void);
|
||||
|
||||
int xc_interface_close(xc_interface *xch)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -70,9 +68,6 @@ int xc_interface_close(xc_interface *xch)
|
||||
rc = xc_interface_close_core(xch, xch->fd);
|
||||
if (rc) PERROR("Could not close hypervisor interface");
|
||||
}
|
||||
|
||||
xc_clean_hcall_buf();
|
||||
|
||||
free(xch);
|
||||
return rc;
|
||||
}
|
||||
@@ -185,8 +180,6 @@ void unlock_pages(void *addr, size_t len) { }
|
||||
int hcall_buf_prep(void **addr, size_t len) { return 0; }
|
||||
void hcall_buf_release(void **addr, size_t len) { }
|
||||
|
||||
static void xc_clean_hcall_buf(void) { }
|
||||
|
||||
#else /* !__sun__ */
|
||||
|
||||
int lock_pages(void *addr, size_t len)
|
||||
@@ -232,14 +225,6 @@ static void _xc_clean_hcall_buf(void *m)
|
||||
pthread_setspecific(hcall_buf_pkey, NULL);
|
||||
}
|
||||
|
||||
static void xc_clean_hcall_buf(void)
|
||||
{
|
||||
void *hcall_buf = pthread_getspecific(hcall_buf_pkey);
|
||||
|
||||
if (hcall_buf)
|
||||
_xc_clean_hcall_buf(hcall_buf);
|
||||
}
|
||||
|
||||
static void _xc_init_hcall_buf(void)
|
||||
{
|
||||
pthread_key_create(&hcall_buf_pkey, _xc_clean_hcall_buf);
|
||||
|
||||
+6
-6
@@ -410,7 +410,7 @@ int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid)
|
||||
* Does not modify info so that it may be reused.
|
||||
*/
|
||||
int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid,
|
||||
libxl_domain_create_info *info, const char *name_suffix, uint8_t new_uuid[16])
|
||||
libxl_domain_create_info *info, const char *name_suffix, libxl_uuid new_uuid)
|
||||
{
|
||||
struct xs_permissions roperm[2];
|
||||
xs_transaction_t t;
|
||||
@@ -1420,12 +1420,12 @@ int libxl_detach_device_model(libxl_ctx *ctx,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+17
-17
@@ -22,8 +22,12 @@
|
||||
#include <xs.h>
|
||||
#include <sys/wait.h> /* for pid_t */
|
||||
|
||||
typedef uint8_t libxl_uuid[16];
|
||||
|
||||
typedef uint8_t libxl_mac[6];
|
||||
|
||||
typedef struct {
|
||||
uint8_t uuid[16];
|
||||
libxl_uuid uuid;
|
||||
uint32_t domid;
|
||||
uint8_t running:1;
|
||||
uint8_t blocked:1;
|
||||
@@ -50,7 +54,7 @@ typedef struct {
|
||||
} libxl_poolinfo;
|
||||
|
||||
typedef struct {
|
||||
uint8_t uuid[16];
|
||||
libxl_uuid uuid;
|
||||
uint32_t domid;
|
||||
} libxl_vminfo;
|
||||
|
||||
@@ -93,7 +97,7 @@ typedef struct {
|
||||
bool oos;
|
||||
int ssidref;
|
||||
char *name;
|
||||
uint8_t uuid[16];
|
||||
libxl_uuid uuid;
|
||||
char **xsdata;
|
||||
char **platformdata;
|
||||
uint32_t poolid;
|
||||
@@ -173,7 +177,7 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
int domid;
|
||||
uint8_t uuid[16]; /* this is use only with stubdom, and must be different from the domain uuid */
|
||||
libxl_uuid uuid; /* this is use only with stubdom, and must be different from the domain uuid */
|
||||
char *dom_name;
|
||||
char *device_model;
|
||||
char *saved_state;
|
||||
@@ -268,7 +272,7 @@ typedef struct {
|
||||
int devid;
|
||||
int mtu;
|
||||
char *model;
|
||||
uint8_t mac[6];
|
||||
libxl_mac mac;
|
||||
struct in_addr ip;
|
||||
char *bridge;
|
||||
char *ifname;
|
||||
@@ -278,8 +282,8 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
int devid;
|
||||
uint8_t front_mac[6];
|
||||
uint8_t back_mac[6];
|
||||
libxl_mac front_mac;
|
||||
libxl_mac back_mac;
|
||||
uint32_t backend_domid;
|
||||
uint32_t domid;
|
||||
uint32_t trusted:1;
|
||||
@@ -338,7 +342,7 @@ int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info,
|
||||
int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid);
|
||||
int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid, int req);
|
||||
int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force);
|
||||
int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, libxl_domain_create_info *info, const char *name_suffix, uint8_t new_uuid[16]);
|
||||
int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, libxl_domain_create_info *info, const char *name_suffix, libxl_uuid new_uuid);
|
||||
|
||||
int libxl_file_reference_map(libxl_ctx *ctx, libxl_file_reference *f);
|
||||
int libxl_file_reference_unmap(libxl_ctx *ctx, libxl_file_reference *f);
|
||||
@@ -360,7 +364,7 @@ int libxl_run_bootloader(libxl_ctx *ctx,
|
||||
libxl_device_disk *disk,
|
||||
uint32_t domid);
|
||||
|
||||
char *libxl_uuid2string(libxl_ctx *ctx, const uint8_t uuid[16]);
|
||||
char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid);
|
||||
/* 0 means ERROR_ENOMEM, which we have logged */
|
||||
|
||||
/* events handling */
|
||||
@@ -496,7 +500,7 @@ typedef struct {
|
||||
int devid;
|
||||
int state;
|
||||
char *script;
|
||||
uint8_t mac[6];
|
||||
libxl_mac mac;
|
||||
int evtch;
|
||||
int rref_tx;
|
||||
int rref_rx;
|
||||
@@ -516,16 +520,12 @@ int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb);
|
||||
int libxl_device_vfb_clean_shutdown(libxl_ctx *ctx, uint32_t domid);
|
||||
int libxl_device_vfb_hard_shutdown(libxl_ctx *ctx, uint32_t domid);
|
||||
|
||||
#define PCI_BDF "%04x:%02x:%02x.%01x"
|
||||
#define PCI_BDF_VDEVFN "%04x:%02x:%02x.%01x@%02x"
|
||||
int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev);
|
||||
int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev);
|
||||
int libxl_device_pci_shutdown(libxl_ctx *ctx, uint32_t domid);
|
||||
int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint32_t domid, int *num);
|
||||
int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, int *num);
|
||||
int libxl_device_pci_init(libxl_device_pci *pcidev, unsigned int domain,
|
||||
unsigned int bus, unsigned int dev,
|
||||
unsigned int func, unsigned int vdevfn);
|
||||
int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const char *str);
|
||||
|
||||
/*
|
||||
* Functions for allowing users of libxl to store private data
|
||||
@@ -652,9 +652,9 @@ typedef struct {
|
||||
uint32_t frontend_id;
|
||||
int devid;
|
||||
int state;
|
||||
uint8_t mac[6];
|
||||
libxl_mac mac;
|
||||
int trusted;
|
||||
uint8_t back_mac[6];
|
||||
libxl_mac back_mac;
|
||||
int filter_mac;
|
||||
} libxl_net2info;
|
||||
|
||||
|
||||
@@ -380,6 +380,8 @@ int libxl_device_del(libxl_ctx *ctx, libxl_device *dev, int wait)
|
||||
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_ctx *ctx,
|
||||
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);
|
||||
|
||||
@@ -427,7 +427,7 @@ int save_device_model(libxl_ctx *ctx, uint32_t domid, int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *libxl_uuid2string(libxl_ctx *ctx, const uint8_t uuid[16]) {
|
||||
char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid) {
|
||||
char *s = string_of_uuid(ctx, uuid);
|
||||
if (!s) XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate for uuid");
|
||||
return s;
|
||||
|
||||
@@ -162,6 +162,8 @@ int libxl_devices_destroy(libxl_ctx *ctx, uint32_t domid, int force);
|
||||
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);
|
||||
|
||||
+243
-79
@@ -36,6 +36,161 @@
|
||||
#include "libxl_internal.h"
|
||||
#include "flexarray.h"
|
||||
|
||||
#define PCI_BDF "%04x:%02x:%02x.%01x"
|
||||
#define PCI_BDF_SHORT "%02x:%02x.%01x"
|
||||
#define PCI_BDF_VDEVFN "%04x:%02x:%02x.%01x@%02x"
|
||||
|
||||
static int pcidev_init(libxl_device_pci *pcidev, unsigned int domain,
|
||||
unsigned int bus, unsigned int dev,
|
||||
unsigned int func, unsigned int vdevfn)
|
||||
{
|
||||
pcidev->domain = domain;
|
||||
pcidev->bus = bus;
|
||||
pcidev->dev = dev;
|
||||
pcidev->func = func;
|
||||
pcidev->vdevfn = vdevfn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hex_convert(const char *str, unsigned int *val, unsigned int mask)
|
||||
{
|
||||
unsigned long ret;
|
||||
char *end;
|
||||
|
||||
ret = strtoul(str, &end, 16);
|
||||
if ( end == str || *end != '\0' )
|
||||
return -1;
|
||||
if ( ret & ~mask )
|
||||
return -1;
|
||||
*val = (unsigned int)ret & mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define STATE_DOMAIN 0
|
||||
#define STATE_BUS 1
|
||||
#define STATE_DEV 2
|
||||
#define STATE_FUNC 3
|
||||
#define STATE_VSLOT 4
|
||||
#define STATE_OPTIONS_K 6
|
||||
#define STATE_OPTIONS_V 7
|
||||
#define STATE_TERMINAL 8
|
||||
int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const char *str)
|
||||
{
|
||||
unsigned state = STATE_DOMAIN;
|
||||
unsigned dom, bus, dev, func, vslot = 0;
|
||||
char *buf2, *tok, *ptr, *end, *optkey = NULL;
|
||||
|
||||
if ( NULL == (buf2 = ptr = strdup(str)) )
|
||||
return ERROR_NOMEM;
|
||||
|
||||
for(tok = ptr, end = ptr + strlen(ptr) + 1; ptr < end; ptr++) {
|
||||
switch(state) {
|
||||
case STATE_DOMAIN:
|
||||
if ( *ptr == ':' ) {
|
||||
state = STATE_BUS;
|
||||
*ptr = '\0';
|
||||
if ( hex_convert(tok, &dom, 0xffff) )
|
||||
goto parse_error;
|
||||
tok = ptr + 1;
|
||||
}
|
||||
break;
|
||||
case STATE_BUS:
|
||||
if ( *ptr == ':' ) {
|
||||
state = STATE_DEV;
|
||||
*ptr = '\0';
|
||||
if ( hex_convert(tok, &bus, 0xff) )
|
||||
goto parse_error;
|
||||
tok = ptr + 1;
|
||||
}else if ( *ptr == '.' ) {
|
||||
state = STATE_FUNC;
|
||||
*ptr = '\0';
|
||||
if ( dom & ~0xff )
|
||||
goto parse_error;
|
||||
bus = dom;
|
||||
dom = 0;
|
||||
if ( hex_convert(tok, &dev, 0xff) )
|
||||
goto parse_error;
|
||||
tok = ptr + 1;
|
||||
}
|
||||
break;
|
||||
case STATE_DEV:
|
||||
if ( *ptr == '.' ) {
|
||||
state = STATE_FUNC;
|
||||
*ptr = '\0';
|
||||
if ( hex_convert(tok, &dev, 0xff) )
|
||||
goto parse_error;
|
||||
tok = ptr + 1;
|
||||
}
|
||||
break;
|
||||
case STATE_FUNC:
|
||||
if ( *ptr == '\0' || *ptr == '@' || *ptr == ',' ) {
|
||||
switch( *ptr ) {
|
||||
case '\0':
|
||||
state = STATE_TERMINAL;
|
||||
break;
|
||||
case '@':
|
||||
state = STATE_VSLOT;
|
||||
break;
|
||||
case ',':
|
||||
state = STATE_OPTIONS_K;
|
||||
break;
|
||||
}
|
||||
*ptr = '\0';
|
||||
if ( hex_convert(tok, &func, 0x7) )
|
||||
goto parse_error;
|
||||
tok = ptr + 1;
|
||||
}
|
||||
break;
|
||||
case STATE_VSLOT:
|
||||
if ( *ptr == '\0' || *ptr == ',' ) {
|
||||
state = ( *ptr == ',' ) ? STATE_OPTIONS_K : STATE_TERMINAL;
|
||||
*ptr = '\0';
|
||||
if ( hex_convert(tok, &vslot, 0xff) )
|
||||
goto parse_error;
|
||||
tok = ptr + 1;
|
||||
}
|
||||
break;
|
||||
case STATE_OPTIONS_K:
|
||||
if ( *ptr == '=' ) {
|
||||
state = STATE_OPTIONS_V;
|
||||
*ptr = '\0';
|
||||
optkey = tok;
|
||||
tok = ptr + 1;
|
||||
}
|
||||
break;
|
||||
case STATE_OPTIONS_V:
|
||||
if ( *ptr == ',' || *ptr == '\0' ) {
|
||||
state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL;
|
||||
*ptr = '\0';
|
||||
if ( !strcmp(optkey, "msitranslate") ) {
|
||||
pcidev->msitranslate = atoi(tok);
|
||||
}else if ( !strcmp(optkey, "power_mgmt") ) {
|
||||
pcidev->power_mgmt = atoi(tok);
|
||||
}else{
|
||||
XL_LOG(ctx, XL_LOG_WARNING,
|
||||
"Unknown PCI BDF option: %s", optkey);
|
||||
}
|
||||
tok = ptr + 1;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(buf2);
|
||||
|
||||
if ( tok != ptr || state != STATE_TERMINAL )
|
||||
goto parse_error;
|
||||
|
||||
pcidev_init(pcidev, dom, bus, dev, func, vslot << 3);
|
||||
|
||||
return 0;
|
||||
|
||||
parse_error:
|
||||
printf("parse error: %s\n", str);
|
||||
return ERROR_INVAL;
|
||||
}
|
||||
|
||||
static int libxl_create_pci_backend(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev, int num)
|
||||
{
|
||||
flexarray_t *front;
|
||||
@@ -288,7 +443,7 @@ static int get_all_assigned_devices(libxl_ctx *ctx, libxl_device_pci **list, int
|
||||
if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
|
||||
continue;
|
||||
|
||||
libxl_device_pci_init(pcidevs + *num, dom, bus, dev, func, 0);
|
||||
pcidev_init(pcidevs + *num, dom, bus, dev, func, 0);
|
||||
(*num)++;
|
||||
}
|
||||
}
|
||||
@@ -325,6 +480,71 @@ static int is_assigned(libxl_device_pci *assigned, int num_assigned,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, int *num)
|
||||
{
|
||||
libxl_device_pci *pcidevs = NULL, *new, *assigned;
|
||||
struct dirent *de;
|
||||
DIR *dir;
|
||||
int rc, num_assigned;
|
||||
|
||||
*num = 0;
|
||||
*list = NULL;
|
||||
|
||||
rc = get_all_assigned_devices(ctx, &assigned, &num_assigned);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
dir = opendir(SYSFS_PCIBACK_DRIVER);
|
||||
if ( NULL == dir ) {
|
||||
if ( errno == ENOENT ) {
|
||||
XL_LOG(ctx, XL_LOG_ERROR, "Looks like pciback driver not loaded");
|
||||
}else{
|
||||
XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", SYSFS_PCIBACK_DRIVER);
|
||||
}
|
||||
free(assigned);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
while( (de = readdir(dir)) ) {
|
||||
unsigned dom, bus, dev, func;
|
||||
if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
|
||||
continue;
|
||||
|
||||
if ( is_assigned(assigned, num_assigned, dom, bus, dev, func) )
|
||||
continue;
|
||||
|
||||
new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
|
||||
if ( NULL == new )
|
||||
continue;
|
||||
|
||||
pcidevs = new;
|
||||
new = pcidevs + *num;
|
||||
|
||||
memset(new, 0, sizeof(*new));
|
||||
pcidev_init(new, dom, bus, dev, func, 0);
|
||||
(*num)++;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
free(assigned);
|
||||
*list = pcidevs;
|
||||
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;
|
||||
@@ -347,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);
|
||||
@@ -460,12 +684,20 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcide
|
||||
|
||||
int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
|
||||
{
|
||||
libxl_device_pci *assigned;
|
||||
char *path;
|
||||
char *state;
|
||||
int hvm, rc;
|
||||
int hvm, rc, num;
|
||||
int stubdomid = 0;
|
||||
|
||||
/* TODO: check if the device can be detached */
|
||||
if ( !libxl_device_pci_list_assigned(ctx, &assigned, domid, &num) ) {
|
||||
if ( !is_assigned(assigned, num, pcidev->domain,
|
||||
pcidev->bus, pcidev->dev, pcidev->func) ) {
|
||||
XL_LOG(ctx, XL_LOG_ERROR, "PCI device not attached to this domain");
|
||||
return ERROR_INVAL;
|
||||
}
|
||||
}
|
||||
|
||||
libxl_device_pci_remove_xenstore(ctx, domid, pcidev);
|
||||
|
||||
hvm = is_hvm(ctx, domid);
|
||||
@@ -554,63 +786,6 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static libxl_device_pci *scan_sys_pcidir(libxl_device_pci *assigned,
|
||||
int num_assigned, const char *path, int *num)
|
||||
{
|
||||
libxl_device_pci *pcidevs = NULL, *new;
|
||||
struct dirent *de;
|
||||
DIR *dir;
|
||||
|
||||
dir = opendir(path);
|
||||
if ( NULL == dir )
|
||||
return pcidevs;
|
||||
|
||||
while( (de = readdir(dir)) ) {
|
||||
unsigned dom, bus, dev, func;
|
||||
if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
|
||||
continue;
|
||||
|
||||
if ( is_assigned(assigned, num_assigned, dom, bus, dev, func) )
|
||||
continue;
|
||||
|
||||
new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
|
||||
if ( NULL == new )
|
||||
continue;
|
||||
|
||||
pcidevs = new;
|
||||
new = pcidevs + *num;
|
||||
|
||||
memset(new, 0, sizeof(*new));
|
||||
libxl_device_pci_init(new, dom, bus, dev, func, 0);
|
||||
(*num)++;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return pcidevs;
|
||||
}
|
||||
|
||||
int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, int *num)
|
||||
{
|
||||
libxl_device_pci *pcidevs = NULL;
|
||||
libxl_device_pci *assigned;
|
||||
int num_assigned, rc;
|
||||
|
||||
*num = 0;
|
||||
*list = NULL;
|
||||
|
||||
rc = get_all_assigned_devices(ctx, &assigned, &num_assigned);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
pcidevs = scan_sys_pcidir(assigned, num_assigned,
|
||||
SYSFS_PCIBACK_DRIVER, num);
|
||||
|
||||
free(assigned);
|
||||
if ( *num )
|
||||
*list = pcidevs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint32_t domid, int *num)
|
||||
{
|
||||
char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts;
|
||||
@@ -623,7 +798,7 @@ int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint
|
||||
if (!num_devs) {
|
||||
*num = 0;
|
||||
*list = NULL;
|
||||
return ERROR_FAIL;
|
||||
return 0;
|
||||
}
|
||||
n = atoi(num_devs);
|
||||
pcidevs = calloc(n, sizeof(libxl_device_pci));
|
||||
@@ -635,7 +810,7 @@ int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint
|
||||
xsvdevfn = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, i));
|
||||
if (xsvdevfn)
|
||||
vdevfn = strtol(xsvdevfn, (char **) NULL, 16);
|
||||
libxl_device_pci_init(pcidevs + i, domain, bus, dev, func, vdevfn);
|
||||
pcidev_init(pcidevs + i, domain, bus, dev, func, vdevfn);
|
||||
xsopts = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/opts-%d", be_path, i));
|
||||
if (xsopts) {
|
||||
char *saveptr;
|
||||
@@ -674,24 +849,13 @@ int libxl_device_pci_shutdown(libxl_ctx *ctx, uint32_t domid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl_device_pci_init(libxl_device_pci *pcidev, unsigned int domain,
|
||||
unsigned int bus, unsigned int dev,
|
||||
unsigned int func, unsigned int vdevfn)
|
||||
{
|
||||
pcidev->domain = domain;
|
||||
pcidev->bus = bus;
|
||||
pcidev->dev = dev;
|
||||
pcidev->func = func;
|
||||
pcidev->vdevfn = vdevfn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int bus,
|
||||
unsigned int dev, unsigned int func)
|
||||
{
|
||||
char *reset = "/sys/bus/pci/drivers/pciback/do_flr";
|
||||
char *reset;
|
||||
int fd, rc;
|
||||
|
||||
reset = libxl_sprintf(ctx, "%s/pciback/do_flr", SYSFS_PCI_DEV);
|
||||
fd = open(reset, O_WRONLY);
|
||||
if (fd > 0) {
|
||||
char *buf = libxl_sprintf(ctx, PCI_BDF, domain, bus, dev, func);
|
||||
@@ -703,7 +867,7 @@ int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int bus
|
||||
}
|
||||
if (errno != ENOENT)
|
||||
XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", reset);
|
||||
reset = libxl_sprintf(ctx, "/sys/bus/pci/devices/"PCI_BDF"/reset", domain, bus, dev, func);
|
||||
reset = libxl_sprintf(ctx, "%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, dev, func);
|
||||
fd = open(reset, O_WRONLY);
|
||||
if (fd > 0) {
|
||||
rc = write(fd, "1", 1);
|
||||
|
||||
@@ -91,7 +91,11 @@ int xlu_cfg_readdata(XLU_Config *cfg, const char *data, int length) {
|
||||
}
|
||||
|
||||
void xlu__cfg_set_free(XLU_ConfigSetting *set) {
|
||||
int i;
|
||||
|
||||
free(set->name);
|
||||
for (i=0; i<set->nvalues; i++)
|
||||
free(set->values[i]);
|
||||
free(set->values);
|
||||
free(set);
|
||||
}
|
||||
|
||||
+13
-43
@@ -265,11 +265,11 @@ static void init_build_info(libxl_domain_build_info *b_info, libxl_domain_create
|
||||
}
|
||||
}
|
||||
|
||||
static void random_uuid(uint8_t *uuid)
|
||||
static void random_uuid(libxl_uuid *uuid)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
uuid[i] = rand();
|
||||
(*uuid)[i] = rand();
|
||||
}
|
||||
|
||||
static void init_dm_info(libxl_device_model_info *dm_info,
|
||||
@@ -277,7 +277,7 @@ static void init_dm_info(libxl_device_model_info *dm_info,
|
||||
{
|
||||
memset(dm_info, '\0', sizeof(*dm_info));
|
||||
|
||||
random_uuid(&dm_info->uuid[0]);
|
||||
random_uuid(&dm_info->uuid);
|
||||
|
||||
dm_info->dom_name = c_info->name;
|
||||
dm_info->device_model = "qemu-dm";
|
||||
@@ -495,7 +495,7 @@ static void printf_info(int domid,
|
||||
for (i = 0; i < d_config->num_pcidevs; i++) {
|
||||
printf("\t(device\n");
|
||||
printf("\t\t(pci\n");
|
||||
printf("\t\t\t(pci dev "PCI_BDF_VDEVFN")\n",
|
||||
printf("\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n",
|
||||
d_config->pcidevs[i].domain, d_config->pcidevs[i].bus,
|
||||
d_config->pcidevs[i].dev, d_config->pcidevs[i].func,
|
||||
d_config->pcidevs[i].vdevfn);
|
||||
@@ -586,7 +586,7 @@ static void parse_config_data(const char *configfile_filename_report,
|
||||
c_info->name = strdup(buf);
|
||||
else
|
||||
c_info->name = "test";
|
||||
random_uuid(&c_info->uuid[0]);
|
||||
random_uuid(&c_info->uuid);
|
||||
|
||||
if (!xlu_cfg_get_long(config, "oos", &l))
|
||||
c_info->oos = l;
|
||||
@@ -953,46 +953,20 @@ skip_vfb:
|
||||
pci_power_mgmt = l;
|
||||
|
||||
if (!xlu_cfg_get_list (config, "pci", &pcis, 0)) {
|
||||
int i;
|
||||
d_config->num_pcidevs = 0;
|
||||
d_config->pcidevs = NULL;
|
||||
while ((buf = xlu_cfg_get_listitem (pcis, d_config->num_pcidevs)) != NULL) {
|
||||
for(i = 0; (buf = xlu_cfg_get_listitem (pcis, i)) != NULL; i++) {
|
||||
libxl_device_pci *pcidev;
|
||||
unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0;
|
||||
char *buf2 = strdup(buf);
|
||||
char *p;
|
||||
|
||||
d_config->pcidevs = (libxl_device_pci *) realloc(d_config->pcidevs, sizeof (libxl_device_pci) * (d_config->num_pcidevs + 1));
|
||||
pcidev = d_config->pcidevs + d_config->num_pcidevs;
|
||||
memset(pcidev, 0x00, sizeof(libxl_device_pci));
|
||||
|
||||
p = strtok(buf2, ",");
|
||||
if (!p)
|
||||
goto skip_pci;
|
||||
if (sscanf(p, PCI_BDF_VDEVFN, &domain, &bus, &dev, &func, &vdevfn) < 4) {
|
||||
domain = 0;
|
||||
if (sscanf(p, "%02x:%02x.%01x@%02x", &bus, &dev, &func, &vdevfn) < 3) {
|
||||
fprintf(stderr,"xl: Unable to parse pci bdf (%s)\n", p);
|
||||
goto skip_pci;
|
||||
}
|
||||
}
|
||||
|
||||
libxl_device_pci_init(pcidev, domain, bus, dev, func, vdevfn);
|
||||
pcidev->msitranslate = pci_msitranslate;
|
||||
pcidev->power_mgmt = pci_power_mgmt;
|
||||
while ((p = strtok(NULL, ",=")) != NULL) {
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
if (!strcmp(p, "msitranslate")) {
|
||||
p = strtok(NULL, ",=");
|
||||
pcidev->msitranslate = atoi(p);
|
||||
} else if (!strcmp(p, "power_mgmt")) {
|
||||
p = strtok(NULL, ",=");
|
||||
pcidev->power_mgmt = atoi(p);
|
||||
}
|
||||
}
|
||||
d_config->num_pcidevs++;
|
||||
skip_pci:
|
||||
free(buf2);
|
||||
if (!libxl_device_pci_parse_bdf(&ctx, pcidev, buf))
|
||||
d_config->num_pcidevs++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1181,7 +1155,7 @@ static int preserve_domain(libxl_ctx *ctx, uint32_t domid, libxl_event *event,
|
||||
struct tm tm;
|
||||
char stime[24];
|
||||
|
||||
uint8_t new_uuid[16];
|
||||
libxl_uuid new_uuid;
|
||||
|
||||
int rc;
|
||||
|
||||
@@ -1202,7 +1176,7 @@ static int preserve_domain(libxl_ctx *ctx, uint32_t domid, libxl_event *event,
|
||||
return 0;
|
||||
}
|
||||
|
||||
random_uuid(&new_uuid[0]);
|
||||
random_uuid(&new_uuid);
|
||||
|
||||
LOG("Preserving domain %d %s with suffix%s", domid, d_config->c_info.name, stime);
|
||||
rc = libxl_domain_preserve(ctx, domid, &d_config->c_info, stime, new_uuid);
|
||||
@@ -2019,16 +1993,14 @@ int main_pcilist(int argc, char **argv)
|
||||
void pcidetach(char *dom, char *bdf)
|
||||
{
|
||||
libxl_device_pci pcidev;
|
||||
unsigned int domain, bus, dev, func;
|
||||
|
||||
find_domain(dom);
|
||||
|
||||
memset(&pcidev, 0x00, sizeof(pcidev));
|
||||
if (sscanf(bdf, PCI_BDF, &domain, &bus, &dev, &func) != 4) {
|
||||
if (libxl_device_pci_parse_bdf(&ctx, &pcidev, bdf)) {
|
||||
fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", bdf);
|
||||
exit(2);
|
||||
}
|
||||
libxl_device_pci_init(&pcidev, domain, bus, dev, func, 0);
|
||||
libxl_device_pci_remove(&ctx, domid, &pcidev);
|
||||
}
|
||||
|
||||
@@ -2061,16 +2033,14 @@ int main_pcidetach(int argc, char **argv)
|
||||
void pciattach(char *dom, char *bdf, char *vs)
|
||||
{
|
||||
libxl_device_pci pcidev;
|
||||
unsigned int domain, bus, dev, func;
|
||||
|
||||
find_domain(dom);
|
||||
|
||||
memset(&pcidev, 0x00, sizeof(pcidev));
|
||||
if (sscanf(bdf, PCI_BDF, &domain, &bus, &dev, &func) != 4) {
|
||||
if (libxl_device_pci_parse_bdf(&ctx, &pcidev, bdf)) {
|
||||
fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf);
|
||||
exit(2);
|
||||
}
|
||||
libxl_device_pci_init(&pcidev, domain, bus, dev, func, 0);
|
||||
libxl_device_pci_add(&ctx, domid, &pcidev);
|
||||
}
|
||||
|
||||
|
||||