summaryrefslogtreecommitdiffstats
path: root/src/hardware
diff options
context:
space:
mode:
authorPeter Schiffer <pschiffe@redhat.com>2013-04-15 18:57:02 +0200
committerPeter Schiffer <pschiffe@redhat.com>2013-04-15 18:57:02 +0200
commita8b751d7c530e103910885c757a2e36abefe625d (patch)
tree97ea17eed124ad46195fab21a8e37751be2d90f2 /src/hardware
parentd65c216cb9d8bcce65f19d4e0b1a06b298c8d654 (diff)
downloadopenlmi-providers-a8b751d7c530e103910885c757a2e36abefe625d.tar.gz
openlmi-providers-a8b751d7c530e103910885c757a2e36abefe625d.tar.xz
openlmi-providers-a8b751d7c530e103910885c757a2e36abefe625d.zip
Hardware: Added System Memory Provider
Added new provider: * LMI_MemoryProvider
Diffstat (limited to 'src/hardware')
-rw-r--r--src/hardware/CMakeLists.txt2
-rw-r--r--src/hardware/LMI_Hardware.h1
-rw-r--r--src/hardware/LMI_MemoryProvider.c322
-rw-r--r--src/hardware/LMI_ProcessorCacheMemoryProvider.c1
-rw-r--r--src/hardware/LMI_ProcessorProvider.c2
-rw-r--r--src/hardware/dmidecode.c150
-rw-r--r--src/hardware/dmidecode.h28
-rw-r--r--src/hardware/procfs.c (renamed from src/hardware/cpuinfo.c)32
-rw-r--r--src/hardware/procfs.h (renamed from src/hardware/cpuinfo.h)12
9 files changed, 544 insertions, 6 deletions
diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt
index 3949a8a..c50acef 100644
--- a/src/hardware/CMakeLists.txt
+++ b/src/hardware/CMakeLists.txt
@@ -6,7 +6,7 @@ set(provider_SRCS
utils.c
dmidecode.c
lscpu.c
- cpuinfo.c
+ procfs.c
sysfs.c
LMI_ProcessorProvider.c
LMI_ProcessorCapabilitiesProvider.c
diff --git a/src/hardware/LMI_Hardware.h b/src/hardware/LMI_Hardware.h
index 1f30be6..19a8ff7 100644
--- a/src/hardware/LMI_Hardware.h
+++ b/src/hardware/LMI_Hardware.h
@@ -28,5 +28,6 @@
#define CPU_CAP_CLASS_NAME "ProcessorCapabilities"
#define CPU_CACHE_CLASS_NAME "ProcessorCacheMemory"
#define CPU_CHIP_CLASS_NAME "ProcessorChip"
+#define MEM_CLASS_NAME "Memory"
#endif /* LMI_HARDWARE_H_ */
diff --git a/src/hardware/LMI_MemoryProvider.c b/src/hardware/LMI_MemoryProvider.c
new file mode 100644
index 0000000..6c9a2ec
--- /dev/null
+++ b/src/hardware/LMI_MemoryProvider.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Peter Schiffer <pschiffe@redhat.com>
+ */
+
+#include <konkret/konkret.h>
+#include "LMI_Memory.h"
+#include "LMI_Hardware.h"
+#include "globals.h"
+#include "dmidecode.h"
+#include "procfs.h"
+
+static const CMPIBroker* _cb = NULL;
+
+static void LMI_MemoryInitialize()
+{
+}
+
+static CMPIStatus LMI_MemoryCleanup(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_MemoryEnumInstanceNames(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop)
+{
+ return KDefaultEnumerateInstanceNames(
+ _cb, mi, cc, cr, cop);
+}
+
+static CMPIStatus LMI_MemoryEnumInstances(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char** properties)
+{
+ LMI_Memory lmi_mem;
+ const char *ns = KNameSpace(cop), *name = "System Memory";
+ char *error_msg = NULL;
+ unsigned long fallback_memory_size = 0;
+ DmiMemory dmi_memory;
+
+ if (dmi_get_memory(&dmi_memory) != 0) {
+ fallback_memory_size = meminfo_get_memory_size();
+ if (!fallback_memory_size) {
+ error_msg = "Unable to get memory information.";
+ goto done;
+ }
+ }
+
+ LMI_Memory_Init(&lmi_mem, _cb, ns);
+
+ LMI_Memory_Set_SystemCreationClassName(&lmi_mem,
+ get_system_creation_class_name());
+ LMI_Memory_Set_SystemName(&lmi_mem, get_system_name());
+ LMI_Memory_Set_CreationClassName(&lmi_mem, ORGID "_" MEM_CLASS_NAME);
+
+ LMI_Memory_Set_DeviceID(&lmi_mem, "0");
+ LMI_Memory_Set_Volatile(&lmi_mem, 1);
+ LMI_Memory_Set_Access(&lmi_mem, LMI_Memory_Access_Read_Write_Supported);
+ LMI_Memory_Set_BlockSize(&lmi_mem, 1);
+ LMI_Memory_Set_EnabledState(&lmi_mem, LMI_Memory_EnabledState_Enabled);
+ LMI_Memory_Init_OperationalStatus(&lmi_mem, 1);
+ LMI_Memory_Set_OperationalStatus(&lmi_mem, 0,
+ LMI_Memory_OperationalStatus_Unknown);
+ LMI_Memory_Set_HealthState(&lmi_mem, LMI_Memory_HealthState_Unknown);
+ LMI_Memory_Set_ElementName(&lmi_mem, name);
+ LMI_Memory_Set_Caption(&lmi_mem, name);
+ LMI_Memory_Set_Name(&lmi_mem, name);
+ LMI_Memory_Set_Description(&lmi_mem,
+ "This object represents all memory available in system.");
+ LMI_Memory_Set_InstanceID(&lmi_mem, ORGID ":" MEM_CLASS_NAME ":0");
+ LMI_Memory_Set_IsCompressed(&lmi_mem, 0);
+ LMI_Memory_Set_Purpose(&lmi_mem, "The system memory is temporary storage "
+ "area storing instructions and data required by processor "
+ "to run programs.");
+
+ if (!fallback_memory_size) {
+ LMI_Memory_Set_NumberOfBlocks(&lmi_mem, dmi_memory.physical_size);
+ LMI_Memory_Set_ConsumableBlocks(&lmi_mem, dmi_memory.available_size);
+ LMI_Memory_Set_StartingAddress(&lmi_mem, dmi_memory.start_addr);
+ LMI_Memory_Set_EndingAddress(&lmi_mem, dmi_memory.end_addr);
+ } else {
+ LMI_Memory_Set_NumberOfBlocks(&lmi_mem, fallback_memory_size);
+ }
+
+ KReturnInstance(cr, lmi_mem);
+
+done:
+ dmi_free_memory(&dmi_memory);
+
+ if (error_msg) {
+ KReturn2(_cb, ERR_FAILED, error_msg);
+ }
+
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_MemoryGetInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char** properties)
+{
+ return KDefaultGetInstance(
+ _cb, mi, cc, cr, cop, properties);
+}
+
+static CMPIStatus LMI_MemoryCreateInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const CMPIInstance* ci)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_MemoryModifyInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const CMPIInstance* ci,
+ const char** properties)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_MemoryDeleteInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_MemoryExecQuery(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* lang,
+ const char* query)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+CMInstanceMIStub(
+ LMI_Memory,
+ LMI_Memory,
+ _cb,
+ LMI_MemoryInitialize())
+
+static CMPIStatus LMI_MemoryMethodCleanup(
+ CMPIMethodMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_MemoryInvokeMethod(
+ CMPIMethodMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* meth,
+ const CMPIArgs* in,
+ CMPIArgs* out)
+{
+ return LMI_Memory_DispatchMethod(
+ _cb, mi, cc, cr, cop, meth, in, out);
+}
+
+CMMethodMIStub(
+ LMI_Memory,
+ LMI_Memory,
+ _cb,
+ LMI_MemoryInitialize())
+
+KUint32 LMI_Memory_RequestStateChange(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_MemoryRef* self,
+ const KUint16* RequestedState,
+ KRef* Job,
+ const KDateTime* TimeoutPeriod,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KUint32 LMI_Memory_SetPowerState(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_MemoryRef* self,
+ const KUint16* PowerState,
+ const KDateTime* Time,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KUint32 LMI_Memory_Reset(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_MemoryRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KUint32 LMI_Memory_EnableDevice(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_MemoryRef* self,
+ const KBoolean* Enabled,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KUint32 LMI_Memory_OnlineDevice(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_MemoryRef* self,
+ const KBoolean* Online,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KUint32 LMI_Memory_QuiesceDevice(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_MemoryRef* self,
+ const KBoolean* Quiesce,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KUint32 LMI_Memory_SaveProperties(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_MemoryRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KUint32 LMI_Memory_RestoreProperties(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_MemoryRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KONKRET_REGISTRATION(
+ "root/cimv2",
+ "LMI_Memory",
+ "LMI_Memory",
+ "instance method")
diff --git a/src/hardware/LMI_ProcessorCacheMemoryProvider.c b/src/hardware/LMI_ProcessorCacheMemoryProvider.c
index afc5d7f..030ddd1 100644
--- a/src/hardware/LMI_ProcessorCacheMemoryProvider.c
+++ b/src/hardware/LMI_ProcessorCacheMemoryProvider.c
@@ -98,6 +98,7 @@ static CMPIStatus LMI_ProcessorCacheMemoryEnumInstances(
ORGID "_" CPU_CACHE_CLASS_NAME);
LMI_ProcessorCacheMemory_Set_BlockSize(&lmi_cpu_cache, 1);
+ LMI_ProcessorCacheMemory_Set_Volatile(&lmi_cpu_cache, 1);
LMI_ProcessorCacheMemory_Set_HealthState(&lmi_cpu_cache,
LMI_ProcessorCacheMemory_HealthState_Unknown);
LMI_ProcessorCacheMemory_Init_OperationalStatus(&lmi_cpu_cache, 1);
diff --git a/src/hardware/LMI_ProcessorProvider.c b/src/hardware/LMI_ProcessorProvider.c
index 99b0fad..c14b105 100644
--- a/src/hardware/LMI_ProcessorProvider.c
+++ b/src/hardware/LMI_ProcessorProvider.c
@@ -27,7 +27,7 @@
#include "globals.h"
#include "dmidecode.h"
#include "lscpu.h"
-#include "cpuinfo.h"
+#include "procfs.h"
CMPIUint16 get_family(const char *family);
CMPIUint16 get_cpustatus(const char *status);
diff --git a/src/hardware/dmidecode.c b/src/hardware/dmidecode.c
index 348c7a2..367a08c 100644
--- a/src/hardware/dmidecode.c
+++ b/src/hardware/dmidecode.c
@@ -692,3 +692,153 @@ void dmi_free_cpu_caches(DmiCpuCache **caches, unsigned *caches_nb)
*caches_nb = 0;
*caches = NULL;
}
+
+
+/******************************************************************************
+ * DmiMemory
+ */
+
+/*
+ * Initialize DmiMemory attributes.
+ * @param memory
+ */
+void init_dmi_memory_struct(DmiMemory *memory)
+{
+ memory->physical_size = 0;
+ memory->available_size = 0;
+ memory->start_addr = 0;
+ memory->end_addr = 0;
+ memory->modules = NULL;
+ memory->modules_nb = 0;
+}
+
+/*
+ * Initialize DmiMemoryModule attributes.
+ * @param mem
+ */
+void init_dmi_memory_module_struct(DmiMemoryModule *mem)
+{
+ mem->size = 0;
+}
+
+short dmi_get_memory(DmiMemory *memory)
+{
+ short ret = -1;
+ int curr_mem = -1;
+ unsigned i, buffer_size = 0;
+ char **buffer = NULL, *buf;
+
+ init_dmi_memory_struct(memory);
+
+ /* get dmidecode output for memory modules */
+ if (run_command("dmidecode -t 17", &buffer, &buffer_size) != 0) {
+ ret = -2;
+ goto done;
+ }
+
+ /* count modules */
+ for (i = 0; i < buffer_size; i++) {
+ if (strstr(buffer[i], "Size: ") &&
+ !strstr(buffer[i], "Size: No Module Installed")) {
+ memory->modules_nb++;
+ }
+ }
+
+ /* if no module was found */
+ if (memory->modules_nb < 1) {
+ warn("Dmidecode didn't recognize any memory module.");
+ ret = -3;
+ goto done;
+ }
+
+ /* allocate memory for modules */
+ memory->modules = (DmiMemoryModule *)calloc(memory->modules_nb, sizeof(DmiMemoryModule));
+ if (!memory->modules) {
+ warn("Failed to allocate memory.");
+ ret = -4;
+ goto done;
+ }
+
+ /* parse information about modules */
+ for (i = 0; i < buffer_size; i++) {
+ if (strstr(buffer[i], "Size: ") &&
+ !strstr(buffer[i], "Size: No Module Installed")) {
+ curr_mem++;
+ init_dmi_memory_module_struct(&memory->modules[curr_mem]);
+
+ /* Module Size */
+ buf = copy_string_part_after_delim(buffer[i], "Size: ");
+ if (buf) {
+ sscanf(buf, "%lu", &memory->modules[curr_mem].size);
+ memory->modules[curr_mem].size *= 1048576; /* It's in MB, we want B */
+ memory->physical_size += memory->modules[curr_mem].size;
+ free(buf);
+ buf = NULL;
+ }
+
+ continue;
+ }
+ /* ignore first useless lines */
+ if (curr_mem < 0) {
+ continue;
+ }
+ }
+
+ free_2d_buffer(&buffer, &buffer_size);
+
+ /* get dmidecode output for memory array */
+ if (run_command("dmidecode -t 19", &buffer, &buffer_size) != 0) {
+ ret = -5;
+ goto done;
+ }
+
+ /* parse information about memory array */
+ short first_array = 1;
+ unsigned long start_addr, end_addr;
+ for (i = 0; i < buffer_size; i++) {
+ /* Starting Address */
+ buf = copy_string_part_after_delim(buffer[i], "Starting Address: ");
+ if (buf) {
+ sscanf(buf, "%lx", &start_addr);
+ if (first_array || start_addr < memory->start_addr) {
+ memory->start_addr = start_addr / 1024; /* in Bytes, we want KB */
+ first_array = 0;
+ }
+ free(buf);
+ buf = NULL;
+ continue;
+ }
+ /* Ending Address */
+ buf = copy_string_part_after_delim(buffer[i], "Ending Address: ");
+ if (buf) {
+ sscanf(buf, "%lx", &end_addr);
+ if (end_addr > memory->end_addr) {
+ memory->end_addr = end_addr / 1024; /* in Bytes, we want KB */
+ }
+ memory->available_size += end_addr - start_addr;
+ free(buf);
+ buf = NULL;
+ continue;
+ }
+ }
+
+ ret = 0;
+
+done:
+ free_2d_buffer(&buffer, &buffer_size);
+
+ if (ret != 0) {
+ dmi_free_memory(memory);
+ }
+
+ return ret;
+}
+
+void dmi_free_memory(DmiMemory *memory)
+{
+ if (memory->modules_nb > 0) {
+ free (memory->modules);
+ }
+ memory->modules_nb = 0;
+ memory->modules = NULL;
+}
diff --git a/src/hardware/dmidecode.h b/src/hardware/dmidecode.h
index 9190ea4..91eda85 100644
--- a/src/hardware/dmidecode.h
+++ b/src/hardware/dmidecode.h
@@ -65,6 +65,20 @@ typedef struct _DmiCpuCache {
char *associativity; /* Cache Associativity */
} DmiCpuCache;
+/* Memory module from dmidecode. */
+typedef struct _DmiMemoryModule {
+ unsigned long size; /* Memory Module Size in Bytes */
+} DmiMemoryModule;
+
+/* Memory from dmidecode. */
+typedef struct _DmiMemory {
+ unsigned long physical_size; /* Physical Memory Size in Bytes */
+ unsigned long available_size; /* Available Memory Size in Bytes */
+ unsigned long start_addr; /* Starting Address of Memory Array in KB */
+ unsigned long end_addr; /* Ending Address of Memory Array in KB */
+ DmiMemoryModule *modules; /* Memory Modules */
+ unsigned modules_nb; /* Number of Memory Modules */
+} DmiMemory;
/*
* Get array of processors according to the dmidecode program.
@@ -98,5 +112,19 @@ short dmi_get_cpu_caches(DmiCpuCache **caches, unsigned *caches_nb);
*/
void dmi_free_cpu_caches(DmiCpuCache **caches, unsigned *caches_nb);
+/*
+ * Get memory structure according to the dmidecode program.
+ * @param memory structure, this function will allocate
+ * necessary memory, but caller is responsible for freeing it
+ * @return 0 if success, negative value otherwise
+ */
+short dmi_get_memory(DmiMemory *memory);
+
+/*
+ * Free memory structure.
+ * @param memory structure
+ */
+void dmi_free_memory(DmiMemory *memory);
+
#endif /* DMIDECODE_H_ */
diff --git a/src/hardware/cpuinfo.c b/src/hardware/procfs.c
index 6634b05..288c8a9 100644
--- a/src/hardware/cpuinfo.c
+++ b/src/hardware/procfs.c
@@ -18,7 +18,7 @@
* Authors: Peter Schiffer <pschiffe@redhat.com>
*/
-#include "cpuinfo.h"
+#include "procfs.h"
/*
@@ -140,3 +140,33 @@ void cpuinfo_free_processor(CpuinfoProcessor *cpu)
return;
}
+
+unsigned long meminfo_get_memory_size()
+{
+ unsigned long ret = 0;
+ unsigned i, buffer_size = 0;
+ char **buffer = NULL, *buf;
+
+ /* read /proc/meminfo file */
+ if (read_file("/proc/meminfo", &buffer, &buffer_size) != 0) {
+ goto done;
+ }
+
+ /* read memory size */
+ for (i = 0; i < buffer_size; i++) {
+ /* memory size */
+ buf = copy_string_part_after_delim(buffer[i], "MemTotal:");
+ if (buf) {
+ sscanf(buf, "%lu", &ret);
+ ret *= 1024; /* it's in kB, we want B */
+ free(buf);
+ buf = NULL;
+ break;
+ }
+ }
+
+done:
+ free_2d_buffer(&buffer, &buffer_size);
+
+ return ret;
+}
diff --git a/src/hardware/cpuinfo.h b/src/hardware/procfs.h
index 5ec5dd5..4bcdf61 100644
--- a/src/hardware/cpuinfo.h
+++ b/src/hardware/procfs.h
@@ -18,8 +18,8 @@
* Authors: Peter Schiffer <pschiffe@redhat.com>
*/
-#ifndef CPUINFO_H_
-#define CPUINFO_H_
+#ifndef PROCFS_H_
+#define PROCFS_H_
#include <stdio.h>
#include <stdlib.h>
@@ -50,5 +50,11 @@ short cpuinfo_get_processor(CpuinfoProcessor *cpu);
*/
void cpuinfo_free_processor(CpuinfoProcessor *cpu);
+/*
+ * Get total memory from /proc/meminfo file.
+ * @return memory size or 0 in case of a problem
+ */
+unsigned long meminfo_get_memory_size();
+
-#endif /* CPUINFO_H_ */
+#endif /* PROCFS_H_ */