migration: set data_fd to -1 in device state response (#876)
* migration: set data_fd to -1 in device state response
The vfio-user protocol specification requires that data_fd must be set
to -1 in both the request and response of VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE,
as migration data transport relies on socket messages rather than a file descriptor.
Force data_fd to -1 in both the GET and SET migration feature handlers
to ensure the server properly complies with the specification.
Signed-off-by: Hugo Komatsu <hugo.komatsu@nutanix.com>
Co-authored-by: John Levon <john.levon@nutanix.com>
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 7f083a1..62a5f13 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -1018,6 +1018,7 @@
struct vfio_user_device_feature_mig_state *state =
(void *)res->data;
state->device_state = migration_get_state(vfu_ctx);
+ state->data_fd = -1;
return 0;
}
@@ -1032,11 +1033,14 @@
handle_migration_device_feature_set(vfu_ctx_t *vfu_ctx, uint32_t feature,
struct vfio_user_device_feature *res)
{
+ int ret;
assert(feature == VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE);
struct vfio_user_device_feature_mig_state *state = (void *)res->data;
- return migration_set_state(vfu_ctx, state->device_state);
+ ret = migration_set_state(vfu_ctx, state);
+
+ return ret;
}
static int
diff --git a/lib/migration.c b/lib/migration.c
index f995fca..603dc92 100644
--- a/lib/migration.c
+++ b/lib/migration.c
@@ -262,16 +262,17 @@
}
ssize_t
-migration_set_state(vfu_ctx_t *vfu_ctx, uint32_t device_state)
+migration_set_state(vfu_ctx_t *vfu_ctx, struct vfio_user_device_feature_mig_state *mig_state)
{
struct migration *migr = vfu_ctx->migration;
uint32_t state;
ssize_t ret = 0;
-
+ uint32_t device_state = mig_state->device_state;
+
if (device_state >= VFIO_USER_DEVICE_NUM_STATES) {
return ERROR_INT(EINVAL);
}
-
+
while (migr->state != device_state && ret == 0) {
state = next_state[migr->state][device_state];
@@ -280,8 +281,11 @@
}
ret = handle_device_state(vfu_ctx, migr, state, true);
- };
-
+ }
+
+ /* Force data_fd to -1 in the response per the vfio-user protocol */
+ mig_state->data_fd = -1;
+
return ret;
}
diff --git a/lib/migration.h b/lib/migration.h
index 928a7e5..513cf59 100644
--- a/lib/migration.h
+++ b/lib/migration.h
@@ -51,7 +51,7 @@
migration_get_state(vfu_ctx_t *vfu_ctx);
ssize_t
-migration_set_state(vfu_ctx_t *vfu_ctx, uint32_t device_state);
+migration_set_state(vfu_ctx_t *vfu_ctx, struct vfio_user_device_feature_mig_state *mig_state);
ssize_t
handle_mig_data_read(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg);
diff --git a/test/py/test_migration.py b/test/py/test_migration.py
index 3fc3d19..6c0878f 100644
--- a/test/py/test_migration.py
+++ b/test/py/test_migration.py
@@ -347,6 +347,8 @@
_, result = vfio_user_device_feature.pop_from_buffer(result)
state, _ = vfio_user_device_feature_mig_state.pop_from_buffer(result)
assert state.device_state == VFIO_USER_DEVICE_STATE_RUNNING
+ # defined as -1 embedded into a uint32_t
+ assert state.data_fd == 4294967295
def test_handle_mig_data_read():