summaryrefslogtreecommitdiffstats
path: root/src/hardware/dmidecode.c
diff options
context:
space:
mode:
authorPeter Schiffer <pschiffe@redhat.com>2013-04-23 15:43:40 +0200
committerPeter Schiffer <pschiffe@redhat.com>2013-04-23 15:43:40 +0200
commit1e4187b50657065445a33148bfb2224005fb0dff (patch)
treebe2a363d74215eab1c98be2776b408dfc98cff23 /src/hardware/dmidecode.c
parente229f6f4752c30c4fb48c429174f81bbda02242d (diff)
downloadopenlmi-providers-1e4187b50657065445a33148bfb2224005fb0dff.tar.gz
openlmi-providers-1e4187b50657065445a33148bfb2224005fb0dff.tar.xz
openlmi-providers-1e4187b50657065445a33148bfb2224005fb0dff.zip
Hardware: Added Physical Memory Provider
New Providers: * LMI_PhysicalMemoryProvider * LMI_PhysicalMemoryRealizesProvider Other Changes: * Fixed InstanceID in hardware to match the rest of the providers * Removed some unused variables
Diffstat (limited to 'src/hardware/dmidecode.c')
-rw-r--r--src/hardware/dmidecode.c272
1 files changed, 256 insertions, 16 deletions
diff --git a/src/hardware/dmidecode.c b/src/hardware/dmidecode.c
index 367a08c..f034b56 100644
--- a/src/hardware/dmidecode.c
+++ b/src/hardware/dmidecode.c
@@ -719,14 +719,80 @@ void init_dmi_memory_struct(DmiMemory *memory)
void init_dmi_memory_module_struct(DmiMemoryModule *mem)
{
mem->size = 0;
+ mem->serial_number = NULL;
+ mem->form_factor = NULL;
+ mem->type = NULL;
+ mem->slot = -1;
+ mem->speed_time = 0;
+ mem->bank_label = NULL;
+ mem->name = NULL;
+ mem->manufacturer = NULL;
+ mem->part_number = NULL;
+ mem->speed_clock = 0;
+ mem->data_width = 0;
+ mem->total_width = 0;
+}
+
+/*
+ * Check attributes of memory structure and fill in defaults if needed.
+ * @param memory
+ * @return 0 if success, negative value otherwise
+ */
+short check_dmi_memory_attributes(DmiMemory *memory)
+{
+ short ret = -1;
+ unsigned i;
+
+ for (i = 0; i < memory->modules_nb; i++) {
+ if (!memory->modules[i].serial_number) {
+ if (!(memory->modules[i].serial_number = strdup(""))) {
+ ret = -2;
+ goto done;
+ }
+ if (!(memory->modules[i].form_factor = strdup("Unknown"))) {
+ ret = -3;
+ goto done;
+ }
+ if (!(memory->modules[i].type = strdup("Unknown"))) {
+ ret = -4;
+ goto done;
+ }
+ if (!(memory->modules[i].bank_label = strdup(""))) {
+ ret = -5;
+ goto done;
+ }
+ if (!(memory->modules[i].name = strdup("Memory Module"))) {
+ ret = -6;
+ goto done;
+ }
+ if (!(memory->modules[i].manufacturer = strdup(""))) {
+ ret = -7;
+ goto done;
+ }
+ if (!(memory->modules[i].part_number = strdup(""))) {
+ ret = -8;
+ goto done;
+ }
+ }
+ }
+
+ ret = 0;
+
+done:
+ if (ret != 0) {
+ warn("Failed to allocate memory.");
+ }
+
+ return ret;
}
short dmi_get_memory(DmiMemory *memory)
{
short ret = -1;
- int curr_mem = -1;
- unsigned i, buffer_size = 0;
- char **buffer = NULL, *buf;
+ int curr_mem = -1, last_mem = -1, slot = -1;
+ unsigned i, j, buffer_size = 0, data_width = 0, total_width = 0;
+ unsigned long memory_size;
+ char **buffer = NULL, *buf, *str_format;
init_dmi_memory_struct(memory);
@@ -761,34 +827,184 @@ short dmi_get_memory(DmiMemory *memory)
/* 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]);
+ /* Total Width */
+ buf = copy_string_part_after_delim(buffer[i], "Total Width: ");
+ if (buf) {
+ sscanf(buf, "%u", &total_width);
+ free(buf);
+ buf = NULL;
+ continue;
+ }
+ /* Memory Module Data Width */
+ buf = copy_string_part_after_delim(buffer[i], "Data Width: ");
+ if (buf) {
+ sscanf(buf, "%u", &data_width);
+ free(buf);
+ buf = NULL;
+ continue;
+ }
+ if (strstr(buffer[i], "Size: ")) {
+ if (strstr(buffer[i], "Size: No Module Installed")) {
+ last_mem = curr_mem;
+ curr_mem = -1;
+ continue;
+ } else {
+ curr_mem = last_mem + 1;
+ 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;
+ }
+ /*Pretty, human readable module name */
+ if (memory->modules[curr_mem].size >= 1073741824) {
+ memory_size = memory->modules[curr_mem].size / 1073741824;
+ str_format = "%lu GB Memory Module";
+ } else {
+ memory_size = memory->modules[curr_mem].size / 1048576;
+ str_format = "%lu MB Memory Module";
+ }
+ if (asprintf(&memory->modules[curr_mem].name, str_format, memory_size) < 0) {
+ memory->modules[curr_mem].name = NULL;
+ warn("Failed to allocate memory.");
+ ret = -5;
+ goto done;
+ }
+
+ memory->modules[curr_mem].total_width = total_width;
+ memory->modules[curr_mem].data_width = data_width;
+ total_width = 0;
+ data_width = 0;
- /* Module Size */
- buf = copy_string_part_after_delim(buffer[i], "Size: ");
+ continue;
+ }
+ }
+ /* ignore useless lines */
+ if (curr_mem < 0) {
+ continue;
+ }
+ /* Serial Number */
+ buf = copy_string_part_after_delim(buffer[i], "Serial Number: ");
+ if (buf) {
+ if (strcmp(buf, "Not Specified") != 0) {
+ memory->modules[curr_mem].serial_number = buf;
+ buf = NULL;
+ } else {
+ free(buf);
+ buf = NULL;
+ if (asprintf(&memory->modules[curr_mem].serial_number, "%u", curr_mem) < 0) {
+ memory->modules[curr_mem].serial_number = NULL;
+ warn("Failed to allocate memory.");
+ ret = -6;
+ goto done;
+ }
+ }
+ continue;
+ }
+ if (!strstr(buffer[i], "Bank Locator:")) {
+ /* Slot */
+ buf = copy_string_part_after_delim(buffer[i], "Locator: ");
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;
+ sscanf(buf, "%*s %d", &memory->modules[curr_mem].slot);
free(buf);
buf = NULL;
+ continue;
}
+ } else {
+ /* Memory Module Bank Label */
+ buf = copy_string_part_after_delim(buffer[i], "Bank Locator: ");
+ if (buf) {
+ memory->modules[curr_mem].bank_label = buf;
+ buf = NULL;
+ continue;
+ }
+ }
+ /* Form Factor */
+ buf = copy_string_part_after_delim(buffer[i], "Form Factor: ");
+ if (buf) {
+ memory->modules[curr_mem].form_factor = buf;
+ buf = NULL;
+ continue;
+ }
+ /* Memory Module Type */
+ buf = copy_string_part_after_delim(buffer[i], "Type: ");
+ if (buf) {
+ memory->modules[curr_mem].type = buf;
+ buf = NULL;
+ continue;
+ }
+ /* Manufacturer */
+ buf = copy_string_part_after_delim(buffer[i], "Manufacturer: ");
+ if (buf) {
+ memory->modules[curr_mem].manufacturer = buf;
+ buf = NULL;
+ continue;
+ }
+ /* Part Number */
+ buf = copy_string_part_after_delim(buffer[i], "Part Number: ");
+ if (buf) {
+ memory->modules[curr_mem].part_number = buf;
+ buf = NULL;
+ continue;
+ }
+ /* Speed in MHz */
+ buf = copy_string_part_after_delim(buffer[i], "Speed: ");
+ if (buf) {
+ sscanf(buf, "%u", &memory->modules[curr_mem].speed_clock);
+ free(buf);
+ buf = NULL;
+ continue;
+ }
+ }
+
+ free_2d_buffer(&buffer, &buffer_size);
+ /* get additional dmidecode output for memory modules */
+ if (run_command("dmidecode -t 6", &buffer, &buffer_size) != 0) {
+ ret = -7;
+ goto done;
+ }
+
+ /* parse additional information about modules */
+ for (i = 0; i < buffer_size; i++) {
+ /* Slot */
+ buf = copy_string_part_after_delim(buffer[i], "Socket Designation: ");
+ if (buf) {
+ sscanf(buf, "%*s %*s %d", &slot);
+ free(buf);
+ buf = NULL;
continue;
}
- /* ignore first useless lines */
- if (curr_mem < 0) {
+ /* ignore useless lines */
+ if (slot < 0) {
continue;
}
+ /* Memory Speed */
+ buf = copy_string_part_after_delim(buffer[i], "Current Speed: ");
+ if (buf) {
+ if (slot != -1) {
+ for (j = 0; j < memory->modules_nb; j++) {
+ if (memory->modules[j].slot == slot) {
+ sscanf(buf, "%u", &memory->modules[j].speed_time);
+ break;
+ }
+ }
+ }
+ free(buf);
+ buf = NULL;
+ slot = -1;
+ }
}
free_2d_buffer(&buffer, &buffer_size);
/* get dmidecode output for memory array */
if (run_command("dmidecode -t 19", &buffer, &buffer_size) != 0) {
- ret = -5;
+ ret = -8;
goto done;
}
@@ -822,6 +1038,12 @@ short dmi_get_memory(DmiMemory *memory)
}
}
+ /* fill in default attributes if needed */
+ if (check_dmi_memory_attributes(memory) != 0) {
+ ret = -9;
+ goto done;
+ }
+
ret = 0;
done:
@@ -836,8 +1058,26 @@ done:
void dmi_free_memory(DmiMemory *memory)
{
+ unsigned i;
+
if (memory->modules_nb > 0) {
- free (memory->modules);
+ for (i = 0; i < memory->modules_nb; i++) {
+ free(memory->modules[i].serial_number);
+ memory->modules[i].serial_number = NULL;
+ free(memory->modules[i].form_factor);
+ memory->modules[i].form_factor = NULL;
+ free(memory->modules[i].type);
+ memory->modules[i].type = NULL;
+ free(memory->modules[i].bank_label);
+ memory->modules[i].bank_label = NULL;
+ free(memory->modules[i].name);
+ memory->modules[i].name = NULL;
+ free(memory->modules[i].manufacturer);
+ memory->modules[i].manufacturer = NULL;
+ free(memory->modules[i].part_number);
+ memory->modules[i].part_number = NULL;
+ }
+ free(memory->modules);
}
memory->modules_nb = 0;
memory->modules = NULL;