Added VMGR Tables: VMGR.VMVideo, VMGR.VMInterface, VMGR.Networks, VMGR.Storages
authorzev <zev@radensolutions.com>
Mon, 1 Aug 2016 14:52:39 +0000 (17:52 +0300)
committerzev <zev@radensolutions.com>
Mon, 1 Aug 2016 14:52:51 +0000 (17:52 +0300)
src/agent/subagents/vmgr/dataproviders.cpp
src/agent/subagents/vmgr/hostconnections.cpp
src/agent/subagents/vmgr/vmgr.cpp
src/agent/subagents/vmgr/vmgr.h

index 18c563a..af5bd4e 100644 (file)
@@ -54,11 +54,17 @@ LONG H_GetFromCapabilities(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pVal
 
    const char *xml = conn->getCapabilitiesAndLock();
    if(xml == NULL)
+   {
+      conn->unlockCapabilities();
       return SYSINFO_RC_ERROR;
+   }
 
    Config conf;
    if(!conf.loadXmlConfigFromMemory(xml, strlen(xml), NULL, "capabilities", false))
+   {
+      conn->unlockCapabilities();
       return SYSINFO_RC_ERROR;
+   }
 
    ret_string(pValue, conf.getValue(pArg, _T("")));
    conn->unlockCapabilities();
@@ -284,18 +290,23 @@ struct VMDataStr
  */
 EnumerationCallbackResult FillVMData(const TCHAR *key, const void *obj, void *userData)
 {
-   virDomainPtr vm = (virDomainPtr)obj;
+   NXvirDomain *vm = (NXvirDomain *)obj;
    Table *value = ((VMDataStr *)userData)->value;
    HostConnections *conn = ((VMDataStr *)userData)->conn;
 
    const char *xml = conn->getDomainDefenitionAndLock(key, vm);
+   if(xml == NULL)
+   {
+      conn->unlockDomainDefenition();
+      return _CONTINUE;
+   }
    Config conf;
    if(!conf.loadXmlConfigFromMemory(xml, strlen(xml), NULL, "domain", false))
       AgentWriteLog(2, _T("VMGR.FillVMData(): Not possible to parse VM XML definition"));
    conn->unlockDomainDefenition();
 
    value->addRow();
-   value->set(0, virDomainGetID(vm));
+   value->set(0, virDomainGetID(*vm));
    value->set(1, key);
    value->set(2, conf.getValue(_T("/uuid"), _T("")));
    String os(conf.getValue(_T("/os/type"), _T("Unkonown")));
@@ -308,7 +319,7 @@ EnumerationCallbackResult FillVMData(const TCHAR *key, const void *obj, void *us
    value->set(4, os.getBuffer());
 
    virDomainInfo info;
-   if(virDomainGetInfo(vm, &info) == 0)
+   if(virDomainGetInfo(*vm, &info) == 0)
    {
       value->set(3, info.state < 8 ? vmStateMapping[info.state] :  _T("Unkonown"));
       value->set(6, (UINT64)info.maxMem * 1024);
@@ -326,7 +337,7 @@ EnumerationCallbackResult FillVMData(const TCHAR *key, const void *obj, void *us
    }
 
    int autostart;
-   if(virDomainGetAutostart(vm, &autostart) == 0)
+   if(virDomainGetAutostart(*vm, &autostart) == 0)
    {
       value->set(5, autostart == 0 ? _T("No") : _T("Yes"));
    }
@@ -334,7 +345,7 @@ EnumerationCallbackResult FillVMData(const TCHAR *key, const void *obj, void *us
       value->set(5, _T("Unkonown"));
 
    virDomainControlInfo cInfo;
-   if(virDomainGetControlInfo(vm, &cInfo,0) == 0)
+   if(virDomainGetControlInfo(*vm, &cInfo,0) == 0)
    {
       value->set(10, cInfo.state > 4 ? _T("Unknown") : vmOpStateMapping[cInfo.state]);
       value->set(11, cInfo.details > 4 ? _T("Unknown") : vmOpStateDescMapping[cInfo.details]);
@@ -349,12 +360,12 @@ EnumerationCallbackResult FillVMData(const TCHAR *key, const void *obj, void *us
 
    INT64 seconds;
    UINT32 nsec;
-   if(virDomainGetTime(vm, &seconds, &nsec, 0) == 0)
+   if(virDomainGetTime(*vm, &seconds, &nsec, 0) == 0)
       value->set(13, seconds);
    else
       value->set(13, 0);
 
-   int pers = virDomainIsPersistent(vm);
+   int pers = virDomainIsPersistent(*vm);
    value->set(14, pers == -1 ? _T("Unknown") : pers == 1 ? _T("Yes") : _T("No"));
 
    return _CONTINUE;
@@ -374,7 +385,7 @@ LONG H_GetVMTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractComm
    if(conn == NULL)
       return SYSINFO_RC_NO_SUCH_INSTANCE;
 
-   const StringObjectMap<virDomain> *domains = conn->getDomainListAndLock();
+   const StringObjectMap<NXvirDomain> *domains = conn->getDomainListAndLock();
 
    value->addColumn(_T("ID"), DCI_DT_UINT, _T("ID"));
        value->addColumn(_T("NAME"), DCI_DT_STRING, _T("Name"), true);
@@ -448,7 +459,10 @@ LONG H_GetVMDiskTable(const TCHAR *cmd, const TCHAR *arg, Table *value, Abstract
 
    const char *xml = conn->getDomainDefenitionAndLock(vmName);
    if(xml == NULL)
+   {
+      conn->unlockDomainDefenition();
       return SYSINFO_RC_NO_SUCH_INSTANCE;
+   }
 
    Config conf;
    if(!conf.loadXmlConfigFromMemory(xml, strlen(xml), NULL, "domain", false))
@@ -488,6 +502,7 @@ LONG H_GetVMDiskTable(const TCHAR *cmd, const TCHAR *arg, Table *value, Abstract
          value->set(5, address);
       }
    }
+   delete deviceList;
 
    return SYSINFO_RC_SUCCESS;
 }
@@ -513,7 +528,10 @@ LONG H_GetVMControllerTable(const TCHAR *cmd, const TCHAR *arg, Table *value, Ab
 
    const char *xml = conn->getDomainDefenitionAndLock(vmName);
    if(xml == NULL)
+   {
+      conn->unlockDomainDefenition();
       return SYSINFO_RC_NO_SUCH_INSTANCE;
+   }
 
    Config conf;
    if(!conf.loadXmlConfigFromMemory(xml, strlen(xml), NULL, "domain", false))
@@ -533,6 +551,7 @@ LONG H_GetVMControllerTable(const TCHAR *cmd, const TCHAR *arg, Table *value, Ab
       value->set(1, item->getAttributeAsInt(_T("index"), 0));
       value->set(2, item->getAttribute(_T("model")));
    }
+   delete deviceList;
 
    return SYSINFO_RC_SUCCESS;
 }
@@ -558,7 +577,10 @@ LONG H_GetVMInterfaceTable(const TCHAR *cmd, const TCHAR *arg, Table *value, Abs
 
    const char *xml = conn->getDomainDefenitionAndLock(vmName);
    if(xml == NULL)
+   {
+      conn->unlockDomainDefenition();
       return SYSINFO_RC_NO_SUCH_INSTANCE;
+   }
 
    Config conf;
    if(!conf.loadXmlConfigFromMemory(xml, strlen(xml), NULL, "domain", false))
@@ -586,6 +608,218 @@ LONG H_GetVMInterfaceTable(const TCHAR *cmd, const TCHAR *arg, Table *value, Abs
       if(tmp != NULL)
          value->set(3, tmp->getAttribute(_T("type")));
    }
+   delete deviceList;
+
+   return SYSINFO_RC_SUCCESS;
+}
+
+/**
+ * Get table of video adapter settings for VM
+ */
+LONG H_GetVMVideoTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session)
+{
+   TCHAR name[256];
+   TCHAR vmName[256];
+
+       if (!AgentGetParameterArg(cmd, 1, name, 256))
+               return SYSINFO_RC_UNSUPPORTED;
+
+       if (!AgentGetParameterArg(cmd, 2, vmName, 256))
+               return SYSINFO_RC_UNSUPPORTED;
+
+   _tcsupr(vmName);
+   HostConnections *conn = g_connectionList.get(name);
+   if(conn == NULL)
+      return SYSINFO_RC_NO_SUCH_INSTANCE;
+
+   const char *xml = conn->getDomainDefenitionAndLock(vmName);
+   if(xml == NULL)
+   {
+      conn->unlockDomainDefenition();
+      return SYSINFO_RC_NO_SUCH_INSTANCE;
+   }
+
+   Config conf;
+   if(!conf.loadXmlConfigFromMemory(xml, strlen(xml), NULL, "domain", false))
+               return SYSINFO_RC_UNSUPPORTED;
+   conn->unlockDomainDefenition();
+
+       value->addColumn(_T("TYPE"), DCI_DT_STRING, _T("Type"), true);
+       value->addColumn(_T("VRAM"), DCI_DT_UINT64, _T("Video RAM"));
+
+   ObjectArray<ConfigEntry> *deviceList = conf.getSubEntries(_T("/devices"), _T("video"));
+   for(int i = 0; i < deviceList->size(); i++)
+   {
+      value->addRow();
+      ConfigEntry *item = deviceList->get(i);
+      ConfigEntry *tmp = item->findEntry(_T("model"));
+      if(tmp != NULL)
+      {
+         value->set(0, tmp->getAttribute(_T("type")));
+         value->set(1, tmp->getAttributeAsUInt64(_T("vram")) * 1024);
+      }
+   }
+   delete deviceList;
+
+   return SYSINFO_RC_SUCCESS;
+}
+
+
+/**
+ * Callback that fills table with Network information
+ */
+EnumerationCallbackResult FillNetworkData(const TCHAR *key, const void *obj, void *userData)
+{
+   NXvirNetwork *network = (NXvirNetwork *)obj;
+   Table *value = ((VMDataStr *)userData)->value;
+   HostConnections *conn = ((VMDataStr *)userData)->conn;
+
+   const char *xml = conn->getNetworkDefenitionAndLock(key, network);
+   if(xml == NULL)
+   {
+      conn->unlockNetworkDefenition();
+      return _CONTINUE;
+   }
+   Config conf;
+   if(!conf.loadXmlConfigFromMemory(xml, strlen(xml), NULL, "network", false))
+      AgentWriteLog(2, _T("VMGR.FillVMData(): Not possible to parse VM XML definition"));
+   conn->unlockNetworkDefenition();
+
+   value->addRow();
+   value->set(0, conf.getValue(_T("/name"), _T("Unkonown")));
+   value->set(1, conf.getValue(_T("/uuid"), _T("")));
+
+   //concat all interfaces
+   String ifaces;
+   ObjectArray<ConfigEntry> *ifaceList = conf.getSubEntries(_T("/forward"), _T("interface"));
+   for(int i = 0; i < ifaceList->size(); i++)
+   {
+      ConfigEntry *item = ifaceList->get(i);
+      ifaces.append(item->getAttribute(_T("dev")));
+      if(i+1 != ifaceList->size())
+         ifaces.append(_T(", "));
+   }
+   value->set(2, ifaces.getBuffer());
+   delete ifaceList;
+
+   //concat all portgroups
+   String portgroup;
+   ObjectArray<ConfigEntry> *portgroupList = conf.getSubEntries(_T("/"), _T("portgroup"));
+   for(int i = 0; i < portgroupList->size(); i++)
+   {
+      ConfigEntry *item = portgroupList->get(i);
+      portgroup.append(item->getAttribute(_T("name")));
+      if(i+1 != portgroupList->size())
+         portgroup.append(_T(", "));
+   }
+   value->set(3, portgroup.getBuffer());
+   delete portgroupList;
+
+   return _CONTINUE;
+}
+
+/**
+ * Get table of networks
+ */
+LONG H_GetNetworksTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session)
+{
+   TCHAR name[256];
+
+       if (!AgentGetParameterArg(cmd, 1, name, 256))
+               return SYSINFO_RC_UNSUPPORTED;
+
+
+   HostConnections *conn = g_connectionList.get(name);
+   if(conn == NULL)
+      return SYSINFO_RC_NO_SUCH_INSTANCE;
+
+   const StringObjectMap<NXvirNetwork> *networks = conn->getNetworkListAndLock();
+   if(networks == NULL)
+   {
+      conn->unlockNetworkList();
+      return SYSINFO_RC_NO_SUCH_INSTANCE;
+   }
+
+       value->addColumn(_T("NAME"), DCI_DT_STRING, _T("Name"), true);
+       value->addColumn(_T("UUID"), DCI_DT_UINT64, _T("UUID"));
+       value->addColumn(_T("IFACE"), DCI_DT_UINT64, _T("Interfaces"));
+       value->addColumn(_T("PORTGROUP"), DCI_DT_UINT64, _T("Port group"));
+
+   VMDataStr data;
+   data.value = value;
+   data.conn = conn;
+
+   networks->forEach(FillNetworkData, &data);
+   conn->unlockNetworkList();
+   return SYSINFO_RC_SUCCESS;
+}
+
+static const TCHAR *storagePoolState[] =
+{
+   _T("Not running"),
+   _T("Initializing pool, not available"),
+   _T("Running normally"),
+   _T("Running degraded"),
+   _T("Running, but not accessible")
+   _T("Unknown")
+};
+
+/**
+ * Callback that fills table with VM information
+ */
+EnumerationCallbackResult FillStorageData(const TCHAR *key, const void *obj, void *userData)
+{
+   NXvirStoragePool *storage = (NXvirStoragePool *)obj;
+   Table *value = ((VMDataStr *)userData)->value;
+   HostConnections *conn = ((VMDataStr *)userData)->conn;
+   const virStoragePoolInfo *info = conn->getStorageInformationAndLock(key, storage);
+
+   value->addRow();
+   value->set(0, key);
+   value->set(1, storagePoolState[info->state < 5 && info->state >= 0 ? info->state : 5]);
+   value->set(2, info->capacity);
+   value->set(3, info->allocation);
+   value->set(4, info->available);
+
+   conn->unlockStorageInfo();
+   return _CONTINUE;
+}
+
+
+/**
+ * Get table of storage
+ */
+LONG H_GetStoragesTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session)
+{
+   TCHAR name[256];
+
+       if (!AgentGetParameterArg(cmd, 1, name, 256))
+               return SYSINFO_RC_UNSUPPORTED;
+
+
+   HostConnections *conn = g_connectionList.get(name);
+   if(conn == NULL)
+      return SYSINFO_RC_NO_SUCH_INSTANCE;
+
+   const StringObjectMap<NXvirStoragePool> *storages = conn->getStorageListAndLock();
+   if(storages == NULL)
+   {
+      conn->unlockStorageList();
+      return SYSINFO_RC_NO_SUCH_INSTANCE;
+   }
+
+
+       value->addColumn(_T("NAME"), DCI_DT_STRING, _T("Name"), true);
+       value->addColumn(_T("STATE"), DCI_DT_STRING, _T("State"));
+       value->addColumn(_T("CAPACITY"), DCI_DT_UINT64, _T("Capacity"));
+       value->addColumn(_T("ALLOCATION"), DCI_DT_UINT64, _T("Allocation"));
+       value->addColumn(_T("AVAILABLE"), DCI_DT_UINT64, _T("Available"));
+
+   VMDataStr data;
+   data.value = value;
+   data.conn = conn;
 
+   storages->forEach(FillStorageData, &data);
+   conn->unlockStorageList();
    return SYSINFO_RC_SUCCESS;
 }
index 11d41f2..af37f4c 100644 (file)
 /**
  * Host connection constructor
  */
-HostConnections::HostConnections(const TCHAR *name, const char *url, const char *login, const char *password) : m_vmXMLs(true)
+HostConnections::HostConnections(const TCHAR *name, const char *url, const char *login, const char *password)
+                                 : m_vmXMLs(true),m_networkXMLs(true),m_storageInfo(true),m_domains(false),m_iface(false),
+                                 m_networks(false),m_storages(false)
 {
    m_name = _tcsdup(name);
    m_url = strdup(url);
    m_login = strdup(login);
    m_password = strdup(password);
-   m_domains.setMalloc(false);
-   m_iface.setMalloc(false);
    m_vmXMLMutex = MutexCreate();
+   m_networkXMLMutex = MutexCreate();
+   m_storageInfoMutex = MutexCreate();
 }
 
 /**
@@ -45,6 +47,8 @@ HostConnections::~HostConnections()
    free(m_login);
    free(m_password);
    MutexDestroy(m_vmXMLMutex);
+   MutexDestroy(m_networkXMLMutex);
+   MutexDestroy(m_storageInfoMutex);
 }
 
 /**
@@ -214,7 +218,7 @@ UINT64 HostConnections::getLibraryVersion()
 /**
  * List running VMs(domains)
  */
-const StringObjectMap<virDomain> *HostConnections::getDomainListAndLock()
+const StringObjectMap<NXvirDomain> *HostConnections::getDomainListAndLock()
 {
    m_domains.lock();
    if(m_domains.shouldUpdate())
@@ -228,25 +232,25 @@ const StringObjectMap<virDomain> *HostConnections::getDomainListAndLock()
       numActiveDomains = virConnectListDomains(m_connection, activeDomains, numActiveDomains);
       numInactiveDomains = virConnectListDefinedDomains(m_connection, inactiveDomains, numInactiveDomains);
 
-      StringObjectMapC<virDomain> *allDomains = new StringObjectMapC<virDomain>(true);
+      StringObjectMap<NXvirDomain> *allDomains = new StringObjectMap<NXvirDomain>(true);
 
       for (int i = 0 ; i < numActiveDomains ; i++)
       {
          virDomainPtr vm = virDomainLookupByID(m_connection, activeDomains[i]);
 #ifdef UNICODE
-         allDomains->setPreallocated(WideStringFromMBString(virDomainGetName(vm)), vm);
+         allDomains->setPreallocated(WideStringFromMBString(virDomainGetName(vm)), new NXvirDomain(vm));
 #else
-         allDomains->set(virDomainGetName(vm), vm);
+         allDomains->set(virDomainGetName(vm), new NXvirDomain(vm));
 #endif
       }
 
       for (int i = 0 ; i < numInactiveDomains ; i++)
       {
  #ifdef UNICODE
-         allDomains->setPreallocated(WideStringFromMBString(inactiveDomains[i]), virDomainLookupByName(m_connection, inactiveDomains[i]));
+         allDomains->setPreallocated(WideStringFromMBString(inactiveDomains[i]), new NXvirDomain(virDomainLookupByName(m_connection, inactiveDomains[i])));
          free(inactiveDomains[i]);
 #else
-         allDomains->setPreallocated(inactiveDomains[i], virDomainLookupByName(m_connection, inactiveDomains[i]));
+         allDomains->setPreallocated(inactiveDomains[i], new NXvirDomain(virDomainLookupByName(m_connection, inactiveDomains[i])));
 #endif
       }
 
@@ -269,7 +273,7 @@ void HostConnections::unlockDomainList()
 /**
  * Returns domain definition in XML format
  */
-const char *HostConnections::getDomainDefenitionAndLock(const TCHAR *name, virDomainPtr vm)
+const char *HostConnections::getDomainDefenitionAndLock(const TCHAR *name, NXvirDomain *vm)
 {
    MutexLock(m_vmXMLMutex);
    Cashe<char> *xmlChase = m_vmXMLs.get(name);
@@ -278,12 +282,12 @@ const char *HostConnections::getDomainDefenitionAndLock(const TCHAR *name, virDo
       bool getDomain = vm == NULL;
       if(getDomain)
       {
-         const StringObjectMap<virDomain> *vmMap = getDomainListAndLock();
+         const StringObjectMap<NXvirDomain> *vmMap = getDomainListAndLock();
          vm = vmMap->get(name);
       }
       if(vm != NULL)
       {
-         char *xml = virDomainGetXMLDesc(vm, VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_INACTIVE);
+         char *xml = virDomainGetXMLDesc(*vm, VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_INACTIVE);
          if(xmlChase == NULL)
          {
             xmlChase = new Cashe<char>();
@@ -295,6 +299,7 @@ const char *HostConnections::getDomainDefenitionAndLock(const TCHAR *name, virDo
       else
       {
          m_vmXMLs.remove(name);
+         xmlChase = NULL;
       }
 
       if(getDomain)
@@ -371,3 +376,229 @@ void HostConnections::unlockIfaceList()
 {
    m_iface.unlock();
 }
+
+/**---------
+ * Networks
+ */
+
+/**
+ * List networks
+ */
+const StringObjectMap<NXvirNetwork> *HostConnections::getNetworkListAndLock()
+{
+   m_networks.lock();
+   if(m_networks.shouldUpdate())
+   {
+      int numActiveNetworks = virConnectNumOfNetworks(m_connection);
+      int numInactiveNetworks = virConnectNumOfDefinedNetworks(m_connection);
+
+      char **inactiveNetworks = (char **)malloc(sizeof(char *) * numInactiveNetworks);
+      char **activeNetworks = (char **)malloc(sizeof(char *) * numActiveNetworks);
+
+      numActiveNetworks = virConnectListNetworks(m_connection, activeNetworks, numActiveNetworks);
+      numInactiveNetworks = virConnectListDefinedNetworks(m_connection, inactiveNetworks, numInactiveNetworks);
+
+      StringObjectMap<NXvirNetwork> *allNetworks = new StringObjectMap<NXvirNetwork>(true);
+
+      for (int i = 0 ; i < numActiveNetworks ; i++)
+      {
+#ifdef UNICODE
+         allNetworks->setPreallocated(WideStringFromMBString(activeNetworks[i]), new NXvirNetwork(virNetworkLookupByName(m_connection, activeNetworks[i])));
+         free(activeNetworks[i]);
+#else
+         allNetworks->set(activeNetworks[i], new NXvirNetwork(virNetworkLookupByName(m_connection, activeNetworks[i])));
+#endif
+      }
+
+      for (int i = 0 ; i < numInactiveNetworks ; i++)
+      {
+ #ifdef UNICODE
+         allNetworks->setPreallocated(WideStringFromMBString(inactiveNetworks[i]), new NXvirNetwork(virNetworkLookupByName(m_connection, inactiveNetworks[i])));
+         free(inactiveNetworks[i]);
+#else
+         allNetworks->setPreallocated(inactiveNetworks[i], new NXvirNetwork(virNetworkLookupByName(m_connection, inactiveNetworks[i])));
+#endif
+      }
+
+      free(activeNetworks);
+      free(inactiveNetworks);
+
+      m_networks.update(allNetworks);
+   }
+   //AgentWriteLog(6, _T("VMGR: ******Network list size: %d"), m_networks.getData()->size());
+   return m_networks.getData();
+}
+
+void HostConnections::unlockNetworkList()
+{
+   m_networks.unlock();
+}
+
+/**
+ * Returns network definition in XML format
+ */
+const char *HostConnections::getNetworkDefenitionAndLock(const TCHAR *name, NXvirNetwork *network)
+{
+   MutexLock(m_networkXMLMutex);
+   Cashe<char> *xmlChase = m_networkXMLs.get(name);
+   if (xmlChase == NULL || xmlChase->shouldUpdate())
+   {
+      bool getNetwork = network == NULL;
+      if(getNetwork)
+      {
+         const StringObjectMap<NXvirNetwork> *networkMap = getNetworkListAndLock();
+         network = networkMap->get(name);
+      }
+      if(network != NULL)
+      {
+         char *xml = virNetworkGetXMLDesc(*network, 0);
+         if(xmlChase == NULL)
+         {
+            xmlChase = new Cashe<char>();
+            m_networkXMLs.set(name, xmlChase);
+         }
+         xmlChase->update(xml);
+      }
+      else
+      {
+         m_networkXMLs.remove(name);
+         xmlChase = NULL;
+      }
+
+      if(getNetwork)
+         unlockNetworkList();
+   }
+/*
+   if(xmlChase != NULL)
+      AgentWriteLog(6, _T("VMGR: ******Network defenition: %hs"), xmlChase->getData());
+   else
+      AgentWriteLog(6, _T("VMGR: ******Network defenition: NULL"));
+*/
+   return xmlChase != NULL ? xmlChase->getData() : NULL;
+}
+
+/**
+ * Unlocks network definition
+ */
+void HostConnections::unlockNetworkDefenition()
+{
+   MutexUnlock(m_networkXMLMutex);
+}
+
+
+/**---------
+ * Storages
+ */
+
+ /*
+   virConnectNumOfStoragePools
+   virConnectNumOfDefinedStoragePools
+   virConnectListStoragePools
+   virConnectListDefinedStoragePools
+   virStoragePoolGetInfo - more info
+   virStoragePoolGetXMLDesc - more info
+   virStoragePoolLookupByName - get pointer
+   */
+
+/**
+ * List volumes
+ */
+const StringObjectMap<NXvirStoragePool> *HostConnections::getStorageListAndLock()
+{
+   m_storages.lock();
+   if(m_storages.shouldUpdate())
+   {
+      int numActive = virConnectNumOfStoragePools(m_connection);
+      int numInactive = virConnectNumOfDefinedStoragePools(m_connection);
+
+      char **inactive = (char **)malloc(sizeof(char *) * numInactive);
+      char **active = (char **)malloc(sizeof(char *) * numActive);
+
+      numActive = virConnectListStoragePools(m_connection, active, numActive);
+      numInactive = virConnectListDefinedStoragePools(m_connection, inactive, numInactive);
+
+      StringObjectMap<NXvirStoragePool> *allStorage = new StringObjectMap<NXvirStoragePool>(true);
+
+      for (int i = 0 ; i < numActive; i++)
+      {
+#ifdef UNICODE
+         allStorage->setPreallocated(WideStringFromMBString(active[i]), new NXvirStoragePool(virStoragePoolLookupByName(m_connection, active[i])));
+         free(active[i]);
+#else
+         allStorage->set(activeNetworks[i], new NXvirStoragePool(virStoragePoolLookupByName(m_connection, activeNetworks[i])));
+#endif
+      }
+
+      for (int i = 0 ; i < numInactive; i++)
+      {
+ #ifdef UNICODE
+         allStorage->setPreallocated(WideStringFromMBString(inactive[i]), new NXvirStoragePool(virStoragePoolLookupByName(m_connection, inactive[i])));
+         free(inactive[i]);
+#else
+         allStorage->setPreallocated(inactive[i], new NXvirStoragePool(virStoragePoolLookupByName(m_connection, inactive[i])));
+#endif
+      }
+
+      free(active);
+      free(inactive);
+
+      m_storages.update(allStorage);
+   }
+   //AgentWriteLog(6, _T("VMGR: ******Storage list size: %d"), m_storages.getData()->size());
+   return m_storages.getData();
+}
+
+void HostConnections::unlockStorageList()
+{
+   m_storages.unlock();
+}
+
+/**
+ * Returns storage definition in XML format
+ */
+const virStoragePoolInfo *HostConnections::getStorageInformationAndLock(const TCHAR *name, NXvirStoragePool *storage)
+{
+   MutexLock(m_storageInfoMutex);
+   Cashe<virStoragePoolInfo> *info = m_storageInfo.get(name);
+   if (info == NULL || info->shouldUpdate())
+   {
+      bool getStorage = storage == NULL;
+      if(getStorage)
+      {
+         const StringObjectMap<NXvirStoragePool> *storageMap = getStorageListAndLock();
+         storage = storageMap->get(name);
+      }
+      if(storage != NULL)
+      {
+         virStoragePoolInfoPtr newInfo = (virStoragePoolInfoPtr)malloc(sizeof(virStoragePoolInfo));
+         if(virStoragePoolGetInfo(*storage, newInfo) == 0)
+         {
+            if(info == NULL)
+            {
+               info = new Cashe<virStoragePoolInfo>();
+               m_storageInfo.set(name, info);
+            }
+            info->update(newInfo);
+         }
+
+      }
+      else
+      {
+         m_storageInfo.remove(name);
+         info = NULL;
+      }
+
+      if(getStorage)
+         unlockStorageList();
+   }
+   return info != NULL ? info->getData() : NULL;
+}
+
+/**
+ * Unlocks network definition
+ */
+void HostConnections::unlockStorageInfo()
+{
+   MutexUnlock(m_storageInfoMutex);
+}
+
index f494b81..1e418e8 100644 (file)
@@ -212,7 +212,10 @@ static NETXMS_SUBAGENT_TABLE m_tables[] =
        { _T("VMGR.InterfaceList(*)"), H_GetIfaceTable, NULL, _T("NAME"), _T("Connection interface list") },
        { _T("VMGR.VMDisks(*)"), H_GetVMDiskTable, NULL, _T("DNAME"), _T("VM Disks") },
        { _T("VMGR.VMController(*)"), H_GetVMControllerTable, NULL, _T("TYPE"), _T("VM Controllers") },
-       { _T("VMGR.VMInterface(*)"), H_GetVMInterfaceTable, NULL, _T("MAC"), _T("VM Interfaces") }
+       { _T("VMGR.VMInterface(*)"), H_GetVMInterfaceTable, NULL, _T("MAC"), _T("VM Interfaces") },
+       { _T("VMGR.VMVideo(*)"), H_GetVMVideoTable, NULL, _T("TYPE"), _T("VM Video adapter settings") },
+       { _T("VMGR.Networks(*)"), H_GetNetworksTable, NULL, _T("Name"), _T("Networks table") },
+       { _T("VMGR.Storages(*)"), H_GetStoragesTable, NULL, _T("Name"), _T("Storages table") }
 };
 
 /**
index 8aa8a80..f914f50 100644 (file)
@@ -43,50 +43,81 @@ LONG H_GetIfaceTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractC
 LONG H_GetVMDiskTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
 LONG H_GetVMControllerTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
 LONG H_GetVMInterfaceTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
-
+LONG H_GetVMVideoTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
+LONG H_GetNetworksTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
+LONG H_GetStoragesTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
 
 /**
  * String map template for holding objects as values
- */
 template <class T> class StringObjectMapC : public StringObjectMap<T>
 {
 private:
-       static void destructorC(void *object) { virDomainFree((virDomainPtr)object); }
+   int ( *memFreeCallback)(T *obj);
+       static void destructorC(void *object) { memFreeCallback((T *)object); }
 
 public:
-       StringObjectMapC(bool objectOwner) : StringObjectMap<T>(objectOwner) { StringMapBase::m_objectDestructor = destructorC; }
+       StringObjectMapC(bool objectOwner) : StringObjectMap<T>(objectOwner) { memFreeCallback = cb; StringMapBase::m_objectDestructor = destructorC; }
 };
+*/
 
+class NXvirDomain
+{
+private:
+   virDomainPtr vm;
+public:
+   NXvirDomain(virDomainPtr vm) { this->vm = vm; }
+   ~NXvirDomain() { virDomainFree(vm); }
+   operator virDomainPtr() const { return vm; }
+};
+
+class NXvirNetwork
+{
+private:
+   virNetworkPtr network;
+public:
+   NXvirNetwork(virNetworkPtr network) { this->network = network; }
+   ~NXvirNetwork() { virNetworkFree(network); }
+   operator virNetworkPtr() const { return network; }
+};
+
+class NXvirStoragePool
+{
+private:
+   virStoragePoolPtr storage;
+public:
+   NXvirStoragePool(virStoragePoolPtr storage) { this->storage = storage; }
+   ~NXvirStoragePool() {virStoragePoolFree(storage); }
+   operator virStoragePoolPtr() const { return storage; }
+};
 
 /**
  * Data cashing class
  */
-template <class StoredData> class Cashe
+template <class T> class Cashe
 {
 private:
    time_t m_lastCollectionTime;
-   StoredData *m_data;
-   bool isMallocAlloc;
+   T *m_data;
+   bool mallocObj;
+
 public:
-   Cashe() { m_lastCollectionTime = NEVER; m_data = NULL; isMallocAlloc = true;}
-   ~Cashe() { if(isMallocAlloc){ free(m_data); } else { delete(m_data); } }
-   //XmlCashe(StoredData *data) { m_lastCollectionTime = time(NULL); m_data = data; }
-   void setMalloc(bool value) { isMallocAlloc = value; }
-   const StoredData *getData() { return m_data; }
+   Cashe(bool mallocObj = true) { m_lastCollectionTime = NEVER; m_data = NULL; this->mallocObj = mallocObj;}
+   ~Cashe() { if(mallocObj){ free(m_data); } else { delete(m_data); } }
+   const T *getData() { return m_data; }
    const time_t getLastCollecitonTime() { return m_lastCollectionTime; }
-   void update(StoredData* data) { m_lastCollectionTime = time(NULL); if(isMallocAlloc){ free(m_data); } else { delete(m_data); } m_data = data; }
+   void update(T* data) { m_lastCollectionTime = time(NULL); if(mallocObj){ free(m_data); } else { delete(m_data); } m_data = data; }
    bool shouldUpdate() { return (time(NULL) - m_lastCollectionTime) > DATA_COLLECTION_CASHE_TIME; }
 };
 
 /**
  * Data cashing class
  */
-template <class StoredData> class CasheAndLock : public Cashe<StoredData>
+template <class T> class CasheAndLock : public Cashe<T>
 {
 private:
    MUTEX m_mutex;
 public:
-   CasheAndLock() : Cashe<StoredData>() { m_mutex = MutexCreate(); }
+   CasheAndLock(bool mallocObj = true) : Cashe<T>(mallocObj) { m_mutex = MutexCreate(); }
    ~CasheAndLock() { MutexDestroy(m_mutex); }
    void lock() { MutexLock(m_mutex); }
    void unlock() { MutexUnlock(m_mutex); }
@@ -106,11 +137,17 @@ private:
 
    CasheAndLock<char> m_capabilities;
    CasheAndLock<virNodeInfo> m_nodeInfo;
-   CasheAndLock<StringObjectMap<virDomain> > m_domains;
+   CasheAndLock<StringObjectMap<NXvirDomain> > m_domains;
    CasheAndLock<StringList> m_iface;
-   //XmlCashe m_storages;
+   CasheAndLock<StringObjectMap<NXvirNetwork> > m_networks;
+   CasheAndLock<StringObjectMap<NXvirStoragePool> > m_storages;
+
    MUTEX m_vmXMLMutex;
    StringObjectMap<Cashe<char> > m_vmXMLs;
+   MUTEX m_networkXMLMutex;
+   StringObjectMap<Cashe<char> > m_networkXMLs;
+   MUTEX m_storageInfoMutex;
+   StringObjectMap<Cashe<virStoragePoolInfo> > m_storageInfo;
 
    static int authCb(virConnectCredentialPtr cred, unsigned int ncred, void *cbdata);
 
@@ -125,15 +162,24 @@ public:
    const virNodeInfo *getNodeInfoAndLock();
    void unlockNodeInfo();
    //Domains
-   const StringObjectMap<virDomain> *getDomainListAndLock();
+   const StringObjectMap<NXvirDomain> *getDomainListAndLock();
    void unlockDomainList();
-   const char *getDomainDefenitionAndLock(const TCHAR *name, virDomainPtr vm = NULL);
+   const char *getDomainDefenitionAndLock(const TCHAR *name, NXvirDomain *vm = NULL);
    void unlockDomainDefenition();
    //Iface
    const StringList *getIfaceListAndLock();
    void unlockIfaceList();
-   //void getStorages();
-   //void getDomains();
+   //Networks
+   const StringObjectMap<NXvirNetwork> *getNetworkListAndLock();
+   void unlockNetworkList();
+   const char *getNetworkDefenitionAndLock(const TCHAR *name, NXvirNetwork *network = NULL);
+   void unlockNetworkDefenition();
+   //Storage
+   const StringObjectMap<NXvirStoragePool> *getStorageListAndLock();
+   void unlockStorageList();
+   const virStoragePoolInfo *getStorageInformationAndLock(const TCHAR *name, NXvirStoragePool *storage = NULL);
+   void unlockStorageInfo();
+
 
    UINT32 getMaxVCpuCount();
    UINT64 getHostFreeMemory();
@@ -142,6 +188,39 @@ public:
    UINT64 getLibraryVersion();
 
    const TCHAR *getName() { return m_name; }
+   /***
+   Functions that can be added:
+   virDomainScreenshot - get screenshot form VM
+
+   Under question:
+   virDomainShutdown
+   virDomainSuspend
+
+
+   Check whay not working:
+   virInterfaceLookupByName, when fixed use virInterfaceIsActive, virInterfaceGetXMLDesc to find more information
+
+
+   Storage information:
+   virConnectNumOfStoragePools
+   virConnectNumOfDefinedStoragePools
+   virConnectListStoragePools
+   virConnectListDefinedStoragePools
+   virStoragePoolGetInfo - more info
+   virStoragePoolGetXMLDesc - more info
+   virStoragePoolLookupByName - get pointer
+   Valume:
+   virStoragePoolListVolumes - volume information
+   virStoragePoolNumOfVolumes - num of volumes
+   virStorageVolGetInfo
+   virStorageVolGetPath
+   virStorageVolGetXMLDesc
+   virStorageVolLookupByName
+
+   Add callbacks that will generate nxevents on call(there are network and domain callbacks at least)
+
+   !!!!! Add free functions for object(vm, iface...) like: virStoragePoolFree
+   ****/
 };
 
 /**