Note that this version removes GSS support. In the future, authentication
will be handled through matahari.
---
AUTHORS | 4
libvirt-qpid.spec | 4
src/DomainWrap.cpp | 444 +++++++++++++++++++++++------------------
src/DomainWrap.h | 49 ++---
src/Error.h | 8 +
src/Exception.cpp | 38 ++++
src/Exception.h | 30 +++
src/Makefile.am | 29 +--
src/ManagedObject.h | 78 +++++++
src/NodeWrap.cpp | 552 ++++++++++++++++++++++++++++-----------------------
src/NodeWrap.h | 76 ++++---
src/PoolWrap.cpp | 365 +++++++++++++++++++---------------
src/PoolWrap.h | 60 ++----
src/VolumeWrap.cpp | 153 +++++++-------
src/VolumeWrap.h | 58 ++---
15 files changed, 1100 insertions(+), 848 deletions(-)
create mode 100644 src/Exception.cpp
create mode 100644 src/Exception.h
create mode 100644 src/ManagedObject.h
diff --git a/AUTHORS b/AUTHORS
index d042b71..367ea49 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -8,3 +8,7 @@ The libvirt-qpid project was initiated by:
Patches have also been contributed by:
Ted Ross <tross(a)redhat.com>
+
+Conversion to QMFv2 API by:
+
+ Zane Bitter <zbitter(a)redhat.com>
diff --git a/libvirt-qpid.spec b/libvirt-qpid.spec
index 5de1fd2..d64552d 100644
--- a/libvirt-qpid.spec
+++ b/libvirt-qpid.spec
@@ -8,12 +8,12 @@ License: LGPLv2+
Group: Applications/System
Requires: libxml2 >= 2.7.1
Requires: qmf >= 0.5.790661
-Requires: qpid-cpp-client >= 0.5.790661
+Requires: qpid-cpp-client >= 0.10
Requires: libvirt >= 0.4.4
Requires(post): /sbin/chkconfig
Requires(preun): /sbin/chkconfig
Requires(preun): initscripts
-BuildRequires: qpid-cpp-client-devel >= 0.5.790661
+BuildRequires: qpid-cpp-client-devel >= 0.10
BuildRequires: libxml2-devel >= 2.7.1
BuildRequires: libvirt-devel >= 0.5.0
BuildRequires: qmf-devel >= 0.5.790661
diff --git a/src/DomainWrap.cpp b/src/DomainWrap.cpp
index 47876de..eab6bbc 100644
--- a/src/DomainWrap.cpp
+++ b/src/DomainWrap.cpp
@@ -2,266 +2,310 @@
#include "NodeWrap.h"
#include "DomainWrap.h"
#include "Error.h"
+#include "Exception.h"
-#include "ArgsDomainMigrate.h"
-#include "ArgsDomainRestore.h"
-#include "ArgsDomainSave.h"
-#include "ArgsDomainGetXMLDesc.h"
+#include <cstdio>
-namespace _qmf = qmf::com::redhat::libvirt;
-DomainWrap::DomainWrap(ManagementAgent *agent, NodeWrap *parent,
- virDomainPtr _domain_ptr, virConnectPtr _conn) :
- domain_ptr(_domain_ptr), conn(_conn)
+DomainWrap::DomainWrap(
+ NodeWrap *parent,
+ virDomainPtr domain_ptr,
+ virConnectPtr conn):
+ PackageOwner<NodeWrap::PackageDefinition>(parent),
+ ManagedObject(package().data_Domain),
+ _domain_ptr(domain_ptr), _conn(conn)
{
char dom_uuid[VIR_UUID_STRING_BUFLEN];
- domain = NULL;
-
- if (virDomainGetUUIDString(domain_ptr, dom_uuid) < 0) {
- REPORT_ERR(conn, "DomainWrap: Unable to get UUID string of domain.");
+ if (virDomainGetUUIDString(_domain_ptr, dom_uuid) < 0) {
+ REPORT_ERR(_conn, "DomainWrap: Unable to get UUID string of domain.");
throw 1;
}
- domain_uuid = dom_uuid;
+ _domain_uuid = dom_uuid;
- const char *dom_name = virDomainGetName(domain_ptr);
+ const char *dom_name = virDomainGetName(_domain_ptr);
if (!dom_name) {
- REPORT_ERR(conn, "Unable to get domain name!\n");
+ REPORT_ERR(_conn, "Unable to get domain name!\n");
throw 1;
}
- domain_name = dom_name;
+ _domain_name = dom_name;
+
+ _data.setProperty("uuid", _domain_uuid);
+ _data.setProperty("name", _domain_name);
+ _data.setProperty("node", parent->objectID());
+
+ // Set defaults
+ _data.setProperty("state", "");
+ _data.setProperty("numVcpus", 0);
+ _data.setProperty("maximumMemory", 0);
+ _data.setProperty("memory", (uint64_t)0);
+ _data.setProperty("cpuTime", (uint64_t)0);
+
+ addData(_data);
- domain = new _qmf::Domain(agent, this, parent, domain_uuid, domain_name);
- printf("Creating new domain object for %s\n", domain_name.c_str());
- agent->addObject(domain);
+ printf("Initialised new domain object for %s\n", _domain_name.c_str());
}
DomainWrap::~DomainWrap()
{
- if (domain) {
- domain->resourceDestroy();
- }
- virDomainFree(domain_ptr);
+ virDomainFree(_domain_ptr);
+ delData(_data);
}
-
void
DomainWrap::update()
{
virDomainInfo info;
int ret;
- ret = virDomainGetInfo(domain_ptr, &info);
+ ret = virDomainGetInfo(_domain_ptr, &info);
if (ret < 0) {
- REPORT_ERR(conn, "Domain get info failed.");
+ REPORT_ERR(_conn, "Domain get info failed.");
/* Next domainSync() will take care of this in the node wrapper if the domain is
* indeed dead. */
return;
} else {
+ const char *state = NULL;
switch (info.state) {
-
case VIR_DOMAIN_NOSTATE:
- domain->set_state("nostate");
+ state = "nostate";
break;
case VIR_DOMAIN_RUNNING:
- domain->set_state("running");
+ state = "running";
break;
case VIR_DOMAIN_BLOCKED:
- domain->set_state("blocked");
+ state = "blocked";
break;
case VIR_DOMAIN_PAUSED:
- domain->set_state("paused");
+ state = "paused";
break;
case VIR_DOMAIN_SHUTDOWN:
- domain->set_state("shutdown");
+ state = "shutdown";
break;
case VIR_DOMAIN_SHUTOFF:
- domain->set_state("shutoff");
+ state = "shutoff";
break;
case VIR_DOMAIN_CRASHED:
- domain->set_state("crashed");
+ state = "crashed";
break;
}
- domain->set_numVcpus(info.nrVirtCpu);
- domain->set_maximumMemory(info.maxMem);
- domain->set_memory(info.memory);
- domain->set_cpuTime(info.cpuTime);
+ if (state) {
+ _data.setProperty("state", state);
+ }
+ _data.setProperty("numVcpus", info.nrVirtCpu);
+ _data.setProperty("maximumMemory", info.maxMem);
+ _data.setProperty("memory", (uint64_t)info.memory);
+ _data.setProperty("cpuTime", (uint64_t)info.cpuTime);
}
- ret = virDomainGetID(domain_ptr);
+ int id = virDomainGetID(_domain_ptr);
// Just set it directly, if there's an error, -1 will be right.
- domain->set_id(ret);
+ _data.setProperty("id", id);
- if (ret > 0) {
- domain->set_active("true");
- } else {
- domain->set_active("false");
- }
- domain->set_id(ret);
+ _data.setProperty("active", (id > 0) ? "true" :
"false");
}
-Manageable::status_t
-DomainWrap::ManagementMethod(uint32_t methodId, Args& args, std::string &errstr)
+bool
+DomainWrap::handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event)
{
int ret;
- switch (methodId) {
- case _qmf::Domain::METHOD_CREATE:
- ret = virDomainCreate(domain_ptr);
- update();
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error creating new domain
(virDomainCreate).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
-
- case _qmf::Domain::METHOD_DESTROY:
- ret = virDomainDestroy(domain_ptr);
- update();
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error destroying domain
(virDomainDestroy).", &ret);
- return STATUS_USER + ret;
- }
-
- return STATUS_OK;
-
- case _qmf::Domain::METHOD_UNDEFINE:
- ret = virDomainUndefine(domain_ptr);
-
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error undefining domain
(virDomainUndefine).", &ret);
- return STATUS_USER + ret;
- }
-
- /* We now wait for domainSync() to clean this up. */
- return STATUS_OK;
-
- case _qmf::Domain::METHOD_SUSPEND:
- ret = virDomainSuspend(domain_ptr);
- update();
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error suspending domain
(virDomainSuspend).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
-
- case _qmf::Domain::METHOD_RESUME:
- ret = virDomainResume(domain_ptr);
- update();
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error resuming domain
(virDomainResume).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
-
- case _qmf::Domain::METHOD_SAVE:
- {
- _qmf::ArgsDomainSave *io_args = (_qmf::ArgsDomainSave *) &args;
-
- ret = virDomainSave(domain_ptr, io_args->i_filename.c_str());
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error saving domain
(virDomainSave).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
- }
-
- case _qmf::Domain::METHOD_RESTORE:
- {
- _qmf::ArgsDomainRestore *io_args = (_qmf::ArgsDomainRestore *)
&args;
-
- ret = virDomainRestore(conn, io_args->i_filename.c_str());
- update();
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error restoring domain
(virDomainRestore).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
- }
-
- case _qmf::Domain::METHOD_SHUTDOWN:
- ret = virDomainShutdown(domain_ptr);
- update();
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error shutting down domain
(virDomainShutdown).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
-
- case _qmf::Domain::METHOD_REBOOT:
- ret = virDomainReboot(domain_ptr, 0);
- update();
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error rebooting domain
(virDomainReboot).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
-
- case _qmf::Domain::METHOD_GETXMLDESC:
- {
- _qmf::ArgsDomainGetXMLDesc *io_args = (_qmf::ArgsDomainGetXMLDesc *)
&args;
- char *desc;
- desc = virDomainGetXMLDesc(domain_ptr, VIR_DOMAIN_XML_SECURE |
VIR_DOMAIN_XML_INACTIVE);
- if (desc) {
- io_args->o_description = desc;
- } else {
- errstr = FORMAT_ERR(conn, "Error getting XML description of
domain(virDomainGetXMLDesc).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
- }
-
- case _qmf::Domain::METHOD_MIGRATE:
- {
- virConnectPtr dest_conn;
- virDomainPtr rem_dom;
- _qmf::ArgsDomainMigrate *io_args = (_qmf::ArgsDomainMigrate *)
&args;
-
- // This is actually quite broken. Most setups won't allow
unauthorized connection
- // from one node to another directly like this.
- dest_conn = virConnectOpen(io_args->i_destinationUri.c_str());
- if (!dest_conn) {
- errstr = FORMAT_ERR(dest_conn, "Unable to connect to remote
system for migration: virConnectOpen", &ret);
- return STATUS_USER + ret;
- }
-
- const char *new_dom_name = NULL;
- if (io_args->i_newDomainName.size() > 0) {
- new_dom_name = io_args->i_newDomainName.c_str();
- }
-
- const char *uri = NULL;
- if (io_args->i_uri.size() > 0) {
- uri = io_args->i_uri.c_str();
- }
-
- printf ("calling migrate, new_dom_name: %s, uri: %s, flags: %d (live
is %d)\n",
- new_dom_name ? new_dom_name : "NULL",
- uri ? uri : "NULL",
- io_args->i_flags,
- VIR_MIGRATE_LIVE);
-
- rem_dom = virDomainMigrate(domain_ptr, dest_conn, io_args->i_flags,
- new_dom_name,
- uri,
- io_args->i_bandwidth);
-
- virConnectClose(dest_conn);
-
- if (!rem_dom) {
- errstr = FORMAT_ERR(conn, "virDomainMigrate", &ret);
- return STATUS_USER + ret;
- }
- virDomainFree(rem_dom);
-
- return STATUS_OK;
- }
+ if (*this != event.getDataAddr()) {
+ return false;
+ }
+
+ const std::string& methodName(event.getMethodName());
+ qpid::types::Variant::Map args(event.getArguments());
+
+ if (methodName == "create") {
+ int ret = virDomainCreate(_domain_ptr);
+ update();
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error creating new domain
(virDomainCreate).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ else if (methodName == "destroy") {
+ int ret = virDomainDestroy(_domain_ptr);
+ update();
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error destroying domain
(virDomainDestroy).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ else if (methodName == "undefine") {
+ int ret = virDomainUndefine(_domain_ptr);
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error undefining domain
(virDomainUndefine).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ session.methodSuccess(event);
+ }
+ /* We now wait for domainSync() to clean this up. */
+ return true;
}
- return STATUS_NOT_IMPLEMENTED;
+ else if (methodName == "suspend") {
+ int ret = virDomainSuspend(_domain_ptr);
+ update();
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error suspending domain
(virDomainSuspend).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ else if (methodName == "resume") {
+ int ret = virDomainResume(_domain_ptr);
+ update();
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error resuming domain
(virDomainResume).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ else if (methodName == "save") {
+ const std::string filename = args["filename"].asString();
+ int ret = virDomainSave(_domain_ptr, filename.c_str());
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error saving domain
(virDomainSave).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ else if (methodName == "restore") {
+ const std::string filename = args["filename"].asString();
+ int ret = virDomainRestore(_conn, filename.c_str());
+ update();
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error saving domain
(virDomainSave).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ else if (methodName == "shutdown") {
+ int ret = virDomainShutdown(_domain_ptr);
+ update();
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error shutting down domain
(virDomainShutdown).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ else if (methodName == "reboot") {
+ int ret = virDomainReboot(_domain_ptr, 0);
+ update();
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error rebooting domain
(virDomainReboot).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ else if (methodName == "getXMLDesc") {
+ const char *desc = virDomainGetXMLDesc(_domain_ptr,
+ VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_INACTIVE);
+ if (!desc) {
+ std::string err = FORMAT_ERR(_conn, "Error rebooting domain
(virDomainReboot).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ event.addReturnArgument("description", desc);
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ else if (methodName == "migrate") {
+ if (migrate(session, event)) {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ raiseException(session, event,
+ ERROR_UNKNOWN_METHOD, STATUS_UNKNOWN_METHOD);
+ return true;
}
+bool
+DomainWrap::migrate(qmf::AgentSession& session, qmf::AgentEvent& event)
+{
+ virConnectPtr dest_conn;
+ virDomainPtr rem_dom;
+ qpid::types::Variant::Map args(event.getArguments());
+ int ret;
+
+ // This is actually quite broken. Most setups won't allow unauthorized
+ // connection from one node to another directly like this.
+ dest_conn = virConnectOpen(args["destinationUri"].asString().c_str());
+ if (!dest_conn) {
+ std::string err = FORMAT_ERR(dest_conn, "Unable to connect to remote system
for migration: virConnectOpen", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
+
+ const std::string newDomainName_arg(args["newDomainName"]);
+ const char *new_dom_name = NULL;
+ if (newDomainName_arg.size() > 0) {
+ new_dom_name = newDomainName_arg.c_str();
+ }
+
+ const std::string uri_arg(args["uri"]);
+ const char *uri = NULL;
+ if (uri_arg.size() > 0) {
+ uri = uri_arg.c_str();
+ }
+
+ uint32_t flags(args["flags"]);
+ uint32_t bandwidth(args["bandwidth"]);
+
+ printf ("calling migrate, new_dom_name: %s, uri: %s, flags: %d (live is
%d)\n",
+ new_dom_name ? new_dom_name : "NULL",
+ uri ? uri : "NULL",
+ flags,
+ VIR_MIGRATE_LIVE);
+
+ rem_dom = virDomainMigrate(_domain_ptr, dest_conn, flags,
+ new_dom_name,
+ uri,
+ bandwidth);
+
+ virConnectClose(dest_conn);
+
+ if (!rem_dom) {
+ std::string err = FORMAT_ERR(_conn, "virDomainMigrate", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
+ virDomainFree(rem_dom);
+
+ return true;
+}
diff --git a/src/DomainWrap.h b/src/DomainWrap.h
index 27822bd..fc39a5f 100644
--- a/src/DomainWrap.h
+++ b/src/DomainWrap.h
@@ -1,10 +1,7 @@
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-#include <qpid/sys/Mutex.h>
+#ifndef DOMAIN_WRAP_H
+#define DOMAIN_WRAP_H
-#include "Package.h"
-#include "Domain.h"
+#include "NodeWrap.h"
#include <unistd.h>
#include <cstdlib>
@@ -15,38 +12,30 @@
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
-using namespace qpid::management;
-using namespace qpid::sys;
-using namespace std;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::Mutex;
-class DomainWrap : public Manageable
+class DomainWrap:
+ PackageOwner<NodeWrap::PackageDefinition>,
+ public ManagedObject
{
- ManagementAgent *agent;
- qmf::com::redhat::libvirt::Domain *domain;
+ virDomainPtr _domain_ptr;
+ virConnectPtr _conn;
- virDomainPtr domain_ptr;
- virConnectPtr conn;
+ std::string _domain_name;
+ std::string _domain_uuid;
public:
-
- std::string domain_name;
- std::string domain_uuid;
-
- DomainWrap(ManagementAgent *agent, NodeWrap *parent, virDomainPtr domain_ptr,
- virConnectPtr connect);
+ DomainWrap(NodeWrap *parent,
+ virDomainPtr domain_ptr, virConnectPtr conn);
~DomainWrap();
- ManagementObject* GetManagementObject(void) const
- {
- return domain;
- }
-
+ std::string& name(void) { return _domain_name; }
+ std::string& uuid(void) { return _domain_uuid; }
void update();
- status_t ManagementMethod (uint32_t methodId, Args& args, std::string
&errstr);
+ bool handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event);
+
+private:
+ bool migrate(qmf::AgentSession& session, qmf::AgentEvent& event);
};
+#endif
diff --git a/src/Error.h b/src/Error.h
index 388b41a..5bd7397 100644
--- a/src/Error.h
+++ b/src/Error.h
@@ -1,11 +1,19 @@
+#ifndef ERROR_H
+#define ERROR_H
+
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+
#define REPORT_ERR(conn,msg) reportError(conn, msg, __func__, __LINE__, __FILE__)
#define FORMAT_ERR(conn,msg,err_ret) formatError(conn, msg, err_ret, __func__, __LINE__,
__FILE__)
+
void
reportError(virConnectPtr conn, const char *msg, const char *function, int line, const
char *file);
std::string
formatError(virConnectPtr conn, const char *msg, int *err_ret, const char *function, int
line, const char *file);
+#endif
diff --git a/src/Exception.cpp b/src/Exception.cpp
new file mode 100644
index 0000000..105df27
--- /dev/null
+++ b/src/Exception.cpp
@@ -0,0 +1,38 @@
+#include "Exception.h"
+#include "Error.h"
+#include <qmf/Schema.h>
+#include <qmf/SchemaProperty.h>
+#include <qmf/Data.h>
+
+
+#define ERROR_TEXT "error_text"
+#define ERROR_CODE "error_code"
+
+
+static qmf::Schema errorSchema(qmf::SCHEMA_TYPE_DATA,
+ "com.redhat.libvirt", "error");
+
+
+void
+initErrorSchema(qmf::AgentSession& session)
+{
+ qmf::SchemaProperty status_text(ERROR_TEXT, qmf::SCHEMA_DATA_STRING);
+ qmf::SchemaProperty status_code(ERROR_CODE, qmf::SCHEMA_DATA_INT);
+
+ errorSchema.addProperty(status_text);
+ errorSchema.addProperty(status_code);
+
+ session.registerSchema(errorSchema);
+}
+
+void
+raiseException(qmf::AgentSession& session,
+ qmf::AgentEvent& event,
+ const std::string& error_text,
+ unsigned int error_code)
+{
+ qmf::Data response(errorSchema);
+ response.setProperty(ERROR_TEXT, error_text);
+ response.setProperty(ERROR_CODE, error_code);
+ session.raiseException(event, response);
+}
diff --git a/src/Exception.h b/src/Exception.h
new file mode 100644
index 0000000..efbd327
--- /dev/null
+++ b/src/Exception.h
@@ -0,0 +1,30 @@
+#ifndef EXCEPTION_H
+#define EXCEPTION_H
+
+#include <qmf/AgentSession.h>
+#include <qmf/AgentEvent.h>
+#include <string>
+
+
+#define STATUS_OK 0
+#define STATUS_UNKNOWN_OBJECT 1
+#define STATUS_UNKNOWN_METHOD 2
+#define STATUS_NOT_IMPLEMENTED 3
+#define STATUS_EXCEPTION 7
+#define STATUS_USER 0x10000
+
+#define ERROR_UNKNOWN_OBJECT "Unknown Object"
+#define ERROR_UNKNOWN_METHOD "Unknown Method"
+#define ERROR_NOT_IMPLEMENTED "Not implemented"
+
+
+void
+initErrorSchema(qmf::AgentSession& session);
+
+void
+raiseException(qmf::AgentSession& session,
+ qmf::AgentEvent& event,
+ const std::string& error_text,
+ unsigned int error_code);
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 1b4ef23..4bb27b2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,37 +5,22 @@ INCLUDES = -I$(top_srcdir)/src/qmf/com/redhat/libvirt $(XML_CFLAGS)
sbin_PROGRAMS = libvirt-qpid
generated_file_list = \
- qmf/com/redhat/libvirt/Domain.cpp\
- qmf/com/redhat/libvirt/Node.cpp\
- qmf/com/redhat/libvirt/Package.cpp\
- qmf/com/redhat/libvirt/Pool.cpp\
- qmf/com/redhat/libvirt/Volume.cpp\
- qmf/com/redhat/libvirt/ArgsDomainGetXMLDesc.h\
- qmf/com/redhat/libvirt/ArgsDomainMigrate.h\
- qmf/com/redhat/libvirt/ArgsDomainRestore.h\
- qmf/com/redhat/libvirt/ArgsDomainSave.h\
- qmf/com/redhat/libvirt/ArgsNodeDomainDefineXML.h\
- qmf/com/redhat/libvirt/ArgsNodeStoragePoolCreateXML.h\
- qmf/com/redhat/libvirt/ArgsNodeStoragePoolDefineXML.h\
- qmf/com/redhat/libvirt/ArgsPoolCreateVolumeXML.h\
- qmf/com/redhat/libvirt/ArgsPoolGetXMLDesc.h\
- qmf/com/redhat/libvirt/ArgsVolumeGetXMLDesc.h\
- qmf/com/redhat/libvirt/Domain.h\
- qmf/com/redhat/libvirt/Node.h\
- qmf/com/redhat/libvirt/Package.h\
- qmf/com/redhat/libvirt/Pool.h\
- qmf/com/redhat/libvirt/Volume.h
+ qmf/com/redhat/libvirt/QmfPackage.cpp\
+ qmf/com/redhat/libvirt/QmfPackage.h
nodist_libvirt_qpid_SOURCES = $(generated_file_list)
libvirt_qpid_SOURCES = \
DomainWrap.cpp \
Error.cpp \
+ Exception.cpp \
NodeWrap.cpp \
PoolWrap.cpp \
VolumeWrap.cpp \
+ ManagedObject.h \
DomainWrap.h \
Error.h \
+ Exception.h \
NodeWrap.h \
PoolWrap.h \
VolumeWrap.h
@@ -43,12 +28,12 @@ libvirt_qpid_SOURCES = \
$(generated_file_list): .libvirt-schema.xml.tstamp
.libvirt-schema.xml.tstamp: libvirt-schema.xml
- qmf-gen -o ./qmf $< && touch $@ || rm -f $@
+ qmf-gen -2 -o ./qmf $< && touch $@ || rm -f $@
BUILT_SOURCES = $(generated_file_list)
CLEANFILES = $(generated_file_list) .libvirt-schema.xml.tstamp
-libvirt_qpid_LDADD = -lqmf -lqpidtypes -lqpidcommon -lqpidclient -lvirt $(XML_LIBS)
+libvirt_qpid_LDADD = -lqmf2 -lqpidtypes -lqpidcommon -lqpidmessaging -lvirt $(XML_LIBS)
dist_pkgdata_DATA = libvirt-schema.xml
diff --git a/src/ManagedObject.h b/src/ManagedObject.h
new file mode 100644
index 0000000..b372f24
--- /dev/null
+++ b/src/ManagedObject.h
@@ -0,0 +1,78 @@
+#ifndef MANAGED_OBJECT_H
+#define MANAGED_OBJECT_H
+
+#include <qmf/AgentEvent.h>
+#include <qmf/AgentSession.h>
+#include <qmf/Data.h>
+#include <qmf/DataAddr.h>
+
+#include <assert.h>
+
+
+template <class T>
+class PackageOwner
+{
+ PackageOwner<T> *_parent;
+
+public:
+ typedef T PackageDefinition;
+
+protected:
+ PackageOwner<T>(void): _parent(NULL) { }
+ PackageOwner<T>(PackageOwner<T> *parent): _parent(parent) { }
+ virtual ~PackageOwner<T>() { }
+
+ virtual PackageDefinition& package(void) {
+ assert(_parent != NULL);
+ return _parent->package();
+ }
+
+ virtual void addData(qmf::Data& data) {
+ assert(_parent != NULL);
+ _parent->addData(data);
+ }
+
+ virtual void delData(qmf::Data& data) {
+ assert(_parent != NULL);
+ _parent->delData(data);
+ }
+};
+
+
+class ManagedObject
+{
+public:
+ qpid::types::Variant objectID(void) {
+ assert(_data.hasAddr());
+ return _data.getAddr().asMap();
+ }
+
+ virtual bool handleMethod(qmf::AgentSession& session,
+ qmf::AgentEvent& event) = 0;
+
+protected:
+ ManagedObject(qmf::Schema& schema): _data(schema) { }
+ virtual ~ManagedObject() { }
+
+ bool operator==(const qmf::DataAddr& addr) {
+ if (!_data.hasAddr()) {
+ return false;
+ }
+
+ // Due to a bug (#QPID3344) in current versions of libqmf2, the first
+ // operand to qmf::DataAddr::operator==() must not be const, otherwise
+ // a bogus value is returned.
+ qmf::DataAddr& mutableAddr =
const_cast<qmf::DataAddr&>(_data.getAddr());
+
+ return mutableAddr == addr;
+ }
+
+ bool operator!=(const qmf::DataAddr& addr) {
+ return !(*this == addr);
+ }
+
+ qmf::Data _data;
+};
+
+#endif
+
diff --git a/src/NodeWrap.cpp b/src/NodeWrap.cpp
index b663235..d65db11 100644
--- a/src/NodeWrap.cpp
+++ b/src/NodeWrap.cpp
@@ -6,20 +6,19 @@
#include <getopt.h>
#include <syslog.h>
#include <signal.h>
+#include <cstdio>
#include "NodeWrap.h"
#include "DomainWrap.h"
#include "PoolWrap.h"
#include "Error.h"
+#include "Exception.h"
-#include "ArgsNodeDomainDefineXML.h"
-#include "ArgsNodeStoragePoolCreateXML.h"
-#include "ArgsNodeStoragePoolDefineXML.h"
-#include "ArgsNodeFindStoragePoolSources.h"
-namespace _qmf = qmf::com::redhat::libvirt;
-
-NodeWrap::NodeWrap(ManagementAgent* _agent, string _name) : name(_name), agent(_agent)
+NodeWrap::NodeWrap(qmf::AgentSession& agent_session, PackageDefinition&
package):
+ ManagedObject(package.data_Node),
+ _session(agent_session),
+ _package(package)
{
virNodeInfo info;
char *hostname;
@@ -36,33 +35,33 @@ NodeWrap::NodeWrap(ManagementAgent* _agent, string _name) :
name(_name), agent(_
unsigned int minor;
unsigned int rel;
- conn = virConnectOpen(NULL);
- if (!conn) {
- REPORT_ERR(conn, "virConnectOpen");
+ _conn = virConnectOpen(NULL);
+ if (!_conn) {
+ REPORT_ERR(_conn, "virConnectOpen");
throw -1;
}
- hostname = virConnectGetHostname(conn);
+ hostname = virConnectGetHostname(_conn);
if (hostname == NULL) {
- REPORT_ERR(conn, "virConnectGetHostname");
+ REPORT_ERR(_conn, "virConnectGetHostname");
throw -1;
}
- hv_type = virConnectGetType(conn);
+ hv_type = virConnectGetType(_conn);
if (hv_type == NULL) {
- REPORT_ERR(conn, "virConnectGetType");
+ REPORT_ERR(_conn, "virConnectGetType");
throw -1;
}
- uri = virConnectGetURI(conn);
+ uri = virConnectGetURI(_conn);
if (uri == NULL) {
- REPORT_ERR(conn, "virConnectGetURI");
+ REPORT_ERR(_conn, "virConnectGetURI");
throw -1;
}
ret = virGetVersion(&libvirt_v, hv_type, &api_v);
if (ret < 0) {
- REPORT_ERR(conn, "virGetVersion");
+ REPORT_ERR(_conn, "virGetVersion");
} else {
major = libvirt_v / 1000000;
libvirt_v %= 1000000;
@@ -77,9 +76,9 @@ NodeWrap::NodeWrap(ManagementAgent* _agent, string _name) : name(_name),
agent(_
snprintf(api_version, sizeof(api_version), "%d.%d.%d", major, minor,
rel);
}
- ret = virConnectGetVersion(conn, &hv_v);
+ ret = virConnectGetVersion(_conn, &hv_v);
if (ret < 0) {
- REPORT_ERR(conn, "virConnectGetVersion");
+ REPORT_ERR(_conn, "virConnectGetVersion");
} else {
major = hv_v / 1000000;
hv_v %= 1000000;
@@ -88,48 +87,64 @@ NodeWrap::NodeWrap(ManagementAgent* _agent, string _name) :
name(_name), agent(_
snprintf(hv_version, sizeof(hv_version), "%d.%d.%d", major, minor,
rel);
}
- ret = virNodeGetInfo(conn, &info);
+ ret = virNodeGetInfo(_conn, &info);
if (ret < 0) {
- REPORT_ERR(conn, "virNodeGetInfo");
+ REPORT_ERR(_conn, "virNodeGetInfo");
memset((void *) &info, sizeof(info), 1);
}
- mgmtObject = new _qmf::Node(agent, this, hostname, uri, libvirt_version, api_version,
hv_version, hv_type,
- info.model, info.memory, info.cpus, info.mhz, info.nodes,
info.sockets,
- info.cores, info.threads);
- agent->addObject(mgmtObject);
+
+ _data.setProperty("hostname", hostname);
+ _data.setProperty("uri", uri);
+ _data.setProperty("libvirtVersion", libvirt_version);
+ _data.setProperty("apiVersion", api_version);
+ _data.setProperty("hypervisorVersion", hv_version);
+ _data.setProperty("hypervisorType", hv_type);
+
+ _data.setProperty("model", info.model);
+ _data.setProperty("memory", info.memory);
+ _data.setProperty("cpus", info.cpus);
+ _data.setProperty("mhz", info.mhz);
+ _data.setProperty("nodes", info.nodes);
+ _data.setProperty("sockets", info.sockets);
+ _data.setProperty("cores", info.cores);
+ _data.setProperty("threads", info.threads);
+
+ addData(_data);
}
NodeWrap::~NodeWrap()
{
/* Go through our list of pools and destroy them all! MOOOHAHAHA */
- for (std::vector<PoolWrap*>::iterator iter = pools.begin(); iter !=
pools.end();) {
- delete(*iter);
- iter = pools.erase(iter);
+ PoolList::iterator iter_p = _pools.begin();
+ while (iter_p != _pools.end()) {
+ delete(*iter_p);
+ iter_p = _pools.erase(iter_p);
}
/* Same for domains.. */
- for (std::vector<DomainWrap*>::iterator iter = domains.begin(); iter !=
domains.end();) {
- delete (*iter);
- iter = domains.erase(iter);
+ DomainList::iterator iter_d = _domains.begin();
+ while (iter_d != _domains.end()) {
+ delete (*iter_d);
+ iter_d = _domains.erase(iter_d);
}
- mgmtObject->resourceDestroy();
+ delData(_data);
}
-void NodeWrap::syncDomains()
+void NodeWrap::syncDomains(void)
{
/* Sync up with domains that are defined but not active. */
- int maxname = virConnectNumOfDefinedDomains(conn);
+ int maxname = virConnectNumOfDefinedDomains(_conn);
if (maxname < 0) {
- REPORT_ERR(conn, "virConnectNumOfDefinedDomains");
+ REPORT_ERR(_conn, "virConnectNumOfDefinedDomains");
return;
} else {
char **dnames;
dnames = (char **) malloc(sizeof(char *) * maxname);
- if ((maxname = virConnectListDefinedDomains(conn, dnames, maxname)) < 0) {
- REPORT_ERR(conn, "virConnectListDefinedDomains");
+ if ((maxname = virConnectListDefinedDomains(_conn, dnames, maxname)) < 0) {
+ REPORT_ERR(_conn, "virConnectListDefinedDomains");
free(dnames);
return;
}
@@ -139,9 +154,9 @@ void NodeWrap::syncDomains()
virDomainPtr domain_ptr;
bool found = false;
- for (std::vector<DomainWrap*>::iterator iter = domains.begin();
- iter != domains.end(); iter++) {
- if ((*iter)->domain_name == dnames[i]) {
+ for (DomainList::iterator iter = _domains.begin();
+ iter != _domains.end(); iter++) {
+ if ((*iter)->name() == dnames[i]) {
found = true;
break;
}
@@ -151,18 +166,18 @@ void NodeWrap::syncDomains()
continue;
}
- domain_ptr = virDomainLookupByName(conn, dnames[i]);
+ domain_ptr = virDomainLookupByName(_conn, dnames[i]);
if (!domain_ptr) {
- REPORT_ERR(conn, "virDomainLookupByName");
+ REPORT_ERR(_conn, "virDomainLookupByName");
} else {
DomainWrap *domain;
try {
- domain = new DomainWrap(agent, this, domain_ptr, conn);
+ domain = new DomainWrap(this, domain_ptr, _conn);
printf("Created new domain: %s, ptr is %p\n", dnames[i],
domain_ptr);
- domains.push_back(domain);
+ _domains.push_back(domain);
} catch (int i) {
- printf ("Error constructing domain\n");
- REPORT_ERR(conn, "constructing domain.");
+ printf("Error constructing domain\n");
+ REPORT_ERR(_conn, "constructing domain.");
delete domain;
}
}
@@ -175,15 +190,15 @@ void NodeWrap::syncDomains()
}
/* Go through all the active domains */
- int maxids = virConnectNumOfDomains(conn);
+ int maxids = virConnectNumOfDomains(_conn);
if (maxids < 0) {
- REPORT_ERR(conn, "virConnectNumOfDomains");
+ REPORT_ERR(_conn, "virConnectNumOfDomains");
return;
} else {
int *ids;
ids = (int *) malloc(sizeof(int *) * maxids);
- if ((maxids = virConnectListDomains(conn, ids, maxids)) < 0) {
+ if ((maxids = virConnectListDomains(_conn, ids, maxids)) < 0) {
printf("Error getting list of defined domains\n");
return;
}
@@ -192,21 +207,21 @@ void NodeWrap::syncDomains()
virDomainPtr domain_ptr;
char dom_uuid[VIR_UUID_STRING_BUFLEN];
- domain_ptr = virDomainLookupByID(conn, ids[i]);
+ domain_ptr = virDomainLookupByID(_conn, ids[i]);
if (!domain_ptr) {
- REPORT_ERR(conn, "virDomainLookupByID");
+ REPORT_ERR(_conn, "virDomainLookupByID");
continue;
}
if (virDomainGetUUIDString(domain_ptr, dom_uuid) < 0) {
- REPORT_ERR(conn, "virDomainGetUUIDString");
+ REPORT_ERR(_conn, "virDomainGetUUIDString");
continue;
}
bool found = false;
- for (std::vector<DomainWrap*>::iterator iter = domains.begin();
- iter != domains.end(); iter++) {
- if (strcmp((*iter)->domain_uuid.c_str(), dom_uuid) == 0) {
+ for (DomainList::iterator iter = _domains.begin();
+ iter != _domains.end(); iter++) {
+ if (strcmp((*iter)->uuid().c_str(), dom_uuid) == 0) {
found = true;
break;
}
@@ -219,12 +234,12 @@ void NodeWrap::syncDomains()
DomainWrap *domain;
try {
- domain = new DomainWrap(agent, this, domain_ptr, conn);
+ domain = new DomainWrap(this, domain_ptr, _conn);
printf("Created new domain: %d, ptr is %p\n", ids[i],
domain_ptr);
- domains.push_back(domain);
+ _domains.push_back(domain);
} catch (int i) {
- printf ("Error constructing domain\n");
- REPORT_ERR(conn, "constructing domain.");
+ printf("Error constructing domain\n");
+ REPORT_ERR(_conn, "constructing domain.");
delete domain;
}
}
@@ -233,14 +248,14 @@ void NodeWrap::syncDomains()
}
/* Go through our list of domains and ensure that they still exist. */
- for (std::vector<DomainWrap*>::iterator iter = domains.begin(); iter !=
domains.end();) {
-
- printf("verifying domain %s\n", (*iter)->domain_name.c_str());
- virDomainPtr ptr = virDomainLookupByUUIDString(conn,
(*iter)->domain_uuid.c_str());
+ DomainList::iterator iter = _domains.begin();
+ while (iter != _domains.end()) {
+ printf("verifying domain %s\n", (*iter)->name().c_str());
+ virDomainPtr ptr = virDomainLookupByUUIDString(_conn,
(*iter)->uuid().c_str());
if (ptr == NULL) {
- REPORT_ERR(conn, "virDomainLookupByUUIDString");
+ REPORT_ERR(_conn, "virDomainLookupByUUIDString");
delete (*iter);
- iter = domains.erase(iter);
+ iter = _domains.erase(iter);
} else {
virDomainFree(ptr);
iter++;
@@ -253,9 +268,9 @@ void NodeWrap::checkPool(char *pool_name)
virStoragePoolPtr pool_ptr;
bool found = false;
- for (std::vector<PoolWrap*>::iterator iter = pools.begin();
- iter != pools.end(); iter++) {
- if ((*iter)->pool_name == pool_name) {
+ for (PoolList::iterator iter = _pools.begin();
+ iter != _pools.end(); iter++) {
+ if ((*iter)->name() == pool_name) {
found = true;
break;
}
@@ -265,38 +280,37 @@ void NodeWrap::checkPool(char *pool_name)
return;
}
- pool_ptr = virStoragePoolLookupByName(conn, pool_name);
+ pool_ptr = virStoragePoolLookupByName(_conn, pool_name);
if (!pool_ptr) {
- REPORT_ERR(conn, "virStoragePoolLookupByName");
+ REPORT_ERR(_conn, "virStoragePoolLookupByName");
} else {
printf("Creating new pool: %s, ptr is %p\n", pool_name, pool_ptr);
PoolWrap *pool;
try {
- pool = new PoolWrap(agent, this, pool_ptr, conn);
+ pool = new PoolWrap(this, pool_ptr, _conn);
printf("Created new pool: %s, ptr is %p\n", pool_name, pool_ptr);
- pools.push_back(pool);
+ _pools.push_back(pool);
} catch (int i) {
- printf ("Error constructing pool\n");
- REPORT_ERR(conn, "constructing pool.");
+ printf("Error constructing pool\n");
+ REPORT_ERR(_conn, "constructing pool.");
delete pool;
}
}
}
-void NodeWrap::syncPools()
+void NodeWrap::syncPools(void)
{
int maxname;
- maxname = virConnectNumOfStoragePools(conn);
+ maxname = virConnectNumOfStoragePools(_conn);
if (maxname < 0) {
- REPORT_ERR(conn, "virConnectNumOfStroagePools");
+ REPORT_ERR(_conn, "virConnectNumOfStoragePools");
return;
} else {
- char **names;
- names = (char **) malloc(sizeof(char *) * maxname);
+ char *names[maxname];
- if ((maxname = virConnectListStoragePools(conn, names, maxname)) < 0) {
- REPORT_ERR(conn, "virConnectListStoragePools");
+ if ((maxname = virConnectListStoragePools(_conn, names, maxname)) < 0) {
+ REPORT_ERR(_conn, "virConnectListStoragePools");
return;
}
@@ -304,19 +318,17 @@ void NodeWrap::syncPools()
checkPool(names[i]);
free(names[i]);
}
- free(names);
}
- maxname = virConnectNumOfDefinedStoragePools(conn);
+ maxname = virConnectNumOfDefinedStoragePools(_conn);
if (maxname < 0) {
- REPORT_ERR(conn, "virConnectNumOfDefinedStoragePools");
+ REPORT_ERR(_conn, "virConnectNumOfDefinedStoragePools");
return;
} else {
- char **names;
- names = (char **) malloc(sizeof(char *) * maxname);
+ char *names[maxname];
- if ((maxname = virConnectListDefinedStoragePools(conn, names, maxname)) < 0)
{
- REPORT_ERR(conn, "virConnectListDefinedStoragePools");
+ if ((maxname = virConnectListDefinedStoragePools(_conn, names, maxname)) < 0)
{
+ REPORT_ERR(_conn, "virConnectListDefinedStoragePools");
return;
}
@@ -324,19 +336,17 @@ void NodeWrap::syncPools()
checkPool(names[i]);
free(names[i]);
}
-
- free(names);
}
/* Go through our list of pools and ensure that they still exist. */
- for (std::vector<PoolWrap*>::iterator iter = pools.begin(); iter !=
pools.end();) {
-
- printf ("Verifying pool %s\n", (*iter)->pool_name.c_str());
- virStoragePoolPtr ptr = virStoragePoolLookupByUUIDString(conn,
(*iter)->pool_uuid.c_str());
+ PoolList::iterator iter = _pools.begin();
+ while (iter != _pools.end()) {
+ printf("Verifying pool %s\n", (*iter)->name().c_str());
+ virStoragePoolPtr ptr = virStoragePoolLookupByUUIDString(_conn,
(*iter)->uuid().c_str());
if (ptr == NULL) {
- printf("Destroying pool %s\n", (*iter)->pool_name.c_str());
+ printf("Destroying pool %s\n", (*iter)->name().c_str());
delete(*iter);
- iter = pools.erase(iter);
+ iter = _pools.erase(iter);
} else {
virStoragePoolFree(ptr);
iter++;
@@ -344,7 +354,6 @@ void NodeWrap::syncPools()
}
}
-
void NodeWrap::doLoop()
{
fd_set fds;
@@ -354,12 +363,10 @@ void NodeWrap::doLoop()
/* Go through all domains and call update() for each, letting them update
* information and statistics. */
while (1) {
- int read_fd = agent->getSignalFd();
-
// We're using this to check to see if our connection is still good.
// I don't see any reason this call should fail unless there is some
// connection problem..
- int maxname = virConnectNumOfDefinedDomains(conn);
+ int maxname = virConnectNumOfDefinedDomains(_conn);
if (maxname < 0) {
return;
}
@@ -367,151 +374,200 @@ void NodeWrap::doLoop()
syncDomains();
syncPools();
- for (std::vector<DomainWrap*>::iterator iter = domains.begin();
- iter != domains.end(); iter++) {
+ for (DomainList::iterator iter = _domains.begin();
+ iter != _domains.end(); iter++) {
(*iter)->update();
}
- for (std::vector<PoolWrap*>::iterator iter = pools.begin();
- iter != pools.end(); iter++) {
+ for (PoolList::iterator iter = _pools.begin();
+ iter != _pools.end(); iter++) {
(*iter)->update();
}
- /* Poll agent fd. If any methods are being made this FD will be ready for
reading. */
- FD_ZERO(&fds);
- FD_SET(read_fd, &fds);
+ qmf::AgentEvent event;
+ if (_session.nextEvent(event, qpid::messaging::Duration(3000))) {
+ if (event.getType() == qmf::AGENT_METHOD) {
+ bool handled = handleMethod(_session, event);
+ if (!handled) {
+ raiseException(_session, event,
+ ERROR_UNKNOWN_OBJECT, STATUS_UNKNOWN_OBJECT);
+ }
+ }
+ }
- /* Wait up to three seconds. */
- tv.tv_sec = 3;
- tv.tv_usec = 0;
+ }
+}
- retval = select(read_fd + 1, &fds, NULL, NULL, &tv);
- if (retval < 0) {
- fprintf(stderr, "Error in select loop: %s\n", strerror(errno));
- continue;
- }
+bool
+NodeWrap::domainDefineXML(qmf::AgentSession& session,
+ qmf::AgentEvent& event)
+{
+ const std::string xmlDesc(event.getArguments()["xmlDesc"].asString());
+ int ret;
+
+ virDomainPtr domain_ptr = virDomainDefineXML(_conn, xmlDesc.c_str());
+ if (!domain_ptr) {
+ std::string err = FORMAT_ERR(_conn, "Error creating domain using xml
description (virDomainDefineXML).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
- if (retval > 0) {
- /* This implements any pending methods. */
- agent->pollCallbacks();
+ // Now we have to check to see if this domain is actually new or not,
+ // because it's possible that one already exists with this name/description
+ // and we just replaced it... *ugh*
+ DomainList::iterator iter = _domains.begin();
+ while (iter != _domains.end()) {
+ if ((*iter)->name() == virDomainGetName(domain_ptr)) {
+ // We're just replacing an existing domain, however I'm pretty sure
+ // the old domain pointer becomes invalid at this point, so we
+ // should destroy the old domain reference. The other option would
+ // be to replace it and keep the object valid... not sure which is
+ // better.
+ printf("Old domain already exists, removing it in favor of new
object.");
+ delete(*iter);
+ iter = _domains.erase(iter);
+ } else {
+ iter++;
}
+ }
+ DomainWrap *domain;
+ try {
+ domain = new DomainWrap(this, domain_ptr, _conn);
+ _domains.push_back(domain);
+ event.addReturnArgument("domain", domain->objectID());
+ } catch (int i) {
+ delete domain;
+ std::string err = FORMAT_ERR(_conn, "Error constructing domain object in
virDomainDefineXML.", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
}
+
+ return true;
}
-Manageable::status_t
-NodeWrap::ManagementMethod(uint32_t methodId, Args& args, std::string &errstr)
+bool
+NodeWrap::storagePoolDefineXML(qmf::AgentSession& session,
+ qmf::AgentEvent& event)
{
- virDomainPtr domain_ptr;
- cout << "Method Received: " << methodId << endl;
+ const std::string xmlDesc(event.getArguments()["xmlDesc"].asString());
+ virStoragePoolPtr pool_ptr;
int ret;
- switch (methodId) {
- case _qmf::Node::METHOD_DOMAINDEFINEXML:
- {
- _qmf::ArgsNodeDomainDefineXML *io_args = (_qmf::ArgsNodeDomainDefineXML *)
&args;
- domain_ptr = virDomainDefineXML(conn, io_args->i_xmlDesc.c_str());
- if (!domain_ptr) {
- errstr = FORMAT_ERR(conn, "Error creating domain using xml
description (virDomainDefineXML).", &ret);
- return STATUS_USER + ret;
- } else {
- // Now we have to check to see if this domain is actually new or not,
because it's possible that
- // one already exists with this name/description and we just replaced
it.. *ugh*
- for (std::vector<DomainWrap*>::iterator iter = domains.begin();
iter != domains.end();) {
- if (strcmp((*iter)->domain_name.c_str(),
virDomainGetName(domain_ptr)) == 0) {
- // We're just replacing an existing domain, however I'm
pretty sure the
- // old domain pointer becomes invalid at this point, so we should
destroy
- // the old domain reference. The other option would be to
replace it and
- // keep the object valid.. not sure which is better.
- printf("Old domain already exists, removing it in favor of
new object.");
- delete(*iter);
- iter = domains.erase(iter);
- } else {
- iter++;
- }
- }
+ pool_ptr = virStoragePoolDefineXML(_conn, xmlDesc.c_str(), 0);
+ if (pool_ptr == NULL) {
+ std::string err = FORMAT_ERR(_conn, "Error defining storage pool using xml
description (virStoragePoolDefineXML).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
- DomainWrap *domain;
- try {
- domain = new DomainWrap(agent, this, domain_ptr, conn);
- domains.push_back(domain);
- io_args->o_domain =
domain->GetManagementObject()->getObjectId();
- } catch (int i) {
- delete domain;
- errstr = FORMAT_ERR(conn, "Error constructing domain object in
virDomainDefineXML.", &ret);
- return STATUS_USER + i;
- }
+ PoolWrap *pool;
+ try {
+ pool = new PoolWrap(this, pool_ptr, _conn);
+ _pools.push_back(pool);
+ event.addReturnArgument("pool", pool->objectID());
+ } catch (int i) {
+ delete pool;
+ std::string err = FORMAT_ERR(_conn, "Error constructing pool object in
virStoragePoolDefineXML.", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
- return STATUS_OK;
- }
- }
+ return true;
+}
+
+bool
+NodeWrap::storagePoolCreateXML(qmf::AgentSession& session,
+ qmf::AgentEvent& event)
+{
+ const std::string xmlDesc(event.getArguments()["xmlDesc"].asString());
+ virStoragePoolPtr pool_ptr;
+ int ret;
- case _qmf::Node::METHOD_STORAGEPOOLDEFINEXML:
- {
- _qmf::ArgsNodeStoragePoolDefineXML *io_args =
(_qmf::ArgsNodeStoragePoolDefineXML *) &args;
- virStoragePoolPtr pool_ptr;
+ pool_ptr = virStoragePoolCreateXML (_conn, xmlDesc.c_str(), 0);
+ if (pool_ptr == NULL) {
+ std::string err = FORMAT_ERR(_conn, "Error creating storage pool using xml
description (virStoragePoolCreateXML).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
- pool_ptr = virStoragePoolDefineXML (conn, io_args->i_xmlDesc.c_str(), 0);
- if (pool_ptr == NULL) {
- errstr = FORMAT_ERR(conn, "Error defining storage pool using xml
description (virStoragePoolDefineXML).", &ret);
- return STATUS_USER + ret;
- }
+ PoolWrap *pool;
+ try {
+ pool = new PoolWrap(this, pool_ptr, _conn);
+ _pools.push_back(pool);
+ event.addReturnArgument("pool", pool->objectID());
+ } catch (int i) {
+ delete pool;
+ std::string err = FORMAT_ERR(_conn, "Error constructing pool object in
virStoragePoolCreateXML.", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
- PoolWrap *pool;
- try {
- pool = new PoolWrap(agent, this, pool_ptr, conn);
- pools.push_back(pool);
- io_args->o_pool = pool->GetManagementObject()->getObjectId();
- } catch (int i) {
- delete pool;
- errstr = FORMAT_ERR(conn, "Error constructing pool object in
virStoragePoolDefineXML.", &ret);
- return STATUS_USER + i;
- }
- return STATUS_OK;
+ return true;
+}
- }
- case _qmf::Node::METHOD_STORAGEPOOLCREATEXML:
- {
- _qmf::ArgsNodeStoragePoolCreateXML *io_args =
(_qmf::ArgsNodeStoragePoolCreateXML *) &args;
- virStoragePoolPtr pool_ptr;
-
- pool_ptr = virStoragePoolCreateXML (conn, io_args->i_xmlDesc.c_str(), 0);
- if (pool_ptr == NULL) {
- errstr = FORMAT_ERR(conn, "Error creating storage pool using xml
description (virStoragePoolCreateXML).", &ret);
- return STATUS_USER + ret;
- }
+bool
+NodeWrap::findStoragePoolSources(qmf::AgentSession& session,
+ qmf::AgentEvent& event)
+{
+ qpid::types::Variant::Map args(event.getArguments());
+ const std::string type(args["type"].asString());
+ const std::string srcSpec(args["srcSpec"].asString());
+ char *xml_result;
+ int ret;
- PoolWrap *pool;
- try {
- pool = new PoolWrap(agent, this, pool_ptr, conn);
- pools.push_back(pool);
- io_args->o_pool = pool->GetManagementObject()->getObjectId();
- } catch (int i) {
- delete pool;
- errstr = FORMAT_ERR(conn, "Error constructing pool object in
virStoragePoolCreateXML.", &ret);
- return STATUS_USER + i;
- }
+ xml_result = virConnectFindStoragePoolSources(_conn, type.c_str(), srcSpec.c_str(),
0);
+ if (xml_result == NULL) {
+ std::string err = FORMAT_ERR(_conn, "Error creating storage pool using xml
description (virStoragePoolCreateXML).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
- return STATUS_OK;
+ event.addReturnArgument("xmlDesc", xml_result);
+ free(xml_result);
+
+ return true;
+}
+
+bool
+NodeWrap::handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event)
+{
+ if (!event.hasDataAddr() || *this == event.getDataAddr()) {
+ const std::string& methodName(event.getMethodName());
+ bool success;
+
+ if (methodName == "domainDefineXML") {
+ success = domainDefineXML(session, event);
+ } else if (methodName == "storagePoolDefineXML") {
+ success = storagePoolDefineXML(session, event);
+ } else if (methodName == "storagePoolCreateXML") {
+ success = storagePoolCreateXML(session, event);
+ } else if (methodName == "findStoragePoolSources") {
+ success = findStoragePoolSources(session, event);
+ } else {
+ raiseException(session, event,
+ ERROR_UNKNOWN_METHOD, STATUS_UNKNOWN_METHOD);
+ return true;
}
- case _qmf::Node::METHOD_FINDSTORAGEPOOLSOURCES:
- {
- _qmf::ArgsNodeFindStoragePoolSources *io_args =
(_qmf::ArgsNodeFindStoragePoolSources *) &args;
- char *xml_result;
-
- xml_result = virConnectFindStoragePoolSources(conn,
io_args->i_type.c_str(), io_args->i_srcSpec.c_str(), 0);
- if (xml_result == NULL) {
- errstr = FORMAT_ERR(conn, "Error creating storage pool using xml
description (virStoragePoolCreateXML).", &ret);
- return STATUS_USER + ret;
- }
- io_args->o_xmlDesc = xml_result;
- free(xml_result);
+ if (success) {
+ session.methodSuccess(event);
+ }
+ return true;
+ } else {
+ bool handled = false;
- return STATUS_OK;
+ for (DomainList::iterator iter = _domains.begin();
+ !handled && iter != _domains.end(); iter++) {
+ handled = (*iter)->handleMethod(session, event);
+ }
+
+ for (PoolList::iterator iter = _pools.begin();
+ !handled && iter != _pools.end(); iter++) {
+ handled = (*iter)->handleMethod(session, event);
}
- }
- return STATUS_NOT_IMPLEMENTED;
+ return handled;
+ }
}
static void
@@ -521,7 +577,6 @@ print_usage()
printf("\t-d | --daemon run as a daemon.\n");
printf("\t-h | --help print this help message.\n");
printf("\t-b | --broker specify broker host name..\n");
- printf("\t-g | --gssapi force GSSAPI authentication.\n");
printf("\t-u | --username username to use for authentication
purproses.\n");
printf("\t-s | --service service name to use for authentication
purproses.\n");
printf("\t-p | --port specify broker port.\n");
@@ -536,8 +591,7 @@ int main(int argc, char** argv) {
int idx = 0;
bool verbose = false;
bool daemonize = false;
- bool gssapi = false;
- char *host = NULL;
+ const char *host = NULL;
char *username = NULL;
char *service = NULL;
int port = 5672;
@@ -546,14 +600,13 @@ int main(int argc, char** argv) {
{"help", 0, 0, 'h'},
{"daemon", 0, 0, 'd'},
{"broker", 1, 0, 'b'},
- {"gssapi", 0, 0, 'g'},
{"username", 1, 0, 'u'},
{"service", 1, 0, 's'},
{"port", 1, 0, 'p'},
{0, 0, 0, 0}
};
- while ((arg = getopt_long(argc, argv, "hdb:gu:s:p:", opt, &idx)) != -1)
{
+ while ((arg = getopt_long(argc, argv, "hdb:u:s:p:", opt, &idx)) != -1)
{
switch (arg) {
case 'h':
case '?':
@@ -582,9 +635,6 @@ int main(int argc, char** argv) {
exit(1);
}
break;
- case 'g':
- gssapi = true;
- break;
case 'p':
if (optarg) {
port = atoi(optarg);
@@ -620,44 +670,42 @@ int main(int argc, char** argv) {
// This prevents us from dying if libvirt disconnects.
signal(SIGPIPE, SIG_IGN);
- // Create the management agent
- ManagementAgent::Singleton singleton;
- ManagementAgent* agent = singleton.getInstance();
-
- // Register the schema with the agent
- _qmf::Package packageInit(agent);
-
- // Start the agent. It will attempt to make a connection to the
- // management broker. The third argument is the interval for sending
- // updates to stats/properties to the broker. The last is set to 'true'
- // to keep this all single threaded. Otherwise a second thread would be
- // used to implement methods.
-
- qpid::management::ConnectionSettings settings;
- settings.host = host ? host : "127.0.0.1";
- settings.port = port;
+ qpid::types::Variant::Map options;
if (username != NULL) {
- settings.username = username;
+ options["username"] = username;
}
if (service != NULL) {
- settings.service = service;
+ options["service"] = service;
}
- if (gssapi == true) {
- settings.mechanism = "GSSAPI";
+
+ if (host == NULL) {
+ host = "127.0.0.1";
}
- agent->setName("Red Hat", "libvirt-qpid");
- agent->init(settings, 3, true);
+ std::stringstream url;
+
+ url << "amqp:" << "tcp" << ":"
<< host << ":" << port;
+
+ qpid::messaging::Connection amqp_connection(url.str(), options);
+ amqp_connection.open();
+
+ qmf::AgentSession session(amqp_connection);
+ session.setVendor("redhat.com");
+ session.setProduct("libvirt-qpid");
+ session.setAttribute("hostname", host);
- while(true) {
+ session.open();
+ NodeWrap::PackageDefinition package;
+ package.configure(session);
+
+ initErrorSchema(session);
+
+ while (true) {
try {
- NodeWrap node(agent, "Libvirt Node");
+ NodeWrap node(session, package);
node.doLoop();
- } catch (int err) {
- }
+ } catch (int err) { }
sleep(10);
}
}
-
-
diff --git a/src/NodeWrap.h b/src/NodeWrap.h
index 920608b..6f55061 100644
--- a/src/NodeWrap.h
+++ b/src/NodeWrap.h
@@ -1,60 +1,70 @@
+#ifndef NODE_WRAP_H
+#define NODE_WRAP_H
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-#include <qpid/client/ConnectionSettings.h>
-#include <qpid/sys/Mutex.h>
-
-#include "Package.h"
-#include "Node.h"
-#include "Domain.h"
-#include "Pool.h"
+#include "ManagedObject.h"
+#include "QmfPackage.h"
#include <unistd.h>
#include <cstdlib>
#include <iostream>
+#include <vector>
#include <sstream>
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
-using namespace qpid::management;
-using namespace qpid::sys;
-using namespace std;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::Mutex;
-// Forward decl of DomainWrap to get around cyclic reference.
class DomainWrap;
class PoolWrap;
-class NodeWrap : public Manageable
+class NodeWrap:
+ public PackageOwner<qmf::com::redhat::libvirt::PackageDefinition>,
+ public ManagedObject
{
- string name;
- ManagementAgent *agent;
- qmf::com::redhat::libvirt::Node *mgmtObject;
- std::vector<DomainWrap*> domains;
- std::vector<PoolWrap*> pools;
+ typedef std::vector<DomainWrap*> DomainList;
+ typedef std::vector<PoolWrap*> PoolList;
- virConnectPtr conn;
+ DomainList _domains;
+ PoolList _pools;
-public:
+ virConnectPtr _conn;
- NodeWrap(ManagementAgent* agent, string _name);
- ~NodeWrap();
+ qmf::AgentSession& _session;
+ PackageDefinition& _package;
- ManagementObject* GetManagementObject(void) const
- { return mgmtObject; }
+public:
+ NodeWrap(qmf::AgentSession& agent_session, PackageDefinition& package);
+ ~NodeWrap();
void doLoop();
- void syncDomains();
+
+ bool handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event);
+
+ virtual PackageDefinition& package(void) { return _package; }
+
+ virtual void addData(qmf::Data& data) {
+ _session.addData(data);
+ }
+
+ virtual void delData(qmf::Data& data) {
+ _session.delData(data.getAddr());
+ }
+
+protected:
+ void syncDomains(void);
+ void syncPools(void);
void checkPool(char *pool_name);
- void syncPools();
- status_t ManagementMethod (uint32_t methodId, Args& args, std::string
&errstr);
+ bool domainDefineXML(qmf::AgentSession& session,
+ qmf::AgentEvent& event);
+ bool storagePoolDefineXML(qmf::AgentSession& session,
+ qmf::AgentEvent& event);
+ bool storagePoolCreateXML(qmf::AgentSession& session,
+ qmf::AgentEvent& event);
+ bool findStoragePoolSources(qmf::AgentSession& session,
+ qmf::AgentEvent& event);
};
+#endif
diff --git a/src/PoolWrap.cpp b/src/PoolWrap.cpp
index 0274e63..a5992f2 100644
--- a/src/PoolWrap.cpp
+++ b/src/PoolWrap.cpp
@@ -1,4 +1,3 @@
-
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <string.h>
@@ -7,42 +6,40 @@
#include "PoolWrap.h"
#include "VolumeWrap.h"
#include "Error.h"
+#include "Exception.h"
-#include "ArgsPoolCreateVolumeXML.h"
-#include "ArgsPoolGetXMLDesc.h"
-
-namespace _qmf = qmf::com::redhat::libvirt;
-PoolWrap::PoolWrap(ManagementAgent *_agent, NodeWrap *parent,
- virStoragePoolPtr _pool_pointer, virConnectPtr _connect) :
- agent(_agent), pool_ptr(_pool_pointer), conn(_connect)
+PoolWrap::PoolWrap(NodeWrap *parent,
+ virStoragePoolPtr pool_ptr,
+ virConnectPtr connect):
+ PackageOwner<NodeWrap::PackageDefinition>(parent),
+ ManagedObject(package().data_Pool),
+ _pool_ptr(pool_ptr), _conn(connect)
{
int ret;
char pool_uuid_str[VIR_UUID_STRING_BUFLEN];
const char *pool_name_str;
char *parent_volume = NULL;
- pool = NULL;
-
- ret = virStoragePoolGetUUIDString(pool_ptr, pool_uuid_str);
+ ret = virStoragePoolGetUUIDString(_pool_ptr, pool_uuid_str);
if (ret < 0) {
- REPORT_ERR(conn, "PoolWrap: Unable to get UUID\n");
+ REPORT_ERR(_conn, "PoolWrap: Unable to get UUID\n");
throw 1;
}
- pool_name_str = virStoragePoolGetName(pool_ptr);
+ pool_name_str = virStoragePoolGetName(_pool_ptr);
if (pool_name_str == NULL) {
- REPORT_ERR(conn, "PoolWrap: error getting pool name\n");
+ REPORT_ERR(_conn, "PoolWrap: error getting pool name\n");
throw 1;
}
- pool_sources_xml = virConnectFindStoragePoolSources(conn, "logical", NULL,
0);
+ _pool_sources_xml = virConnectFindStoragePoolSources(_conn, "logical",
NULL, 0);
- if (pool_sources_xml) {
+ if (_pool_sources_xml) {
xmlDocPtr doc;
xmlNodePtr cur;
- doc = xmlParseMemory(pool_sources_xml, strlen(pool_sources_xml));
+ doc = xmlParseMemory(_pool_sources_xml, strlen(_pool_sources_xml));
if (doc == NULL ) {
goto done;
@@ -77,7 +74,7 @@ PoolWrap::PoolWrap(ManagementAgent *_agent, NodeWrap *parent,
if (name && path) {
if (strcmp(pool_name_str, (char *) name) == 0) {
virStorageVolPtr vol;
- vol = virStorageVolLookupByPath(conn, (char *) path);
+ vol = virStorageVolLookupByPath(_conn, (char *) path);
if (vol != NULL) {
printf ("found storage volume associated with
pool!\n");
parent_volume = virStorageVolGetPath(vol);
@@ -96,22 +93,28 @@ PoolWrap::PoolWrap(ManagementAgent *_agent, NodeWrap *parent,
}
done:
+ _pool_name = pool_name_str;
+ _pool_uuid = pool_uuid_str;
- pool_name_str = virStoragePoolGetName(pool_ptr);
-
- pool_name = pool_name_str;
- pool_uuid = pool_uuid_str;
-
- pool = new _qmf::Pool(agent, this, parent, pool_uuid, pool_name, parent_volume ?
parent_volume : "");
- agent->addObject(pool);
+ _data.setProperty("uuid", _pool_uuid);
+ _data.setProperty("name", _pool_name);
+ _data.setProperty("parentVolume", parent_volume ? parent_volume :
"");
+ _data.setProperty("node", parent->objectID());
// Call refresh storage volumes in case anything changed in libvirt.
// I don't think we're too concerned if it fails?
- virStoragePoolRefresh(pool_ptr, 0);
+ virStoragePoolRefresh(_pool_ptr, 0);
// Set storage pool state to an inactive. Should the state be different, the
// subsequent call to update will pick it up and fix it.
- storagePoolState = VIR_STORAGE_POOL_INACTIVE;
+ _storagePoolState = VIR_STORAGE_POOL_INACTIVE;
+
+ // Set the state before adding the new Data object
+ updateProperties();
+
+ // This must be done before update(), which will check for and create any
+ // volumes. (VolumeWrap objects will need a valid parent DataAddr.)
+ addData(_data);
// Call update() here so we set the state and see if there are any volumes
// before returning the new object.
@@ -121,21 +124,21 @@ done:
PoolWrap::~PoolWrap()
{
// Destroy volumes..
- for (std::vector<VolumeWrap*>::iterator iter = volumes.begin(); iter !=
volumes.end();) {
+ VolumeList::iterator iter = _volumes.begin();
+ while (iter != _volumes.end()) {
delete (*iter);
- iter = volumes.erase(iter);
+ iter = _volumes.erase(iter);
}
- if (pool) {
- pool->resourceDestroy();
- }
- virStoragePoolFree(pool_ptr);
+ virStoragePoolFree(_pool_ptr);
+
+ delData(_data);
}
-char *
+const char *
PoolWrap::getPoolSourcesXml()
{
- return pool_sources_xml;
+ return _pool_sources_xml;
}
void
@@ -146,30 +149,30 @@ PoolWrap::syncVolumes()
int i;
virStoragePoolInfo info;
- cout << "Syncing volumes.\n";
+ std::cout << "Syncing volumes.\n";
- ret = virStoragePoolGetInfo(pool_ptr, &info);
+ ret = virStoragePoolGetInfo(_pool_ptr, &info);
if (ret < 0) {
- REPORT_ERR(conn, "PoolWrap: Unable to get info of storage pool");
+ REPORT_ERR(_conn, "PoolWrap: Unable to get info of storage pool");
return;
}
// Only try to list volumes if the storage pool is active.
if (info.state != VIR_STORAGE_POOL_INACTIVE) {
- maxactive = virStoragePoolNumOfVolumes(pool_ptr);
+ maxactive = virStoragePoolNumOfVolumes(_pool_ptr);
if (maxactive < 0) {
//vshError(ctl, FALSE, "%s", _("Failed to list active
vols"));
- REPORT_ERR(conn, "error getting number of volumes in pool\n");
+ REPORT_ERR(_conn, "error getting number of volumes in pool\n");
return;
}
char **names;
names = (char **) malloc(sizeof(char *) * maxactive);
- ret = virStoragePoolListVolumes(pool_ptr, names, maxactive);
+ ret = virStoragePoolListVolumes(_pool_ptr, names, maxactive);
if (ret < 0) {
- REPORT_ERR(conn, "error getting list of volumes\n");
+ REPORT_ERR(_conn, "error getting list of volumes\n");
return;
}
@@ -178,28 +181,28 @@ PoolWrap::syncVolumes()
bool found = false;
char *volume_name = names[i];
- for (std::vector<VolumeWrap*>::iterator iter = volumes.begin();
- iter != volumes.end(); iter++) {
- if ((*iter)->volume_name == volume_name) {
+ for (VolumeList::iterator iter = _volumes.begin();
+ iter != _volumes.end(); iter++) {
+ if (strcmp((*iter)->name(), volume_name) == 0) {
found = true;
break;
}
}
if (!found) {
- vol_ptr = virStorageVolLookupByName(pool_ptr, volume_name);
+ vol_ptr = virStorageVolLookupByName(_pool_ptr, volume_name);
if (vol_ptr == NULL) {
- REPORT_ERR(conn, "error looking up storage volume by
name\n");
+ REPORT_ERR(_conn, "error looking up storage volume by
name\n");
continue;
}
VolumeWrap *volume = NULL;
try {
- VolumeWrap *volume = new VolumeWrap(agent, this, vol_ptr, conn);
+ VolumeWrap *volume = new VolumeWrap(this, vol_ptr, _conn);
printf("Created new volume: %s, ptr is %p\n", volume_name,
vol_ptr);
- volumes.push_back(volume);
+ _volumes.push_back(volume);
} catch (int i) {
printf ("Error constructing volume\n");
- REPORT_ERR(conn, "constructing volume.");
+ REPORT_ERR(_conn, "constructing volume.");
if (volume) {
delete volume;
}
@@ -214,14 +217,14 @@ PoolWrap::syncVolumes()
}
/* Go through our list of volumes and ensure that they still exist. */
- for (std::vector<VolumeWrap*>::iterator iter = volumes.begin(); iter !=
volumes.end();) {
-
- printf ("Verifying volume %s\n", (*iter)->volume_name.c_str());
- virStorageVolPtr ptr = virStorageVolLookupByName(pool_ptr,
(*iter)->volume_name.c_str());
+ VolumeList::iterator iter = _volumes.begin();
+ while (iter != _volumes.end()) {
+ printf ("Verifying volume %s\n", (*iter)->name());
+ virStorageVolPtr ptr = virStorageVolLookupByName(_pool_ptr, (*iter)->name());
if (ptr == NULL) {
- printf("Destroying volume %s\n", (*iter)->volume_name.c_str());
+ printf("Destroying volume %s\n", (*iter)->name());
delete(*iter);
- iter = volumes.erase(iter);
+ iter = _volumes.erase(iter);
} else {
virStorageVolFree(ptr);
iter++;
@@ -229,170 +232,206 @@ PoolWrap::syncVolumes()
}
/* And finally *phew*, call update() on all volumes. */
- for (std::vector<VolumeWrap*>::iterator iter = volumes.begin(); iter !=
volumes.end(); iter++) {
+ for (iter = _volumes.begin(); iter != _volumes.end(); iter++) {
(*iter)->update();
}
}
void
-PoolWrap::update()
+PoolWrap::updateProperties(void)
{
virStoragePoolInfo info;
int ret;
- ret = virStoragePoolGetInfo(pool_ptr, &info);
+ ret = virStoragePoolGetInfo(_pool_ptr, &info);
if (ret < 0) {
- REPORT_ERR(conn, "PoolWrap: Unable to get info of storage pool");
+ REPORT_ERR(_conn, "PoolWrap: Unable to get info of storage pool");
return;
}
+ const char *state = NULL;
switch (info.state) {
case VIR_STORAGE_POOL_INACTIVE:
- pool->set_state("inactive");
+ state = "inactive";
break;
case VIR_STORAGE_POOL_BUILDING:
- pool->set_state("building");
+ state = "building";
break;
case VIR_STORAGE_POOL_RUNNING:
- pool->set_state("running");
+ state = "running";
break;
case VIR_STORAGE_POOL_DEGRADED:
- pool->set_state("degraded");
+ state = "degraded";
break;
}
+ _data.setProperty("state", state);
- pool->set_capacity(info.capacity);
- pool->set_allocation(info.allocation);
- pool->set_available(info.available);
+ _data.setProperty("capacity", (uint64_t)info.capacity);
+ _data.setProperty("allocation", (uint64_t)info.allocation);
+ _data.setProperty("available", (uint64_t)info.available);
// Check if state has changed compared to stored state. If so, rescan
// storage pool sources (eg. logical pools on a lun might now be visible)
- if (storagePoolState != info.state)
- pool_sources_xml = virConnectFindStoragePoolSources(conn, "logical",
NULL, 0);
+ if (_storagePoolState != info.state) {
+ _pool_sources_xml = virConnectFindStoragePoolSources(_conn, "logical",
NULL, 0);
+ }
+
+ _storagePoolState = info.state;
+}
- storagePoolState = info.state;
+void
+PoolWrap::update(void)
+{
+ updateProperties();
- // Sync volumes after (potentially) rescanning for logical storage pool sources
- // so we pick up any new pools if the state of this pool changed.
+ // Sync volumes after (potentially) rescanning for logical storage pool
+ // sources so we pick up any new pools if the state of this pool changed.
syncVolumes();
}
-Manageable::status_t
-PoolWrap::ManagementMethod(uint32_t methodId, Args& args, std::string &errstr)
+bool
+PoolWrap::handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event)
{
- cout << "Method Received: " << methodId << endl;
int ret;
- switch (methodId) {
- case _qmf::Pool::METHOD_GETXMLDESC:
- {
- _qmf::ArgsPoolGetXMLDesc *ioArgs = (_qmf::ArgsPoolGetXMLDesc *) &args;
- char *desc;
-
- desc = virStoragePoolGetXMLDesc(pool_ptr, 0);
- if (desc) {
- ioArgs->o_description = desc;
- } else {
- errstr = FORMAT_ERR(conn, "Error getting XML description of storage
pool (virStoragePoolGetXMLDesc).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
+ if (*this != event.getDataAddr()) {
+ bool handled = false;
+ VolumeList::iterator iter = _volumes.begin();
+
+ while (!handled && iter != _volumes.end()) {
+ handled = (*iter)->handleMethod(session, event);
}
+ return handled;
+ }
- case _qmf::Pool::METHOD_CREATE:
- {
- ret = virStoragePoolCreate(pool_ptr, 0);
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error creating new storage pool
(virStoragePoolCreate).", &ret);
- return STATUS_USER + ret;
- }
- update();
- return STATUS_OK;
+ const std::string& methodName(event.getMethodName());
+ qpid::types::Variant::Map args(event.getArguments());
+
+ if (methodName == "getXMLDesc") {
+ const char *desc = virStoragePoolGetXMLDesc(_pool_ptr, 0);
+ if (!desc) {
+ std::string err = FORMAT_ERR(_conn, "Error getting XML description of
storage pool (virStoragePoolGetXMLDesc).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ event.addReturnArgument("description", desc);
+ session.methodSuccess(event);
}
+ return true;
+ }
- case _qmf::Pool::METHOD_BUILD:
- {
- ret = virStoragePoolBuild(pool_ptr, 0);
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error building storage pool
(virStoragePoolBuild).", &ret);
- return STATUS_USER + ret;
- }
+ if (methodName == "create") {
+ ret = virStoragePoolCreate(_pool_ptr, 0);
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error creating new storage pool
(virStoragePoolCreate).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
update();
- return STATUS_OK;
+ session.methodSuccess(event);
}
+ return true;
+ }
- case _qmf::Pool::METHOD_DESTROY:
- {
- ret = virStoragePoolDestroy(pool_ptr);
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error destroying storage pool
(virStoragePoolDestroy).", &ret);
- return STATUS_USER + ret;
- }
+ if (methodName == "build") {
+ ret = virStoragePoolBuild(_pool_ptr, 0);
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error building storage pool
(virStoragePoolBuild).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
update();
- return STATUS_OK;
+ session.methodSuccess(event);
}
+ return true;
+ }
- case _qmf::Pool::METHOD_DELETE:
- {
- ret = virStoragePoolDelete(pool_ptr, 0);
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error deleting storage pool
(virStoragePoolDelete).", &ret);
- return STATUS_USER + ret;
- }
+ if (methodName == "destroy") {
+ ret = virStoragePoolDestroy(_pool_ptr);
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error destroying storage pool
(virStoragePoolDestroy).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
update();
- return STATUS_OK;
+ session.methodSuccess(event);
}
+ return true;
+ }
- case _qmf::Pool::METHOD_UNDEFINE:
- {
- ret = virStoragePoolUndefine(pool_ptr);
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error undefining storage pool
(virStoragePoolUndefine).", &ret);
- return STATUS_USER + ret;
- }
+ if (methodName == "delete") {
+ ret = virStoragePoolDelete(_pool_ptr, 0);
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error deleting storage pool
(virStoragePoolDelete).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
update();
- return STATUS_OK;
+ session.methodSuccess(event);
}
+ return true;
+ }
- case _qmf::Pool::METHOD_CREATEVOLUMEXML:
- {
- _qmf::ArgsPoolCreateVolumeXML *io_args = (_qmf::ArgsPoolCreateVolumeXML *)
&args;
- virStorageVolPtr volume_ptr;
-
- volume_ptr = virStorageVolCreateXML(pool_ptr, io_args->i_xmlDesc.c_str(),
0);
- if (volume_ptr == NULL) {
- errstr = FORMAT_ERR(conn, "Error creating new storage volume from
XML description (virStorageVolCreateXML).", &ret);
- return STATUS_USER + ret;
- }
-
- VolumeWrap *volume;
- try {
- volume = new VolumeWrap(agent, this, volume_ptr, conn);
- volumes.push_back(volume);
- io_args->o_volume =
volume->GetManagementObject()->getObjectId();
- } catch (int i) {
- delete volume;
- errstr = FORMAT_ERR(conn, "Error constructing pool object in
virStorageVolCreateXML.", &ret);
- return STATUS_USER + i;
- }
-
+ if (methodName == "undefine") {
+ ret = virStoragePoolUndefine(_pool_ptr);
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error undefining storage pool
(virStoragePoolUndefine).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
update();
- return STATUS_OK;
+ session.methodSuccess(event);
}
-
- case _qmf::Pool::METHOD_REFRESH:
- {
- ret = virStoragePoolRefresh(pool_ptr, 0);
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error refreshing storage pool
(virStoragePoolRefresh).", &ret);
- return STATUS_USER + ret;
- }
+ return true;
+ }
+
+ if (methodName == "createVolumeXML") {
+ if (createVolumeXML(session, event)) {
+ session.methodSuccess(event);
+ }
+ return true;
+ }
+
+ if (methodName == "refresh") {
+ ret = virStoragePoolRefresh(_pool_ptr, 0);
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error refreshing storage pool
(virStoragePoolRefresh).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
update();
- return STATUS_OK;
+ session.methodSuccess(event);
}
+ return true;
}
- return STATUS_NOT_IMPLEMENTED;
+ raiseException(session, event,
+ ERROR_UNKNOWN_METHOD, STATUS_UNKNOWN_METHOD);
+ return true;
}
+bool
+PoolWrap::createVolumeXML(qmf::AgentSession& session, qmf::AgentEvent& event)
+{
+ int ret;
+ virStorageVolPtr volume_ptr;
+
+ qpid::types::Variant::Map args(event.getArguments());
+
+ std::string xmlDesc(args["xmlDesc"]);
+ volume_ptr = virStorageVolCreateXML(_pool_ptr, xmlDesc.c_str(), 0);
+ if (volume_ptr == NULL) {
+ std::string err = FORMAT_ERR(_conn, "Error creating new storage volume from
XML description (virStorageVolCreateXML).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
+
+ VolumeWrap *volume;
+ try {
+ volume = new VolumeWrap(this, volume_ptr, _conn);
+ _volumes.push_back(volume);
+ event.addReturnArgument("volume", volume->objectID());
+ } catch (int i) {
+ delete volume;
+ std::string err = FORMAT_ERR(_conn, "Error constructing pool object in
virStorageVolCreateXML.", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ return false;
+ }
+
+ update();
+ return true;
+}
diff --git a/src/PoolWrap.h b/src/PoolWrap.h
index 654ce44..1e6dfeb 100644
--- a/src/PoolWrap.h
+++ b/src/PoolWrap.h
@@ -1,10 +1,7 @@
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-#include <qpid/sys/Mutex.h>
+#ifndef POOL_WRAP_H
+#define POOL_WRAP_H
-#include "Package.h"
-#include "Pool.h"
+#include "NodeWrap.h"
#include <unistd.h>
#include <cstdlib>
@@ -15,49 +12,46 @@
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
-using namespace qpid::management;
-using namespace qpid::sys;
-using namespace std;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::Mutex;
-// Forward decl.
class VolumeWrap;
-class PoolWrap : public Manageable
+class PoolWrap:
+ public PackageOwner<NodeWrap::PackageDefinition>,
+ public ManagedObject
{
- ManagementAgent *agent;
- qmf::com::redhat::libvirt::Pool *pool;
+ typedef std::vector<VolumeWrap*> VolumeList;
- virStoragePoolPtr pool_ptr;
- virConnectPtr conn;
+ virStoragePoolPtr _pool_ptr;
+ virConnectPtr _conn;
- std::vector<VolumeWrap*> volumes;
+ VolumeList _volumes;
- char *pool_sources_xml;
- int storagePoolState;
+ char *_pool_sources_xml;
+ int _storagePoolState;
-public:
+ std::string _pool_name;
+ std::string _pool_uuid;
- PoolWrap(ManagementAgent *agent, NodeWrap *parent, virStoragePoolPtr pool_ptr,
virConnectPtr connect);
+public:
+ PoolWrap(NodeWrap *parent,
+ virStoragePoolPtr pool_ptr,
+ virConnectPtr connect);
~PoolWrap();
- std::string pool_name;
- std::string pool_uuid;
+ std::string name(void) { return _pool_name; }
+ std::string uuid(void) { return _pool_uuid; }
- ManagementObject* GetManagementObject(void) const
- {
- return pool;
- }
+ bool handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event);
- char * getPoolSourcesXml();
+ const char *getPoolSourcesXml();
void update();
void syncVolumes();
- status_t ManagementMethod (uint32_t methodId, Args& args, std::string
&errstr);
-};
+private:
+ void updateProperties();
+ bool createVolumeXML(qmf::AgentSession& session, qmf::AgentEvent& event);
+};
+#endif
diff --git a/src/VolumeWrap.cpp b/src/VolumeWrap.cpp
index d4ce536..fcda96e 100644
--- a/src/VolumeWrap.cpp
+++ b/src/VolumeWrap.cpp
@@ -9,52 +9,54 @@
#include "PoolWrap.h"
#include "VolumeWrap.h"
#include "Error.h"
+#include "Exception.h"
-#include "ArgsVolumeGetXMLDesc.h"
-namespace _qmf = qmf::com::redhat::libvirt;
-
-VolumeWrap::VolumeWrap(ManagementAgent *agent, PoolWrap *parent,
- virStorageVolPtr _volume_ptr, virConnectPtr _conn) :
- conn(_conn), volume_ptr(_volume_ptr)
+VolumeWrap::VolumeWrap(PoolWrap *parent,
+ virStorageVolPtr volume_ptr,
+ virConnectPtr connect):
+ PackageOwner<PoolWrap::PackageDefinition>(parent),
+ ManagedObject(package().data_Volume),
+ _volume_ptr(volume_ptr), _conn(connect),
+ _lvm_name(""), _has_lvm_child(false),
+ _wrap_parent(parent)
{
- const char *volume_key_s;
- char *volume_path_s;
- const char *volume_name_s;
-
- volume = NULL;
+ const char *volume_key;
+ char *volume_path;
+ const char *volume_name;
- wrap_parent = parent;
-
- volume_key_s = virStorageVolGetKey(volume_ptr);
- if (volume_key_s == NULL) {
- REPORT_ERR(conn, "Error getting storage volume key\n");
+ volume_key = virStorageVolGetKey(_volume_ptr);
+ if (volume_key == NULL) {
+ REPORT_ERR(_conn, "Error getting storage volume key\n");
throw 1;
}
- volume_key = volume_key_s;
+ _volume_key = volume_key;
- volume_path_s = virStorageVolGetPath(volume_ptr);
- if (volume_path_s == NULL) {
- REPORT_ERR(conn, "Error getting volume path\n");
+ volume_path = virStorageVolGetPath(_volume_ptr);
+ if (volume_path == NULL) {
+ REPORT_ERR(_conn, "Error getting volume path\n");
throw 1;
}
- volume_path = volume_path_s;
+ _volume_path = volume_path;
- volume_name_s = virStorageVolGetName(volume_ptr);
- if (volume_name_s == NULL) {
- REPORT_ERR(conn, "Error getting volume name\n");
+ volume_name = virStorageVolGetName(_volume_ptr);
+ if (volume_name == NULL) {
+ REPORT_ERR(_conn, "Error getting volume name\n");
throw 1;
}
- volume_name = volume_name_s;
+ _volume_name = volume_name;
- lvm_name = "";
- has_lvm_child = false;
+ _data.setProperty("key", _volume_key);
+ _data.setProperty("path", _volume_path);
+ _data.setProperty("name", _volume_name);
+ _data.setProperty("childLVMName", _lvm_name);
+ _data.setProperty("storagePool", parent->objectID());
- checkForLVMPool();
+ // Set defaults
+ _data.setProperty("capacity", (uint64_t)0);
+ _data.setProperty("allocation", (uint64_t)0);
- volume = new _qmf::Volume(agent, this, parent, volume_key, volume_path, volume_name,
lvm_name);
- printf("adding volume to agent - volume %p\n", volume);
- agent->addObject(volume);
+ addData(_data);
printf("done\n");
}
@@ -63,9 +65,9 @@ void
VolumeWrap::checkForLVMPool()
{
char *real_path = NULL;
- char *pool_sources_xml;
+ const char *pool_sources_xml;
- pool_sources_xml = wrap_parent->getPoolSourcesXml();
+ pool_sources_xml = _wrap_parent->getPoolSourcesXml();
if (pool_sources_xml) {
xmlDocPtr doc;
@@ -106,14 +108,14 @@ VolumeWrap::checkForLVMPool()
if (name && path) {
virStorageVolPtr vol;
- printf ("xml returned device name %s, path %s; volume path is
%s\n", name, path, volume_path.c_str());
- vol = virStorageVolLookupByPath(conn, (char *) path);
+ printf ("xml returned device name %s, path %s; volume path is
%s\n", name, path, _volume_path.c_str());
+ vol = virStorageVolLookupByPath(_conn, (char *) path);
if (vol != NULL) {
real_path = virStorageVolGetPath(vol);
- if (real_path && strcmp(real_path, volume_path.c_str())
== 0) {
+ if (real_path && strcmp(real_path, _volume_path.c_str())
== 0) {
printf ("found matching storage volume associated with
pool!\n");
- lvm_name.assign((char *) name);
- has_lvm_child = true;
+ _lvm_name.assign((char *) name);
+ _has_lvm_child = true;
}
}
xmlFree(path);
@@ -136,58 +138,59 @@ VolumeWrap::update()
printf("Updating volume info\n");
- ret = virStorageVolGetInfo(volume_ptr, &info);
+ ret = virStorageVolGetInfo(_volume_ptr, &info);
if (ret < 0) {
- REPORT_ERR(conn, "VolumeWrap: Unable to get info of storage volume
info\n");
+ REPORT_ERR(_conn, "VolumeWrap: Unable to get info of storage volume
info\n");
return;
}
- volume->set_capacity(info.capacity);
- volume->set_allocation(info.allocation);
+ _data.setProperty("capacity", (uint64_t)info.capacity);
+ _data.setProperty("allocation", (uint64_t)info.allocation);
}
VolumeWrap::~VolumeWrap()
{
- if (volume) {
- volume->resourceDestroy();
- }
- virStorageVolFree(volume_ptr);
+ virStorageVolFree(_volume_ptr);
+
+ delData(_data);
}
-Manageable::status_t
-VolumeWrap::ManagementMethod(uint32_t methodId, Args& args, std::string &errstr)
+bool
+VolumeWrap::handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event)
{
- cout << "Method Received: " << methodId << endl;
int ret;
- switch (methodId) {
- case _qmf::Volume::METHOD_GETXMLDESC:
- {
- _qmf::ArgsVolumeGetXMLDesc *io_args = (_qmf::ArgsVolumeGetXMLDesc *)
&args;
- char *desc;
-
- desc = virStorageVolGetXMLDesc(volume_ptr, 0);
- if (desc) {
- io_args->o_description = desc;
- } else {
- errstr = FORMAT_ERR(conn, "Error getting xml description for volume
(virStorageVolGetXMLDesc).", &ret);
- return STATUS_USER + ret;
- }
- return STATUS_OK;
+ if (*this != event.getDataAddr()) {
+ return false;
+ }
+
+ const std::string& methodName(event.getMethodName());
+ qpid::types::Variant::Map args(event.getArguments());
+
+ if (methodName == "getXMLDesc") {
+ const char *desc = virStorageVolGetXMLDesc(_volume_ptr, 0);
+ if (!desc) {
+ std::string err = FORMAT_ERR(_conn, "Error getting xml description for
volume (virStorageVolGetXMLDesc).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
+ event.addReturnArgument("description", desc);
+ session.methodSuccess(event);
}
- case _qmf::Volume::METHOD_DELETE:
- {
- ret = virStorageVolDelete(volume_ptr, 0);
- if (ret < 0) {
- errstr = FORMAT_ERR(conn, "Error deleting storage volume
(virStorageVolDelete).", &ret);
- return STATUS_USER + ret;
- }
+ return true;
+ }
+
+ if (methodName == "delete") {
+ ret = virStorageVolDelete(_volume_ptr, 0);
+ if (ret < 0) {
+ std::string err = FORMAT_ERR(_conn, "Error deleting storage volume
(virStorageVolDelete).", &ret);
+ raiseException(session, event, err, STATUS_USER + ret);
+ } else {
update();
- return STATUS_OK;
+ session.methodSuccess(event);
}
+ return true;
}
-
- return STATUS_NOT_IMPLEMENTED;
+ raiseException(session, event,
+ ERROR_UNKNOWN_METHOD, STATUS_UNKNOWN_METHOD);
+ return true;
}
-
-
diff --git a/src/VolumeWrap.h b/src/VolumeWrap.h
index 50d1347..7f3a63f 100644
--- a/src/VolumeWrap.h
+++ b/src/VolumeWrap.h
@@ -1,10 +1,7 @@
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-#include <qpid/sys/Mutex.h>
+#ifndef VOLUME_WRAP_H
+#define VOLUME_WRAP_H
-#include "Package.h"
-#include "Volume.h"
+#include "PoolWrap.h"
#include <unistd.h>
#include <cstdlib>
@@ -15,51 +12,36 @@
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
-using namespace qpid::management;
-using namespace qpid::sys;
-using namespace std;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::Mutex;
-// Forward decl.
-class PoolWrap;
-
-class VolumeWrap : public Manageable
+class VolumeWrap:
+ PackageOwner<PoolWrap::PackageDefinition>,
+ public ManagedObject
{
- ManagementAgent *agent;
- qmf::com::redhat::libvirt::Volume *volume;
-
- std::string volume_key;
- std::string volume_path;
+ virStorageVolPtr _volume_ptr;
+ virConnectPtr _conn;
- std::string lvm_name;
- bool has_lvm_child;
+ std::string _volume_name;
+ std::string _volume_key;
+ std::string _volume_path;
- virConnectPtr conn;
- virStorageVolPtr volume_ptr;
+ std::string _lvm_name;
+ bool _has_lvm_child;
- PoolWrap *wrap_parent;
+ PoolWrap *_wrap_parent;
void checkForLVMPool();
public:
-
- std::string volume_name;
-
- VolumeWrap(ManagementAgent *agent, PoolWrap *parent, virStorageVolPtr pool_ptr,
virConnectPtr connect);
+ VolumeWrap(PoolWrap *parent,
+ virStorageVolPtr volume_ptr,
+ virConnectPtr connect);
~VolumeWrap();
- ManagementObject* GetManagementObject(void) const
- {
- return volume;
- }
+ const char *name(void) { return _volume_name.c_str(); }
void update();
- status_t ManagementMethod (uint32_t methodId, Args& args, std::string
&errstr);
+ bool handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event);
};
-
-
+#endif