diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c | 130 | ||||
-rw-r--r-- | src/hardware/LMI_ProcessorProvider.c | 1 | ||||
-rw-r--r-- | src/hardware/dmidecode.c | 23 | ||||
-rw-r--r-- | src/hardware/sysfs.c | 78 | ||||
-rw-r--r-- | src/hardware/sysfs.h | 2 | ||||
-rw-r--r-- | src/hardware/utils.c | 46 | ||||
-rw-r--r-- | src/hardware/utils.h | 11 |
7 files changed, 217 insertions, 74 deletions
diff --git a/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c b/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c index 3d06a65..6310ea9 100644 --- a/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c +++ b/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c @@ -89,8 +89,8 @@ static CMPIStatus LMI_AssociatedProcessorCacheMemoryEnumInstances( dmi_free_cpu_caches(&dmi_cpu_caches, &dmi_cpu_caches_nb); } - /* if we don't have dmidecode data */ - if (dmi_cpus_nb < 1 || dmi_cpu_caches_nb < 1) { + /* without dmi cpus, we can't use dmi cache */ + if (dmi_cpus_nb < 1) { dmi_free_processors(&dmi_cpus, &dmi_cpus_nb); dmi_free_cpu_caches(&dmi_cpu_caches, &dmi_cpu_caches_nb); @@ -104,6 +104,15 @@ static CMPIStatus LMI_AssociatedProcessorCacheMemoryEnumInstances( error_msg = "Unable to get processor cache information."; goto done; } + } else if (dmi_cpu_caches_nb < 1) { + /* but we can do OK with dmi cpu and no dmi cache */ + dmi_free_cpu_caches(&dmi_cpu_caches, &dmi_cpu_caches_nb); + + if (sysfs_get_cpu_caches(&sysfs_cpu_caches, &sysfs_cpu_caches_nb) != 0 + || sysfs_cpu_caches_nb < 1) { + error_msg = "Unable to get processor cache information."; + goto done; + } } if (dmi_cpus_nb > 0) { @@ -115,7 +124,7 @@ static CMPIStatus LMI_AssociatedProcessorCacheMemoryEnumInstances( goto done; } - /* if we have cpus and caches from dmidecode */ + /* if we have cpus and caches from dmidecode; */ /* in this case, we can match exactly cpus and caches */ if (dmi_cpus_nb > 0 && dmi_cpu_caches_nb > 0) { /* loop cpus */ @@ -198,8 +207,7 @@ static CMPIStatus LMI_AssociatedProcessorCacheMemoryEnumInstances( } } } else { - /* in this case, we match every cache to every cpu, assuming all the */ - /* cpus are the same */ + /* in this case, we have all caches for every cpu */ /* loop caches */ for (i = 0; i < sysfs_cpu_caches_nb; i++) { LMI_AssociatedProcessorCacheMemory_Init(&lmi_assoc_cache, _cb, ns); @@ -214,71 +222,71 @@ static CMPIStatus LMI_AssociatedProcessorCacheMemoryEnumInstances( LMI_ProcessorCacheMemoryRef_Set_DeviceID(&lmi_cpu_cache, sysfs_cpu_caches[i].id); - /* loop cpus */ - for (j = 0; j < cpus_nb; j++) { - LMI_ProcessorRef_Init(&lmi_cpu, _cb, ns); - LMI_ProcessorRef_Set_SystemCreationClassName(&lmi_cpu, - get_system_creation_class_name()); - LMI_ProcessorRef_Set_SystemName(&lmi_cpu, get_system_name()); - LMI_ProcessorRef_Set_CreationClassName(&lmi_cpu, - ORGID "_" CPU_CLASS_NAME); - - if (dmi_cpus_nb > 0) { - LMI_ProcessorRef_Set_DeviceID(&lmi_cpu, dmi_cpus[j].id); - } else { - char cpu_id[LONG_INT_LEN] = ""; - snprintf(cpu_id, LONG_INT_LEN, "%u", j); - LMI_ProcessorRef_Set_DeviceID(&lmi_cpu, cpu_id); - } + /* determine the right CPU index */ + j = i / (sysfs_cpu_caches_nb / cpus_nb); - LMI_AssociatedProcessorCacheMemory_Set_Dependent( - &lmi_assoc_cache, &lmi_cpu); - LMI_AssociatedProcessorCacheMemory_Set_Antecedent( - &lmi_assoc_cache, &lmi_cpu_cache); - - cache_level = get_cache_level(sysfs_cpu_caches[i].level); - if (cache_level == LMI_AssociatedProcessorCacheMemory_Level_Other) { - char other_level[LONG_INT_LEN]; - snprintf(other_level, LONG_INT_LEN, "%u", - sysfs_cpu_caches[i].level); - LMI_AssociatedProcessorCacheMemory_Set_OtherLevelDescription( - &lmi_assoc_cache, other_level); - } - cache_type = get_cache_type(sysfs_cpu_caches[i].type); - if (cache_type == LMI_AssociatedProcessorCacheMemory_CacheType_Other) { - LMI_AssociatedProcessorCacheMemory_Set_OtherCacheTypeDescription( - &lmi_assoc_cache, sysfs_cpu_caches[i].type); - } + LMI_ProcessorRef_Init(&lmi_cpu, _cb, ns); + LMI_ProcessorRef_Set_SystemCreationClassName(&lmi_cpu, + get_system_creation_class_name()); + LMI_ProcessorRef_Set_SystemName(&lmi_cpu, get_system_name()); + LMI_ProcessorRef_Set_CreationClassName(&lmi_cpu, + ORGID "_" CPU_CLASS_NAME); - LMI_AssociatedProcessorCacheMemory_Set_Level( - &lmi_assoc_cache, cache_level); - LMI_AssociatedProcessorCacheMemory_Set_CacheType( - &lmi_assoc_cache, cache_type); - LMI_AssociatedProcessorCacheMemory_Set_Associativity( - &lmi_assoc_cache, - get_cache_associativity_sysfs( - sysfs_cpu_caches[i].ways_of_assoc)); - - LMI_AssociatedProcessorCacheMemory_Set_WritePolicy( - &lmi_assoc_cache, - LMI_AssociatedProcessorCacheMemory_WritePolicy_Unknown); - LMI_AssociatedProcessorCacheMemory_Set_ReadPolicy( - &lmi_assoc_cache, - LMI_AssociatedProcessorCacheMemory_ReadPolicy_Unknown); - - if (sysfs_cpu_caches[i].line_size) { - LMI_AssociatedProcessorCacheMemory_Set_LineSize( - &lmi_assoc_cache, sysfs_cpu_caches[i].line_size); - } + if (dmi_cpus_nb > 0) { + LMI_ProcessorRef_Set_DeviceID(&lmi_cpu, dmi_cpus[j].id); + } else { + char cpu_id[LONG_INT_LEN] = ""; + snprintf(cpu_id, LONG_INT_LEN, "%u", j); + LMI_ProcessorRef_Set_DeviceID(&lmi_cpu, cpu_id); + } - KReturnInstance(cr, lmi_assoc_cache); + LMI_AssociatedProcessorCacheMemory_Set_Dependent( + &lmi_assoc_cache, &lmi_cpu); + LMI_AssociatedProcessorCacheMemory_Set_Antecedent( + &lmi_assoc_cache, &lmi_cpu_cache); + + cache_level = get_cache_level(sysfs_cpu_caches[i].level); + if (cache_level == LMI_AssociatedProcessorCacheMemory_Level_Other) { + char other_level[LONG_INT_LEN]; + snprintf(other_level, LONG_INT_LEN, "%u", + sysfs_cpu_caches[i].level); + LMI_AssociatedProcessorCacheMemory_Set_OtherLevelDescription( + &lmi_assoc_cache, other_level); + } + cache_type = get_cache_type(sysfs_cpu_caches[i].type); + if (cache_type == LMI_AssociatedProcessorCacheMemory_CacheType_Other) { + LMI_AssociatedProcessorCacheMemory_Set_OtherCacheTypeDescription( + &lmi_assoc_cache, sysfs_cpu_caches[i].type); } + + LMI_AssociatedProcessorCacheMemory_Set_Level( + &lmi_assoc_cache, cache_level); + LMI_AssociatedProcessorCacheMemory_Set_CacheType( + &lmi_assoc_cache, cache_type); + LMI_AssociatedProcessorCacheMemory_Set_Associativity( + &lmi_assoc_cache, + get_cache_associativity_sysfs( + sysfs_cpu_caches[i].ways_of_assoc)); + + LMI_AssociatedProcessorCacheMemory_Set_WritePolicy( + &lmi_assoc_cache, + LMI_AssociatedProcessorCacheMemory_WritePolicy_Unknown); + LMI_AssociatedProcessorCacheMemory_Set_ReadPolicy( + &lmi_assoc_cache, + LMI_AssociatedProcessorCacheMemory_ReadPolicy_Unknown); + + if (sysfs_cpu_caches[i].line_size) { + LMI_AssociatedProcessorCacheMemory_Set_LineSize( + &lmi_assoc_cache, sysfs_cpu_caches[i].line_size); + } + + KReturnInstance(cr, lmi_assoc_cache); } } done: /* free lscpu only if it was used */ - if (dmi_cpus_nb < 1 || dmi_cpu_caches_nb < 1) { + if (dmi_cpus_nb < 1) { lscpu_free_processor(&lscpu); } dmi_free_processors(&dmi_cpus, &dmi_cpus_nb); diff --git a/src/hardware/LMI_ProcessorProvider.c b/src/hardware/LMI_ProcessorProvider.c index d96c679..b8a30a6 100644 --- a/src/hardware/LMI_ProcessorProvider.c +++ b/src/hardware/LMI_ProcessorProvider.c @@ -237,7 +237,6 @@ static CMPIStatus LMI_ProcessorEnumInstances( done: free(architecture); - architecture = NULL; dmi_free_processors(&dmi_cpus, &dmi_cpus_nb); lscpu_free_processor(&lscpu); diff --git a/src/hardware/dmidecode.c b/src/hardware/dmidecode.c index dfff7e3..b3d00ef 100644 --- a/src/hardware/dmidecode.c +++ b/src/hardware/dmidecode.c @@ -203,7 +203,13 @@ 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; + char curr_cpu_str[LONG_INT_LEN]; + snprintf(curr_cpu_str, LONG_INT_LEN, "-%u", curr_cpu); + (*cpus)[curr_cpu].id = append_str(buf, curr_cpu_str, NULL); + if (!(*cpus)[curr_cpu].id) { + ret = -8; + goto done; + } buf = NULL; continue; } @@ -745,30 +751,43 @@ short check_dmi_memory_attributes(DmiMemory *memory) for (i = 0; i < memory->modules_nb; i++) { if (!memory->modules[i].serial_number) { - if (!(memory->modules[i].serial_number = strdup(""))) { + if (asprintf(&memory->modules[i].serial_number, "%u", i) < 0) { + memory->modules[i].serial_number = NULL; ret = -2; goto done; } + } + if (!memory->modules[i].form_factor) { if (!(memory->modules[i].form_factor = strdup("Unknown"))) { ret = -3; goto done; } + } + if (!memory->modules[i].type) { if (!(memory->modules[i].type = strdup("Unknown"))) { ret = -4; goto done; } + } + if (!memory->modules[i].bank_label) { if (!(memory->modules[i].bank_label = strdup(""))) { ret = -5; goto done; } + } + if (!memory->modules[i].name) { if (!(memory->modules[i].name = strdup("Memory Module"))) { ret = -6; goto done; } + } + if (!memory->modules[i].manufacturer) { if (!(memory->modules[i].manufacturer = strdup(""))) { ret = -7; goto done; } + } + if (!memory->modules[i].part_number) { if (!(memory->modules[i].part_number = strdup(""))) { ret = -8; goto done; diff --git a/src/hardware/sysfs.c b/src/hardware/sysfs.c index 80d360e..565269f 100644 --- a/src/hardware/sysfs.c +++ b/src/hardware/sysfs.c @@ -144,11 +144,35 @@ done: return ret; } +/* + * Deep copy SysfsCpuCache structure. + * @param to destination + * @param from source + * @return 0 if success, negative value otherwise + */ +short copy_sysfs_cpu_cache(SysfsCpuCache *to, const SysfsCpuCache from) +{ + *to = from; + to->id = strdup(from.id); + to->name = strdup(from.name); + to->type = strdup(from.type); + + if (!to->id || !to->name || !to->type) { + warn("Failed to allocate memory."); + return -1; + } + + return 0; +} + short sysfs_get_cpu_caches(SysfsCpuCache **caches, unsigned *caches_nb) { short ret = -1; unsigned i, level; char *buf = NULL, *format_str, path[PATH_MAX]; + DmiProcessor *dmi_cpus = NULL; + unsigned dmi_cpus_nb = 0, cpus_nb = 0; + LscpuProcessor lscpu; *caches_nb = 0; @@ -177,8 +201,27 @@ short sysfs_get_cpu_caches(SysfsCpuCache **caches, unsigned *caches_nb) goto done; } + /* get processor information */ + if (dmi_get_processors(&dmi_cpus, &dmi_cpus_nb) != 0 || dmi_cpus_nb < 1) { + dmi_free_processors(&dmi_cpus, &dmi_cpus_nb); + + if (lscpu_get_processor(&lscpu) != 0) { + ret = -11; + goto done; + } + } + if (dmi_cpus_nb > 0) { + cpus_nb = dmi_cpus_nb; + } else if (lscpu.processors > 0) { + cpus_nb = lscpu.processors; + } else { + warn("No processor found."); + ret = -12; + goto done; + } + /* allocate memory for caches */ - *caches = (SysfsCpuCache *)calloc(*caches_nb, sizeof(SysfsCpuCache)); + *caches = (SysfsCpuCache *)calloc(*caches_nb * cpus_nb, sizeof(SysfsCpuCache)); if (!(*caches)) { warn("Failed to allocate memory."); ret = -4; @@ -203,13 +246,13 @@ short sysfs_get_cpu_caches(SysfsCpuCache **caches, unsigned *caches_nb) goto done; } if (strncmp(buf, "Data", 4) == 0) { - format_str = "L%ud-%u"; + format_str = "L%ud"; } else if (strncmp(buf, "Instruction", 11) == 0) { - format_str = "L%ui-%u"; + format_str = "L%ui"; } else { - format_str = "L%u-%u"; + format_str = "L%u"; } - if (asprintf(&(*caches)[i].id, format_str, level, i) < 0) { + if (asprintf(&(*caches)[i].id, format_str, level) < 0) { (*caches)[i].id = NULL; warn("Failed to allocate memory."); ret = -7; @@ -253,11 +296,34 @@ short sysfs_get_cpu_caches(SysfsCpuCache **caches, unsigned *caches_nb) } } + /* duplicate all caches for every processor; + this assumes that all CPUs in the system are the same */ + for (i = *caches_nb; i < *caches_nb * cpus_nb; i++) { + copy_sysfs_cpu_cache(&(*caches)[i], (*caches)[i % *caches_nb]); + } + *caches_nb *= cpus_nb; + + /* and give them unique ID */ + char cache_id[LONG_INT_LEN]; + for (i = 0; i < *caches_nb; i++) { + snprintf(cache_id, LONG_INT_LEN, "-%u", i); + (*caches)[i].id = append_str((*caches)[i].id, cache_id, NULL); + if (!(*caches)[i].id) { + ret = -10; + goto done; + } + } + ret = 0; done: free(buf); - buf = NULL; + + /* free lscpu only if it was used */ + if (dmi_cpus_nb < 1) { + lscpu_free_processor(&lscpu); + } + dmi_free_processors(&dmi_cpus, &dmi_cpus_nb); if (ret != 0) { sysfs_free_cpu_caches(caches, caches_nb); diff --git a/src/hardware/sysfs.h b/src/hardware/sysfs.h index 297a1a7..6ff7085 100644 --- a/src/hardware/sysfs.h +++ b/src/hardware/sysfs.h @@ -30,6 +30,8 @@ #include <sys/stat.h> #include <sys/types.h> #include "utils.h" +#include "dmidecode.h" +#include "lscpu.h" #define SYSFS_PATH "/sys/devices/system" #define SYSFS_CPU_PATH SYSFS_PATH "/cpu" diff --git a/src/hardware/utils.c b/src/hardware/utils.c index 8c1b63e..1d80411 100644 --- a/src/hardware/utils.c +++ b/src/hardware/utils.c @@ -104,7 +104,6 @@ short read_fp_to_2d_buffer(FILE *fp, char ***buffer, unsigned *buffer_size) done: free(line); - line = NULL; if (ret != 0) { free_2d_buffer(&tmp_buffer, &tmp_buffer_lines); @@ -249,7 +248,7 @@ char *trim(const char *str, const char *delims) delims = default_delims; } - /* trim start of the string */ + /* trim beginning of the string */ while (strchr(delims, str[0]) && str[0] != '\0') { str++; } @@ -262,7 +261,7 @@ char *trim(const char *str, const char *delims) } /* shorten length of string if there are trailing white spaces */ - while (strchr(delims, str[l - 1]) && l != 0) { + while (strchr(delims, str[l - 1]) && l > 0) { l--; } @@ -366,7 +365,6 @@ short explode(const char *str, const char *delims, char ***buffer, unsigned *buf done: free(trimmed_str); - trimmed_str = NULL; if (ret != 0) { free_2d_buffer(&tmp_buffer, &tmp_buffer_size); @@ -374,3 +372,43 @@ done: return ret; } + +char *append_str(char *str, ...) +{ + va_list ap; + size_t len, newlen; + char *next, *end; + + if (str) { + len = strlen(str); + } else { + len = 0; + } + + /* count final length */ + va_start(ap, str); + newlen = len + 1; + while ((next = va_arg(ap, char *))) { + newlen += strlen(next); + } + va_end(ap); + + /* reallocate string */ + char *temp = (char *)realloc(str, newlen); + if (!temp) { + warn("Failed to allocate memory."); + return NULL; + } + str = temp; + end = str + len; + + /* append parameters */ + va_start(ap, str); + while ((next = va_arg(ap, char *))) { + strcpy(end, next); + end += strlen(next); + } + va_end(ap); + + return str; +} diff --git a/src/hardware/utils.h b/src/hardware/utils.h index 933c042..2a1a690 100644 --- a/src/hardware/utils.h +++ b/src/hardware/utils.h @@ -25,6 +25,7 @@ #include <stdlib.h> #include <string.h> #include <errno.h> +#include <stdarg.h> #include "globals.h" #define LONG_INT_LEN 21 /* 64 bit unsigned int can has 20 decimals + \0 */ @@ -109,5 +110,15 @@ char *trim(const char *str, const char *delims); */ short explode(const char *str, const char *delims, char ***buffer, unsigned *buffer_size); +/* + * Append strings to the first string parameter. + * @param str string where the rest of params will be appended. Can be NULL. + * When appending, str will be reallocated to the correct size. + * Last parameter must be NULL. + * @return pointer to the final string (same as str, if it wasn't NULL). In case + * of any problem, NULL is returned. + */ +char *append_str(char *str, ...); + #endif /* UTILS_H_ */ |