You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
3.0 KiB
81 lines
3.0 KiB
5 years ago
|
From 7bb8b4580b19f1d48e9beb201387d6c321b3ae7b Mon Sep 17 00:00:00 2001
|
||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||
|
Date: Tue, 2 Oct 2018 16:07:00 +0200
|
||
|
Subject: [PATCH] detect-virt: do not try to read all of /proc/cpuinfo
|
||
|
|
||
|
Quoting #10074:
|
||
|
> detect_vm_uml() reads /proc/cpuinfo with read_full_file()
|
||
|
> read_full_file() has a file max limit size of READ_FULL_BYTES_MAX=(4U*1024U*1024U)
|
||
|
> Unfortunately, the size of my /proc/cpuinfo is bigger, approximately:
|
||
|
> echo $(( 4* $(cat /proc/cpuinfo | wc -c)))
|
||
|
> 9918072
|
||
|
> This causes read_full_file() to fail and the Condition test fallout.
|
||
|
|
||
|
Let's just read line by line until we find an intersting line. This also
|
||
|
helps if not running under UML, because we avoid reading as much data.
|
||
|
|
||
|
(cherry picked from commit 6058516a14ada1748313af6783f5b4e7e3006654)
|
||
|
Resolves: #1631531
|
||
|
---
|
||
|
src/shared/virt.c | 40 ++++++++++++++++++++++++++++++++--------
|
||
|
1 file changed, 32 insertions(+), 8 deletions(-)
|
||
|
|
||
|
diff --git a/src/shared/virt.c b/src/shared/virt.c
|
||
|
index 55a6ca90fb..e6362f6645 100644
|
||
|
--- a/src/shared/virt.c
|
||
|
+++ b/src/shared/virt.c
|
||
|
@@ -185,7 +185,8 @@ static int detect_vm_dmi(const char **_id) {
|
||
|
|
||
|
/* Returns a short identifier for the various VM implementations */
|
||
|
int detect_vm(const char **id) {
|
||
|
- _cleanup_free_ char *domcap = NULL, *cpuinfo_contents = NULL;
|
||
|
+ _cleanup_free_ char *domcap = NULL;
|
||
|
+ _cleanup_fclose_ FILE *f = NULL;
|
||
|
static thread_local int cached_found = -1;
|
||
|
static thread_local const char *cached_id = NULL;
|
||
|
const char *_id = NULL;
|
||
|
@@ -252,13 +253,36 @@ int detect_vm(const char **id) {
|
||
|
}
|
||
|
|
||
|
/* Detect User-Mode Linux by reading /proc/cpuinfo */
|
||
|
- r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
|
||
|
- if (r < 0)
|
||
|
- return r;
|
||
|
- if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) {
|
||
|
- _id = "uml";
|
||
|
- r = 1;
|
||
|
- goto finish;
|
||
|
+ f = fopen("/proc/cpuinfo", "re");
|
||
|
+ if (!f) {
|
||
|
+ if (errno == ENOENT) {
|
||
|
+ log_debug("/proc/cpuinfo not found, assuming no UML virtualization.");
|
||
|
+ r = 0;
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+ return -errno;
|
||
|
+ }
|
||
|
+ for (;;) {
|
||
|
+ _cleanup_free_ char *line = NULL;
|
||
|
+ const char *t;
|
||
|
+
|
||
|
+ r = read_line(f, LONG_LINE_MAX, &line);
|
||
|
+ if (r < 0)
|
||
|
+ return r;
|
||
|
+ if (r == 0)
|
||
|
+ break;
|
||
|
+
|
||
|
+ t = startswith(line, "vendor_id\t: ");
|
||
|
+ if (t) {
|
||
|
+ if (startswith(t, "User Mode Linux")) {
|
||
|
+ log_debug("UML virtualization found in /proc/cpuinfo");
|
||
|
+ _id = "uml";
|
||
|
+ r = 1;
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ break;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
#if defined(__s390__)
|