1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-25 02:50:08 +03:00

Merge branch 'master' of git.opennebula.org:one

This commit is contained in:
Jaime Melis 2012-07-03 18:07:01 +02:00
commit f377603649
44 changed files with 956 additions and 307 deletions

View File

@ -20,6 +20,7 @@
#include "PoolSQL.h"
#include "ObjectCollection.h"
#include "DatastorePool.h"
#include "ClusterTemplate.h"
using namespace std;
@ -30,6 +31,23 @@ class Cluster : public PoolObjectSQL
{
public:
/**
* Returns the SYSTEM_DS attribute, or the system DS id if it is not defined
*
* @return the SYSTEM_DS attribute, or the system DS id if it is not defined
*/
int get_ds_id()
{
int ds_id;
if ( obj_template->get("SYSTEM_DS", ds_id) == false )
{
ds_id = DatastorePool::SYSTEM_DS_ID;
}
return ds_id;
}
// *************************************************************************
// Object Collections (Public)
// *************************************************************************
@ -78,6 +96,7 @@ public:
*/
int add_datastore(int id, string& error_msg)
{
// TODO: should fail for any system DS?
if ( id == DatastorePool::SYSTEM_DS_ID )
{
ostringstream oss;
@ -184,11 +203,9 @@ private:
// Constructor
// *************************************************************************
Cluster(int id, const string& name):
PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table),
hosts("HOSTS"),
datastores("DATASTORES"),
vnets("VNETS"){};
Cluster(int id,
const string& name,
ClusterTemplate* cl_template);
virtual ~Cluster(){};
@ -259,6 +276,14 @@ private:
* @return 0 if cluster can be dropped, -1 otherwise
*/
int check_drop(string& error_msg);
/**
* Factory method for cluster templates
*/
Template * get_new_template() const
{
return new ClusterTemplate;
}
};
#endif /*CLUSTER_H_*/

View File

@ -151,7 +151,7 @@ private:
*/
PoolObjectSQL * create()
{
return new Cluster(-1,"");
return new Cluster(-1,"",0);
};
};

39
include/ClusterTemplate.h Normal file
View File

@ -0,0 +1,39 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
#ifndef CLUSTER_TEMPLATE_H_
#define CLUSTER_TEMPLATE_H_
#include "Template.h"
using namespace std;
/**
* Cluster Template class
*/
class ClusterTemplate : public Template
{
public:
ClusterTemplate():
Template(false,'=',"TEMPLATE"){};
~ClusterTemplate(){};
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#endif /*CLUSTER_TEMPLATE_H_*/

View File

@ -91,6 +91,16 @@ public:
{
return disk_type;
};
/**
* Returns true if this is a system datastore
* @return true if this is a system datastore
*/
bool is_system() const
{
return system_ds == 1;
};
/**
* Modifies the given VM disk attribute adding the relevant datastore
* attributes
@ -134,6 +144,11 @@ private:
*/
string base_path;
/**
* 1 if this is a system DS
*/
int system_ds;
/**
* Disk types for the Images created in this datastore
*/
@ -203,7 +218,7 @@ private:
}
/**
* Factory method for virtual network templates
* Factory method for datastore templates
*/
Template * get_new_template() const
{

View File

@ -46,6 +46,8 @@ public:
const string& hostname,
const string& vmm,
const string& vnm,
const string& tmm,
int ds_id,
const string& vm_info);
~History(){};
@ -89,6 +91,9 @@ private:
string vmm_mad_name;
string vnm_mad_name;
string tm_mad_name;
int ds_id;
time_t stime;
time_t etime;

View File

@ -243,30 +243,6 @@ public:
return ds_location;
};
/**
* Returns the Transfer Manager for the system datastore
* @return the tm name.
*/
string get_system_ds_tm_mad()
{
Datastore * ds;
string tm_mad = "";
ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true);
if ( ds == 0 )
{
NebulaLog::log("DaS", Log::ERROR, "Can not get system datastore");
return tm_mad;
}
tm_mad = ds->get_tm_mad();
ds->unlock();
return tm_mad;
};
/**
* Returns the path of the log file for a VM, depending where OpenNebula is
* installed,

View File

@ -170,6 +170,24 @@ public:
~DocumentUpdateTemplate(){};
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class ClusterUpdateTemplate : public RequestManagerUpdateTemplate
{
public:
ClusterUpdateTemplate():
RequestManagerUpdateTemplate("ClusterUpdateTemplate",
"Updates a cluster template")
{
Nebula& nd = Nebula::instance();
pool = nd.get_clpool();
auth_object = PoolObjectSQL::CLUSTER;
};
~ClusterUpdateTemplate(){};
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -57,13 +57,16 @@ protected:
AuthRequest::Operation op);
int get_host_information(int hid, string& name, string& vmm, string& vnm,
RequestAttributes& att, PoolObjectAuth& host_perms);
string& tm, int& ds_id, RequestAttributes& att,
PoolObjectAuth& host_perms);
int add_history(VirtualMachine * vm,
int hid,
const string& hostname,
const string& vmm_mad,
const string& vnm_mad,
const string& tm_mad,
int ds_id,
RequestAttributes& att);
VirtualMachine * get_vm(int id, RequestAttributes& att);

View File

@ -242,7 +242,9 @@ public:
int hid,
const string& hostname,
const string& vmm_mad,
const string& vnm_mad);
const string& vnm_mad,
const string& tm_mad,
int ds_id);
/**
* Duplicates the last history record. Only the host related fields are
@ -318,6 +320,55 @@ public:
return previous_history->vnm_mad_name;
};
/**
* Returns the datastore ID of the system DS for the host. The hasHistory()
* function MUST be called before this one.
* @return the ds id
*/
string get_ds_id() const
{
ostringstream oss;
oss << history->ds_id;
return oss.str();
};
/**
* Returns the datastore ID of the system DS for the previous host.
* The hasPreviousHistory() function MUST be called before this one.
* @return the TM mad name
*/
string get_previous_ds_id() const
{
ostringstream oss;
oss << previous_history->ds_id;
return oss.str();
};
/**
* Returns the TM driver name for the current host. The hasHistory()
* function MUST be called before this one.
* @return the TM mad name
*/
const string & get_tm_mad() const
{
return history->tm_mad_name;
};
/**
* Returns the TM driver name for the previous host. The
* hasPreviousHistory() function MUST be called before this one.
* @return the TM mad name
*/
const string & get_previous_tm_mad() const
{
return previous_history->tm_mad_name;
};
/**
* Returns the transfer filename. The transfer file is in the form:
* $ONE_LOCATION/var/$VM_ID/transfer.$SEQ

View File

@ -925,6 +925,7 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \
src/onedb/3.3.80_to_3.4.0.rb \
src/onedb/3.4.0_to_3.4.1.rb \
src/onedb/3.4.1_to_3.5.80.rb \
src/onedb/3.5.80_to_3.6.0.rb \
src/onedb/onedb.rb \
src/onedb/onedb_backend.rb"

View File

@ -21,6 +21,8 @@
<xs:element name="ETIME" type="xs:integer"/>
<xs:element name="VMMMAD" type="xs:string"/>
<xs:element name="VNMMAD" type="xs:string"/>
<xs:element name="TMMAD" type="xs:string"/>
<xs:element name="DS_ID" type="xs:integer"/>
<xs:element name="PSTIME" type="xs:integer"/>
<xs:element name="PETIME" type="xs:integer"/>
<xs:element name="RSTIME" type="xs:integer"/>

View File

@ -27,6 +27,7 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="TEMPLATE" type="xs:anyType"/>
</xs:sequence>
</xs:complexType>
</xs:element>

View File

@ -28,6 +28,7 @@
<xs:element name="DS_MAD" type="xs:string"/>
<xs:element name="TM_MAD" type="xs:string"/>
<xs:element name="BASE_PATH" type="xs:string"/>
<xs:element name="SYSTEM" type="xs:integer"/>
<xs:element name="DISK_TYPE" type="xs:integer"/>
<xs:element name="CLUSTER_ID" type="xs:integer"/>
<xs:element name="CLUSTER" type="xs:string"/>

View File

@ -33,8 +33,8 @@ onegroup create newgroup
# Host
onehost create host01 --im im_test --vm vmm_test --net dummy
onehost create host02 --im im_test --vm vmm_test --net dummy
onehost create host01 --im im_dummy --vm vmm_dummy --net dummy
onehost create host02 --im im_dummy --vm vmm_dummy --net dummy
onecluster addhost newcluster host02

View File

@ -95,6 +95,8 @@
<xs:element name="ETIME" type="xs:integer"/>
<xs:element name="VMMMAD" type="xs:string"/>
<xs:element name="VNMMAD" type="xs:string"/>
<xs:element name="TMMAD" type="xs:string"/>
<xs:element name="DS_ID" type="xs:integer"/>
<xs:element name="PSTIME" type="xs:integer"/>
<xs:element name="PETIME" type="xs:integer"/>
<xs:element name="RSTIME" type="xs:integer"/>

View File

@ -99,6 +99,11 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper
puts str % ["NAME", cluster.name]
puts
CLIHelper.print_header(str_h1 % "CLUSTER TEMPLATE", false)
puts cluster.template_str
puts
CLIHelper.print_header("%-15s" % ["HOSTS"])
cluster.host_ids.each do |id|
puts "%-15s" % [id]

View File

@ -173,4 +173,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do
cluster.delvnet(args[1].to_i)
end
end
update_desc = <<-EOT.unindent
Update the template contents. If a path is not provided the editor will
be launched to modify the current content.
EOT
command :update, update_desc, :clusterid, [:file, nil] do
helper.perform_action(args[0],options,"modified") do |obj|
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
obj.update(str)
end
end
end

View File

@ -45,6 +45,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do
:description => "Type of the new Image"
}
TARGET={
:name => "target",
:short => "-t type",
:large => "--target type",
:format => String,
:description => "Device where the image will be attached"
}
########################################################################
# Global Options
########################################################################
@ -345,7 +353,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
EOT
command :attachdisk, attachdisk_desc, :vmid,
:options => [OneVMHelper::FILE, OneVMHelper::IMAGE] do
:options => [OneVMHelper::FILE, OneVMHelper::IMAGE, TARGET] do
if options[:file].nil? and options[:image].nil?
STDERR.puts "Provide a template file or an image:"
@ -358,7 +366,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do
template = File.read(options[:file])
else
image_id = options[:image]
template = "DISK = [ IMAGE_ID = #{image_id}, DEV_PREFIX = sd ]"
target = options[:target]
if target
template =
"DISK = [ IMAGE_ID = #{image_id}, TARGET = #{target} ]"
else
template =
"DISK = [ IMAGE_ID = #{image_id}, DEV_PREFIX = sd ]"
end
end
helper.perform_action(args[0],options,"Attach disk") do |vm|

View File

@ -33,6 +33,29 @@ const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool ("
"gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, "
"UNIQUE(name))";
/* ************************************************************************ */
/* Cluster :: Constructor/Destructor */
/* ************************************************************************ */
Cluster::Cluster(
int id,
const string& name,
ClusterTemplate* cl_template):
PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table),
hosts("HOSTS"),
datastores("DATASTORES"),
vnets("VNETS")
{
if (cl_template != 0)
{
obj_template = cl_template;
}
else
{
obj_template = new ClusterTemplate;
}
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
@ -170,6 +193,7 @@ string& Cluster::to_xml(string& xml) const
string host_collection_xml;
string ds_collection_xml;
string vnet_collection_xml;
string template_xml;
oss <<
"<CLUSTER>" <<
@ -179,7 +203,7 @@ string& Cluster::to_xml(string& xml) const
hosts.to_xml(host_collection_xml) <<
datastores.to_xml(ds_collection_xml) <<
vnets.to_xml(vnet_collection_xml) <<
obj_template->to_xml(template_xml) <<
"</CLUSTER>";
xml = oss.str();
@ -256,6 +280,18 @@ int Cluster::from_xml(const string& xml)
ObjectXML::free_nodes(content);
content.clear();
// Get associated classes
ObjectXML::get_nodes("/CLUSTER/TEMPLATE", content);
if (content.empty())
{
return -1;
}
rc += obj_template->from_xml_node(content[0]);
ObjectXML::free_nodes(content);
if (rc != 0)
{
return -1;

View File

@ -72,7 +72,7 @@ int ClusterPool::allocate(string name, int * oid, string& error_str)
}
// Build a new Cluster object
cluster = new Cluster(-1, name);
cluster = new Cluster(-1, name, 0);
// Insert the Object in the pool
*oid = PoolSQL::allocate(cluster, error_str);

View File

@ -19,6 +19,8 @@
#include "NebulaLog.h"
#include "Nebula.h"
#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper)
const char * Datastore::table = "datastore_pool";
const char * Datastore::db_names =
@ -47,7 +49,8 @@ Datastore::Datastore(
Clusterable(cluster_id, cluster_name),
ds_mad(""),
tm_mad(""),
base_path("")
base_path(""),
system_ds(0)
{
group_u = 1;
@ -97,6 +100,7 @@ int Datastore::insert(SqlDB *db, string& error_str)
int rc;
ostringstream oss;
string s_disk_type;
string s_system_ds;
Nebula& nd = Nebula::instance();
@ -108,8 +112,22 @@ int Datastore::insert(SqlDB *db, string& error_str)
// NAME is checked in DatastorePool::allocate
get_template_attribute("DS_MAD", ds_mad);
get_template_attribute("SYSTEM", s_system_ds);
if ( ds_mad.empty() == true )
TO_UPPER(s_system_ds);
system_ds = (s_system_ds == "YES");
if ( system_ds == 1 )
{
if ( !ds_mad.empty() )
{
goto error_exclusive;
}
ds_mad = "-";
}
else if ( ds_mad.empty() == true )
{
goto error_ds;
}
@ -152,6 +170,10 @@ int Datastore::insert(SqlDB *db, string& error_str)
return rc;
error_exclusive:
error_str = "SYSTEM datastores cannot have DS_MAD defined.";
goto error_common;
error_ds:
error_str = "No DS_MAD in template.";
goto error_common;
@ -273,6 +295,7 @@ string& Datastore::to_xml(string& xml) const
"<DS_MAD>" << ds_mad << "</DS_MAD>" <<
"<TM_MAD>" << tm_mad << "</TM_MAD>" <<
"<BASE_PATH>" << base_path << "</BASE_PATH>" <<
"<SYSTEM>" << system_ds << "</SYSTEM>" <<
"<DISK_TYPE>" << disk_type << "</DISK_TYPE>" <<
"<CLUSTER_ID>" << cluster_id << "</CLUSTER_ID>" <<
"<CLUSTER>" << cluster << "</CLUSTER>" <<
@ -307,6 +330,7 @@ int Datastore::from_xml(const string& xml)
rc += xpath(ds_mad, "/DATASTORE/DS_MAD", "not_found");
rc += xpath(tm_mad, "/DATASTORE/TM_MAD", "not_found");
rc += xpath(base_path, "/DATASTORE/BASE_PATH", "not_found");
rc += xpath(system_ds, "/DATASTORE/SYSTEM", -1);
rc += xpath(int_disk_type,"/DATASTORE/DISK_TYPE", -1);
rc += xpath(cluster_id, "/DATASTORE/CLUSTER_ID", -1);
@ -354,14 +378,15 @@ int Datastore::from_xml(const string& xml)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Datastore::replace_template(const string& tmpl_str, string& error)
int Datastore::replace_template(const string& tmpl_str, string& error_str)
{
string new_ds_mad;
string new_tm_mad;
string s_system_ds;
int rc;
rc = PoolObjectSQL::replace_template(tmpl_str, error);
rc = PoolObjectSQL::replace_template(tmpl_str, error_str);
if ( rc != 0 )
{
@ -369,15 +394,37 @@ int Datastore::replace_template(const string& tmpl_str, string& error)
}
get_template_attribute("DS_MAD", new_ds_mad);
get_template_attribute("SYSTEM", s_system_ds);
if ( oid == DatastorePool::SYSTEM_DS_ID )
{
system_ds = 1;
}
else if ( !s_system_ds.empty() )
{
TO_UPPER(s_system_ds);
system_ds = (s_system_ds == "YES");
}
if ( system_ds == 1 )
{
replace_template_attribute("SYSTEM", "YES");
new_ds_mad = "-";
}
else
{
obj_template->erase("SYSTEM");
}
if ( !new_ds_mad.empty() )
{
ds_mad = new_ds_mad;
}
else
{
replace_template_attribute("DS_MAD", ds_mad);
}
replace_template_attribute("DS_MAD", ds_mad);
get_template_attribute("TM_MAD", new_tm_mad);

View File

@ -53,7 +53,7 @@ DatastorePool::DatastorePool(SqlDB * db):
// ---------------------------------------------------------------------
oss << "NAME = " << SYSTEM_DS_NAME << endl
<< "DS_MAD = -" << endl
<< "SYSTEM = YES" << endl
<< "TM_MAD = shared";
ds_tmpl = new DatastoreTemplate;

View File

@ -148,8 +148,8 @@ if vm_ids_array
end
end
# 80% of the total free calculated memory to take hypervisor into account
free_memory = ($total_memory.to_i - used_memory) * 0.8
# Scheduler will take hypervisor memory usage into account
free_memory = ($total_memory.to_i - used_memory)
# assume all the host's CPU is devoted to running Virtual Machines
free_cpu = ($total_cpu.to_f - used_cpu)

View File

@ -138,6 +138,24 @@ static void cp_action(istringstream& is,
if ( image == 0 )
{
if (result == "SUCCESS")
{
ostringstream oss;
if ( is.good())
{
is >> source >> ws;
}
if (!source.empty())
{
oss << "CP operation succeeded but image no longer exists."
<< " Source image: " << source << ", may be left in datastore";
NebulaLog::log("ImM", Log::ERROR, oss);
}
}
return;
}
@ -224,6 +242,24 @@ static void clone_action(istringstream& is,
if ( image == 0 )
{
if (result == "SUCCESS")
{
ostringstream oss;
if ( is.good())
{
is >> source >> ws;
}
if (!source.empty())
{
oss << "CLONE operation succeeded but image no longer exists."
<< " Source image: " << source << ", may be left in datastore";
NebulaLog::log("ImM", Log::ERROR, oss);
}
}
return;
}
@ -310,6 +346,24 @@ static void mkfs_action(istringstream& is,
if ( image == 0 )
{
if (result == "SUCCESS")
{
ostringstream oss;
if ( is.good())
{
is >> source >> ws;
}
if (!source.empty())
{
oss << "MkFS operation succeeded but image no longer exists."
<< " Source image: " << source << ", may be left in datastore";
NebulaLog::log("ImM", Log::ERROR, oss);
}
}
return;
}

View File

@ -44,7 +44,7 @@ SYNC=sync
TAR=tar
TGTADM=tgtadm
TGTADMIN=tgt-admin
VMKFSTOOLS=/usr/sbin/vmkfstools
VMKFSTOOLS=vmkfstools
WGET=wget
if [ "x$(uname -s)" = "xLinux" ]; then

View File

@ -30,6 +30,7 @@ public class Cluster extends PoolElement{
private static final String ALLOCATE = METHOD_PREFIX + "allocate";
private static final String DELETE = METHOD_PREFIX + "delete";
private static final String INFO = METHOD_PREFIX + "info";
private static final String UPDATE = METHOD_PREFIX + "update";
private static final String ADDHOST = METHOD_PREFIX + "addhost";
private static final String DELHOST = METHOD_PREFIX + "delhost";
private static final String ADDDATASTORE = METHOD_PREFIX + "adddatastore";
@ -99,6 +100,19 @@ public class Cluster extends PoolElement{
return client.call(DELETE, id);
}
/**
* Replaces the cluster contents.
*
* @param client XML-RPC Client.
* @param id The id of the target cluster we want to modify.
* @param new_template New template contents.
* @return If successful the message contains the cluster id.
*/
public static OneResponse update(Client client, int id, String new_template)
{
return client.call(UPDATE, id, new_template);
}
/**
* Adds a Host to this Cluster
*
@ -210,6 +224,17 @@ public class Cluster extends PoolElement{
return delete(client, id);
}
/**
* Replaces the cluster template.
*
* @param new_template New cluster template.
* @return If successful the message contains the cluster id.
*/
public OneResponse update(String new_template)
{
return update(client, id, new_template);
}
/**
* Adds a Host to this Cluster
*

View File

@ -32,7 +32,8 @@ module OpenNebula
:adddatastore => "cluster.adddatastore",
:deldatastore => "cluster.deldatastore",
:addvnet => "cluster.addvnet",
:delvnet => "cluster.delvnet"
:delvnet => "cluster.delvnet",
:update => "cluster.update",
}
# Creates a Cluster description with just its identifier
@ -156,6 +157,16 @@ module OpenNebula
return rc
end
# Replaces the template contents
#
# @param new_template [String] New template contents
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def update(new_template)
super(CLUSTER_METHODS[:update], new_template)
end
# ---------------------------------------------------------------------
# Helpers to get information
# ---------------------------------------------------------------------

View File

@ -0,0 +1,146 @@
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
require "rexml/document"
include REXML
module Migrator
def db_version
"3.6.0"
end
def one_version
"OpenNebula 3.6.0"
end
def up
@db.run "ALTER TABLE cluster_pool RENAME TO old_cluster_pool;"
@db.run "CREATE TABLE cluster_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));"
@db.fetch("SELECT * FROM old_cluster_pool") do |row|
doc = Document.new(row[:body])
doc.root.add_element("TEMPLATE")
@db[:cluster_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.run "DROP TABLE old_cluster_pool;"
@db.run "ALTER TABLE datastore_pool RENAME TO old_datastore_pool;"
@db.run "CREATE TABLE datastore_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));"
system_tm = ""
@db.fetch("SELECT * FROM old_datastore_pool WHERE oid = 0") do |row|
doc = Document.new(row[:body])
doc.root.each_element("TM_MAD") { |e|
system_tm = e.text
}
doc.root.add_element("SYSTEM").text = "1"
@db[:datastore_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.fetch("SELECT * FROM old_datastore_pool WHERE oid > 0") do |row|
doc = Document.new(row[:body])
doc.root.add_element("SYSTEM").text = "0"
@db[:datastore_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.run "DROP TABLE old_datastore_pool;"
@db.run "ALTER TABLE vm_pool RENAME TO old_vm_pool;"
@db.run "CREATE TABLE vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER);"
@db.fetch("SELECT * FROM old_vm_pool") do |row|
doc = Document.new(row[:body])
doc.root.each_element("HISTORY_RECORDS/HISTORY") { |e|
e.add_element("TMMAD").text = system_tm
e.add_element("DS_ID").text = "0"
}
@db[:vm_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:last_poll => row[:last_poll],
:state => row[:state],
:lcm_state => row[:lcm_state],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.run "DROP TABLE old_vm_pool;"
@db.run "ALTER TABLE history RENAME TO old_history;"
@db.run "CREATE TABLE history (vid INTEGER, seq INTEGER, body TEXT, stime INTEGER, etime INTEGER, PRIMARY KEY(vid,seq));"
@db.fetch("SELECT * FROM old_history") do |row|
doc = Document.new(row[:body])
doc.root.add_element("TMMAD").text = system_tm
doc.root.add_element("DS_ID").text = "0"
@db[:history].insert(
:vid => row[:vid],
:seq => row[:seq],
:body => doc.root.to_s,
:stime => row[:stime],
:etime => row[:etime])
end
@db.run "DROP TABLE old_history;"
return true
end
end

View File

@ -268,6 +268,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr user_update(new UserUpdateTemplate());
xmlrpc_c::methodPtr datastore_update(new DatastoreUpdateTemplate());
xmlrpc_c::methodPtr doc_update(new DocumentUpdateTemplate());
xmlrpc_c::methodPtr cluster_update(new ClusterUpdateTemplate());
// Allocate Methods
xmlrpc_c::methodPtr vm_allocate(new VirtualMachineAllocate());
@ -468,6 +469,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.cluster.allocate",cluster_allocate);
RequestManagerRegistry.addMethod("one.cluster.delete", cluster_delete);
RequestManagerRegistry.addMethod("one.cluster.info", cluster_info);
RequestManagerRegistry.addMethod("one.cluster.update", cluster_update);
RequestManagerRegistry.addMethod("one.cluster.addhost", cluster_addhost);
RequestManagerRegistry.addMethod("one.cluster.delhost", cluster_delhost);

View File

@ -322,17 +322,6 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
// ------------------------- Check Datastore exists ------------------------
if ( ds_id == DatastorePool::SYSTEM_DS_ID )
{
ostringstream oss;
oss << "New images cannot be allocated in the system datastore.";
failure_response(INTERNAL, allocate_error(oss.str()), att);
delete tmpl;
return;
}
if ((ds = dspool->get(ds_id,true)) == 0 )
{
failure_response(NO_EXISTS,
@ -343,6 +332,20 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
return;
}
if ( ds->is_system() )
{
ostringstream oss;
ds->unlock();
oss << "New images cannot be allocated in a system datastore.";
failure_response(INTERNAL, allocate_error(oss.str()), att);
delete tmpl;
return;
}
ds->get_permissions(ds_perms);
ds_name = ds->get_name();

View File

@ -99,13 +99,19 @@ int RequestManagerVirtualMachine::get_host_information(int hid,
string& name,
string& vmm,
string& vnm,
string& tm,
int& ds_id,
RequestAttributes& att,
PoolObjectAuth& host_perms)
{
Nebula& nd = Nebula::instance();
HostPool * hpool = nd.get_hpool();
Host * host;
Host * host;
Cluster * cluster;
Datastore * ds;
int cluster_id;
host = hpool->get(hid,true);
@ -124,8 +130,65 @@ int RequestManagerVirtualMachine::get_host_information(int hid,
host->get_permissions(host_perms);
cluster_id = host->get_cluster_id();
host->unlock();
if ( cluster_id != -1 )
{
cluster = nd.get_clpool()->get(cluster_id, true);
if ( cluster == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id),
att);
return -1;
}
ds_id = cluster->get_ds_id();
cluster->unlock();
}
else
{
ds_id = DatastorePool::SYSTEM_DS_ID;
}
ds = nd.get_dspool()->get(ds_id, true);
if ( ds == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE),ds_id),
att);
return -1;
}
if ( ds->is_system() == false )
{
ostringstream oss;
ds->unlock();
oss << object_name(PoolObjectSQL::CLUSTER)
<< " [" << cluster_id << "] has its SYSTEM_DS set to "
<< object_name(PoolObjectSQL::DATASTORE)
<< " [" << ds_id << "], but it is not a system one.";
failure_response(INTERNAL,
request_error(oss.str(),""),
att);
return -1;
}
tm = ds->get_tm_mad();
ds->unlock();
return 0;
}
@ -156,6 +219,8 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm,
const string& hostname,
const string& vmm_mad,
const string& vnm_mad,
const string& tm_mad,
int ds_id,
RequestAttributes& att)
{
string vmdir;
@ -163,7 +228,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm,
VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
vm->add_history(hid,hostname,vmm_mad,vnm_mad);
vm->add_history(hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id);
rc = vmpool->update_history(vm);
@ -308,13 +373,16 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
string hostname;
string vmm_mad;
string vnm_mad;
string tm_mad;
int ds_id;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int hid = xmlrpc_c::value_int(paramList.getInt(2));
bool auth = false;
if (get_host_information(hid,hostname,vmm_mad,vnm_mad,att, host_perms) != 0)
if (get_host_information(
hid,hostname,vmm_mad,vnm_mad,tm_mad, ds_id, att, host_perms) != 0)
{
return;
}
@ -341,7 +409,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,att) != 0)
if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id,att) != 0)
{
vm->unlock();
return;
@ -369,6 +437,8 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
string hostname;
string vmm_mad;
string vnm_mad;
string tm_mad;
int ds_id;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int hid = xmlrpc_c::value_int(paramList.getInt(2));
@ -376,7 +446,8 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
bool auth = false;
if (get_host_information(hid,hostname,vmm_mad,vnm_mad,att, host_perms) != 0)
if (get_host_information(
hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id, att, host_perms) != 0)
{
return;
}
@ -405,7 +476,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,att) != 0)
if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id,att) != 0)
{
vm->unlock();
return;

View File

@ -20,13 +20,8 @@
#
# LIVE_RESCHEDS: Perform live (1) or cold migrations (0) when rescheduling a VM
#
# CPU_THRESHOLD: Fraction of the actual amount of CPU
# (HOST/HOST_SHARE/MAX_CPU) that the scheduler will use.
# E.g. 0.9 means that only 90% of the total CPU will be used
#
# MEM_THRESHOLD: Fraction of the actual amount of MEMORY
# (HOST/HOST_SHARE/MAX_MEM) that the scheduler will use.
# E.g. 0.9 means that only 90% of the total MEMORY will be used
# HYPERVISOR_MEM: Fraction of total MEMORY reserved for the hypervisor.
# E.g. 0.1 means that only 90% of the total MEMORY will be used
#
# DEFAULT_SCHED: Definition of the default scheduling algorithm
# - policy:
@ -45,16 +40,13 @@ ONED_PORT = 2633
SCHED_INTERVAL = 30
MAX_VM = 300
MAX_VM = 300
MAX_DISPATCH = 30
MAX_HOST = 1
MAX_HOST = 1
LIVE_RESCHEDS = 0
LIVE_RESCHEDS = 0
CPU_THRESHOLD = 0.9
MEM_THRESHOLD = 1
HYPERVISOR_MEM = 0.1
DEFAULT_SCHED = [
policy = 1

View File

@ -27,7 +27,10 @@ class HostPoolXML : public PoolXML
{
public:
HostPoolXML(Client* client):PoolXML(client){};
HostPoolXML(Client* client, float mem):PoolXML(client)
{
HostXML::set_hypervisor_mem(mem);
};
int set_up();

View File

@ -40,16 +40,6 @@ public:
return oid;
};
/**
* Gets the current host capacity
* @param cpu the host free cpu, scaled according to a given threshold
* @param memory the host free memory
* @param cpu_threshold to consider the host totally free
* @param mem_threshold to consider the host totally free
*/
void get_capacity(int& cpu, int& memory,
float cpu_threshold, float mem_threshold) const;
/**
* Tests whether a new VM can be hosted by the host or not
* @param cpu needed by the VM (percentage)
@ -81,6 +71,14 @@ public:
running_vms++;
};
/**
* Sets the memory fraction reserved for the hypervisor. This function
* should be called before using the host pool.
*/
static void set_hypervisor_mem(float mem)
{
hypervisor_mem = 1.0 - mem;
};
private:
int oid;
@ -94,12 +92,10 @@ private:
int max_mem; /**< Total memory capacity (in Mb) */
int max_cpu; /**< Total cpu capacity (in percentage) */
int free_disk; /**< Free disk from the IM monitor */
int free_mem; /**< Free memory from the IM monitor */
int free_cpu; /**< Free cpu from the IM monitor */
int running_vms; /**< Number of running VMs in this Host */
static float hypervisor_mem; /**< Fraction of memory for the VMs */
void init_attributes();
};

View File

@ -54,8 +54,7 @@ protected:
machines_limit(0),
dispatch_limit(0),
host_dispatch_limit(0),
cpu_threshold(0.9),
mem_threshold(1),
hypervisor_mem(0),
client(0)
{
am.addListener(this);
@ -157,14 +156,9 @@ private:
unsigned int host_dispatch_limit;
/**
* Threshold value to round up freecpu
* Memory reserved for the hypervisor
*/
float cpu_threshold;
/**
* Threshold value to round up freemem
*/
float mem_threshold;
float hypervisor_mem;
/**
* XML_RPC client

View File

@ -18,25 +18,7 @@
#include "HostXML.h"
void HostXML::get_capacity(int& cpu, int& memory,
float cpu_threshold, float mem_threshold) const
{
vector<string> result;
memory = free_mem;
cpu = free_cpu;
/* eg. 96.7 >= 0.9 * 100, We need to round */
if ( cpu >= static_cast<int>(cpu_threshold * static_cast<float>(max_cpu)) )
{
cpu = static_cast<int>(ceil(static_cast<float>(cpu)/100.0) * 100);
}
if ( memory >= static_cast<int>(mem_threshold * static_cast<float>(max_mem)) )
{
memory = static_cast<int>(ceil(static_cast<float>(memory)/100.0) * 100);
}
}
float HostXML::hypervisor_mem;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -53,11 +35,10 @@ void HostXML::init_attributes()
max_mem = atoi(((*this)["/HOST/HOST_SHARE/MAX_MEM"])[0].c_str());
max_cpu = atoi(((*this)["/HOST/HOST_SHARE/MAX_CPU"])[0].c_str());
free_disk = atoi(((*this)["/HOST/HOST_SHARE/FREE_DISK"])[0].c_str());
free_mem = atoi(((*this)["/HOST/HOST_SHARE/FREE_MEM"])[0].c_str());
free_cpu = atoi(((*this)["/HOST/HOST_SHARE/FREE_CPU"])[0].c_str());
running_vms = atoi(((*this)["/HOST/HOST_SHARE/RUNNING_VMS"])[0].c_str());
//Reserve memory for the hypervisor
max_mem = static_cast<int>(hypervisor_mem * static_cast<float>(max_mem));
}
/* -------------------------------------------------------------------------- */

View File

@ -139,10 +139,9 @@ void Scheduler::start()
conf.get("MAX_HOST", host_dispatch_limit);
conf.get("CPU_THRESHOLD", cpu_threshold);
conf.get("MEM_THRESHOLD", mem_threshold);
conf.get("LIVE_RESCHEDS", live_rescheds);
conf.get("HYPERVISOR_MEM", hypervisor_mem);
oss.str("");
@ -175,7 +174,7 @@ void Scheduler::start()
// Pools
// -----------------------------------------------------------
hpool = new HostPoolXML(client);
hpool = new HostPoolXML(client, hypervisor_mem);
vmpool = new VirtualMachinePoolXML(client,
machines_limit,
(live_rescheds == 1));
@ -428,24 +427,18 @@ void Scheduler::match()
vm->get_requirements(vm_cpu,vm_memory,vm_disk);
host->get_capacity(host_cpu, host_memory, cpu_threshold, mem_threshold);
if ((vm_memory <= host_memory) && (vm_cpu <= host_cpu))
if (host->test_capacity(vm_cpu,vm_memory,vm_disk) == true)
{
if (host->test_capacity(vm_cpu,vm_memory,vm_disk) == true)
{
vm->add_host(host->get_hid());
}
vm->add_host(host->get_hid());
}
else
{
ostringstream oss;
oss << "Host " << host->get_hid() <<
" filtered out. It does not have enough capacity.";
oss << "Host " << host->get_hid() << " filtered out. "
<< "Not enough capacity. " << endl;
NebulaLog::log("SCHED",Log::DEBUG,oss);
}
}
}

View File

@ -41,6 +41,7 @@ void SchedulerTemplate::set_conf_default()
# MAX_HOST
# DEFAULT_SCHED
# LIVE_RESCHEDS
# HYPERVISOR_MEM
#-------------------------------------------------------------------------------
*/
// ONED_PORT
@ -85,6 +86,12 @@ void SchedulerTemplate::set_conf_default()
vattribute = new VectorAttribute("DEFAULT_SCHED",vvalue);
conf_default.insert(make_pair(attribute->name(),vattribute));
//HYPERVISOR_MEM
value = "0.1";
attribute = new SingleAttribute("HYPERVISOR_MEM",value);
conf_default.insert(make_pair(attribute->name(),attribute));
}
/* -------------------------------------------------------------------------- */

View File

@ -212,7 +212,7 @@ void TransferManager::do_action(const string &action, void * arg)
int TransferManager::prolog_transfer_command(
VirtualMachine * vm,
const VectorAttribute * disk,
string& system_tm_mad,
string& vm_tm_mad,
string& opennebula_hostname,
ostream& xfr,
ostringstream& os)
@ -248,7 +248,7 @@ int TransferManager::prolog_transfer_command(
//MKSWAP tm_mad size host:remote_system_dir/disk.i vmid dsid(=0)
xfr << "MKSWAP "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< size << " "
<< vm->get_hostname() << ":"
<< vm->get_remote_system_dir() << "/disk." << disk_index << " "
@ -273,7 +273,7 @@ int TransferManager::prolog_transfer_command(
//MKIMAGE tm_mad size format host:remote_system_dir/disk.i vmid dsid(=0)
xfr << "MKIMAGE "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< size << " "
<< format << " "
<< vm->get_hostname() << ":"
@ -356,7 +356,7 @@ void TransferManager::prolog_action(int vid)
const VectorAttribute * disk;
string files;
string system_tm_mad;
string vm_tm_mad;
string opennebula_hostname;
int rc;
string error_str;
@ -374,17 +374,6 @@ void TransferManager::prolog_action(int vid)
// -------------------------------------------------------------------------
// Setup & Transfer script
// -------------------------------------------------------------------------
system_tm_mad = nd.get_system_ds_tm_mad();
tm_md = get();
if ( tm_md == 0 || system_tm_mad.empty() )
{
NebulaLog::log("TM", Log::ERROR, "prolog, error getting drivers.");
(nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid);
return;
}
vm = vmpool->get(vid,true);
if (vm == 0)
@ -397,6 +386,14 @@ void TransferManager::prolog_action(int vid)
goto error_history;
}
vm_tm_mad = vm->get_tm_mad();
tm_md = get();
if ( tm_md == 0 || vm_tm_mad.empty() )
{
goto error_drivers;
}
xfr_name = vm->get_transfer_file() + ".prolog";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
@ -423,7 +420,7 @@ void TransferManager::prolog_action(int vid)
rc = prolog_transfer_command(vm,
disk,
system_tm_mad,
vm_tm_mad,
opennebula_hostname,
xfr,
os);
@ -447,7 +444,7 @@ void TransferManager::prolog_action(int vid)
{
//CONTEXT tm_mad files hostname:remote_system_dir/disk.i vmid dsid(=0)
xfr << "CONTEXT "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< vm->get_context_file() << " ";
if (!files.empty())
@ -472,6 +469,11 @@ error_history:
os << "VM " << vid << " has no history";
goto error_common;
error_drivers:
os.str("");
os << "prolog, error getting drivers.";
goto error_common;
error_file:
os << "could not open file: " << xfr_name;
goto error_common;
@ -497,6 +499,19 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static bool isVolatile(const VectorAttribute * disk)
{
string type;
type = disk->vector_value("TYPE");
transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper);
return ( type == "SWAP" || type == "FS");
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::prolog_migr_action(int vid)
{
ofstream xfr;
@ -505,7 +520,8 @@ void TransferManager::prolog_migr_action(int vid)
const VectorAttribute * disk;
string tm_mad;
string system_tm_mad;
string vm_tm_mad;
string vm_ds_id;
string ds_id;
int disk_id;
@ -520,17 +536,6 @@ void TransferManager::prolog_migr_action(int vid)
// -------------------------------------------------------------------------
// Setup & Transfer script
// -------------------------------------------------------------------------
system_tm_mad = nd.get_system_ds_tm_mad();
tm_md = get();
if ( tm_md == 0 || system_tm_mad.empty() )
{
NebulaLog::log("TM", Log::ERROR, "prolog_migr, error getting drivers.");
(nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid);
return;
}
vm = vmpool->get(vid,true);
if (vm == 0)
@ -538,11 +543,20 @@ void TransferManager::prolog_migr_action(int vid)
return;
}
if (!vm->hasHistory())
if (!vm->hasHistory() || !vm->hasPreviousHistory())
{
goto error_history;
}
vm_tm_mad = vm->get_tm_mad();
vm_ds_id = vm->get_ds_id();
tm_md = get();
if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty())
{
goto error_drivers;
}
xfr_name = vm->get_transfer_file() + ".migrate";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
@ -566,13 +580,22 @@ void TransferManager::prolog_migr_action(int vid)
continue;
}
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
disk->vector_value_str("DISK_ID", disk_id);
if ( tm_mad.empty() || ds_id.empty() )
if ( isVolatile(disk) == true )
{
continue;
tm_mad = vm_tm_mad;
ds_id = vm_ds_id;
}
else
{
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
if ( tm_mad.empty() || ds_id.empty() )
{
continue;
}
}
//MV tm_mad prev_host:remote_system_dir/disk.i host:remote_system_dir/disk.i vmid dsid
@ -588,13 +611,13 @@ void TransferManager::prolog_migr_action(int vid)
//MV tm_mad prev_host:remote_system_dir host:remote_system_dir VMID 0
xfr << "MV "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< vm->get_previous_hostname() << ":"
<< vm->get_remote_system_dir() << " "
<< vm->get_hostname() << ":"
<< vm->get_remote_system_dir() << " "
<< vm->get_oid() << " "
<< "0" << endl;
<< vm_ds_id << endl;
xfr.close();
@ -608,6 +631,11 @@ error_history:
os << "prolog_migr, VM " << vid << " has no history";
goto error_common;
error_drivers:
os.str("");
os << "prolog_migr, error getting drivers.";
goto error_common;
error_file:
os.str("");
os << "prolog_migr, could not open file: " << xfr_name;
@ -632,7 +660,8 @@ void TransferManager::prolog_resume_action(int vid)
const VectorAttribute * disk;
string tm_mad;
string system_tm_mad;
string vm_tm_mad;
string vm_ds_id;
string ds_id;
int disk_id;
@ -647,17 +676,6 @@ void TransferManager::prolog_resume_action(int vid)
// -------------------------------------------------------------------------
// Setup & Transfer script
// -------------------------------------------------------------------------
system_tm_mad = nd.get_system_ds_tm_mad();
tm_md = get();
if ( tm_md == 0 || system_tm_mad.empty() )
{
NebulaLog::log("TM", Log::ERROR, "prolog_resume, error getting drivers.");
(nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid);
return;
}
vm = vmpool->get(vid,true);
if (vm == 0)
@ -670,6 +688,15 @@ void TransferManager::prolog_resume_action(int vid)
goto error_history;
}
vm_tm_mad = vm->get_tm_mad();
vm_ds_id = vm->get_ds_id();
tm_md = get();
if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty())
{
goto error_drivers;
}
xfr_name = vm->get_transfer_file() + ".resume";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
@ -692,13 +719,22 @@ void TransferManager::prolog_resume_action(int vid)
continue;
}
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
disk->vector_value_str("DISK_ID", disk_id);
if ( tm_mad.empty() || ds_id.empty() )
if ( isVolatile(disk) == true )
{
continue;
tm_mad = vm_tm_mad;
ds_id = vm_ds_id;
}
else
{
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
if ( tm_mad.empty() || ds_id.empty() )
{
continue;
}
}
//MV tm_mad fe:system_dir/disk.i host:remote_system_dir/disk.i vmid dsid
@ -714,11 +750,11 @@ void TransferManager::prolog_resume_action(int vid)
//MV tm_mad fe:system_dir host:remote_system_dir vmid 0
xfr << "MV "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< nd.get_nebula_hostname() << ":"<< vm->get_system_dir() << " "
<< vm->get_hostname() << ":" << vm->get_remote_system_dir()<< " "
<< vm->get_oid() << " "
<< "0" << endl;
<< vm_ds_id << endl;
xfr.close();
@ -732,6 +768,11 @@ error_history:
os << "prolog_resume, VM " << vid << " has no history";
goto error_common;
error_drivers:
os.str("");
os << "prolog_resume, error getting drivers.";
goto error_common;
error_file:
os.str("");
os << "prolog_resume, could not open file: " << xfr_name;
@ -758,13 +799,22 @@ void TransferManager::epilog_transfer_command(
string ds_id;
int disk_index;
save = disk->vector_value("SAVE");
ds_id = disk->vector_value("DATASTORE_ID");
tm_mad = disk->vector_value("TM_MAD");
if ( save.empty() || ds_id.empty() || tm_mad.empty() )
if ( isVolatile(disk) == true )
{
return;
save = "NO";
tm_mad = vm->get_tm_mad();
ds_id = vm->get_ds_id();
}
else
{
save = disk->vector_value("SAVE");
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
if ( save.empty() || ds_id.empty() || tm_mad.empty() )
{
return;
}
}
disk->vector_value("DISK_ID", disk_index);
@ -820,9 +870,10 @@ void TransferManager::epilog_action(int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
string system_tm_mad;
string error_str;
string xfr_name;
string vm_tm_mad;
string vm_ds_id;
string error_str;
const VectorAttribute * disk;
@ -837,17 +888,6 @@ void TransferManager::epilog_action(int vid)
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
system_tm_mad = nd.get_system_ds_tm_mad();
tm_md = get();
if ( tm_md == 0 || system_tm_mad.empty() )
{
NebulaLog::log("TM", Log::ERROR, "epilog, error getting drivers.");
(nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid);
return;
}
vm = vmpool->get(vid,true);
if (vm == 0)
@ -860,6 +900,15 @@ void TransferManager::epilog_action(int vid)
goto error_history;
}
vm_tm_mad = vm->get_tm_mad();
vm_ds_id = vm->get_ds_id();
tm_md = get();
if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty())
{
goto error_drivers;
}
xfr_name = vm->get_transfer_file() + ".epilog";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
@ -885,12 +934,12 @@ void TransferManager::epilog_action(int vid)
epilog_transfer_command(vm, disk, xfr);
}
//DELETE system_tm_mad hostname:remote_system_dir vmid ds_id
//DELETE vm_tm_mad hostname:remote_system_dir vmid ds_id
xfr << "DELETE "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< vm->get_hostname() << ":" << vm->get_remote_system_dir() << " "
<< vm->get_oid() << " "
<< "0" << endl;
<< vm_ds_id << endl;
xfr.close();
@ -904,6 +953,11 @@ error_history:
os << "epilog, VM " << vid << " has no history";
goto error_common;
error_drivers:
os.str("");
os << "epilog, error getting drivers.";
goto error_common;
error_file:
os.str("");
os << "epilog, could not open file: " << xfr_name;
@ -924,11 +978,14 @@ void TransferManager::epilog_stop_action(int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
string tm_mad;
string system_tm_mad;
string ds_id;
int disk_id;
string xfr_name;
string tm_mad;
string vm_tm_mad;
string vm_ds_id;
string ds_id;
int disk_id;
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
@ -942,17 +999,6 @@ void TransferManager::epilog_stop_action(int vid)
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
system_tm_mad = nd.get_system_ds_tm_mad();
tm_md = get();
if ( tm_md == 0 || system_tm_mad.empty() )
{
NebulaLog::log("TM", Log::ERROR, "epilog_stop, error getting drivers.");
(nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid);
return;
}
vm = vmpool->get(vid,true);
if (vm == 0)
@ -965,6 +1011,15 @@ void TransferManager::epilog_stop_action(int vid)
goto error_history;
}
vm_tm_mad = vm->get_tm_mad();
vm_ds_id = vm->get_ds_id();
tm_md = get();
if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty())
{
goto error_drivers;
}
xfr_name = vm->get_transfer_file() + ".stop";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
@ -987,13 +1042,22 @@ void TransferManager::epilog_stop_action(int vid)
continue;
}
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
disk->vector_value_str("DISK_ID", disk_id);
if (tm_mad.empty() || ds_id.empty())
if ( isVolatile(disk) == true )
{
continue;
tm_mad = vm_tm_mad;
ds_id = vm_ds_id;
}
else
{
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
if ( tm_mad.empty() || ds_id.empty() )
{
continue;
}
}
//MV tm_mad host:remote_system_dir/disk.i fe:system_dir/disk.i vmid dsid
@ -1007,13 +1071,13 @@ void TransferManager::epilog_stop_action(int vid)
<< ds_id << endl;
}
//MV system_tm_mad hostname:remote_system_dir fe:system_dir
//MV vm_tm_mad hostname:remote_system_dir fe:system_dir
xfr << "MV "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< vm->get_hostname() << ":" << vm->get_remote_system_dir() << " "
<< nd.get_nebula_hostname() << ":" << vm->get_system_dir() << " "
<< vm->get_oid() << " "
<< "0" << endl;
<< vm_ds_id << endl;
xfr.close();
@ -1028,6 +1092,11 @@ error_history:
os << "epilog_stop, VM " << vid << " has no history";
goto error_common;
error_drivers:
os.str("");
os << "epilog_stop, error getting drivers.";
goto error_common;
error_file:
os.str("");
os << "epilog_stop, could not open file: " << xfr_name;
@ -1048,11 +1117,14 @@ void TransferManager::epilog_delete_action(bool local, int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
string system_tm_mad;
string tm_mad;
string ds_id;
int disk_id;
string xfr_name;
string vm_tm_mad;
string tm_mad;
string vm_ds_id;
string ds_id;
int disk_id;
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
@ -1066,17 +1138,6 @@ void TransferManager::epilog_delete_action(bool local, int vid)
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
system_tm_mad = nd.get_system_ds_tm_mad();
tm_md = get();
if ( tm_md == 0 || system_tm_mad.empty() )
{
NebulaLog::log("TM", Log::ERROR, "epilog_delete, error getting drivers.");
(nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid);
return;
}
vm = vmpool->get(vid,true);
if (vm == 0)
@ -1088,7 +1149,16 @@ void TransferManager::epilog_delete_action(bool local, int vid)
{
goto error_history;
}
vm_tm_mad = vm->get_tm_mad();
vm_ds_id = vm->get_ds_id();
tm_md = get();
if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty())
{
goto error_drivers;
}
xfr_name = vm->get_transfer_file() + ".delete";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
@ -1111,13 +1181,22 @@ void TransferManager::epilog_delete_action(bool local, int vid)
continue;
}
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
disk->vector_value_str("DISK_ID", disk_id);
if ( tm_mad.empty() || ds_id.empty() )
if ( isVolatile(disk) == true )
{
continue;
tm_mad = vm_tm_mad;
ds_id = vm_ds_id;
}
else
{
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
if ( tm_mad.empty() || ds_id.empty() )
{
continue;
}
}
if ( local )
@ -1144,21 +1223,21 @@ void TransferManager::epilog_delete_action(bool local, int vid)
if ( local )
{
//DELETE system_tm_mad fe:system_dir vmid dsid(=0)
//DELETE vm_tm_mad fe:system_dir vmid dsid(=0)
xfr << "DELETE "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< nd.get_nebula_hostname() <<":"<< vm->get_system_dir() << " "
<< vm->get_oid() << " "
<< "0";
<< vm_ds_id;
}
else
{
//DELETE system_tm_mad hostname:remote_system_dir vmid dsid(=0)
//DELETE vm_tm_mad hostname:remote_system_dir vmid dsid(=0)
xfr << "DELETE "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< vm->get_hostname() <<":"<< vm->get_remote_system_dir() << " "
<< vm->get_oid() << " "
<< "0";
<< vm_ds_id;
}
xfr.close();
@ -1173,6 +1252,11 @@ error_history:
os << "epilog_delete, VM " << vid << " has no history";
goto error_common;
error_drivers:
os.str("");
os << "epilog_delete, error getting drivers.";
goto error_common;
error_file:
os.str("");
os << "epilog_delete, could not open file: " << xfr_name;
@ -1195,11 +1279,14 @@ void TransferManager::epilog_delete_previous_action(int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
string system_tm_mad;
string tm_mad;
string ds_id;
int disk_id;
string xfr_name;
string vm_tm_mad;
string tm_mad;
string vm_ds_id;
string ds_id;
int disk_id;
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
@ -1213,17 +1300,6 @@ void TransferManager::epilog_delete_previous_action(int vid)
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
system_tm_mad = nd.get_system_ds_tm_mad();
tm_md = get();
if ( tm_md == 0 || system_tm_mad.empty() )
{
NebulaLog::log("TM", Log::ERROR, "epilog_delete, error getting drivers.");
(nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid);
return;
}
vm = vmpool->get(vid,true);
if (vm == 0)
@ -1236,6 +1312,15 @@ void TransferManager::epilog_delete_previous_action(int vid)
goto error_history;
}
vm_tm_mad = vm->get_previous_tm_mad();
vm_ds_id = vm->get_previous_ds_id();
tm_md = get();
if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty() )
{
goto error_drivers;
}
xfr_name = vm->get_transfer_file() + ".delete_prev";
xfr.open(xfr_name.c_str(),ios::out | ios::trunc);
@ -1258,13 +1343,22 @@ void TransferManager::epilog_delete_previous_action(int vid)
continue;
}
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
disk->vector_value_str("DISK_ID", disk_id);
if (tm_mad.empty() || ds_id.empty())
if ( isVolatile(disk) == true )
{
continue;
tm_mad = vm_tm_mad;
ds_id = vm_ds_id;
}
else
{
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
if ( tm_mad.empty() || ds_id.empty() )
{
continue;
}
}
//DELETE tm_mad prev_host:remote_system_dir/disk.i vmid ds_id
@ -1276,12 +1370,12 @@ void TransferManager::epilog_delete_previous_action(int vid)
<< ds_id << endl;
}
//DELTE system_tm_mad prev_host:remote_system_dir vmid ds_id(=0)
//DELTE vm_tm_mad prev_host:remote_system_dir vmid ds_id(=0)
xfr << "DELETE "
<< system_tm_mad << " "
<< vm_tm_mad << " "
<< vm->get_previous_hostname() <<":"<< vm->get_remote_system_dir()
<< " " << vm->get_oid() << " "
<< "0" << endl;
<< vm_ds_id << endl;
xfr.close();
@ -1295,9 +1389,14 @@ error_history:
os << "epilog_delete_previous, VM " << vid << " has no history";
goto error_common;
error_drivers:
os.str("");
os << "epilog_delete_previous, error getting drivers.";
goto error_common;
error_file:
os.str("");
os << "epilog_delete, could not open file: " << xfr_name;
os << "epilog_delete_previous, could not open file: " << xfr_name;
os << ". You may need to manually clean " << vm->get_previous_hostname()
<< ":" << vm->get_remote_system_dir();
goto error_common;

View File

@ -44,6 +44,8 @@ History::History(
hid(-1),
vmm_mad_name(""),
vnm_mad_name(""),
tm_mad_name(""),
ds_id(0),
stime(0),
etime(0),
prolog_stime(0),
@ -64,6 +66,8 @@ History::History(
const string& _hostname,
const string& _vmm,
const string& _vnm,
const string& _tmm,
int _ds_id,
const string& _vm_info):
oid(_oid),
seq(_seq),
@ -71,6 +75,8 @@ History::History(
hid(_hid),
vmm_mad_name(_vmm),
vnm_mad_name(_vnm),
tm_mad_name(_tmm),
ds_id(_ds_id),
stime(0),
etime(0),
prolog_stime(0),
@ -123,7 +129,7 @@ void History::non_persistent_data()
os.str("");
nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location);
os << ds_location << "/" << DatastorePool::SYSTEM_DS_ID << "/" << oid;
os << ds_location << "/" << ds_id << "/" << oid;
vm_rhome = os.str();
@ -292,6 +298,8 @@ string& History::to_xml(string& xml, bool database) const
"<ETIME>" << etime << "</ETIME>" <<
"<VMMMAD>" << vmm_mad_name << "</VMMMAD>"<<
"<VNMMAD>" << vnm_mad_name << "</VNMMAD>"<<
"<TMMAD>" << tm_mad_name << "</TMMAD>" <<
"<DS_ID>" << ds_id << "</DS_ID>" <<
"<PSTIME>" << prolog_stime << "</PSTIME>"<<
"<PETIME>" << prolog_etime << "</PETIME>"<<
"<RSTIME>" << running_stime << "</RSTIME>"<<
@ -328,6 +336,8 @@ int History::rebuild_attributes()
rc += xpath(etime , "/HISTORY/ETIME", 0);
rc += xpath(vmm_mad_name , "/HISTORY/VMMMAD", "not_found");
xpath(vnm_mad_name , "/HISTORY/VNMMAD", "dummy");
rc += xpath(tm_mad_name , "/HISTORY/TMMAD", "not_found");
rc += xpath(ds_id , "/HISTORY/DS_ID", 0);
rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0);
rc += xpath(prolog_etime , "/HISTORY/PETIME", 0);
rc += xpath(running_stime , "/HISTORY/RSTIME", 0);

View File

@ -826,7 +826,9 @@ void VirtualMachine::add_history(
int hid,
const string& hostname,
const string& vmm_mad,
const string& vnm_mad)
const string& vnm_mad,
const string& tm_mad,
int ds_id)
{
ostringstream os;
int seq;
@ -851,6 +853,8 @@ void VirtualMachine::add_history(
hostname,
vmm_mad,
vnm_mad,
tm_mad,
ds_id,
vm_xml);
history_records.push_back(history);
@ -877,6 +881,8 @@ void VirtualMachine::cp_history()
history->hostname,
history->vmm_mad_name,
history->vnm_mad_name,
history->tm_mad_name,
history->ds_id,
vm_xml);
previous_history = history;
@ -906,6 +912,8 @@ void VirtualMachine::cp_previous_history()
previous_history->hostname,
previous_history->vmm_mad_name,
previous_history->vnm_mad_name,
previous_history->tm_mad_name,
previous_history->ds_id,
vm_xml);
previous_history = history;
@ -1980,7 +1988,7 @@ string VirtualMachine::get_remote_system_dir() const
Nebula& nd = Nebula::instance();
nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location);
oss << ds_location << "/" << DatastorePool::SYSTEM_DS_ID << "/" << oid;
oss << ds_location << "/" << history->ds_id << "/" << oid;
return oss.str();
}
@ -1993,7 +2001,7 @@ string VirtualMachine::get_system_dir() const
ostringstream oss;
Nebula& nd = Nebula::instance();
oss << nd.get_ds_location() << DatastorePool::SYSTEM_DS_ID << "/"<< oid;
oss << nd.get_ds_location() << history->ds_id << "/"<< oid;
return oss.str();
};

View File

@ -1313,7 +1313,7 @@ void VirtualMachineManager::attach_action(
string vm_tmpl;
string* drv_msg;
string tm_command;
string system_tm_mad;
string vm_tm_mad;
string opennebula_hostname;
string prolog_cmd;
string disk_path;
@ -1352,13 +1352,13 @@ void VirtualMachineManager::attach_action(
goto error_disk;
}
system_tm_mad = nd.get_system_ds_tm_mad();
vm_tm_mad = vm->get_tm_mad();
opennebula_hostname = nd.get_nebula_hostname();
rc = Nebula::instance().get_tm()->prolog_transfer_command(
vm,
disk,
system_tm_mad,
vm_tm_mad,
opennebula_hostname,
os,
error_os);
@ -1445,7 +1445,7 @@ void VirtualMachineManager::detach_action(
string vm_tmpl;
string * drv_msg;
string tm_command;
string system_tm_mad;
string vm_tm_mad;
string opennebula_hostname;
string epilog_cmd;
string disk_path;
@ -1484,7 +1484,7 @@ void VirtualMachineManager::detach_action(
goto error_disk;
}
system_tm_mad = nd.get_system_ds_tm_mad();
vm_tm_mad = vm->get_tm_mad();
opennebula_hostname = nd.get_nebula_hostname();
disk->vector_value("DISK_ID", disk_id);

View File

@ -90,7 +90,7 @@ class DummyDriver < VirtualMachineDriver
max_memory = 256
if msg.elements["VM/TEMPLATE/MEMORY"]
max_memory = msg.elements["VM/TEMPLATE/MEMORY"].text.to_i
max_memory = msg.elements["VM/TEMPLATE/MEMORY"].text.to_i * 1024
end
max_cpu = 100

View File

@ -224,8 +224,8 @@ module XEN
dom_hash[:state]=get_state(dom_data[1])
dom_hash[:usedcpu]=dom_data[3]
dom_hash[:usedmemory]=dom_data[4]
dom_hash[:nettx]=dom_data[10]
dom_hash[:netrx]=dom_data[11]
dom_hash[:nettx]=dom_data[10].to_i * 1024
dom_hash[:netrx]=dom_data[11].to_i * 1024
domains[dom_hash[:name]]=dom_hash
end