From 59385fad03d20cb19e0df6f19027d6b77943dda7 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Fri, 10 Nov 2023 14:22:13 +0100 Subject: [PATCH] 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). --- include/ovni.h.in | 2 +- src/emu/model.c | 18 ++++++++++++++++++ src/emu/proc.c | 8 ++++++++ src/emu/proc.h | 1 + src/emu/system.c | 23 +++++++++++++---------- src/emu/thread.c | 7 ++++++- 6 files changed, 47 insertions(+), 12 deletions(-) diff --git a/include/ovni.h.in b/include/ovni.h.in index 19d0137..ca371bb 100644 --- a/include/ovni.h.in +++ b/include/ovni.h.in @@ -18,7 +18,7 @@ extern "C" { #include #include -#define OVNI_METADATA_VERSION 1 +#define OVNI_METADATA_VERSION 2 #define OVNI_TRACEDIR "ovni" #define OVNI_MAX_HOSTNAME 512 diff --git a/src/emu/model.c b/src/emu/model.c index a884edb..90db93e 100644 --- a/src/emu/model.c +++ b/src/emu/model.c @@ -7,6 +7,7 @@ #include "version.h" #include "emu.h" #include "thread.h" +#include "proc.h" void 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 */ struct system *sys = &emu->system; 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 */ JSON_Object *require = json_object_dotget_object(t->meta, "ovni.require"); if (require == NULL) { diff --git a/src/emu/proc.c b/src/emu/proc.c index a521d4e..7e4f363 100644 --- a/src/emu/proc.c +++ b/src/emu/proc.c @@ -110,6 +110,14 @@ proc_load_metadata(struct proc *proc, JSON_Object *meta) 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"); if (appid_val == NULL) { err("missing attribute 'app_id' in metadata"); diff --git a/src/emu/proc.h b/src/emu/proc.h index 892e798..e60113b 100644 --- a/src/emu/proc.h +++ b/src/emu/proc.h @@ -19,6 +19,7 @@ struct proc { int is_init; int metadata_loaded; + int metadata_version; int pid; int index; int appid; diff --git a/src/emu/system.c b/src/emu/system.c index 7ba5691..27ac00b 100644 --- a/src/emu/system.c +++ b/src/emu/system.c @@ -50,17 +50,20 @@ create_thread(struct proc *proc, const char *tracedir, const char *relpath) return NULL; } - /* Build metadata path */ - char mpath[PATH_MAX]; - if (snprintf(mpath, PATH_MAX, "%s/%s/thread.%d.json", - tracedir, proc->id, tid) >= PATH_MAX) { - err("path too long"); - return NULL; - } + /* Old version 1 doesn't have thread metadata */ + if (proc->metadata_version > 1) { + /* Build metadata path */ + char mpath[PATH_MAX]; + if (snprintf(mpath, PATH_MAX, "%s/%s/thread.%d.json", + tracedir, proc->id, tid) >= PATH_MAX) { + err("path too long"); + return NULL; + } - if (metadata_load_thread(mpath, thread) != 0) { - err("cannot load metadata from %s", mpath); - return NULL; + if (metadata_load_thread(mpath, thread) != 0) { + err("cannot load metadata from %s", mpath); + return NULL; + } } if (proc_add_thread(proc, thread) != 0) { diff --git a/src/emu/thread.c b/src/emu/thread.c index 7660c38..fcedbe4 100644 --- a/src/emu/thread.c +++ b/src/emu/thread.c @@ -153,7 +153,7 @@ thread_init_end(struct thread *th) } if (th->meta == NULL) { - err("missing metadata for thread %s", th->id); + err("missing thread metadata for %s", th->id); return -1; } @@ -448,6 +448,11 @@ thread_migrate_cpu(struct thread *th, struct cpu *cpu) int thread_load_metadata(struct thread *thread, JSON_Object *meta) { + if (meta == NULL) { + err("metadata is null"); + return -1; + } + if (thread->meta != NULL) { err("thread %s already loaded metadata", thread->id); return -1;