mirror of
https://github.com/systemd/systemd.git
synced 2026-08-05 15:40:26 +00:00
Merge pull request #1415 from aakoskin/bootchart-v2
[v2] bootchart: don't fail if "model name" is missing from cpuinfo
This commit is contained in:
@@ -775,15 +775,19 @@ int executable_is_script(const char *path, char **interpreter) {
|
||||
|
||||
/**
|
||||
* Retrieve one field from a file like /proc/self/status. pattern
|
||||
* should start with '\n' and end with a ':'. Whitespace and zeros
|
||||
* after the ':' will be skipped. field must be freed afterwards.
|
||||
* should not include whitespace or the delimiter (':'). pattern matches only
|
||||
* the beginning of a line. Whitespace before ':' is skipped. Whitespace and
|
||||
* zeros after the ':' will be skipped. field must be freed afterwards.
|
||||
* terminator specifies the terminating characters of the field value (not
|
||||
* included in the value).
|
||||
*/
|
||||
int get_status_field(const char *filename, const char *pattern, char **field) {
|
||||
int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
|
||||
_cleanup_free_ char *status = NULL;
|
||||
char *t, *f;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
assert(terminator);
|
||||
assert(filename);
|
||||
assert(pattern);
|
||||
assert(field);
|
||||
@@ -792,11 +796,31 @@ int get_status_field(const char *filename, const char *pattern, char **field) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
t = strstr(status, pattern);
|
||||
if (!t)
|
||||
return -ENOENT;
|
||||
t = status;
|
||||
|
||||
do {
|
||||
bool pattern_ok;
|
||||
|
||||
do {
|
||||
t = strstr(t, pattern);
|
||||
if (!t)
|
||||
return -ENOENT;
|
||||
|
||||
/* Check that pattern occurs in beginning of line. */
|
||||
pattern_ok = (t == status || t[-1] == '\n');
|
||||
|
||||
t += strlen(pattern);
|
||||
|
||||
} while (!pattern_ok);
|
||||
|
||||
t += strspn(t, " \t");
|
||||
if (!*t)
|
||||
return -ENOENT;
|
||||
|
||||
} while (*t != ':');
|
||||
|
||||
t++;
|
||||
|
||||
t += strlen(pattern);
|
||||
if (*t) {
|
||||
t += strspn(t, " \t");
|
||||
|
||||
@@ -812,7 +836,7 @@ int get_status_field(const char *filename, const char *pattern, char **field) {
|
||||
t --;
|
||||
}
|
||||
|
||||
len = strcspn(t, WHITESPACE);
|
||||
len = strcspn(t, terminator);
|
||||
|
||||
f = strndup(t, len);
|
||||
if (!f)
|
||||
|
||||
@@ -48,4 +48,4 @@ int write_env_file(const char *fname, char **l);
|
||||
|
||||
int executable_is_script(const char *path, char **interpreter);
|
||||
|
||||
int get_status_field(const char *filename, const char *pattern, char **field);
|
||||
int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field);
|
||||
|
||||
@@ -215,7 +215,7 @@ int get_process_capeff(pid_t pid, char **capeff) {
|
||||
|
||||
p = procfs_file_alloca(pid, "status");
|
||||
|
||||
r = get_status_field(p, "\nCapEff:", capeff);
|
||||
r = get_proc_field(p, "CapEff", WHITESPACE, capeff);
|
||||
if (r == -ENOENT)
|
||||
return -ESRCH;
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ static int detect_vm_zvm(void) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
int r;
|
||||
|
||||
r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t);
|
||||
r = get_proc_field("/proc/sysinfo", "VM00 Control Program", WHITESPACE, &t);
|
||||
if (r == -ENOENT)
|
||||
return VIRTUALIZATION_NONE;
|
||||
if (r < 0)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <sys/utsname.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "architecture.h"
|
||||
#include "util.h"
|
||||
#include "fileio.h"
|
||||
#include "macro.h"
|
||||
@@ -147,7 +148,7 @@ static int svg_title(FILE *of, const char *build, int pscount, double log_start,
|
||||
_cleanup_free_ char *model = NULL;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
char date[256] = "Unknown";
|
||||
char *cpu;
|
||||
const char *cpu;
|
||||
char *c;
|
||||
time_t t;
|
||||
int r;
|
||||
@@ -188,20 +189,11 @@ static int svg_title(FILE *of, const char *build, int pscount, double log_start,
|
||||
assert_se(r > 0);
|
||||
|
||||
/* CPU type */
|
||||
r = read_full_file("/proc/cpuinfo", &buf, NULL);
|
||||
r = get_proc_field("/proc/cpuinfo", PROC_CPUINFO_MODEL, "\n", &buf);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Unable to read cpuinfo: %m");
|
||||
|
||||
cpu = strstr(buf, "model name");
|
||||
if (!cpu) {
|
||||
log_error("Unable to read module name from cpuinfo.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
cpu += 13;
|
||||
c = strchr(cpu, '\n');
|
||||
if (c)
|
||||
*c = '\0';
|
||||
cpu = "Unknown";
|
||||
else
|
||||
cpu = buf;
|
||||
|
||||
fprintf(of, "<text class=\"t1\" x=\"0\" y=\"30\">Bootchart for %s - %s</text>\n",
|
||||
uts.nodename, date);
|
||||
|
||||
@@ -78,9 +78,11 @@ int uname_architecture(void);
|
||||
#if defined(__x86_64__)
|
||||
# define native_architecture() ARCHITECTURE_X86_64
|
||||
# define LIB_ARCH_TUPLE "x86_64-linux-gnu"
|
||||
# define PROC_CPUINFO_MODEL "model name"
|
||||
#elif defined(__i386__)
|
||||
# define native_architecture() ARCHITECTURE_X86
|
||||
# define LIB_ARCH_TUPLE "i386-linux-gnu"
|
||||
# define PROC_CPUINFO_MODEL "model name"
|
||||
#elif defined(__powerpc64__)
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define native_architecture() ARCHITECTURE_PPC64
|
||||
@@ -89,6 +91,7 @@ int uname_architecture(void);
|
||||
# define native_architecture() ARCHITECTURE_PPC64_LE
|
||||
# define LIB_ARCH_TUPLE "powerpc64le-linux-gnu"
|
||||
# endif
|
||||
# define PROC_CPUINFO_MODEL "cpu"
|
||||
#elif defined(__powerpc__)
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define native_architecture() ARCHITECTURE_PPC
|
||||
@@ -97,15 +100,18 @@ int uname_architecture(void);
|
||||
# define native_architecture() ARCHITECTURE_PPC_LE
|
||||
# error "Missing LIB_ARCH_TUPLE for PPCLE"
|
||||
# endif
|
||||
# define PROC_CPUINFO_MODEL "cpu"
|
||||
#elif defined(__ia64__)
|
||||
# define native_architecture() ARCHITECTURE_IA64
|
||||
# define LIB_ARCH_TUPLE "ia64-linux-gnu"
|
||||
#elif defined(__hppa64__)
|
||||
# define native_architecture() ARCHITECTURE_PARISC64
|
||||
# error "Missing LIB_ARCH_TUPLE for HPPA64"
|
||||
# define PROC_CPUINFO_MODEL "cpu"
|
||||
#elif defined(__hppa__)
|
||||
# define native_architecture() ARCHITECTURE_PARISC
|
||||
# define LIB_ARCH_TUPLE "hppa‑linux‑gnu"
|
||||
# define PROC_CPUINFO_MODEL "cpu"
|
||||
#elif defined(__s390x__)
|
||||
# define native_architecture() ARCHITECTURE_S390X
|
||||
# define LIB_ARCH_TUPLE "s390x-linux-gnu"
|
||||
@@ -115,9 +121,11 @@ int uname_architecture(void);
|
||||
#elif defined(__sparc64__)
|
||||
# define native_architecture() ARCHITECTURE_SPARC64
|
||||
# define LIB_ARCH_TUPLE "sparc64-linux-gnu"
|
||||
# define PROC_CPUINFO_MODEL "cpu"
|
||||
#elif defined(__sparc__)
|
||||
# define native_architecture() ARCHITECTURE_SPARC
|
||||
# define LIB_ARCH_TUPLE "sparc-linux-gnu"
|
||||
# define PROC_CPUINFO_MODEL "cpu"
|
||||
#elif defined(__mips64__)
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define native_architecture() ARCHITECTURE_MIPS64
|
||||
@@ -126,6 +134,7 @@ int uname_architecture(void);
|
||||
# define native_architecture() ARCHITECTURE_MIPS64_LE
|
||||
# error "Missing LIB_ARCH_TUPLE for MIPS64_LE"
|
||||
# endif
|
||||
# define PROC_CPUINFO_MODEL "cpu model"
|
||||
#elif defined(__mips__)
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define native_architecture() ARCHITECTURE_MIPS
|
||||
@@ -134,6 +143,7 @@ int uname_architecture(void);
|
||||
# define native_architecture() ARCHITECTURE_MIPS_LE
|
||||
# define LIB_ARCH_TUPLE "mipsel-linux-gnu"
|
||||
# endif
|
||||
# define PROC_CPUINFO_MODEL "cpu model"
|
||||
#elif defined(__alpha__)
|
||||
# define native_architecture() ARCHITECTURE_ALPHA
|
||||
# define LIB_ARCH_TUPLE "alpha-linux-gnu"
|
||||
@@ -169,6 +179,7 @@ int uname_architecture(void);
|
||||
# define LIB_ARCH_TUPLE "arm-linux-gnu"
|
||||
# endif
|
||||
# endif
|
||||
# define PROC_CPUINFO_MODEL "model name"
|
||||
#elif defined(__sh64__)
|
||||
# define native_architecture() ARCHITECTURE_SH64
|
||||
# error "Missing LIB_ARCH_TUPLE for SH64"
|
||||
@@ -188,5 +199,10 @@ int uname_architecture(void);
|
||||
# error "Please register your architecture here!"
|
||||
#endif
|
||||
|
||||
#ifndef PROC_CPUINFO_MODEL
|
||||
#warning "PROC_CPUINFO_MODEL not defined for your architecture"
|
||||
#define PROC_CPUINFO_MODEL "model name"
|
||||
#endif
|
||||
|
||||
const char *architecture_to_string(int a) _const_;
|
||||
int architecture_from_string(const char *s) _pure_;
|
||||
|
||||
@@ -226,7 +226,7 @@ static bool enough_memory_for_hibernation(void) {
|
||||
if (r < 0)
|
||||
return false;
|
||||
|
||||
r = get_status_field("/proc/meminfo", "\nActive(anon):", &active);
|
||||
r = get_proc_field("/proc/meminfo", "Active(anon)", WHITESPACE, &active);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to retrieve Active(anon) from /proc/meminfo: %m");
|
||||
return false;
|
||||
|
||||
@@ -241,18 +241,18 @@ static void test_status_field(void) {
|
||||
unsigned long long total = 0, buffers = 0;
|
||||
int r;
|
||||
|
||||
assert_se(get_status_field("/proc/self/status", "\nThreads:", &t) == 0);
|
||||
assert_se(get_proc_field("/proc/self/status", "Threads", WHITESPACE, &t) == 0);
|
||||
puts(t);
|
||||
assert_se(streq(t, "1"));
|
||||
|
||||
r = get_status_field("/proc/meminfo", "MemTotal:", &p);
|
||||
r = get_proc_field("/proc/meminfo", "MemTotal", WHITESPACE, &p);
|
||||
if (r != -ENOENT) {
|
||||
assert_se(r == 0);
|
||||
puts(p);
|
||||
assert_se(safe_atollu(p, &total) == 0);
|
||||
}
|
||||
|
||||
r = get_status_field("/proc/meminfo", "\nBuffers:", &s);
|
||||
r = get_proc_field("/proc/meminfo", "Buffers", WHITESPACE, &s);
|
||||
if (r != -ENOENT) {
|
||||
assert_se(r == 0);
|
||||
puts(s);
|
||||
@@ -263,7 +263,7 @@ static void test_status_field(void) {
|
||||
assert_se(buffers < total);
|
||||
|
||||
/* Seccomp should be a good test for field full of zeros. */
|
||||
r = get_status_field("/proc/meminfo", "\nSeccomp:", &z);
|
||||
r = get_proc_field("/proc/meminfo", "Seccomp", WHITESPACE, &z);
|
||||
if (r != -ENOENT) {
|
||||
assert_se(r == 0);
|
||||
puts(z);
|
||||
|
||||
Reference in New Issue
Block a user