Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143042755
D54650.id169470.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D54650.id169470.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D54650: bhyve: Generalize the IPC thread
Attached
Detach File
Event Timeline
Log In to Comment