Commit a13ffdd1 authored by Daniele Kruse's avatar Daniele Kruse
Browse files

Replaced old dump methods for objectstore objects and fixed JSON memory leaks

parent 14a3d2d6
......@@ -225,6 +225,7 @@ std::string cta::objectstore::Agent::dump() {
json_object_object_add(jo, "heartbeat", json_object_new_int64(m_payload.heartbeat()));
json_object_object_add(jo, "timeout_us", json_object_new_int64(m_payload.timeout_us()));
ret << json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(jo);
return ret.str();
}
......
......@@ -128,6 +128,6 @@ std::string cta::objectstore::AgentRegister::dump() {
}
json_object_object_add(jo, "untrackedAgents", jual);
ret << json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY) << std::endl;
free(jo);
json_object_put(jo);
return ret.str();
}
\ No newline at end of file
......@@ -408,6 +408,7 @@ std::string cta::objectstore::ArchiveToFileRequest::dump() {
json_object_object_add(jrf, "size", json_object_new_int64(m_payload.remotefile().size()));
json_object_object_add(jo, "remoteFile", jrf);
ret << json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(jo);
return ret.str();
}
......
......@@ -220,5 +220,6 @@ std::string cta::objectstore::RetrieveToFileRequest::dump() {
json_object_object_add(jo, "log", jlog);
json_object_object_add(jo, "remoteFile", json_object_new_string(m_payload.remotefile().c_str()));
ret << json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(jo);
return ret.str();
}
......@@ -25,6 +25,7 @@
#include "SchedulerGlobalLock.hpp"
#include <cxxabi.h>
#include "ProtocolBuffersAlgorithms.hpp"
#include <json/json.h>
// construtor, when the backend store exists.
// Checks the existence and correctness of the root entry
......@@ -850,18 +851,190 @@ void cta::objectstore::RootEntry::removeSchedulerGlobalLockAndCommit() {
// Dump the root entry
std::string cta::objectstore::RootEntry::dump () {
std::string cta::objectstore::RootEntry::dump () {
checkPayloadReadable();
std::stringstream ret;
ret << "<<<< Root entry dump start" << std::endl;
if (m_payload.has_agentregisterpointer() &&
m_payload.agentregisterpointer().address().size())
ret << "agentRegister=" << m_payload.agentregisterpointer().address() << std::endl;
if (m_payload.agentregisterintent().size())
ret << "agentRegister Intent=" << m_payload.agentregisterintent() << std::endl;
// if (m_payload.has_jobpool()) ret << "jobPool=" << m_payload.jobpool() << std::endl;
/* if (m_payload.has_driveregister()) ret << "driveRegister=" << m_payload.driveregister() << std::endl;
if (m_payload.has_taperegister()) ret << "tapeRegister=" << m_payload.taperegister() << std::endl;*/
ret << ">>>> Root entry dump end" << std::endl;
ret << "RootEntry" << std::endl;
struct json_object * jo = json_object_new_object();
json_object_object_add(jo, "agentregisterintent", json_object_new_string(m_payload.agentregisterintent().c_str()));
{
json_object * pointer = json_object_new_object();
json_object_object_add(pointer, "address", json_object_new_string(m_payload.driveregisterpointer().address().c_str()));
json_object * jlog = json_object_new_object();
json_object_object_add(jlog, "comment", json_object_new_string(m_payload.driveregisterpointer().log().comment().c_str()));
json_object_object_add(jlog, "host", json_object_new_string(m_payload.driveregisterpointer().log().host().c_str()));
json_object_object_add(jlog, "time", json_object_new_int64(m_payload.driveregisterpointer().log().time()));
json_object * id = json_object_new_object();
json_object_object_add(id, "uid", json_object_new_int(m_payload.driveregisterpointer().log().user().uid()));
json_object_object_add(id, "gid", json_object_new_int(m_payload.driveregisterpointer().log().user().gid()));
json_object_object_add(jlog, "user", id);
json_object_object_add(pointer, "log", jlog);
json_object_object_add(jo, "driveregisterpointer", pointer);
}
{
json_object * pointer = json_object_new_object();
json_object_object_add(pointer, "address", json_object_new_string(m_payload.agentregisterpointer().address().c_str()));
json_object * jlog = json_object_new_object();
json_object_object_add(jlog, "comment", json_object_new_string(m_payload.agentregisterpointer().log().comment().c_str()));
json_object_object_add(jlog, "host", json_object_new_string(m_payload.agentregisterpointer().log().host().c_str()));
json_object_object_add(jlog, "time", json_object_new_int64(m_payload.agentregisterpointer().log().time()));
json_object * id = json_object_new_object();
json_object_object_add(id, "uid", json_object_new_int(m_payload.agentregisterpointer().log().user().uid()));
json_object_object_add(id, "gid", json_object_new_int(m_payload.agentregisterpointer().log().user().gid()));
json_object_object_add(jlog, "user", id);
json_object_object_add(pointer, "log", jlog);
json_object_object_add(jo, "agentregisterpointer", pointer);
}
{
json_object * pointer = json_object_new_object();
json_object_object_add(pointer, "address", json_object_new_string(m_payload.schedulerlockpointer().address().c_str()));
json_object * jlog = json_object_new_object();
json_object_object_add(jlog, "comment", json_object_new_string(m_payload.schedulerlockpointer().log().comment().c_str()));
json_object_object_add(jlog, "host", json_object_new_string(m_payload.schedulerlockpointer().log().host().c_str()));
json_object_object_add(jlog, "time", json_object_new_int64(m_payload.schedulerlockpointer().log().time()));
json_object * id = json_object_new_object();
json_object_object_add(id, "uid", json_object_new_int(m_payload.schedulerlockpointer().log().user().uid()));
json_object_object_add(id, "gid", json_object_new_int(m_payload.schedulerlockpointer().log().user().gid()));
json_object_object_add(jlog, "user", id);
json_object_object_add(pointer, "log", jlog);
json_object_object_add(jo, "schedulerlockpointer", pointer);
}
{
json_object * array = json_object_new_array();
for (auto i = m_payload.adminhosts().begin(); i!=m_payload.adminhosts().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "hostname", json_object_new_string(i->hostname().c_str()));
json_object * jlog = json_object_new_object();
json_object_object_add(jlog, "comment", json_object_new_string(i->log().comment().c_str()));
json_object_object_add(jlog, "host", json_object_new_string(i->log().host().c_str()));
json_object_object_add(jlog, "time", json_object_new_int64(i->log().time()));
json_object * id = json_object_new_object();
json_object_object_add(id, "uid", json_object_new_int(i->log().user().uid()));
json_object_object_add(id, "gid", json_object_new_int(i->log().user().gid()));
json_object_object_add(jlog, "user", id);
json_object_object_add(jot, "log", jlog);
json_object_array_add(array, jot);
}
json_object_object_add(jo, "adminhosts", array);
}
{
json_object * array = json_object_new_array();
for (auto i = m_payload.adminusers().begin(); i!=m_payload.adminusers().end(); i++) {
json_object * jot = json_object_new_object();
json_object * fid = json_object_new_object();
json_object_object_add(fid, "uid", json_object_new_int(i->user().uid()));
json_object_object_add(fid, "gid", json_object_new_int(i->user().gid()));
json_object_object_add(jot, "user", fid);
json_object * jlog = json_object_new_object();
json_object_object_add(jlog, "comment", json_object_new_string(i->log().comment().c_str()));
json_object_object_add(jlog, "host", json_object_new_string(i->log().host().c_str()));
json_object_object_add(jlog, "time", json_object_new_int64(i->log().time()));
json_object * id = json_object_new_object();
json_object_object_add(id, "uid", json_object_new_int(i->log().user().uid()));
json_object_object_add(id, "gid", json_object_new_int(i->log().user().gid()));
json_object_object_add(jlog, "user", id);
json_object_object_add(jot, "log", jlog);
json_object_array_add(array, jot);
}
json_object_object_add(jo, "adminusers", array);
}
{
json_object * array = json_object_new_array();
for (auto i = m_payload.storageclasses().begin(); i!=m_payload.storageclasses().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "name", json_object_new_string(i->name().c_str()));
json_object_object_add(jot, "copycount", json_object_new_int(i->copycount()));
json_object * array = json_object_new_array();
for (auto j = i->routes().begin(); j!=i->routes().end(); j++) {
json_object * jott = json_object_new_object();
json_object_object_add(jott, "tapepool", json_object_new_string(j->tapepool().c_str()));
json_object_object_add(jott, "copynb", json_object_new_int(j->copynb()));
json_object * jlogt = json_object_new_object();
json_object_object_add(jlogt, "comment", json_object_new_string(j->log().comment().c_str()));
json_object_object_add(jlogt, "host", json_object_new_string(j->log().host().c_str()));
json_object_object_add(jlogt, "time", json_object_new_int64(j->log().time()));
json_object * idt = json_object_new_object();
json_object_object_add(idt, "uid", json_object_new_int(j->log().user().uid()));
json_object_object_add(idt, "gid", json_object_new_int(j->log().user().gid()));
json_object_object_add(jlogt, "user", idt);
json_object_object_add(jott, "log", jlogt);
json_object_array_add(array, jott);
}
json_object_object_add(jot, "routes", array);
json_object * jlog = json_object_new_object();
json_object_object_add(jlog, "comment", json_object_new_string(i->log().comment().c_str()));
json_object_object_add(jlog, "host", json_object_new_string(i->log().host().c_str()));
json_object_object_add(jlog, "time", json_object_new_int64(i->log().time()));
json_object * id = json_object_new_object();
json_object_object_add(id, "uid", json_object_new_int(i->log().user().uid()));
json_object_object_add(id, "gid", json_object_new_int(i->log().user().gid()));
json_object_object_add(jlog, "user", id);
json_object_object_add(jot, "log", jlog);
json_object_array_add(array, jot);
}
json_object_object_add(jo, "storageclasses", array);
}
{
json_object * array = json_object_new_array();
for (auto i = m_payload.tapepoolpointers().begin(); i!=m_payload.tapepoolpointers().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "name", json_object_new_string(i->name().c_str()));
json_object_object_add(jot, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(jot, "nbpartialtapes", json_object_new_int(i->nbpartialtapes()));
json_object * jlog = json_object_new_object();
json_object_object_add(jlog, "comment", json_object_new_string(i->log().comment().c_str()));
json_object_object_add(jlog, "host", json_object_new_string(i->log().host().c_str()));
json_object_object_add(jlog, "time", json_object_new_int64(i->log().time()));
json_object * id = json_object_new_object();
json_object_object_add(id, "uid", json_object_new_int(i->log().user().uid()));
json_object_object_add(id, "gid", json_object_new_int(i->log().user().gid()));
json_object_object_add(jlog, "user", id);
json_object_object_add(jot, "log", jlog);
json_object_array_add(array, jot);
}
json_object_object_add(jo, "tapepoolpointers", array);
}
{
json_object * array = json_object_new_array();
for (auto i = m_payload.libraries().begin(); i!=m_payload.libraries().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "name", json_object_new_string(i->name().c_str()));
json_object * jlog = json_object_new_object();
json_object_object_add(jlog, "comment", json_object_new_string(i->log().comment().c_str()));
json_object_object_add(jlog, "host", json_object_new_string(i->log().host().c_str()));
json_object_object_add(jlog, "time", json_object_new_int64(i->log().time()));
json_object * id = json_object_new_object();
json_object_object_add(id, "uid", json_object_new_int(i->log().user().uid()));
json_object_object_add(id, "gid", json_object_new_int(i->log().user().gid()));
json_object_object_add(jlog, "user", id);
json_object_object_add(jot, "log", jlog);
json_object_array_add(array, jot);
}
json_object_object_add(jo, "libraries", array);
}
ret << json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(jo);
return ret.str();
}
......@@ -99,6 +99,7 @@ std::string SchedulerGlobalLock::dump() {
json_object_object_add(jo, "nextmountid", json_object_new_int64(m_payload.nextmountid()));
ret << json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(jo);
return ret.str();
}
......
......@@ -19,6 +19,7 @@
#include "Tape.hpp"
#include "GenericObject.hpp"
#include "CreationLog.hpp"
#include <json/json.h>
cta::objectstore::Tape::Tape(const std::string& address, Backend& os):
ObjectOps<serializers::Tape>(os, address) { }
......@@ -117,26 +118,91 @@ std::string cta::objectstore::Tape::getVid() {
return m_payload.vid();
}
std::string cta::objectstore::Tape::dump() {
std::string cta::objectstore::Tape::dump() {
checkPayloadReadable();
std::stringstream ret;
ret << "<<<< Tape dump start: vid=" << m_payload.vid() << std::endl;
ret << " lastFseq=" << m_payload.lastfseq()
<< " bytesStored=" << m_payload.bytesstored() << std::endl;
ret << " Retrieve jobs queued: " << m_payload.retrievejobs_size() << std::endl;
if (m_payload.readmounts_size()) {
auto lrm = m_payload.readmounts(0);
ret << " Latest read for mount: " << lrm.host() << " " << lrm.time() << " "
<< lrm.drivevendor() << " " << lrm.drivemodel() << " "
<< lrm.driveserial() << std::endl;
ret << "TapePool" << std::endl;
struct json_object * jo = json_object_new_object();
json_object_object_add(jo, "vid", json_object_new_string(m_payload.vid().c_str()));
json_object_object_add(jo, "logicallibrary", json_object_new_string(m_payload.logicallibrary().c_str()));
json_object_object_add(jo, "lastfseq", json_object_new_int64(m_payload.lastfseq()));
json_object_object_add(jo, "bytesstored", json_object_new_int64(m_payload.bytesstored()));
json_object_object_add(jo, "retrievejobstotalsize", json_object_new_int64(m_payload.retrievejobstotalsize()));
json_object_object_add(jo, "oldestjobtime", json_object_new_int64(m_payload.oldestjobtime()));
json_object_object_add(jo, "priority", json_object_new_int64(m_payload.priority()));
json_object_object_add(jo, "currentmounttype", json_object_new_int(m_payload.currentmounttype()));
json_object_object_add(jo, "busy", json_object_new_boolean(m_payload.busy()));
json_object_object_add(jo, "archived", json_object_new_boolean(m_payload.archived()));
json_object_object_add(jo, "disabled", json_object_new_boolean(m_payload.disabled()));
json_object_object_add(jo, "readonly", json_object_new_boolean(m_payload.readonly()));
json_object_object_add(jo, "full", json_object_new_boolean(m_payload.full()));
json_object * jlog = json_object_new_object();
json_object_object_add(jlog, "comment", json_object_new_string(m_payload.log().comment().c_str()));
json_object_object_add(jlog, "host", json_object_new_string(m_payload.log().host().c_str()));
json_object_object_add(jlog, "time", json_object_new_int64(m_payload.log().time()));
json_object * id = json_object_new_object();
json_object_object_add(id, "uid", json_object_new_int(m_payload.log().user().uid()));
json_object_object_add(id, "gid", json_object_new_int(m_payload.log().user().gid()));
json_object_object_add(jlog, "user", id);
json_object_object_add(jo, "log", jlog);
{
json_object * minfo = json_object_new_object();
json_object_object_add(minfo, "host", json_object_new_string(m_payload.currentmount().host().c_str()));
json_object_object_add(minfo, "drivevendor", json_object_new_string(m_payload.currentmount().drivevendor().c_str()));
json_object_object_add(minfo, "drivemodel", json_object_new_string(m_payload.currentmount().drivemodel().c_str()));
json_object_object_add(minfo, "driveserial", json_object_new_string(m_payload.currentmount().driveserial().c_str()));
json_object_object_add(minfo, "drivename", json_object_new_string(m_payload.currentmount().drivename().c_str()));
json_object_object_add(minfo, "time", json_object_new_int64(m_payload.currentmount().time()));
json_object_object_add(jo, "currentmount", minfo);
}
if (m_payload.writemounts_size()) {
auto lwm = m_payload.writemounts(0);
ret << " Latest write for mount: " << lwm.host() << " " << lwm.time() << " "
<< lwm.drivevendor() << " " << lwm.drivemodel() << " "
<< lwm.driveserial() << std::endl;
{
json_object * array = json_object_new_array();
for (auto i = m_payload.readmounts().begin(); i!=m_payload.readmounts().end(); i++) {
json_object * minfo = json_object_new_object();
json_object_object_add(minfo, "host", json_object_new_string(i->host().c_str()));
json_object_object_add(minfo, "drivevendor", json_object_new_string(i->drivevendor().c_str()));
json_object_object_add(minfo, "drivemodel", json_object_new_string(i->drivemodel().c_str()));
json_object_object_add(minfo, "driveserial", json_object_new_string(i->driveserial().c_str()));
json_object_object_add(minfo, "drivename", json_object_new_string(i->drivename().c_str()));
json_object_object_add(minfo, "time", json_object_new_int64(i->time()));
json_object_array_add(array, minfo);
}
json_object_object_add(jo, "readmounts", array);
}
{
json_object * array = json_object_new_array();
for (auto i = m_payload.writemounts().begin(); i!=m_payload.writemounts().end(); i++) {
json_object * minfo = json_object_new_object();
json_object_object_add(minfo, "host", json_object_new_string(i->host().c_str()));
json_object_object_add(minfo, "drivevendor", json_object_new_string(i->drivevendor().c_str()));
json_object_object_add(minfo, "drivemodel", json_object_new_string(i->drivemodel().c_str()));
json_object_object_add(minfo, "driveserial", json_object_new_string(i->driveserial().c_str()));
json_object_object_add(minfo, "drivename", json_object_new_string(i->drivename().c_str()));
json_object_object_add(minfo, "time", json_object_new_int64(i->time()));
json_object_array_add(array, minfo);
}
json_object_object_add(jo, "writemounts", array);
}
{
json_object * array = json_object_new_array();
for (auto i = m_payload.retrievejobs().begin(); i!=m_payload.retrievejobs().end(); i++) {
json_object * rjobs = json_object_new_object();
json_object_object_add(rjobs, "size", json_object_new_int64(i->size()));
json_object_object_add(rjobs, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(rjobs, "copynb", json_object_new_int(i->copynb()));
json_object_array_add(array, rjobs);
}
json_object_object_add(jo, "retrievejobs", array);
}
ret << ">>>> Tape dump end" << std::endl;
ret << json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(jo);
return ret.str();
}
......
......@@ -55,52 +55,56 @@ std::string cta::objectstore::TapePool::dump() {
json_object_object_add(jo, "priority", json_object_new_int64(m_payload.priority()));
json_object_object_add(jo, "maxretriespermount", json_object_new_int(m_payload.maxretriespermount()));
json_object_object_add(jo, "maxtotalretries", json_object_new_int(m_payload.maxtotalretries()));
json_object * array = json_object_new_array();
for (auto i = m_payload.tapes().begin(); i!=m_payload.tapes().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "vid", json_object_new_string(i->vid().c_str()));
json_object_object_add(jot, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(jot, "capacity", json_object_new_int64(i->capacity()));
json_object_object_add(jot, "library", json_object_new_string(i->library().c_str()));
json_object_array_add(array, jot);
{
json_object * array = json_object_new_array();
for (auto i = m_payload.tapes().begin(); i!=m_payload.tapes().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "vid", json_object_new_string(i->vid().c_str()));
json_object_object_add(jot, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(jot, "capacity", json_object_new_int64(i->capacity()));
json_object_object_add(jot, "library", json_object_new_string(i->library().c_str()));
json_object_array_add(array, jot);
}
json_object_object_add(jo, "tapes", array);
}
json_object_object_add(jo, "tapes", array);
array = json_object_new_array();
for (auto i = m_payload.pendingarchivejobs().begin(); i!=m_payload.pendingarchivejobs().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(jot, "copynb", json_object_new_int(i->copynb()));
json_object_object_add(jot, "path", json_object_new_string(i->path().c_str()));
json_object_object_add(jot, "size", json_object_new_int64(i->size()));
json_object_array_add(array, jot);
{
json_object * array = json_object_new_array();
for (auto i = m_payload.pendingarchivejobs().begin(); i!=m_payload.pendingarchivejobs().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(jot, "copynb", json_object_new_int(i->copynb()));
json_object_object_add(jot, "path", json_object_new_string(i->path().c_str()));
json_object_object_add(jot, "size", json_object_new_int64(i->size()));
json_object_array_add(array, jot);
}
json_object_object_add(jo, "pendingarchivejobs", array);
}
json_object_object_add(jo, "pendingarchivejobs", array);
array = json_object_new_array();
for (auto i = m_payload.orphanedarchivejobsnscreation().begin(); i!=m_payload.orphanedarchivejobsnscreation().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(jot, "copynb", json_object_new_int(i->copynb()));
json_object_object_add(jot, "path", json_object_new_string(i->path().c_str()));
json_object_object_add(jot, "size", json_object_new_int64(i->size()));
json_object_array_add(array, jot);
{
json_object * array = json_object_new_array();
for (auto i = m_payload.orphanedarchivejobsnscreation().begin(); i!=m_payload.orphanedarchivejobsnscreation().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(jot, "copynb", json_object_new_int(i->copynb()));
json_object_object_add(jot, "path", json_object_new_string(i->path().c_str()));
json_object_object_add(jot, "size", json_object_new_int64(i->size()));
json_object_array_add(array, jot);
}
json_object_object_add(jo, "orphanedarchivejobsnscreation", array);
}
json_object_object_add(jo, "orphanedarchivejobsnscreation", array);
array = json_object_new_array();
for (auto i = m_payload.orphanedarchivejobsnsdeletion().begin(); i!=m_payload.orphanedarchivejobsnsdeletion().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(jot, "copynb", json_object_new_int(i->copynb()));
json_object_object_add(jot, "path", json_object_new_string(i->path().c_str()));
json_object_object_add(jot, "size", json_object_new_int64(i->size()));
json_object_array_add(array, jot);
{
json_object * array = json_object_new_array();
for (auto i = m_payload.orphanedarchivejobsnsdeletion().begin(); i!=m_payload.orphanedarchivejobsnsdeletion().end(); i++) {
json_object * jot = json_object_new_object();
json_object_object_add(jot, "address", json_object_new_string(i->address().c_str()));
json_object_object_add(jot, "copynb", json_object_new_int(i->copynb()));
json_object_object_add(jot, "path", json_object_new_string(i->path().c_str()));
json_object_object_add(jot, "size", json_object_new_int64(i->size()));
json_object_array_add(array, jot);
}
json_object_object_add(jo, "orphanedarchivejobsnsdeletion", array);
}
json_object_object_add(jo, "orphanedarchivejobsnsdeletion", array);
ret << json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(jo);
return ret.str();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment