Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F132023110
D34719.id104392.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
D34719.id104392.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
@@ -66,6 +66,8 @@
#include "pci_emul.h"
#include "snapshot.h"
+#define MB (1024UL * 1024)
+#define GB (1024UL * MB)
#ifdef BHYVE_DEBUG
#define DPRINTF(FMT, ...) \
({ \
@@ -336,6 +338,160 @@
return (0);
}
+
+static int
+migrate_check_memsize(size_t local_lowmem_size, size_t local_highmem_size,
+ size_t remote_lowmem_size, size_t remote_highmem_size)
+{
+ int ret;
+
+ ret = MIGRATION_SPECS_OK;
+
+ if (local_lowmem_size != remote_lowmem_size){
+ ret = MIGRATION_SPECS_NOT_OK;
+ DPRINTF("Local and remote lowmem size mismatch");
+ }
+
+ if (local_highmem_size != remote_highmem_size){
+ ret = MIGRATION_SPECS_NOT_OK;
+ DPRINTF("Local and remote highmem size mismatch");
+ }
+
+ return (ret);
+}
+
+static int
+migrate_recv_memory(struct vmctx *ctx, int socket)
+{
+ size_t local_lowmem_size, local_highmem_size;
+ size_t remote_lowmem_size, remote_highmem_size;
+ char *baseaddr;
+ int memsize_ok;
+ int rc;
+
+ local_lowmem_size = local_highmem_size = 0;
+ remote_lowmem_size = remote_highmem_size = 0;
+ rc = 0;
+
+ rc = vm_get_guestmem_from_ctx(ctx,
+ &baseaddr, &local_lowmem_size,
+ &local_highmem_size);
+ if (rc != 0) {
+ DPRINTF("Could not get guest lowmem size and highmem size");
+ return (rc);
+ }
+
+ rc = migration_transfer_data(socket, &remote_lowmem_size, sizeof(remote_lowmem_size), MIGRATION_RECV_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not recv lowmem size");
+ return (rc);
+ }
+
+ rc = migration_transfer_data(socket, &remote_highmem_size, sizeof(remote_highmem_size), MIGRATION_RECV_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not recv highmem size");
+ return (rc);
+ }
+
+ memsize_ok = migrate_check_memsize(local_lowmem_size, local_highmem_size,
+ remote_lowmem_size, remote_highmem_size);
+
+ rc = migration_transfer_data(socket,
+ &memsize_ok, sizeof(memsize_ok), MIGRATION_SEND_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not send migration_ok to remote");
+ return (rc);
+ }
+
+ if (memsize_ok != MIGRATION_SPECS_OK) {
+ DPRINTF("Memory size mismatch with remote host");
+ return (-1);
+ }
+
+ rc = migration_transfer_data(socket, baseaddr, local_lowmem_size, MIGRATION_RECV_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not recv chunk lowmem.");
+ return (-1);
+ }
+
+ if (local_highmem_size > 0){
+ rc = migration_transfer_data(socket, baseaddr + 4 * GB, local_highmem_size, MIGRATION_RECV_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not recv highmem");
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+static int
+migrate_send_memory(struct vmctx *ctx, int socket)
+{
+ size_t lowmem_size, highmem_size;
+ char *mmap_vm_lowmem, *mmap_vm_highmem;
+ char *baseaddr;
+ int memsize_ok;
+ int rc;
+
+ rc = 0;
+ mmap_vm_lowmem = MAP_FAILED;
+ mmap_vm_highmem = MAP_FAILED;
+
+ rc = vm_get_guestmem_from_ctx(ctx, &baseaddr,
+ &lowmem_size, &highmem_size);
+ if (rc != 0) {
+ DPRINTF("Could not get guest lowmem size and highmem size");
+ return (rc);
+ }
+
+ /* Send the size of the lowmem segment */
+ rc = migration_transfer_data(socket, &lowmem_size, sizeof(lowmem_size), MIGRATION_SEND_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not send lowmem size");
+ return (rc);
+ }
+
+ /* Send the size of the highmem segment */
+ rc = migration_transfer_data(socket, &highmem_size, sizeof(lowmem_size), MIGRATION_SEND_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not send highmem size");
+ return (rc);
+ }
+
+ /* Wait for answer - params ok (if memory size matches) */
+ rc = migration_transfer_data(socket, &memsize_ok, sizeof(memsize_ok), MIGRATION_RECV_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not receive response from remote");
+ return (rc);
+ }
+
+ if (memsize_ok != MIGRATION_SPECS_OK) {
+ DPRINTF("Memory size mismatch with remote host");
+ return (-1);
+ }
+
+ mmap_vm_lowmem = baseaddr;
+ mmap_vm_highmem = baseaddr + 4 * GB;
+
+ /* Send the lowmem segment */
+ rc = migration_transfer_data(socket, mmap_vm_lowmem, lowmem_size, MIGRATION_SEND_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not send lowmem");
+ return (-1);
+ }
+
+ /* Send the highmem segment */
+ if (highmem_size > 0){
+ rc = migration_transfer_data(socket, mmap_vm_highmem, highmem_size, MIGRATION_SEND_REQ);
+ if (rc < 0) {
+ DPRINTF("Could not send highmem");
+ return (-1);
+ }
+ }
+
+ return (0);
+}
static inline int
migrate_connections(struct migrate_req req, int *socket_fd,
int *connection_socket_fd,
@@ -474,6 +630,12 @@
goto unlock_vm_and_exit;
}
+ rc = migrate_send_memory(ctx, s);
+ if (rc != 0) {
+ EPRINTF("Could not send memory 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)) {
@@ -521,6 +683,13 @@
return (rc);
}
+ rc = migrate_recv_memory(ctx, con_socket);
+ if (rc < 0) {
+ EPRINTF("Could not recv :lowmem and highmem");
+ close(con_socket);
+ close(s);
+ return (-1);
+ }
fprintf(stdout, "%s: Migration completed\r\n", __func__);
migration_completed = MIGRATION_SPECS_OK;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 14, 1:02 AM (4 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23699739
Default Alt Text
D34719.id104392.diff (5 KB)
Attached To
Mode
D34719: Warm Migration feature for bhyve [Part 3]
Attached
Detach File
Event Timeline
Log In to Comment