Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102128166
D34721.id105514.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D34721.id105514.diff
View Options
diff --git a/usr.sbin/bhyve/migration.c b/usr.sbin/bhyve/migration.c
--- a/usr.sbin/bhyve/migration.c
+++ b/usr.sbin/bhyve/migration.c
@@ -633,6 +633,179 @@
return (error);
}
+
+static inline const struct vm_snapshot_dev_info *
+find_entry_for_dev(const char *name)
+{
+ int i;
+ int ndevs;
+ const struct vm_snapshot_dev_info *snapshot_devs;
+
+ snapshot_devs = get_snapshot_devs(&ndevs);
+
+ for (i = 0; i < ndevs; i++) {
+ if (strncmp(name, snapshot_devs[i].dev_name, MAX_DEV_NAME_LEN) == 0) {
+ return (&snapshot_devs[i]);
+ }
+ }
+
+ return NULL;
+}
+
+static inline int
+migrate_transfer_dev(struct vmctx *ctx, int socket, const char *dev,
+ char *buffer, size_t len, enum migration_transfer_req req)
+{
+ int rc;
+ size_t data_size;
+ struct migration_message_type msg;
+ struct vm_snapshot_meta *meta;
+ const struct vm_snapshot_dev_info *dev_info;
+
+ if ((req != MIGRATION_SEND_REQ) && (req != MIGRATION_RECV_REQ)) {
+ DPRINTF("Unknown transfer request option");
+ return (-1);
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ memset(buffer, 0, len);
+ if (req == MIGRATION_SEND_REQ) {
+ dev_info = find_entry_for_dev(dev);
+ if (dev_info == NULL) {
+ EPRINTF("Could not find the device %s "
+ "or migration not implemented yet for it.", dev);
+ return (0);
+ }
+
+ meta = ALLOCA_VM_SNAPSHOT_META(ctx, dev, 0, buffer, len, VM_SNAPSHOT_SAVE);
+
+ memset(meta->buffer.buf_start, 0, meta->buffer.buf_size);
+ meta->buffer.buf = meta->buffer.buf_start;
+ meta->buffer.buf_rem = meta->buffer.buf_size;
+
+ rc = (*dev_info->snapshot_cb)(meta);
+ if (rc < 0) {
+ DPRINTF("Could not get info about %s dev", dev);
+ return (-1);
+ }
+
+ data_size = vm_get_snapshot_size(meta);
+
+ msg.type = MESSAGE_TYPE_DEV;
+ msg.len = data_size;
+ strlcpy(msg.name, dev, MAX_DEV_NAME_LEN);
+ }
+
+ rc = migration_transfer_data(socket, &msg, sizeof(msg), req);
+ if (rc < 0) {
+ DPRINTF("Could not transfer msg for %s dev", dev);
+ return (-1);
+ }
+
+ if (req == MIGRATION_RECV_REQ) {
+ if (msg.type != MESSAGE_TYPE_DEV) {
+ DPRINTF("Wrong message type for device.");
+ return (-1);
+ }
+
+ data_size = msg.len;
+ }
+
+ if (data_size == 0)
+ return (0); // this type of device is not used
+
+
+ rc = migration_transfer_data(socket, buffer, data_size, req);
+ if (rc < 0) {
+ DPRINTF("Could not transfer %s dev", dev);
+ return (-1);
+ }
+
+ if (req == MIGRATION_RECV_REQ) {
+ dev_info = find_entry_for_dev(msg.name);
+ if (dev_info == NULL) {
+ EPRINTF("Could not find the device %s "
+ "or migration not implemented yet for it.", msg.name);
+ return (0);
+ }
+ meta = ALLOCA_VM_SNAPSHOT_META(ctx, msg.name, 0, buffer, data_size, VM_SNAPSHOT_RESTORE);
+ meta->buffer.buf = meta->buffer.buf_start;
+ meta->buffer.buf_rem = meta->buffer.buf_size;
+
+ rc = (*dev_info->snapshot_cb)(meta);
+ if (rc != 0) {
+ EPRINTF("Could not restore %s dev", msg.name);
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+static int
+migrate_devs(struct vmctx *ctx, int socket, enum migration_transfer_req req)
+{
+ int i, num_items;
+ int rc, error;
+ char *buffer;
+ const struct vm_snapshot_dev_info *snapshot_devs;
+
+ error = 0;
+ buffer = malloc(SNAPSHOT_BUFFER_SIZE);
+ if (buffer == NULL) {
+ EPRINTF("Could not allocate memory");
+ error = -1;
+ goto end;
+ }
+
+ if (req == MIGRATION_SEND_REQ) {
+ /*
+ * Send to the destination the number of devices that will
+ * be migrated.
+ */
+ snapshot_devs = get_snapshot_devs(&num_items);
+
+ rc = migration_transfer_data(socket, &num_items, sizeof(num_items), req);
+ if (rc < 0) {
+ DPRINTF("Could not send num_items to destination");
+ return (-1);
+ }
+
+ for (i = 0; i < num_items; i++) {
+ rc = migrate_transfer_dev(ctx, socket, snapshot_devs[i].dev_name,
+ buffer, SNAPSHOT_BUFFER_SIZE, req);
+
+ if (rc < 0) {
+ DPRINTF("Could not send %s", snapshot_devs[i].dev_name);
+ error = -1;
+ goto end;
+ }
+ }
+ } else if (req == MIGRATION_RECV_REQ) {
+ /* receive the number of devices that will be migrated */
+ rc = migration_transfer_data(socket, &num_items, sizeof(num_items), MIGRATION_RECV_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not recv num_items from source");
+ return (-1);
+ }
+
+ for (i = 0; i < num_items; i++) {
+ rc = migrate_transfer_dev(ctx, socket, NULL, buffer, SNAPSHOT_BUFFER_SIZE, req);
+ if (rc < 0) {
+ DPRINTF("Could not recv device");
+ error = -1;
+ goto end;
+ }
+ }
+ }
+
+end:
+ if (buffer != NULL)
+ free(buffer);
+
+ return (error);
+}
+
static inline int
migrate_connections(struct migrate_req req, int *socket_fd,
int *connection_socket_fd,
@@ -785,6 +958,13 @@
goto unlock_vm_and_exit;
}
+ rc = migrate_devs(ctx, s, MIGRATION_SEND_REQ);
+ if (rc < 0) {
+ EPRINTF("Could not send pci devs to destination");
+ error = rc;
+ goto unlock_vm_and_exit;
+ }
+
rc = migration_transfer_data(s, &migration_completed,
sizeof(migration_completed), MIGRATION_RECV_REQ);
if ((rc < 0) || (migration_completed != MIGRATION_SPECS_OK)) {
@@ -793,10 +973,6 @@
goto unlock_vm_and_exit;
}
- EPRINTF("Migration not yet implemented");
- error = -1;
- goto unlock_vm_and_exit;
-
vm_destroy(ctx);
exit(0);
@@ -848,6 +1024,14 @@
return (-1);
}
+ rc = migrate_devs(ctx, con_socket, MIGRATION_RECV_REQ);
+ if (rc < 0) {
+ EPRINTF("Could not recv pci devs");
+ close(con_socket);
+ close(s);
+ return (-1);
+ }
+
fprintf(stdout, "%s: Migration completed\r\n", __func__);
migration_completed = MIGRATION_SPECS_OK;
rc = migration_transfer_data(con_socket, &migration_completed,
@@ -861,7 +1045,5 @@
close(con_socket);
close(s);
-
- EPRINTF("Migration not currently implemented");
- return (-1);
+ return (0);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 8, 11:25 PM (10 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14545195
Default Alt Text
D34721.id105514.diff (5 KB)
Attached To
Mode
D34721: Warm Migration feature for bhyve [Part 5]
Attached
Detach File
Event Timeline
Log In to Comment