mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-01 20:58:18 +03:00
B #5131: Track VNC allocation across migration
(cherry picked from commit dd6a7f4cd6baad55d57c140c9d1ba057e5d1a9fe)
This commit is contained in:
parent
e8da3aea37
commit
26498959bc
@ -452,8 +452,8 @@ public:
|
||||
void replace(const std::string& name, const std::string& value);
|
||||
|
||||
/**
|
||||
* Removes given the vector attribute
|
||||
* @param name of the vector attribute
|
||||
* Removes the given attribute from the vector
|
||||
* @param name of the attribute
|
||||
*/
|
||||
void remove(const std::string& name);
|
||||
|
||||
|
@ -847,6 +847,19 @@ public:
|
||||
previous_history->req_id = rid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Release the previous VNC port when a VM is migrated to another cluster
|
||||
* (GRAPHICS/PREVIOUS_PORT present)
|
||||
*/
|
||||
void release_previous_vnc_port();
|
||||
|
||||
/**
|
||||
* Frees current PORT from **current** cluster and sets it to PREVIOUS_PORT
|
||||
* (which is allocated in previous cluster). This function is called when
|
||||
* the migration fails.
|
||||
*/
|
||||
void rollback_previous_vnc_port();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Template & Object Representation
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -325,6 +325,8 @@ void LifeCycleManager::trigger_migrate(int vid, const RequestAttributes& ra,
|
||||
if ( vm->get_hid() != vm->get_previous_hid() )
|
||||
{
|
||||
hpool->del_capacity(vm->get_previous_hid(), sr);
|
||||
|
||||
vm->release_previous_vnc_port();
|
||||
}
|
||||
|
||||
vm->set_stime(the_time);
|
||||
|
@ -62,6 +62,8 @@ void LifeCycleManager::start_prolog_migrate(VirtualMachine* vm)
|
||||
if ( vm->get_hid() != vm->get_previous_hid() )
|
||||
{
|
||||
hpool->del_capacity(vm->get_previous_hid(), sr);
|
||||
|
||||
vm->release_previous_vnc_port();
|
||||
}
|
||||
|
||||
vmpool->update(vm);
|
||||
@ -95,6 +97,8 @@ void LifeCycleManager::revert_migrate_after_failure(VirtualMachine* vm)
|
||||
if ( vm->get_hid() != vm->get_previous_hid() )
|
||||
{
|
||||
hpool->del_capacity(vm->get_hid(), sr);
|
||||
|
||||
vm->rollback_previous_vnc_port();
|
||||
}
|
||||
|
||||
vm->set_previous_etime(the_time);
|
||||
@ -275,6 +279,8 @@ void LifeCycleManager::trigger_deploy_success(int vid)
|
||||
vm->delete_snapshots();
|
||||
}
|
||||
|
||||
vm->release_previous_vnc_port();
|
||||
|
||||
vmpool->update(vm.get());
|
||||
}
|
||||
else if ( vm->get_lcm_state() == VirtualMachine::BOOT ||
|
||||
@ -353,6 +359,8 @@ void LifeCycleManager::trigger_deploy_failure(int vid)
|
||||
|
||||
hpool->del_capacity(vm->get_hid(), sr);
|
||||
|
||||
vm->rollback_previous_vnc_port();
|
||||
|
||||
// --- Add new record by copying the previous one
|
||||
|
||||
vm->cp_previous_history();
|
||||
|
@ -705,6 +705,52 @@ int set_vnc_port(VirtualMachine *vm, int cluster_id, RequestAttributes& att)
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int set_migrate_vnc_port(VirtualMachine *vm, int cluster_id, bool keep)
|
||||
{
|
||||
ClusterPool * cpool = Nebula::instance().get_clpool();
|
||||
|
||||
VectorAttribute * graphics = vm->get_template_attribute("GRAPHICS");
|
||||
|
||||
unsigned int previous_port;
|
||||
unsigned int port;
|
||||
|
||||
int rc;
|
||||
|
||||
// Do not update VM if no GRAPHICS or GRAPHICS/PORT defined
|
||||
if (graphics == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (graphics->vector_value("PORT", previous_port) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//live migrations need to keep VNC port
|
||||
if (keep)
|
||||
{
|
||||
rc = cpool->set_vnc_port(cluster_id, previous_port);
|
||||
|
||||
port = previous_port;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = cpool->get_vnc_port(cluster_id, vm->get_oid(), port);
|
||||
}
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
graphics->replace("PREVIOUS_PORT", previous_port);
|
||||
graphics->replace("PORT", port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -1015,6 +1061,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
|
||||
PoolObjectAuth * auth_ds_perms;
|
||||
|
||||
int c_hid;
|
||||
int c_cluster_id;
|
||||
int c_ds_id;
|
||||
string c_tm_mad, tm_mad;
|
||||
bool c_is_public_cloud;
|
||||
@ -1211,6 +1258,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
|
||||
if (auto host = nd.get_hpool()->get_ro(c_hid))
|
||||
{
|
||||
c_is_public_cloud = host->is_public_cloud();
|
||||
c_cluster_id = host->get_cluster_id();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1221,7 +1269,6 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!cluster_ids.empty() && cluster_ids.count(cluster_id) == 0)
|
||||
{
|
||||
ostringstream oss;
|
||||
@ -1301,7 +1348,8 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "Cannot migrate VM [" << id << "] to host [" << hid << "] and system datastore [" << ds_id << "]. Host is in cluster ["
|
||||
oss << "Cannot migrate VM [" << id << "] to host [" << hid
|
||||
<< "] and system datastore [" << ds_id << "]. Host is in cluster ["
|
||||
<< cluster_id << "], and the datastore is in cluster ["
|
||||
<< one_util::join(ds_cluster_ids, ',') << "]";
|
||||
|
||||
@ -1311,6 +1359,20 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
|
||||
return;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Request a new VNC port in the new cluster
|
||||
// -------------------------------------------------------------------------
|
||||
if ( c_cluster_id != cluster_id )
|
||||
{
|
||||
if ( set_migrate_vnc_port(vm.get(), cluster_id, live) == -1 )
|
||||
{
|
||||
att.resp_msg = "No free VNC port available in the new cluster";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Add a new history record and update volatile DISK attributes
|
||||
// ------------------------------------------------------------------------
|
||||
@ -1334,7 +1396,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
|
||||
// Migrate the VM
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (live == true && vm->get_lcm_state() == VirtualMachine::RUNNING )
|
||||
if (live && vm->get_lcm_state() == VirtualMachine::RUNNING )
|
||||
{
|
||||
dm->live_migrate(vm.get(), att);
|
||||
}
|
||||
|
@ -3623,3 +3623,49 @@ void VirtualMachine::get_quota_template(VirtualMachineTemplate& quota_tmpl,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachine::release_previous_vnc_port()
|
||||
{
|
||||
ClusterPool * cpool = Nebula::instance().get_clpool();
|
||||
|
||||
VectorAttribute * graphics = get_template_attribute("GRAPHICS");
|
||||
|
||||
unsigned int previous_port;
|
||||
|
||||
if (graphics == nullptr ||
|
||||
graphics->vector_value("PREVIOUS_PORT", previous_port) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cpool->release_vnc_port(previous_history->cid, previous_port);
|
||||
|
||||
graphics->remove("PREVIOUS_PORT");
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachine::rollback_previous_vnc_port()
|
||||
{
|
||||
ClusterPool * cpool = Nebula::instance().get_clpool();
|
||||
|
||||
VectorAttribute * graphics = get_template_attribute("GRAPHICS");
|
||||
|
||||
unsigned int previous_port;
|
||||
unsigned int port;
|
||||
|
||||
if (graphics == nullptr ||
|
||||
graphics->vector_value("PREVIOUS_PORT", previous_port) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( graphics->vector_value("PORT", port) == 0 )
|
||||
{
|
||||
cpool->release_vnc_port(history->cid, port);
|
||||
}
|
||||
|
||||
graphics->replace("PORT", previous_port);
|
||||
|
||||
graphics->remove("PREVIOUS_PORT");
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user