Page MenuHomeFreeBSD

D34721.diff
No OneTemporary

D34721.diff

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

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)

Event Timeline