From patchwork Mon Jun 17 11:52:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 10998865 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 89F7913AF for ; Mon, 17 Jun 2019 11:52:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 78DB728662 for ; Mon, 17 Jun 2019 11:52:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6C9F72858A; Mon, 17 Jun 2019 11:52:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B35322858A for ; Mon, 17 Jun 2019 11:52:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725973AbfFQLwY (ORCPT ); Mon, 17 Jun 2019 07:52:24 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:41296 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725763AbfFQLwY (ORCPT ); Mon, 17 Jun 2019 07:52:24 -0400 Received: by mail-wr1-f67.google.com with SMTP id c2so9610698wrm.8 for ; Mon, 17 Jun 2019 04:52:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=z4mIb9AqZ9eEQ5gCttxCkDbiizETgqiC0ssBre6vZoY=; b=OOcVTx8BZsWI8T1OfWdn1ZVYPxKdp7WjtdhNXHNTiL8qOQN0OEracTndn7v98EVmWZ UAdX6wVnsPMSLspXBW2ahu+ZtqpE+P8UhBUXSiBcst63EJ66XxbY905jplC4Nem8gpZs CLtbe1MYPmeSmKuX7IMeoQxu/cjJkVFKdU5GeT9aA28VgR94wHpgNnu7vEgNVCiXJwSA WuSI/5jmhC/9cyG41AQ1FbdjIWpXdK8CPOlCJANFfMzaZ0lEZbdC1g0h0XVOV18I40Io 4JzJZMdixDqEq8PKv1jUxARId+7j92hB0R1y0+s9Ssz0YAOGwVOLavDMofIwZQJAxieA NRfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=z4mIb9AqZ9eEQ5gCttxCkDbiizETgqiC0ssBre6vZoY=; b=OzbYlga9qcBPvETFkXBaH/PIVUiC9Yo/vsdarRsich/Cfl/NTf/poTNPXIHpUaqYWP s1GnjaN/k49LvaHZNU+Mpyz7yNFd0EqJ3GiL2ZjFROeYQQuKQ2l0bUsplywks8EP3oSo LA/R7H39rbvtbG7imbV3bEAQeXbQwcQKIThsYsMrXP99hhDoSlDjum8Wdzi7jz80igQY 5l+vhjWhX0277hFgyKtE+Bca79U/yrKrLEhM7S6My4d4J/jzdsz8zh3E/fNsWjzdHGBv orb/isTv0rYADNcHzlr/YIo5/lWesQ20nVO086fujEfGsbcfWcftad0d03j+laZtMdze UK9w== X-Gm-Message-State: APjAAAXHa2jc91pfzjYUdiMgkVl3whGKtSWlzI2CYRjeAqixDRynhskE 8C2vPrpgmjPM5BYdwR3GlKU= X-Google-Smtp-Source: APXvYqwbu3SIp2x4HH36aiu0guaCGtyBEBefxuA9dOoOjijz+JAAHneQwL8L2Yl0jWo5v2PCaWMRuA== X-Received: by 2002:a5d:4e50:: with SMTP id r16mr24663532wrt.227.1560772341516; Mon, 17 Jun 2019 04:52:21 -0700 (PDT) Received: from oberon.eng.vmware.com ([146.247.46.5]) by smtp.gmail.com with ESMTPSA id d18sm13332040wrb.90.2019.06.17.04.52.20 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 17 Jun 2019 04:52:20 -0700 (PDT) From: tz.stoyanov@gmail.com To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH 1/2] trace-cmd: Implemented new API tracecmd_add_option_v() Date: Mon, 17 Jun 2019 14:52:17 +0300 Message-Id: <20190617115218.6279-2-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190617115218.6279-1-tz.stoyanov@gmail.com> References: <20190617115218.6279-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Sender: linux-trace-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: "Tzvetomir Stoyanov (VMware)" From: Tzvetomir Stoyanov This patch implements a new tracecmd API, tracecmd_add_option_v() It adds new option in trace.dat, similar to tracecmd_add_option(), but the option's data is passed as list of buffers. The standard struct iovec is used as input parameter, containing the option's data buffers. Signed-off-by: Tzvetomir Stoyanov --- include/trace-cmd/trace-cmd.h | 5 ++ include/traceevent/event-parse.h | 1 + tracecmd/trace-output.c | 117 ++++++++++++++++++++++++++----- 3 files changed, 106 insertions(+), 17 deletions(-) diff --git a/include/trace-cmd/trace-cmd.h b/include/trace-cmd/trace-cmd.h index ceb03f4..3919673 100644 --- a/include/trace-cmd/trace-cmd.h +++ b/include/trace-cmd/trace-cmd.h @@ -245,11 +245,16 @@ struct tracecmd_output *tracecmd_create_init_file_override(const char *output_fi struct tracecmd_option *tracecmd_add_option(struct tracecmd_output *handle, unsigned short id, int size, const void *data); +struct tracecmd_option * +tracecmd_add_option_v(struct tracecmd_output *handle, + unsigned short id, const struct iovec *vector, int count); + struct tracecmd_option *tracecmd_add_buffer_option(struct tracecmd_output *handle, const char *name, int cpus); int tracecmd_write_cpus(struct tracecmd_output *handle, int cpus); int tracecmd_write_options(struct tracecmd_output *handle); +int tracecmd_append_options(struct tracecmd_output *handle); int tracecmd_update_option(struct tracecmd_output *handle, struct tracecmd_option *option, int size, const void *data); diff --git a/include/traceevent/event-parse.h b/include/traceevent/event-parse.h index 5e0fd19..62057b3 100644 --- a/include/traceevent/event-parse.h +++ b/include/traceevent/event-parse.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "trace-seq.h" diff --git a/tracecmd/trace-output.c b/tracecmd/trace-output.c index 33d6ce3..f7a2791 100644 --- a/tracecmd/trace-output.c +++ b/tracecmd/trace-output.c @@ -883,21 +883,23 @@ static struct tracecmd_output *create_file(const char *output_file, } /** - * tracecmd_add_option - add options to the file + * tracecmd_add_option_v - add options to the file * @handle: the output file handle name * @id: the id of the option - * @size: the size of the option data - * @data: the data to write to the file. + * @vector: array of vectors, pointing to the data to write in the file + * @count: number of items in the vector array * * Returns handle to update option if needed. * Just the content can be updated, with smaller or equal to * content than the specified size. */ struct tracecmd_option * -tracecmd_add_option(struct tracecmd_output *handle, - unsigned short id, int size, const void *data) +tracecmd_add_option_v(struct tracecmd_output *handle, + unsigned short id, const struct iovec *vector, int count) { struct tracecmd_option *option; + char *data = NULL; + int i, size = 0; /* * We can only add options before they were written. @@ -906,32 +908,63 @@ tracecmd_add_option(struct tracecmd_output *handle, if (handle->options_written) return NULL; - handle->nr_options++; + for (i = 0; i < count; i++) + size += vector[i].iov_len; + + /* Some IDs (like TRACECMD_OPTION_TRACECLOCK) pass vector with 0 / NULL data */ + if (size) { + data = malloc(size); + if (!data) { + warning("Insufficient memory"); + return NULL; + } + } option = malloc(sizeof(*option)); if (!option) { warning("Could not allocate space for option"); + free(data); return NULL; } - option->id = id; - option->size = size; - option->data = malloc(size); - if (!option->data) { - warning("Insufficient memory"); - free(option); - return NULL; + handle->nr_options++; + option->data = data; + for (i = 0; i < count; i++) { + if (vector[i].iov_base && vector[i].iov_len) { + memcpy(data, vector[i].iov_base, vector[i].iov_len); + data += vector[i].iov_len; + } } - - /* Some IDs (like TRACECMD_OPTION_TRACECLOCK) pass 0 / NULL data */ - if (size) - memcpy(option->data, data, size); + option->size = size; + option->id = id; list_add_tail(&option->list, &handle->options); return option; } +/** + * tracecmd_add_option - add options to the file + * @handle: the output file handle name + * @id: the id of the option + * @size: the size of the option data + * @data: the data to write to the file. + * + * Returns handle to update option if needed. + * Just the content can be updated, with smaller or equal to + * content than the specified size. + */ +struct tracecmd_option * +tracecmd_add_option(struct tracecmd_output *handle, + unsigned short id, int size, const void *data) +{ + struct iovec vect; + + vect.iov_base = (void *) data; + vect.iov_len = size; + return tracecmd_add_option_v(handle, id, &vect, 1); +} + int tracecmd_write_cpus(struct tracecmd_output *handle, int cpus) { cpus = convert_endian_4(handle, cpus); @@ -979,6 +1012,56 @@ int tracecmd_write_options(struct tracecmd_output *handle) return 0; } +int tracecmd_append_options(struct tracecmd_output *handle) +{ + struct tracecmd_option *options; + unsigned short option; + unsigned short endian2; + unsigned int endian4; + off_t offset; + int r; + + /* If already written, ignore */ + if (handle->options_written) + return 0; + + if (lseek64(handle->fd, 0, SEEK_END) == (off_t)-1) + return -1; + offset = lseek64(handle->fd, -2, SEEK_CUR); + if (offset == (off_t)-1) + return -1; + + r = pread(handle->fd, &option, 2, offset); + if (r != 2 || option != TRACECMD_OPTION_DONE) + return -1; + + list_for_each_entry(options, &handle->options, list) { + endian2 = convert_endian_2(handle, options->id); + if (do_write_check(handle, &endian2, 2)) + return -1; + + endian4 = convert_endian_4(handle, options->size); + if (do_write_check(handle, &endian4, 4)) + return -1; + + /* Save the data location in case it needs to be updated */ + options->offset = lseek64(handle->fd, 0, SEEK_CUR); + + if (do_write_check(handle, options->data, + options->size)) + return -1; + } + + option = TRACECMD_OPTION_DONE; + + if (do_write_check(handle, &option, 2)) + return -1; + + handle->options_written = 1; + + return 0; +} + int tracecmd_update_option(struct tracecmd_output *handle, struct tracecmd_option *option, int size, const void *data)