diff options
| author | Karel Zak <kzak@redhat.com> | 2020-03-17 17:27:51 +0100 |
|---|---|---|
| committer | Karel Zak <kzak@redhat.com> | 2020-11-13 09:19:02 +0100 |
| commit | 329ec35ff03b073d13ec6bb52283cb6711537569 (patch) | |
| tree | 286a94e789479909f6e79b0348fcfc2b18c2f16e | |
| parent | ad2659383c1b3e7b0f1174515730bafebbeadf84 (diff) | |
| download | util-linux-329ec35ff03b073d13ec6bb52283cb6711537569.tar.gz | |
lscpu: (cputype) add cpuinfo parser
Signed-off-by: Karel Zak <kzak@redhat.com>
| -rw-r--r-- | sys-utils/lscpu-cputype.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/sys-utils/lscpu-cputype.c b/sys-utils/lscpu-cputype.c index bcf183e9e0..693bba6893 100644 --- a/sys-utils/lscpu-cputype.c +++ b/sys-utils/lscpu-cputype.c @@ -49,6 +49,9 @@ struct lscpu_cputype { int virtype; /* VIRT_PARA|FULL|NONE ? */ char *stepping; char *bogomips; + char *mhz; + char *dynamic_mhz; + char *static_mhz; char *flags; char *mtid; /* maximum thread id (s390) */ char *addrsz; /* address sizes */ @@ -145,6 +148,111 @@ void lscpu_unref_cputype(struct lscpu_cputype *ct) } } +struct cpuinfo_patern { + const char *pattern; + size_t offset; +}; + +#define DEF_PATTERN(_str, _member) \ + { \ + .pattern = (_str), \ + .offset = offsetof(struct lscpu_cputype, _member) \ + } + +static const struct cpuinfo_patern patterns[] = +{ + DEF_PATTERN("BogoMIPS", bogomips), /* aarch64 */ + DEF_PATTERN("CPU implementer", vendor), /* ARM and aarch64 */ + DEF_PATTERN("CPU part", model), /* ARM and aarch64 */ + DEF_PATTERN("CPU revision", revision), /* aarch64 */ + DEF_PATTERN("CPU variant", stepping), /* aarch64 */ + DEF_PATTERN("Features", flags), /* aarch64 */ + DEF_PATTERN("address sizes", addrsz), /* x86 */ + DEF_PATTERN("bogomips per cpu", bogomips), /* s390 */ + DEF_PATTERN("bogomips", bogomips), + DEF_PATTERN("cpu MHz dynamic", dynamic_mhz), /* s390 */ + DEF_PATTERN("cpu MHz static", static_mhz), /* s390 */ + DEF_PATTERN("cpu MHz", mhz), + DEF_PATTERN("cpu family", family), + DEF_PATTERN("cpu", cpu), + DEF_PATTERN("family", family), + DEF_PATTERN("features", flags), /* s390 */ + DEF_PATTERN("flags", flags), /* x86 */ + DEF_PATTERN("max thread id", mtid), /* s390 */ + DEF_PATTERN("model name", modelname), + DEF_PATTERN("model", model), + DEF_PATTERN("revision", revision), + DEF_PATTERN("stepping", stepping), + DEF_PATTERN("type", flags), /* sparc64 */ + DEF_PATTERN("vendor", vendor), + DEF_PATTERN("vendor_id", vendor), +}; + +#define CPUTYPE_PATTERN_BUFSZ 32 + +static int cmp_pattern(const void *a0, const void *b0) +{ + const struct cpuinfo_patern + *a = (const struct cpuinfo_patern *) a0, + *b = (const struct cpuinfo_patern *) b0; + return strcmp(a->pattern, b->pattern); +} + +static int cputype_parse(struct lscpu_cputype *ct, const char *str) +{ + struct cpuinfo_patern key, *pat; + const char *p, *v; + char buf[CPUTYPE_PATTERN_BUFSZ] = { 0 }, **data; + + DBG(TYPE, ul_debugobj(ct, "parse \"%s\"", str)); + + if (!str || !*str) + return -EINVAL; + p = skip_blank(str); + if (!p || !*p) + return -EINVAL; + + v = strchr(p, ':'); + if (!v || !*v) + return -EINVAL; + + /* prepare value name */ + xstrncpy(buf, p, sizeof(buf)); + buf[v - p] = '\0'; + v++; + + rtrim_whitespace((unsigned char *)buf); + + /* search by name */ + key.pattern = buf; + pat = bsearch(&key, patterns, ARRAY_SIZE(patterns), + sizeof(struct cpuinfo_patern), + cmp_pattern); + if (!pat) { + DBG(TYPE, ul_debugobj(ct, "'%s' not found", buf)); + return 1; /* not found */ + } + + /* copy value to struct lscpu_cputype */ + v = skip_space(v); + if (!v || !*v) + return -EINVAL; + strdup_to_offset(ct, pat->offset, v); + + /* cleanuup white chars */ + data = (char **) ((char *) ct + pat->offset); + rtrim_whitespace((unsigned char *) *data); + + return 0; +} + +static void print_cputype(struct lscpu_cputype *ct, FILE *f) +{ + fprintf(f, "vendor=\"%s\"\n", ct->vendor); + fprintf(f, "model=\"%s\"\n", ct->model); + fprintf(f, "flags=\"%s\"\n", ct->flags); +} + struct lscpu_cxt *lscpu_new_context(void) { return xcalloc(1, sizeof(struct lscpu_cxt)); @@ -173,7 +281,43 @@ static void lscpu_free_context(struct lscpu_cxt *cxt) int lscpu_read_cputypes(struct lscpu_cxt *cxt) { + struct lscpu_cputype *ct = NULL; + FILE *fp; + char buf[BUFSIZ]; + DBG(GATHER, ul_debugobj(cxt, "reading types")); + + fp = ul_path_fopen(cxt->procfs, "r", "cpuinfo"); + if (!fp) + err(EXIT_FAILURE, _("cannot open %s"), "/proc/cpuinfo"); + + while (fgets(buf, sizeof(buf), fp) != NULL) { + const char *p = skip_space(buf); + + if (*buf && !*p) { + if (ct) { + ON_DBG(GATHER, print_cputype(ct, stdout)); + //lscpu_add_cputype(&cxt->cputypes, &cxt->ncputypes, ct); + } + lscpu_unref_cputype(ct); + ct = NULL; + continue; + } + if (!ct) + ct = lscpu_new_cputype(); + + cputype_parse(ct, p); + + /* TODO: else lscpu_parse_cache(cxt, buf); */ + } + + if (ct) { + //lscpu_add_cputype(&cxt->cputypes, &cxt->ncputypes, ct); + lscpu_unref_cputype(ct); + } + + fclose(fp); + return 0; return 0; } |
