1/*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2016 Flavius Anton 5 * Copyright (c) 2016 Mihai Tiganus 6 * Copyright (c) 2016-2019 Mihai Carabas 7 * Copyright (c) 2017-2019 Darius Mihai 8 * Copyright (c) 2017-2019 Elena Mihailescu 9 * Copyright (c) 2018-2019 Sergiu Weisz 10 * All rights reserved. 11 * The bhyve-snapshot feature was developed under sponsorships 12 * from Matthew Grooms. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#ifndef _BHYVE_SNAPSHOT_ 37#define _BHYVE_SNAPSHOT_ 38 39#include <machine/vmm_snapshot.h> 40#include <libxo/xo.h> 41#include <ucl.h> 42 43#define BHYVE_RUN_DIR "/var/run/bhyve/" 44#define MAX_SNAPSHOT_FILENAME PATH_MAX 45 46struct vmctx; 47 48struct restore_state { 49 int kdata_fd; 50 int vmmem_fd; 51 52 void *kdata_map; 53 size_t kdata_len; 54 55 size_t vmmem_len; 56 57 struct ucl_parser *meta_parser; 58 ucl_object_t *meta_root_obj; 59}; 60 61struct checkpoint_thread_info { 62 struct vmctx *ctx; 63 int socket_fd; 64}; 65 66typedef int (*vm_snapshot_dev_cb)(struct vm_snapshot_meta *); 67typedef int (*vm_pause_dev_cb) (const char *); 68typedef int (*vm_resume_dev_cb) (const char *); 69 70struct vm_snapshot_dev_info { 71 const char *dev_name; /* device name */ 72 vm_snapshot_dev_cb snapshot_cb; /* callback for device snapshot */ 73 vm_pause_dev_cb pause_cb; /* callback for device pause */ 74 vm_resume_dev_cb resume_cb; /* callback for device resume */ 75}; 76 77struct vm_snapshot_kern_info { 78 const char *struct_name; /* kernel structure name*/ 79 enum snapshot_req req; /* request type */ 80}; 81 82void destroy_restore_state(struct restore_state *rstate); 83 84const char *lookup_vmname(struct restore_state *rstate); 85int lookup_memflags(struct restore_state *rstate); 86size_t lookup_memsize(struct restore_state *rstate); 87int lookup_guest_ncpus(struct restore_state *rstate); 88 89void checkpoint_cpu_add(int vcpu); 90void checkpoint_cpu_resume(int vcpu); 91void checkpoint_cpu_suspend(int vcpu); 92 93int restore_vm_mem(struct vmctx *ctx, struct restore_state *rstate); 94int vm_restore_kern_structs(struct vmctx *ctx, struct restore_state *rstate); 95 96int vm_restore_devices(struct restore_state *rstate); 97int vm_pause_devices(void); 98int vm_resume_devices(void); 99 100int get_checkpoint_msg(int conn_fd, struct vmctx *ctx); 101void *checkpoint_thread(void *param); 102int init_checkpoint_thread(struct vmctx *ctx); 103 104int load_restore_file(const char *filename, struct restore_state *rstate); 105 106int vm_snapshot_guest2host_addr(struct vmctx *ctx, void **addrp, size_t len, 107 bool restore_null, struct vm_snapshot_meta *meta); 108 109/* 110 * Address variables are pointers to guest memory. 111 * 112 * When RNULL != 0, do not enforce invalid address checks; instead, make the 113 * pointer NULL at restore time. 114 */ 115#define SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(CTX, ADDR, LEN, RNULL, META, RES, LABEL) \ 116do { \ 117 (RES) = vm_snapshot_guest2host_addr((CTX), (void **)&(ADDR), (LEN), \ 118 (RNULL), (META)); \ 119 if ((RES) != 0) { \ 120 if ((RES) == EFAULT) \ 121 EPRINTLN("%s: invalid address: %s", __func__, #ADDR); \ 122 goto LABEL; \ 123 } \ 124} while (0) 125 126#endif 127