Also adds a new source module, processor, which contains APIs for retrieve processor details.
Moved the processor initialization code to this new source module.
Signed-off-by: Darryl L. Pierce dpierce@redhat.com --- src/Makefile.am | 10 ++- src/host.cpp | 139 +----------------------------------- src/host.h | 11 +++ src/main.cpp | 3 + src/processor.cpp | 169 ++++++++++++++++++++++++++++++++++++++++++++ src/processor.h | 26 +++++++ src/qmf/processoragent.cpp | 45 ++++++++++++ src/qmf/processoragent.h | 47 ++++++++++++ src/schema-host.xml | 5 ++ 9 files changed, 318 insertions(+), 137 deletions(-) create mode 100644 src/processor.cpp create mode 100644 src/processor.h create mode 100644 src/qmf/processoragent.cpp create mode 100644 src/qmf/processoragent.h
diff --git a/src/Makefile.am b/src/Makefile.am index 304214c..c56a900 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,7 +15,9 @@ generated_file_list = \ qmf/com/redhat/matahari/host/Host.cpp \ qmf/com/redhat/matahari/host/Host.h \ qmf/com/redhat/matahari/host/Package.cpp \ - qmf/com/redhat/matahari/host/Package.h + qmf/com/redhat/matahari/host/Package.h \ + qmf/com/redhat/matahari/host/Processor.cpp \ + qmf/com/redhat/matahari/host/Processor.h
nodist_matahari_SOURCES = $(generated_file_list) config.h
@@ -24,8 +26,12 @@ matahari_SOURCES = \ host.h \ hostlistener.h \ main.cpp \ + processor.cpp \ + processor.h \ qmf/hostagent.cpp \ - qmf/hostagent.h + qmf/hostagent.h \ + qmf/processoragent.cpp \ + qmf/processoragent.h
SCHEMAS = \ schema-host.xml diff --git a/src/host.cpp b/src/host.cpp index d129121..e653107 100644 --- a/src/host.cpp +++ b/src/host.cpp @@ -22,9 +22,8 @@ #include <fstream> #include "host.h" #include <libvirt/libvirt.h> -#include <pcre.h> +#include "processor.h" #include <set> -#include <stdexcept> #include <string> #include <sys/sysinfo.h>
@@ -95,18 +94,6 @@ typedef BOOL (WINAPI* LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
#endif
-typedef struct cpuinfo_ -{ - static bool initialized; - string model; - unsigned int cpus; - unsigned int cores; -} cpuinfo_t; - -bool cpuinfo_t::initialized = false; - -cpuinfo_t cpuinfo; - set<HostListener*> _listeners; unsigned int _heartbeat_sequence;
@@ -286,128 +273,10 @@ host_get_memory() return memory; }
-void -host_get_cpu_details() -{ - if(cpuinfo.initialized) return; - - cpuinfo.initialized = true; - -#if __linux__ - 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()) - { - 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") - { - cpuinfo.cpus++; - if (started) - { - done = true; - } - else - { - started = true; - } - } - else if (!done) - { - if (name == "cpu cores") cpuinfo.cores = atoi(value.c_str()); - else if (name == "model name") cpuinfo.model = value; - } - } - } - input.close(); - cpuinfo.cpus /= cpuinfo.cores; - } -#elif defined WIN32 - LPFN_GLPI proc; - DWORD ret_length; - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer, ptr; - - proc = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), - "GetLogicalProcessorInformation"); - if(proc) - { - BOOL done = FALSE; - - while (!done) - { - DWORD rc = proc(buffer, &ret_length); - - if(rc == FALSE) - { - if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - if(buffer) - { - free(buffer); - buffer = NULL; - } - - buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(ret_length); - } - } - else - { - done = TRUE; - } - } - - ptr = buffer; - - DWORD offset = 0; - - while(offset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= ret_length) - { - switch(ptr->Relationship) - { - case RelationProcessorCore: cpuinfo.cores++; break; - case RelationProcessorPackage: cpuinfo.cpus++; break; - } - } - - if(buffer) - { - free(buffer); - buffer = NULL; - } - } -#endif -} - string host_get_cpu_model() { - host_get_cpu_details(); + cpu_get_details();
return cpuinfo.model; } @@ -415,7 +284,7 @@ host_get_cpu_model() unsigned int host_get_number_of_cpus() { - host_get_cpu_details(); + cpu_get_details();
return cpuinfo.cpus; } @@ -423,7 +292,7 @@ host_get_number_of_cpus() unsigned int host_get_number_of_cpu_cores() { - host_get_cpu_details(); + cpu_get_details();
return cpuinfo.cores; } diff --git a/src/host.h b/src/host.h index 574e8b5..b6e9ffb 100644 --- a/src/host.h +++ b/src/host.h @@ -27,6 +27,17 @@
using namespace std;
+typedef struct cpuinfo_ +{ + static bool initialized; + string model; + unsigned int cpus; + unsigned int cores; + unsigned int wordsize; +} cpuinfo_t; + +extern cpuinfo_t cpuinfo; + void host_register_listener(HostListener* listener);
void host_remove_istener(HostListener* listener); diff --git a/src/main.cpp b/src/main.cpp index f7d6329..c75d0ce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,6 +35,7 @@ #include "host.h"
#include "qmf/hostagent.h" +#include "qmf/processoragent.h"
#include "qmf/com/redhat/matahari/host/Package.h"
@@ -81,6 +82,7 @@ main(int argc, char **argv) ConnectionSettings settings; ManagementAgent *agent; HostAgent hostAgent; + ProcessorAgent processorAgent;
struct option opt[] = { {"help", no_argument, NULL, 'h'}, @@ -183,6 +185,7 @@ main(int argc, char **argv)
// Get the info and post it to the broker hostAgent.setup(agent); + processorAgent.setup(agent, hostAgent);
while(1) { diff --git a/src/processor.cpp b/src/processor.cpp new file mode 100644 index 0000000..bc72757 --- /dev/null +++ b/src/processor.cpp @@ -0,0 +1,169 @@ +/* processor.cpp - Copyright (C) 2010 Red Hat, Inc. + * Written by Darryl L. Pierce dpierce@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 "config.h" +#include <fstream> +#include "host.h" +#include <limits.h> +#include <pcre.h> +#include "processor.h" +#include <stdexcept> + +cpuinfo_t cpuinfo; +bool cpuinfo_t::initialized = false; + +void +cpu_get_details() +{ + if(cpuinfo.initialized) return; + + cpuinfo.initialized = true; + +#if __linux__ + 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()) + { + 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") + { + cpuinfo.cpus++; + if (started) + { + done = true; + } + else + { + started = true; + } + } + else if (!done) + { + if (name == "cpu cores") cpuinfo.cores = atoi(value.c_str()); + else if (name == "model name") cpuinfo.model = value; + else if (name == "flags") + { + string flags(value); + + // if the cpuflags contain "lm" then it's a 64 bit CPU + // http://www.brandonhutchinson.com/Understanding_proc_cpuinfo.html + cpuinfo.wordsize = (flags.find(" lm ") ? 64 : 32); + } + } + } + } + input.close(); + cpuinfo.cpus /= cpuinfo.cores; + } +#elif defined WIN32 + LPFN_GLPI proc; + DWORD ret_length; + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer, ptr; + + proc = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), + "GetLogicalProcessorInformation"); + if(proc) + { + BOOL done = FALSE; + + while (!done) + { + DWORD rc = proc(buffer, &ret_length); + + if(rc == FALSE) + { + if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + if(buffer) + { + free(buffer); + buffer = NULL; + } + + buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(ret_length); + } + } + else + { + done = TRUE; + } + } + + ptr = buffer; + + DWORD offset = 0; + + while(offset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= ret_length) + { + switch(ptr->Relationship) + { + case RelationProcessorCore: cpuinfo.cores++; break; + case RelationProcessorPackage: cpuinfo.cpus++; break; + } + } + + if(buffer) + { + free(buffer); + buffer = NULL; + } + } +#endif +} + +unsigned int +cpu_get_wordsize() +{ + static unsigned int wordsize = 0; + + if(wordsize == 0) + { + cpu_get_details(); + return cpuinfo.wordsize; + } + + return wordsize; +} diff --git a/src/processor.h b/src/processor.h new file mode 100644 index 0000000..f56f177 --- /dev/null +++ b/src/processor.h @@ -0,0 +1,26 @@ +#ifndef __PROCESSOR_H +#define __PROCESSOR_H + +/* processor.h - Copyright (C) 2010 Red Hat, Inc. + * Written by Darryl L. Pierce dpierce@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. + */ + +void cpu_get_details(); +unsigned int cpu_get_wordsize(); + +#endif diff --git a/src/qmf/processoragent.cpp b/src/qmf/processoragent.cpp new file mode 100644 index 0000000..7c0d6ec --- /dev/null +++ b/src/qmf/processoragent.cpp @@ -0,0 +1,45 @@ +/* processoragent.cpp - Copyright (C) 2010 Red Hat, Inc. + * Written by Darryl L. Pierce dpierce@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 "config.h" +#include "processoragent.h" +#include "processor.h" + +ProcessorAgent::ProcessorAgent() +{ } + +ProcessorAgent::~ProcessorAgent() +{ } + +void +ProcessorAgent::setup(ManagementAgent* agent, HostAgent& parent) +{ + this->_agent = agent; + this->_management_object = new _qmf::Processor(agent, this); + agent->addObject(this->_management_object); + + _management_object->set_host(parent.GetManagementObject()->getObjectId()); + _management_object->set_wordsize(cpu_get_wordsize()); +} + +ManagementObject* +ProcessorAgent::GetManagementObject() const +{ + return this->_management_object; +} diff --git a/src/qmf/processoragent.h b/src/qmf/processoragent.h new file mode 100644 index 0000000..08d6090 --- /dev/null +++ b/src/qmf/processoragent.h @@ -0,0 +1,47 @@ +#ifndef __PROCESSORAGENT_H +#define __PROCESSORAGENT_H + +/* processoragent.h - Copyright (C) 2010 Red Hat, Inc. + * Written by Darryl L. Pierce dpierce@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 "qmf/hostagent.h" +#include "qmf/com/redhat/matahari/host/Processor.h" + +using namespace qpid::management; + +namespace _qmf = qmf::com::redhat::matahari::host; + +class ProcessorAgent : public Manageable +{ + private: + _qmf::Processor* _management_object; + ManagementAgent* _agent; + + public: + ProcessorAgent(); + virtual ~ProcessorAgent(); + + void setup(ManagementAgent* agent, HostAgent& parent); + ManagementObject* GetManagementObject() const; +}; + +#endif diff --git a/src/schema-host.xml b/src/schema-host.xml index 7a223f9..e5253a5 100644 --- a/src/schema-host.xml +++ b/src/schema-host.xml @@ -25,7 +25,12 @@ <method name="identify" desc="Tells the host to beep its pc speaker." /> <method name="shutdown" desc="Shutdown node" /> <method name="reboot" desc="Reboot node" /> + </class>
+ <class name="Processor"> + <!-- properties --> + <property name="host" type="objId" access="RO" desc="The host agent." /> + <property name="wordsize" type="uint8" access="RO" desc="The wordsize for the processor." /> </class>
<eventArguments>