1483d953aSJohn Baldwin /*- 2*4d846d26SWarner 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 #include <sys/cdefs.h> 37483d953aSJohn Baldwin __FBSDID("$FreeBSD$"); 38483d953aSJohn Baldwin 39483d953aSJohn Baldwin #include <sys/types.h> 40483d953aSJohn Baldwin #include <sys/systm.h> 41483d953aSJohn Baldwin 42483d953aSJohn Baldwin #include <machine/vmm_snapshot.h> 43483d953aSJohn Baldwin 44483d953aSJohn Baldwin void 45483d953aSJohn Baldwin vm_snapshot_buf_err(const char *bufname, const enum vm_snapshot_op op) 46483d953aSJohn Baldwin { 47483d953aSJohn Baldwin const char *opstr; 48483d953aSJohn Baldwin 49483d953aSJohn Baldwin if (op == VM_SNAPSHOT_SAVE) 50483d953aSJohn Baldwin opstr = "save"; 51483d953aSJohn Baldwin else if (op == VM_SNAPSHOT_RESTORE) 52483d953aSJohn Baldwin opstr = "restore"; 53483d953aSJohn Baldwin else 54483d953aSJohn Baldwin opstr = "unknown"; 55483d953aSJohn Baldwin 56483d953aSJohn Baldwin printf("%s: snapshot-%s failed for %s\r\n", __func__, opstr, bufname); 57483d953aSJohn Baldwin } 58483d953aSJohn Baldwin 59483d953aSJohn Baldwin int 608b1adff8SMark Johnston vm_snapshot_buf(void *data, size_t data_size, struct vm_snapshot_meta *meta) 61483d953aSJohn Baldwin { 62483d953aSJohn Baldwin struct vm_snapshot_buffer *buffer; 63483d953aSJohn Baldwin int op; 64483d953aSJohn Baldwin 65483d953aSJohn Baldwin buffer = &meta->buffer; 66483d953aSJohn Baldwin op = meta->op; 67483d953aSJohn Baldwin 68483d953aSJohn Baldwin if (buffer->buf_rem < data_size) { 69483d953aSJohn Baldwin printf("%s: buffer too small\r\n", __func__); 70483d953aSJohn Baldwin return (E2BIG); 71483d953aSJohn Baldwin } 72483d953aSJohn Baldwin 73483d953aSJohn Baldwin if (op == VM_SNAPSHOT_SAVE) 748b1adff8SMark Johnston copyout(data, buffer->buf, data_size); 75483d953aSJohn Baldwin else if (op == VM_SNAPSHOT_RESTORE) 768b1adff8SMark Johnston copyin(buffer->buf, data, data_size); 77483d953aSJohn Baldwin else 78483d953aSJohn Baldwin return (EINVAL); 79483d953aSJohn Baldwin 80483d953aSJohn Baldwin buffer->buf += data_size; 81483d953aSJohn Baldwin buffer->buf_rem -= data_size; 82483d953aSJohn Baldwin 83483d953aSJohn Baldwin return (0); 84483d953aSJohn Baldwin } 85483d953aSJohn Baldwin 86483d953aSJohn Baldwin size_t 87483d953aSJohn Baldwin vm_get_snapshot_size(struct vm_snapshot_meta *meta) 88483d953aSJohn Baldwin { 89483d953aSJohn Baldwin size_t length; 90483d953aSJohn Baldwin struct vm_snapshot_buffer *buffer; 91483d953aSJohn Baldwin 92483d953aSJohn Baldwin buffer = &meta->buffer; 93483d953aSJohn Baldwin 94483d953aSJohn Baldwin if (buffer->buf_size < buffer->buf_rem) { 95483d953aSJohn Baldwin printf("%s: Invalid buffer: size = %zu, rem = %zu\r\n", 96483d953aSJohn Baldwin __func__, buffer->buf_size, buffer->buf_rem); 97483d953aSJohn Baldwin length = 0; 98483d953aSJohn Baldwin } else { 99483d953aSJohn Baldwin length = buffer->buf_size - buffer->buf_rem; 100483d953aSJohn Baldwin } 101483d953aSJohn Baldwin 102483d953aSJohn Baldwin return (length); 103483d953aSJohn Baldwin } 104483d953aSJohn Baldwin 105483d953aSJohn Baldwin int 1068b1adff8SMark Johnston vm_snapshot_buf_cmp(void *data, size_t data_size, struct vm_snapshot_meta *meta) 107483d953aSJohn Baldwin { 108483d953aSJohn Baldwin struct vm_snapshot_buffer *buffer; 109483d953aSJohn Baldwin int op; 110483d953aSJohn Baldwin int ret; 111483d953aSJohn Baldwin 112483d953aSJohn Baldwin buffer = &meta->buffer; 113483d953aSJohn Baldwin op = meta->op; 114483d953aSJohn Baldwin 115483d953aSJohn Baldwin if (buffer->buf_rem < data_size) { 116483d953aSJohn Baldwin printf("%s: buffer too small\r\n", __func__); 117483d953aSJohn Baldwin ret = E2BIG; 118483d953aSJohn Baldwin goto done; 119483d953aSJohn Baldwin } 120483d953aSJohn Baldwin 121483d953aSJohn Baldwin if (op == VM_SNAPSHOT_SAVE) { 122483d953aSJohn Baldwin ret = 0; 1238b1adff8SMark Johnston copyout(data, buffer->buf, data_size); 124483d953aSJohn Baldwin } else if (op == VM_SNAPSHOT_RESTORE) { 1258b1adff8SMark Johnston ret = memcmp(data, buffer->buf, data_size); 126483d953aSJohn Baldwin } else { 127483d953aSJohn Baldwin ret = EINVAL; 128483d953aSJohn Baldwin goto done; 129483d953aSJohn Baldwin } 130483d953aSJohn Baldwin 131483d953aSJohn Baldwin buffer->buf += data_size; 132483d953aSJohn Baldwin buffer->buf_rem -= data_size; 133483d953aSJohn Baldwin 134483d953aSJohn Baldwin done: 135483d953aSJohn Baldwin return (ret); 136483d953aSJohn Baldwin } 137