The branch main has been updated by corvink:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ee5023f3c2f46987fd051de2696c1743e4226a37

commit ee5023f3c2f46987fd051de2696c1743e4226a37
Author:     Vitaliy Gusev <[email protected]>
AuthorDate: 2023-05-15 14:27:29 +0000
Commit:     Corvin Köhne <[email protected]>
CommitDate: 2023-06-19 05:51:33 +0000

    bhyve: simplify restore of kernel structs
    
    Both devices and kernel struct can use the same 'lookup_dev'
    function instead of having duplicated code.
    
    Reviewed by:            corvink, rew
    MFC after:              1 week
    Sponsored by:           vStack
    Differential Revision:  https://reviews.freebsd.org/D40105
---
 usr.sbin/bhyve/snapshot.c | 149 ++++++++++++----------------------------------
 1 file changed, 39 insertions(+), 110 deletions(-)

diff --git a/usr.sbin/bhyve/snapshot.c b/usr.sbin/bhyve/snapshot.c
index 7e635c13ef31..dfe341c598b8 100644
--- a/usr.sbin/bhyve/snapshot.c
+++ b/usr.sbin/bhyve/snapshot.c
@@ -415,51 +415,6 @@ do {                                                       
                        \
        }                                                                       
\
 } 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 @@ lookup_check_dev(const char *dev_name, struct 
restore_state *rstate,
        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 @@ restore_vm_mem(struct vmctx *ctx, struct restore_state 
*rstate)
        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 @@ vm_restore_user_dev(struct restore_state *rstate,
        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 @@ vm_resume_user_devs(void)
 }
 
 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 @@ vm_snapshot_kern_struct(struct vmctx *ctx, int data_fd, 
xo_handle_t *xop,
 
        /* 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 @@ done:
 }
 
 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 @@ vm_snapshot_kern_structs(struct vmctx *ctx, int data_fd, 
xo_handle_t *xop)
                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 @@ vm_checkpoint(struct vmctx *ctx, int fddir, const char 
*checkpoint_file,
                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;

Reply via email to