Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F96274014
D34721.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D34721.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
@@ -588,6 +588,160 @@
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(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)) {
+ EPRINTF("Unknown transfer request option");
+ return (EINVAL);
+ }
+
+ 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(dev, 0, buffer, len, VM_SNAPSHOT_SAVE);
+
+ rc = (*dev_info->snapshot_cb)(meta);
+ if (rc != 0) {
+ EPRINTF("Could not get info about %s dev", dev);
+ return (rc);
+ }
+
+ 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) {
+ EPRINTF("Could not transfer msg for %s dev", dev);
+ return (rc);
+ }
+
+ if (req == MIGRATION_RECV_REQ) {
+ if (msg.type != MESSAGE_TYPE_DEV) {
+ EPRINTF("Wrong message type for device.");
+ return (EINVAL);
+ }
+
+ data_size = msg.len;
+ }
+
+ /* This type of device is not used */
+ if (data_size == 0)
+ return (0);
+
+
+ rc = migration_transfer_data(socket, buffer, data_size, req);
+ if (rc != 0) {
+ EPRINTF("Could not transfer %s dev", dev);
+ return (rc);
+ }
+
+ 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(msg.name, 0, buffer, data_size, VM_SNAPSHOT_RESTORE);
+
+ rc = (*dev_info->snapshot_cb)(meta);
+ if (rc != 0) {
+ EPRINTF("Could not restore %s dev", msg.name);
+ return (rc);
+ }
+ }
+
+ return (0);
+}
+
+static int
+migrate_devs(int socket, enum migration_transfer_req req)
+{
+ int i, num_items;
+ int error;
+ char *buffer;
+ const char *dev_name = NULL;
+ const struct vm_snapshot_dev_info *snapshot_devs;
+
+ error = 0;
+ buffer = malloc(SNAPSHOT_BUFFER_SIZE);
+ if (buffer == NULL) {
+ EPRINTF("Could not allocate memory");
+ error = ENOMEM;
+ goto end;
+ }
+
+ /*
+ * Send to the destination the number of devices that will
+ * be migrated.
+ */
+ if (req == MIGRATION_SEND_REQ)
+ snapshot_devs = get_snapshot_devs(&num_items);
+
+ error = migration_transfer_data(socket, &num_items, sizeof(num_items), req);
+ if (error != 0) {
+ EPRINTF("Could not transfer number of devices");
+ goto end;
+ }
+
+ for (i = 0; i < num_items; i++) {
+ if (req == MIGRATION_SEND_REQ)
+ dev_name = snapshot_devs[i].dev_name;
+
+ error = migrate_transfer_dev(socket, dev_name,
+ buffer, SNAPSHOT_BUFFER_SIZE, req);
+
+ if (error != 0) {
+ DPRINTF("Could not transfer dev %s", snapshot_devs[i].dev_name);
+ goto end;
+ }
+ }
+
+end:
+ if (buffer != NULL)
+ free(buffer);
+
+ return (error);
+}
+
static inline int
migrate_connections(struct migrate_req req, int *socket_fd,
enum migration_transfer_req type)
@@ -751,6 +905,13 @@
goto unlock_vm_and_exit;
}
+ rc = migrate_devs(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)) {
@@ -759,10 +920,6 @@
goto unlock_vm_and_exit;
}
- EPRINTF("Rest of migration not yet implemented");
- error = EOPNOTSUPP;
- goto unlock_vm_and_exit;
-
vm_destroy(ctx);
exit(0);
@@ -828,7 +985,13 @@
goto done;
}
- // fprintf(stdout, "%s: Migration completed\n", __func__);
+ rc = migrate_devs(s, MIGRATION_RECV_REQ);
+ if (rc != 0) {
+ EPRINTF("Could not recv pci devs");
+ goto done;
+ }
+
+ fprintf(stdout, "%s: Migration completed\n", __func__);
migration_completed = MIGRATION_SPECS_OK;
rc = migration_transfer_data(s, &migration_completed,
@@ -840,8 +1003,6 @@
done:
close(s);
- EPRINTF("Rest of migration not currently implemented");
- rc = EOPNOTSUPP;
return (rc);
}
diff --git a/usr.sbin/bhyve/snapshot.h b/usr.sbin/bhyve/snapshot.h
--- a/usr.sbin/bhyve/snapshot.h
+++ b/usr.sbin/bhyve/snapshot.h
@@ -83,6 +83,7 @@
enum snapshot_req req; /* request type */
};
+const struct vm_snapshot_dev_info *get_snapshot_devs(int *ndevs);
const struct vm_snapshot_kern_info *get_snapshot_kern_structs(int *ndevs);
void destroy_restore_state(struct restore_state *rstate);
diff --git a/usr.sbin/bhyve/snapshot.c b/usr.sbin/bhyve/snapshot.c
--- a/usr.sbin/bhyve/snapshot.c
+++ b/usr.sbin/bhyve/snapshot.c
@@ -163,6 +163,15 @@
{ "vrtc", STRUCT_VRTC },
};
+const struct vm_snapshot_dev_info *
+get_snapshot_devs(int *ndevs)
+{
+ if (ndevs != NULL)
+ *ndevs = nitems(snapshot_devs);
+
+ return (snapshot_devs);
+}
+
const struct vm_snapshot_kern_info *
get_snapshot_kern_structs(int *ndevs)
{
diff --git a/usr.sbin/bhyve/virtio.c b/usr.sbin/bhyve/virtio.c
--- a/usr.sbin/bhyve/virtio.c
+++ b/usr.sbin/bhyve/virtio.c
@@ -869,7 +869,6 @@
SNAPSHOT_VAR_CMP_OR_LEAVE(vc->vc_nvq, meta, ret, done);
SNAPSHOT_VAR_CMP_OR_LEAVE(vc->vc_cfgsize, meta, ret, done);
- SNAPSHOT_VAR_CMP_OR_LEAVE(vc->vc_hv_caps, meta, ret, done);
done:
return (ret);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Sep 25, 7:39 AM (2 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12704099
Default Alt Text
D34721.diff (6 KB)
Attached To
Mode
D34721: Warm Migration feature for bhyve [Part 5]
Attached
Detach File
Event Timeline
Log In to Comment