diff --git a/util-linux-2.14.1-hypervisor_detection.patch b/util-linux-2.14.1-hypervisor_detection.patch deleted file mode 100644 index 6ac8c11..0000000 --- a/util-linux-2.14.1-hypervisor_detection.patch +++ /dev/null @@ -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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+ -+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 -+.SH COPYRIGHT -+This is free software. You may redistribute copies of it under the terms -+of the GNU General Public License . -+There is NO WARRANTY, to the extent permitted by law. -+ diff --git a/util-linux-2.14.1-lscpu.patch b/util-linux-2.14.1-lscpu.patch new file mode 100644 index 0000000..77392d3 --- /dev/null +++ b/util-linux-2.14.1-lscpu.patch @@ -0,0 +1,630 @@ +commit 5dd7507c18fa3d739266aeda4847be41e0613fad +Author: Cai Qian +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 + Signed-off-by: Cai Qian + Signed-off-by: Karel Zak + +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 ++.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 ++ * Copyright (C) 2008 Karel Zak ++ * ++ * 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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: ++ * ++ * " : " ++ */ ++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 " "*/ ++#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; ++} diff --git a/util-linux-2.14.1-lscpu_add_hypervisor_vendor_id.patch b/util-linux-2.14.1-lscpu_add_hypervisor_vendor_id.patch new file mode 100644 index 0000000..ff3960a --- /dev/null +++ b/util-linux-2.14.1-lscpu_add_hypervisor_vendor_id.patch @@ -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 . +> +> 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 +Date: Wed, 1 Oct 2008 01:29:32 +0200 +Subject: [PATCH] lscpu: add Hypervisor vendor ID + +Signed-off-by: Karel Zak +--- + 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 + diff --git a/util-linux-2.14.1-lscpu_sysroot_option.patch b/util-linux-2.14.1-lscpu_sysroot_option.patch new file mode 100644 index 0000000..839a67f --- /dev/null +++ b/util-linux-2.14.1-lscpu_sysroot_option.patch @@ -0,0 +1,267 @@ +commit 47b6e8b684ad28228c9255fe4237b5a8a1c8c7d3 +Author: Cai Qian +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 + +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); + diff --git a/util-linux.changes b/util-linux.changes index 4320953..932dd36 100644 --- a/util-linux.changes +++ b/util-linux.changes @@ -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 diff --git a/util-linux.spec b/util-linux.spec index c0de37b..73063f5 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -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