forked from pool/util-linux
268 lines
6.9 KiB
Diff
268 lines
6.9 KiB
Diff
commit 47b6e8b684ad28228c9255fe4237b5a8a1c8c7d3
|
|
Author: Cai Qian <qcai@redhat.com>
|
|
Date: Sun Aug 10 15:33:51 2008 +0800
|
|
|
|
lscpu: --sysroot option and stable cache output
|
|
|
|
This patch added a --sysroot command-line option for testing purpose. It
|
|
also sorted cache names, and displayed cache information in a sorted
|
|
manner instead of randomly before. In addition, it had some other minor
|
|
fixes.
|
|
|
|
Signed-off-by: Cai Qian <qcai@redhat.com>
|
|
|
|
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c
|
|
index 275d4c7..d6bb8b9 100644
|
|
--- a/sys-utils/lscpu.c
|
|
+++ b/sys-utils/lscpu.c
|
|
@@ -36,17 +36,24 @@
|
|
#define CACHE_MAX 100
|
|
|
|
/* /sys paths */
|
|
-#define _PATH_SYS_SYSTEM "/sys/devices/system"
|
|
+#define _PATH_SYS_SYSTEM "sys/devices/system"
|
|
#define _PATH_SYS_CPU0 _PATH_SYS_SYSTEM "/cpu/cpu0"
|
|
-#define _PATH_PROC_XENCAP "/proc/xen/capabilities"
|
|
-#define _PATH_PROC_CPUINFO "/proc/cpuinfo"
|
|
+#define _PATH_PROC_XENCAP "proc/xen/capabilities"
|
|
+#define _PATH_PROC_CPUINFO "proc/cpuinfo"
|
|
|
|
int have_topology;
|
|
int have_cache;
|
|
int have_node;
|
|
|
|
+/* cache(s) description */
|
|
+struct ca_desc {
|
|
+ char *caname;
|
|
+ char *casize;
|
|
+ int camap;
|
|
+};
|
|
+
|
|
/* CPU(s) description */
|
|
-struct cpu_decs {
|
|
+struct cpu_desc {
|
|
/* counters */
|
|
int ct_cpu;
|
|
int ct_thread;
|
|
@@ -62,9 +69,7 @@ struct cpu_decs {
|
|
char *model;
|
|
|
|
/* caches */
|
|
- char *caname[CACHE_MAX];
|
|
- char *casize[CACHE_MAX];
|
|
- int camap[CACHE_MAX];
|
|
+ struct ca_desc cache[CACHE_MAX];
|
|
|
|
/* misc */
|
|
char *mhz;
|
|
@@ -75,7 +80,7 @@ struct cpu_decs {
|
|
int *nodecpu;
|
|
};
|
|
|
|
-char pathbuf[PATH_MAX];
|
|
+char pathbuf[PATH_MAX] = "/";
|
|
|
|
static void path_scanstr(char *result, const char *path, ...)
|
|
__attribute__ ((__format__ (__printf__, 2, 3)));
|
|
@@ -211,7 +216,7 @@ int lookup(char *line, char *pattern, char **value)
|
|
}
|
|
|
|
static void
|
|
-read_basicinfo(struct cpu_decs *cpu)
|
|
+read_basicinfo(struct cpu_desc *cpu)
|
|
{
|
|
FILE *fp = xfopen(_PATH_PROC_CPUINFO, "r");
|
|
char buf[BUFSIZ];
|
|
@@ -245,7 +250,7 @@ read_basicinfo(struct cpu_decs *cpu)
|
|
}
|
|
|
|
static void
|
|
-read_topology(struct cpu_decs *cpu)
|
|
+read_topology(struct cpu_desc *cpu)
|
|
{
|
|
/* number of threads */
|
|
cpu->ct_thread = path_sibling(
|
|
@@ -261,7 +266,7 @@ read_topology(struct cpu_decs *cpu)
|
|
}
|
|
|
|
static void
|
|
-read_cache(struct cpu_decs *cpu)
|
|
+read_cache(struct cpu_desc *cpu)
|
|
{
|
|
char buf[256];
|
|
DIR *dp;
|
|
@@ -295,14 +300,14 @@ read_cache(struct cpu_decs *cpu)
|
|
else
|
|
snprintf(buf, sizeof(buf), "L%d", level);
|
|
|
|
- cpu->caname[cpu->ct_cache] = xstrdup(buf);
|
|
+ cpu->cache[cpu->ct_cache].caname = xstrdup(buf);
|
|
|
|
/* cache size */
|
|
path_scanstr(buf, _PATH_SYS_CPU0 "/cache/%s/size", dir->d_name);
|
|
- cpu->casize[cpu->ct_cache] = xstrdup(buf);
|
|
+ cpu->cache[cpu->ct_cache].casize = xstrdup(buf);
|
|
|
|
/* information about how CPUs share different caches */
|
|
- cpu->camap[cpu->ct_cache] = path_sibling(
|
|
+ cpu->cache[cpu->ct_cache].camap = path_sibling(
|
|
_PATH_SYS_CPU0 "/cache/%s/shared_cpu_map",
|
|
dir->d_name);
|
|
cpu->ct_cache++;
|
|
@@ -310,7 +315,7 @@ read_cache(struct cpu_decs *cpu)
|
|
}
|
|
|
|
static void
|
|
-read_nodes(struct cpu_decs *cpu)
|
|
+read_nodes(struct cpu_desc *cpu)
|
|
{
|
|
int i;
|
|
|
|
@@ -346,7 +351,8 @@ check_system(void)
|
|
|
|
/* Read through sysfs. */
|
|
if (access(_PATH_SYS_SYSTEM, F_OK))
|
|
- errx(1, _("error: /sys filesystem is not accessable."));
|
|
+ errx(EXIT_FAILURE,
|
|
+ _("error: /sys filesystem is not accessable."));
|
|
|
|
if (!access(_PATH_SYS_SYSTEM "/node", F_OK))
|
|
have_node = 1;
|
|
@@ -359,22 +365,22 @@ check_system(void)
|
|
}
|
|
|
|
static void
|
|
-print_parsable(struct cpu_decs *cpu)
|
|
+print_parsable(struct cpu_desc *cpu)
|
|
{
|
|
int i, j;
|
|
|
|
- puts(
|
|
+ printf(_(
|
|
"# The following is the parsable format, which can be fed to other\n"
|
|
- "# programs. Each different item in every column has a unique ID\n"
|
|
+ "# programs. Each different item in every column has an unique ID\n"
|
|
"# starting from zero.\n"
|
|
- "# CPU,Core,Socket,Node");
|
|
+ "# CPU,Core,Socket,Node"));
|
|
|
|
if (have_cache) {
|
|
/* separator between CPU topology and cache information */
|
|
putchar(',');
|
|
|
|
for (i = cpu->ct_cache - 1; i >= 0; i--)
|
|
- printf(",%s", cpu->caname[i]);
|
|
+ printf(",%s", cpu->cache[i].caname);
|
|
}
|
|
putchar('\n');
|
|
|
|
@@ -407,11 +413,11 @@ print_parsable(struct cpu_decs *cpu)
|
|
for (j = cpu->ct_cache - 1; j >= 0; j--) {
|
|
/* If shared_cpu_map is 0, all CPUs share the same
|
|
cache. */
|
|
- if (cpu->camap[j] == 0)
|
|
- cpu->camap[j] = cpu->ct_core *
|
|
- cpu->ct_thread;
|
|
+ if (cpu->cache[j].camap == 0)
|
|
+ cpu->cache[j].camap = cpu->ct_core *
|
|
+ cpu->ct_thread;
|
|
|
|
- printf(",%d", i / cpu->camap[j]);
|
|
+ printf(",%d", i / cpu->cache[j].camap);
|
|
}
|
|
}
|
|
putchar('\n');
|
|
@@ -424,7 +430,7 @@ print_parsable(struct cpu_decs *cpu)
|
|
#define print_n(_key, _val) printf("%-23s%d\n", _key, _val)
|
|
|
|
static void
|
|
-print_readable(struct cpu_decs *cpu)
|
|
+print_readable(struct cpu_desc *cpu)
|
|
{
|
|
char buf[BUFSIZ];
|
|
|
|
@@ -462,8 +468,8 @@ print_readable(struct cpu_decs *cpu)
|
|
|
|
for (i = cpu->ct_cache - 1; i >= 0; i--) {
|
|
snprintf(buf, sizeof(buf),
|
|
- _("%s cache:"), cpu->caname[i]);
|
|
- print_s(buf, cpu->casize[i]);
|
|
+ _("%s cache:"), cpu->cache[i].caname);
|
|
+ print_s(buf, cpu->cache[i].casize);
|
|
}
|
|
}
|
|
}
|
|
@@ -475,18 +481,29 @@ void usage(int rc)
|
|
|
|
puts(_( "CPU architecture information helper\n\n"
|
|
" -h, --help usage information\n"
|
|
- " -p, --parse print out in parsable instead of printable format.\n"));
|
|
+ " -p, --parse print out in parsable instead of printable format.\n"
|
|
+ " -s, --sysroot use the directory as a new system root.\n"));
|
|
exit(rc);
|
|
}
|
|
|
|
+static int
|
|
+ca_compare(const void *a, const void *b)
|
|
+{
|
|
+ struct ca_desc *cache1 = (struct ca_desc *) a;
|
|
+ struct ca_desc *cache2 = (struct ca_desc *) b;
|
|
+
|
|
+ return strcmp(cache2->caname, cache1->caname);
|
|
+}
|
|
+
|
|
int main(int argc, char *argv[])
|
|
{
|
|
- struct cpu_decs _cpu, *cpu = &_cpu;
|
|
+ struct cpu_desc _cpu, *cpu = &_cpu;
|
|
int parsable = 0, c;
|
|
|
|
struct option longopts[] = {
|
|
- { "help", no_argument, 0, 'h' },
|
|
- { "parse", no_argument, 0, 'p' },
|
|
+ { "help", no_argument, 0, 'h' },
|
|
+ { "parse", no_argument, 0, 'p' },
|
|
+ { "sysroot", required_argument, 0, 's' },
|
|
{ NULL, 0, 0, 0 }
|
|
};
|
|
|
|
@@ -494,18 +511,25 @@ int main(int argc, char *argv[])
|
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
textdomain(PACKAGE);
|
|
|
|
- while((c = getopt_long(argc, argv, "hp", longopts, NULL)) != -1) {
|
|
+ while((c = getopt_long(argc, argv, "hps:", longopts, NULL)) != -1) {
|
|
switch (c) {
|
|
case 'h':
|
|
usage(EXIT_SUCCESS);
|
|
case 'p':
|
|
parsable = 1;
|
|
break;
|
|
+ case 's':
|
|
+ strncpy(pathbuf, optarg, sizeof(pathbuf));
|
|
+ break;
|
|
default:
|
|
usage(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
+ if (chdir(pathbuf) == -1)
|
|
+ errx(EXIT_FAILURE,
|
|
+ _("error: change working directory to %s."), pathbuf);
|
|
+
|
|
memset(cpu, 0, sizeof(*cpu));
|
|
|
|
check_system();
|
|
@@ -514,8 +538,10 @@ int main(int argc, char *argv[])
|
|
|
|
if (have_topology)
|
|
read_topology(cpu);
|
|
- if (have_cache)
|
|
+ if (have_cache) {
|
|
read_cache(cpu);
|
|
+ qsort(cpu->cache, cpu->ct_cache, sizeof(struct ca_desc), ca_compare);
|
|
+ }
|
|
if (have_node)
|
|
read_nodes(cpu);
|
|
|