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 @@ -60,14 +60,29 @@ ucl_object_t *meta_root_obj; }; +/* Filename that will be used for save/restore */ +struct checkpoint_op { + char snapshot_filename[MAX_SNAPSHOT_FILENAME]; +}; + +/* Messages that a bhyve process understands. */ enum ipc_opcode { START_CHECKPOINT, START_SUSPEND, }; -struct checkpoint_op { - unsigned int op; - char snapshot_filename[MAX_SNAPSHOT_FILENAME]; +/* + * The type of message and associated data to + * send to a bhyve process. + */ +struct ipc_message { + enum ipc_opcode code; + union { + /* + * message specific structures + */ + struct checkpoint_op op; + } data; }; struct checkpoint_thread_info { 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 @@ -1441,16 +1441,16 @@ } int -handle_message(struct checkpoint_op *checkpoint_op, struct vmctx *ctx) +handle_message(struct ipc_message *imsg, struct vmctx *ctx) { int err; - switch (checkpoint_op->op) { + switch (imsg->code) { case START_CHECKPOINT: - err = vm_checkpoint(ctx, checkpoint_op->snapshot_filename, false); + err = vm_checkpoint(ctx, imsg->data.op.snapshot_filename, false); break; case START_SUSPEND: - err = vm_checkpoint(ctx, checkpoint_op->snapshot_filename, true); + err = vm_checkpoint(ctx, imsg->data.op.snapshot_filename, true); break; default: EPRINTLN("Unrecognized checkpoint operation\n"); @@ -1469,7 +1469,7 @@ void * checkpoint_thread(void *param) { - struct checkpoint_op op; + struct ipc_message imsg; struct checkpoint_thread_info *thread_info; ssize_t n; @@ -1477,14 +1477,14 @@ thread_info = (struct checkpoint_thread_info *)param; for (;;) { - n = recvfrom(thread_info->socket_fd, &op, sizeof(op), 0, NULL, 0); + n = recvfrom(thread_info->socket_fd, &imsg, sizeof(imsg), 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); + if (n >= sizeof(imsg.code)) + handle_message(&imsg, thread_info->ctx); else EPRINTLN("Failed to receive message: %s\n", n == -1 ? strerror(errno) : "unknown error"); diff --git a/usr.sbin/bhyvectl/bhyvectl.c b/usr.sbin/bhyvectl/bhyvectl.c --- a/usr.sbin/bhyvectl/bhyvectl.c +++ b/usr.sbin/bhyvectl/bhyvectl.c @@ -1684,7 +1684,7 @@ #ifdef BHYVE_SNAPSHOT static int -send_checkpoint_op_req(struct vmctx *ctx, struct checkpoint_op *op) +send_message(struct vmctx *ctx, void *data, size_t len) { struct sockaddr_un addr; ssize_t len_sent; @@ -1709,7 +1709,7 @@ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s%s", BHYVE_RUN_DIR, vmname_buf); - len_sent = sendto(socket_fd, op, sizeof(*op), 0, + len_sent = sendto(socket_fd, data, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)); if (len_sent < 0) { @@ -1726,12 +1726,15 @@ static int snapshot_request(struct vmctx *ctx, const char *file, enum ipc_opcode code) { - struct checkpoint_op op; + struct ipc_message imsg; + size_t length; - op.op = code; - strlcpy(op.snapshot_filename, file, MAX_SNAPSHOT_FILENAME); + imsg.code = code; + strlcpy(imsg.data.op.snapshot_filename, file, MAX_SNAPSHOT_FILENAME); - return (send_checkpoint_op_req(ctx, &op)); + length = offsetof(struct ipc_message, data) + sizeof(imsg.data.op); + + return (send_message(ctx, (void *)&imsg, length)); } #endif