Page MenuHomeFreeBSD

D34547.id104460.diff
No OneTemporary

D34547.id104460.diff

Index: usr.sbin/bhyve/bhyverun.c
===================================================================
--- usr.sbin/bhyve/bhyverun.c
+++ usr.sbin/bhyve/bhyverun.c
@@ -1247,15 +1247,13 @@
restore_file = NULL;
#endif
- cap_channel_t *capcas;
-
-
+ char *ckp_path = NULL;
init_config();
set_defaults();
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
@@ -1307,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) {
@@ -1552,11 +1553,6 @@
*/
setproctitle("%s", vmname);
- /* Open capability to Casper. */
- capcas = cap_init();
- if (capcas == NULL)
- errx(EX_OSERR, "cap_init() failed");
-
#ifdef BHYVE_SNAPSHOT
if (restore_file != NULL)
destroy_restore_state(&rstate);
@@ -1564,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, capcas) < 0)
+ if (init_checkpoint_thread(ctx) < 0)
printf("Failed to start checkpoint thread!\r\n");
if (restore_file != NULL)
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, 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
@@ -171,7 +171,9 @@
static pthread_cond_t vcpus_idle, vcpus_can_run;
static bool checkpoint_active;
-static int cdir_fd = -1;
+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.
@@ -1362,39 +1364,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;
@@ -1456,8 +1458,7 @@
fprintf(stderr, "Could not pause devices\r\n");
error = ret;
goto done;
- if (cdir_fd > 0)
- close(cdir_fd);}
+ }
memsz = vm_snapshot_mem(ctx, fd_checkpoint, 0, true);
if (memsz == 0) {
@@ -1491,13 +1492,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);
@@ -1528,7 +1529,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;
@@ -1542,8 +1543,8 @@
!nvlist_exists_bool(nvl, "suspend"))
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;
@@ -1575,8 +1576,8 @@
* 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));
}
@@ -1623,11 +1624,27 @@
#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, cap_channel_t *chn)
+init_checkpoint_thread(struct vmctx *ctx)
{
struct checkpoint_thread_info *checkpoint_info = NULL;
struct sockaddr_un addr;
@@ -1646,18 +1663,7 @@
goto fail;
}
- cdir_name = getcwd(NULL, 0);
- cdir_fd = open(cdir_name, O_RDONLY | O_DIRECTORY);
- if (cdir_fd < 0) {
- perror("Failed to open working directory.");
- err = -1;
- goto fail;
- }
- free(cdir_name);
-#ifndef WITHOUT_CAPSICUM
limit_control_socket(socket_fd);
- limit_file_operations();
-#endif
addr.sun_family = AF_UNIX;
err = vm_get_name(ctx, vmname_buf, MAX_VMNAME - 1);
@@ -1682,7 +1688,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
Fri, Feb 27, 7:24 PM (17 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29039863
Default Alt Text
D34547.id104460.diff (7 KB)

Event Timeline