aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/bhyve
diff options
context:
space:
mode:
authorRobert Wing <rew@FreeBSD.org>2021-03-08 00:23:29 +0000
committerRobert Wing <rew@FreeBSD.org>2021-03-08 00:23:29 +0000
commit38dfb0626fd35c64b2e2d5faae2c90e7981a3307 (patch)
tree6ad0a6eb51932390b2c13dcd74b3fd52191e40ff /usr.sbin/bhyve
parent0424d9ebeb17d669f680c696f0d741b714461b4c (diff)
downloadsrc-38dfb0626fd35c64b2e2d5faae2c90e7981a3307.tar.gz
src-38dfb0626fd35c64b2e2d5faae2c90e7981a3307.zip
bhyve/snapshot: use SOCK_DGRAM instead of SOCK_STREAM
The save/restore feature uses a unix domain socket to send messages from bhyvectl(8) to a bhyve(8) process. A datagram socket will suffice for this. An added benefit of using a datagram socket is simplified code. For bhyve, the listen/accept calls are dropped; and for bhyvectl, the connect() call is dropped. EPRINTLN handles raw mode for bhyve(8), use it to print error messages. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D28983
Diffstat (limited to 'usr.sbin/bhyve')
-rw-r--r--usr.sbin/bhyve/snapshot.c65
1 files changed, 25 insertions, 40 deletions
diff --git a/usr.sbin/bhyve/snapshot.c b/usr.sbin/bhyve/snapshot.c
index 11ff963ae1fd..221558b6f205 100644
--- a/usr.sbin/bhyve/snapshot.c
+++ b/usr.sbin/bhyve/snapshot.c
@@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$");
#include "bhyverun.h"
#include "acpi.h"
#include "atkbdc.h"
+#include "debug.h"
#include "inout.h"
#include "fwctl.h"
#include "ioapic.h"
@@ -117,8 +118,6 @@ static sig_t old_winch_handler;
#define MAX_VMNAME 100
-#define MAX_MSG_SIZE 1024
-
#define SNAPSHOT_BUFFER_SIZE (20 * MB)
#define JSON_STRUCT_ARR_KEY "structs"
@@ -1442,24 +1441,10 @@ done:
}
int
-get_checkpoint_msg(int conn_fd, struct vmctx *ctx)
+handle_message(struct checkpoint_op *checkpoint_op, struct vmctx *ctx)
{
- unsigned char buf[MAX_MSG_SIZE];
- struct checkpoint_op *checkpoint_op;
- int len, recv_len, total_recv = 0;
- int err = 0;
-
- len = sizeof(struct checkpoint_op); /* expected length */
- while ((recv_len = recv(conn_fd, buf + total_recv, len - total_recv, 0)) > 0) {
- total_recv += recv_len;
- }
- if (recv_len < 0) {
- perror("Error while receiving data from bhyvectl");
- err = -1;
- goto done;
- }
+ int err;
- checkpoint_op = (struct checkpoint_op *)buf;
switch (checkpoint_op->op) {
case START_CHECKPOINT:
err = vm_checkpoint(ctx, checkpoint_op->snapshot_filename, false);
@@ -1468,12 +1453,13 @@ get_checkpoint_msg(int conn_fd, struct vmctx *ctx)
err = vm_checkpoint(ctx, checkpoint_op->snapshot_filename, true);
break;
default:
- fprintf(stderr, "Unrecognized checkpoint operation.\n");
+ EPRINTLN("Unrecognized checkpoint operation\n");
err = -1;
}
-done:
- close(conn_fd);
+ if (err != 0)
+ EPRINTLN("Unable to perform the requested operation\n");
+
return (err);
}
@@ -1483,21 +1469,25 @@ done:
void *
checkpoint_thread(void *param)
{
+ struct checkpoint_op op;
struct checkpoint_thread_info *thread_info;
- int conn_fd, ret;
+ ssize_t n;
pthread_set_name_np(pthread_self(), "checkpoint thread");
thread_info = (struct checkpoint_thread_info *)param;
- while ((conn_fd = accept(thread_info->socket_fd, NULL, NULL)) > -1) {
- ret = get_checkpoint_msg(conn_fd, thread_info->ctx);
- if (ret != 0) {
- fprintf(stderr, "Failed to read message on checkpoint "
- "socket. Retrying.\n");
- }
- }
- if (conn_fd < -1) {
- perror("Failed to accept connection");
+ for (;;) {
+ n = recvfrom(thread_info->socket_fd, &op, sizeof(op), 0, NULL, 0);
+
+ /*
+ * slight sanity check: see if there's enough data to at
+ * least determine the type of message.
+ */
+ if (n >= sizeof(op.op))
+ handle_message(&op, thread_info->ctx);
+ else
+ EPRINTLN("Failed to receive message: %s\n",
+ n == -1 ? strerror(errno) : "unknown error");
}
return (NULL);
@@ -1527,9 +1517,9 @@ init_checkpoint_thread(struct vmctx *ctx)
if (err != 0)
errc(1, err, "checkpoint cv init");
- socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ socket_fd = socket(PF_UNIX, SOCK_DGRAM, 0);
if (socket_fd < 0) {
- perror("Socket creation failed (IPC with bhyvectl");
+ EPRINTLN("Socket creation failed: %s", strerror(errno));
err = -1;
goto fail;
}
@@ -1548,13 +1538,8 @@ init_checkpoint_thread(struct vmctx *ctx)
unlink(addr.sun_path);
if (bind(socket_fd, (struct sockaddr *)&addr, addr.sun_len) != 0) {
- perror("Failed to bind socket (IPC with bhyvectl)");
- err = -1;
- goto fail;
- }
-
- if (listen(socket_fd, 10) < 0) {
- perror("Failed to listen on socket (IPC with bhyvectl)");
+ EPRINTLN("Failed to bind socket \"%s\": %s\n",
+ addr.sun_path, strerror(errno));
err = -1;
goto fail;
}