[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC V10 4/4] domain snapshot design: libxl



Changes to V9:
  * update libxl_disk_snapshot structures as Ian suggests
  * add more descriptions for libxl_disk_snapshot_delete
  * add two functions for deleting external disk snapshot:
    libxl_domain_block_rebase and libxl_domain_block_commit

===========================================================================

Libxl Design

1. New Structures

libxl_disk_snapshot_type = Struct("disk_snapshot_type", [
    (0, "default"),
    (1, "internal"),
    (2, "external"),
    ])

libxl_disk_snapshot = Struct("disk_snapshot",[
    # target disk
    ("disk",            libxl_device_disk),

    # disk snapshot name
    ("name",            string),

    ("u", KeyedUnion(None, libxl_disk_snapshot_type, "type",
         [("external", Struct(None, [

            # disk format for external files. Since external disk snapshot is
            # implemented with backing file mechanism, the external file disk
            # format must support backing file. This field can be NULL, then
            # a proper disk format will be used by default according to the
            # orignal disk format.
            ("external_format", libxl_disk_format),

            # external file path. This field should be non-NULL and a new path.
            ("external_path",   string),
            ]))
         ]))
    ])


2. New Functions

Since there're already APIs for saving memory (libxl_domain_suspend)
and restoring domain from saved memory (libxl_domain_create_restore), to
xl domain snapshot tasks, the missing part is disk snapshot functionality.
And the disk snapshot functionality would be used by libvirt too.

Considering there is qmp handling in creating/deleting disk snapshot,
will add following new functions to libxl:

/**
 * libxl_disk_snaphost_create:
 * @ctx: libxl context
 * @domid: domain id
 * @snapshot: array of disk snapshot configuration. Has "nb" members.
 *     - libxl_device_disk:
 *         structure to represent which disk.
 *     - name:
 *         snapshot name.
 *     - type:
 *        disk snapshot type: internal or external.
 *     - u.external.external_format:
 *         Format of external file.
 *         After disk snapshot, original file will become a backing
 *         file, while external file will keep the delta, so
 *         external_format should support backing file, like: cow,
 *         qcow, qcow2, etc.
 *         If it is NULL, then it will use proper format by default
 *         according to original disk format.
 *     - u.external.external_path:
 *         path to external file. non-NULL.
 * @nb: number of disks that need to take disk snapshot.
 *
 * createing internal/external disk snapshot
 *
 * Taking disk snapshots to a group of domain disks according to
 * configuration. Support both internal disk snapshot and external
 * disk snapshot. For qcow2 disk backend type, it will call qmp
 * "transaction" command to do the work. For other disk backend types,
 * might call other external commands.
 *
 * Returns 0 on success, <0 on failure.
 */
int libxl_disk_snapshot_create(libxl_ctx *ctx, uint32_t domid,
                               libxl_disk_snapshot *snapshot, int nb);


/**
 * libxl_disk_snaphost_delete:
 * @ctx: libxl context
 * @domid: domain id
 * @snapshot: array of disk snapshot configuration. Has "nb" members.
 * @nb: number of disks.
 *
 * Delete disk snapshot, deal with internal disk snapshot only.
 *
 * Delete disk snapshot of a group of domain disks according to
 * configuration. Can only deal with internal disk snapshot (currently
 * only 'qcow2', by calling qmp command). Can safely delete disk
 * snapshot even when the snapshot is in a snapshot chain, won't affect
 * other snapshots. Don't need to know snapshot chain info.
 *
 * To delete external disk snapshots, means shorten backing file chain
 * and merge snapshot data, must have snapshot chain info. Functions
 * libxl_domain_block_rebase and libxl_domain_block_commit would help.
 *
 * Returns 0 on success, <0 on failure.
 */
int libxl_disk_snapshot_delete(libxl_ctx *ctx, uint32_t domid,
                               libxl_disk_snapshot *snapshot, int nb);


Following two functions would be used to delete external disk snapshots.
They are essentially two directions to shorten backing file chain. One
is from "base" to "top" merge, the other is from "top" to "base" merge.
Both need caller to have the backing file chain information.

(This is active mode, when domain is live.
 When domain is offline, can call 'qemu-img rebase|commit' to do the work

 Since xl won't maintain snapshot chain information, either xl implement
 some commands for users so that users could call xl commands to do merge
 work, or users could do merge work by qemu-img when domain is offline.)

/**
 * libxl_domain_block_rebase:
 * @ctx: libxl context
 * @domid: domain id
 * @disk: path to the block device
 * @base: path to backing file to keep, or NULL for no backing file
 * @bandwidth: (optional) bandwidth limit in B/s, 0 for no limit.
 *
 * Merge data from base to top
 *
 * Populate a disk image with data from its backing image chain, and
 * setting the backing image to @base, or alternatively copy an entire
 * backing chain to a new file @base.
 *
 * @base must be the absolute path of one of the backing images further
 * up the chain, or NULL to convert the disk image so that it has no
 * backing image.  Once all data from its backing image chain has been
 * pulled, the disk no longer depends on those intermediate backing
 * images.
 *
 * The maximum bandwidth that will be used to do the copy can be
 * specified with the @bandwidth parameter, unit is B/s.  If set to 0,
 * there is no limit.
 *
 * e.g.:
 * backing file chain:
 *     RootBase <- A <- B <- disk
 * after libxl_domain_block_rebase(ctx, domid, disk, A, 0):
 *     RootBase <- A <- disk
 * delta in B is merged into disk.
 *
 * Returns 0 on success, <0 on failure.
 */
int libxl_domain_block_rebase(libxl_ctx *ctx, uint32_t domid,
                              const char *disk,
                              const char *base,
                              unsigned long long bandwidth);


/**
 * libxl_domain_block_commit:
 * @ctx: libxl context
 * @domid: domain id
 * @disk: path to the block device
 * @base: path to backing file to merge into, or NULL for default
 * @top: path to file within backing chain that contains data to be merged,
 *       or NULL to merge all possible data
 * @bandwidth: (optional) bandwidth limit in B/s; 0 for no limit
 *
 * Merge data from top to base
 *
 * Commit changes that were made to temporary top-level files within a disk
 * image backing file chain into a lower-level base file.  In other words,
 * take all the difference between @base and @top, and update @base to contain
 * that difference; after the commit, any portion of the chain that previously
 * depended on @top will now depend on @base, and all files after @base up
 * to and including @top will now be invalidated.  A typical use of this
 * command is to reduce the length of a backing file chain after taking an
 * external disk snapshot. To move data in the opposite direction, see
 * libxl_domain_block_commit().
 *
 * e.g.:
 * backing file chain:
 *     RootBase <- A <- B <- disk
 * after libxl_domain_block_commit(ctx, domid, disk, RootBase, B, 0):
 *     RootBase <- B <- disk
 * delta in A is merged to RootBase.
 *
 * Returns 0 on success, <0 on failure.
 */
int libxl_domain_block_commit(libxl_ctx *ctx, uint32_t domid,
                              const char *disk,
                              const char *base,
                              const char *top,
                              unsigned long bandwidth);



For disk snapshot revert, since domain snapshot revert is essentially
destroy, revert disks and restore from RAM. There is no qemu process
to speak to during reverting disks. So, it always calls external
commands to finish the work:

/**
 * libxl_disk_snapshot_revert:
 * @snapshot: array of disk snapshot configuration. Has "nb" members.
 * @nb: number of disks.
 *
 * Revert disks to specified snapshot according to configuration. To
 * different disk backend types, call different external commands to do
 * the work.
 *
 * Returns 0 on success, <0 on failure.
 */
int libxl_disk_snapshot_revert(libxl_disk_snapshot *snapshot, int nb);


/**
 * libxl_disk_to_snapshot:
 * @snapshot: array of disk snapshot configuration. Has "nb" members.
 * @nb: number of disks.
 * @ctx: libxl context
 * @domid: domain id
 * @snapshot (OUTPUT): array of disk snapshot configuration.
 * @num (OUTPUT): number of disks.
 *
 * Helper function to produce an array of libxl_disk_snapshot.
 *
 * Could be used when user doesn't specify disk snapshot information
 * in creating a domain snapshot, it will by default fill disk snapshot
 * information according to domain disks:
 *   By default it will take internal disk snapshot to each domain
 *   disk that could take internal disk snapshot, otherwise, take
 *   external disk snapshot.
 * Then the result libxl_disk_snapshot array could be passed to
 * libxl_disk_snapshot_create to do the disk snapshot creating work.
 *
 * Returns 0 on success, <0 on failure.
 */
int libxl_disk_to_snapshot(libxl_ctx *ctx, uint32_t domid,
                           libxl_disk_snapshot **snapshot, int *num);



3. Simple Architecture View

Creating domain snapshot:
(* means new functions we will need in libxl)

  "xl snapshot-create"
         |
  parse configuration ----> libxl_disk_to_snapshot (*)
         |
  saving memory ----> libxl_domain_suspend
         |
 taking disk snapshot ----> libxl_disk_snapshot_create (*)
         |                     |
         |                     --> libxl_qmp_disk_snapshot_transaction (*)
         |
    unpause domain ---->libxl_domain_unpause
         |
        End


Reverting to a snapshot:
(* means new functions we will need in libxl)

  "xl snapshot-revert"
         |
   parse configuration
         |
   destroy domain ---->libxl_domain_destroy
         |
 reverting disk snapshot ----> libxl_disk_snapshot_revert (*)
         |                       |
         |                       --> call 'qemu-img' to apply disk snapshot
         |
 restore domain from saved memory ----> libxl_domain_create_restore
         |
        End

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.