diff options
author | Peter Schiffer <pschiffe@redhat.com> | 2013-04-23 15:43:40 +0200 |
---|---|---|
committer | Peter Schiffer <pschiffe@redhat.com> | 2013-04-23 15:43:40 +0200 |
commit | 1e4187b50657065445a33148bfb2224005fb0dff (patch) | |
tree | be2a363d74215eab1c98be2776b408dfc98cff23 /src/hardware/dmidecode.c | |
parent | e229f6f4752c30c4fb48c429174f81bbda02242d (diff) | |
download | openlmi-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.c | 272 |
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; |