forked from pool/util-linux
This commit is contained in:
parent
bb14144eb8
commit
810b4a9e48
@ -1,250 +0,0 @@
|
||||
Index: util-linux-ng-2.14.1/sys-utils/hypervisor.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ util-linux-ng-2.14.1/sys-utils/hypervisor.c 2008-09-24 12:21:05.000000000 +0200
|
||||
@@ -0,0 +1,169 @@
|
||||
+/* Detect the presence of a hypervisor
|
||||
+ * Copyright (C) 2008 Novell, Inc.
|
||||
+ * Author: Ky Srinivasan <ksrinivasan@novell.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public
|
||||
+ * License along with this program; if not, write to the Free
|
||||
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
+ * Boston, MA 02110-1301, USA.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <string.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio.h>
|
||||
+#include <unistd.h>
|
||||
+#include <getopt.h>
|
||||
+
|
||||
+static int opt_quiet = 0;
|
||||
+
|
||||
+struct option options[] = {
|
||||
+ { "help", no_argument, NULL, 'h' },
|
||||
+ { "quiet", no_argument, NULL, 'q' },
|
||||
+ { NULL, 9, NULL, 0 }
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ HYPER_NONE = 0,
|
||||
+ HYPER_XEN,
|
||||
+ HYPER_KVM,
|
||||
+ HYPER_MSHV,
|
||||
+ HYPER_MSHV_XENPV
|
||||
+};
|
||||
+
|
||||
+static inline void cpuid(unsigned int op,
|
||||
+ unsigned int *eax, unsigned int *ebx,
|
||||
+ unsigned int *ecx, unsigned int *edx)
|
||||
+{
|
||||
+ __asm__("cpuid"
|
||||
+ : "=a" (*eax),
|
||||
+ "=b" (*ebx),
|
||||
+ "=c" (*ecx),
|
||||
+ "=d" (*edx)
|
||||
+ : "0" (op), "c"(0));
|
||||
+}
|
||||
+
|
||||
+static int hypervisor(void)
|
||||
+{
|
||||
+ unsigned int eax, ebx, ecx, edx;
|
||||
+ char signature[13];
|
||||
+ int xen_pv =0;
|
||||
+
|
||||
+ /*
|
||||
+ * First check if we are running in a para-virtualized guest.
|
||||
+ */
|
||||
+ if ((!access("/sys/hypervisor", F_OK) ||
|
||||
+ (!access("/proc/xen", F_OK)))) {
|
||||
+ /*
|
||||
+ * For now we are only dealing with para-virtualized
|
||||
+ * Linux guests (para-virtualized on Xen). So, this must be
|
||||
+ * Xen based.
|
||||
+ */
|
||||
+ xen_pv = 1;
|
||||
+ }
|
||||
+ cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
|
||||
+ *(unsigned int*)(signature + 0) = ebx;
|
||||
+ *(unsigned int*)(signature + 4) = ecx;
|
||||
+ *(unsigned int*)(signature + 8) = edx;
|
||||
+ signature[12] = 0;
|
||||
+
|
||||
+ if ((!strncmp("XenVMMXenVMM", signature, 12) || (xen_pv)))
|
||||
+ return HYPER_XEN;
|
||||
+ if (!strncmp("KVMKVMKVM", signature, 9))
|
||||
+ return HYPER_KVM;
|
||||
+ if (!strncmp("Microsoft Hv", signature, 12)) {
|
||||
+ if (xen_pv)
|
||||
+ return HYPER_MSHV_XENPV;
|
||||
+ else
|
||||
+ return HYPER_MSHV;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void help(void)
|
||||
+{
|
||||
+ printf("Usage: hypervisor [OPTION]\n");
|
||||
+ printf("Detects the presence/absence of a hypervisor.\n\n");
|
||||
+ printf("Options:\n");
|
||||
+ printf(" -h, --help\tShow this message and exit.\n");
|
||||
+ printf(" -q, --quiet\tDo not show output message.\n\n");
|
||||
+ printf("Exit status:\n");
|
||||
+ printf(" 0\tNo hypervisor detected.\n");
|
||||
+ printf(" 1\tXen detected.\n");
|
||||
+ printf(" 2\tKVM detected.\n");
|
||||
+ printf(" 3\tHyperV detected.\n");
|
||||
+ printf(" 4\tHyperV emulating Xen detected.\n");
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Program to determine if we are being hosted on the hypervisor.
|
||||
+ * If the exit status is 0; we are running on bare hardware. The details of
|
||||
+ * non-zero return values are as follows:
|
||||
+ *
|
||||
+ * 0: No hypervisor (running on bare hardware)
|
||||
+ * 1: Xen is the hypervisor
|
||||
+ * 2: KVM is the hypervisor
|
||||
+ * 3: Veridian
|
||||
+ * 4: Veridian hypervisor emulating Xen.
|
||||
+ * TODO: VmWare Detection.
|
||||
+ */
|
||||
+int main(int argc, char **argv)
|
||||
+{
|
||||
+ int option_index, c;
|
||||
+ int ret;
|
||||
+
|
||||
+ while (1) {
|
||||
+ c = getopt_long(argc, argv, "hq", options, &option_index);
|
||||
+ if (c == -1)
|
||||
+ break;
|
||||
+
|
||||
+ switch (c) {
|
||||
+ case 'h':
|
||||
+ help();
|
||||
+ exit(EXIT_SUCCESS);
|
||||
+ case 'q':
|
||||
+ opt_quiet = 1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = hypervisor();
|
||||
+
|
||||
+ if (!opt_quiet) {
|
||||
+ switch (ret) {
|
||||
+ case HYPER_NONE:
|
||||
+ printf("No");
|
||||
+ break;
|
||||
+ case HYPER_XEN:
|
||||
+ printf("Xen");
|
||||
+ break;
|
||||
+ case HYPER_KVM:
|
||||
+ printf("KVM");
|
||||
+ break;
|
||||
+ case HYPER_MSHV:
|
||||
+ case HYPER_MSHV_XENPV:
|
||||
+ printf("Microsoft");
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ printf(" Hypervisor found\n");
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
Index: util-linux-ng-2.14.1/sys-utils/Makefile.am
|
||||
===================================================================
|
||||
--- util-linux-ng-2.14.1.orig/sys-utils/Makefile.am 2008-09-10 11:02:43.000000000 +0200
|
||||
+++ util-linux-ng-2.14.1/sys-utils/Makefile.am 2008-09-24 13:03:21.000000000 +0200
|
||||
@@ -35,6 +35,11 @@ RDEV_LINKS += ramsize vidmode rootflags
|
||||
dist_man_MANS += rdev.8
|
||||
endif
|
||||
|
||||
+if BUILD_HYPERVISOR
|
||||
+bin_PROGRAMS += hypervisor
|
||||
+dist_man_MANS += hypervisor.1
|
||||
+endif
|
||||
+
|
||||
SETARCH_LINKS = linux32 linux64
|
||||
|
||||
if ARCH_S390
|
||||
Index: util-linux-ng-2.14.1/configure.ac
|
||||
===================================================================
|
||||
--- util-linux-ng-2.14.1.orig/configure.ac 2008-09-10 12:13:27.000000000 +0200
|
||||
+++ util-linux-ng-2.14.1/configure.ac 2008-09-24 11:43:15.000000000 +0200
|
||||
@@ -471,6 +471,12 @@ AC_ARG_ENABLE([elvtune],
|
||||
)
|
||||
AM_CONDITIONAL(BUILD_ELVTUNE, test "x$enable_elvtune" = xyes)
|
||||
|
||||
+AC_ARG_ENABLE([hypervisor],
|
||||
+ AS_HELP_STRING([--enable-hypervisor], [build hypervisor]),
|
||||
+ [], enable_hypervisor=no
|
||||
+)
|
||||
+AM_CONDITIONAL(BUILD_HYPERVISOR, test "x$enable_hypervisor" = xyes)
|
||||
+
|
||||
|
||||
AC_ARG_ENABLE([init],
|
||||
AS_HELP_STRING([--enable-init], [build simpleinit, shutdown, initctl]),
|
||||
Index: util-linux-ng-2.14.1/sys-utils/hypervisor.1
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ util-linux-ng-2.14.1/sys-utils/hypervisor.1 2008-09-24 13:06:24.000000000 +0200
|
||||
@@ -0,0 +1,38 @@
|
||||
+.TH hypervisor 1 "September 2008" "" "User Commands"
|
||||
+.SH NAME
|
||||
+hypervisor \- detect presence of a hypervisor
|
||||
+.SH SYNOPSIS
|
||||
+.B hypervisor
|
||||
+[\fIOPTION\fR]
|
||||
+.SH DESCRIPTION
|
||||
+Detects the presence/absence of a hypervisor.
|
||||
+.SH OPTIONS
|
||||
+.TP
|
||||
+\fB\-h\fR, \fB\-\-help\fR
|
||||
+Show this message and exit.
|
||||
+.TP
|
||||
+\fB\-q\fR, \fB\-\-quiet\fR
|
||||
+Do not show output message.
|
||||
+.SH EXIT CODES
|
||||
+.TP
|
||||
+0
|
||||
+No hypervisor detected.
|
||||
+.TP
|
||||
+1
|
||||
+Xen detected.
|
||||
+.TP
|
||||
+2
|
||||
+KVM detected.
|
||||
+.TP
|
||||
+3
|
||||
+HyperV detected.
|
||||
+.TP
|
||||
+4
|
||||
+HyperV emulating Xen detected.
|
||||
+.SH AUTHOR
|
||||
+Ky Srinivasan <ksrinivasan@novell.com>
|
||||
+.SH COPYRIGHT
|
||||
+This is free software. You may redistribute copies of it under the terms
|
||||
+of the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
|
||||
+There is NO WARRANTY, to the extent permitted by law.
|
||||
+
|
630
util-linux-2.14.1-lscpu.patch
Normal file
630
util-linux-2.14.1-lscpu.patch
Normal file
@ -0,0 +1,630 @@
|
||||
commit 5dd7507c18fa3d739266aeda4847be41e0613fad
|
||||
Author: Cai Qian <qcai@redhat.com>
|
||||
Date: Thu Jul 17 14:19:40 2008 +0200
|
||||
|
||||
lscpu: new command
|
||||
|
||||
Add a lscpu(1) utility program.
|
||||
|
||||
[kzak@redhat.com:
|
||||
- indent by linux-2.6/scripts/Lindent
|
||||
- add lscpu.{c,1} to sys-utils/Makefile.am
|
||||
- add NLS suport
|
||||
- complete code refactoring
|
||||
]
|
||||
|
||||
Co-Author: Karel Zak <kzak@redhat.com>
|
||||
Signed-off-by: Cai Qian <qcai@redhat.com>
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
|
||||
Index: util-linux-ng-2.14.1/README.licensing
|
||||
===================================================================
|
||||
--- util-linux-ng-2.14.1.orig/README.licensing 2008-09-10 11:02:42.000000000 +0200
|
||||
+++ util-linux-ng-2.14.1/README.licensing 2008-10-01 17:18:31.000000000 +0200
|
||||
@@ -2,6 +2,8 @@
|
||||
The project utils-linux-ng doesn't use same license for all code. There are
|
||||
code with:
|
||||
|
||||
+ * GPLv3+ (GNU General Public License version 3, or any later version)
|
||||
+
|
||||
* GPLv2+ (GNU General Public License version 2, or any later version)
|
||||
|
||||
* GPLv2 (GNU General Public License version 2)
|
||||
Index: util-linux-ng-2.14.1/po/POTFILES.in
|
||||
===================================================================
|
||||
--- util-linux-ng-2.14.1.orig/po/POTFILES.in 2008-09-10 11:02:43.000000000 +0200
|
||||
+++ util-linux-ng-2.14.1/po/POTFILES.in 2008-10-01 17:18:31.000000000 +0200
|
||||
@@ -98,6 +98,7 @@ sys-utils/flock.c
|
||||
sys-utils/ipcrm.c
|
||||
sys-utils/ipcs.c
|
||||
sys-utils/ldattach.c
|
||||
+sys-utils/lscpu.c
|
||||
sys-utils/rdev.c
|
||||
sys-utils/readprofile.c
|
||||
sys-utils/renice.c
|
||||
Index: util-linux-ng-2.14.1/sys-utils/Makefile.am
|
||||
===================================================================
|
||||
--- util-linux-ng-2.14.1.orig/sys-utils/Makefile.am 2008-09-10 11:02:43.000000000 +0200
|
||||
+++ util-linux-ng-2.14.1/sys-utils/Makefile.am 2008-10-01 17:19:50.000000000 +0200
|
||||
@@ -11,11 +11,11 @@ dist_man_MANS = flock.1 ipcrm.1 ipcs.1 r
|
||||
if LINUX
|
||||
bin_PROGRAMS += dmesg
|
||||
sbin_PROGRAMS += ctrlaltdel
|
||||
-usrbinexec_PROGRAMS += cytune setarch
|
||||
+usrbinexec_PROGRAMS += cytune setarch lscpu
|
||||
usrsbinexec_PROGRAMS += tunelp rtcwake
|
||||
|
||||
dist_man_MANS += dmesg.1 ctrlaltdel.8 cytune.8 setarch.8 \
|
||||
- tunelp.8 rtcwake.8
|
||||
+ tunelp.8 rtcwake.8 lscpu.1
|
||||
endif
|
||||
|
||||
cytune_SOURCES = cytune.c cyclades.h
|
||||
Index: util-linux-ng-2.14.1/sys-utils/lscpu.1
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ util-linux-ng-2.14.1/sys-utils/lscpu.1 2008-10-01 17:18:31.000000000 +0200
|
||||
@@ -0,0 +1,29 @@
|
||||
+.\" Process this file with
|
||||
+.\" groff -man -Tascii lscpu.1
|
||||
+.\"
|
||||
+.TH LSCPU 1 "JULY 2008" Linux "User Manuals"
|
||||
+.SH NAME
|
||||
+lscpu \- CPU architecture information helper
|
||||
+.SH SYNOPSIS
|
||||
+.B lscpu [-hp]
|
||||
+.SH DESCRIPTION
|
||||
+.B lscpu
|
||||
+gathers CPU architecture information like number of CPUs, threads,
|
||||
+cores, sockets, NUMA nodes, information about CPU caches, CPU family,
|
||||
+model and stepping from sysfs and /proc/cpuinfo, and prints it in
|
||||
+human-readable format. Alternatively, it can print out in parsable
|
||||
+format including how different caches are shared by different CPUs,
|
||||
+which can also be fed to other programs.
|
||||
+.SH OPTIONS
|
||||
+.IP -h, --help
|
||||
+Print a help message.
|
||||
+.IP -p, --parse
|
||||
+Print out in parsable instead of printable format.
|
||||
+.SH BUGS
|
||||
+The program at the moment does not handle the system installed with
|
||||
+different types of physical processors.
|
||||
+.SH AUTHOR
|
||||
+Cai Qian <qcai@redhat.com>
|
||||
+.SH AVAILABILITY
|
||||
+The setarch command is part of the util-linux-ng package and is available from
|
||||
+ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
|
||||
Index: util-linux-ng-2.14.1/sys-utils/lscpu.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ util-linux-ng-2.14.1/sys-utils/lscpu.c 2008-10-01 17:18:31.000000000 +0200
|
||||
@@ -0,0 +1,529 @@
|
||||
+/*
|
||||
+ * lscpu - CPU architecture information helper
|
||||
+ *
|
||||
+ * Copyright (C) 2008 Cai Qian <qcai@redhat.com>
|
||||
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <ctype.h>
|
||||
+#include <dirent.h>
|
||||
+#include <err.h>
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <getopt.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/utsname.h>
|
||||
+#include <unistd.h>
|
||||
+#include <stdarg.h>
|
||||
+
|
||||
+#include "nls.h"
|
||||
+
|
||||
+#define CACHE_MAX 100
|
||||
+
|
||||
+/* /sys paths */
|
||||
+#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"
|
||||
+
|
||||
+int have_topology;
|
||||
+int have_cache;
|
||||
+int have_node;
|
||||
+
|
||||
+/* CPU(s) description */
|
||||
+struct cpu_decs {
|
||||
+ /* counters */
|
||||
+ int ct_cpu;
|
||||
+ int ct_thread;
|
||||
+ int ct_core;
|
||||
+ int ct_socket;
|
||||
+ int ct_node;
|
||||
+ int ct_cache;
|
||||
+
|
||||
+ /* who is who */
|
||||
+ char *arch;
|
||||
+ char *vendor;
|
||||
+ char *family;
|
||||
+ char *model;
|
||||
+
|
||||
+ /* caches */
|
||||
+ char *caname[CACHE_MAX];
|
||||
+ char *casize[CACHE_MAX];
|
||||
+ int camap[CACHE_MAX];
|
||||
+
|
||||
+ /* misc */
|
||||
+ char *mhz;
|
||||
+ char *stepping;
|
||||
+ char *flags;
|
||||
+
|
||||
+ /* NUMA */
|
||||
+ int *nodecpu;
|
||||
+};
|
||||
+
|
||||
+char pathbuf[PATH_MAX];
|
||||
+
|
||||
+static void path_scanstr(char *result, const char *path, ...)
|
||||
+ __attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
+static int path_exist(const char *path, ...)
|
||||
+ __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
+static int path_sibling(const char *path, ...)
|
||||
+ __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
+
|
||||
+static FILE *
|
||||
+xfopen(const char *path, const char *mode)
|
||||
+{
|
||||
+ FILE *fd = fopen(path, mode);
|
||||
+ if (!fd)
|
||||
+ err(EXIT_FAILURE, _("error: %s"), path);
|
||||
+ return fd;
|
||||
+}
|
||||
+
|
||||
+static FILE *
|
||||
+path_vfopen(const char *mode, const char *path, va_list ap)
|
||||
+{
|
||||
+ vsnprintf(pathbuf, sizeof(pathbuf), path, ap);
|
||||
+ return xfopen(pathbuf, mode);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+path_scanstr(char *result, const char *path, ...)
|
||||
+{
|
||||
+ FILE *fd;
|
||||
+ va_list ap;
|
||||
+
|
||||
+ va_start(ap, path);
|
||||
+ fd = path_vfopen("r", path, ap);
|
||||
+ va_end(ap);
|
||||
+
|
||||
+ if (fscanf(fd, "%s", result) != 1) {
|
||||
+ if (ferror(fd))
|
||||
+ err(EXIT_FAILURE, _("error: %s"), pathbuf);
|
||||
+ else
|
||||
+ errx(EXIT_FAILURE, _("error parse: %s"), pathbuf);
|
||||
+ }
|
||||
+ fclose(fd);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+path_exist(const char *path, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+
|
||||
+ va_start(ap, path);
|
||||
+ vsnprintf(pathbuf, sizeof(pathbuf), path, ap);
|
||||
+ va_end(ap);
|
||||
+
|
||||
+ return access(pathbuf, F_OK) == 0;
|
||||
+}
|
||||
+
|
||||
+char *
|
||||
+xstrdup(const char *str)
|
||||
+{
|
||||
+ char *s = strdup(str);
|
||||
+ if (!s)
|
||||
+ err(EXIT_FAILURE, _("error: strdup failed"));
|
||||
+ return s;
|
||||
+}
|
||||
+
|
||||
+/* count the set bit in a mapping file */
|
||||
+static int
|
||||
+path_sibling(const char *path, ...)
|
||||
+{
|
||||
+ int c, n;
|
||||
+ int result = 0;
|
||||
+ char s[2];
|
||||
+ FILE *fp;
|
||||
+ va_list ap;
|
||||
+
|
||||
+ va_start(ap, path);
|
||||
+ fp = path_vfopen("r", path, ap);
|
||||
+ va_end(ap);
|
||||
+
|
||||
+ while ((c = fgetc(fp)) != EOF) {
|
||||
+ if (isxdigit(c)) {
|
||||
+ s[0] = c;
|
||||
+ s[1] = '\0';
|
||||
+ for (n = strtol(s, NULL, 16); n > 0; n /= 2) {
|
||||
+ if (n % 2)
|
||||
+ result++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+/* Lookup a pattern and get the value from cpuinfo.
|
||||
+ * Format is:
|
||||
+ *
|
||||
+ * "<pattern> : <key>"
|
||||
+ */
|
||||
+int lookup(char *line, char *pattern, char **value)
|
||||
+{
|
||||
+ char *p, *v;
|
||||
+ int len = strlen(pattern);
|
||||
+
|
||||
+ if (!*line)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* pattern */
|
||||
+ if (strncmp(line, pattern, len))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* white spaces */
|
||||
+ for (p = line + len; isspace(*p); p++);
|
||||
+
|
||||
+ /* separator */
|
||||
+ if (*p != ':')
|
||||
+ return 0;
|
||||
+
|
||||
+ /* white spaces */
|
||||
+ for (++p; isspace(*p); p++);
|
||||
+
|
||||
+ /* value */
|
||||
+ if (!*p)
|
||||
+ return 0;
|
||||
+ v = p;
|
||||
+
|
||||
+ /* end of value */
|
||||
+ len = strlen(line) - 1;
|
||||
+ for (p = line + len; isspace(*(p-1)); p--);
|
||||
+ *p = '\0';
|
||||
+
|
||||
+ *value = xstrdup(v);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+read_basicinfo(struct cpu_decs *cpu)
|
||||
+{
|
||||
+ FILE *fp = xfopen(_PATH_PROC_CPUINFO, "r");
|
||||
+ char buf[BUFSIZ];
|
||||
+ struct utsname utsbuf;
|
||||
+
|
||||
+ /* architecture */
|
||||
+ if (uname(&utsbuf) == -1)
|
||||
+ err(EXIT_FAILURE, _("error: uname failed"));
|
||||
+ cpu->arch = xstrdup(utsbuf.machine);
|
||||
+
|
||||
+ /* count CPU(s) */
|
||||
+ while(path_exist(_PATH_SYS_SYSTEM "/cpu/cpu%d", cpu->ct_cpu))
|
||||
+ cpu->ct_cpu++;
|
||||
+
|
||||
+ /* details */
|
||||
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
+ /* IA64 */
|
||||
+ if (lookup(buf, "vendor", &cpu->vendor)) ;
|
||||
+ else if (lookup(buf, "vendor_id", &cpu->vendor)) ;
|
||||
+ /* IA64 */
|
||||
+ else if (lookup(buf, "family", &cpu->family)) ;
|
||||
+ else if (lookup(buf, "cpu family", &cpu->family)) ;
|
||||
+ else if (lookup(buf, "model", &cpu->model)) ;
|
||||
+ else if (lookup(buf, "stepping", &cpu->stepping)) ;
|
||||
+ else if (lookup(buf, "cpu MHz", &cpu->mhz)) ;
|
||||
+ else if (lookup(buf, "flags", &cpu->flags)) ;
|
||||
+ else
|
||||
+ continue;
|
||||
+ }
|
||||
+ fclose(fp);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+read_topology(struct cpu_decs *cpu)
|
||||
+{
|
||||
+ /* number of threads */
|
||||
+ cpu->ct_thread = path_sibling(
|
||||
+ _PATH_SYS_CPU0 "/topology/thread_siblings");
|
||||
+
|
||||
+ /* number of cores */
|
||||
+ cpu->ct_core = path_sibling(
|
||||
+ _PATH_SYS_CPU0 "/topology/core_siblings")
|
||||
+ / cpu->ct_thread;
|
||||
+
|
||||
+ /* number of sockets */
|
||||
+ cpu->ct_socket = cpu->ct_cpu / cpu->ct_core / cpu->ct_thread;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+read_cache(struct cpu_decs *cpu)
|
||||
+{
|
||||
+ char buf[256];
|
||||
+ DIR *dp;
|
||||
+ struct dirent *dir;
|
||||
+ int level, type;
|
||||
+
|
||||
+ dp = opendir(_PATH_SYS_CPU0 "/cache");
|
||||
+ if (dp == NULL)
|
||||
+ err(EXIT_FAILURE, _("error: %s"), _PATH_SYS_CPU0 "/cache");
|
||||
+
|
||||
+ while ((dir = readdir(dp)) != NULL) {
|
||||
+ if (!strcmp(dir->d_name, ".")
|
||||
+ || !strcmp(dir->d_name, ".."))
|
||||
+ continue;
|
||||
+
|
||||
+ /* cache type */
|
||||
+ path_scanstr(buf, _PATH_SYS_CPU0 "/cache/%s/type", dir->d_name);
|
||||
+ if (!strcmp(buf, "Data"))
|
||||
+ type = 'd';
|
||||
+ else if (!strcmp(buf, "Instruction"))
|
||||
+ type = 'i';
|
||||
+ else
|
||||
+ type = 0;
|
||||
+
|
||||
+ /* cache level */
|
||||
+ path_scanstr(buf, _PATH_SYS_CPU0 "/cache/%s/level", dir->d_name);
|
||||
+ level = atoi(buf);
|
||||
+
|
||||
+ if (type)
|
||||
+ snprintf(buf, sizeof(buf), "L%d%c", level, type);
|
||||
+ else
|
||||
+ snprintf(buf, sizeof(buf), "L%d", level);
|
||||
+
|
||||
+ cpu->caname[cpu->ct_cache] = xstrdup(buf);
|
||||
+
|
||||
+ /* cache size */
|
||||
+ path_scanstr(buf, _PATH_SYS_CPU0 "/cache/%s/size", dir->d_name);
|
||||
+ cpu->casize[cpu->ct_cache] = xstrdup(buf);
|
||||
+
|
||||
+ /* information about how CPUs share different caches */
|
||||
+ cpu->camap[cpu->ct_cache] = path_sibling(
|
||||
+ _PATH_SYS_CPU0 "/cache/%s/shared_cpu_map",
|
||||
+ dir->d_name);
|
||||
+ cpu->ct_cache++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+read_nodes(struct cpu_decs *cpu)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ /* number of NUMA node */
|
||||
+ while (path_exist(_PATH_SYS_SYSTEM "/node/node%d", cpu->ct_node))
|
||||
+ cpu->ct_node++;
|
||||
+
|
||||
+ cpu->nodecpu = (int *) malloc(cpu->ct_node * sizeof(int));
|
||||
+ if (!cpu->nodecpu)
|
||||
+ err(EXIT_FAILURE, _("error: malloc failed"));
|
||||
+
|
||||
+ /* information about how nodes share different CPUs */
|
||||
+ for (i = 0; i < cpu->ct_node; i++)
|
||||
+ cpu->nodecpu[i] = path_sibling(
|
||||
+ _PATH_SYS_SYSTEM "/node/node%d/cpumap",
|
||||
+ i);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+check_system(void)
|
||||
+{
|
||||
+ FILE *fd;
|
||||
+ char buf[256];
|
||||
+
|
||||
+ /* Dom0 Kernel gives wrong information. */
|
||||
+ fd = fopen(_PATH_PROC_XENCAP, "r");
|
||||
+ if (fd) {
|
||||
+ if (fscanf(fd, "%s", buf) == 1 && !strcmp(buf, "control_d"))
|
||||
+ errx(EXIT_FAILURE,
|
||||
+ _("error: Dom0 Kernel is unsupported."));
|
||||
+ fclose(fd);
|
||||
+ }
|
||||
+
|
||||
+ /* Read through sysfs. */
|
||||
+ if (access(_PATH_SYS_SYSTEM, F_OK))
|
||||
+ errx(1, _("error: /sys filesystem is not accessable."));
|
||||
+
|
||||
+ if (!access(_PATH_SYS_SYSTEM "/node", F_OK))
|
||||
+ have_node = 1;
|
||||
+
|
||||
+ if (!access(_PATH_SYS_CPU0 "/topology/thread_siblings", F_OK))
|
||||
+ have_topology = 1;
|
||||
+
|
||||
+ if (!access(_PATH_SYS_CPU0 "/cache", F_OK))
|
||||
+ have_cache = 1;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+print_parsable(struct cpu_decs *cpu)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ puts(
|
||||
+ "# 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"
|
||||
+ "# starting from zero.\n"
|
||||
+ "# 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]);
|
||||
+ }
|
||||
+ putchar('\n');
|
||||
+
|
||||
+ for (i = 0; i < cpu->ct_cpu; i++) {
|
||||
+ printf("%d", i);
|
||||
+
|
||||
+ if (have_topology)
|
||||
+ printf(",%d,%d",
|
||||
+ i / cpu->ct_thread,
|
||||
+ i / cpu->ct_core / cpu->ct_thread);
|
||||
+ else
|
||||
+ printf(",,");
|
||||
+
|
||||
+ if (have_node) {
|
||||
+ int c = 0;
|
||||
+
|
||||
+ for (j = 0; j < cpu->ct_node; j++) {
|
||||
+ c += cpu->nodecpu[j];
|
||||
+ if (i < c) {
|
||||
+ printf(",%d", j);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ } else
|
||||
+ putchar(',');
|
||||
+
|
||||
+ if (have_cache) {
|
||||
+ putchar(',');
|
||||
+
|
||||
+ 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;
|
||||
+
|
||||
+ printf(",%d", i / cpu->camap[j]);
|
||||
+ }
|
||||
+ }
|
||||
+ putchar('\n');
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* output formats "<key> <value>"*/
|
||||
+#define print_s(_key, _val) printf("%-23s%s\n", _key, _val)
|
||||
+#define print_n(_key, _val) printf("%-23s%d\n", _key, _val)
|
||||
+
|
||||
+static void
|
||||
+print_readable(struct cpu_decs *cpu)
|
||||
+{
|
||||
+ char buf[BUFSIZ];
|
||||
+
|
||||
+ print_s("Architecture:", cpu->arch);
|
||||
+ print_n("CPU(s):", cpu->ct_cpu);
|
||||
+
|
||||
+ if (have_topology) {
|
||||
+ print_n(_("Thread(s) per core:"), cpu->ct_thread);
|
||||
+ print_n(_("Core(s) per socket:"), cpu->ct_core);
|
||||
+ print_n(_("CPU socket(s):"), cpu->ct_socket);
|
||||
+ }
|
||||
+
|
||||
+ if (have_node)
|
||||
+ print_n(_("NUMA node(s):"), cpu->ct_node);
|
||||
+ if (cpu->vendor)
|
||||
+ print_s(_("Vendor ID:"), cpu->vendor);
|
||||
+ if (cpu->family)
|
||||
+ print_s(_("CPU family:"), cpu->family);
|
||||
+ if (cpu->model)
|
||||
+ print_s(_("Model:"), cpu->model);
|
||||
+ if (cpu->stepping)
|
||||
+ print_s(_("Stepping:"), cpu->stepping);
|
||||
+ if (cpu->mhz)
|
||||
+ print_s(_("CPU MHz:"), cpu->mhz);
|
||||
+ if (cpu->flags) {
|
||||
+ snprintf(buf, sizeof(buf), " %s ", cpu->flags);
|
||||
+ if (strstr(buf, " svm "))
|
||||
+ print_s(_("Virtualization:"), "AMD-V");
|
||||
+ else if (strstr(buf, " vmx "))
|
||||
+ print_s(_("Virtualization:"), "VT-x");
|
||||
+ }
|
||||
+
|
||||
+ if (have_cache) {
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = cpu->ct_cache - 1; i >= 0; i--) {
|
||||
+ snprintf(buf, sizeof(buf),
|
||||
+ _("%s cache:"), cpu->caname[i]);
|
||||
+ print_s(buf, cpu->casize[i]);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void usage(int rc)
|
||||
+{
|
||||
+ printf(_("Usage: %s [option]\n"),
|
||||
+ program_invocation_short_name);
|
||||
+
|
||||
+ puts(_( "CPU architecture information helper\n\n"
|
||||
+ " -h, --help usage information\n"
|
||||
+ " -p, --parse print out in parsable instead of printable format.\n"));
|
||||
+ exit(rc);
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char *argv[])
|
||||
+{
|
||||
+ struct cpu_decs _cpu, *cpu = &_cpu;
|
||||
+ int parsable = 0, c;
|
||||
+
|
||||
+ struct option longopts[] = {
|
||||
+ { "help", no_argument, 0, 'h' },
|
||||
+ { "parse", no_argument, 0, 'p' },
|
||||
+ { NULL, 0, 0, 0 }
|
||||
+ };
|
||||
+
|
||||
+ setlocale(LC_MESSAGES, "");
|
||||
+ bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
+ textdomain(PACKAGE);
|
||||
+
|
||||
+ while((c = getopt_long(argc, argv, "hp", longopts, NULL)) != -1) {
|
||||
+ switch (c) {
|
||||
+ case 'h':
|
||||
+ usage(EXIT_SUCCESS);
|
||||
+ case 'p':
|
||||
+ parsable = 1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ usage(EXIT_FAILURE);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ memset(cpu, 0, sizeof(*cpu));
|
||||
+
|
||||
+ check_system();
|
||||
+
|
||||
+ read_basicinfo(cpu);
|
||||
+
|
||||
+ if (have_topology)
|
||||
+ read_topology(cpu);
|
||||
+ if (have_cache)
|
||||
+ read_cache(cpu);
|
||||
+ if (have_node)
|
||||
+ read_nodes(cpu);
|
||||
+
|
||||
+ /* Show time! */
|
||||
+ if (parsable)
|
||||
+ print_parsable(cpu);
|
||||
+ else
|
||||
+ print_readable(cpu);
|
||||
+
|
||||
+ return EXIT_FAILURE;
|
||||
+}
|
196
util-linux-2.14.1-lscpu_add_hypervisor_vendor_id.patch
Normal file
196
util-linux-2.14.1-lscpu_add_hypervisor_vendor_id.patch
Normal file
@ -0,0 +1,196 @@
|
||||
X-Gnus-Coding-System: -*- coding: utf-8; -*-
|
||||
|
||||
On Mon, Sep 29, 2008 at 11:01:05PM +0200, Karel Zak wrote:
|
||||
> On Mon, Sep 29, 2008 at 03:17:28PM +0200, Matthias Koenig wrote:
|
||||
> > The tool has been written by Ky Srinivasan <ksrinivasan@novell.com>.
|
||||
>
|
||||
> Do we really need a new tool? IMHO the hypervisor Vendor ID should
|
||||
> be exported by kernel in /sys or /proc -- or we can add this info to
|
||||
> lscpu(1) or so.
|
||||
|
||||
The (untested) patch below introduces a new fields "Hypervisor vendor
|
||||
ID:" and "Para-Virtualized:" in lscpu(1).
|
||||
|
||||
The "Hypervisor vendor ID:" field reports the raw ID, it means it works
|
||||
for all hypervisors (the same logic like CPU "Vendor ID:").
|
||||
|
||||
I think this solution is a good compromise to avoid a new tool.
|
||||
|
||||
(Note that lscpu(1) does not support XEN dom0 now. This problem will
|
||||
be resolved ASAP.)
|
||||
|
||||
Comments?
|
||||
|
||||
Karel
|
||||
|
||||
>From 5a8e8f8b28eb6ea4bdce27ed6629dfb4fb1665b5 Mon Sep 17 00:00:00 2001
|
||||
From: Karel Zak <kzak@redhat.com>
|
||||
Date: Wed, 1 Oct 2008 01:29:32 +0200
|
||||
Subject: [PATCH] lscpu: add Hypervisor vendor ID
|
||||
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
---
|
||||
sys-utils/lscpu.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 files changed, 101 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c
|
||||
index d6bb8b9..5f39ced 100644
|
||||
--- a/sys-utils/lscpu.c
|
||||
+++ b/sys-utils/lscpu.c
|
||||
@@ -38,7 +38,8 @@
|
||||
/* /sys paths */
|
||||
#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_XEN "proc/xen"
|
||||
+#define _PATH_PROC_XENCAP _PATH_PROC_XEN "/capabilities"
|
||||
#define _PATH_PROC_CPUINFO "proc/cpuinfo"
|
||||
|
||||
int have_topology;
|
||||
@@ -67,6 +68,9 @@ struct cpu_desc {
|
||||
char *vendor;
|
||||
char *family;
|
||||
char *model;
|
||||
+ char *virtflag; /* virtualization flag (vmx, svm) */
|
||||
+ char *hvid; /* hypervisor vendor ID */
|
||||
+ int is_para; /* is paravirtualized ? */
|
||||
|
||||
/* caches */
|
||||
struct ca_desc cache[CACHE_MAX];
|
||||
@@ -246,9 +250,94 @@ read_basicinfo(struct cpu_desc *cpu)
|
||||
else
|
||||
continue;
|
||||
}
|
||||
+
|
||||
+ if (cpu->flags) {
|
||||
+ snprintf(buf, sizeof(buf), " %s ", cpu->flags);
|
||||
+ if (strstr(buf, " svm "))
|
||||
+ cpu->virtflag = strdup("svm");
|
||||
+ else if (strstr(buf, " vmx "))
|
||||
+ cpu->virtflag = strdup("vmx");
|
||||
+ }
|
||||
+
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
+#if defined(__x86_64__) || defined(__i386__)
|
||||
+
|
||||
+/*
|
||||
+ * This CPUID leaf returns the information about the hypervisor.
|
||||
+ * EAX : maximum input value for CPUID supported by the hypervisor.
|
||||
+ * EBX, ECX, EDX : Hypervisor vendor ID signature. E.g. VMwareVMware.
|
||||
+ */
|
||||
+#define HYPERVISOR_INFO_LEAF 0x40000000
|
||||
+
|
||||
+static inline void
|
||||
+cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx,
|
||||
+ unsigned int *ecx, unsigned int *edx)
|
||||
+{
|
||||
+ __asm__("cpuid"
|
||||
+ : "=a" (*eax),
|
||||
+ "=b" (*ebx),
|
||||
+ "=c" (*ecx),
|
||||
+ "=d" (*edx)
|
||||
+ : "0" (op), "c"(0));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+read_hypervisor_cpuid(struct cpu_desc *cpu)
|
||||
+{
|
||||
+ unsigned int eax, ebx, ecx, edx;
|
||||
+ char hyper_vendor_id[13];
|
||||
+
|
||||
+ memset(hyper_vendor_id, 0, sizeof(hyper_vendor_id));
|
||||
+
|
||||
+ cpuid(HYPERVISOR_INFO_LEAF, &eax, &ebx, &ecx, &edx);
|
||||
+ memcpy(hyper_vendor_id + 0, &ebx, 4);
|
||||
+ memcpy(hyper_vendor_id + 4, &ecx, 4);
|
||||
+ memcpy(hyper_vendor_id + 8, &edx, 4);
|
||||
+ hyper_vendor_id[12] = '\0';
|
||||
+
|
||||
+ if (hyper_vendor_id[0])
|
||||
+ cpu->hvid = strdup(hyper_vendor_id);
|
||||
+}
|
||||
+
|
||||
+#else /* ! __x86_64__ */
|
||||
+static void
|
||||
+read_hypervisor_cpuid(struct cpu_desc *cpu)
|
||||
+{
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static void
|
||||
+read_hypervisor(struct cpu_desc *cpu)
|
||||
+{
|
||||
+ read_hypervisor_cpuid(cpu);
|
||||
+
|
||||
+ if (!cpu->hvid) {
|
||||
+ /* fallback for non-x86 archs */
|
||||
+
|
||||
+ if (!access(_PATH_PROC_XEN, F_OK))
|
||||
+ /* XEN dom0 or domU */
|
||||
+ cpu->hvid = strdup("Xen");
|
||||
+ }
|
||||
+
|
||||
+ if (!cpu->virtflag && cpu->hvid && !strncmp(cpu->hvid, "Xen", 3)) {
|
||||
+
|
||||
+ FILE *fd = fopen(_PATH_PROC_XENCAP, "r");
|
||||
+ int dom0 = 0;
|
||||
+
|
||||
+ if (fd) {
|
||||
+ char buf[256];
|
||||
+
|
||||
+ if (fscanf(fd, "%s", buf) == 1 &&
|
||||
+ !strcmp(buf, "control_d"))
|
||||
+ dom0 = 1;
|
||||
+ fclose(fd);
|
||||
+ }
|
||||
+ cpu->is_para = !dom0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
read_topology(struct cpu_desc *cpu)
|
||||
{
|
||||
@@ -344,6 +433,7 @@ check_system(void)
|
||||
fd = fopen(_PATH_PROC_XENCAP, "r");
|
||||
if (fd) {
|
||||
if (fscanf(fd, "%s", buf) == 1 && !strcmp(buf, "control_d"))
|
||||
+ /* !!!!!!!! TODO */
|
||||
errx(EXIT_FAILURE,
|
||||
_("error: Dom0 Kernel is unsupported."));
|
||||
fclose(fd);
|
||||
@@ -455,13 +545,17 @@ print_readable(struct cpu_desc *cpu)
|
||||
print_s(_("Stepping:"), cpu->stepping);
|
||||
if (cpu->mhz)
|
||||
print_s(_("CPU MHz:"), cpu->mhz);
|
||||
- if (cpu->flags) {
|
||||
- snprintf(buf, sizeof(buf), " %s ", cpu->flags);
|
||||
- if (strstr(buf, " svm "))
|
||||
+ if (cpu->virtflag) {
|
||||
+ if (!strcmp(cpu->virtflag, "svm"))
|
||||
print_s(_("Virtualization:"), "AMD-V");
|
||||
- else if (strstr(buf, " vmx "))
|
||||
+ else if (!strcmp(cpu->virtflag, "vmx"))
|
||||
print_s(_("Virtualization:"), "VT-x");
|
||||
}
|
||||
+ if (cpu->hvid) {
|
||||
+ print_s(_("Hypervisor vendor ID:"), cpu->hvid);
|
||||
+ print_s(_("Para-Virtualized:"),
|
||||
+ cpu->is_para ? _("Yes") : _("Not"));
|
||||
+ }
|
||||
|
||||
if (have_cache) {
|
||||
int i;
|
||||
@@ -545,6 +639,8 @@ int main(int argc, char *argv[])
|
||||
if (have_node)
|
||||
read_nodes(cpu);
|
||||
|
||||
+ read_hypervisor(cpu);
|
||||
+
|
||||
/* Show time! */
|
||||
if (parsable)
|
||||
print_parsable(cpu);
|
||||
--
|
||||
1.5.5.1
|
||||
|
267
util-linux-2.14.1-lscpu_sysroot_option.patch
Normal file
267
util-linux-2.14.1-lscpu_sysroot_option.patch
Normal file
@ -0,0 +1,267 @@
|
||||
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);
|
||||
|
@ -1,3 +1,11 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Oct 2 11:10:11 CEST 2008 - mkoenig@suse.de
|
||||
|
||||
- add lscpu tool from current util-linux-ng git,
|
||||
needed for fate#303051
|
||||
- replace hypervisor detection tool with the solution blessed by
|
||||
upstream, which adds hv detection as lscpu feature [fate#303051]
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Sep 24 11:28:07 CEST 2008 - mkoenig@suse.de
|
||||
|
||||
|
@ -30,7 +30,7 @@ License: BSD 3-Clause; GPL v2 or later
|
||||
Group: System/Base
|
||||
AutoReqProv: on
|
||||
Version: 2.14.1
|
||||
Release: 2
|
||||
Release: 3
|
||||
Requires: %name-lang = %{version}
|
||||
Summary: A collection of basic system utilities
|
||||
Source: ftp://ftp.kernel.org/pub/linux/utils/util-linux/%name-ng-%version.tar.bz2
|
||||
@ -71,7 +71,9 @@ Patch4: util-linux-2.13-hwclock_rtc_wait_busy_tempfix.patch
|
||||
#
|
||||
Patch5: util-linux-2.13.1-fdisk_cfdisk_yesno.patch
|
||||
Patch7: util-linux-2.14-mount_retry_on_nomedium.patch
|
||||
Patch8: util-linux-2.14.1-hypervisor_detection.patch
|
||||
Patch8: util-linux-2.14.1-lscpu.patch
|
||||
Patch9: util-linux-2.14.1-lscpu_sysroot_option.patch
|
||||
Patch10: util-linux-2.14.1-lscpu_add_hypervisor_vendor_id.patch
|
||||
# crypto patch
|
||||
Patch20: util-linux-mount_losetup_crypto.patch
|
||||
##
|
||||
@ -116,6 +118,8 @@ Authors:
|
||||
%patch5 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch20 -p1
|
||||
cp %{SOURCE7} %{SOURCE8} .
|
||||
#
|
||||
@ -185,7 +189,7 @@ CFLAGS=-DCONFIG_SMP
|
||||
# architecture dependent builds
|
||||
BUILD_ENABLE=
|
||||
%ifarch %ix86 x86_64
|
||||
BUILD_ENABLE="--enable-rdev --enable-hypervisor"
|
||||
BUILD_ENABLE="--enable-rdev"
|
||||
%endif
|
||||
# Use autogen, when building from git tree
|
||||
autoreconf -fi
|
||||
@ -411,6 +415,7 @@ fi
|
||||
#/usr/bin/linux32
|
||||
#/usr/bin/linux64
|
||||
/usr/bin/look
|
||||
/usr/bin/lscpu
|
||||
/usr/bin/mcookie
|
||||
/usr/bin/mesg
|
||||
%ifnarch ppc ppc64
|
||||
@ -465,6 +470,7 @@ fi
|
||||
%{_mandir}/man1/line.1.gz
|
||||
%{_mandir}/man1/logger.1.gz
|
||||
%{_mandir}/man1/look.1.gz
|
||||
%{_mandir}/man1/lscpu.1.gz
|
||||
%{_mandir}/man1/mcookie.1.gz
|
||||
%{_mandir}/man1/mesg.1.gz
|
||||
%{_mandir}/man1/more.1.gz
|
||||
@ -536,12 +542,10 @@ fi
|
||||
/sbin/sfdisk
|
||||
%endif
|
||||
%ifarch %ix86 x86_64
|
||||
/bin/hypervisor
|
||||
/usr/sbin/ramsize
|
||||
/usr/sbin/rdev
|
||||
/usr/sbin/rootflags
|
||||
/usr/sbin/vidmode
|
||||
%{_mandir}/man1/hypervisor.1.gz
|
||||
%{_mandir}/man8/ramsize.8.gz
|
||||
%{_mandir}/man8/rdev.8.gz
|
||||
%{_mandir}/man8/rootflags.8.gz
|
||||
@ -583,6 +587,11 @@ fi
|
||||
#%endif
|
||||
|
||||
%changelog
|
||||
* Thu Oct 02 2008 mkoenig@suse.de
|
||||
- add lscpu tool from current util-linux-ng git,
|
||||
needed for fate#303051
|
||||
- replace hypervisor detection tool with the solution blessed by
|
||||
upstream, which adds hv detection as lscpu feature [fate#303051]
|
||||
* Wed Sep 24 2008 mkoenig@suse.de
|
||||
- add new tool /bin/hypervisor for x86, x86_64
|
||||
from Ky Srinivasan <ksrinivasan@novell.com>
|
||||
|
Loading…
Reference in New Issue
Block a user