aboutsummaryrefslogtreecommitdiff
path: root/samples/client.c
diff options
context:
space:
mode:
authorThanos Makatos <thanos.makatos@nutanix.com>2020-11-20 11:52:46 -0500
committerThanos Makatos <thanos.makatos@nutanix.com>2020-11-20 11:54:08 -0500
commit1449d02a00c9beda04d917e0da181802d5455fd1 (patch)
tree284a7ccd503862bbe3e669001e286871ceda598d /samples/client.c
parent45c91ab9297f049569af0cf35c619c0ae107005e (diff)
downloadlibvfio-user-1449d02a00c9beda04d917e0da181802d5455fd1.zip
libvfio-user-1449d02a00c9beda04d917e0da181802d5455fd1.tar.gz
libvfio-user-1449d02a00c9beda04d917e0da181802d5455fd1.tar.bz2
don't expose migration as region
Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'samples/client.c')
-rw-r--r--samples/client.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/samples/client.c b/samples/client.c
index 1c3a491..21630ff 100644
--- a/samples/client.c
+++ b/samples/client.c
@@ -198,7 +198,8 @@ send_device_reset(int sock)
}
}
-static void
+/* returns whether a VFIO migration capability is found */
+static bool
get_region_vfio_caps(int sock, size_t cap_sz)
{
struct vfio_info_cap_header *header, *_header;
@@ -206,6 +207,7 @@ get_region_vfio_caps(int sock, size_t cap_sz)
struct vfio_region_info_cap_sparse_mmap *sparse;
unsigned int i;
ssize_t ret;
+ bool migr = false;
header = _header = calloc(cap_sz, 1);
if (header == NULL) {
@@ -236,6 +238,7 @@ get_region_vfio_caps(int sock, size_t cap_sz)
errx(EXIT_FAILURE, "bad region type %d/%d", type->type,
type->subtype);
}
+ migr = true;
printf("migration region\n");
break;
default:
@@ -247,15 +250,19 @@ get_region_vfio_caps(int sock, size_t cap_sz)
header = (struct vfio_info_cap_header*)((char*)header + header->next - sizeof(struct vfio_region_info));
}
free(_header);
+ return migr;
}
-static void
+/*
+ * Returns the index of the migration region if found, -1 otherwise.
+ */
+static int
get_device_region_info(int sock, struct vfio_device_info *client_dev_info)
{
struct vfio_region_info region_info;
uint16_t msg_id = 0;
size_t cap_sz;
- int ret;
+ int ret, migr_reg_index = -1;
unsigned int i;
msg_id = 1;
@@ -279,9 +286,13 @@ get_device_region_info(int sock, struct vfio_device_info *client_dev_info)
"cap_sz %lu\n", __func__, i, region_info.offset,
region_info.flags, region_info.size, cap_sz);
if (cap_sz) {
- get_region_vfio_caps(sock, cap_sz);
+ if (get_region_vfio_caps(sock, cap_sz)) {
+ assert(migr_reg_index == -1);
+ migr_reg_index = i;
+ }
}
}
+ return migr_reg_index;
}
static void
@@ -299,11 +310,6 @@ get_device_info(int sock, struct vfio_device_info *dev_info)
errx(EXIT_FAILURE, "failed to get device info: %s", strerror(-ret));
}
- if (dev_info->num_regions != 10) {
- errx(EXIT_FAILURE, "bad number of device regions %d",
- dev_info->num_regions);
- }
-
printf("devinfo: flags %#x, num_regions %d, num_irqs %d\n",
dev_info->flags, dev_info->num_regions, dev_info->num_irqs);
}
@@ -649,13 +655,13 @@ usage(char *path) {
}
static void
-migrate_from(int sock, void **data, __u64 *len)
+migrate_from(int sock, int migr_reg_index, void **data, __u64 *len)
{
__u32 device_state = VFIO_DEVICE_STATE_SAVING;
__u64 pending_bytes, data_offset, data_size;
/* XXX set device state to stop-and-copy */
- int ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, true,
+ int ret = access_region(sock, migr_reg_index, true,
offsetof(struct vfio_device_migration_info, device_state),
&device_state, sizeof(device_state));
if (ret < 0) {
@@ -664,7 +670,7 @@ migrate_from(int sock, void **data, __u64 *len)
}
/* XXX read pending_bytes */
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, false,
+ ret = access_region(sock, migr_reg_index, false,
offsetof(struct vfio_device_migration_info, pending_bytes),
&pending_bytes, sizeof pending_bytes);
if (ret < 0) {
@@ -690,7 +696,7 @@ migrate_from(int sock, void **data, __u64 *len)
while (pending_bytes > 0) {
/* XXX read data_offset and data_size */
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, false,
+ ret = access_region(sock, migr_reg_index, false,
offsetof(struct vfio_device_migration_info, data_offset),
&data_offset, sizeof data_offset);
if (ret < 0) {
@@ -698,7 +704,7 @@ migrate_from(int sock, void **data, __u64 *len)
strerror(-ret));
}
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, false,
+ ret = access_region(sock, migr_reg_index, false,
offsetof(struct vfio_device_migration_info, data_size),
&data_size, sizeof data_size);
if (ret < 0) {
@@ -709,7 +715,7 @@ migrate_from(int sock, void **data, __u64 *len)
assert(data_offset - sizeof(struct vfio_device_migration_info) + data_size <= *len);
/* XXX read migration data */
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, false, data_offset,
+ ret = access_region(sock, migr_reg_index, false, data_offset,
(char*)*data + data_offset - sizeof(struct vfio_device_migration_info),
data_size);
if (ret < 0) {
@@ -723,7 +729,7 @@ migrate_from(int sock, void **data, __u64 *len)
* XXX read pending_bytes again to indicate to the sever that the
* migration data have been consumed.
*/
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, false,
+ ret = access_region(sock, migr_reg_index, false,
offsetof(struct vfio_device_migration_info, pending_bytes),
&pending_bytes, sizeof pending_bytes);
if (ret < 0) {
@@ -734,7 +740,7 @@ migrate_from(int sock, void **data, __u64 *len)
/* XXX read device state, migration must have finished now */
device_state = VFIO_DEVICE_STATE_STOP;
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, true,
+ ret = access_region(sock, migr_reg_index, true,
offsetof(struct vfio_device_migration_info, device_state),
&device_state, sizeof(device_state));
if (ret < 0) {
@@ -746,7 +752,7 @@ migrate_from(int sock, void **data, __u64 *len)
static int
migrate_to(char *old_sock_path, int client_max_fds, int *server_max_fds,
size_t *pgsize, void *migr_data, __u64 migr_data_len,
- char *path_to_server)
+ char *path_to_server, int migr_reg_index)
{
int ret, sock;
char *sock_path;
@@ -797,18 +803,18 @@ migrate_to(char *old_sock_path, int client_max_fds, int *server_max_fds,
negotiate(sock, client_max_fds, server_max_fds, pgsize);
/* XXX set device state to resuming */
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, true,
- offsetof(struct vfio_device_migration_info, device_state),
- &device_state, sizeof(device_state));
+ ret = access_region(sock, migr_reg_index, true,
+ offsetof(struct vfio_device_migration_info, device_state),
+ &device_state, sizeof(device_state));
if (ret < 0) {
errx(EXIT_FAILURE, "failed to set device state to resuming: %s",
strerror(-ret));
}
/* XXX read data offset */
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, false,
- offsetof(struct vfio_device_migration_info, data_offset),
- &data_offset, sizeof(data_offset));
+ ret = access_region(sock, migr_reg_index, false,
+ offsetof(struct vfio_device_migration_info, data_offset),
+ &data_offset, sizeof(data_offset));
if (ret < 0) {
errx(EXIT_FAILURE, "failed to read data offset: %s", strerror(-ret));
}
@@ -819,7 +825,7 @@ migrate_to(char *old_sock_path, int client_max_fds, int *server_max_fds,
* TODO write half of migration data via regular write and other half via
* memopy map.
*/
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, true,
+ ret = access_region(sock, migr_reg_index, true,
data_offset, migr_data, migr_data_len);
if (ret < 0) {
errx(EXIT_FAILURE, "failed to write migration data: %s",
@@ -827,7 +833,7 @@ migrate_to(char *old_sock_path, int client_max_fds, int *server_max_fds,
}
/* XXX write data_size */
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, true,
+ ret = access_region(sock, migr_reg_index, true,
offsetof(struct vfio_device_migration_info, data_size),
&migr_data_len, sizeof migr_data_len);
if (ret < 0) {
@@ -836,7 +842,7 @@ migrate_to(char *old_sock_path, int client_max_fds, int *server_max_fds,
/* XXX set device state to running */
device_state = VFIO_DEVICE_STATE_RUNNING;
- ret = access_region(sock, LM_DEV_MIGRATION_REG_IDX, true,
+ ret = access_region(sock, migr_reg_index, true,
offsetof(struct vfio_device_migration_info, device_state),
&device_state, sizeof(device_state));
if (ret < 0) {
@@ -885,6 +891,7 @@ int main(int argc, char *argv[])
__u64 migr_data_len;
char *path_to_server = NULL;
lm_pci_hdr_t config_space;
+ int migr_reg_index;
while ((opt = getopt(argc, argv, "h")) != -1) {
switch (opt) {
@@ -923,7 +930,10 @@ int main(int argc, char *argv[])
get_device_info(sock, &client_dev_info);
/* XXX VFIO_USER_DEVICE_GET_REGION_INFO */
- get_device_region_info(sock, &client_dev_info);
+ migr_reg_index = get_device_region_info(sock, &client_dev_info);
+ if (migr_reg_index == -1) {
+ errx(EXIT_FAILURE, "could not find migration region");
+ }
ret = access_region(sock, LM_DEV_CFG_REG_IDX, false, 0, &config_space,
sizeof config_space);
@@ -1046,7 +1056,7 @@ int main(int argc, char *argv[])
*/
sleep(1);
- migrate_from(sock, &migr_data, &migr_data_len);
+ migrate_from(sock, migr_reg_index, &migr_data, &migr_data_len);
/*
* Normally the client would now send the device state to the destination
@@ -1059,7 +1069,7 @@ int main(int argc, char *argv[])
}
sock = migrate_to(argv[optind], client_max_fds, &server_max_fds, &pgsize,
- migr_data, migr_data_len, path_to_server);
+ migr_data, migr_data_len, path_to_server, migr_reg_index);
/*
* Now we must reconfigure the destination server.