diff --git a/usr.sbin/bhyve/snapshot.c b/usr.sbin/bhyve/snapshot.c --- a/usr.sbin/bhyve/snapshot.c +++ b/usr.sbin/bhyve/snapshot.c @@ -415,51 +415,6 @@ } \ } while(0) -static void * -lookup_struct(enum snapshot_req struct_id, struct restore_state *rstate, - size_t *struct_size) -{ - const ucl_object_t *structs = NULL, *obj = NULL; - ucl_object_iter_t it = NULL; - int64_t snapshot_req, size, file_offset; - - structs = ucl_object_lookup(rstate->meta_root_obj, JSON_KERNEL_ARR_KEY); - if (structs == NULL) { - fprintf(stderr, "Failed to find '%s' object.\n", - JSON_KERNEL_ARR_KEY); - return (NULL); - } - - if (ucl_object_type(structs) != UCL_ARRAY) { - fprintf(stderr, "Object '%s' is not an array.\n", - JSON_KERNEL_ARR_KEY); - return (NULL); - } - - while ((obj = ucl_object_iterate(structs, &it, true)) != NULL) { - snapshot_req = -1; - JSON_GET_INT_OR_RETURN(JSON_SNAPSHOT_REQ_KEY, obj, - &snapshot_req, NULL); - assert(snapshot_req >= 0); - if ((enum snapshot_req) snapshot_req == struct_id) { - JSON_GET_INT_OR_RETURN(JSON_SIZE_KEY, obj, - &size, NULL); - assert(size >= 0); - - JSON_GET_INT_OR_RETURN(JSON_FILE_OFFSET_KEY, obj, - &file_offset, NULL); - assert(file_offset >= 0); - assert((uint64_t)file_offset + size <= - rstate->kdata_len); - - *struct_size = (size_t)size; - return ((uint8_t *)rstate->kdata_map + file_offset); - } - } - - return (NULL); -} - static void * lookup_check_dev(const char *dev_name, struct restore_state *rstate, const ucl_object_t *obj, size_t *data_size) @@ -488,15 +443,15 @@ return (NULL); } -static void* -lookup_dev(const char *dev_name, struct restore_state *rstate, - size_t *data_size) +static void * +lookup_dev(const char *dev_name, const char *key, struct restore_state *rstate, + size_t *data_size) { const ucl_object_t *devs = NULL, *obj = NULL; ucl_object_iter_t it = NULL; void *ret; - devs = ucl_object_lookup(rstate->meta_root_obj, JSON_DEV_ARR_KEY); + devs = ucl_object_lookup(rstate->meta_root_obj, key); if (devs == NULL) { fprintf(stderr, "Failed to find '%s' object.\n", JSON_DEV_ARR_KEY); @@ -861,67 +816,42 @@ return (0); } -static int -vm_restore_kern_struct(struct vmctx *ctx, struct restore_state *rstate, - const struct vm_snapshot_kern_info *info) +int +vm_restore_kern_structs(struct vmctx *ctx, struct restore_state *rstate) { - void *struct_ptr; - size_t struct_size; - int ret; - struct vm_snapshot_meta *meta; - - struct_ptr = lookup_struct(info->req, rstate, &struct_size); - if (struct_ptr == NULL) { - fprintf(stderr, "%s: Failed to lookup struct %s\r\n", - __func__, info->struct_name); - ret = -1; - goto done; - } + for (unsigned i = 0; i < nitems(snapshot_kern_structs); i++) { + const struct vm_snapshot_kern_info *info; + struct vm_snapshot_meta *meta; + void *data; + size_t size; - if (struct_size == 0) { - fprintf(stderr, "%s: Kernel struct size was 0 for: %s\r\n", - __func__, info->struct_name); - ret = -1; - goto done; - } + info = &snapshot_kern_structs[i]; + data = lookup_dev(info->struct_name, JSON_KERNEL_ARR_KEY, rstate, &size); + if (data == NULL) + errx(EX_DATAERR, "Cannot find kern struct %s", + info->struct_name); - meta = &(struct vm_snapshot_meta) { - .dev_name = info->struct_name, - .dev_req = info->req, - - .buffer.buf_start = struct_ptr, - .buffer.buf_size = struct_size, + if (size == 0) + errx(EX_DATAERR, "data with zero size for %s", + info->struct_name); - .buffer.buf = struct_ptr, - .buffer.buf_rem = struct_size, + meta = &(struct vm_snapshot_meta) { + .dev_name = info->struct_name, + .dev_req = info->req, - .op = VM_SNAPSHOT_RESTORE, - }; + .buffer.buf_start = data, + .buffer.buf_size = size, - ret = vm_snapshot_req(ctx, meta); - if (ret != 0) { - fprintf(stderr, "%s: Failed to restore struct: %s\r\n", - __func__, info->struct_name); - goto done; - } + .buffer.buf = data, + .buffer.buf_rem = size, -done: - return (ret); -} - -int -vm_restore_kern_structs(struct vmctx *ctx, struct restore_state *rstate) -{ - size_t i; - int ret; + .op = VM_SNAPSHOT_RESTORE, + }; - for (i = 0; i < nitems(snapshot_kern_structs); i++) { - ret = vm_restore_kern_struct(ctx, rstate, - &snapshot_kern_structs[i]); - if (ret != 0) - return (ret); + if (vm_snapshot_req(ctx, meta)) + err(EX_DATAERR, "Failed to restore %s", + info->struct_name); } - return (0); } @@ -934,7 +864,8 @@ int ret; struct vm_snapshot_meta *meta; - dev_ptr = lookup_dev(info->dev_name, rstate, &dev_size); + dev_ptr = lookup_dev(info->dev_name, JSON_DEV_ARR_KEY, rstate, + &dev_size); if (dev_ptr == NULL) { fprintf(stderr, "Failed to lookup dev: %s\r\n", info->dev_name); fprintf(stderr, "Continuing the restore/migration process\r\n"); @@ -1027,7 +958,7 @@ } static int -vm_snapshot_kern_struct(struct vmctx *ctx, int data_fd, xo_handle_t *xop, +vm_save_kern_struct(struct vmctx *ctx, int data_fd, xo_handle_t *xop, const char *array_key, struct vm_snapshot_meta *meta, off_t *offset) { int ret; @@ -1054,9 +985,8 @@ /* Write metadata. */ xo_open_instance_h(xop, array_key); - xo_emit_h(xop, "{:debug_name/%s}\n", meta->dev_name); - xo_emit_h(xop, "{:" JSON_SNAPSHOT_REQ_KEY "/%d}\n", - meta->dev_req); + xo_emit_h(xop, "{:" JSON_SNAPSHOT_REQ_KEY "/%s}\n", + meta->dev_name); xo_emit_h(xop, "{:" JSON_SIZE_KEY "/%lu}\n", data_size); xo_emit_h(xop, "{:" JSON_FILE_OFFSET_KEY "/%lu}\n", *offset); xo_close_instance_h(xop, JSON_KERNEL_ARR_KEY); @@ -1068,7 +998,7 @@ } static int -vm_snapshot_kern_structs(struct vmctx *ctx, int data_fd, xo_handle_t *xop) +vm_save_kern_structs(struct vmctx *ctx, int data_fd, xo_handle_t *xop) { int ret, error; size_t buf_size, i, offset; @@ -1102,7 +1032,7 @@ meta->buffer.buf = meta->buffer.buf_start; meta->buffer.buf_rem = meta->buffer.buf_size; - ret = vm_snapshot_kern_struct(ctx, data_fd, xop, + ret = vm_save_kern_struct(ctx, data_fd, xop, JSON_DEV_ARR_KEY, meta, &offset); if (ret != 0) { error = -1; @@ -1385,8 +1315,7 @@ goto done; } - - ret = vm_snapshot_kern_structs(ctx, kdata_fd, xop); + ret = vm_save_kern_structs(ctx, kdata_fd, xop); if (ret != 0) { fprintf(stderr, "Failed to snapshot vm kernel data.\n"); error = -1;