CrossPoolMigrationv3
From Xen
Jump to navigationJump to search
This page describes a possible design for Cross-pool migration (which also works for within-pool migration with and without shared storage).
This design has the following features:
- disks are replicated between the two sites/SRs using a "replication service" which is aware of the underlying disk structure (e.g. in the case of .vhd it can use the sparseness information to speed up the copying)
- the mirror is made synchronous by using the *tapdisk* "mirror" plugin (the same as used by the existing disk caching feature)
- the pool-level VM metadata is export/imported by xapi
- the domain-level VM metadata is export/imported by xenopsd
See the following diagram:
This design has the following advantages:
- by separating the act of mirroring the disks (like a storage array would do) from the act of copying a running memory image, we don't need to hack libxenguest. There is a clean division of responsibility between managing storage and managing running VMs.
- by creating a synchronous mirror, we don't increase the migration blackout time
- we can re-use the disk replication service to do efficient cross-site backup/restore (ie to make periodic VM snapshot and archive use an incremental archive)
Proposed APIs
- VM.migrate_receive(Host host, SR sr, Map(String,String) options): Map(String, String)
- host: the host to move the running VM to
- sr: the SR to replicate the VM's disks to
- options: for future advanced options
- the return value should be considered an abstract token, identifying the receiver. The token should be passed to the transmitter.
- VM.migrate(VM vm, Map(String, String) dest, Bool live, Map(String, String) options)
- vm: the running VM to migrate
- dest: the result of a previous VM.migrate_receive call
- live: if true this is a "live" migration
- options: for future advanced options
Usage
A client wishing to perform a storage migration could do something like this:
# 1. Log into the remote pool remote = xmlrpclib.Server("https://my.remote.pool/") remote_session_id = remote.session.login_with_password("root", "password")["Value"] # 2. Decide where you want the VM to go remote_sr = remote.SR.get_by_name_label(remote_session_id, "my favourite storage")["Value"] remote_host = remote.Host.get_by_name_label(remote_session_id, "my favourite host")["Value"] # 3. Generate a token representing this destination dest = remote.VM.migrate_receive(remote_session_id, host, sr, {})["Value"] # Note: We don't log out of the remote session because it would invalidate 'dest' # 4. Log into the local pool local = xmlrpclib.Server("https://my.local.pool/") local_session_id = local.session.login_with_password("root", "password")["Value"] # 5. Decide which VM we want to move local_vm = local.VM.get_by_name_label(local_session_id, "my lovely VM")["Value"] # 6. Migrate the VM: task = local.Async.VM.migrate(local_session_id, vm, dest, true, {})["Value"] # Monitor the task for success/failure # 7. Clean up remote.session.logout(remote_session_id) local.session.logout(local_session_id)