Migrating Matahari to Python...
by Darryl L. Pierce
Therw was some discussion today about converting the Matahari codebase
over to Python from C++. Since Matahari is fairly young at this point
and not feature rich, it would be a good time to change languages if we
were to do so.
However, in discussing things with Ian, I think that there's not really
that much of an advantage to going from C++ to Python.
I know some are concerned that, with C++, there's the chance that the
code could become hard to maintain.
And proffered as an advantage of using Python is the speed of
development. Though this is debatable.
A pro in favor of staying with the C++ code is that the QMF framework is
itself being developed primarily in C++ and the Python bindings are a
port based on that C++ code. Also speed of execution and reduced
dependencies in using C++ over Python.
What are everybody's thoughts on this topic? Is there an advantage to be
gained in switching to Python or should we stay with the C++ codebase?
The Python code for QMF is not yet available, but is scheduled to come
out with F13/RHEL6.
--
Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc.
Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/
13 years, 12 months
Patch supercedes previous patch...
by Darryl L. Pierce
In looking at the code I realized that the last of the HAL depenencies were
removed with this patch. So, I'm pushing an updated patch that contains
none of the HAL code in it.
13 years, 12 months
[PATCH matahari] Created the NetworkDevice agent.
by Darryl L. Pierce
Created a new class to represent network interface devices, named
NetworkDeviceAgent.
Signed-off-by: Darryl L. Pierce <dpierce(a)redhat.com>
---
src/Makefile.am | 9 +-
src/host.cpp | 26 +++--
src/host.h | 4 +-
src/linux_platform.cpp | 70 +++++++++++
src/linux_platform.h | 4 +
src/networkdevice.cpp | 49 ++++++++
src/networkdevice.h | 52 +++++++++
src/nic.cpp | 297 ------------------------------------------------
src/nic.h | 95 ---------------
src/platform.h | 5 +
src/processors.h | 5 +
src/schema.xml | 22 +---
12 files changed, 214 insertions(+), 424 deletions(-)
create mode 100644 src/networkdevice.cpp
create mode 100644 src/networkdevice.h
delete mode 100644 src/nic.cpp
delete mode 100644 src/nic.h
diff --git a/src/Makefile.am b/src/Makefile.am
index e4f394d..92ccec7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,10 +5,9 @@ sbin_PROGRAMS = matahari
first = qmf/com/redhat/matahari/Host.cpp
generated_file_list = \
- qmf/com/redhat/matahari/ArgsNICIdentify_nic.h \
qmf/com/redhat/matahari/Host.h \
- qmf/com/redhat/matahari/NIC.cpp \
- qmf/com/redhat/matahari/NIC.h \
+ qmf/com/redhat/matahari/NetworkDevice.cpp \
+ qmf/com/redhat/matahari/NetworkDevice.h \
qmf/com/redhat/matahari/Package.cpp \
qmf/com/redhat/matahari/Package.h \
qmf/com/redhat/matahari/Processors.cpp \
@@ -24,8 +23,8 @@ matahari_SOURCES = \
linux_platform.cpp \
linux_platform.h \
main.cpp \
- nic.cpp \
- nic.h \
+ networkdevice.cpp \
+ networkdevice.h \
platform.cpp \
platform.h \
processors.cpp \
diff --git a/src/host.cpp b/src/host.cpp
index 11c5a8f..34d4550 100644
--- a/src/host.cpp
+++ b/src/host.cpp
@@ -25,6 +25,7 @@
#include <sys/utsname.h>
#include "host.h"
+#include "platform.h"
#include "qmf/com/redhat/matahari/Host.h"
using namespace qpid::management;
@@ -41,6 +42,14 @@ HostAgent::setup(ManagementAgent* agent)
// discover the aspects of the host
processors.setup(agent, this);
+ networkdevices = Platform::instance()->get_network_devices();
+
+ for(vector<NetworkDeviceAgent>::iterator iter = networkdevices.begin();
+ iter != networkdevices.end();
+ iter++)
+ {
+ iter->setup(agent, this);
+ }
struct utsname details;
string uuid = "Unknown";
@@ -94,20 +103,17 @@ HostAgent::setup(ManagementAgent* agent)
management_object->set_arch(architecture);
management_object->set_memory(memory);
management_object->set_beeping(beeping);
-
- NICWrapper::fillNICInfo(this->nics, agent);
-
- // setup the nic objects
- for(vector<NICWrapper*>::iterator iter = nics.begin();
- iter != nics.end();
- iter++)
- {
- (*iter)->setupQMFObject(agent, this);
- }
}
void
HostAgent::update(void)
{
processors.update();
+
+ for(vector<NetworkDeviceAgent>::iterator iter = networkdevices.begin();
+ iter != networkdevices.end();
+ iter++)
+ {
+ iter->update();
+ }
}
diff --git a/src/host.h b/src/host.h
index ba5a1ed..d2da776 100644
--- a/src/host.h
+++ b/src/host.h
@@ -26,7 +26,7 @@
#include "qmf/com/redhat/matahari/Host.h"
-#include "nic.h"
+#include "networkdevice.h"
#include "processors.h"
using namespace qpid::management;
@@ -39,7 +39,7 @@ class HostAgent : public Manageable
private:
qmf::com::redhat::matahari::Host* management_object;
ProcessorsAgent processors;
- vector<NICWrapper*> nics;
+ vector<NetworkDeviceAgent> networkdevices;
public:
HostAgent() {}
diff --git a/src/linux_platform.cpp b/src/linux_platform.cpp
index 26418f5..fbcfdb9 100644
--- a/src/linux_platform.cpp
+++ b/src/linux_platform.cpp
@@ -18,9 +18,14 @@
*/
#include <fstream>
+#include <iomanip>
#include <iostream>
+#include <dirent.h>
+#include <net/if.h>
#include <pcre.h>
#include <stdexcept>
+#include <string.h>
+#include <sys/ioctl.h>
// TODO remove this wrapper once rhbz#583747 is fixed
extern "C" {
@@ -115,3 +120,68 @@ LinuxPlatform::get_load_average() const
return load_average;
}
+
+vector<NetworkDeviceAgent>
+LinuxPlatform::get_network_devices() const
+{
+ vector<NetworkDeviceAgent> result;
+
+ DIR* entries = opendir("/sys/class/net");
+
+ if(entries)
+ {
+ struct udev* udev = udev_new();
+ struct dirent* entry;
+
+ while(entry = (readdir(entries)))
+ {
+ string ifname = string(entry->d_name);
+ if(ifname != "." && ifname != "..")
+ {
+ string fullpath = "/sys/class/net/" + ifname;
+ struct udev_device* device = udev_device_new_from_syspath(udev,
+ fullpath.c_str());
+
+ if(udev_device_get_property_value(device, "ID_BUS"))
+ {
+ int sock = socket(AF_INET, SOCK_DGRAM, 0);
+ struct ifreq ifr;
+ string vendor = string(udev_device_get_property_value(device, "ID_VENDOR_FROM_DATABASE"));
+ string model = string(udev_device_get_property_value(device, "ID_MODEL_FROM_DATABASE"));
+
+ if(sock >= 0)
+ {
+ ifr.ifr_addr.sa_family = AF_INET;
+ strncpy(ifr.ifr_name, ifname.c_str(), IFNAMSIZ - 1);
+
+ if(!ioctl(sock, SIOCGIFHWADDR, &ifr))
+ {
+ char macaddr[256];
+
+ sprintf(macaddr,
+ "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
+ (unsigned char )ifr.ifr_hwaddr.sa_data[0],
+ (unsigned char )ifr.ifr_hwaddr.sa_data[1],
+ (unsigned char )ifr.ifr_hwaddr.sa_data[2],
+ (unsigned char )ifr.ifr_hwaddr.sa_data[3],
+ (unsigned char )ifr.ifr_hwaddr.sa_data[4],
+ (unsigned char )ifr.ifr_hwaddr.sa_data[5]);
+
+ result.push_back(NetworkDeviceAgent(ifname,
+ vendor,
+ model,
+ string(macaddr)));
+ }
+ }
+
+ udev_device_unref(device);
+ }
+ }
+ }
+
+ udev_unref(udev);
+ closedir(entries);
+ }
+
+ return result;
+}
diff --git a/src/linux_platform.h b/src/linux_platform.h
index 13116df..095bc08 100644
--- a/src/linux_platform.h
+++ b/src/linux_platform.h
@@ -21,7 +21,10 @@
*/
#include <string>
+#include <vector>
+
#include "platform.h"
+#include "networkdevice.h"
class LinuxPlatform : public Platform
{
@@ -30,6 +33,7 @@ class LinuxPlatform : public Platform
virtual ~LinuxPlatform() {}
virtual double get_load_average() const;
+ virtual vector<NetworkDeviceAgent> get_network_devices() const;
};
#endif
diff --git a/src/networkdevice.cpp b/src/networkdevice.cpp
new file mode 100644
index 0000000..5e30e33
--- /dev/null
+++ b/src/networkdevice.cpp
@@ -0,0 +1,49 @@
+/* networkingdevice.cpp - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include <qpid/agent/ManagementAgent.h>
+#include <qpid/management/Manageable.h>
+
+#include "networkdevice.h"
+
+namespace _qmf = qmf::com::redhat::matahari;
+
+NetworkDeviceAgent::NetworkDeviceAgent(string ifname, string vendor, string model, string macaddr)
+ :ifname(ifname)
+ ,vendor(vendor)
+ ,model(model)
+ ,macaddr(macaddr)
+{}
+
+void
+NetworkDeviceAgent::setup(ManagementAgent* agent, Manageable* parent)
+{
+ management_object = new _qmf::NetworkDevice(agent, this, parent);
+ agent->addObject(management_object);
+
+ management_object->set_interface(ifname);
+ management_object->set_vendor(vendor);
+ management_object->set_model(model);
+ management_object->set_mac_address(macaddr);
+}
+
+void
+NetworkDeviceAgent::update() const
+{
+}
diff --git a/src/networkdevice.h b/src/networkdevice.h
new file mode 100644
index 0000000..3884b22
--- /dev/null
+++ b/src/networkdevice.h
@@ -0,0 +1,52 @@
+#ifndef __NETWORKDEVICE_H
+#define __NETWORKDEVICE_H
+
+/* networkdevice.h - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include <qpid/management/Manageable.h>
+
+#include "qmf/com/redhat/matahari/NetworkDevice.h"
+
+using namespace qpid::management;
+using namespace std;
+
+class NetworkDeviceAgent : public Manageable
+{
+ private:
+ qmf::com::redhat::matahari::NetworkDevice* management_object;
+
+ string ifname;
+ string vendor;
+ string model;
+ string macaddr;
+
+ public:
+ NetworkDeviceAgent(string ifname, string vendor, string model, string macaddr);
+ virtual ~NetworkDeviceAgent() {}
+
+ string get_mac_address() const { return macaddr; }
+
+ ManagementObject* GetManagementObject(void) const { return management_object; }
+
+ void setup(ManagementAgent* agent, Manageable* parent);
+ void update() const;
+};
+
+#endif
diff --git a/src/nic.cpp b/src/nic.cpp
deleted file mode 100644
index 040ca67..0000000
--- a/src/nic.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-/* nic.cpp - Copyright (C) 2009 Red Hat, Inc.
- * Written by Arjun Roy <arroy(a)redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA. A copy of the GNU General Public License is
- * also available at http://www.gnu.org/copyleft/gpl.html.
- */
-
-#include <iostream>
-#include <string>
-#include <sstream>
-#include <vector>
-#include <stdexcept>
-
-#include <hal/libhal.h>
-#include <cstdio>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <linux/types.h>
-#include <linux/ethtool.h>
-#include <linux/sockios.h>
-#include <linux/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-
-#include "nic.h"
-#include "qmf/com/redhat/matahari/NIC.h"
-#include "qmf/com/redhat/matahari/ArgsNICIdentify_nic.h"
-
-using namespace qpid::management;
-using namespace std;
-
-using qpid::management::Manageable;
-
-namespace _qmf = qmf::com::redhat::matahari;
-
-extern DBusConnection *dbus_connection;
-extern DBusError dbus_error;
-
-ostream &operator<<(ostream& output, const NICWrapper& nic) {
- output << "NIC" << endl;
- output << "Interface Name: " << nic.interfaceName << endl;
- output << "MAC Address: " << nic.macaddr << endl;
- output << "IP Address: " << nic.ipaddr << endl;
- output << "Netmask: " << nic.netmask << endl;
- output << "Broadcast: " << nic.broadcast << endl;
- output << "Bandwidth: " << nic.bandwidth << endl;
- return output;
-}
-
-void NICWrapper::setupQMFObject(ManagementAgent *agent, Manageable *parent)
-{
- mgmt_object = new _qmf::NIC(agent, this, parent);
- agent->addObject(mgmt_object);
- syncQMFObject();
-}
-
-void NICWrapper::cleanupQMFObject(void)
-{
- mgmt_object->resourceDestroy();
-}
-
-void NICWrapper::syncQMFObject(void)
-{
- mgmt_object->set_interface(interfaceName);
- mgmt_object->set_macaddr(macaddr);
- mgmt_object->set_ipaddr(ipaddr);
- mgmt_object->set_netmask(netmask);
- mgmt_object->set_broadcast(broadcast);
- mgmt_object->set_bandwidth(bandwidth);
-}
-
-NICWrapper *NICWrapper::getNIC(ManagementAgent *agent,
- LibHalContext *hal_ctx,
- char *nic_handle)
-{
- // Used to get the data
- char *macaddr_c;
- char *interface_c;
- int sock, ret;
- struct ifreq ifr;
- struct ethtool_cmd ecmd;
-
- // The data that we care about
- NICWrapper *nic = NULL;
- string macaddr;
- string interface;
- string ipaddr;
- string netmask;
- string broadcast;
- int bandwidth;
-
- // Grab the MAC Address from libhal
- macaddr_c = libhal_device_get_property_string(hal_ctx,
- nic_handle,
- "net.address",
- &dbus_error);
- // Or throw an exception if we could not find it. No cleanup yet.
- if (!macaddr_c)
- throw runtime_error("Could not get mac address for NIC");
-
- // Grab the interface name from libhal or return cleanup and fail
- interface_c = libhal_device_get_property_string(hal_ctx,
- nic_handle,
- "net.interface",
- &dbus_error);
- // Or cleanup the macaddr and return NULL.
- if (!interface_c) {
- libhal_free_string(macaddr_c);
- throw runtime_error("Could not get interface name for nic");
- }
-
- // Open socket for running ioctls for getting rest of data
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock >= 0) {
- // Get the IP Address
- ifr.ifr_addr.sa_family = AF_INET;
- strncpy(ifr.ifr_name, interface_c, IFNAMSIZ - 1);
- cout << interface_c << endl;
-
- ret = ioctl(sock, SIOCGIFADDR, &ifr);
- if(ret == 0) {
- struct sockaddr_in *addr = (struct sockaddr_in *) &ifr.ifr_addr;
- cout << "ip_address = " << inet_ntoa(addr->sin_addr) << endl;
- ipaddr = inet_ntoa(addr->sin_addr);
- }
- else {
- perror("SIOCGIFADDR");
- ipaddr = "unable to determine";
- }
- // Get the netmask
- ret = ioctl(sock, SIOCGIFNETMASK, &ifr);
- if(ret == 0 && strcmp("255.255.255.255",
- inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr))) {
-
- struct sockaddr_in *addr = (struct sockaddr_in *) &ifr.ifr_addr;
- cout << "netmask = " << inet_ntoa(addr->sin_addr) << endl;
- netmask = inet_ntoa(addr->sin_addr);
- }
- else {
- perror("SIOCGIFNETMASK");
- netmask = "unable to determine";
- }
- // Get the broadcast address
- ret = ioctl(sock, SIOCGIFBRDADDR, &ifr);
- if(ret == 0) {
- struct sockaddr_in *addr = (struct sockaddr_in *) &ifr.ifr_addr;
- cout << "broadcast = " << inet_ntoa(addr->sin_addr);
- broadcast = inet_ntoa(addr->sin_addr);
- }
- else {
- perror("SIOCGIFBRDADDR");
- broadcast = "unable to determine";
- }
- // Get the bandwidth for this NIC
- ecmd.cmd = ETHTOOL_GSET;
- ifr.ifr_data = (caddr_t)&ecmd;
- bandwidth = 10;
-
- // TODO: Error checking on this ioctl. For now, assume success
- ret = ioctl(sock, SIOCETHTOOL, &ifr);
- if (1) {
-
- if (ecmd.supported & SUPPORTED_10000baseT_Full) {
- bandwidth = 10000;
- } else if (ecmd.supported & SUPPORTED_2500baseX_Full) {
- bandwidth = 2500;
- } else if (ecmd.supported & (SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full)) {
- bandwidth = 1000;
- } else if (ecmd.supported & (SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full)) {
- bandwidth = 100;
- } else if (ecmd.supported & (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full)) {
- bandwidth = 10;
- }
- }
- else {
- cout << "Unable to determine link speed, defaulting to 10" << endl;
- }
- // And we're done here
- close(sock);
- }
- else {
- /* Couldn't open socket, so cleanup and fail */
- libhal_free_string(interface_c);
- libhal_free_string(macaddr_c);
- throw runtime_error("Unable to open socket.");
- }
- // We have all the data. Create the NICWrapper instance
- macaddr = macaddr_c;
- interface = interface_c;
- nic = new NICWrapper(interface,
- macaddr,
- ipaddr,
- netmask,
- broadcast,
- bandwidth);
-
- // Free resources and return
- libhal_free_string(interface_c);
- libhal_free_string(macaddr_c);
- return nic;
-}
-
-/**
- * void fillNICInfo(vector <NICWrapper*> &nics,
- * ManagementAgent *agent,
- * LibHalContext *hal_ctx)
- *
- * Takes in a vector of NICWrapper object pointers and populates it with
- * NICs found in the system found by querying dbus and making other system
- * calls.
- */
-void NICWrapper::fillNICInfo(vector <NICWrapper*> &nics,
- ManagementAgent *agent)
-{
- LibHalContext* hal_ctx = get_hal_ctx();
- char **net_devices;
- int num_results, i;
- net_devices = libhal_find_device_by_capability(hal_ctx,
- "net.80203",
- &num_results,
- &dbus_error);
- if (!net_devices)
- throw runtime_error("Error: Couldn't get NIC devices through libhal.");
-
- cout << "Found " << num_results << " NICs" << endl;
- for (i = 0; i < num_results; i++) {
- NICWrapper *nic;
- char *nic_handle = net_devices[i];
- // If we couldn't read the info for a nic, free the list of devices
- // and throw an error. Any devices added already will be cleaned up
- // by the caller.
- try {
- nic = getNIC(agent, hal_ctx, nic_handle);
- }
- catch (...) {
- libhal_free_string_array(net_devices);
- throw;
- }
- // Add the NIC to our list
- nics.push_back(nic);
- }
- // And we're all done.
- libhal_free_string_array(net_devices);
-}
-
-int NICWrapper::identifyNIC(int seconds)
-{
- struct ethtool_value edata;
- struct ifreq ifr;
- int sock, ret;
-
- edata.cmd = ETHTOOL_PHYS_ID;
- edata.data = seconds; // seconds of blink time
-
- strncpy(ifr.ifr_name, interfaceName.c_str(), IFNAMSIZ - 1);
- ifr.ifr_data = (caddr_t)&edata;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- ret = ioctl(sock, SIOCETHTOOL, &ifr);
- close(sock);
-
- if (ret != 0)
- ret = errno;
-
- return ret;
-}
-
-Manageable::status_t
-NICWrapper::ManagementMethod(uint32_t methodId, Args& args, string& text)
-{
- switch (methodId) {
- case _qmf::NIC::METHOD_IDENTIFY_NIC:
- _qmf::ArgsNICIdentify_nic& ioArgs = (_qmf::ArgsNICIdentify_nic&) args;
- int seconds = ioArgs.i_seconds;
- ioArgs.o_ret = identifyNIC(seconds);
- return STATUS_OK;
- }
-
- return STATUS_NOT_IMPLEMENTED;
-}
diff --git a/src/nic.h b/src/nic.h
deleted file mode 100644
index e0e5874..0000000
--- a/src/nic.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* nic.h - Copyright (C) 2009 Red Hat, Inc.
- * Written by Arjun Roy <arroy(a)redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA. A copy of the GNU General Public License is
- * also available at http://www.gnu.org/copyleft/gpl.html.
- */
-
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-
-#include "qmf/com/redhat/matahari/NIC.h"
-#include "hal.h"
-
-using namespace qpid::management;
-using namespace std;
-
-using qpid::management::Manageable;
-
-class NICWrapper : public Manageable
-{
- friend ostream& operator <<(ostream &output, const NICWrapper& nic);
- friend class HostWrapper;
-
- // NIC Parameters
- string interfaceName;
- string macaddr;
- string ipaddr;
- string netmask;
- string broadcast;
- int bandwidth;
-
- // QMF related fields
- ManagementAgent *agent;
- qmf::com::redhat::matahari::NIC *mgmt_object;
-
- // Methods to put up / take down QMF Objects
- void cleanupQMFObject(void);
- void syncQMFObject(void);
-
- // Constructors and Destructor are private
- NICWrapper() {}
- NICWrapper(const NICWrapper&) {}
- ~NICWrapper() {}
-
- NICWrapper(const string &interfaceName__,
- const string &macaddr__,
- const string &ipaddr__,
- const string &netmask__,
- const string &broadcast__,
- int bandwidth__) {
- interfaceName = interfaceName__;
- macaddr = macaddr__;
- ipaddr = ipaddr__;
- netmask = netmask__;
- broadcast = broadcast__;
- bandwidth = bandwidth__;
- }
-
- static NICWrapper *getNIC(ManagementAgent *agent,
- LibHalContext *hal_ctx,
- char *nic_handle);
-
- int identifyNIC(int seconds);
-public:
-
- void setupQMFObject(ManagementAgent *agent, Manageable *parent);
- // Factory like method
- static void fillNICInfo(vector<NICWrapper*> &nics,
- ManagementAgent *agent);
-
- // QMF Methods
- ManagementObject *GetManagementObject(void) const { return mgmt_object; }
- status_t ManagementMethod(uint32_t methodId, Args& args, string& text);
-
- // Field Accessors
- const string &getInterfaceName(void) { return interfaceName; }
- const string &getMacaddr(void) { return macaddr; }
- const string &getIpaddr(void) { return ipaddr; }
- const string &getNetmask(void) { return netmask; }
- const string &getBroadcast(void) { return broadcast; }
- int getBandwidth(void) { return bandwidth; }
-};
diff --git a/src/platform.h b/src/platform.h
index 514ad20..54fbe37 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -21,6 +21,8 @@
*/
#include <string>
+#include <vector>
+#include "networkdevice.h"
using namespace std;
@@ -57,6 +59,9 @@ class Platform
// returns the load average for the platform
virtual double get_load_average() const = 0;
+
+ // returns the list of network devices for this platform
+ virtual vector<NetworkDeviceAgent> get_network_devices() const = 0;
};
#endif
diff --git a/src/processors.h b/src/processors.h
index 17a6a6a..e681453 100644
--- a/src/processors.h
+++ b/src/processors.h
@@ -1,3 +1,6 @@
+#ifndef __PROCESSORS_H
+#define __PROCESSORS_H
+
/* processor.h - Copyright (C) 2010 Red Hat, Inc.
* Written by Darryl L. Pierce <dpierce(a)redhat.com>
*
@@ -48,3 +51,5 @@ class ProcessorsAgent : public Manageable
// agent methods
void update_load_averages(void) const;
};
+
+#endif
diff --git a/src/schema.xml b/src/schema.xml
index 890e4ed..206e39b 100644
--- a/src/schema.xml
+++ b/src/schema.xml
@@ -23,21 +23,13 @@
<statistic name="load_average" type="float" desc="The processing load average." />
</class>
- <class name="NIC">
-
- <property name="host" type="objId" access="RO" desc="Host that this NIC belongs to" index="y" references="Host" parentRef="y"/>
- <property name="macaddr" type="sstr" access="RO" desc="MAC Address" index="y"/>
- <property name="interface" type="sstr" access="RO" desc="Interface name"/>
- <property name="ipaddr" type="sstr" access="RO" desc="IP Address"/>
- <property name="netmask" type="sstr" access="RO" desc="Netmask"/>
- <property name="broadcast" type="sstr" access="RO" desc="Broadcast"/>
- <property name="bandwidth" type="int32" access="RO" desc="Bandwidth"/>
-
- <method name="identify_nic" desc="Physically Identify NIC">
- <arg name="seconds" dir="I" type="int32" />
- <arg name="ret" dir="O" type="int32" />
- </method>
-
+ <!-- represents a physical network device -->
+ <class name="NetworkDevice">
+ <property name="host" type="objId" access="RC" desc="The host machine." index="y" references="Host" parentRef="y" />
+ <property name="mac_address" type="sstr" access="RO" desc="The device's MAC address" index="y" />
+ <property name="vendor" type="sstr" access="RO" desc="The device vendor." />
+ <property name="model" type="sstr" access="RO" desc="The device model." />
+ <property name="interface" type="sstr" access="RO" desc="The interface name for the device." />
</class>
</schema>
--
1.6.6.1
14 years
[PATCH matahari] Created a new platform-abstraction layer named Platform.
by Darryl L. Pierce
It provides an initial implementation, LinuxPlatform, which is by
default included in the build. Later code will refactor the build
process to include the appropriate implementation depending on the
target platform.
Signed-off-by: Darryl L. Pierce <dpierce(a)redhat.com>
---
src/Makefile.am | 4 ++
src/linux_platform.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++++++++
src/linux_platform.h | 35 ++++++++++++++
src/platform.cpp | 35 ++++++++++++++
src/platform.h | 62 +++++++++++++++++++++++++
src/processors.cpp | 93 ++------------------------------------
6 files changed, 258 insertions(+), 88 deletions(-)
create mode 100644 src/linux_platform.cpp
create mode 100644 src/linux_platform.h
create mode 100644 src/platform.cpp
create mode 100644 src/platform.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 7606e20..e4f394d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,9 +21,13 @@ matahari_SOURCES = \
hal.h \
host.cpp \
host.h \
+ linux_platform.cpp \
+ linux_platform.h \
main.cpp \
nic.cpp \
nic.h \
+ platform.cpp \
+ platform.h \
processors.cpp \
processors.h
diff --git a/src/linux_platform.cpp b/src/linux_platform.cpp
new file mode 100644
index 0000000..26418f5
--- /dev/null
+++ b/src/linux_platform.cpp
@@ -0,0 +1,117 @@
+/* linux_platform.cpp - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include <fstream>
+#include <iostream>
+#include <pcre.h>
+#include <stdexcept>
+
+// TODO remove this wrapper once rhbz#583747 is fixed
+extern "C" {
+#include <libudev.h>
+}
+
+#include "linux_platform.h"
+
+LinuxPlatform::LinuxPlatform()
+{
+ int core_count = 0;
+ string model = "unknown";
+
+ struct udev* udev = udev_new();
+ struct udev_enumerate* enumerator = udev_enumerate_new(udev);
+
+ udev_enumerate_add_match_property(enumerator, "DRIVER", "processor");
+ if(!udev_enumerate_scan_devices(enumerator))
+ {
+ struct udev_list_entry* entries = udev_enumerate_get_list_entry(enumerator);
+ struct udev_list_entry* entry;
+
+ udev_list_entry_foreach(entry, entries)
+ {
+ core_count++;
+ }
+ set_number_of_cores(core_count);
+ }
+
+ udev_enumerate_unref(enumerator);
+ udev_unref(udev);
+
+ ifstream input("/proc/cpuinfo");
+ if(input.is_open())
+ {
+ string regexstr = "(.*\\S)\\s*:\\s*(\\S.*)";
+ int expected = 3;
+ int found[expected * 3];
+ const char* pcre_error;
+ int pcre_error_offset;
+ pcre* regex;
+ bool done = false;
+ bool started = false;
+
+ regex = pcre_compile(regexstr.c_str(), 0, &pcre_error, &pcre_error_offset, NULL);
+ if(!regex) { throw runtime_error("Unable to compile regular expression."); }
+
+ while(!input.eof() && !done)
+ {
+ string line;
+
+ getline(input, line);
+ int match = pcre_exec(regex, NULL, line.c_str(), line.length(),
+ 0, PCRE_NOTEMPTY,found, expected * 3);
+
+ if(match == expected)
+ {
+ string name = line.substr(found[2], found[3] - found[2]);
+ string value = line.substr(found[4], found[5] - found[4]);
+
+ // if we're at a second processor and we've already started, then we're done
+ if (name == "processor")
+ {
+ if (started)
+ {
+ done = true;
+ }
+ else
+ {
+ started = true;
+ }
+ }
+ else
+ {
+ if(name == "model name") set_processor_model(value);
+ }
+ }
+ }
+ input.close();
+ }
+}
+
+double
+LinuxPlatform::get_load_average() const
+{
+ double load_average;
+ ifstream input;
+
+ input.open("/proc/loadavg", ios::in);
+ input >> load_average;
+ input.close();
+
+ return load_average;
+}
diff --git a/src/linux_platform.h b/src/linux_platform.h
new file mode 100644
index 0000000..13116df
--- /dev/null
+++ b/src/linux_platform.h
@@ -0,0 +1,35 @@
+#ifndef __LINUX_PLATFORM_H
+#define __LINUX_PLATFORM_H
+
+/* linux_platform.h - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include <string>
+#include "platform.h"
+
+class LinuxPlatform : public Platform
+{
+ public:
+ LinuxPlatform();
+ virtual ~LinuxPlatform() {}
+
+ virtual double get_load_average() const;
+};
+
+#endif
diff --git a/src/platform.cpp b/src/platform.cpp
new file mode 100644
index 0000000..69f528b
--- /dev/null
+++ b/src/platform.cpp
@@ -0,0 +1,35 @@
+/* platform.cpp - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "platform.h"
+#include "linux_platform.h"
+
+Platform* Platform::_instance = 0;
+
+Platform*
+Platform::instance()
+{
+ // TODO this is where we decide which implementation to use
+ if(!_instance)
+ {
+ _instance = new LinuxPlatform;
+ }
+
+ return _instance;
+}
diff --git a/src/platform.h b/src/platform.h
new file mode 100644
index 0000000..514ad20
--- /dev/null
+++ b/src/platform.h
@@ -0,0 +1,62 @@
+#ifndef __PLATFORM_H
+#define __PLATFORM_H
+
+/* platform.h - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include <string>
+
+using namespace std;
+
+/*
+ * Platform defines a type that provides platform-specific details.
+ *
+ * Implementations provide the specific details needed by the
+ * various agents at runtime.
+ */
+class Platform
+{
+ private:
+ static Platform* _instance;
+
+ string processor_model;
+ unsigned int number_of_cores;
+
+ protected:
+ Platform() {}
+ virtual~ Platform() {}
+
+ void set_processor_model(const string model) { processor_model = model; }
+ void set_number_of_cores(const int number) { number_of_cores = number; }
+
+ public:
+ // the singleton instance
+ static Platform* instance();
+
+ // returns text describing the processor model.
+ string get_processor_model() const { return processor_model; }
+
+ // returns the number of cores in the processor.
+ int get_number_of_cores() const { return number_of_cores; }
+
+ // returns the load average for the platform
+ virtual double get_load_average() const = 0;
+};
+
+#endif
diff --git a/src/processors.cpp b/src/processors.cpp
index cbc2979..13c492d 100644
--- a/src/processors.cpp
+++ b/src/processors.cpp
@@ -18,14 +18,7 @@
*/
#include "processors.h"
-#include <fstream>
-#include <iostream>
-#include <pcre.h>
-
-// TODO remove this wrapper once rhbz#583747 is fixed
-extern "C" {
-#include <libudev.h>
-}
+#include "platform.h"
using namespace std;
namespace _qmf = qmf::com::redhat::matahari;
@@ -37,79 +30,10 @@ ProcessorsAgent::setup(ManagementAgent* agent, Manageable* parent)
management_object = new _qmf::Processors(agent, this, parent);
agent->addObject(management_object);
- int core_count = 0;
- string model = "unknown";
-
- struct udev* udev = udev_new();
- struct udev_enumerate* enumerator = udev_enumerate_new(udev);
-
- udev_enumerate_add_match_property(enumerator, "DRIVER", "processor");
- if(!udev_enumerate_scan_devices(enumerator))
- {
- struct udev_list_entry* entries = udev_enumerate_get_list_entry(enumerator);
- struct udev_list_entry* entry;
-
- udev_list_entry_foreach(entry, entries)
- {
- core_count++;
- }
- }
-
- udev_enumerate_unref(enumerator);
- udev_unref(udev);
-
- ifstream input("/proc/cpuinfo");
- if(input.is_open())
- {
- string regexstr = "(.*\\S)\\s*:\\s*(\\S.*)";
- int expected = 3;
- int found[expected * 3];
- const char* pcre_error;
- int pcre_error_offset;
- pcre* regex;
- bool done = false;
- bool started = false;
+ Platform* platform = Platform::instance();
- regex = pcre_compile(regexstr.c_str(), 0, &pcre_error, &pcre_error_offset, NULL);
- if(!regex) { throw runtime_error("Unable to compile regular expression."); }
-
- while(!input.eof() && !done)
- {
- string line;
-
- getline(input, line);
- int match = pcre_exec(regex, NULL, line.c_str(), line.length(),
- 0, PCRE_NOTEMPTY,found, expected * 3);
-
- if(match == expected)
- {
- string name = line.substr(found[2], found[3] - found[2]);
- string value = line.substr(found[4], found[5] - found[4]);
-
- // if we're at a second processor and we've already started, then we're done
- if (name == "processor")
- {
- if (started)
- {
- done = true;
- }
- else
- {
- started = true;
- }
- }
- else
- {
- if(name == "model name") model = value;
- }
- }
- }
- input.close();
- }
-
- // populate the managed object's values
- management_object->set_model(model);
- management_object->set_cores(core_count);
+ management_object->set_model(platform->get_processor_model());
+ management_object->set_cores(platform->get_number_of_cores());
}
void
@@ -121,12 +45,5 @@ ProcessorsAgent::update(void) const
void
ProcessorsAgent::update_load_averages(void) const
{
- double load_average;
- ifstream input;
-
- input.open("/proc/loadavg", ios::in);
- input >> load_average;
- input.close();
-
- management_object->set_load_average(load_average);
+ management_object->set_load_average(Platform::instance()->get_load_average());
}
--
1.6.6.1
14 years
[PATCH matahari] Removes HAL code from the HostAgent codebase.
by Darryl L. Pierce
Now all aspects of the host environment are details by other means. The
fully qualified hostname and architecture are taken from uname(). Memory
is taken from sysinfo(). The machine UUID is taken from DBus rather than
udev since udev reports hardware UUID which is not guaranteed to be
unique, while DBus is designed to be just that.
Refactored, for now, the NICWrapper class to get its own HAL context
rather than it being supplied by the HostAgent class. This way the
HostAgent is completely HAL free.
Signed-off-by: Darryl L. Pierce <dpierce(a)redhat.com>
---
src/host.cpp | 131 +++++++++++++++++++++++++++----------------------------
src/nic.cpp | 4 +-
src/nic.h | 3 +-
src/schema.xml | 2 +-
4 files changed, 68 insertions(+), 72 deletions(-)
diff --git a/src/host.cpp b/src/host.cpp
index 885068b..11c5a8f 100644
--- a/src/host.cpp
+++ b/src/host.cpp
@@ -17,16 +17,12 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
-#include <qpid/management/Manageable.h>
-
-#include <iostream>
#include <fstream>
-#include <stdexcept>
-
-#include <cstdlib>
-#include <unistd.h>
#include <libvirt/libvirt.h>
+#include <qpid/management/Manageable.h>
+#include <sys/sysinfo.h>
+#include <sys/utsname.h>
#include "host.h"
#include "qmf/com/redhat/matahari/Host.h"
@@ -46,67 +42,68 @@ HostAgent::setup(ManagementAgent* agent)
// discover the aspects of the host
processors.setup(agent, this);
- LibHalContext *hal_ctx;
- int ret;
-
- // Get our HAL Context or die trying
- hal_ctx = get_hal_ctx();
- if (!hal_ctx)
- throw runtime_error("Unable to get HAL Context Structure.");
-
- try {
- NICWrapper::fillNICInfo(this->nics, agent, hal_ctx);
-
- // Host UUID
- char *uuid_c = get_uuid(hal_ctx);
- string uuid(uuid_c);
- management_object->set_uuid(uuid);
-
- // Hostname
- char hostname_c[HOST_NAME_MAX];
- ret = gethostname(hostname_c, sizeof(hostname_c));
- if (ret != 0)
- throw runtime_error("Unable to get hostname");
- string hostname(hostname_c);
- management_object->set_hostname(hostname);
-
- // Hypervisor, arch, memory
- management_object->set_memory(0);
- management_object->set_hypervisor("unknown");
- management_object->set_arch("unknown");
-
- virConnectPtr connection;
- virNodeInfo info;
- connection = virConnectOpenReadOnly(NULL);
- if (connection) {
- const char *hv = virConnectGetType(connection);
- if (hv != NULL)
- management_object->set_hypervisor(hv);
- ret = virNodeGetInfo(connection, &info);
- if (ret == 0) {
- management_object->set_arch(info.model);
- management_object->set_memory(info.memory);
- }
+ struct utsname details;
+ string uuid = "Unknown";
+ string hostname = "Unknown";
+ string hypervisor = "Unknown";
+ string architecture = "None";
+ unsigned long memory = 0;
+ bool beeping = false;
+
+ ifstream input("/var/lib/dbus/machine-id");
+
+ if(input.is_open())
+ {
+ getline(input, uuid);
+ input.close();
+ }
+
+ if(!uname(&details))
+ {
+ hostname = string(details.nodename);
+ architecture = string(details.machine);
+ }
+ else
+ {
+ throw runtime_error("Unable to retrieve system details");
+ }
+
+ virConnectPtr lvconn = virConnectOpenReadOnly(NULL);
+
+ if(lvconn)
+ {
+ hypervisor = string(virConnectGetType(lvconn));
+ virConnectClose(lvconn);
+ }
+
+ struct sysinfo sysinf;
+ if(!sysinfo(&sysinf))
+ {
+ memory = sysinf.totalram / 1024L;
+ }
+ else
+ {
+ throw runtime_error("Unable to retrieve system memory details.");
+ }
+
+ cout << "memory: " << memory << endl;
+
+ management_object->set_uuid(uuid);
+ management_object->set_hostname(hostname);
+ management_object->set_hypervisor(hypervisor);
+ management_object->set_arch(architecture);
+ management_object->set_memory(memory);
+ management_object->set_beeping(beeping);
+
+ NICWrapper::fillNICInfo(this->nics, agent);
+
+ // setup the nic objects
+ for(vector<NICWrapper*>::iterator iter = nics.begin();
+ iter != nics.end();
+ iter++)
+ {
+ (*iter)->setupQMFObject(agent, this);
}
- virConnectClose(connection);
-
- management_object->set_beeping(false);
-
- // setup the nic objects
- for(vector<NICWrapper*>::iterator iter = nics.begin();
- iter != nics.end();
- iter++)
- {
- (*iter)->setupQMFObject(agent, this);
- }
- }
- catch (...) {
- put_hal_ctx(hal_ctx);
- throw;
- }
-
- // Close the Hal Context
- put_hal_ctx(hal_ctx);
}
void
diff --git a/src/nic.cpp b/src/nic.cpp
index 197f5c7..040ca67 100644
--- a/src/nic.cpp
+++ b/src/nic.cpp
@@ -227,9 +227,9 @@ NICWrapper *NICWrapper::getNIC(ManagementAgent *agent,
* calls.
*/
void NICWrapper::fillNICInfo(vector <NICWrapper*> &nics,
- ManagementAgent *agent,
- LibHalContext *hal_ctx)
+ ManagementAgent *agent)
{
+ LibHalContext* hal_ctx = get_hal_ctx();
char **net_devices;
int num_results, i;
net_devices = libhal_find_device_by_capability(hal_ctx,
diff --git a/src/nic.h b/src/nic.h
index c79ecf9..e0e5874 100644
--- a/src/nic.h
+++ b/src/nic.h
@@ -79,8 +79,7 @@ public:
void setupQMFObject(ManagementAgent *agent, Manageable *parent);
// Factory like method
static void fillNICInfo(vector<NICWrapper*> &nics,
- ManagementAgent *agent,
- LibHalContext *ctx);
+ ManagementAgent *agent);
// QMF Methods
ManagementObject *GetManagementObject(void) const { return mgmt_object; }
diff --git a/src/schema.xml b/src/schema.xml
index e6b54db..890e4ed 100644
--- a/src/schema.xml
+++ b/src/schema.xml
@@ -4,7 +4,7 @@
<property name="uuid" type="sstr" access="RO" desc="Host UUID" index="y"/>
<property name="hostname" type="sstr" access="RO" desc="Hostname"/>
- <property name="memory" type="int32" access="RO" desc="Amount of primary memory for host (kb)" unit="kb"/>
+ <property name="memory" type="int64" access="RO" desc="Amount of primary memory for host (kb)" unit="kb"/>
<property name="hypervisor" type="sstr" access="RO" desc="Hypervisor used by host"/>
<property name="arch" type="sstr" access="RO" desc="Architecture of host"/>
<property name="beeping" type="bool" access="RW" desc="speaker beep loop active? (used to identify host)"/>
--
1.6.6.1
14 years
[PATCH matahari] Removes all code for the previous CPUWrapper class.
by Darryl L. Pierce
This class has been replaced by the ProcessorsAgent.
Signed-off-by: Darryl L. Pierce <dpierce(a)redhat.com>
---
src/Makefile.am | 4 -
src/cpu.cpp | 216 -------------------------------------------------------
src/cpu.h | 111 ----------------------------
src/host.cpp | 24 ------
src/host.h | 3 -
src/schema.xml | 16 ----
6 files changed, 0 insertions(+), 374 deletions(-)
delete mode 100644 src/cpu.cpp
delete mode 100644 src/cpu.h
diff --git a/src/Makefile.am b/src/Makefile.am
index b4668b9..7606e20 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,8 +6,6 @@ first = qmf/com/redhat/matahari/Host.cpp
generated_file_list = \
qmf/com/redhat/matahari/ArgsNICIdentify_nic.h \
- qmf/com/redhat/matahari/CPU.cpp \
- qmf/com/redhat/matahari/CPU.h \
qmf/com/redhat/matahari/Host.h \
qmf/com/redhat/matahari/NIC.cpp \
qmf/com/redhat/matahari/NIC.h \
@@ -19,8 +17,6 @@ generated_file_list = \
nodist_matahari_SOURCES = $(generated_file_list) $(first)
matahari_SOURCES = \
- cpu.cpp \
- cpu.h \
hal.cpp \
hal.h \
host.cpp \
diff --git a/src/cpu.cpp b/src/cpu.cpp
deleted file mode 100644
index 453c571..0000000
--- a/src/cpu.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/* cpu.cpp - Copyright (C) 2009 Red Hat, Inc.
- * Written by Arjun Roy <arroy(a)redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA. A copy of the GNU General Public License is
- * also available at http://www.gnu.org/copyleft/gpl.html.
- */
-
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <string>
-#include <vector>
-#include <stdexcept>
-
-#include <pcre.h>
-
-#include "cpu.h"
-#include "qmf/com/redhat/matahari/CPU.h"
-
-using namespace std;
-namespace _qmf = qmf::com::redhat::matahari;
-
-template<typename targetType> targetType convert(const std::string& str)
-{
- istringstream i(str);
- targetType t;
- if (!(i >> t))
- throw invalid_argument("Conversion failure for " + str);
- return t;
-}
-
-ostream& operator<<(ostream& output, const CPUWrapper& cpu)
-{
- output << "Processor" << endl;
- output << "CPU #: " << cpu.cpunum << endl;
- output << "Core #: " << cpu.corenum << endl;
- output << "Num. Cores: " << cpu.numcores << endl;
- output << "Model: " << cpu.model << endl;
- output << "Family: " << cpu.family << endl;
- output << "CPU ID Level: " << cpu.cpuid_lvl << endl;
- output << "Speed (Mhz): " << cpu.speed << endl;
- output << "Cache (kB): " << cpu.cache << endl;
- output << "Vendor: " << cpu.vendor << endl;
- output << "Flags: " << cpu.flags << endl;
- return output;
-}
-
-void CPUWrapper::setupQMFObject(ManagementAgent *agent, Manageable *parent)
-{
- mgmt_object = new _qmf::CPU(agent, this, parent);
- agent->addObject(mgmt_object);
- syncQMFObject();
-}
-
-void CPUWrapper::cleanupQMFObject(void)
-{
- mgmt_object->resourceDestroy();
-}
-
-void CPUWrapper::syncQMFObject(void)
-{
- mgmt_object->set_cpunum(cpunum);
- mgmt_object->set_corenum(corenum);
- mgmt_object->set_numcores(numcores);
- mgmt_object->set_model(model);
- mgmt_object->set_family(family);
- mgmt_object->set_cpuid_lvl(cpuid_lvl);
- mgmt_object->set_speed(speed);
- mgmt_object->set_cache(cache);
- mgmt_object->set_vendor(vendor);
- mgmt_object->set_flags(flags);
-}
-
-/**
- * void fillCPUInfo(vector <CPUWrapper*> &cpus, ManagementAgent *agent)
- *
- * Takes in a vector of CPUWrapper object pointers and populates it with
- * CPUs found by querying /proc/cpuinfo. NOTE: This method is very sensitive
- * to the output format of /proc/cpuinfo.
- *
- * Throws a runtime error if file io is unsuccessful.
- */
-void CPUWrapper::fillCPUInfo(vector<CPUWrapper*> &cpus, ManagementAgent *agent)
-{
- string line;
- string regexstr = "(.*\\S)\\s*:\\s*(\\S.*)";
- int desiredmatches = 3; // Match string and two captured substrings
- int matchArraySize = desiredmatches * 3;
- int results[matchArraySize]; // pcre requires this much
- const char *pcre_err;
- int pcre_err_offset;
- pcre *regex;
-
- regex = pcre_compile(regexstr.c_str(), // input
- 0, // no options
- &pcre_err, // where to place static error str
- &pcre_err_offset, // index in regex string of error
- NULL // use the default charset
- );
- if (!regex) {
- ostringstream err;
- err << "Error: Bad regex: " << regexstr << endl;
- err << "Error was: " << pcre_err << " at " << pcre_err_offset << endl;
- throw runtime_error(err.str());
- }
-
- ifstream cpuinfo("/proc/cpuinfo", ios::in);
- if (!cpuinfo.is_open() || cpuinfo.fail())
- throw runtime_error("Unable to open /proc/cpuinfo");
-
- // Each line is a key:value pair. New processor
- // delimiter is the "processor" key.
- while (!cpuinfo.eof()) {
- getline(cpuinfo, line);
- int match = pcre_exec(regex, // Regex
- NULL, // No extra optimizations
- line.c_str(), // Input
- line.length(), // Input length
- 0, // Start offset
- PCRE_NOTEMPTY, // options bitvector
- results, // Results vector
- matchArraySize // Vector size
- );
-
- if (match == desiredmatches) {
- if (line.substr(results[2], results[3] - results[2]) == "processor") {
- // Start pulling data for a new processor
- int cpunum = -1;
- int coreid = -1;
- int cpucores = -1;
- int model = -1;
- int family = -1;
- int cpuid_lvl = -1;
- double speed = -1;
- int cache = -1;
- string vendor = "unknown";
- string flags = "unknown";
-
- // Get the cpu # from this line
- cpunum = convert<int>(line.substr(results[4],
- results[5] - results[4]));
- // And now grab the rest
- do {
- getline(cpuinfo, line);
- match = pcre_exec(regex, // Regex
- NULL, // No extra optimizations
- line.c_str(), // Input
- line.length(), // Input length
- 0, // Start offset
- PCRE_NOTEMPTY, // options bitvector
- results, // Results vector
- matchArraySize // Vector size
- );
-
- if (match == desiredmatches) {
- string key = line.substr(results[2],
- results[3] - results[2]);
-
- string value = line.substr(results[4],
- results[5] - results[4]);
-
- if (key == "core id") {
- coreid = convert<int>(value);
- } else if (key == "cpu cores") {
- cpucores = convert<int>(value);
- } else if (key == "model") {
- model = convert<int>(value);
- } else if (key == "cpu family") {
- family = convert<int>(value);
- } else if (key == "cpuid level") {
- cpuid_lvl = convert<int>(value);
- } else if (key == "cpu MHz") {
- speed = convert<int>(value);
- } else if (key == "cache size") {
- int space = value.find(' ');
- cache = convert<int>(value.substr(0, space));
- } else if (key == "vendor_id") {
- vendor = value;
- } else if (key == "flags") {
- flags = value;
- }
- }
- }
- while (line != "");
-
- // Got all the data. Add the CPU to our list
- CPUWrapper *cpu = new CPUWrapper(cpunum,
- coreid,
- cpucores,
- model,
- family,
- cpuid_lvl,
- speed,
- cache,
- vendor,
- flags);
- cpus.push_back(cpu);
- }
- }
- else
- continue;
- }
- cpuinfo.close();
-}
diff --git a/src/cpu.h b/src/cpu.h
deleted file mode 100644
index bb3a9b3..0000000
--- a/src/cpu.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* cpu.h - Copyright (C) 2009 Red Hat, Inc.
- * Written by Arjun Roy <arroy(a)redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA. A copy of the GNU General Public License is
- * also available at http://www.gnu.org/copyleft/gpl.html.
- */
-
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-
-#include "qmf/com/redhat/matahari/CPU.h"
-
-using namespace qpid::management;
-using namespace std;
-
-using qpid::management::Manageable;
-
-class CPUWrapper : public Manageable
-{
- friend ostream& operator<<(ostream &output, const CPUWrapper& cpu);
- friend class HostWrapper;
-
- // CPU Parameters
- int cpunum;
- int corenum;
- int numcores;
-
- int model;
- int family;
- int cpuid_lvl;
- double speed;
- int cache;
-
- string vendor;
- string flags;
-
- // QMF related fields
- ManagementAgent *agent;
- qmf::com::redhat::matahari::CPU *mgmt_object;
-
- // Methods to put up / take down QMF Objects
- void setupQMFObject(ManagementAgent *agent, Manageable *parent);
- void cleanupQMFObject(void);
- void syncQMFObject(void);
-
- // Constructors and Destructor are private
- CPUWrapper() {}
- CPUWrapper(const CPUWrapper&) {}
- ~CPUWrapper() {}
-
- CPUWrapper(int cpunum__,
- int corenum__,
- int numcores__,
- int model__,
- int family__,
- int cpuid_lvl__,
- double speed__,
- int cache__,
- const string &vendor__,
- const string &flags__) {
- cpunum = cpunum__;
- corenum = corenum__;
- numcores = numcores__;
- model = model__;
- family = family__;
- cpuid_lvl = cpuid_lvl__;
- speed = speed__;
- cache = cache__;
- vendor = vendor__;
- flags = flags__;
- }
-
-public:
-
- // Factory like method
- static void fillCPUInfo(vector<CPUWrapper*> &cpus, ManagementAgent *agent);
-
- // QMF Methods
- ManagementObject* GetManagementObject(void) const { return mgmt_object; }
-
- status_t ManagementMethod(uint32_t methodId, Args& args, string& text) {
- return STATUS_NOT_IMPLEMENTED;
- }
-
- // Field Accessors
- int getCpunum(void) { return cpunum; }
- int getCorenum(void) { return corenum; }
- int getNumcores(void) { return numcores; }
-
- int getModel(void) { return model; }
- int getFamily(void) { return family; }
- int getCpuid_Lvl(void) { return cpuid_lvl; }
- double getSpeed(void) { return speed; }
- int getCache(void) { return cache; }
-
- const string &getVendor(void) { return vendor; }
- const string &getFlags(void) { return flags; }
-};
diff --git a/src/host.cpp b/src/host.cpp
index ac04f47..b3ed51f 100644
--- a/src/host.cpp
+++ b/src/host.cpp
@@ -46,14 +46,8 @@ ostream& operator<<(ostream &output, const HostWrapper& host)
output << "Hypervisor: " << host.hypervisor << endl;
output << "Arch: " << host.arch << endl << endl;
- vector<CPUWrapper*> cpus = host.cpus;
vector<NICWrapper*> nics = host.nics;
- for (vector<CPUWrapper*>::iterator iter = cpus.begin();
- iter!= cpus.end();
- iter++) {
- output << **iter << endl;
- }
for (vector<NICWrapper*>::iterator iter = nics.begin();
iter!= nics.end();
iter++) {
@@ -84,12 +78,6 @@ void HostWrapper::setupQMFObjects(ManagementAgent *agent)
processors.setup(agent, this);
- // Iterate over list and set up CPU objects
- for (vector<CPUWrapper*>::iterator iter = cpus.begin();
- iter!= cpus.end();
- iter++) {
- (*iter)->setupQMFObject(agent, this);
- }
// Iterate over list and set up NIC objects
for (vector<NICWrapper*>::iterator iter = nics.begin();
iter!= nics.end();
@@ -113,12 +101,6 @@ void HostWrapper::cleanupQMFObjects(void)
// Clean up Host object
mgmt_object->resourceDestroy();
- // Iterate over list and clean up CPU objects
- for (vector<CPUWrapper*>::iterator iter = cpus.begin();
- iter!= cpus.end();
- iter++) {
- (*iter)->cleanupQMFObject();
- }
// Iterate over list and clean up NIC objects
for (vector<NICWrapper*>::iterator iter = nics.begin();
iter!= nics.end();
@@ -129,11 +111,6 @@ void HostWrapper::cleanupQMFObjects(void)
void HostWrapper::cleanupMemberObjects(void)
{
- // Get rid of the CPUWrapper objects for this host
- for (vector<CPUWrapper*>::iterator iter = cpus.begin(); iter != cpus.end();) {
- delete (*iter);
- iter = cpus.erase(iter);
- }
// Get rid of the NICWrapper objects for this host
for (vector<NICWrapper*>::iterator iter = nics.begin(); iter != nics.end();) {
delete (*iter);
@@ -169,7 +146,6 @@ HostWrapper* HostWrapper::setupHostWrapper(ManagementAgent *agent)
HostWrapper *host = new HostWrapper();
try {
- CPUWrapper::fillCPUInfo(host->cpus, agent);
NICWrapper::fillNICInfo(host->nics, agent, hal_ctx);
// Host UUID
diff --git a/src/host.h b/src/host.h
index 148c91f..bdf43fa 100644
--- a/src/host.h
+++ b/src/host.h
@@ -23,7 +23,6 @@
#include "qmf/com/redhat/matahari/Host.h"
-#include "cpu.h"
#include "nic.h"
#include "processors.h"
@@ -47,7 +46,6 @@ class HostWrapper : public Manageable
int memory;
// Aggregated components
- vector<CPUWrapper*> cpus;
vector<NICWrapper*> nics;
ProcessorsAgent processors;
@@ -90,7 +88,6 @@ class HostWrapper : public Manageable
bool isBeeping(void) { return beeping; }
int getMemory(void) { return memory; }
- const vector<CPUWrapper*> &getCPUList(void) { return cpus; }
const vector<NICWrapper*> &getNICList(void) { return nics; }
// Main Loop
diff --git a/src/schema.xml b/src/schema.xml
index f9c6f6b..e6b54db 100644
--- a/src/schema.xml
+++ b/src/schema.xml
@@ -23,22 +23,6 @@
<statistic name="load_average" type="float" desc="The processing load average." />
</class>
- <class name="CPU">
-
- <property name="host" type="objId" access="RO" desc="Host that this cpu belongs to" index="y" references="Host" parentRef="y"/>
- <property name="cpunum" type="int32" access="RO" desc="CPU # for this host" index="y"/>
- <property name="corenum" type="int32" access="RO" desc="Index of core within CPU"/>
- <property name="numcores" type="int32" access="RO" desc="Total # of cores for CPU"/>
- <property name="model" type="int32" access="RO" desc="Processor Model"/>
- <property name="family" type="int32" access="RO" desc="Processor Family"/>
- <property name="cpuid_lvl" type="int32" access="RO" desc="CPU ID Level"/>
- <property name="speed" type="double" access="RO" desc="CPU Speed" unit="MHz"/>
- <property name="cache" type="int32" access="RO" desc="CPU Cache Size" unit="kb"/>
- <property name="vendor" type="sstr" access="RO" desc="CPU Vendor"/>
- <property name="flags" type="lstr" access="RO" desc="CPU Flags"/>
-
- </class>
-
<class name="NIC">
<property name="host" type="objId" access="RO" desc="Host that this NIC belongs to" index="y" references="Host" parentRef="y"/>
--
1.6.6.1
14 years
[PATCH matahari] Replaces the existing HAL code for ProcessorAgent with udev.
by Darryl L. Pierce
Stripped out the HAL support code and replaced with calls to udev. The
remainder of the code to extract CPU details parses through the
/proc/cpuinfo file since udev/sysfs will not return such information.
Signed-off-by: Darryl L. Pierce <dpierce(a)redhat.com>
---
configure.ac | 3 +-
src/Makefile.am | 4 +-
src/processors.cpp | 94 +++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 79 insertions(+), 22 deletions(-)
diff --git a/configure.ac b/configure.ac
index 9102c66..c51c23e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,7 +8,7 @@ AM_INIT_AUTOMAKE
AC_PROG_CXX
AC_PROG_CC
AC_PROG_CPP
-AC_CHECK_HEADERS([arpa/inet.h netinet/in.h sys/ioctl.h sys/socket.h unistd.h])
+AC_CHECK_HEADERS([arpa/inet.h netinet/in.h sys/ioctl.h sys/socket.h unistd.h libudev.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
@@ -19,6 +19,7 @@ PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.2.12)
PKG_CHECK_MODULES(HAL, hal >= 0.5.12)
PKG_CHECK_MODULES(LIBVIRT, libvirt >= 0.6.2)
PKG_CHECK_MODULES(PCRE, libpcre >= 7.8)
+PKG_CHECK_MODULES(UDEV, libudev >= 145)
# Checks for library functions.
AC_CHECK_FUNCS([gethostname inet_ntoa socket])
diff --git a/src/Makefile.am b/src/Makefile.am
index ee30443..b4668b9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-INCLUDES = -I$(top_srcdir)/src/qmf/com/redhat/matahari $(HAL_CFLAGS) $(LIBVIRT_CFLAGS) $(PCRE_CFLAGS)
+INCLUDES = -I$(top_srcdir)/src/qmf/com/redhat/matahari $(HAL_CFLAGS) $(LIBVIRT_CFLAGS) $(PCRE_CFLAGS) $(UDEV_CFLAGS)
sbin_PROGRAMS = matahari
@@ -41,6 +41,6 @@ CLEANFILES = $(generated_file_list) $(first)
matahari_CPPFLAGS = -fno-strict-aliasing
matahari_LDFLAGS = -L/usr/local/lib
-matahari_LDADD = -lqmf $(HAL_LIBS) $(LIBVIRT_LIBS) $(PCRE_LIBS)
+matahari_LDADD = -lqmf $(HAL_LIBS) $(LIBVIRT_LIBS) $(PCRE_LIBS) $(UDEV_LIBS)
dist_pkgdata_DATA = schema.xml
diff --git a/src/processors.cpp b/src/processors.cpp
index 4317b1f..30a2837 100644
--- a/src/processors.cpp
+++ b/src/processors.cpp
@@ -17,25 +17,19 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
-#include <iostream>
+#include "processors.h"
#include <fstream>
-#include <sstream>
-#include <string>
-#include <vector>
-#include <stdexcept>
-
-#include <hal/libhal.h>
-
+#include <iostream>
#include <pcre.h>
-#include "hal.h"
-#include "processors.h"
+// TODO remove this wrapper once rhbz#583747 is fixed
+extern "C" {
+#include <libudev.h>
+}
using namespace std;
namespace _qmf = qmf::com::redhat::matahari;
-extern DBusError dbus_error;
-
void
ProcessorsAgent::setup(ManagementAgent* agent, Manageable* parent)
{
@@ -43,17 +37,79 @@ ProcessorsAgent::setup(ManagementAgent* agent, Manageable* parent)
management_object = new _qmf::Processors(agent, this, parent);
agent->addObject(management_object);
- LibHalContext* context = get_hal_ctx();
+ int core_count = 0;
+ string model = "unknown";
+
+ struct udev* udev = udev_new();
+ struct udev_enumerate* enumerator = udev_enumerate_new(udev);
+
+ udev_enumerate_add_match_property(enumerator, "DRIVER", "processor");
+ if(!udev_enumerate_scan_devices(enumerator))
+ {
+ struct udev_list_entry* entries = udev_enumerate_get_list_entry(enumerator);
+ struct udev_list_entry* entry;
+
+ udev_list_entry_foreach(entry, entries)
+ {
+ core_count++;
+ }
+ }
+
+ udev_enumerate_unref(enumerator);
+ udev_unref(udev);
+
+ ifstream input("/proc/cpuinfo");
+ if(input.is_open())
+ {
+ string regexstr = "(.*\\S)\\s*:\\s*(\\S.*)";
+ int expected = 3;
+ int found[expected * 3];
+ const char* pcre_error;
+ int pcre_error_offset;
+ pcre* regex;
+ bool done = false;
+ bool started = false;
+
+ regex = pcre_compile(regexstr.c_str(), 0, &pcre_error, &pcre_error_offset, NULL);
+ if(!regex) { throw runtime_error("Unable to compile regular expression."); }
+
+ while(!input.eof() && !done)
+ {
+ string line;
+
+ getline(input, line);
+ int match = pcre_exec(regex, NULL, line.c_str(), line.length(),
+ 0, PCRE_NOTEMPTY,found, expected * 3);
- int num_results;
- char** processors = libhal_find_device_by_capability(context,"processor", &num_results, &dbus_error);
+ if(match == expected)
+ {
+ string name = line.substr(found[2], found[3] - found[2]);
+ string value = line.substr(found[4], found[5] - found[4]);
- if (!processors)
- throw runtime_error("Error: could not query processors via HAL.");
+ // if we're at a second processor and we've already started, then we're done
+ if (name == "processor")
+ {
+ if (started)
+ {
+ done = true;
+ }
+ else
+ {
+ started = true;
+ }
+ }
+ else
+ {
+ if(name == "model name") model = value;
+ }
+ }
+ }
+ input.close();
+ }
// populate the managed object's values
- management_object->set_model(libhal_device_get_property_string(context, processors[0], "info.product", &dbus_error));
- management_object->set_cores(num_results);
+ management_object->set_model(model);
+ management_object->set_cores(core_count);
}
void
--
1.6.6.1
14 years
[PATCH matahari] Refactored the Host agent.
by Darryl L. Pierce
Replaced the previous HostWrapper class with the new HostAgent class,
which more closely resembles the style of the ProcessorsAgent class.
Deleted the HostWrapper class entirely.
Refactored the daemon entry point to reduce the number of methods
invoked in order to start or stop the HostAgent instance. Moved the
NICWrapper's setupQMFObject method from private to public so that it can
be invoked by the HostAgent. This is a temporary measure since the
NICWrapper will be replaced by a future patch.
Signed-off-by: Darryl L. Pierce <dpierce(a)redhat.com>
---
src/host.cpp | 263 +++++++++++++---------------------------------------
src/host.h | 75 ++++-----------
src/main.cpp | 57 ++++--------
src/nic.h | 2 +-
src/processors.cpp | 6 +
src/processors.h | 3 +
6 files changed, 111 insertions(+), 295 deletions(-)
diff --git a/src/host.cpp b/src/host.cpp
index ac04f47..885068b 100644
--- a/src/host.cpp
+++ b/src/host.cpp
@@ -37,213 +37,80 @@ using namespace std;
using qpid::management::Manageable;
namespace _qmf = qmf::com::redhat::matahari;
-ostream& operator<<(ostream &output, const HostWrapper& host)
+void
+HostAgent::setup(ManagementAgent* agent)
{
- output << "Node" << endl << endl;
- output << "UUID: " << host.uuid << endl;
- output << "Hostname: " << host.hostname << endl;
- output << "Memory: " << host.memory << endl;
- output << "Hypervisor: " << host.hypervisor << endl;
- output << "Arch: " << host.arch << endl << endl;
-
- vector<CPUWrapper*> cpus = host.cpus;
- vector<NICWrapper*> nics = host.nics;
-
- for (vector<CPUWrapper*>::iterator iter = cpus.begin();
- iter!= cpus.end();
- iter++) {
- output << **iter << endl;
- }
- for (vector<NICWrapper*>::iterator iter = nics.begin();
- iter!= nics.end();
- iter++) {
- output << **iter << endl;
+ management_object = new _qmf::Host(agent, this);
+ agent->addObject(management_object);
+
+ // discover the aspects of the host
+ processors.setup(agent, this);
+
+ LibHalContext *hal_ctx;
+ int ret;
+
+ // Get our HAL Context or die trying
+ hal_ctx = get_hal_ctx();
+ if (!hal_ctx)
+ throw runtime_error("Unable to get HAL Context Structure.");
+
+ try {
+ NICWrapper::fillNICInfo(this->nics, agent, hal_ctx);
+
+ // Host UUID
+ char *uuid_c = get_uuid(hal_ctx);
+ string uuid(uuid_c);
+ management_object->set_uuid(uuid);
+
+ // Hostname
+ char hostname_c[HOST_NAME_MAX];
+ ret = gethostname(hostname_c, sizeof(hostname_c));
+ if (ret != 0)
+ throw runtime_error("Unable to get hostname");
+ string hostname(hostname_c);
+ management_object->set_hostname(hostname);
+
+ // Hypervisor, arch, memory
+ management_object->set_memory(0);
+ management_object->set_hypervisor("unknown");
+ management_object->set_arch("unknown");
+
+ virConnectPtr connection;
+ virNodeInfo info;
+ connection = virConnectOpenReadOnly(NULL);
+ if (connection) {
+ const char *hv = virConnectGetType(connection);
+ if (hv != NULL)
+ management_object->set_hypervisor(hv);
+ ret = virNodeGetInfo(connection, &info);
+ if (ret == 0) {
+ management_object->set_arch(info.model);
+ management_object->set_memory(info.memory);
+ }
}
+ virConnectClose(connection);
- output << "End Node" << endl;
- return output;
-}
+ management_object->set_beeping(false);
-void HostWrapper::doLoop(void)
-{
- // Someday we might update statistics too!
- while(1)
+ // setup the nic objects
+ for(vector<NICWrapper*>::iterator iter = nics.begin();
+ iter != nics.end();
+ iter++)
{
- // update all statistics
- processors.update_load_averages();
- sleep(5);
- }
-}
-
-void HostWrapper::setupQMFObjects(ManagementAgent *agent)
-{
- // Set up Host object
- mgmt_object = new _qmf::Host(agent, this);
- agent->addObject(mgmt_object);
- syncQMFHostObject();
-
- processors.setup(agent, this);
-
- // Iterate over list and set up CPU objects
- for (vector<CPUWrapper*>::iterator iter = cpus.begin();
- iter!= cpus.end();
- iter++) {
- (*iter)->setupQMFObject(agent, this);
- }
- // Iterate over list and set up NIC objects
- for (vector<NICWrapper*>::iterator iter = nics.begin();
- iter!= nics.end();
- iter++) {
(*iter)->setupQMFObject(agent, this);
- }
-}
-
-void HostWrapper::syncQMFHostObject(void)
-{
- mgmt_object->set_uuid(uuid);
- mgmt_object->set_hostname(hostname);
- mgmt_object->set_memory(memory);
- mgmt_object->set_hypervisor(hypervisor);
- mgmt_object->set_arch(arch);
- mgmt_object->set_beeping(beeping);
-}
-
-void HostWrapper::cleanupQMFObjects(void)
-{
- // Clean up Host object
- mgmt_object->resourceDestroy();
-
- // Iterate over list and clean up CPU objects
- for (vector<CPUWrapper*>::iterator iter = cpus.begin();
- iter!= cpus.end();
- iter++) {
- (*iter)->cleanupQMFObject();
- }
- // Iterate over list and clean up NIC objects
- for (vector<NICWrapper*>::iterator iter = nics.begin();
- iter!= nics.end();
- iter++) {
- (*iter)->cleanupQMFObject();
- }
-}
-
-void HostWrapper::cleanupMemberObjects(void)
-{
- // Get rid of the CPUWrapper objects for this host
- for (vector<CPUWrapper*>::iterator iter = cpus.begin(); iter != cpus.end();) {
- delete (*iter);
- iter = cpus.erase(iter);
- }
- // Get rid of the NICWrapper objects for this host
- for (vector<NICWrapper*>::iterator iter = nics.begin(); iter != nics.end();) {
- delete (*iter);
- iter = nics.erase(iter);
- }
-}
-
-void HostWrapper::disposeHostWrapper()
-{
- if (hostSingleton == NULL)
- return;
-
- hostSingleton->cleanupQMFObjects();
- hostSingleton->cleanupMemberObjects();
-
- delete hostSingleton;
- hostSingleton = NULL;
-}
-
-HostWrapper* HostWrapper::setupHostWrapper(ManagementAgent *agent)
-{
- if (hostSingleton != NULL)
- return hostSingleton;
-
- LibHalContext *hal_ctx;
- int ret;
-
- // Get our HAL Context or die trying
- hal_ctx = get_hal_ctx();
- if (!hal_ctx)
- throw runtime_error("Unable to get HAL Context Structure.");
-
- HostWrapper *host = new HostWrapper();
-
- try {
- CPUWrapper::fillCPUInfo(host->cpus, agent);
- NICWrapper::fillNICInfo(host->nics, agent, hal_ctx);
-
- // Host UUID
- char *uuid_c = get_uuid(hal_ctx);
- string uuid(uuid_c);
- host->uuid = uuid;
-
- // Hostname
- char hostname_c[HOST_NAME_MAX];
- ret = gethostname(hostname_c, sizeof(hostname_c));
- if (ret != 0)
- throw runtime_error("Unable to get hostname");
- string hostname(hostname_c);
- host->hostname = hostname;
-
- // Hypervisor, arch, memory
- host->memory = 0;
- host->hypervisor = "unknown";
- host->arch = "unknown";
-
- virConnectPtr connection;
- virNodeInfo info;
- connection = virConnectOpenReadOnly(NULL);
- if (connection) {
- const char *hv = virConnectGetType(connection);
- if (hv != NULL)
- host->hypervisor = hv;
- ret = virNodeGetInfo(connection, &info);
- if (ret == 0) {
- host->arch = info.model;
- host->memory = info.memory;
- }
- }
- virConnectClose(connection);
-
- host->beeping = false;
- }
- catch (...) {
- host->cleanupMemberObjects();
- put_hal_ctx(hal_ctx);
- delete host;
- throw;
- }
-
- // Close the Hal Context
+ }
+ }
+ catch (...) {
put_hal_ctx(hal_ctx);
+ throw;
+ }
- host->setupQMFObjects(agent);
-
- // Setup singleton reference and return
- hostSingleton = host;
- return hostSingleton;
+ // Close the Hal Context
+ put_hal_ctx(hal_ctx);
}
-void HostWrapper::reboot()
+void
+HostAgent::update(void)
{
- system("shutdown -r now");
-}
-
-void HostWrapper::shutdown()
-{
- system("shutdown -h now");
-}
-
-Manageable::status_t
-HostWrapper::ManagementMethod(uint32_t methodId, Args& args, string& text)
-{
- switch(methodId) {
- case _qmf::Host::METHOD_SHUTDOWN:
- shutdown();
- return Manageable::STATUS_OK;
- case _qmf::Host::METHOD_REBOOT:
- reboot();
- return Manageable::STATUS_OK;
- }
- return Manageable::STATUS_NOT_IMPLEMENTED;
+ processors.update();
}
diff --git a/src/host.h b/src/host.h
index 148c91f..c19da3e 100644
--- a/src/host.h
+++ b/src/host.h
@@ -1,3 +1,6 @@
+#ifndef __HOST_H
+#define __HOST_H
+
/* host.h - Copyright (C) 2009 Red Hat, Inc.
* Written by Arjun Roy <arroy(a)redhat.com>
*
@@ -32,67 +35,25 @@ using namespace std;
using qpid::management::Manageable;
-class HostWrapper : public Manageable
+class HostAgent : public Manageable
{
- static HostWrapper *hostSingleton;
-
- friend ostream& operator<<(ostream &output, const HostWrapper& host);
-
- // Host Parameters
- string uuid;
- string hostname;
- string hypervisor;
- string arch;
- bool beeping;
- int memory;
-
- // Aggregated components
- vector<CPUWrapper*> cpus;
- vector<NICWrapper*> nics;
-
- ProcessorsAgent processors;
-
- // QMF related fields
- ManagementAgent *agent;
- qmf::com::redhat::matahari::Host *mgmt_object;
-
- // Methods to put up / take down QMF objects
- void setupQMFObjects(ManagementAgent *agent);
- void cleanupQMFObjects(void);
-
- // Housekeeping methods
- void syncQMFHostObject(void);
- void cleanupMemberObjects(void);
-
- // Host functionality
- void reboot();
- void shutdown();
-
- // Constructors and Destructor are private
- HostWrapper() {}
- HostWrapper(const HostWrapper &) {}
- ~HostWrapper() {}
+ private:
+ qmf::com::redhat::matahari::Host* management_object;
+ ProcessorsAgent processors;
+ vector<NICWrapper*> nics;
public:
- // Factory methods to create/dispose of the singleton
- static HostWrapper *setupHostWrapper(ManagementAgent *agent);
- static void disposeHostWrapper(void);
-
- // QMF Methods
- ManagementObject* GetManagementObject(void) const { return mgmt_object; }
- status_t ManagementMethod(uint32_t methodId, Args& args, string& text);
+ HostAgent() {}
+ virtual ~HostAgent() {}
- // Field Accessors
- const string &getUUID(void) { return uuid; }
- const string &getHostname(void) { return hostname; }
- const string &getHypervisor(void) { return hypervisor; }
- const string &getArch(void) { return arch; }
- bool isBeeping(void) { return beeping; }
- int getMemory(void) { return memory; }
+ ManagementObject* GetManagementObject(void) const { return management_object; }
- const vector<CPUWrapper*> &getCPUList(void) { return cpus; }
- const vector<NICWrapper*> &getNICList(void) { return nics; }
+ void setup(ManagementAgent* agent);
+ void update(void);
- // Main Loop
- void doLoop(void);
+ // agent methods
+ void shutdown(void);
+ void reboot(void);
};
+
+#endif // __HOST_H
diff --git a/src/main.cpp b/src/main.cpp
index 002a02e..8493864 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -42,18 +42,11 @@ namespace _qmf = qmf::com::redhat::matahari;
// Global Variables
ManagementAgent::Singleton* singleton;
-HostWrapper* HostWrapper::hostSingleton = NULL;
-void cleanup(void)
+void
+shutdown(int /*signal*/)
{
- HostWrapper::disposeHostWrapper();
- delete singleton;
-}
-
-void shutdown(int)
-{
- cleanup();
- exit(0);
+ exit(0);
}
static void
@@ -69,21 +62,22 @@ print_usage()
printf("\t-p | --port specify broker port.\n");
}
-int do_main(int argc, char **argv)
+int
+main(int argc, char **argv)
{
int arg;
int idx = 0;
bool daemonize = false;
bool gssapi = false;
bool verbose = false;
- char *host = NULL;
+ char *servername = NULL;
char *username = NULL;
char *service = NULL;
- int port = 5672;
+ int serverport = 5672;
ConnectionSettings settings;
ManagementAgent *agent;
- HostWrapper *hostWrapper;
+ HostAgent host;
struct option opt[] = {
{"help", no_argument, NULL, 'h'},
@@ -131,7 +125,7 @@ int do_main(int argc, char **argv)
break;
case 'p':
if (optarg) {
- port = atoi(optarg);
+ serverport = atoi(optarg);
} else {
print_usage();
exit(1);
@@ -139,7 +133,7 @@ int do_main(int argc, char **argv)
break;
case 'b':
if (optarg) {
- host = strdup(optarg);
+ servername = strdup(optarg);
} else {
print_usage();
exit(1);
@@ -169,8 +163,8 @@ int do_main(int argc, char **argv)
signal(SIGINT, shutdown);
// Connect to the broker
- settings.host = host ? host : "127.0.0.1";
- settings.port = port;
+ settings.host = servername ? servername : "127.0.0.1";
+ settings.port = serverport;
if (username != NULL) {
settings.username = username;
@@ -185,28 +179,13 @@ int do_main(int argc, char **argv)
agent->init(settings, 5, false, ".magentdata");
// Get the info and post it to the broker
- try {
- hostWrapper = HostWrapper::setupHostWrapper(agent);
- }
- catch (...) {
- cleanup();
- throw;
- }
+ host.setup(agent);
- // Main loop
- hostWrapper->doLoop();
+ while(1)
+ {
+ host.update();
+ sleep(5);
+ }
- // And we are done
- cleanup();
return 0;
}
-
-int main(int argc, char** argv)
-{
- try {
- return do_main(argc, argv);
- }
- catch(std::exception& e) {
- cout << "Top Level Exception: " << e.what() << endl;
- }
-}
diff --git a/src/nic.h b/src/nic.h
index 15f31fb..c79ecf9 100644
--- a/src/nic.h
+++ b/src/nic.h
@@ -47,7 +47,6 @@ class NICWrapper : public Manageable
qmf::com::redhat::matahari::NIC *mgmt_object;
// Methods to put up / take down QMF Objects
- void setupQMFObject(ManagementAgent *agent, Manageable *parent);
void cleanupQMFObject(void);
void syncQMFObject(void);
@@ -77,6 +76,7 @@ class NICWrapper : public Manageable
int identifyNIC(int seconds);
public:
+ void setupQMFObject(ManagementAgent *agent, Manageable *parent);
// Factory like method
static void fillNICInfo(vector<NICWrapper*> &nics,
ManagementAgent *agent,
diff --git a/src/processors.cpp b/src/processors.cpp
index 4317b1f..cff66d9 100644
--- a/src/processors.cpp
+++ b/src/processors.cpp
@@ -57,6 +57,12 @@ ProcessorsAgent::setup(ManagementAgent* agent, Manageable* parent)
}
void
+ProcessorsAgent::update(void) const
+{
+ update_load_averages();
+}
+
+void
ProcessorsAgent::update_load_averages(void) const
{
double load_average;
diff --git a/src/processors.h b/src/processors.h
index 3e46b16..17a6a6a 100644
--- a/src/processors.h
+++ b/src/processors.h
@@ -42,6 +42,9 @@ class ProcessorsAgent : public Manageable
void setup(ManagementAgent* agent, Manageable* parent);
+ void update(void) const;
+
+ private:
// agent methods
void update_load_averages(void) const;
};
--
1.6.6.1
14 years
Representing networks on the node...
by Darryl L. Pierce
I meant to send this out a while back, but don't see that I ever
actually sent it.
I'm currently reworking the matahari agents to clean up the code,
refactor elements and also enhance the agents. And the one that has me
stumped is the NIC agent.
The main problem is that, if we're going to represent network
interfaces, we shouldn't limit it to only physical devices. Instead, I
feel that it should represent all network devices, including virtual
interfaces, bridges, etc.
So what I was thinking about was to have an agent to represent the
physical device, and then agents under it to represent the network(s) to
which it is associated.
So the physical device would represented by a NetworkDevice agent with
the following properties/methods:
* mac_address - address for device
* vendor - the NIC manufacturer
* model - the NIC model
* interface - the system iface name
* create() - creates a network definition
* destroy() - deletes the network definition
* blink() - causes the device to blink, so it can be identified
The properties are, hopefully, pretty clear. The methods will likely
need a little more clarification.
create() - Takes arguments that configure the network to which the
device is to be connected; i.e., the address, netmask, gateway, DNS
entries, whether to use DHCP, etc. This can become a very heavy method
so might logically be broken up into related methods.
destroy() - The reverse of connect(), it would take down an active
network. An option argument would indicate to also delete the
configuration file(s) for the network.
The Network agent would represent the networks to which a NetworkDevice
is connected. It has a parent reference to the NetworkDevice parent, and
has the following properties/methods:
* active - reports whether the interface is up or down
* address - the assigned network address [1]
* netmask
* gateway
* DNS
* bridge - reports whether the interface is a bridge
* virtual - reports whether the interface is virtual
* up() - brings the interface up
* down() - stops the interface
Granted, this is not a complete list: here is where I really would like
to kick around some ideas of how we ought to implement things if we go
in this direction.
In addition to being directed by the management server, the status of
Network agents would be affected by local messaging (dbus?) to keep its
status as real-time as possible.
Ideas? Questions?
[1] - duplication is needed to support IPv6
--
Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc.
Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/
14 years