From patchwork Sun Apr 21 19:12:54 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Llu=C3=ADs_Vilanova?= X-Patchwork-Id: 238245 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 134342C010C for ; Mon, 22 Apr 2013 05:18:50 +1000 (EST) Received: from localhost ([::1]:59762 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UTzmi-0000XD-63 for incoming@patchwork.ozlabs.org; Sun, 21 Apr 2013 15:18:48 -0400 Received: from eggs.gnu.org ([208.118.235.92]:35119) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UTzh2-0000WL-UJ for qemu-devel@nongnu.org; Sun, 21 Apr 2013 15:12:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UTzh1-0001tZ-I8 for qemu-devel@nongnu.org; Sun, 21 Apr 2013 15:12:56 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:33206) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UTzh1-0001sw-6l for qemu-devel@nongnu.org; Sun, 21 Apr 2013 15:12:55 -0400 Received: from gw.ac.upc.edu (gw.ac.upc.es [147.83.30.3]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id r3LJCsOa001845 for ; Sun, 21 Apr 2013 21:12:54 +0200 Received: from localhost (unknown [84.88.51.85]) by gw.ac.upc.edu (Postfix) with ESMTP id 7352F6B01A4 for ; Sun, 21 Apr 2013 21:12:54 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Sun, 21 Apr 2013 21:12:54 +0200 Message-Id: <20130421191254.8947.81470.stgit@fimbulvetr.bsc.es> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <20130421191129.8947.77964.stgit@fimbulvetr.bsc.es> References: <20130421191129.8947.77964.stgit@fimbulvetr.bsc.es> User-Agent: StGit/0.16 MIME-Version: 1.0 X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id r3LJCsOa001845 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v3 15/24] instrument: [qmp, qapi] Add control interface X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add QMP commands to control (un)loading of dynamic instrumentation library. Signed-off-by: Lluís Vilanova --- instrument/Makefile.objs | 2 + instrument/control.h | 4 + instrument/qapi-schema.json | 124 +++++++++++++++++++++++++++++++++++++++++++ instrument/qmp.c | 78 +++++++++++++++++++++++++++ qmp-commands.hx | 71 +++++++++++++++++++++++++ qmp.c | 4 + 6 files changed, 283 insertions(+) create mode 100644 instrument/qmp.c diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index e571c71..af1c96b 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -66,3 +66,5 @@ endif # Control code target-obj-y += control.o + +common-obj-$(CONFIG_SOFTMMU) += qmp.o diff --git a/instrument/control.h b/instrument/control.h index a6a648a..77d77ad 100644 --- a/instrument/control.h +++ b/instrument/control.h @@ -21,6 +21,8 @@ * @INSTR_LOAD_ERROR: Error with libdl (see dlerror). * * Error codes for instr_load(). + * + * Warning: Keep in sync with #InstrLoadCode */ typedef enum { INSTR_LOAD_OK, @@ -36,6 +38,8 @@ typedef enum { * @INSTR_UNLOAD_ERROR: Error with libdl (see dlerror). * * Error codes for instr_unload(). + * + * Warning: Keep in sync with #InstrUnloadCode */ typedef enum { INSTR_UNLOAD_OK, diff --git a/instrument/qapi-schema.json b/instrument/qapi-schema.json index e450ddf..900160b 100644 --- a/instrument/qapi-schema.json +++ b/instrument/qapi-schema.json @@ -24,3 +24,127 @@ ## { 'enum': 'InstrType', 'data': [ 'None', 'Static', 'Dynamic' ] } + +## +# @InstrState +# +# Instrumentation state. +# +# Instrumentation is never active if @type is #None. +# +# Instrumentation is always active if @type is #Static. +# +# @type: The system's @InstrType. +# +# @active: Whether an instrumentation is loaded. +# +# @handles: List of handles for currently loaded instrumentation libraries. +# +# Since: 1.5 +## +{ 'type': 'InstrState', + 'data': { 'type': 'InstrType', 'active': 'bool' } } + +## +# @instr-query: +# +# Returns the current instrumentation state. +# +# Since: 1.5 +## +{ 'command': 'instr-query', + 'returns': 'InstrState' } + + +## +# @InstrLoadCode +# +# Result code of an 'instr-load' command. +# +# @OK: Correctly loaded. +# +# @Unavailable: Service not available. +# +# @Error: Error with libdl (see 'msg'). +# +# Since: 1.5 +## +{ 'enum': 'InstrLoadCode' + 'data': [ 'OK', 'Unavailable', 'Error' ] } + +## +# @InstrLoadResult +# +# Result of an 'instr-load' command. +# +# @code: Result code. +# +# @msg: Additional error message. +# +# @handle: Instrumentation library identifier (undefined in case of error). +# +# Since: 1.5 +## +{ 'type': 'InstrLoadResult' + 'data': { 'code': 'InstrLoadCode', 'msg': 'str', 'handle': 'int' } } + +## +# @instr-load: +# +# Load an instrumentation library. +# +# @path: path to the dynamic instrumentation library +# +# @args: arguments to the dynamic instrumentation library +# +# Since: 1.5 +## +{ 'command': 'instr-load', + 'data': { 'path': 'str', '*args': ['String'] }, + 'returns': 'InstrLoadResult' } + + +## +# @InstrUnloadCode +# +# Result code of an 'instr-unload' command. +# +# @OK: Correctly unloaded. +# +# @Unavailable: Service not available. +# +# @Invalid: Invalid handle. +# +# @Error: Error with libdl (see 'msg'). +# +# Since: 1.5 +## +{ 'enum': 'InstrUnloadCode' + 'data': [ 'OK', 'Unavailable', 'Invalid', 'Error' ] } + +## +# @InstrUnloadResult +# +# Result of an 'instr-unload' command. +# +# @code: Result code. +# +# @msg: Additional error message. +# +# Since: 1.5 +## +{ 'type': 'InstrUnloadResult' + 'data': { 'code': 'InstrUnloadCode', 'msg': 'str' } } + +## +# @instr-unload: +# +# Unload an instrumentation library. +# +# @handle: Instrumentation library identifier (see #InstrLoadResult). +# +# Since: 1.5 +## +{ 'command': 'instr-unload', + 'data': { 'handle': 'int' }, + 'returns': 'InstrUnloadResult' } diff --git a/instrument/qmp.c b/instrument/qmp.c new file mode 100644 index 0000000..780c06e --- /dev/null +++ b/instrument/qmp.c @@ -0,0 +1,78 @@ +/* + * QMP interface for dynamic trace instrumentation control commands. + * + * Copyright (C) 2012-2013 Lluís Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu-common.h" +#include "qapi/qmp/qerror.h" +#include "qmp-commands.h" + +#include + +#include "instrument/control.h" + + + +InstrState *qmp_instr_query (Error **errp) +{ + InstrState *res = g_malloc0(sizeof(*res)); + res->type = instr_type(); + res->active = instr_active(); + return res; +} + +InstrLoadResult *qmp_instr_load(const char * path, + bool have_args, StringList * args, + Error **errp) +{ + int argc = 0; + const char **argv = NULL; + + StringList *entry = have_args ? args : NULL; + while (entry != NULL) { + argv = realloc(argv, sizeof(*argv) * (argc + 1)); + argv[argc] = entry->value->str; + argc++; + entry = entry->next; + } + + InstrLoadResult *res = g_malloc0(sizeof(*res)); + res->code = instr_load(path, argc, argv, &res->handle); + switch (res->code) { + case INSTR_LOAD_CODE_OK: + case INSTR_LOAD_CODE_UNAVAILABLE: + break; + case INSTR_LOAD_CODE_ERROR: + res->msg = dlerror(); + break; + default: + fprintf(stderr, "Unknown instrumentation load code: %d", res->code); + exit(1); + break; + } + return res; +} + +InstrUnloadResult *qmp_instr_unload(int64_t handle, Error **errp) +{ + InstrUnloadResult *res = g_malloc0(sizeof(*res)); + res->code = instr_unload(handle); + switch (res->code) { + case INSTR_UNLOAD_OK: + case INSTR_UNLOAD_UNAVAILABLE: + case INSTR_UNLOAD_INVALID: + break; + case INSTR_UNLOAD_CODE_ERROR: + res->msg = dlerror(); + break; + default: + fprintf(stderr, "Unknown instrumentation unload code: %d", res->code); + exit(1); + break; + } + return res; +} diff --git a/qmp-commands.hx b/qmp-commands.hx index 1e0e11e..65873dd 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1510,6 +1510,77 @@ Notes: o Commands that prompt the user for data (eg. 'cont' when the block device is encrypted) don't currently work +instr-query +----------- + +Query the instrumentation state. + +Arguments: None. + +Example: + +-> { "execute": "instr-query" } +<- { "return": { "type": "Dynamic", "active": "None" } } + +EQMP + + { + .name = "instr-query", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_instr_query, + }, + + +SQMP + +instr-load +---------- + +Load a dynamic instrumentation library. + +Arguments: + +- path: path to the dynamic instrumentation library +- args: arguments to the dynamic instrumentation library + +Example: + +-> { "execute": "instr-load", "arguments": { "path": "/tmp/libtrace-instrument.so" } } +<- { "return": {} } + +EQMP + + { + .name = "instr-load", + .args_type = "path:F,args:s?", + .mhandler.cmd_new = qmp_marshal_input_instr_load, + }, + + +SQMP + +instr-unload +------------ + +Unload the current dynamic instrumentation library. + +Arguments: None. + +Example: + +-> { "execute": "instr-unload" } +<- { "return": {} } + +EQMP + + { + .name = "instr-unload", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_instr_unload, + }, + + +SQMP 3. Query Commands ================= diff --git a/qmp.c b/qmp.c index 55b056b..72abe03 100644 --- a/qmp.c +++ b/qmp.c @@ -24,6 +24,10 @@ #include "hw/qdev.h" #include "sysemu/blockdev.h" #include "qom/qom-qobject.h" +#if defined(TRACE_INSTRUMENT_DYNAMIC) +#include "instrument/qi-qmp-commands.h" +#endif + NameInfo *qmp_query_name(Error **errp) {