Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.7k views
in Technique[技术] by (71.8m points)

How to merge/delete snapshots with libvirt-python

I'm trying to write some Python code that uses libvirt-python to manage external snapshots with the KVM APIs. I'm not sure of what to do in order to delete (aka merge) a certain snapshot. Let's say we have mainly 2 case in the following scenario: base <- snap_a <- snap-b <- top (as shown in this webpage).

  1. I want to merge snap_a and snap_b (b is the active one). The result should have base as backing file in the snapshot chain.
  2. I want to merge base and snap_a (none of them is active). The result should keep snap_b as active snapshot, which has base as backing file.

In the first case I lost my base backing file, while in the second one i got this error: Failed to merge snapshot: invalid argument: active commit requested but '/var/lib/nova/instances/b9c9cd3b-1102-4084-a7a9-6e85c179ac9c/disk.snap_system_1610446663' is not active (snap_system_numbers here is like snap_a in my example).

This is my merging function:

def snapshot_merge(instance_name: str, snapshot_name: str):
    # Getting the connection to qemu
    conn, dom = open_qemu_connection(instance_name)
    if conn is not None and dom is not None:
        logging.info(
                     'Merging domain {} from snapshot {}'
                     .format(instance_name, snapshot_name))
        # Merge snapshot (Block commit, first phase)
        # Get the vda path from my custom function
        disk_path = get_vda_path(dom)
        top = disk_path+'.'+snapshot_name
        disk = 'vda'
        bandwith = 0
        # Check if snapshot in input is the active/current one. Also setting flags
        snapshot = dom.snapshotCurrent()
        if snapshot.getName() == snapshot_name:
            bc_flags = (libvirt.VIR_DOMAIN_BLOCK_COMMIT_ACTIVE
                        + libvirt.VIR_DOMAIN_BLOCK_COMMIT_SHALLOW)
        else:
            bc_flags = 0
        try:
            dom.blockCommit(disk,
                            None,
                            top,
                            bandwith,
                            bc_flags)
            logging.info('Snapshot merged')
        except libvirt.libvirtError as e:
            logging.info('Failed to merge snapshot: %s' % e)
            close_qemu_connection(conn)
            raise HTTPException(status_code=500, detail=ERR_MERGE)
        # Merge snapshot (Pivoting, second phase)
        piv_flags = libvirt.VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT
        # Wait for ready state
        time.sleep(5)
        try:
            dom.blockJobAbort(disk, piv_flags)
            logging.info('Snapshot pivoted')
            snapshot_delete(dom, snapshot_name, top)
            return {"snapshot_name": snapshot_name}
        except libvirt.libvirtError as e:
            logging.info('Failed to pivot snapshot: %s' % e)
            # TODO snapshot_delete(dom, snapshot_name, top)
            raise HTTPException(status_code=500, detail=ERR_PIVOT)
        finally:
            close_qemu_connection(conn)
    else:
        logging.info('Process failed')
        raise HTTPException(status_code=500, detail=ERR_CONN)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...