aboutsummaryrefslogtreecommitdiff
path: root/wmediumd/lib/vhost.c
diff options
context:
space:
mode:
Diffstat (limited to 'wmediumd/lib/vhost.c')
-rw-r--r--wmediumd/lib/vhost.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/wmediumd/lib/vhost.c b/wmediumd/lib/vhost.c
index b6a7a70..7e177ac 100644
--- a/wmediumd/lib/vhost.c
+++ b/wmediumd/lib/vhost.c
@@ -41,6 +41,7 @@ struct usfstl_vhost_user_dev_int {
struct {
struct usfstl_loop_entry entry;
bool enabled;
+ bool sleeping;
bool triggered;
struct vring virtq;
int call_fd;
@@ -673,6 +674,63 @@ static void usfstl_vhost_user_handle_msg(struct usfstl_loop_entry *entry)
reply_len = sizeof(uint64_t);
msg.payload.u64 = 0;
break;
+ case VHOST_USER_SLEEP:
+ USFSTL_ASSERT_EQ(len, (ssize_t)0, "%zd");
+ USFSTL_ASSERT_EQ(dev->ext.server->max_queues, NUM_SNAPSHOT_QUEUES, "%d");
+ for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) {
+ if (dev->virtqs[virtq].enabled) {
+ dev->virtqs[virtq].enabled = false;
+ dev->virtqs[virtq].sleeping = true;
+ usfstl_loop_unregister(&dev->virtqs[virtq].entry);
+ }
+ }
+ break;
+ case VHOST_USER_WAKE:
+ USFSTL_ASSERT_EQ(len, (ssize_t)0, "%zd");
+ USFSTL_ASSERT_EQ(dev->ext.server->max_queues, NUM_SNAPSHOT_QUEUES, "%d");
+ // enable previously enabled queues on wake
+ for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) {
+ if (dev->virtqs[virtq].sleeping) {
+ dev->virtqs[virtq].enabled = true;
+ dev->virtqs[virtq].sleeping = false;
+ usfstl_loop_register(&dev->virtqs[virtq].entry);
+ // TODO: is this needed?
+ usfstl_vhost_user_virtq_kick(dev, virtq);
+ }
+ }
+ break;
+ case VHOST_USER_SNAPSHOT: {
+ USFSTL_ASSERT_EQ(len, (ssize_t)0, "%zd");
+ USFSTL_ASSERT_EQ(dev->ext.server->max_queues, NUM_SNAPSHOT_QUEUES, "%d");
+ for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) {
+ msg.payload.snapshot_response.snapshot.sleeping[virtq] = dev->virtqs[virtq].sleeping;
+ }
+ msg.payload.snapshot_response.bool_store = 1;
+ reply_len = (int)sizeof(msg.payload.snapshot_response);
+ break;
+ }
+ case VHOST_USER_RESTORE: {
+ int *fds;
+ USFSTL_ASSERT(len == (int)sizeof(msg.payload.restore_request));
+ USFSTL_ASSERT_EQ(dev->ext.server->max_queues, NUM_SNAPSHOT_QUEUES, "%d");
+
+ fds = (int*)malloc(dev->ext.server->max_queues * sizeof(int));
+ for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) {
+ fds[virtq] = -1;
+ }
+ usfstl_vhost_user_get_msg_fds(&msghdr, fds, 2);
+
+ for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) {
+ dev->virtqs[virtq].sleeping = msg.payload.restore_request.snapshot.sleeping[virtq];
+ dev->virtqs[virtq].entry.fd = fds[virtq];
+ }
+
+ free(fds);
+
+ msg.payload.i8 = 1; // success
+ reply_len = sizeof(msg.payload.i8);
+ break;
+ }
default:
USFSTL_ASSERT(0, "Unsupported message: %d\n", msg.hdr.request);
}