mirror of
https://github.com/OpenNebula/one.git
synced 2024-12-22 13:33:52 +03:00
feature #206: VirtualMachine uses SqlDB
This commit is contained in:
parent
aeb27c1004
commit
ce7d0681e3
@ -17,17 +17,10 @@
|
||||
#ifndef HISTORY_H_
|
||||
#define HISTORY_H_
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "ObjectSQL.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" int history_select_cb (
|
||||
void * _history,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names);
|
||||
|
||||
/**
|
||||
* The History class, it represents an execution record of a Virtual Machine.
|
||||
*/
|
||||
@ -37,23 +30,23 @@ class History:public ObjectSQL
|
||||
public:
|
||||
enum MigrationReason
|
||||
{
|
||||
NONE, /** < Normal termination in host */
|
||||
ERROR, /** < The VM was migrated because of an error */
|
||||
NONE, /** < Normal termination in host */
|
||||
ERROR, /** < The VM was migrated because of an error */
|
||||
STOP_RESUME,/** < The VM was migrated because of a stop/resume request*/
|
||||
USER, /** < The VM was migrated because of an explicit request */
|
||||
CANCEL /** < The VM was migrated because of an explicit cancel */
|
||||
USER, /** < The VM was migrated because of an explicit request */
|
||||
CANCEL /** < The VM was migrated because of an explicit cancel */
|
||||
};
|
||||
|
||||
History(int oid, int _seq = -1);
|
||||
|
||||
History(
|
||||
int oid,
|
||||
int seq,
|
||||
int hid,
|
||||
string& hostname,
|
||||
string& vm_dir,
|
||||
string& vmm,
|
||||
string& tm);
|
||||
int oid,
|
||||
int seq,
|
||||
int hid,
|
||||
string& hostname,
|
||||
string& vm_dir,
|
||||
string& vmm,
|
||||
string& tm);
|
||||
|
||||
~History(){};
|
||||
|
||||
@ -77,9 +70,10 @@ public:
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
|
||||
private:
|
||||
friend class VirtualMachine;
|
||||
friend class VirtualMachinePool;
|
||||
|
||||
// ----------------------------------------
|
||||
// DataBase implementation variables
|
||||
@ -166,25 +160,19 @@ private:
|
||||
string checkpoint_file;
|
||||
string rdeployment_file;
|
||||
|
||||
friend int history_select_cb (
|
||||
void * _history,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names);
|
||||
|
||||
/**
|
||||
* Writes the history record in the DB
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int insert(SqliteDB * db);
|
||||
int insert(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Reads the history record from the DB
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int select(SqliteDB * db);
|
||||
int select(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Removes the all history records from the DB
|
||||
@ -192,26 +180,26 @@ private:
|
||||
* @return 0 on success.
|
||||
|
||||
*/
|
||||
int drop(SqliteDB * db);
|
||||
int drop(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Updates the history record
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int update(SqliteDB * db)
|
||||
int update(SqlDB * db)
|
||||
{
|
||||
return insert(db);
|
||||
}
|
||||
return insert(db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to unmarshall a history object
|
||||
* Callback function to unmarshall a history object (History::select)
|
||||
* @param num the number of columns read from the DB
|
||||
* @para names the column names
|
||||
* @para vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int unmarshall(int num, char **names, char ** values);
|
||||
int select_cb(void *nil, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Function to unmarshall a History object into an output stream with XML
|
||||
@ -222,10 +210,7 @@ private:
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int unmarshall(ostringstream& oss,
|
||||
int num,
|
||||
char ** names,
|
||||
char ** values);
|
||||
static int dump(ostringstream& oss, int num, char **names, char **values);
|
||||
};
|
||||
|
||||
#endif /*HISTORY_H_*/
|
||||
#endif /*HISTORY_H_*/
|
@ -27,9 +27,6 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" int vm_select_cb (void * _vm, int num,char ** values, char ** names);
|
||||
extern "C" int vm_dump_cb (void * _oss, int num,char ** values, char ** names);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -125,7 +122,7 @@ public:
|
||||
* Function to print the VirtualMachine object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
@ -133,10 +130,10 @@ public:
|
||||
* Function to print the VirtualMachine object into a string in
|
||||
* XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Dynamic Info
|
||||
// ------------------------------------------------------------------------
|
||||
@ -291,7 +288,7 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the TM driver name for the previous host. The
|
||||
* Returns the TM driver name for the previous host. The
|
||||
* hasPreviousHistory() function MUST be called before this one.
|
||||
* @return the TM mad name
|
||||
*/
|
||||
@ -608,19 +605,19 @@ public:
|
||||
{
|
||||
vm_template.to_xml(xml);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a string and substitute variables (e.g. $NAME) using the VM
|
||||
* Parse a string and substitute variables (e.g. $NAME) using the VM
|
||||
* template values:
|
||||
* @param attribute, the string to be parsed
|
||||
* @param parsed, the resulting parsed string
|
||||
* @return 0 on success.
|
||||
*/
|
||||
*/
|
||||
int parse_template_attribute(const string& attribute,
|
||||
string& parsed);
|
||||
|
||||
|
||||
/**
|
||||
* Parse a string and substitute variables (e.g. $NAME) using the VM
|
||||
* Parse a string and substitute variables (e.g. $NAME) using the VM
|
||||
* template values (blocking-free version for cross references):
|
||||
* @param vm_id ID of the VM used to substitute the variables
|
||||
* @param attribute, the string to be parsed
|
||||
@ -632,14 +629,14 @@ public:
|
||||
const string& attribute,
|
||||
string& parsed,
|
||||
char ** error_msg)
|
||||
{
|
||||
{
|
||||
return parse_attribute(0,vm_id,attribute,parsed,error_msg);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// States
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Returns the VM state (Dispatch Manager)
|
||||
* @return the VM state
|
||||
@ -747,18 +744,6 @@ private:
|
||||
// -------------------------------------------------------------------------
|
||||
friend class VirtualMachinePool;
|
||||
|
||||
friend int vm_select_cb (
|
||||
void * _vm,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names);
|
||||
|
||||
friend int vm_dump_cb (
|
||||
void * _vm,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names);
|
||||
|
||||
// *************************************************************************
|
||||
// Virtual Machine Attributes
|
||||
// *************************************************************************
|
||||
@ -857,9 +842,9 @@ private:
|
||||
|
||||
/**
|
||||
* Log class for the virtual machine, it writes log messages in
|
||||
* $ONE_LOCATION/var/$VID/vm.log
|
||||
* $ONE_LOCATION/var/$VID/vm.log
|
||||
* or, in case that OpenNebula is installed in root
|
||||
* /var/log/one/$VM_ID.log
|
||||
* /var/log/one/$VM_ID.log
|
||||
*/
|
||||
Log * _log;
|
||||
|
||||
@ -870,44 +855,33 @@ private:
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the VirtualMachine
|
||||
*/
|
||||
static void bootstrap(SqliteDB * db)
|
||||
static void bootstrap(SqlDB * db)
|
||||
{
|
||||
db->exec(VirtualMachine::db_bootstrap);
|
||||
ostringstream oss_vm(VirtualMachine::db_bootstrap);
|
||||
ostringstream oss_tmpl(VirtualMachineTemplate::db_bootstrap);
|
||||
ostringstream oss_hist(History::db_bootstrap);
|
||||
|
||||
db->exec(VirtualMachineTemplate::db_bootstrap);
|
||||
|
||||
db->exec(History::db_bootstrap);
|
||||
db->exec(oss_vm);
|
||||
db->exec(oss_tmpl);
|
||||
db->exec(oss_hist);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to unmarshall a VM object, an associated classes.
|
||||
* Callback function to unmarshall a VirtualMachine object
|
||||
* (VirtualMachine::select)
|
||||
* @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 unmarshall(int num, char **names, char ** values);
|
||||
|
||||
/**
|
||||
* Function to unmarshall a VM object into an output stream with XML
|
||||
* format.
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int unmarshall(ostringstream& oss,
|
||||
int num,
|
||||
char ** names,
|
||||
char ** values);
|
||||
int select_cb(void *nil, int num, char **names, char ** values);
|
||||
|
||||
/**
|
||||
* Updates the VM history record
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_history(SqliteDB * db)
|
||||
int update_history(SqlDB * db)
|
||||
{
|
||||
if ( history != 0 )
|
||||
{
|
||||
@ -922,7 +896,7 @@ private:
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_previous_history(SqliteDB * db)
|
||||
int update_previous_history(SqlDB * db)
|
||||
{
|
||||
if ( previous_history != 0 )
|
||||
{
|
||||
@ -941,9 +915,9 @@ private:
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_template_attribute(
|
||||
SqliteDB * db,
|
||||
string& name,
|
||||
string& value)
|
||||
SqlDB * db,
|
||||
string& name,
|
||||
string& value)
|
||||
{
|
||||
SingleAttribute * sattr;
|
||||
int rc;
|
||||
@ -966,7 +940,7 @@ private:
|
||||
* @param attribute the new attribute for the template
|
||||
* @return 0 on success
|
||||
*/
|
||||
int insert_template_attribute(SqliteDB * db, Attribute * attribute)
|
||||
int insert_template_attribute(SqlDB * db, Attribute * attribute)
|
||||
{
|
||||
return vm_template.insert_attribute(db,attribute);
|
||||
}
|
||||
@ -991,13 +965,13 @@ private:
|
||||
* @param parsed, the resulting parsed string
|
||||
* @param error_msg, string describing the syntax error
|
||||
* @return 0 on success.
|
||||
*/
|
||||
*/
|
||||
static int parse_attribute(VirtualMachine * vm,
|
||||
int vm_id,
|
||||
const string& attribute,
|
||||
string& parsed,
|
||||
char ** error_msg);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
//**************************************************************************
|
||||
@ -1042,22 +1016,22 @@ protected:
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select(SqliteDB * db);
|
||||
int select(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Writes the Virtual Machine and its associated template in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int insert(SqliteDB * db);
|
||||
virtual int insert(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Writes/updates the Virtual Machine data fields in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int update(SqliteDB * db);
|
||||
|
||||
virtual int update(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Deletes a VM from the database and all its associated information:
|
||||
* - History records
|
||||
@ -1065,29 +1039,30 @@ protected:
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int drop(SqliteDB * db)
|
||||
virtual int drop(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
int rc;
|
||||
|
||||
rc = vm_template.drop(db);
|
||||
rc = vm_template.drop(db);
|
||||
|
||||
if ( history != 0 )
|
||||
{
|
||||
rc += history->drop(db);
|
||||
}
|
||||
if ( history != 0 )
|
||||
{
|
||||
rc += history->drop(db);
|
||||
}
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the contect of a set of VirtualMachine objects in the given stream
|
||||
* using XML format
|
||||
* @param db pointer to the db
|
||||
* @param oss the output stream
|
||||
* @param where string to filter the VirtualMachine objects
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump(SqliteDB * db, ostringstream& oss, const string& where);
|
||||
static int dump(ostringstream& oss, int num, char ** values, char ** names);
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_MACHINE_H_*/
|
||||
|
@ -32,7 +32,7 @@ class VirtualMachinePool : public PoolSQL
|
||||
{
|
||||
public:
|
||||
|
||||
VirtualMachinePool(SqliteDB * db, vector<const Attribute *> hook_mads);
|
||||
VirtualMachinePool(SqlDB * db, vector<const Attribute *> hook_mads);
|
||||
|
||||
~VirtualMachinePool(){};
|
||||
|
||||
@ -126,11 +126,11 @@ public:
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the VirtualMachine pool
|
||||
*/
|
||||
static void bootstrap(SqliteDB * _db)
|
||||
static void bootstrap(SqlDB * _db)
|
||||
{
|
||||
VirtualMachine::bootstrap(_db);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Dumps the VM pool in XML format. A filter can be also added to the query
|
||||
* Also the hostname where the VirtualMachine is running is added to the
|
||||
@ -140,19 +140,8 @@ public:
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
int dump(ostringstream& oss, const string& where);
|
||||
|
||||
oss << "<VM_POOL>";
|
||||
|
||||
rc = VirtualMachine::dump(db,oss,where);
|
||||
|
||||
oss << "</VM_POOL>";
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Generate context file to be sourced upon VM booting
|
||||
@ -169,6 +158,16 @@ private:
|
||||
{
|
||||
return new VirtualMachine;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to get output the vm pool in XML format
|
||||
* (VirtualMachinePool::dump)
|
||||
* @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 dump_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_MACHINE_POOL_H_*/
|
||||
|
@ -134,44 +134,44 @@ void History::non_persistent_data()
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int History::insert(SqliteDB * db)
|
||||
int History::insert(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
|
||||
int rc;
|
||||
|
||||
char * sql_hostname;
|
||||
char * sql_vm_dir;
|
||||
char * sql_vmm_mad_name;
|
||||
char * sql_tm_mad_name;
|
||||
|
||||
|
||||
if (seq == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
sql_hostname = sqlite3_mprintf("%q",hostname.c_str());
|
||||
|
||||
sql_hostname = db->escape_str(hostname.c_str());
|
||||
|
||||
if ( sql_hostname == 0 )
|
||||
{
|
||||
goto error_hostname;
|
||||
}
|
||||
|
||||
sql_vm_dir = sqlite3_mprintf("%q",vm_dir.c_str());
|
||||
sql_vm_dir = db->escape_str(vm_dir.c_str());
|
||||
|
||||
if ( sql_vm_dir == 0 )
|
||||
{
|
||||
goto error_vm_dir;
|
||||
}
|
||||
|
||||
sql_vmm_mad_name = sqlite3_mprintf("%q",vmm_mad_name.c_str());
|
||||
|
||||
sql_vmm_mad_name = db->escape_str(vmm_mad_name.c_str());
|
||||
|
||||
if ( sql_vmm_mad_name == 0 )
|
||||
{
|
||||
goto error_vmm;
|
||||
}
|
||||
|
||||
sql_tm_mad_name = sqlite3_mprintf("%q",tm_mad_name.c_str());
|
||||
|
||||
sql_tm_mad_name = db->escape_str(tm_mad_name.c_str());
|
||||
|
||||
if ( sql_tm_mad_name == 0 )
|
||||
{
|
||||
@ -198,19 +198,19 @@ int History::insert(SqliteDB * db)
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
sqlite3_free(sql_hostname);
|
||||
sqlite3_free(sql_vm_dir);
|
||||
sqlite3_free(sql_vmm_mad_name);
|
||||
sqlite3_free(sql_tm_mad_name);
|
||||
|
||||
db->free_str(sql_hostname);
|
||||
db->free_str(sql_vm_dir);
|
||||
db->free_str(sql_vmm_mad_name);
|
||||
db->free_str(sql_tm_mad_name);
|
||||
|
||||
return rc;
|
||||
|
||||
|
||||
error_tm:
|
||||
sqlite3_free(sql_vmm_mad_name);
|
||||
db->free_str(sql_vmm_mad_name);
|
||||
error_vmm:
|
||||
sqlite3_free(sql_vm_dir);
|
||||
db->free_str(sql_vm_dir);
|
||||
error_vm_dir:
|
||||
sqlite3_free(sql_hostname);
|
||||
db->free_str(sql_hostname);
|
||||
error_hostname:
|
||||
return -1;
|
||||
}
|
||||
@ -218,7 +218,7 @@ error_hostname:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int History::unmarshall(int num, char **names, char ** values)
|
||||
int History::select_cb(void *nil, int num, char **values, char **names)
|
||||
{
|
||||
if ((!values[VID]) ||
|
||||
(!values[SEQ]) ||
|
||||
@ -243,10 +243,10 @@ int History::unmarshall(int num, char **names, char ** values)
|
||||
|
||||
oid = atoi(values[VID]);
|
||||
seq = atoi(values[SEQ]);
|
||||
|
||||
|
||||
hostname = values[HOSTNAME];
|
||||
vm_dir = values[VM_DIR];
|
||||
|
||||
|
||||
hid = atoi(values[HID]);
|
||||
|
||||
vmm_mad_name = values[VMMMAD];
|
||||
@ -272,12 +272,9 @@ int History::unmarshall(int num, char **names, char ** values)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int History::unmarshall(ostringstream& oss,
|
||||
int num,
|
||||
char ** names,
|
||||
char ** values)
|
||||
int History::dump(ostringstream& oss, int num, char **values, char **names)
|
||||
{
|
||||
if ((!values[VID])||
|
||||
if ((!values[VID])||
|
||||
(!values[SEQ])||
|
||||
(!values[HOSTNAME])||
|
||||
(!values[HID])||
|
||||
@ -290,11 +287,11 @@ int History::unmarshall(ostringstream& oss,
|
||||
(!values[EPILOG_STIME])||
|
||||
(!values[EPILOG_ETIME])||
|
||||
(!values[REASON])||
|
||||
(num != LIMIT))
|
||||
(num != LIMIT))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss <<
|
||||
"<HISTORY>" <<
|
||||
"<SEQ>" << values[SEQ] << "</SEQ>" <<
|
||||
@ -310,34 +307,13 @@ int History::unmarshall(ostringstream& oss,
|
||||
"<EETIME>" << values[EPILOG_ETIME] << "</EETIME>" <<
|
||||
"<REASON>" << values[REASON] << "</REASON>" <<
|
||||
"</HISTORY>";
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
extern "C" int history_select_cb (
|
||||
void * _history,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
History * history;
|
||||
|
||||
history = static_cast<History *>(_history);
|
||||
|
||||
if (history == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return history->unmarshall(num,names,values);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int History::select(SqliteDB * db)
|
||||
int History::select(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
@ -349,15 +325,17 @@ int History::select(SqliteDB * db)
|
||||
|
||||
if ( seq == -1)
|
||||
{
|
||||
oss << "SELECT * FROM history WHERE vid = "<< oid <<
|
||||
" AND seq=(SELECT MAX(seq) FROM history WHERE vid = " << oid << ")";
|
||||
oss << "SELECT * FROM history WHERE vid = "<< oid <<
|
||||
" AND seq=(SELECT MAX(seq) FROM history WHERE vid = " << oid << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "SELECT * FROM history WHERE vid = "<< oid <<" AND seq = "<< seq;
|
||||
oss << "SELECT * FROM history WHERE vid = "<< oid <<" AND seq = "<< seq;
|
||||
}
|
||||
|
||||
rc = db->exec(oss,history_select_cb,(void *) this);
|
||||
set_callback(static_cast<Callbackable::Callback>(&History::select_cb));
|
||||
|
||||
rc = db->exec(oss,this);
|
||||
|
||||
if ( rc == 0 ) // Regenerate non-persistent data
|
||||
{
|
||||
@ -370,7 +348,7 @@ int History::select(SqliteDB * db)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int History::drop(SqliteDB * db)
|
||||
int History::drop(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
@ -424,7 +402,7 @@ string& History::to_str(string& str) const
|
||||
string& History::to_xml(string& xml) const
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
|
||||
oss <<
|
||||
"<HISTORY>" <<
|
||||
"<SEQ>" << seq << "</SEQ>" <<
|
||||
|
@ -87,7 +87,7 @@ const char * VirtualMachine::db_bootstrap = "CREATE TABLE vm_pool ("
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::unmarshall(int num, char **names, char ** values)
|
||||
int VirtualMachine::select_cb(void *nil, int num, char **values, char **names)
|
||||
{
|
||||
if ((values[OID] == 0) ||
|
||||
(values[UID] == 0) ||
|
||||
@ -134,30 +134,9 @@ int VirtualMachine::unmarshall(int num, char **names, char ** values)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
extern "C" int vm_select_cb (
|
||||
void * _vm,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
VirtualMachine * vm;
|
||||
|
||||
vm = static_cast<VirtualMachine *>(_vm);
|
||||
|
||||
if (vm == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vm->unmarshall(num,names,values);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::select(SqliteDB * db)
|
||||
int VirtualMachine::select(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
ostringstream ose;
|
||||
@ -166,15 +145,17 @@ int VirtualMachine::select(SqliteDB * db)
|
||||
int boid;
|
||||
|
||||
string filename;
|
||||
Nebula& nd = Nebula::instance();
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&VirtualMachine::select_cb));
|
||||
|
||||
oss << "SELECT * FROM " << table << " WHERE oid = " << oid;
|
||||
|
||||
boid = oid;
|
||||
oid = -1;
|
||||
|
||||
rc = db->exec(oss,vm_select_cb,(void *) this);
|
||||
|
||||
rc = db->exec(oss,this);
|
||||
|
||||
if ((rc != 0) || (oid != boid ))
|
||||
{
|
||||
@ -208,14 +189,14 @@ int VirtualMachine::select(SqliteDB * db)
|
||||
}
|
||||
else if (history->seq > 0)
|
||||
{
|
||||
previous_history = new History(oid,history->seq - 1);
|
||||
previous_history = new History(oid,history->seq - 1);
|
||||
|
||||
rc = previous_history->select(db);
|
||||
rc = previous_history->select(db);
|
||||
|
||||
if ( rc != 0)
|
||||
{
|
||||
goto error_previous_history;
|
||||
}
|
||||
if ( rc != 0)
|
||||
{
|
||||
goto error_previous_history;
|
||||
}
|
||||
}
|
||||
|
||||
//Create support directory fo this VM
|
||||
@ -230,15 +211,15 @@ int VirtualMachine::select(SqliteDB * db)
|
||||
|
||||
try
|
||||
{
|
||||
_log = new Log(nd.get_vm_log_filename(oid),Log::DEBUG);
|
||||
}
|
||||
_log = new Log(nd.get_vm_log_filename(oid),Log::DEBUG);
|
||||
}
|
||||
catch(exception &e)
|
||||
{
|
||||
ose << "Error creating log: " << e.what();
|
||||
Nebula::log("ONE",Log::ERROR, ose);
|
||||
ose << "Error creating log: " << e.what();
|
||||
Nebula::log("ONE",Log::ERROR, ose);
|
||||
|
||||
_log = 0;
|
||||
}
|
||||
_log = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -258,8 +239,8 @@ error_history:
|
||||
return -1;
|
||||
|
||||
error_previous_history:
|
||||
ose << "Can not get previous history record (seq:" << history->seq
|
||||
<< ") for VM id: " << oid;
|
||||
ose << "Can not get previous history record (seq:" << history->seq
|
||||
<< ") for VM id: " << oid;
|
||||
log("ONE", Log::ERROR, ose);
|
||||
return -1;
|
||||
}
|
||||
@ -267,7 +248,7 @@ error_previous_history:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::insert(SqliteDB * db)
|
||||
int VirtualMachine::insert(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
string name;
|
||||
@ -285,8 +266,8 @@ int VirtualMachine::insert(SqliteDB * db)
|
||||
attr = new SingleAttribute("VMID",value);
|
||||
|
||||
vm_template.set(attr);
|
||||
|
||||
|
||||
|
||||
|
||||
get_template_attribute("NAME",name);
|
||||
|
||||
if ( name.empty() == true )
|
||||
@ -333,25 +314,25 @@ int VirtualMachine::insert(SqliteDB * db)
|
||||
return 0;
|
||||
|
||||
error_update:
|
||||
Nebula::log("ONE",Log::ERROR, "Can not update VM in the database");
|
||||
vm_template.drop(db);
|
||||
return -1;
|
||||
Nebula::log("ONE",Log::ERROR, "Can not update VM in the database");
|
||||
vm_template.drop(db);
|
||||
return -1;
|
||||
|
||||
error_template:
|
||||
Nebula::log("ONE",Log::ERROR, "Can not insert template in the database");
|
||||
release_network_leases();
|
||||
return -1;
|
||||
Nebula::log("ONE",Log::ERROR, "Can not insert template in the database");
|
||||
release_network_leases();
|
||||
return -1;
|
||||
|
||||
error_leases:
|
||||
Nebula::log("ONE",Log::ERROR, "Could not get network lease for VM");
|
||||
release_network_leases();
|
||||
return -1;
|
||||
Nebula::log("ONE",Log::ERROR, "Could not get network lease for VM");
|
||||
release_network_leases();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::update(SqliteDB * db)
|
||||
int VirtualMachine::update(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
@ -359,18 +340,18 @@ int VirtualMachine::update(SqliteDB * db)
|
||||
char * sql_deploy_id;
|
||||
char * sql_name;
|
||||
|
||||
sql_deploy_id = sqlite3_mprintf("%q",deploy_id.c_str());
|
||||
sql_deploy_id = db->escape_str(deploy_id.c_str());
|
||||
|
||||
if ( sql_deploy_id == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
sql_name = sqlite3_mprintf("%q",name.c_str());
|
||||
sql_name = db->escape_str(name.c_str());
|
||||
|
||||
if ( sql_name == 0 )
|
||||
{
|
||||
sqlite3_free(sql_deploy_id);
|
||||
db->free_str(sql_deploy_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -390,8 +371,8 @@ int VirtualMachine::update(SqliteDB * db)
|
||||
net_tx << "," <<
|
||||
net_rx << ")";
|
||||
|
||||
sqlite3_free(sql_deploy_id);
|
||||
sqlite3_free(sql_name);
|
||||
db->free_str(sql_deploy_id);
|
||||
db->free_str(sql_name);
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
@ -401,10 +382,7 @@ int VirtualMachine::update(SqliteDB * db)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::unmarshall(ostringstream& oss,
|
||||
int num,
|
||||
char ** names,
|
||||
char ** values)
|
||||
int VirtualMachine::dump(ostringstream& oss,int num,char **values,char **names)
|
||||
{
|
||||
if ((!values[OID])||
|
||||
(!values[UID])||
|
||||
@ -429,7 +407,7 @@ int VirtualMachine::unmarshall(ostringstream& oss,
|
||||
"<ID>" << values[OID] << "</ID>" <<
|
||||
"<UID>" << values[UID] << "</UID>" <<
|
||||
"<USERNAME>" << values[LIMIT] << "</USERNAME>"<<
|
||||
"<NAME>" << values[NAME] << "</NAME>" <<
|
||||
"<NAME>" << values[NAME] << "</NAME>" <<
|
||||
"<LAST_POLL>"<< values[LAST_POLL]<< "</LAST_POLL>"<<
|
||||
"<STATE>" << values[STATE] << "</STATE>" <<
|
||||
"<LCM_STATE>"<< values[LCM_STATE]<< "</LCM_STATE>"<<
|
||||
@ -441,67 +419,18 @@ int VirtualMachine::unmarshall(ostringstream& oss,
|
||||
"<NET_TX>" << values[NET_TX] << "</NET_TX>" <<
|
||||
"<NET_RX>" << values[NET_RX] << "</NET_RX>";
|
||||
|
||||
History::unmarshall(oss, num-LIMIT-2, names+LIMIT+1, values+LIMIT+1);
|
||||
|
||||
History::dump(oss, num-LIMIT-2, values+LIMIT+1, names+LIMIT+1);
|
||||
|
||||
oss << "</VM>";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
extern "C" int vm_dump_cb (
|
||||
void * _oss,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
ostringstream dbg;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
if (oss == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return VirtualMachine::unmarshall(*oss,num,names,values);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::dump(SqliteDB * db, ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
cmd << "SELECT " << VirtualMachine::table << ".*, "
|
||||
<< "user_pool.user_name, " << History::table << ".* FROM "
|
||||
<< VirtualMachine::table
|
||||
<< " LEFT OUTER JOIN (SELECT *,MAX(seq) FROM "
|
||||
<< History::table << " GROUP BY vid) AS " << History::table
|
||||
<< " ON " << VirtualMachine::table << ".oid = "
|
||||
<< History::table << ".vid LEFT OUTER JOIN (SELECT oid,user_name FROM "
|
||||
<< "user_pool) AS user_pool ON "
|
||||
<< VirtualMachine::table << ".uid = user_pool.oid WHERE "
|
||||
<< VirtualMachine::table << ".state != " << VirtualMachine::DONE;
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " AND " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd,vm_dump_cb,(void *) &oss);
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachine::add_history(
|
||||
int hid,
|
||||
int hid,
|
||||
string& hostname,
|
||||
string& vm_dir,
|
||||
string& vmm_mad,
|
||||
@ -520,7 +449,7 @@ void VirtualMachine::add_history(
|
||||
|
||||
if (previous_history != 0)
|
||||
{
|
||||
delete previous_history;
|
||||
delete previous_history;
|
||||
}
|
||||
|
||||
previous_history = history;
|
||||
@ -534,29 +463,29 @@ void VirtualMachine::add_history(
|
||||
|
||||
void VirtualMachine::cp_history()
|
||||
{
|
||||
History * htmp;
|
||||
History * htmp;
|
||||
|
||||
if (history == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (history == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
htmp = new History(oid,
|
||||
history->seq + 1,
|
||||
history->hid,
|
||||
history->hostname,
|
||||
history->vm_dir,
|
||||
history->vmm_mad_name,
|
||||
history->tm_mad_name);
|
||||
htmp = new History(oid,
|
||||
history->seq + 1,
|
||||
history->hid,
|
||||
history->hostname,
|
||||
history->vm_dir,
|
||||
history->vmm_mad_name,
|
||||
history->tm_mad_name);
|
||||
|
||||
if ( previous_history != 0 )
|
||||
{
|
||||
delete previous_history;
|
||||
}
|
||||
if ( previous_history != 0 )
|
||||
{
|
||||
delete previous_history;
|
||||
}
|
||||
|
||||
previous_history = history;
|
||||
previous_history = history;
|
||||
|
||||
history = htmp;
|
||||
history = htmp;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -564,26 +493,26 @@ void VirtualMachine::cp_history()
|
||||
|
||||
void VirtualMachine::cp_previous_history()
|
||||
{
|
||||
History * htmp;
|
||||
History * htmp;
|
||||
|
||||
if ( previous_history == 0 || history == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( previous_history == 0 || history == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
htmp = new History(oid,
|
||||
history->seq + 1,
|
||||
previous_history->hid,
|
||||
previous_history->hostname,
|
||||
previous_history->vm_dir,
|
||||
previous_history->vmm_mad_name,
|
||||
previous_history->tm_mad_name);
|
||||
htmp = new History(oid,
|
||||
history->seq + 1,
|
||||
previous_history->hid,
|
||||
previous_history->hostname,
|
||||
previous_history->vm_dir,
|
||||
previous_history->vmm_mad_name,
|
||||
previous_history->tm_mad_name);
|
||||
|
||||
delete previous_history;
|
||||
delete previous_history;
|
||||
|
||||
previous_history = history;
|
||||
previous_history = history;
|
||||
|
||||
history = htmp;
|
||||
history = htmp;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -667,10 +596,10 @@ int VirtualMachine::get_network_leases()
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( vn->get_uid() != uid && vn->get_uid() != 0 && uid != 0)
|
||||
if ( vn->get_uid() != uid && vn->get_uid() != 0 && uid != 0)
|
||||
{
|
||||
ostringstream ose;
|
||||
ose << "Owner " << uid << " of the VM doesn't have ownership of Virtual Network "
|
||||
ose << "Owner " << uid << " of the VM doesn't have ownership of Virtual Network "
|
||||
<< vn->get_uid();
|
||||
Nebula::log("VMM", Log::ERROR, ose);
|
||||
return -1;
|
||||
@ -707,7 +636,7 @@ int VirtualMachine::get_network_leases()
|
||||
|
||||
if ( !model.empty() )
|
||||
{
|
||||
new_nic.insert(make_pair("MODEL",model));
|
||||
new_nic.insert(make_pair("MODEL",model));
|
||||
}
|
||||
|
||||
nic->replace(new_nic);
|
||||
@ -738,7 +667,7 @@ void VirtualMachine::release_network_leases()
|
||||
|
||||
for(int i=0; i<num_nics; i++)
|
||||
{
|
||||
VectorAttribute const * nic =
|
||||
VectorAttribute const * nic =
|
||||
dynamic_cast<VectorAttribute const * >(nics[i]);
|
||||
|
||||
if ( nic == 0 )
|
||||
@ -838,17 +767,17 @@ int VirtualMachine::parse_template_attribute(const string& attribute,
|
||||
{
|
||||
int rc;
|
||||
char * err = 0;
|
||||
|
||||
|
||||
rc = parse_attribute(this,-1,attribute,parsed,&err);
|
||||
|
||||
|
||||
if ( rc != 0 && err != 0 )
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
|
||||
oss << "Error parsing: " << attribute << ". " << err;
|
||||
log("VM",Log::ERROR,oss);
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -858,19 +787,19 @@ int VirtualMachine::parse_template_attribute(const string& attribute,
|
||||
pthread_mutex_t VirtualMachine::lex_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
{
|
||||
typedef struct yy_buffer_state * YY_BUFFER_STATE;
|
||||
|
||||
int vm_var_parse (VirtualMachine * vm,
|
||||
int vm_id,
|
||||
int vm_id,
|
||||
ostringstream * parsed,
|
||||
char ** errmsg);
|
||||
|
||||
|
||||
int vm_var_lex_destroy();
|
||||
|
||||
YY_BUFFER_STATE vm_var__scan_string(const char * str);
|
||||
|
||||
void vm_var__delete_buffer(YY_BUFFER_STATE);
|
||||
void vm_var__delete_buffer(YY_BUFFER_STATE);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -922,9 +851,9 @@ error_yy:
|
||||
ostream& operator<<(ostream& os, const VirtualMachine& vm)
|
||||
{
|
||||
string vm_str;
|
||||
|
||||
|
||||
os << vm.to_xml(vm_str);
|
||||
|
||||
|
||||
return os;
|
||||
};
|
||||
|
||||
@ -934,9 +863,9 @@ string& VirtualMachine::to_xml(string& xml) const
|
||||
{
|
||||
string template_xml;
|
||||
string history_xml;
|
||||
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
|
||||
oss << "<VM>"
|
||||
<< "<ID>" << oid << "</ID>"
|
||||
<< "<UID>" << uid << "</UID>"
|
||||
@ -952,15 +881,15 @@ string& VirtualMachine::to_xml(string& xml) const
|
||||
<< "<NET_TX>" << net_tx << "</NET_TX>"
|
||||
<< "<NET_RX>" << net_rx << "</NET_RX>"
|
||||
<< vm_template.to_xml(template_xml);
|
||||
|
||||
|
||||
if ( hasHistory() )
|
||||
{
|
||||
oss << history->to_xml(history_xml);
|
||||
}
|
||||
oss << "</VM>";
|
||||
|
||||
|
||||
xml = oss.str();
|
||||
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
@ -970,9 +899,9 @@ string& VirtualMachine::to_str(string& str) const
|
||||
{
|
||||
string template_str;
|
||||
string history_str;
|
||||
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
|
||||
oss<< "ID : " << oid << endl
|
||||
<< "UID : " << uid << endl
|
||||
<< "NAME : " << name << endl
|
||||
@ -987,14 +916,14 @@ string& VirtualMachine::to_str(string& str) const
|
||||
<< "NET TX : " << net_tx << endl
|
||||
<< "NET RX : " << net_rx << endl
|
||||
<< "Template" << endl << vm_template.to_str(template_str) << endl;
|
||||
|
||||
|
||||
if ( hasHistory() )
|
||||
{
|
||||
oss << "Last History Record" << endl << history->to_str(history_str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
str = oss.str();
|
||||
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
VirtualMachinePool::VirtualMachinePool(SqliteDB * db,
|
||||
VirtualMachinePool::VirtualMachinePool(SqlDB * db,
|
||||
vector<const Attribute *> hook_mads)
|
||||
: PoolSQL(db,VirtualMachine::table)
|
||||
{
|
||||
@ -199,7 +199,7 @@ int VirtualMachinePool::allocate (
|
||||
// ------------------------------------------------------------------------
|
||||
// Insert the Object in the pool
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
*oid = PoolSQL::allocate(vm);
|
||||
|
||||
if ( *oid == -1 )
|
||||
@ -210,7 +210,7 @@ int VirtualMachinePool::allocate (
|
||||
// ------------------------------------------------------------------------
|
||||
// Insert parsed context in the VM template and clean-up
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
if ((num_attr = (int) attrs.size()) > 0)
|
||||
{
|
||||
generate_context(*oid,attrs[0]);
|
||||
@ -331,4 +331,50 @@ void VirtualMachinePool::generate_context(int vm_id, Attribute * attr)
|
||||
vm->unlock();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachinePool::dump_cb(void * _oss,int num,char **values,char **names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
return VirtualMachine::dump(*oss, num, values, names);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachinePool::dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<VM_POOL>";
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&VirtualMachinePool::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT " << VirtualMachine::table << ".*, "
|
||||
<< "user_pool.user_name, " << History::table << ".* FROM "
|
||||
<< VirtualMachine::table
|
||||
<< " LEFT OUTER JOIN (SELECT *,MAX(seq) FROM "
|
||||
<< History::table << " GROUP BY vid) AS " << History::table
|
||||
<< " ON " << VirtualMachine::table << ".oid = "
|
||||
<< History::table << ".vid LEFT OUTER JOIN (SELECT oid,user_name FROM "
|
||||
<< "user_pool) AS user_pool ON "
|
||||
<< VirtualMachine::table << ".uid = user_pool.oid WHERE "
|
||||
<< VirtualMachine::table << ".state != " << VirtualMachine::DONE;
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " AND " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd,this);
|
||||
|
||||
oss << "</VM_POOL>";
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user