perf env: Add helper to lazily compute the os_release

In live mode the os_release isn't being initialized, make a lazy
initialization helper that assumes when the os_release isn't
initialized this is live mode.

Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Honglei Wang <jameshongleiwang@126.com>
Cc: Jan Polensky <japo@linux.ibm.com>
Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Ian Rogers 2026-06-02 08:25:14 -07:00 committed by Arnaldo Carvalho de Melo
parent 0ff9718c26
commit b34c7c147b
6 changed files with 57 additions and 10 deletions

View File

@ -1414,7 +1414,7 @@ do { \
ADD("host", env->hostname);
ADD("sysname", "Linux");
ADD("release", env->os_release);
ADD("release", perf_env__os_release(env));
ADD("version", env->version);
ADD("machine", env->arch);
ADD("domain", "kernel");

View File

@ -16,6 +16,7 @@
#include "linux/err.h"
#include "util/auxtrace.h"
#include "util/debug.h"
#include "util/env.h"
#include "util/dso.h"
#include "util/event.h"
#include "util/evsel.h"
@ -272,7 +273,7 @@ static void output_headers(struct perf_session *session, struct convert_json *c)
{
struct stat st;
const struct perf_header *header = &session->header;
const struct perf_env *env = perf_session__env(session);
struct perf_env *env = perf_session__env(session);
int ret;
int fd = perf_data__fd(session->data);
int i;
@ -296,7 +297,8 @@ static void output_headers(struct perf_session *session, struct convert_json *c)
output_json_key_format(out, true, 2, "feat-offset", "%" PRIu64, header->feat_offset);
output_json_key_string(out, true, 2, "hostname", env->hostname);
output_json_key_string(out, true, 2, "os-release", env->os_release);
output_json_key_string(out, true, 2, "os-release",
perf_env__os_release(env));
output_json_key_string(out, true, 2, "arch", env->arch);
if (env->cpu_desc)

View File

@ -361,6 +361,44 @@ bool perf_arch_is_big_endian(const char *arch)
return false;
}
const char *perf_env__os_release(struct perf_env *env)
{
struct utsname uts;
int ret;
const char *release;
if (!env)
return perf_version_string;
mutex_lock(&env->lock);
if (env->os_release) {
release = env->os_release;
goto out;
}
/*
* If env->arch is set, this is an offline target environment.
* If the os_release is not populated in the file, we do not want
* to poison it with the host's release which would break guest checks.
*/
if (env->arch) {
release = NULL;
goto out;
}
/*
* The os_release is being accessed but wasn't initialized from a data
* file, assume this is 'live' mode and use the release from uname. If
* uname or strdup fails then use the current perf tool version.
*/
ret = uname(&uts);
env->os_release = strdup(ret < 0 ? perf_version_string : uts.release);
release = env->os_release ?: perf_version_string;
out:
mutex_unlock(&env->lock);
return release;
}
int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
{
int i;

View File

@ -176,6 +176,7 @@ void perf_env__exit(struct perf_env *env);
int perf_env__kernel_is_64_bit(struct perf_env *env);
bool perf_arch_is_big_endian(const char *arch);
const char *perf_env__os_release(struct perf_env *env);
int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]);

View File

@ -432,13 +432,19 @@ static int write_osrelease(struct feat_fd *ff,
struct evlist *evlist __maybe_unused)
{
struct utsname uts;
int ret;
const char *release = NULL;
ret = uname(&uts);
if (ret < 0)
return -1;
if (evlist->session)
release = perf_env__os_release(perf_session__env(evlist->session));
return do_write_string(ff, uts.release);
if (!release) {
int ret = uname(&uts);
if (ret < 0)
return -1;
release = uts.release;
}
return do_write_string(ff, release);
}
static int write_arch(struct feat_fd *ff, struct evlist *evlist)

View File

@ -2225,7 +2225,7 @@ static int vmlinux_path__init(struct perf_env *env)
{
struct utsname uts;
char bf[PATH_MAX];
char *kernel_version;
const char *kernel_version;
unsigned int i;
vmlinux_path = malloc(sizeof(char *) * (ARRAY_SIZE(vmlinux_paths) +
@ -2242,7 +2242,7 @@ static int vmlinux_path__init(struct perf_env *env)
return 0;
if (env) {
kernel_version = env->os_release;
kernel_version = perf_env__os_release(env);
} else {
if (uname(&uts) < 0)
goto out_fail;