[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 5/9] tools/libs/light: Add "write" command to xl pcid and libxl PCI
From: Anastasiia Lukianenko <anastasiia_lukianenko@xxxxxxxx> Add functions for handling "write" command on xl pcid side. Libxl PCI side receives reply: 1. success - string in "return" message 2. fail - error type of reply message Signed-off-by: Anastasiia Lukianenko <anastasiia_lukianenko@xxxxxxxx> --- tools/include/pcid.h | 7 ++++ tools/libs/light/libxl_pci.c | 69 +++++++++++++++++++---------------- tools/libs/light/libxl_pcid.c | 69 +++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 32 deletions(-) diff --git a/tools/include/pcid.h b/tools/include/pcid.h index e9c3c497c6..935d99b186 100644 --- a/tools/include/pcid.h +++ b/tools/include/pcid.h @@ -31,7 +31,14 @@ #define PCID_CMD_LIST "ls" #define PCID_CMD_DIR_ID "dir_id" +#define PCID_CMD_WRITE "write" +#define PCID_CMD_PCI_PATH "pci_path" +#define PCID_CMD_PCI_INFO "pci_info" + #define PCID_PCIBACK_DRIVER "pciback_driver" +#define PCID_PCI_DEV "pci_dev" + +#define SYSFS_DRIVER_PATH "driver_path" #if defined(__linux__) #define SYSFS_PCIBACK_DRIVER "/sys/bus/pci/drivers/pciback" diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index 6534b70777..03ce42dec3 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -455,28 +455,34 @@ static bool is_pci_in_array(libxl_device_pci *pcis, int num, } /* Write the standard BDF into the sysfs path given by sysfs_path. */ -static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path, +static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path, + const char *pci_path, libxl_device_pci *pci) { - int rc, fd; char *buf; - fd = open(sysfs_path, O_WRONLY); - if (fd < 0) { - LOGE(ERROR, "Couldn't open %s", sysfs_path); - return ERROR_FAIL; - } + struct vchan_info *vchan; + libxl__json_object *args = NULL, *result = NULL; - buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus, - pci->dev, pci->func); - rc = write(fd, buf, strlen(buf)); - /* Annoying to have two if's, but we need the errno */ - if (rc < 0) - LOGE(ERROR, "write to %s returned %d", sysfs_path, rc); - close(fd); + vchan = pci_prepare_vchan(gc); + if (!vchan) + return ERROR_FAIL; - if (rc < 0) + buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func); + if (strcmp(SYSFS_PCI_DEV, sysfs_path) == 0) + libxl__vchan_param_add_string(gc, &args, PCID_CMD_DIR_ID, PCID_PCI_DEV); + else if (strcmp(SYSFS_PCIBACK_DRIVER, sysfs_path) == 0) + libxl__vchan_param_add_string(gc, &args, PCID_CMD_DIR_ID, PCID_PCIBACK_DRIVER); + else if (strcmp(SYSFS_DRIVER_PATH, sysfs_path) == 0) + libxl__vchan_param_add_string(gc, &args, PCID_CMD_DIR_ID, SYSFS_DRIVER_PATH); + + libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_PATH, pci_path); + libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_INFO, buf); + result = vchan_send_command(gc, vchan, PCID_CMD_WRITE, args); + if (!result) { + LOGE(WARN, "Write %s to %s failed\n", buf, sysfs_path); return ERROR_FAIL; + } return 0; } @@ -593,14 +599,13 @@ void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num) static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci, char **driver_path) { - char * spath, *dp = NULL; + char *spath, *pci_path, *dp = NULL; struct stat st; - spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver", - pci->domain, - pci->bus, - pci->dev, - pci->func); + pci_path = GCSPRINTF("/"PCI_BDF"/driver", pci->domain, pci->bus, + pci->dev, pci->func); + + spath = GCSPRINTF(SYSFS_PCI_DEV"%s", pci_path); if ( !lstat(spath, &st) ) { /* Find the canonical path to the driver. */ dp = libxl__zalloc(gc, PATH_MAX); @@ -614,7 +619,7 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci, /* Unbind from the old driver */ spath = GCSPRINTF("%s/unbind", dp); - if ( sysfs_write_bdf(gc, spath, pci) < 0 ) { + if (sysfs_write_bdf(gc, SYSFS_PCI_DEV, pci_path, pci) < 0) { LOGE(ERROR, "Couldn't unbind device"); return -1; } @@ -816,14 +821,14 @@ static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pci) LOGE(ERROR, "Error checking for pciback slot"); return ERROR_FAIL; } else if (rc == 0) { - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot", - pci) < 0 ) { + if (sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER, "/new_slot", + pci) < 0) { LOGE(ERROR, "Couldn't bind device to pciback!"); return ERROR_FAIL; } } - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pci) < 0 ) { + if (sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER, "/bind", pci) < 0) { LOGE(ERROR, "Couldn't bind device to pciback!"); return ERROR_FAIL; } @@ -840,8 +845,8 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci) /* Remove slot if necessary */ if ( pciback_dev_has_slot(gc, pci) > 0 ) { - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot", - pci) < 0 ) { + if (sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER, "/remove_slot", + pci) < 0) { LOGE(ERROR, "Couldn't remove pciback slot"); return ERROR_FAIL; } @@ -1022,9 +1027,9 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc, if ( rebind ) { LOG(INFO, "Rebinding to driver at %s", driver_path); - if ( sysfs_write_bdf(gc, - GCSPRINTF("%s/bind", driver_path), - pci) < 0 ) { + if (sysfs_write_bdf(gc, SYSFS_DRIVER_PATH, + GCSPRINTF("%s/bind", driver_path), + pci) < 0) { LOGE(ERROR, "Couldn't bind device to %s", driver_path); return -1; } @@ -1565,8 +1570,8 @@ static void pci_add_dm_done(libxl__egc *egc, /* Don't restrict writes to the PCI config space from this VM */ if (pci->permissive) { - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive", - pci) < 0 ) { + if (sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER, "/permissive", + pci) < 0) { LOGD(ERROR, domainid, "Setting permissive for device"); rc = ERROR_FAIL; goto out; diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c index c897244e8a..ee4c832779 100644 --- a/tools/libs/light/libxl_pcid.c +++ b/tools/libs/light/libxl_pcid.c @@ -87,6 +87,73 @@ out: return result; } +static int handle_write_cmd(libxl__gc *gc, char *sysfs_path, char *pci_info) +{ + int rc, fd; + + fd = open(sysfs_path, O_WRONLY); + if (fd < 0) { + LOGE(ERROR, "Couldn't open %s\n", sysfs_path); + return ERROR_FAIL; + } + + rc = write(fd, pci_info, strlen(pci_info)); + close(fd); + if (rc < 0) { + LOGE(ERROR, "write to %s returned %d\n", sysfs_path, rc); + return ERROR_FAIL; + } + + return 0; +} + +static libxl__json_object *process_write_cmd(libxl__gc *gc, + const struct libxl__json_object *resp) +{ + libxl__json_object *result = NULL; + const struct libxl__json_object *args, *dir_id, *pci_path, *pci_info; + char *full_path; + int ret; + + args = libxl__json_map_get(PCID_MSG_FIELD_ARGS, resp, JSON_MAP); + if (!args) + goto out; + dir_id = libxl__json_map_get(PCID_CMD_DIR_ID, args, JSON_ANY); + if (!dir_id) + goto out; + pci_path = libxl__json_map_get(PCID_CMD_PCI_PATH, args, JSON_ANY); + if (!pci_path) + goto out; + pci_info = libxl__json_map_get(PCID_CMD_PCI_INFO, args, JSON_ANY); + if (!pci_info) + goto out; + + if (strcmp(dir_id->u.string, PCID_PCI_DEV) == 0) + full_path = libxl__sprintf(gc, SYSFS_PCI_DEV"%s", pci_path->u.string); + else if (strcmp(dir_id->u.string, PCID_PCIBACK_DRIVER) == 0) + full_path = libxl__sprintf(gc, SYSFS_PCIBACK_DRIVER"%s", pci_path->u.string); + else if (strcmp(dir_id->u.string, SYSFS_DRIVER_PATH) == 0) + full_path = pci_path->u.string; + else { + LOGE(ERROR, "Unknown write directory %s\n", dir_id->u.string); + goto out; + } + + ret = handle_write_cmd(gc, full_path, pci_info->u.string); + if (ret != 0) + goto out; + + result = libxl__json_object_alloc(gc, JSON_STRING); + if (!result) { + LOGE(ERROR, "Memory allocation failed\n"); + goto out; + } + result->u.string = pci_path->u.string; + +out: + return result; +} + static int pcid_handle_message(libxl__gc *gc, const libxl__json_object *request, libxl__json_object **result) { @@ -102,6 +169,8 @@ static int pcid_handle_message(libxl__gc *gc, const libxl__json_object *request, if (strcmp(command_name, PCID_CMD_LIST) == 0) *result = process_ls_cmd(gc, request); + else if (strcmp(PCID_CMD_WRITE, command_name) == 0) + *result = process_write_cmd(gc, request); else return ERROR_NOTFOUND; -- 2.17.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |