1483d953aSJohn Baldwin /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3483d953aSJohn Baldwin * 4483d953aSJohn Baldwin * Copyright (c) 2016 Flavius Anton 5483d953aSJohn Baldwin * Copyright (c) 2016 Mihai Tiganus 6483d953aSJohn Baldwin * Copyright (c) 2016-2019 Mihai Carabas 7483d953aSJohn Baldwin * Copyright (c) 2017-2019 Darius Mihai 8483d953aSJohn Baldwin * Copyright (c) 2017-2019 Elena Mihailescu 9483d953aSJohn Baldwin * Copyright (c) 2018-2019 Sergiu Weisz 10483d953aSJohn Baldwin * All rights reserved. 11483d953aSJohn Baldwin * The bhyve-snapshot feature was developed under sponsorships 12483d953aSJohn Baldwin * from Matthew Grooms. 13483d953aSJohn Baldwin * 14483d953aSJohn Baldwin * Redistribution and use in source and binary forms, with or without 15483d953aSJohn Baldwin * modification, are permitted provided that the following conditions 16483d953aSJohn Baldwin * are met: 17483d953aSJohn Baldwin * 1. Redistributions of source code must retain the above copyright 18483d953aSJohn Baldwin * notice, this list of conditions and the following disclaimer. 19483d953aSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 20483d953aSJohn Baldwin * notice, this list of conditions and the following disclaimer in the 21483d953aSJohn Baldwin * documentation and/or other materials provided with the distribution. 22483d953aSJohn Baldwin * 23483d953aSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 24483d953aSJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25483d953aSJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26483d953aSJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 27483d953aSJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28483d953aSJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29483d953aSJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30483d953aSJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31483d953aSJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32483d953aSJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33483d953aSJohn Baldwin * SUCH DAMAGE. 34483d953aSJohn Baldwin */ 35483d953aSJohn Baldwin 36483d953aSJohn Baldwin #ifndef _BHYVE_SNAPSHOT_ 37483d953aSJohn Baldwin #define _BHYVE_SNAPSHOT_ 38483d953aSJohn Baldwin 39483d953aSJohn Baldwin #include <machine/vmm_snapshot.h> 40483d953aSJohn Baldwin #include <libxo/xo.h> 41483d953aSJohn Baldwin #include <ucl.h> 42483d953aSJohn Baldwin 435ce2d4a1SRobert Wing #define BHYVE_RUN_DIR "/var/run/bhyve/" 44d656ce19SRobert Wing #define MAX_SNAPSHOT_FILENAME PATH_MAX 454f4065e0SRobert Wing 46483d953aSJohn Baldwin struct vmctx; 47483d953aSJohn Baldwin 48483d953aSJohn Baldwin struct restore_state { 49483d953aSJohn Baldwin int kdata_fd; 50483d953aSJohn Baldwin int vmmem_fd; 51483d953aSJohn Baldwin 52483d953aSJohn Baldwin void *kdata_map; 53483d953aSJohn Baldwin size_t kdata_len; 54483d953aSJohn Baldwin 55483d953aSJohn Baldwin size_t vmmem_len; 56483d953aSJohn Baldwin 57483d953aSJohn Baldwin struct ucl_parser *meta_parser; 58483d953aSJohn Baldwin ucl_object_t *meta_root_obj; 59483d953aSJohn Baldwin }; 60483d953aSJohn Baldwin 61483d953aSJohn Baldwin struct checkpoint_thread_info { 62483d953aSJohn Baldwin struct vmctx *ctx; 63483d953aSJohn Baldwin int socket_fd; 64483d953aSJohn Baldwin }; 65483d953aSJohn Baldwin 66483d953aSJohn Baldwin typedef int (*vm_snapshot_dev_cb)(struct vm_snapshot_meta *); 676a284cacSJohn Baldwin typedef int (*vm_pause_dev_cb) (const char *); 686a284cacSJohn Baldwin typedef int (*vm_resume_dev_cb) (const char *); 69483d953aSJohn Baldwin 70483d953aSJohn Baldwin struct vm_snapshot_dev_info { 71483d953aSJohn Baldwin const char *dev_name; /* device name */ 72483d953aSJohn Baldwin vm_snapshot_dev_cb snapshot_cb; /* callback for device snapshot */ 73483d953aSJohn Baldwin vm_pause_dev_cb pause_cb; /* callback for device pause */ 74483d953aSJohn Baldwin vm_resume_dev_cb resume_cb; /* callback for device resume */ 75483d953aSJohn Baldwin }; 76483d953aSJohn Baldwin 77483d953aSJohn Baldwin struct vm_snapshot_kern_info { 78483d953aSJohn Baldwin const char *struct_name; /* kernel structure name*/ 79483d953aSJohn Baldwin enum snapshot_req req; /* request type */ 80483d953aSJohn Baldwin }; 81483d953aSJohn Baldwin 82483d953aSJohn Baldwin void destroy_restore_state(struct restore_state *rstate); 83483d953aSJohn Baldwin 84483d953aSJohn Baldwin const char *lookup_vmname(struct restore_state *rstate); 85483d953aSJohn Baldwin int lookup_memflags(struct restore_state *rstate); 86483d953aSJohn Baldwin size_t lookup_memsize(struct restore_state *rstate); 87483d953aSJohn Baldwin int lookup_guest_ncpus(struct restore_state *rstate); 88483d953aSJohn Baldwin 89483d953aSJohn Baldwin void checkpoint_cpu_add(int vcpu); 90483d953aSJohn Baldwin void checkpoint_cpu_resume(int vcpu); 91483d953aSJohn Baldwin void checkpoint_cpu_suspend(int vcpu); 92483d953aSJohn Baldwin 93483d953aSJohn Baldwin int restore_vm_mem(struct vmctx *ctx, struct restore_state *rstate); 94483d953aSJohn Baldwin int vm_restore_kern_structs(struct vmctx *ctx, struct restore_state *rstate); 95483d953aSJohn Baldwin 96b10d65a4SVitaliy Gusev int vm_restore_devices(struct restore_state *rstate); 97b10d65a4SVitaliy Gusev int vm_pause_devices(void); 98b10d65a4SVitaliy Gusev int vm_resume_devices(void); 99483d953aSJohn Baldwin 100483d953aSJohn Baldwin int get_checkpoint_msg(int conn_fd, struct vmctx *ctx); 101483d953aSJohn Baldwin void *checkpoint_thread(void *param); 102483d953aSJohn Baldwin int init_checkpoint_thread(struct vmctx *ctx); 103483d953aSJohn Baldwin 104483d953aSJohn Baldwin int load_restore_file(const char *filename, struct restore_state *rstate); 105483d953aSJohn Baldwin 1060f735657SJohn Baldwin int vm_snapshot_guest2host_addr(struct vmctx *ctx, void **addrp, size_t len, 1070f735657SJohn Baldwin bool restore_null, struct vm_snapshot_meta *meta); 1080f735657SJohn Baldwin 1090f735657SJohn Baldwin /* 1100f735657SJohn Baldwin * Address variables are pointers to guest memory. 1110f735657SJohn Baldwin * 1120f735657SJohn Baldwin * When RNULL != 0, do not enforce invalid address checks; instead, make the 1130f735657SJohn Baldwin * pointer NULL at restore time. 1140f735657SJohn Baldwin */ 1150f735657SJohn Baldwin #define SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(CTX, ADDR, LEN, RNULL, META, RES, LABEL) \ 1160f735657SJohn Baldwin do { \ 1170f735657SJohn Baldwin (RES) = vm_snapshot_guest2host_addr((CTX), (void **)&(ADDR), (LEN), \ 1180f735657SJohn Baldwin (RNULL), (META)); \ 1190f735657SJohn Baldwin if ((RES) != 0) { \ 1200f735657SJohn Baldwin if ((RES) == EFAULT) \ 121*b0936440SJohn Baldwin EPRINTLN("%s: invalid address: %s", __func__, #ADDR); \ 1220f735657SJohn Baldwin goto LABEL; \ 1230f735657SJohn Baldwin } \ 1240f735657SJohn Baldwin } while (0) 1250f735657SJohn Baldwin 126483d953aSJohn Baldwin #endif 127