Page MenuHomeFreeBSD

D34587.diff
No OneTemporary

D34587.diff

Index: Makefile.inc1
===================================================================
--- Makefile.inc1
+++ Makefile.inc1
@@ -2779,7 +2779,7 @@
-DNO_CPU_CFLAGS \
-DNO_PIC \
SSP_CFLAGS= \
- MK_CASPER=yes \
+ MK_CASPER=no \
MK_CLANG_EXTRAS=no \
MK_CLANG_FORMAT=no \
MK_CLANG_FULL=no \
Index: usr.sbin/bhyve/bhyverun.c
===================================================================
--- usr.sbin/bhyve/bhyverun.c
+++ usr.sbin/bhyve/bhyverun.c
@@ -1229,44 +1229,6 @@
set_config_bool("x86.strictmsr", true);
}
-#ifndef WITHOUT_CAPSICUM
-char *get_ckp_path(char *str)
-{
- char *strcopy;
- char *aux1, *aux2, *aux3, *aux4, *aux5;
- char *path = NULL;
- const char delim[2] = ",";
-
- strcopy = strdup(str);
- assert(strcopy != NULL);
-
-
- aux1 = strtok(strcopy, delim);
- aux2 = strtok(NULL, delim);
- aux3 = strtok(NULL, delim);
- if (aux3 != NULL) {
- if (strcmp(aux3, "virtio-blk") ||
- strcmp(aux3, "ahci-hd") ||
- strcmp(aux3, "ahci")) {
-
- aux4 = realpath(aux3, NULL);
- if (aux4 != NULL) {
- aux5 = strrchr(aux4, '/');
- if (aux5 != NULL) {
- *aux5 = '\0';
- path = strdup(aux4);
- }
- free(aux4);
- }
- }
- }
-
- free(strcopy);
-
- return path;
-}
-#endif
-
int
main(int argc, char *argv[])
{
@@ -1284,7 +1246,6 @@
restore_file = NULL;
#endif
- cap_channel_t *capcas = NULL;
char *ckp_path = NULL;
init_config();
@@ -1292,7 +1253,7 @@
progname = basename(argv[0]);
#ifdef BHYVE_SNAPSHOT
- optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:K:U:r:";
+ optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:K:U:r:t:";
#else
optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:K:U:";
#endif
@@ -1344,6 +1305,9 @@
case 'r':
restore_file = optarg;
break;
+ case 't':
+ ckp_path = optarg;
+ break;
#endif
case 's':
if (strncmp(optarg, "help", strlen(optarg)) == 0) {
@@ -1351,13 +1315,8 @@
exit(0);
} else if (pci_parse_slot(optarg) != 0)
exit(4);
- else {
-#ifndef WITHOUT_CAPSISCUM
- if (ckp_path == NULL)
- ckp_path = get_ckp_path(optarg);
-#endif
+ else
break;
- }
case 'S':
set_config_bool("memory.wired", true);
break;
@@ -1594,13 +1553,6 @@
*/
setproctitle("%s", vmname);
-#ifndef WITHOUT_CAPSICUM
- /* Open capability to Casper. */
- capcas = cap_init();
- if (capcas == NULL)
- errx(EX_OSERR, "cap_init() failed");
-#endif
-
#ifdef BHYVE_SNAPSHOT
if (restore_file != NULL)
destroy_restore_state(&rstate);
@@ -1608,10 +1560,13 @@
/* initialize mutex/cond variables */
init_snapshot();
+ /* initialize snapshot files parent directory and casper channel */
+ init_capsicum_info(ckp_path);
+
/*
* checkpointing thread for communication with bhyvectl
*/
- if (init_checkpoint_thread(ctx, ckp_path, capcas) < 0)
+ if (init_checkpoint_thread(ctx) < 0)
printf("Failed to start checkpoint thread!\r\n");
if (restore_file != NULL)
@@ -1619,7 +1574,6 @@
#endif
#ifndef WITHOUT_CAPSICUM
- free(ckp_path);
caph_cache_catpages();
if (caph_limit_stdout() == -1 || caph_limit_stderr() == -1)
Index: usr.sbin/bhyve/snapshot.h
===================================================================
--- usr.sbin/bhyve/snapshot.h
+++ usr.sbin/bhyve/snapshot.h
@@ -68,7 +68,6 @@
struct checkpoint_thread_info {
struct vmctx *ctx;
int socket_fd;
- cap_channel_t *channel;
};
typedef int (*vm_snapshot_dev_cb)(struct vm_snapshot_meta *);
@@ -108,7 +107,8 @@
int get_checkpoint_msg(int conn_fd, struct vmctx *ctx);
void *checkpoint_thread(void *param);
void init_snapshot(void);
-int init_checkpoint_thread(struct vmctx *ctx, char *ckp_path, cap_channel_t *chn);
+int init_checkpoint_thread(struct vmctx *ctx);
+void init_capsicum_info(char *ckp_path);
int load_restore_file(const char *filename, struct restore_state *rstate);
Index: usr.sbin/bhyve/snapshot.c
===================================================================
--- usr.sbin/bhyve/snapshot.c
+++ usr.sbin/bhyve/snapshot.c
@@ -172,6 +172,8 @@
static bool checkpoint_active;
static int cdir_fd = AT_FDCWD;
+static cap_channel_t *casper_channel = NULL;
+
/*
* TODO: Harden this function and all of its callers since 'base_str' is a user
* provided string.
@@ -1088,8 +1090,8 @@
ret = vm_snapshot_req(meta);
if (ret != 0) {
- fprintf(stderr, "%s: Failed to snapshot struct %s\r\n",
- __func__, meta->dev_name);
+ fprintf(stderr, "%s: Failed to snapshot struct %s(%d - %s)\r\n",
+ __func__, meta->dev_name, errno, strerror(errno));
ret = -1;
goto done;
}
@@ -1381,39 +1383,39 @@
}
#ifndef WITHOUT_CAPSICUM
-#define DESTROY(vm, ch, err, LABEL) \
-do { \
- cap_channel_t *capsysctl = NULL; \
- char *name = "hw.vmm.destroy"; \
- void *limit; \
- \
- /* Create capability to the system.sysctl service with Casper. */ \
- capsysctl = cap_service_open(ch, "system.sysctl"); \
- if (capsysctl == NULL) \
+#define DESTROY(vm, ch, err, LABEL) \
+do { \
+ cap_channel_t *capsysctl = NULL; \
+ char *name = "hw.vmm.destroy"; \
+ void *limit; \
+ \
+ /* Create capability to the system.sysctl service with Casper. */ \
+ capsysctl = cap_service_open(ch, "system.sysctl"); \
+ if (capsysctl == NULL) \
fprintf(stderr, "%s: Unable to open system.sysctl service", __func__); \
- \
- cap_close(ch); \
- \
- /* Create limit for one MIB with write access only. */ \
- limit = cap_sysctl_limit_init(capsysctl); \
- (void)cap_sysctl_limit_name(limit, name, CAP_SYSCTL_WRITE); \
- \
- /* Limit system.sysctl. */ \
- if (cap_sysctl_limit(limit) < 0) \
- fprintf(stderr, "%s: Unable to set limits", __func__); \
- \
+ \
+ cap_close(ch); \
+ \
+ /* Create limit for one MIB with write access only. */ \
+ limit = cap_sysctl_limit_init(capsysctl); \
+ (void)cap_sysctl_limit_name(limit, name, CAP_SYSCTL_WRITE); \
+ \
+ /* Limit system.sysctl. */ \
+ if (cap_sysctl_limit(limit) < 0) \
+ fprintf(stderr, "%s: Unable to set limits", __func__); \
+ \
err = cap_sysctlbyname(capsysctl, name, NULL, NULL, (vm), strlen((vm))); \
- \
- cap_close(capsysctl); \
- if (err != 0) { \
- fprintf(stderr, "%s: err is %d\r\n", __func__, errno); \
- goto LABEL; \
- } \
+ \
+ cap_close(capsysctl); \
+ if (err != 0) { \
+ fprintf(stderr, "%s: err is %d\r\n", __func__, errno); \
+ goto LABEL; \
+ } \
} while(0)
#endif
static int
-vm_checkpoint(struct vmctx *ctx, char *checkpoint_file, cap_channel_t *chn, bool stop_vm)
+vm_checkpoint(struct vmctx *ctx, const char *checkpoint_file, bool stop_vm)
{
int fd_checkpoint = 0, kdata_fd = 0, meta_fd = 0;
int ret = 0;
@@ -1476,10 +1478,6 @@
fprintf(stderr, "Could not pause devices\r\n");
error = ret;
goto done;
-#ifndef WITHOUT_CAPSICUM
- if (cdir_fd > 0)
- close(cdir_fd);
-#endif
}
memsz = vm_snapshot_mem(ctx, fd_checkpoint, 0, true);
@@ -1514,13 +1512,13 @@
if (stop_vm) {
- if (chn != NULL) {
+ if (casper_channel != NULL) {
error = vm_get_name(ctx, vmname, MAX_VMNAME - 1);
if (error != 0) {
fprintf(stderr, "%s: Failed to get VM name", __func__);
goto done;
}
- DESTROY(vmname, chn, error, done);
+ DESTROY(vmname, casper_channel, error, done);
free(ctx);
} else
vm_destroy(ctx);
@@ -1553,7 +1551,7 @@
}
int
-handle_message(struct vmctx *ctx, nvlist_t *nvl, cap_channel_t *chn)
+handle_message(struct vmctx *ctx, nvlist_t *nvl)
{
int err;
const char *cmd;
@@ -1565,10 +1563,10 @@
if (strcmp(cmd, "checkpoint") == 0) {
if (!nvlist_exists_string(nvl, "filename") ||
!nvlist_exists_bool(nvl, "suspend"))
- err = -1;
+ err = -1;
else
- err = vm_checkpoint(ctx, nvlist_get_string(nvl, "filename"),
- chn, nvlist_get_bool(nvl, "suspend"));
+ err = vm_checkpoint(ctx, nvlist_get_string(nvl, "filename"),
+ nvlist_get_bool(nvl, "suspend"));
} else {
EPRINTLN("Unrecognized checkpoint operation\n");
err = -1;
@@ -1594,14 +1592,14 @@
thread_info = (struct checkpoint_thread_info *)param;
for (;;) {
- n = recvfrom(thread_info->socket_fd, &imsg, sizeof(imsg), 0, NULL, 0);
+ nvl = nvlist_recv(thread_info->socket_fd, 0);
/*
* slight sanity check: see if there's enough data to at
* least determine the type of message.
*/
- if (n >= sizeof(imsg.code))
- handle_message(&imsg, thread_info->ctx, thread_info->channel);
+ if (nvl != NULL)
+ handle_message(thread_info->ctx, nvl);
else
EPRINTLN("nvlist_recv() failed: %s", strerror(errno));
}
@@ -1631,7 +1629,7 @@
{
cap_rights_t rights;
- cap_rights_init(&rights, CAP_BIND, CAP_READ);
+ cap_rights_init(&rights, CAP_BIND, CAP_READ, CAP_GETSOCKOPT);
if (caph_rights_limit(s, &rights) == -1)
errx(EX_OSERR, "Unable to apply rights for sandbox");
}
@@ -1648,18 +1646,34 @@
#endif
+void
+init_capsicum_info(char *ckp_path)
+{
+ /* Open capability to Casper. */
+ casper_channel = cap_init();
+ if (casper_channel == NULL)
+ errx(EX_OSERR, "cap_init() failed");
+
+ if (ckp_path != NULL) {
+ cdir_fd = open(ckp_path, O_RDONLY | O_DIRECTORY);
+ if (cdir_fd < 0)
+ errc(1, cdir_fd, "open snapshot files directory");
+ limit_file_operations();
+ }
+}
+
/*
* Create the listening socket for IPC with bhyvectl
*/
int
-init_checkpoint_thread(struct vmctx *ctx, char *ckp_path, cap_channel_t *chn)
+init_checkpoint_thread(struct vmctx *ctx)
{
struct checkpoint_thread_info *checkpoint_info = NULL;
struct sockaddr_un addr;
int socket_fd;
pthread_t checkpoint_pthread;
char vmname_buf[MAX_VMNAME];
- int ret, err = 0;
+ int err = 0;
memset(&addr, 0, sizeof(addr));
@@ -1670,16 +1684,7 @@
goto fail;
}
- if (ckp_path != NULL) {
- cdir_fd = open(ckp_path, O_RDONLY | O_DIRECTORY);
- if (cdir_fd < 0) {
- perror("Failed to open working directory.");
- err = -1;
- goto fail;
- }
- limit_control_socket(socket_fd);
- limit_file_operations();
- }
+ limit_control_socket(socket_fd);
addr.sun_family = AF_UNIX;
@@ -1704,7 +1709,6 @@
checkpoint_info = calloc(1, sizeof(*checkpoint_info));
checkpoint_info->ctx = ctx;
checkpoint_info->socket_fd = socket_fd;
- checkpoint_info->channel = chn;
err = pthread_create(&checkpoint_pthread, NULL, checkpoint_thread,
checkpoint_info);

File Metadata

Mime Type
text/plain
Expires
Wed, Aug 26, 8:03 AM (7 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37277648
Default Alt Text
D34587.diff (10 KB)

Event Timeline