|
[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 |