Add compatibility mode for missing require key

Traces with metadata version 1 don't use per-thread information, so we
cannot read the 'require' key. All models will be enabled for old traces
(which will cause performance problems).
This commit is contained in:
Rodrigo Arias 2023-11-10 14:22:13 +01:00
parent 30d5e4b0ca
commit 59385fad03
6 changed files with 47 additions and 12 deletions

View File

@ -18,7 +18,7 @@ extern "C" {
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#define OVNI_METADATA_VERSION 1 #define OVNI_METADATA_VERSION 2
#define OVNI_TRACEDIR "ovni" #define OVNI_TRACEDIR "ovni"
#define OVNI_MAX_HOSTNAME 512 #define OVNI_MAX_HOSTNAME 512

View File

@ -7,6 +7,7 @@
#include "version.h" #include "version.h"
#include "emu.h" #include "emu.h"
#include "thread.h" #include "thread.h"
#include "proc.h"
void void
model_init(struct model *model) model_init(struct model *model)
@ -180,6 +181,23 @@ model_version_probe(struct model_spec *spec, struct emu *emu)
/* Find a stream with an model name key */ /* Find a stream with an model name key */
struct system *sys = &emu->system; struct system *sys = &emu->system;
for (struct thread *t = sys->threads; t; t = t->gnext) { for (struct thread *t = sys->threads; t; t = t->gnext) {
/* If there is not metadata, it may be a stream created with
* older libovni, so ensure the proc metadata version. */
if (t->meta == NULL) {
/* Version 1 doesn't have thread metadata, so we enable
* all models. */
if (t->proc->metadata_version == 1) {
warn("found old metadata (version 1), enabling model %s",
spec->name);
enable = 1;
break;
}
/* Otherwise is an error */
err("missing metadata for thread %s with version > 1", t->id);
return -1;
}
/* The ovni.require key is mandatory */ /* The ovni.require key is mandatory */
JSON_Object *require = json_object_dotget_object(t->meta, "ovni.require"); JSON_Object *require = json_object_dotget_object(t->meta, "ovni.require");
if (require == NULL) { if (require == NULL) {

View File

@ -110,6 +110,14 @@ proc_load_metadata(struct proc *proc, JSON_Object *meta)
return -1; return -1;
} }
JSON_Value *version_val = json_object_get_value(meta, "version");
if (version_val == NULL) {
err("missing attribute 'version' in metadata");
return -1;
}
proc->metadata_version = (int) json_number(version_val);
JSON_Value *appid_val = json_object_get_value(meta, "app_id"); JSON_Value *appid_val = json_object_get_value(meta, "app_id");
if (appid_val == NULL) { if (appid_val == NULL) {
err("missing attribute 'app_id' in metadata"); err("missing attribute 'app_id' in metadata");

View File

@ -19,6 +19,7 @@ struct proc {
int is_init; int is_init;
int metadata_loaded; int metadata_loaded;
int metadata_version;
int pid; int pid;
int index; int index;
int appid; int appid;

View File

@ -50,6 +50,8 @@ create_thread(struct proc *proc, const char *tracedir, const char *relpath)
return NULL; return NULL;
} }
/* Old version 1 doesn't have thread metadata */
if (proc->metadata_version > 1) {
/* Build metadata path */ /* Build metadata path */
char mpath[PATH_MAX]; char mpath[PATH_MAX];
if (snprintf(mpath, PATH_MAX, "%s/%s/thread.%d.json", if (snprintf(mpath, PATH_MAX, "%s/%s/thread.%d.json",
@ -62,6 +64,7 @@ create_thread(struct proc *proc, const char *tracedir, const char *relpath)
err("cannot load metadata from %s", mpath); err("cannot load metadata from %s", mpath);
return NULL; return NULL;
} }
}
if (proc_add_thread(proc, thread) != 0) { if (proc_add_thread(proc, thread) != 0) {
err("failed to add thread to proc"); err("failed to add thread to proc");

View File

@ -153,7 +153,7 @@ thread_init_end(struct thread *th)
} }
if (th->meta == NULL) { if (th->meta == NULL) {
err("missing metadata for thread %s", th->id); err("missing thread metadata for %s", th->id);
return -1; return -1;
} }
@ -448,6 +448,11 @@ thread_migrate_cpu(struct thread *th, struct cpu *cpu)
int int
thread_load_metadata(struct thread *thread, JSON_Object *meta) thread_load_metadata(struct thread *thread, JSON_Object *meta)
{ {
if (meta == NULL) {
err("metadata is null");
return -1;
}
if (thread->meta != NULL) { if (thread->meta != NULL) {
err("thread %s already loaded metadata", thread->id); err("thread %s already loaded metadata", thread->id);
return -1; return -1;