Page MenuHomeFreeBSD

D54650.id169470.diff
No OneTemporary

D54650.id169470.diff

diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile
--- a/usr.sbin/bhyve/Makefile
+++ b/usr.sbin/bhyve/Makefile
@@ -31,6 +31,7 @@
ctl_util.c \
hda_codec.c \
iov.c \
+ ipc.c \
mem.c \
mevent.c \
net_backend_netmap.c \
diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c
--- a/usr.sbin/bhyve/bhyverun.c
+++ b/usr.sbin/bhyve/bhyverun.c
@@ -84,6 +84,7 @@
#ifdef BHYVE_GDB
#include "gdb.h"
#endif
+#include "ipc.h"
#include "mem.h"
#include "mevent.h"
#include "pci_emul.h"
@@ -1024,13 +1025,11 @@
*/
setproctitle("%s", vmname);
-#ifdef BHYVE_SNAPSHOT
/*
- * checkpointing thread for communication with bhyvectl
+ * Thread for handling bhyvectl commands.
*/
- if (init_checkpoint_thread(ctx) != 0)
+ if (init_ipc_thread(ctx) != 0)
errx(EX_OSERR, "Failed to start checkpoint thread");
-#endif
#ifndef WITHOUT_CAPSICUM
caph_cache_catpages();
diff --git a/usr.sbin/bhyve/ipc.h b/usr.sbin/bhyve/ipc.h
--- a/usr.sbin/bhyve/ipc.h
+++ b/usr.sbin/bhyve/ipc.h
@@ -33,18 +33,17 @@
#include <sys/linker_set.h>
#include <sys/nv.h>
+struct vmctx;
+
struct ipc_command {
const char *name;
- int (*handler)(struct vmctx *ctx, const nvlist_t *nvl);
+ int (*handler)(struct vmctx *ctx, nvlist_t *nvl);
};
-#define IPC_COMMAND(set, name, function) \
- static struct ipc_command name ## _ipc_command = \
- { #name, function }; \
- DATA_SET(set, name ## _ipc_command)
-
-#define IPC_COMMAND_FOREACH(pvar, set) SET_FOREACH(pvar, set)
+#define IPC_COMMAND(name, function) \
+ static struct ipc_command name##_ipc_command = { #name, function }; \
+ DATA_SET(ipc_cmd_set, name##_ipc_command)
-SET_DECLARE(ipc_cmd_set, struct ipc_command);
+int init_ipc_thread(struct vmctx *ctx);
#endif /* _IPC_H_ */
diff --git a/usr.sbin/bhyve/ipc.c b/usr.sbin/bhyve/ipc.c
new file mode 100644
--- /dev/null
+++ b/usr.sbin/bhyve/ipc.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2016 Flavius Anton
+ * Copyright (c) 2016 Mihai Tiganus
+ * Copyright (c) 2016-2019 Mihai Carabas
+ * Copyright (c) 2017-2019 Darius Mihai
+ * Copyright (c) 2017-2019 Elena Mihailescu
+ * Copyright (c) 2018-2019 Sergiu Weisz
+ * Copyright (c) 2025 Bojan Novković <bnovkov@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "ipc.h"
+
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
+#include <sys/types.h>
+#include <sys/linker_set.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#ifndef WITHOUT_CAPSICUM
+#include <capsicum_helpers.h>
+#endif
+#include <sys/cpuset.h>
+#include <sys/ioctl.h>
+
+#include <machine/vmm.h>
+#include <machine/vmm_snapshot.h>
+
+#include <assert.h>
+#include <bhyve/pci.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <vmmapi.h>
+
+#include "bhyverun.h"
+#include "debug.h"
+
+#define IPC_COMMAND_FOREACH(pvar, set) SET_FOREACH(pvar, set)
+
+SET_DECLARE(ipc_cmd_set, struct ipc_command);
+
+static struct ipc_thread_ctx {
+ struct vmctx *vmctx;
+ int sockfd;
+} thr_ctx;
+
+static int
+handle_message(struct vmctx *ctx, nvlist_t *nvl)
+{
+ const char *cmd;
+ struct ipc_command **ipc_cmd;
+
+ cmd = nvlist_get_string(nvl, "cmd");
+ IPC_COMMAND_FOREACH(ipc_cmd, ipc_cmd_set)
+ {
+ if (strcmp(cmd, (*ipc_cmd)->name) == 0)
+ return ((*ipc_cmd)->handler(ctx, nvl));
+ }
+
+ return (EOPNOTSUPP);
+}
+
+/*
+ * Listen for commands from bhyvectl.
+ */
+static void *
+ipc_thread(void *param)
+{
+ int fd;
+ nvlist_t *nvl;
+ const char *cmdname;
+ struct ipc_thread_ctx *ctx;
+
+ pthread_set_name_np(pthread_self(), "IPC thread");
+ ctx = (struct ipc_thread_ctx *)param;
+ while ((fd = accept(ctx->sockfd, NULL, NULL)) != -1) {
+ nvl = nvlist_recv(fd, 0);
+ if (nvl == NULL) {
+ EPRINTLN("%s: nvlist_recv() failed: %s", __func__,
+ strerror(errno));
+ close(fd);
+ continue;
+ }
+
+ cmdname = nvlist_get_string(nvl, "cmd");
+ if (cmdname == NULL) {
+ nvlist_add_string(nvl, "error", "missing command name");
+ nvlist_send(fd, nvl);
+ nvlist_destroy(nvl);
+ close(fd);
+ continue;
+ }
+ handle_message(ctx->vmctx, nvl);
+ /* The handler should set the error message if need be. */
+ nvlist_send(fd, nvl);
+
+ nvlist_destroy(nvl);
+ close(fd);
+ }
+
+ return (NULL);
+}
+
+/*
+ * Create the listening socket for IPC with bhyvectl.
+ */
+int
+init_ipc_thread(struct vmctx *ctx)
+{
+ struct sockaddr_un addr;
+ int socket_fd;
+ pthread_t ipc_pthread;
+ int err;
+#ifndef WITHOUT_CAPSICUM
+ cap_rights_t rights;
+#endif
+
+ memset(&addr, 0, sizeof(addr));
+ socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (socket_fd < 0) {
+ EPRINTLN("%s: Socket creation failed: %s", __func__,
+ strerror(errno));
+ err = -1;
+ goto fail;
+ }
+
+ addr.sun_family = AF_UNIX;
+
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s%s", BHYVE_RUN_DIR,
+ vm_get_name(ctx));
+ addr.sun_len = SUN_LEN(&addr);
+ unlink(addr.sun_path);
+
+ if (bind(socket_fd, (struct sockaddr *)&addr, addr.sun_len) != 0) {
+ EPRINTLN("Failed to bind socket \"%s\": %s\n", addr.sun_path,
+ strerror(errno));
+ err = -1;
+ goto fail;
+ }
+
+ if (listen(socket_fd, 10) < 0) {
+ EPRINTLN("ipc socket listen: %s\n", strerror(errno));
+ err = errno;
+ goto fail;
+ }
+
+#ifndef WITHOUT_CAPSICUM
+ cap_rights_init(&rights, CAP_ACCEPT, CAP_READ, CAP_RECV, CAP_WRITE,
+ CAP_SEND, CAP_GETSOCKOPT);
+
+ if (caph_rights_limit(socket_fd, &rights) == -1)
+ errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
+
+ memset(&thr_ctx, 0, sizeof(thr_ctx));
+ thr_ctx.vmctx = ctx;
+ thr_ctx.sockfd = socket_fd;
+
+ err = pthread_create(&ipc_pthread, NULL, ipc_thread, &thr_ctx);
+ if (err != 0)
+ goto fail;
+
+ return (0);
+fail:
+ if (socket_fd > 0)
+ close(socket_fd);
+ unlink(addr.sun_path);
+
+ return (err);
+}
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
@@ -40,7 +40,6 @@
#include <libxo/xo.h>
#include <ucl.h>
-#define BHYVE_RUN_DIR "/var/run/bhyve/"
#define MAX_SNAPSHOT_FILENAME PATH_MAX
struct vmctx;
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
@@ -1331,51 +1331,6 @@
return (error);
}
-static int
-handle_message(struct vmctx *ctx, nvlist_t *nvl)
-{
- const char *cmd;
- struct ipc_command **ipc_cmd;
-
- if (!nvlist_exists_string(nvl, "cmd"))
- return (EINVAL);
-
- cmd = nvlist_get_string(nvl, "cmd");
- IPC_COMMAND_FOREACH(ipc_cmd, ipc_cmd_set) {
- if (strcmp(cmd, (*ipc_cmd)->name) == 0)
- return ((*ipc_cmd)->handler(ctx, nvl));
- }
-
- return (EOPNOTSUPP);
-}
-
-/*
- * Listen for commands from bhyvectl
- */
-void *
-checkpoint_thread(void *param)
-{
- int fd;
- struct checkpoint_thread_info *thread_info;
- nvlist_t *nvl;
-
- pthread_set_name_np(pthread_self(), "checkpoint thread");
- thread_info = (struct checkpoint_thread_info *)param;
-
- while ((fd = accept(thread_info->socket_fd, NULL, NULL)) != -1) {
- nvl = nvlist_recv(fd, 0);
- if (nvl != NULL)
- handle_message(thread_info->ctx, nvl);
- else
- EPRINTLN("nvlist_recv() failed: %s", strerror(errno));
-
- close(fd);
- nvlist_destroy(nvl);
- }
-
- return (NULL);
-}
-
static int
vm_do_checkpoint(struct vmctx *ctx, const nvlist_t *nvl)
{
@@ -1393,77 +1348,7 @@
return (error);
}
-IPC_COMMAND(ipc_cmd_set, checkpoint, vm_do_checkpoint);
-
-/*
- * Create the listening socket for IPC with bhyvectl
- */
-int
-init_checkpoint_thread(struct vmctx *ctx)
-{
- struct checkpoint_thread_info *checkpoint_info = NULL;
- struct sockaddr_un addr;
- int socket_fd;
- pthread_t checkpoint_pthread;
- int err;
-#ifndef WITHOUT_CAPSICUM
- cap_rights_t rights;
-#endif
-
- memset(&addr, 0, sizeof(addr));
-
- socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (socket_fd < 0) {
- EPRINTLN("Socket creation failed: %s", strerror(errno));
- err = -1;
- goto fail;
- }
-
- addr.sun_family = AF_UNIX;
-
- snprintf(addr.sun_path, sizeof(addr.sun_path), "%s%s",
- BHYVE_RUN_DIR, vm_get_name(ctx));
- addr.sun_len = SUN_LEN(&addr);
- unlink(addr.sun_path);
-
- if (bind(socket_fd, (struct sockaddr *)&addr, addr.sun_len) != 0) {
- EPRINTLN("Failed to bind socket \"%s\": %s\n",
- addr.sun_path, strerror(errno));
- err = -1;
- goto fail;
- }
-
- if (listen(socket_fd, 10) < 0) {
- EPRINTLN("ipc socket listen: %s\n", strerror(errno));
- err = errno;
- goto fail;
- }
-
-#ifndef WITHOUT_CAPSICUM
- cap_rights_init(&rights, CAP_ACCEPT, CAP_READ, CAP_RECV, CAP_WRITE,
- CAP_SEND, CAP_GETSOCKOPT);
-
- if (caph_rights_limit(socket_fd, &rights) == -1)
- errx(EX_OSERR, "Unable to apply rights for sandbox");
-#endif
- checkpoint_info = calloc(1, sizeof(*checkpoint_info));
- checkpoint_info->ctx = ctx;
- checkpoint_info->socket_fd = socket_fd;
-
- err = pthread_create(&checkpoint_pthread, NULL, checkpoint_thread,
- checkpoint_info);
- if (err != 0)
- goto fail;
-
- return (0);
-fail:
- free(checkpoint_info);
- if (socket_fd > 0)
- close(socket_fd);
- unlink(addr.sun_path);
-
- return (err);
-}
+IPC_COMMAND(checkpoint, vm_do_checkpoint);
void
vm_snapshot_buf_err(const char *bufname, const enum vm_snapshot_op op)

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 26, 11:18 AM (19 m, 40 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28024958
Default Alt Text
D54650.id169470.diff (9 KB)

Event Timeline