diff --git a/include/TransferManager.h b/include/TransferManager.h index 6b08f3d73b..30c4088825 100644 --- a/include/TransferManager.h +++ b/include/TransferManager.h @@ -128,6 +128,15 @@ public: VirtualMachine * vm, const VectorAttribute * disk, ostream& xfr); + /** + * Inserts a transfer command in the xfs stream, for live migration + * + * @param vm The VM + * @param xfr Stream where the transfer command will be written + */ + void migrate_transfer_command( + VirtualMachine * vm, + ostream& xfr); private: /** diff --git a/install.sh b/install.sh index 1f11ba740f..cc46ee6986 100755 --- a/install.sh +++ b/install.sh @@ -840,6 +840,8 @@ TM_SHARED_FILES="src/tm_mad/shared/clone \ src/tm_mad/shared/mkimage \ src/tm_mad/shared/mv \ src/tm_mad/shared/context \ + src/tm_mad/shared/premigrate \ + src/tm_mad/shared/postmigrate \ src/tm_mad/shared/mvds" TM_QCOW2_FILES="src/tm_mad/qcow2/clone \ @@ -849,6 +851,8 @@ TM_QCOW2_FILES="src/tm_mad/qcow2/clone \ src/tm_mad/qcow2/mkimage \ src/tm_mad/qcow2/mv \ src/tm_mad/qcow2/context \ + src/tm_mad/qcow2/premigrate \ + src/tm_mad/qcow2/postmigrate \ src/tm_mad/qcow2/mvds" TM_SSH_FILES="src/tm_mad/ssh/clone \ @@ -858,6 +862,8 @@ TM_SSH_FILES="src/tm_mad/ssh/clone \ src/tm_mad/ssh/mkimage \ src/tm_mad/ssh/mv \ src/tm_mad/ssh/context \ + src/tm_mad/ssh/premigrate \ + src/tm_mad/ssh/postmigrate \ src/tm_mad/ssh/mvds" TM_DUMMY_FILES="src/tm_mad/dummy/clone \ @@ -867,6 +873,8 @@ TM_DUMMY_FILES="src/tm_mad/dummy/clone \ src/tm_mad/dummy/mkimage \ src/tm_mad/dummy/mv \ src/tm_mad/dummy/context \ + src/tm_mad/dummy/premigrate \ + src/tm_mad/dummy/postmigrate \ src/tm_mad/dummy/mvds" TM_VMWARE_FILES="src/tm_mad/vmware/clone \ @@ -876,18 +884,24 @@ TM_VMWARE_FILES="src/tm_mad/vmware/clone \ src/tm_mad/vmware/mkimage \ src/tm_mad/vmware/mv \ src/tm_mad/vmware/context \ + src/tm_mad/vmware/premigrate \ + src/tm_mad/vmware/postmigrate \ src/tm_mad/vmware/mvds" TM_ISCSI_FILES="src/tm_mad/iscsi/clone \ src/tm_mad/iscsi/ln \ src/tm_mad/iscsi/mv \ src/tm_mad/iscsi/mvds \ + src/tm_mad/iscsi/premigrate \ + src/tm_mad/iscsi/postmigrate \ src/tm_mad/iscsi/delete" TM_LVM_FILES="src/tm_mad/lvm/clone \ src/tm_mad/lvm/ln \ src/tm_mad/lvm/mv \ src/tm_mad/lvm/mvds \ + src/tm_mad/lvm/premigrate \ + src/tm_mad/lvm/postmigrate \ src/tm_mad/lvm/delete" #------------------------------------------------------------------------------- diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index d31f81cd2e..df45927b92 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -224,8 +224,12 @@ int TransferManager::prolog_transfer_command( string format; string tm_mad; string ds_id; + string vm_ds_id; + int disk_index; + vm_ds_id = vm->get_ds_id(); + disk->vector_value("DISK_ID", disk_index); type = disk->vector_value("TYPE"); @@ -253,7 +257,7 @@ int TransferManager::prolog_transfer_command( << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << disk_index << " " << vm->get_oid() << " " - << "0" + << vm_ds_id << endl; } else if ( type == "FS" ) @@ -279,7 +283,7 @@ int TransferManager::prolog_transfer_command( << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << disk_index << " " << vm->get_oid() << " " - << "0" + << vm_ds_id << endl; } else @@ -386,8 +390,8 @@ void TransferManager::prolog_action(int vid) goto error_history; } - vm_tm_mad = vm->get_tm_mad(); - tm_md = get(); + vm_tm_mad = vm->get_tm_mad(); + tm_md = get(); if ( tm_md == 0 || vm_tm_mad.empty() ) { @@ -455,7 +459,8 @@ void TransferManager::prolog_action(int vid) xfr << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << num << " " << vm->get_oid() << " " - << "0" << endl; + << vm->get_ds_id() + << endl; } xfr.close(); @@ -1457,6 +1462,25 @@ void TransferManager::checkpoint_action(int vid) } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void TransferManager::migrate_transfer_command( + VirtualMachine * vm, + ostream& xfr) +{ + // tm_mad SOURCE DST remote_system_dir vmid dsid + + xfr << "MIGRATE " //TM action PRE or POST to be completed by VMM driver + << vm->get_tm_mad() << " " + << vm->get_hostname() << " " + << vm->get_previous_hostname() << " " + << vm->get_remote_system_dir() << " " + << vm->get_oid() << " " + << vm->get_ds_id() + << endl; +} + /* ************************************************************************** */ /* MAD Loading */ /* ************************************************************************** */ diff --git a/src/tm_mad/common/postmigrate b/src/tm_mad/common/postmigrate new file mode 100755 index 0000000000..f368a8bfa9 --- /dev/null +++ b/src/tm_mad/common/postmigrate @@ -0,0 +1,29 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # +# POSTMIGRATE SOURCE DST remote_system_dir vmid dsid template +# - SOURCE is the host where the VM is running +# - DST is the host where the VM is to be migrated +# - remote_system_dir is the path for the VM home in the system datastore +# - vmid is the id of the VM +# - dsid is the target datastore +# - template is the template of the VM in XML and base64 encoded + +# To access the vm_template you can use the xpath.rb utility. Check the +# datastore drivers for an example. + +exit 0 diff --git a/src/tm_mad/common/premigrate b/src/tm_mad/common/premigrate new file mode 100755 index 0000000000..cbc203c210 --- /dev/null +++ b/src/tm_mad/common/premigrate @@ -0,0 +1,29 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # +# PREMIGRATE SOURCE DST remote_system_dir vmid dsid template +# - SOURCE is the host where the VM is running +# - DST is the host where the VM is to be migrated +# - remote_system_dir is the path for the VM home in the system datastore +# - vmid is the id of the VM +# - dsid is the target datastore +# - template is the template of the VM in XML and base64 encoded + +# To access the vm_template you can use the xpath.rb utility. Check the +# datastore drivers for an example. + +exit 0 diff --git a/src/tm_mad/dummy/postmigrate b/src/tm_mad/dummy/postmigrate new file mode 120000 index 0000000000..300563f2ad --- /dev/null +++ b/src/tm_mad/dummy/postmigrate @@ -0,0 +1 @@ +../common/dummy.sh \ No newline at end of file diff --git a/src/tm_mad/dummy/premigrate b/src/tm_mad/dummy/premigrate new file mode 120000 index 0000000000..300563f2ad --- /dev/null +++ b/src/tm_mad/dummy/premigrate @@ -0,0 +1 @@ +../common/dummy.sh \ No newline at end of file diff --git a/src/tm_mad/iscsi/postmigrate b/src/tm_mad/iscsi/postmigrate new file mode 120000 index 0000000000..d580dd8260 --- /dev/null +++ b/src/tm_mad/iscsi/postmigrate @@ -0,0 +1 @@ +../common/postmigrate \ No newline at end of file diff --git a/src/tm_mad/iscsi/premigrate b/src/tm_mad/iscsi/premigrate new file mode 120000 index 0000000000..0e108a8a26 --- /dev/null +++ b/src/tm_mad/iscsi/premigrate @@ -0,0 +1 @@ +../common/premigrate \ No newline at end of file diff --git a/src/tm_mad/lvm/postmigrate b/src/tm_mad/lvm/postmigrate new file mode 120000 index 0000000000..d580dd8260 --- /dev/null +++ b/src/tm_mad/lvm/postmigrate @@ -0,0 +1 @@ +../common/postmigrate \ No newline at end of file diff --git a/src/tm_mad/lvm/premigrate b/src/tm_mad/lvm/premigrate new file mode 120000 index 0000000000..0e108a8a26 --- /dev/null +++ b/src/tm_mad/lvm/premigrate @@ -0,0 +1 @@ +../common/premigrate \ No newline at end of file diff --git a/src/tm_mad/qcow2/postmigrate b/src/tm_mad/qcow2/postmigrate new file mode 120000 index 0000000000..d580dd8260 --- /dev/null +++ b/src/tm_mad/qcow2/postmigrate @@ -0,0 +1 @@ +../common/postmigrate \ No newline at end of file diff --git a/src/tm_mad/qcow2/premigrate b/src/tm_mad/qcow2/premigrate new file mode 120000 index 0000000000..0e108a8a26 --- /dev/null +++ b/src/tm_mad/qcow2/premigrate @@ -0,0 +1 @@ +../common/premigrate \ No newline at end of file diff --git a/src/tm_mad/shared/postmigrate b/src/tm_mad/shared/postmigrate new file mode 120000 index 0000000000..d580dd8260 --- /dev/null +++ b/src/tm_mad/shared/postmigrate @@ -0,0 +1 @@ +../common/postmigrate \ No newline at end of file diff --git a/src/tm_mad/shared/premigrate b/src/tm_mad/shared/premigrate new file mode 120000 index 0000000000..0e108a8a26 --- /dev/null +++ b/src/tm_mad/shared/premigrate @@ -0,0 +1 @@ +../common/premigrate \ No newline at end of file diff --git a/src/tm_mad/ssh/postmigrate b/src/tm_mad/ssh/postmigrate new file mode 120000 index 0000000000..d580dd8260 --- /dev/null +++ b/src/tm_mad/ssh/postmigrate @@ -0,0 +1 @@ +../common/postmigrate \ No newline at end of file diff --git a/src/tm_mad/ssh/premigrate b/src/tm_mad/ssh/premigrate new file mode 120000 index 0000000000..0e108a8a26 --- /dev/null +++ b/src/tm_mad/ssh/premigrate @@ -0,0 +1 @@ +../common/premigrate \ No newline at end of file diff --git a/src/tm_mad/vmware/postmigrate b/src/tm_mad/vmware/postmigrate new file mode 120000 index 0000000000..d580dd8260 --- /dev/null +++ b/src/tm_mad/vmware/postmigrate @@ -0,0 +1 @@ +../common/postmigrate \ No newline at end of file diff --git a/src/tm_mad/vmware/premigrate b/src/tm_mad/vmware/premigrate new file mode 120000 index 0000000000..0e108a8a26 --- /dev/null +++ b/src/tm_mad/vmware/premigrate @@ -0,0 +1 @@ +../common/premigrate \ No newline at end of file diff --git a/src/vmm/VirtualMachineManager.cc b/src/vmm/VirtualMachineManager.cc index 7a13d15444..4e75086489 100644 --- a/src/vmm/VirtualMachineManager.cc +++ b/src/vmm/VirtualMachineManager.cc @@ -337,13 +337,20 @@ string * VirtualMachineManager::format_message( if ( !tm_command.empty() ) { - oss << "" - << ""<< disk_target_path << ""; + oss << ""; } else { - oss << "" - << ""; + oss << ""; + } + + if ( !disk_target_path.empty() ) + { + oss << ""<< disk_target_path << ""; + } + else + { + oss << ""; } oss << tmpl @@ -954,6 +961,8 @@ void VirtualMachineManager::migrate_action( goto error_previous_history; } + Nebula::instance().get_tm()->migrate_transfer_command(vm, os); + // Invoke driver method drv_msg = format_message( vm->get_previous_hostname(), @@ -964,7 +973,7 @@ void VirtualMachineManager::migrate_action( "", "", "", - "", + os.str(), "", vm->to_xml(vm_tmpl)); diff --git a/src/vmm_mad/exec/one_vmm_exec.rb b/src/vmm_mad/exec/one_vmm_exec.rb index 943ee34932..b315bbac96 100755 --- a/src/vmm_mad/exec/one_vmm_exec.rb +++ b/src/vmm_mad/exec/one_vmm_exec.rb @@ -75,6 +75,9 @@ class VmmAction get_data(:disk_target_path) get_data(:tm_command) + # VM template + @data[:vm] = Base64.encode64(@xml_data.elements['VM'].to_s).delete("\n") + # Initialize streams and vnm @ssh_src = @vmm.get_ssh_stream(action, @data[:host], @id) @vnm_src = VirtualNetworkDriver.new(@data[:net_drv], @@ -438,9 +441,20 @@ class ExecDriver < VirtualMachineDriver # MIGRATE (live) action, migrates a VM to another host creating network # def migrate(id, drv_message) - action=VmmAction.new(self, id, :migrate, drv_message) + action = VmmAction.new(self, id, :migrate, drv_message) + pre = "PRE" + post = "POST" + pre << action.data[:tm_command] << " " << action.data[:vm] + post << action.data[:tm_command] << " " << action.data[:vm] + steps=[ + # Execute a pre-migrate TM setup + { + :driver => :tm, + :action => :tm_premigrate, + :parameters => pre.split + }, # Execute pre-boot networking setup on migrating host { :driver => :vnm, @@ -466,6 +480,12 @@ class ExecDriver < VirtualMachineDriver :destination => :true #TODO :fail_action what to do here? cancel VM? }, + { + :driver => :tm, + :action => :tm_postmigrate, + :parameters => post.split + #TODO :fail_action what to do here? cancel VM? + }, ] action.run(steps)