1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

feature #1611: Abstracts system properties and system DB management

This commit is contained in:
Ruben S. Montero 2012-11-30 02:59:26 +01:00
parent e4a601dde8
commit d6091c439e
8 changed files with 762 additions and 309 deletions

View File

@ -21,7 +21,7 @@
#include "SqlDB.h"
#include "ObjectSQL.h"
class DefaultQuotas : public Quotas, ObjectSQL
class DefaultQuotas : public Quotas
{
public:
DefaultQuotas(
@ -48,95 +48,34 @@ public:
* @param db pointer to the db
* @return 0 on success
*/
int insert(SqlDB *db, string& error_str)
{
return insert_replace(db, false, error_str);
};
int insert();
/**
* Writes/updates the quotas data fields in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update(SqlDB *db)
{
string error_str;
return insert_replace(db, true, error_str);
};
int update();
/**
* Reads the Quotas from the database.
* @param db pointer to the db
* @return 0 on success
*/
int select(SqlDB *db);
/**
* Bootstraps the database table(s) associated to the default quotas
* @return 0 on success
*/
static int bootstrap(SqlDB * db)
{
ostringstream oss(DefaultQuotas::db_bootstrap);
return db->exec(oss);
}
int select();
private:
/**
* Name for the default quota attribute
*/
const char * root_elem;
// *************************************************************************
// DataBase implementation
// *************************************************************************
static const char * db_names;
static const char * db_bootstrap;
static const char * table;
/**
* Execute an INSERT or REPLACE Sql query.
* @param db The SQL DB
* @param replace Execute an INSERT or a REPLACE
* @param error_str Returns the error reason, if any
* @return 0 one success
*/
int insert_replace(SqlDB *db, bool replace, string& error_str);
/**
* Callback function to unmarshall a PoolObjectSQL
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
int select_cb(void *nil, int num, char **values, char **names)
{
if ( (!values[0]) || (num != 1) )
{
return -1;
}
return from_xml(values[0]);
};
/**
* Builds quota object from an ObjectXML
* @param xml The xml-formatted string
* @return 0 on success
*/
int from_xml(const string& xml);
/**
* Removes the Quotas from the database.
* @param db pointer to the db
* @return 0 on success
*/
int drop(SqlDB * db)
{
return -1; // Not supported
};
};
#endif /*DEFAULT_QUOTAS_H_*/

View File

@ -18,6 +18,7 @@
#define NEBULA_H_
#include "SqlDB.h"
#include "SystemDB.h"
#include "NebulaTemplate.h"
@ -46,7 +47,13 @@
#include "Callbackable.h"
class Nebula : public Callbackable
/**
* This is the main class for the OpenNebula daemon oned. It stores references
* to the main modules and data pools. It also includes functions to bootstrap
* the system and start all its components.
*/
class Nebula
{
public:
@ -325,7 +332,7 @@ public:
if ( rc == 0 )
{
rc = default_user_quota.update(db);
rc = default_user_quota.update();
}
return rc;
@ -343,12 +350,52 @@ public:
if ( rc == 0 )
{
rc = default_group_quota.update(db);
rc = default_group_quota.update();
}
return rc;
};
// -----------------------------------------------------------------------
// System attributes
// -----------------------------------------------------------------------
/**
* Reads a System attribute from the DB
* @param attr_name name of the attribute
* @param cb Callback that will receive the attribute in XML
* @return 0 on success
*/
int select_sys_attribute(const string& attr_name, string& attr_xml)
{
return system_db->select_sys_attribute(attr_name, attr_xml);
};
/**
* Writes a system attribute in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert_sys_attribute(
const string& attr_name,
const string& xml_attr,
string& error_str)
{
return system_db->insert_sys_attribute(attr_name, xml_attr, error_str);
};
/**
* Updates the system attribute in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update_sys_attribute(
const string& attr_name,
const string& xml_attr,
string& error_str)
{
return system_db->update_sys_attribute(attr_name, xml_attr, error_str);
};
private:
// -----------------------------------------------------------------------
@ -366,9 +413,10 @@ private:
"/DEFAULT_GROUP_QUOTAS/NETWORK_QUOTA",
"/DEFAULT_GROUP_QUOTAS/IMAGE_QUOTA",
"/DEFAULT_GROUP_QUOTAS/VM_QUOTA"),
db(0),vmpool(0),hpool(0),vnpool(0),
upool(0),ipool(0),gpool(0),tpool(0),dspool(0),clpool(0),docpool(0),
lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0),aclm(0),imagem(0)
system_db(0), db(0), vmpool(0), hpool(0), vnpool(0),
upool(0), ipool(0), gpool(0), tpool(0), dspool(0), clpool(0),
docpool(0), lcm(0), vmm(0), im(0), tm(0), dm(0), rm(0), hm(0), authm(0),
aclm(0), imagem(0)
{
const char * nl = getenv("ONE_LOCATION");
@ -514,6 +562,11 @@ private:
{
delete db;
}
if ( system_db != 0 )
{
delete system_db;
}
};
Nebula& operator=(Nebula const&){return *this;};
@ -548,6 +601,11 @@ private:
DefaultQuotas default_user_quota;
DefaultQuotas default_group_quota;
// ---------------------------------------------------------------
// The system database
// ---------------------------------------------------------------
SystemDB * system_db;
// ---------------------------------------------------------------
// Nebula Pools
@ -585,34 +643,6 @@ private:
// ---------------------------------------------------------------
friend void nebula_signal_handler (int sig);
/**
* Bootstraps the database control tables
*
* @return 0 on success
*/
int bootstrap();
/**
* Callback function for the check_db_version method. Stores the read
* version in loaded_db_version
* @param _loaded_db_version returned columns
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
int select_cb(void *_loaded_db_version, int num, char **values,
char **names);
/**
* Reads the current DB version.
*
* @return 0 on success,
* -1 if there is a version mismatch,
* -2 if the DB needs a bootstrap
*/
int check_db_version();
};
#endif /*NEBULA_H_*/

147
include/SystemDB.h Normal file
View File

@ -0,0 +1,147 @@
/* -------------------------------------------------------------------------- */
/* 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 SYSTEM_DB_H_
#define SYSTEM_DB_H_
#include "SqlDB.h"
#include "Callbackable.h"
class Nebula;
/**
* This class represents the OpenNebula core system data tables:
* - pool_control
* - db_versioning
* - system attributes
*/
class SystemDB: public Callbackable
{
public:
/**
* Reads a System attribute from the DB
* @param attr_name name of the attribute
* @param attr_xml the attribute in a XML document
* @return 0 on success
*/
int select_sys_attribute(const string& attr_name, string& attr_zml);
/**
* Writes a system attribute in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert_sys_attribute(
const string& attr_name,
const string& xml_attr,
string& error_str)
{
return insert_replace(attr_name, xml_attr, false, error_str);
};
/**
* Updates the system attribute in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update_sys_attribute(
const string& attr_name,
const string& xml_attr,
string& error_str)
{
return insert_replace(attr_name, xml_attr, true, error_str);
};
private:
friend class Nebula; //Only for Nebula class
SystemDB(SqlDB *_db):db(_db){};
~SystemDB(){};
// Pool control table
static const char * pc_names;
static const char * pc_bootstrap;
static const char * pc_table;
// DB versioning table
static const char * ver_names;
static const char * ver_bootstrap;
static const char * ver_table;
// System attributes table
static const char * sys_names;
static const char * sys_bootstrap;
static const char * sys_table;
// Pointer to the db database
SqlDB *db;
/**
* Execute an INSERT or REPLACE Sql query for a system attribute.
* @param db The SQL DB
* @param replace Execute an INSERT or a REPLACE
* @param error_str Returns the error reason, if any
* @return 0 one success
*/
int insert_replace(const string& attr_name,
const string& xml_attr,
bool replace,
string& error_str);
/**
* Bootstraps the database control tables
*
* @return 0 on success
*/
int bootstrap();
/**
* Callback function for the check_db_version method. Stores the read
* version in loaded_db_version
* @param _loaded_db_version returned columns
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
int select_cb(void *_loaded_db_version,
int num,
char **values,
char **names);
/**
* Callback function for selecting system attributes
*/
int select_attr_cb(void *_attr_xml,
int num,
char **values,
char **names);
/**
* Reads the current DB version.
*
* @return 0 on success,
* -1 if there is a version mismatch,
* -2 if the DB needs a bootstrap
*/
int check_db_version();
};
#endif //SYSTEM_DB_H

View File

@ -33,6 +33,238 @@
using namespace std;
// Pool control table
const char * SystemDB::pc_table = "pool_control";
const char * SystemDB::pc_names = "tablename, last_oid";
const char * SystemDB::pc_bootstrap = "CREATE TABLE pool_control "
"(tablename VARCHAR(32) PRIMARY KEY, last_oid BIGINT UNSIGNED)";
// DB versioning table
const char * SystemDB::ver_table = "db_versioning";
const char * SystemDB::ver_names = "oid, version, timestamp, comment";
const char * SystemDB::ver_bootstrap = "CREATE TABLE db_versioning "
"(oid INTEGER PRIMARY KEY, version VARCHAR(256), timestamp INTEGER, "
"comment VARCHAR(256))";
// System attributes table
const char * SystemDB::sys_table = "system_attributes";
const char * SystemDB::sys_names = "name, body";
const char * SystemDB::sys_bootstrap = "CREATE TABLE IF NOT EXISTS"
" system_attributes (name VARCHAR(128) PRIMARY KEY, body TEXT)";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::bootstrap()
{
int rc;
ostringstream oss;
// ------------------------------------------------------------------------
// pool control, tracks the last ID's assigned to objects
// ------------------------------------------------------------------------
oss.str(pc_bootstrap);
rc = db->exec(oss);
// ------------------------------------------------------------------------
// db versioning, version of OpenNebula. Insert this version number
// ------------------------------------------------------------------------
oss.str(ver_bootstrap);
rc += db->exec(oss);
oss.str("");
oss << "INSERT INTO " << ver_table << " (" << ver_names << ") "
<< "VALUES (0, '" << Nebula::db_version() << "', " << time(0)
<< ", '" << Nebula::version() << " daemon bootstrap')";
rc += db->exec(oss);
// ------------------------------------------------------------------------
// system , version of OpenNebula. Insert this version number
// ------------------------------------------------------------------------
oss.str(sys_bootstrap);
rc += db->exec(oss);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::select_cb(void *_loaded_db_version, int num, char **values,
char **names)
{
istringstream iss;
string * loaded_db_version;
loaded_db_version = static_cast<string *>(_loaded_db_version);
if ( (values[0]) && (num == 1) )
{
*loaded_db_version = values[0];
}
return 0;
};
/* -------------------------------------------------------------------------- */
int SystemDB::check_db_version()
{
int rc;
ostringstream oss;
string loaded_db_version = "";
// Try to read latest version
set_callback( static_cast<Callbackable::Callback>(&SystemDB::select_cb),
static_cast<void *>(&loaded_db_version) );
oss << "SELECT version FROM " << ver_table
<< " WHERE oid=(SELECT MAX(oid) FROM " << ver_table << ")";
db->exec(oss, this);
oss.str("");
unset_callback();
if( loaded_db_version == "" )
{
// Table user_pool is present for all OpenNebula versions, and it
// always contains at least the oneadmin user.
oss << "SELECT MAX(oid) FROM user_pool";
rc = db->exec(oss);
oss.str("");
if( rc != 0 ) // Database needs bootstrap
{
return -2;
}
}
if( Nebula::db_version() != loaded_db_version )
{
oss << "Database version mismatch. "
<< "Installed " << Nebula::version() << " uses DB version '"
<< Nebula::db_version() << "', and existing DB version is '"
<< loaded_db_version << "'.";
NebulaLog::log("ONE",Log::ERROR,oss);
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::insert_replace(
const string& attr_name,
const string& xml_attr,
bool replace,
string& err)
{
ostringstream oss;
int rc;
char * sql_xml;
sql_xml = db->escape_str(xml_attr.c_str());
if ( sql_xml == 0 )
{
goto error_body;
}
if ( ObjectXML::validate_xml(sql_xml) != 0 )
{
goto error_xml;
}
if ( replace )
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
// Construct the SQL statement to Insert or Replace
oss <<" INTO "<< sys_table <<
" ("<< sys_names <<") VALUES ("
<< "'" << attr_name << "',"
<< "'" << sql_xml << "')";
rc = db->exec(oss);
db->free_str(sql_xml);
return rc;
error_xml:
db->free_str(sql_xml);
error_body:
err = "Error inserting system attribute in DB.";
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::select_attr_cb(void * _xml_attr,
int num,
char ** values,
char ** names)
{
istringstream iss;
string * xml_attr;
xml_attr = static_cast<string *>(_xml_attr);
if ( (values[0]) && (num == 1) )
{
*xml_attr = values[0];
}
return 0;
};
/* -------------------------------------------------------------------------- */
int SystemDB::select_sys_attribute(const string& attr_name, string& attr_xml)
{
ostringstream oss;
int rc;
set_callback(static_cast<Callbackable::Callback>(&SystemDB::select_attr_cb),
static_cast<void *>(&attr_xml) );
oss << "SELECT body FROM " << sys_table << " WHERE name = '"
<< attr_name << "'";
rc = db->exec(oss, this);
unset_callback();
if (rc != 0)
{
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -219,8 +451,15 @@ void Nebula::start()
}
}
// ---------------------------------------------------------------------
// Prepare the SystemDB and check versions
// ---------------------------------------------------------------------
NebulaLog::log("ONE",Log::INFO,"Checking database version.");
rc = check_db_version();
system_db = new SystemDB(db);
rc = system_db->check_db_version();
if( rc == -1 )
{
@ -245,14 +484,16 @@ void Nebula::start()
rc += ClusterPool::bootstrap(db);
rc += DocumentPool::bootstrap(db);
rc += DefaultQuotas::bootstrap(db);
// Create the versioning table only if bootstrap went well
// Create the system tables only if bootstrap went well
if ( rc == 0 )
{
rc += bootstrap();
rc += system_db->bootstrap();
}
// Insert default system attributes
rc += default_user_quota.insert();
rc += default_group_quota.insert();
if ( rc != 0 )
{
throw runtime_error("Error bootstrapping database.");
@ -343,8 +584,8 @@ void Nebula::start()
dspool = new DatastorePool(db);
default_user_quota.select(db);
default_group_quota.select(db);
default_user_quota.select();
default_group_quota.select();
}
catch (exception&)
{
@ -679,103 +920,3 @@ void Nebula::start()
NebulaLog::log("ONE", Log::INFO, "All modules finalized, exiting.\n");
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Nebula::bootstrap()
{
int rc;
ostringstream oss;
string error;
oss << "CREATE TABLE pool_control (tablename VARCHAR(32) PRIMARY KEY, "
"last_oid BIGINT UNSIGNED)";
rc = db->exec(oss);
oss.str("");
oss << "CREATE TABLE db_versioning (oid INTEGER PRIMARY KEY, "
"version VARCHAR(256), timestamp INTEGER, comment VARCHAR(256))";
rc += db->exec(oss);
oss.str("");
oss << "INSERT INTO db_versioning (oid, version, timestamp, comment) "
<< "VALUES (0, '" << db_version() << "', " << time(0)
<< ", '" << version() << " daemon bootstrap')";
rc += db->exec(oss);
rc += default_user_quota.insert(db, error);
rc += default_group_quota.insert(db, error);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Nebula::check_db_version()
{
int rc;
ostringstream oss;
string loaded_db_version = "";
// Try to read latest version
set_callback( static_cast<Callbackable::Callback>(&Nebula::select_cb),
static_cast<void *>(&loaded_db_version) );
oss << "SELECT version FROM db_versioning "
<< "WHERE oid=(SELECT MAX(oid) FROM db_versioning)";
db->exec(oss, this);
oss.str("");
unset_callback();
if( loaded_db_version == "" )
{
// Table user_pool is present for all OpenNebula versions, and it
// always contains at least the oneadmin user.
oss << "SELECT MAX(oid) FROM user_pool";
rc = db->exec(oss);
oss.str("");
if( rc != 0 ) // Database needs bootstrap
{
return -2;
}
}
if( db_version() != loaded_db_version )
{
oss << "Database version mismatch. "
<< "Installed " << version() << " uses DB version '" << db_version()
<< "', and existing DB version is '"
<< loaded_db_version << "'.";
NebulaLog::log("ONE",Log::ERROR,oss);
return -1;
}
return 0;
}
int Nebula::select_cb(void *_loaded_db_version, int num, char **values,
char **names)
{
istringstream iss;
string * loaded_db_version;
loaded_db_version = static_cast<string *>(_loaded_db_version);
if ( (values[0]) && (num == 1) )
{
*loaded_db_version = values[0];
}
return 0;
};

View File

@ -23,6 +23,7 @@ lib_name='nebula_core'
# Sources to generate the library
source_files=[
'SystemDB.cc',
'Nebula.cc',
'NebulaTemplate.cc',
]

252
src/nebula/SystemDB.cc Normal file
View File

@ -0,0 +1,252 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
#include "Nebula.h"
#include "SystemDB.h"
using namespace std;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// Pool control table
const char * SystemDB::pc_table = "pool_control";
const char * SystemDB::pc_names = "tablename, last_oid";
const char * SystemDB::pc_bootstrap = "CREATE TABLE pool_control "
"(tablename VARCHAR(32) PRIMARY KEY, last_oid BIGINT UNSIGNED)";
// DB versioning table
const char * SystemDB::ver_table = "db_versioning";
const char * SystemDB::ver_names = "oid, version, timestamp, comment";
const char * SystemDB::ver_bootstrap = "CREATE TABLE db_versioning "
"(oid INTEGER PRIMARY KEY, version VARCHAR(256), timestamp INTEGER, "
"comment VARCHAR(256))";
// System attributes table
const char * SystemDB::sys_table = "system_attributes";
const char * SystemDB::sys_names = "name, body";
const char * SystemDB::sys_bootstrap = "CREATE TABLE IF NOT EXISTS"
" system_attributes (name VARCHAR(128) PRIMARY KEY, body TEXT)";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::bootstrap()
{
int rc;
ostringstream oss;
// ------------------------------------------------------------------------
// pool control, tracks the last ID's assigned to objects
// ------------------------------------------------------------------------
oss.str(pc_bootstrap);
rc = db->exec(oss);
// ------------------------------------------------------------------------
// db versioning, version of OpenNebula. Insert this version number
// ------------------------------------------------------------------------
oss.str(ver_bootstrap);
rc += db->exec(oss);
oss.str("");
oss << "INSERT INTO " << ver_table << " (" << ver_names << ") "
<< "VALUES (0, '" << Nebula::db_version() << "', " << time(0)
<< ", '" << Nebula::version() << " daemon bootstrap')";
rc += db->exec(oss);
// ------------------------------------------------------------------------
// system , version of OpenNebula. Insert this version number
// ------------------------------------------------------------------------
oss.str(sys_bootstrap);
rc += db->exec(oss);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::select_cb(void *_loaded_db_version, int num, char **values,
char **names)
{
istringstream iss;
string * loaded_db_version;
loaded_db_version = static_cast<string *>(_loaded_db_version);
if ( (values[0]) && (num == 1) )
{
*loaded_db_version = values[0];
}
return 0;
};
/* -------------------------------------------------------------------------- */
int SystemDB::check_db_version()
{
int rc;
ostringstream oss;
string loaded_db_version = "";
// Try to read latest version
set_callback( static_cast<Callbackable::Callback>(&SystemDB::select_cb),
static_cast<void *>(&loaded_db_version) );
oss << "SELECT version FROM " << ver_table
<< " WHERE oid=(SELECT MAX(oid) FROM " << ver_table << ")";
db->exec(oss, this);
oss.str("");
unset_callback();
if( loaded_db_version == "" )
{
// Table user_pool is present for all OpenNebula versions, and it
// always contains at least the oneadmin user.
oss << "SELECT MAX(oid) FROM user_pool";
rc = db->exec(oss);
oss.str("");
if( rc != 0 ) // Database needs bootstrap
{
return -2;
}
}
if( Nebula::db_version() != loaded_db_version )
{
oss << "Database version mismatch. "
<< "Installed " << Nebula::version() << " uses DB version '"
<< Nebula::db_version() << "', and existing DB version is '"
<< loaded_db_version << "'.";
NebulaLog::log("ONE",Log::ERROR,oss);
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::insert_replace(
const string& attr_name,
const string& xml_attr,
bool replace,
string& err)
{
ostringstream oss;
int rc;
char * sql_xml;
sql_xml = db->escape_str(xml_attr.c_str());
if ( sql_xml == 0 )
{
goto error_body;
}
if ( ObjectXML::validate_xml(sql_xml) != 0 )
{
goto error_xml;
}
if ( replace )
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
// Construct the SQL statement to Insert or Replace
oss <<" INTO "<< sys_table << " ("<< sys_names <<") VALUES ("
<< "'" << attr_name << "'," << "'" << sql_xml << "')";
rc = db->exec(oss);
db->free_str(sql_xml);
return rc;
error_xml:
db->free_str(sql_xml);
error_body:
err = "Error inserting system attribute in DB.";
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::select_attr_cb(void * _xml_attr,
int num,
char ** values,
char ** names)
{
istringstream iss;
string * xml_attr;
xml_attr = static_cast<string *>(_xml_attr);
if ( (values[0]) && (num == 1) )
{
*xml_attr = values[0];
}
return 0;
};
/* -------------------------------------------------------------------------- */
int SystemDB::select_sys_attribute(const string& attr_name, string& attr_xml)
{
ostringstream oss;
int rc;
set_callback(static_cast<Callbackable::Callback>(&SystemDB::select_attr_cb),
static_cast<void *>(&attr_xml) );
oss << "SELECT body FROM " << sys_table << " WHERE name = '"
<< attr_name << "'";
rc = db->exec(oss, this);
unset_callback();
if (rc != 0)
{
return -1;
}
return 0;
}

View File

@ -17,14 +17,7 @@
#include "DefaultQuotas.h"
#include "ObjectXML.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const char * DefaultQuotas::table = "system_attributes";
const char * DefaultQuotas::db_names = "name, body";
const char * DefaultQuotas::db_bootstrap = "CREATE TABLE IF NOT EXISTS"
" system_attributes (name VARCHAR(128) PRIMARY KEY, body TEXT)";
#include "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -61,84 +54,39 @@ int DefaultQuotas::from_xml(const string& xml)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DefaultQuotas::select(SqlDB *db)
int DefaultQuotas::select()
{
ostringstream oss;
int rc;
set_callback(
static_cast<Callbackable::Callback>(&DefaultQuotas::select_cb));
oss << "SELECT body FROM " << table << " WHERE name = '" << root_elem << "'";
rc = db->exec(oss, this);
unset_callback();
if (rc != 0)
{
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DefaultQuotas::insert_replace(SqlDB *db, bool replace, string& error_str)
{
ostringstream oss;
int rc;
string xml_body;
Nebula& nd = Nebula::instance();
char * sql_xml;
sql_xml = db->escape_str(to_xml(xml_body).c_str());
if ( sql_xml == 0 )
if ( nd.select_sys_attribute(root_elem, xml_body) != 0 )
{
goto error_body;
}
if ( ObjectXML::validate_xml(sql_xml) != 0 )
{
goto error_xml;
}
if ( replace )
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
// Construct the SQL statement to Insert or Replace
oss <<" INTO "<<table <<" ("<< db_names <<") VALUES ("
<< "'" << root_elem << "',"
<< "'" << sql_xml << "')";
rc = db->exec(oss);
db->free_str(sql_xml);
return rc;
error_xml:
db->free_str(sql_xml);
error_str = "Error transforming the Quotas to XML.";
return -1;
}
error_body:
error_str = "Error inserting Quotas in DB.";
return -1;
return from_xml(xml_body);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DefaultQuotas::insert()
{
string xml_body;
string error;
Nebula& nd = Nebula::instance();
return nd.insert_sys_attribute(root_elem, to_xml(xml_body), error);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DefaultQuotas::update()
{
string xml_body;
string error;
Nebula& nd = Nebula::instance();
return nd.update_sys_attribute(root_elem, to_xml(xml_body), error);
}

View File

@ -323,8 +323,7 @@ void Quota::cleanup_quota(const string& qid)
VectorAttribute * q;
map<string, Attribute *>::iterator q_it;
float usage, usage_tmp, limit_tmp, implicit_limit;
bool default_limit;
float usage, limit, implicit_limit;
if ( get_quota(qid, &q, q_it) == -1)
{
@ -345,29 +344,25 @@ void Quota::cleanup_quota(const string& qid)
implicit_limit = -1;
}
default_limit = true;
usage = 0;
for (int i=0; i < num_metrics; i++)
{
string metrics_used = metrics[i];
metrics_used += "_USED";
q->vector_value(metrics[i], limit_tmp);
q->vector_value(metrics_used.c_str(), usage_tmp);
q->vector_value(metrics[i], limit);
q->vector_value(metrics_used.c_str(), usage);
default_limit = (default_limit && limit_tmp == implicit_limit );
usage += usage_tmp;
if ( usage != 0 || limit != implicit_limit )
{
return;
}
}
if ( usage == 0 && default_limit )
{
delete static_cast<Attribute *>(q_it->second);
attributes.erase(q_it);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */