diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 9f113da227..bf629e6d32 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -418,6 +418,10 @@ IM_MAD = [ # overridden for each action. # Valid actions: deploy, shutdown, cancel, save, restore, migrate, poll # An example: "-l migrate=migrate_local,save" +# -p more than one action per host in parallel, needs support from hypervisor +# -s to execute remote commands, bash by default +# -d detach disks on running VMs before creating/reverting snaps, by default +# the VM will be suspended # # Note: You can use type = "qemu" to use qemu emulated guests, e.g. if your # CPU does not have virtualization extensions or use nested Qemu-KVM hosts @@ -438,8 +442,12 @@ VM_MAD = [ # overridden for each action. # Valid actions: deploy, shutdown, cancel, save, restore, migrate, poll # An example: "-l migrate,save" +# -p more than one action per host in parallel, needs support from hypervisor +# -s to execute commands, bash by default +# -d detach disks on running VMs before creating/reverting snaps, by default +# the VM will be suspended #------------------------------------------------------------------------------- - +# # Driver for Xen 3.x #VM_MAD = [ # name = "xen", @@ -447,7 +455,7 @@ VM_MAD = [ # arguments = "-t 15 -r 0 xen3", # default = "vmm_exec/vmm_exec_xen3.conf", # type = "xen" ] - +# # Driver for Xen 4.x #VM_MAD = [ # name = "xen", @@ -455,13 +463,17 @@ VM_MAD = [ # arguments = "-t 15 -r 0 xen4", # default = "vmm_exec/vmm_exec_xen4.conf", # type = "xen" ] - +# #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # VMware Virtualization Driver Manager Configuration # -r number of retries when monitoring a host # -t number of threads, i.e. number of hosts monitored at the same time +# -p more than one action per host in parallel, needs support from hypervisor +# -s to execute commands, bash by default +# -d detach disks on running VMs before creating/reverting snaps, by default +# the VM will be suspended #------------------------------------------------------------------------------- #VM_MAD = [ # name = "vmware", @@ -471,11 +483,14 @@ VM_MAD = [ # type = "vmware" ] #------------------------------------------------------------------------------- - #------------------------------------------------------------------------------- # vCenter Virtualization Driver Manager Configuration # -r number of retries when monitoring a host # -t number of threads, i.e. number of hosts monitored at the same time +# -p more than one action per host in parallel, needs support from hypervisor +# -s to execute commands, bash by default +# -d detach disks on running VMs before creating/reverting snaps, by default +# the VM will be suspended #------------------------------------------------------------------------------- #VM_MAD = [ # name = "vcenter", diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index 5eed956421..9c93c48437 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -1750,14 +1750,6 @@ int DispatchManager::disk_snapshot_revert( return -1; } - if (snaps->get_active_id() == snap_id) - { - error_str = "Snapshot is already the active one"; - - vm->unlock(); - return -1; - } - if (vm->set_snapshot_disk(did, snap_id) == -1) { vm->unlock(); diff --git a/src/vmm_mad/exec/one_vmm_exec.rb b/src/vmm_mad/exec/one_vmm_exec.rb index 408f0587fb..02aeddf73f 100755 --- a/src/vmm_mad/exec/one_vmm_exec.rb +++ b/src/vmm_mad/exec/one_vmm_exec.rb @@ -669,7 +669,6 @@ class ExecDriver < VirtualMachineDriver # SNAPSHOTCREATE action, creates a new system snapshot # def snapshot_create(id, drv_message) - action = ACTION[:snapshot_create] xml_data = decode(drv_message) host = xml_data.elements['HOST'].text @@ -689,7 +688,6 @@ class ExecDriver < VirtualMachineDriver # SNAPSHOTREVERT action, reverts to a system snapshot # def snapshot_revert(id, drv_message) - action = ACTION[:snapshot_revert] xml_data = decode(drv_message) host = xml_data.elements['HOST'].text @@ -709,7 +707,6 @@ class ExecDriver < VirtualMachineDriver # SNAPSHOTDELETE action, deletes a system snapshot # def snapshot_delete(id, drv_message) - action = ACTION[:snapshot_delete] xml_data = decode(drv_message) host = xml_data.elements['HOST'].text @@ -729,7 +726,6 @@ class ExecDriver < VirtualMachineDriver # CLEANUP action, frees resources allocated in a host: VM and disk images # def cleanup(id, drv_message) - aname = ACTION[:cleanup] xml_data = decode(drv_message) tm_command = xml_data.elements['TM_COMMAND'].text @@ -899,48 +895,56 @@ class ExecDriver < VirtualMachineDriver tm_rollback= xml_data.elements['TM_COMMAND_ROLLBACK'].text.strip target_xpath = "VM/TEMPLATE/DISK[DISK_SNAPSHOT_ACTIVE='YES']/TARGET" - target = ensure_xpath(xml_data, id, action, target_xpath) || return + target = ensure_xpath(xml_data, id, action, target_xpath) ||return target_index = target.downcase[-1..-1].unpack('c').first - 97 - disk = xml_data.elements[target_xpath] - attach = REXML::Element.new('ATTACH') - attach.add_text('YES') - disk.add(attach) + if @options[:detach_snap] + disk = xml_data.elements[target_xpath] + attach = REXML::Element.new('ATTACH') - drv_message = Base64.encode64(xml_data.to_s) + attach.add_text('YES') + disk.add(attach) + + drv_message = Base64.encode64(xml_data.to_s) + end action = VmmAction.new(self, id, :disk_snapshot_create, drv_message) + if @options[:detach_snap] + pre_action = :detach_disk + pre_params = [:deploy_id, :disk_target_path, target, target_index] + + post_action = :attach_disk + post_params = [:deploy_id, :disk_target_path, target, target_index, + drv_message] + else + pre_action = :save + pre_params = [:deploy_id, :checkpoint_file, :host] + + post_action = :restore + post_params = [:checkpoint_file, :host, :deploy_id] + end + steps = [ - # First detach the disk from the VM - #{ - # :driver => :vmm, - # :action => :detach_disk, - # :parameters => [ - # :deploy_id, - # :disk_target_path, - # target, - # target_index - # ] - #}, - # Save the Virtual Machine state + # Save VM state / detach the disk { :driver => :vmm, - :action => :save, - :parameters => [:deploy_id, :checkpoint_file, :host] + :action => pre_action, + :parameters => pre_params }, # Do the snapshot { :driver => :tm, :action => :tm_snap_create, - :parameters => tm_command.split + :parameters => tm_command.split, + :no_fail => true }, - # Restore the Virtual Machine from checkpoint + # Restore VM / attach the disk { :driver => :vmm, - :action => :restore, - :parameters => [:checkpoint_file, :host, :deploy_id], + :action => post_action, + :parameters => post_params, :fail_actions => [ { :driver => :tm, @@ -948,26 +952,7 @@ class ExecDriver < VirtualMachineDriver :parameters => tm_rollback.split } ] - }, - # Attach the disk again - #{ - # :driver => :vmm, - # :action => :attach_disk, - # :parameters => [ - # :deploy_id, - # :disk_target_path, - # target, - # target_index, - # drv_message - # ], - # :fail_actions => [ - # { - # :driver => :tm, - # :action => :tm_snap_delete, - # :parameters => tm_rollback.split - # } - # ] - #} + } ] action.run(steps) @@ -983,61 +968,57 @@ class ExecDriver < VirtualMachineDriver tm_command = ensure_xpath(xml_data, id, action, 'TM_COMMAND') || return target_xpath = "VM/TEMPLATE/DISK[DISK_SNAPSHOT_ACTIVE='YES']/TARGET" - target = ensure_xpath(xml_data, id, action, target_xpath) || return + target = ensure_xpath(xml_data, id, action, target_xpath) ||return target_index = target.downcase[-1..-1].unpack('c').first - 97 - disk = xml_data.elements[target_xpath] - attach = REXML::Element.new('ATTACH') - attach.add_text('YES') - disk.add(attach) + if @options[:detach_snap] + disk = xml_data.elements[target_xpath] + attach = REXML::Element.new('ATTACH') - drv_message = Base64.encode64(xml_data.to_s) + attach.add_text('YES') + disk.add(attach) + + drv_message = Base64.encode64(xml_data.to_s) + end action = VmmAction.new(self, id, :disk_snapshot_revert, drv_message) + if @options[:detach_snap] + pre_action = :detach_disk + pre_params = [:deploy_id, :disk_target_path, target, target_index] + + post_action = :attach_disk + post_params = [:deploy_id, :disk_target_path, target, target_index, + drv_message] + else + pre_action = :save + pre_params = [:deploy_id, :checkpoint_file, :host] + + post_action = :restore + post_params = [:checkpoint_file, :host, :deploy_id] + end + steps = [ - # First detach the disk from the VM - #{ - # :driver => :vmm, - # :action => :detach_disk, - # :parameters => [ - # :deploy_id, - # :disk_target_path, - # target, - # target_index - # ] - #}, - # Save the Virtual Machine state + # Save VM state / detach the disk { :driver => :vmm, - :action => :save, - :parameters => [:deploy_id, :checkpoint_file, :host] + :action => pre_action, + :parameters => pre_params }, # Do the snapshot { :driver => :tm, :action => :tm_snap_revert, - :parameters => tm_command.split + :parameters => tm_command.split, + :no_fail => true, }, - # Restore the Virtual Machine from checkpoint + # Restore VM / attach the disk { :driver => :vmm, - :action => :restore, - :parameters => [:checkpoint_file, :host, :deploy_id] - }, - # Attach the disk again - #{ - # :driver => :vmm, - # :action => :attach_disk, - # :parameters => [ - # :deploy_id, - # :disk_target_path, - # target, - # target_index, - # drv_message - # ] - #} + :action => post_action, + :parameters => post_params + } ] action.run(steps) @@ -1069,15 +1050,17 @@ opts = GetoptLong.new( [ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ], [ '--local', '-l', GetoptLong::REQUIRED_ARGUMENT ], [ '--shell', '-s', GetoptLong::REQUIRED_ARGUMENT ], - [ '--parallel', '-p', GetoptLong::NO_ARGUMENT ] + [ '--parallel', '-p', GetoptLong::NO_ARGUMENT ], + [ '--detach-snap','-d', GetoptLong::NO_ARGUMENT ] ) -hypervisor = '' -retries = 0 -threads = 15 -shell = 'bash' -local_actions = {} -single_host = true +hypervisor = '' +retries = 0 +threads = 15 +shell = 'bash' +local_actions = {} +single_host = true +detach_snap = false begin opts.each do |opt, arg| @@ -1092,6 +1075,8 @@ begin shell = arg when '--parallel' single_host = false + when '--detach-snap' + detach_snap = true end end rescue Exception => e @@ -1109,6 +1094,7 @@ exec_driver = ExecDriver.new(hypervisor, :retries => retries, :local_actions => local_actions, :shell => shell, - :single_host => single_host) + :single_host => single_host, + :detach_snap => detach_snap) exec_driver.start_driver