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