diff options
author | Peter Schiffer <pschiffe@redhat.com> | 2013-04-04 19:02:29 +0200 |
---|---|---|
committer | Peter Schiffer <pschiffe@redhat.com> | 2013-04-04 19:02:29 +0200 |
commit | 381f0c0a5cd98a48dc6d5a5e0b98443707d8ea81 (patch) | |
tree | bdad2e739aac00eb02e71dfe7d4074268c6f69a4 /src/hardware/dmidecode.c | |
parent | c47c5c19c5857439db30e40d4a691f5b700adf5f (diff) | |
download | openlmi-providers-381f0c0a5cd98a48dc6d5a5e0b98443707d8ea81.tar.gz openlmi-providers-381f0c0a5cd98a48dc6d5a5e0b98443707d8ea81.tar.xz openlmi-providers-381f0c0a5cd98a48dc6d5a5e0b98443707d8ea81.zip |
Hardware: Added Processor Cache Memory Provider
New Providers:
* LMI_ProcessorCacheMemoryProvider
* LMI_AssociatedProcessorCacheMemoryProvider
Other Changes:
* Optimized usage of string constats
* Fixed wrong usage of pointers in dmidecode.c
* Filled unknown mandatory fields in providers with "Unknown" value
* Replaced hard coded numbers with LMI constants
* Minor optimization - don't gather data which won't be used
Diffstat (limited to 'src/hardware/dmidecode.c')
-rw-r--r-- | src/hardware/dmidecode.c | 427 |
1 files changed, 372 insertions, 55 deletions
diff --git a/src/hardware/dmidecode.c b/src/hardware/dmidecode.c index 14e4ac9..a50aa8a 100644 --- a/src/hardware/dmidecode.c +++ b/src/hardware/dmidecode.c @@ -21,6 +21,10 @@ #include "dmidecode.h" +/****************************************************************************** + * DmiProcessor + */ + /* * Initialize DmiProcessor attributes. * @param cpu @@ -42,6 +46,9 @@ void init_dmiprocessor_struct(DmiProcessor *cpu) cpu->upgrade = NULL; cpu->charact_nb = 0; cpu->characteristics = NULL; + cpu->l1_cache_handle = NULL; + cpu->l2_cache_handle = NULL; + cpu->l3_cache_handle = NULL; } /* @@ -95,6 +102,24 @@ short check_dmiprocessor_attributes(DmiProcessor *cpu) goto done; } } + if (!cpu->l1_cache_handle) { + if (!(cpu->l1_cache_handle = strdup(""))) { + ret = -9; + goto done; + } + } + if (!cpu->l2_cache_handle) { + if (!(cpu->l2_cache_handle = strdup(""))) { + ret = -10; + goto done; + } + } + if (!cpu->l3_cache_handle) { + if (!(cpu->l3_cache_handle = strdup(""))) { + ret = -11; + goto done; + } + } ret = 0; @@ -147,7 +172,7 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) for (i = 0; i < buffer_size; i++) { if (strncmp(buffer[i], "Handle 0x", 9) == 0) { curr_cpu++; - init_dmiprocessor_struct(cpus[curr_cpu]); + init_dmiprocessor_struct(&(*cpus)[curr_cpu]); continue; } /* ignore first useless lines */ @@ -157,28 +182,28 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) /* ID */ buf = copy_string_part_after_delim(buffer[i], "ID: "); if (buf) { - cpus[curr_cpu]->id = buf; + (*cpus)[curr_cpu].id = buf; buf = NULL; continue; } /* Family */ buf = copy_string_part_after_delim(buffer[i], "Family: "); if (buf) { - cpus[curr_cpu]->family = buf; + (*cpus)[curr_cpu].family = buf; buf = NULL; continue; } /* Status */ buf = copy_string_part_after_delim(buffer[i], "Status: Populated, "); if (buf) { - cpus[curr_cpu]->status = buf; + (*cpus)[curr_cpu].status = buf; buf = NULL; continue; } /* Current Speed */ buf = copy_string_part_after_delim(buffer[i], "Current Speed: "); if (buf && strcmp(buf, "Unknown") != 0) { - sscanf(buf, "%u", &cpus[curr_cpu]->current_speed); + sscanf(buf, "%u", &(*cpus)[curr_cpu].current_speed); free(buf); buf = NULL; continue; @@ -186,7 +211,7 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) /* Max Speed */ buf = copy_string_part_after_delim(buffer[i], "Max Speed: "); if (buf && strcmp(buf, "Unknown") != 0) { - sscanf(buf, "%u", &cpus[curr_cpu]->max_speed); + sscanf(buf, "%u", &(*cpus)[curr_cpu].max_speed); free(buf); buf = NULL; continue; @@ -194,7 +219,7 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) /* External Clock Speed */ buf = copy_string_part_after_delim(buffer[i], "External Clock: "); if (buf && strcmp(buf, "Unknown") != 0) { - sscanf(buf, "%u", &cpus[curr_cpu]->external_clock); + sscanf(buf, "%u", &(*cpus)[curr_cpu].external_clock); free(buf); buf = NULL; continue; @@ -202,14 +227,14 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) /* CPU Name */ buf = copy_string_part_after_delim(buffer[i], "Version: "); if (buf) { - cpus[curr_cpu]->name = buf; + (*cpus)[curr_cpu].name = buf; buf = NULL; continue; } /* Cores */ buf = copy_string_part_after_delim(buffer[i], "Core Count: "); if (buf) { - sscanf(buf, "%u", &cpus[curr_cpu]->cores); + sscanf(buf, "%u", &(*cpus)[curr_cpu].cores); free(buf); buf = NULL; continue; @@ -217,7 +242,7 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) /* Enabled Cores */ buf = copy_string_part_after_delim(buffer[i], "Core Enabled: "); if (buf) { - sscanf(buf, "%u", &cpus[curr_cpu]->enabled_cores); + sscanf(buf, "%u", &(*cpus)[curr_cpu].enabled_cores); free(buf); buf = NULL; continue; @@ -225,7 +250,7 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) /* Threads */ buf = copy_string_part_after_delim(buffer[i], "Thread Count: "); if (buf) { - sscanf(buf, "%u", &cpus[curr_cpu]->threads); + sscanf(buf, "%u", &(*cpus)[curr_cpu].threads); free(buf); buf = NULL; continue; @@ -233,21 +258,42 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) /* CPU Type/Role */ buf = copy_string_part_after_delim(buffer[i], "Type: "); if (buf) { - cpus[curr_cpu]->type = buf; + (*cpus)[curr_cpu].type = buf; buf = NULL; continue; } /* Stepping */ buf = copy_string_part_after_delim(buffer[i], ", Stepping "); if (buf) { - cpus[curr_cpu]->stepping = buf; + (*cpus)[curr_cpu].stepping = buf; buf = NULL; continue; } /* Upgrade */ buf = copy_string_part_after_delim(buffer[i], "Upgrade: "); if (buf) { - cpus[curr_cpu]->upgrade = buf; + (*cpus)[curr_cpu].upgrade = buf; + buf = NULL; + continue; + } + /* Level 1 Cache Handle */ + buf = copy_string_part_after_delim(buffer[i], "L1 Cache Handle: "); + if (buf) { + (*cpus)[curr_cpu].l1_cache_handle = buf; + buf = NULL; + continue; + } + /* Level 2 Cache Handle */ + buf = copy_string_part_after_delim(buffer[i], "L2 Cache Handle: "); + if (buf) { + (*cpus)[curr_cpu].l2_cache_handle = buf; + buf = NULL; + continue; + } + /* Level 3 Cache Handle */ + buf = copy_string_part_after_delim(buffer[i], "L3 Cache Handle: "); + if (buf) { + (*cpus)[curr_cpu].l3_cache_handle = buf; buf = NULL; continue; } @@ -255,27 +301,27 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) if (strstr(buffer[i], "Characteristics:") && !strstr(buffer[i], "Characteristics: ")) { /* count characteristics */ - cpus[curr_cpu]->charact_nb = 0; - while (strlen(buffer[i + cpus[curr_cpu]->charact_nb + 1])) { - cpus[curr_cpu]->charact_nb += 1; + (*cpus)[curr_cpu].charact_nb = 0; + while (strlen(buffer[i + (*cpus)[curr_cpu].charact_nb + 1])) { + (*cpus)[curr_cpu].charact_nb += 1; } /* allocate memory */ - cpus[curr_cpu]->characteristics = - (char **)calloc(cpus[curr_cpu]->charact_nb, sizeof(char *)); - if (!cpus[curr_cpu]->characteristics) { + (*cpus)[curr_cpu].characteristics = + (char **)calloc((*cpus)[curr_cpu].charact_nb, sizeof(char *)); + if (!(*cpus)[curr_cpu].characteristics) { warn("Failed to allocate memory."); ret = -5; goto done; } unsigned j; char *tmp_line; - for (j = 0; j < cpus[curr_cpu]->charact_nb; j++) { + for (j = 0; j < (*cpus)[curr_cpu].charact_nb; j++) { tmp_line = trim(buffer[i + j + 1], NULL); if (tmp_line) { - cpus[curr_cpu]->characteristics[j] = tmp_line; + (*cpus)[curr_cpu].characteristics[j] = tmp_line; } else { - cpus[curr_cpu]->characteristics[j] = strdup(""); - if (!cpus[curr_cpu]->characteristics[j]) { + (*cpus)[curr_cpu].characteristics[j] = strdup(""); + if (!(*cpus)[curr_cpu].characteristics[j]) { warn("Failed to allocate memory."); ret = -6; goto done; @@ -283,13 +329,13 @@ short dmi_get_processors(DmiProcessor **cpus, unsigned *cpus_nb) } } /* skip characteristics and newline after them */ - i += cpus[curr_cpu]->charact_nb + 1; + i += (*cpus)[curr_cpu].charact_nb + 1; } } /* fill in default attributes if needed */ for (i = 0; i < *cpus_nb; i++) { - if (check_dmiprocessor_attributes(cpus[i]) != 0) { + if (check_dmiprocessor_attributes(&(*cpus)[i]) != 0) { ret = -7; goto done; } @@ -313,45 +359,57 @@ void dmi_free_processors(DmiProcessor **cpus, unsigned *cpus_nb) if (*cpus_nb > 0) { for (i = 0; i < *cpus_nb; i++) { - if (cpus[i]->id) { - free(cpus[i]->id); + if ((*cpus)[i].id) { + free((*cpus)[i].id); } - cpus[i]->id = NULL; - if (cpus[i]->family) { - free(cpus[i]->family); + (*cpus)[i].id = NULL; + if ((*cpus)[i].family) { + free((*cpus)[i].family); } - cpus[i]->family = NULL; - if (cpus[i]->status) { - free(cpus[i]->status); + (*cpus)[i].family = NULL; + if ((*cpus)[i].status) { + free((*cpus)[i].status); } - cpus[i]->status = NULL; - if (cpus[i]->name) { - free(cpus[i]->name); + (*cpus)[i].status = NULL; + if ((*cpus)[i].name) { + free((*cpus)[i].name); } - cpus[i]->name = NULL; - if (cpus[i]->type) { - free(cpus[i]->type); + (*cpus)[i].name = NULL; + if ((*cpus)[i].type) { + free((*cpus)[i].type); } - cpus[i]->type = NULL; - if (cpus[i]->stepping) { - free(cpus[i]->stepping); + (*cpus)[i].type = NULL; + if ((*cpus)[i].stepping) { + free((*cpus)[i].stepping); } - cpus[i]->stepping = NULL; - if (cpus[i]->upgrade) { - free(cpus[i]->upgrade); + (*cpus)[i].stepping = NULL; + if ((*cpus)[i].upgrade) { + free((*cpus)[i].upgrade); } - cpus[i]->upgrade = NULL; - if (cpus[i]->charact_nb > 0) { - for (j = 0; j < cpus[i]->charact_nb; j++) { - if (cpus[i]->characteristics[j]) { - free(cpus[i]->characteristics[j]); + (*cpus)[i].upgrade = NULL; + if ((*cpus)[i].charact_nb > 0) { + for (j = 0; j < (*cpus)[i].charact_nb; j++) { + if ((*cpus)[i].characteristics[j]) { + free((*cpus)[i].characteristics[j]); } - cpus[i]->characteristics[j] = NULL; + (*cpus)[i].characteristics[j] = NULL; } - free(cpus[i]->characteristics); + free((*cpus)[i].characteristics); + } + (*cpus)[i].charact_nb = 0; + (*cpus)[i].characteristics = NULL; + if ((*cpus)[i].l1_cache_handle) { + free((*cpus)[i].l1_cache_handle); + } + (*cpus)[i].l1_cache_handle = NULL; + if ((*cpus)[i].l2_cache_handle) { + free((*cpus)[i].l2_cache_handle); } - cpus[i]->charact_nb = 0; - cpus[i]->characteristics = NULL; + (*cpus)[i].l2_cache_handle = NULL; + if ((*cpus)[i].l3_cache_handle) { + free((*cpus)[i].l3_cache_handle); + } + (*cpus)[i].l3_cache_handle = NULL; } free (*cpus); } @@ -359,3 +417,262 @@ void dmi_free_processors(DmiProcessor **cpus, unsigned *cpus_nb) *cpus_nb = 0; *cpus = NULL; } + + +/****************************************************************************** + * DmiCpuCache + */ + +/* + * Initialize DmiCpuCache attributes. + * @param cache + */ +void init_dmi_cpu_cache_struct(DmiCpuCache *cache) +{ + cache->id = NULL; + cache->size = 0; + cache->name = NULL; + cache->status = NULL; + cache->level = 0; + cache->op_mode = NULL; + cache->type = NULL; + cache->associativity = NULL; +} + +/* + * Check attributes of cache structure and fill in defaults if needed. + * @param cache + * @return 0 if success, negative value otherwise + */ +short check_dmi_cpu_cache_attributes(DmiCpuCache *cache) +{ + short ret = -1; + + if (!cache->id) { + if (!(cache->id = strdup(""))) { + ret = -2; + goto done; + } + } + if (!cache->name) { + if (!(cache->name = strdup(""))) { + ret = -3; + goto done; + } + } + if (!cache->status) { + if (!(cache->status = strdup(""))) { + ret = -4; + goto done; + } + } + if (!cache->op_mode) { + if (!(cache->op_mode = strdup("Unknown"))) { + ret = -5; + goto done; + } + } + if (!cache->type) { + if (!(cache->type = strdup("Unknown"))) { + ret = -6; + goto done; + } + } + if (!cache->associativity) { + if (!(cache->associativity = strdup("Unknown"))) { + ret = -7; + goto done; + } + } + + ret = 0; + +done: + if (ret != 0) { + warn("Failed to allocate memory."); + } + + return ret; +} + +short dmi_get_cpu_caches(DmiCpuCache **caches, unsigned *caches_nb) +{ + short ret = -1; + int curr_cache = -1; + unsigned i, buffer_size = 0; + char **buffer = NULL, *buf; + + *caches_nb = 0; + + /* get dmidecode output */ + if (run_command("dmidecode -t 7", &buffer, &buffer_size) != 0) { + ret = -2; + goto done; + } + + /* count caches */ + for (i = 0; i < buffer_size; i++) { + if (strncmp(buffer[i], "Handle 0x", 9) == 0) { + (*caches_nb)++; + } + } + + /* if no cache was found */ + if (*caches_nb < 1) { + warn("Dmidecode didn't recognize any processor cache memory."); + ret = -3; + goto done; + } + + /* allocate memory for caches */ + *caches = (DmiCpuCache *)calloc(*caches_nb, sizeof(DmiCpuCache)); + if (!(*caches)) { + warn("Failed to allocate memory."); + ret = -4; + goto done; + } + + /* parse information about cache */ + for (i = 0; i < buffer_size; i++) { + if (strncmp(buffer[i], "Handle 0x", 9) == 0) { + curr_cache++; + init_dmi_cpu_cache_struct(&(*caches)[curr_cache]); + + /* Cache ID is it's handle */ + char *id_start = buffer[i] + 7; + char *id_end = strchr(buffer[i], ','); + if (!id_end) { + warn("Unrecognized output from dmidecode program."); + ret = -5; + goto done; + } + (*caches)[curr_cache].id = strndup(id_start, id_end - id_start); + if (!(*caches)[curr_cache].id) { + warn("Failed to allocate memory."); + ret = -6; + goto done; + } + + continue; + } + /* ignore first useless lines */ + if (curr_cache < 0) { + continue; + } + /* Cache Name */ + buf = copy_string_part_after_delim(buffer[i], "Socket Designation: "); + if (buf) { + (*caches)[curr_cache].name = buf; + buf = NULL; + continue; + } + /* Cache Status and Level */ + buf = copy_string_part_after_delim(buffer[i], "Configuration: "); + if (buf) { + char **confs = NULL; + unsigned confs_len = 0; + if (explode(buf, ",", &confs, &confs_len) != 0 || + confs_len < 3) { + free_2d_buffer(&confs, &confs_len); + free(buf); + buf = NULL; + continue; + } + + (*caches)[curr_cache].status = trim(confs[0], NULL); + sscanf(confs[2], "%*s %u", &(*caches)[curr_cache].level); + + free_2d_buffer(&confs, &confs_len); + free(buf); + buf = NULL; + continue; + } + /* Cache Operational Mode */ + buf = copy_string_part_after_delim(buffer[i], "Operational Mode: "); + if (buf) { + (*caches)[curr_cache].op_mode = buf; + buf = NULL; + continue; + } + /* Cache Size */ + buf = copy_string_part_after_delim(buffer[i], "Installed Size: "); + if (buf) { + sscanf(buf, "%u", &(*caches)[curr_cache].size); + (*caches)[curr_cache].size *= 1024; /* It's in kB, we want B */ + free(buf); + buf = NULL; + continue; + } + /* Cache Type */ + buf = copy_string_part_after_delim(buffer[i], "System Type: "); + if (buf) { + (*caches)[curr_cache].type = buf; + buf = NULL; + continue; + } + /* Cache Associativity */ + buf = copy_string_part_after_delim(buffer[i], "Associativity: "); + if (buf) { + (*caches)[curr_cache].associativity = buf; + buf = NULL; + continue; + } + } + + /* fill in default attributes if needed */ + for (i = 0; i < *caches_nb; i++) { + if (check_dmi_cpu_cache_attributes(&(*caches)[i]) != 0) { + ret = -7; + goto done; + } + } + + ret = 0; + +done: + free_2d_buffer(&buffer, &buffer_size); + + if (ret != 0) { + dmi_free_cpu_caches(caches, caches_nb); + } + + return ret; +} + +void dmi_free_cpu_caches(DmiCpuCache **caches, unsigned *caches_nb) +{ + unsigned i; + + if (*caches_nb > 0) { + for (i = 0; i < *caches_nb; i++) { + if ((*caches)[i].id) { + free((*caches)[i].id); + } + (*caches)[i].id = NULL; + if ((*caches)[i].name) { + free((*caches)[i].name); + } + (*caches)[i].name = NULL; + if ((*caches)[i].status) { + free((*caches)[i].status); + } + (*caches)[i].status = NULL; + if ((*caches)[i].op_mode) { + free((*caches)[i].op_mode); + } + (*caches)[i].op_mode = NULL; + if ((*caches)[i].type) { + free((*caches)[i].type); + } + (*caches)[i].type = NULL; + if ((*caches)[i].associativity) { + free((*caches)[i].associativity); + } + (*caches)[i].associativity = NULL; + } + free (*caches); + } + + *caches_nb = 0; + *caches = NULL; +} |