In 4.2, we added VM snapshot for Vmware/Xenserver. The current workflow will be 
like the following:
createVMSnapshot api -> VMSnapshotManagerImpl: creatVMSnapshot -> send 
CreateVMSnapshotCommand to hypervisor to create vm snapshot.

If anybody wants to change the workflow, then need to either change 
VMSnapshotManagerImpl directly or subclass VMSnapshotManagerImpl. Both are not 
the ideal choice, as VMSnapshotManagerImpl should be able to handle different 
ways to take vm snapshot, instead of hard code.

The requirements for the pluggable VM snapshot coming from:
Storage vendor may have their optimization, such as NetApp.
VM snapshot can be implemented in a totally different way(For example, I could 
just send a command to guest VM, to tell my application to flush disk and hold 
disk write, then come to hypervisor to take a volume snapshot). 

If we agree on enable pluggable VM snapshot, then we can move on discuss how to 
implement it.

The possible options:
1. coarse grained interface. Add a VMSnapshotStrategy interface, which has the 
following interfaces:
    VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot);
    Boolean revertVMSnapshot(VMSnapshot vmSnapshot);
    Boolean DeleteVMSnapshot(VMSnapshot vmSnapshot);

   The work flow will be: createVMSnapshot api -> VMSnapshotManagerImpl: 
creatVMSnapshot -> VMSnapshotStrategy: takeVMSnapshot
   VMSnapshotManagerImpl will manage VM state, do the sanity check, then will 
handle over to VMSnapshotStrategy. 
   In VMSnapshotStrategy implementation, it may just send a 
Create/revert/delete VMSnapshotCommand to hypervisor host, or do anything 
special operations.

2. fine-grained interface. Not only add a VMSnapshotStrategy interface, but 
also add certain methods on the storage driver.
    The VMSnapshotStrategy interface will be the same as option 1.
    Will add the following methods on storage driver:
   /* volumesBelongToVM  is the list of volumes of the VM that created on this 
storage, storage vendor can either take one snapshot for this volumes in one 
shot, or take snapshot for each volume separately
       The pre-condition: vm is unquiesced. 
       It will return a Boolean to indicate, do need unquiesce vm or not.
       In the default storage driver, it will return false.
    */
    boolean takeVMSnapshot(List<VolumeInfo> volumesBelongToVM, VMSnapshot 
vmSnapshot);  
    Boolean revertVMSnapshot(List<VolumeInfo> volumesBelongToVM, VMSnapshot 
vmSnapshot);
   Boolean deleteVMSnapshot(List<VolumeInfo> volumesBelongToVM, VMSnapshot 
vmSNapshot);

The work flow will be: createVMSnapshot api -> VMSnapshotManagerImpl: 
creatVMSnapshot -> VMSnapshotStrategy: takeVMSnapshot -> storage 
driver:takeVMSnapshot
 In the implementation of VMSnapshotStrategy's takeVMSnapshot, the pseudo code 
looks like:
       HypervisorHelper.quiesceVM(vm);
       val volumes = vm.getVolumes();
       val maps = new Map[driver, list[VolumeInfo]]();
       Volumes.foreach(volume => maps.put(volume.getDriver, volume :: 
maps.get(volume.getdriver())))
       val needUnquiesce = true;
        maps.foreach((driver, volumes) => needUnquiesce  = needUnquiesce  && 
driver.takeVMSnapshot(volumes))
      if (needUnquiesce ) {
       HypervisorHelper.unquiesce(vm);
    } 

By default, the quiesceVM in HypervisorHelper will actually take vm snapshot 
through hypervisor. 
Does above logic makes senesce?

The pros of option 1 is that: it's simple, no need to change storage driver 
interfaces. The cons is that each storage vendor need to implement a strategy, 
maybe they will do the same thing.
The pros of option 2 is that, storage driver won't need to worry about how to 
quiesce/unquiesce vm. The cons is that, it will add these methods on each 
storage drivers, so it assumes that this work flow will work for everybody.

So which option we should take? Or if you have other options, please let's 
know. 



   

Reply via email to