Skip to contentSkip to conversation

trace-cmd: Simplify the msg handling

PATCH New Steven Rostedt 1 participant 40 messages Jan 3, 2018

lore
Share & tools
lore
#0 lore raw

cover trace-cmd: Simplify the msg handling

The msg handling of trace-cmd for the listen and record code is overly complex due to the multiplexing functions. Rewrite the code such that it is easier to understand. This will allow us to extend it in the future for the virt-server work.

-- Steve

git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
trace-cmd

Head SHA1: 9420ffed51b5a1a28c175efc41fdd49507acda89

Steven Rostedt (Red Hat) (34):
trace-cmd: Remove the creating of msg out of tracecmd_msg_send()
trace-cmd: Move tracecmd_msg_send_and_wait_for_msg() into its only user
trace-cmd: Turn tracecmd_msg data into an anonymous union
trace-cmd: Remove unused structure tracecmd_msg_error
trace-cmd: Move size and cmd in tracecmd_msg into its own header struct
trace-cmd: Move the tracecmd_msg pointers into their own union
trace-cmd: Just use the buf field for sending pointers
trace-cmd: Use an array to map msg types and min sizes
trace-cmd: Merge msg_do_write_check() into msg_write()
trace-cmd: Simplify msg_free() by using min sizes
trace-cmd: Add tracecmd_msg_init() helper function
trace-cmd: Remove mulitplexer tracecmd_msg_create()
trace-cmd: Simplify msg_read_extra()
trace-cmd: Have msg_free() zero out msg contents
trace-cmd: Verify RINIT was received after TINIT msg sent
trace-cmd: Make send_metadata a flag in the output handle
trace-cmd: Pass cpu count and port array to make_rinit()
trace-cmd: Pass cpu_count instead of having it as a global
trace-cmd: Pass in client_ports instead of using a global variable trace-cmd msg: Add debug prints of messages sent and received trace-cmd msg: Move the saved closing fd to the caller trace-cmd listen: Add better output on error of connections trace-cmd msg: Create a msg_handle to pass around for saved state trace-cmd msg: Add server structure of msg_handler
trace-cmd: Remove global use_tcp variable
trace-cmd: Move protocol version into msg_handler
tracecmd: Clean up handling of cpu_count
tracecmd listen: Have pagesize passed as return not parameter
trace-cmd: Have cpu_count reside in instances and not be global
trace-cmd: Add option CPUCOUNT to buffer instance options
trace-cmd: Have msg_handle part of the buffer instance trace-cmd record: Allow instances to be recorded over the network
trace-cmd: Have keep and profile be flags of buffer instance
trace-cmd: Add network handle into buffer instance

Steven Rostedt (VMware) (4):
trace-cmd recorder: Check if pipe_size was modified by fcntl(F_GETPIPE_SZ)
pevent: Simplify pointer print logic and fix %pF
pevent: Handle new pointer processing of bprint strings
trace-cmd record: Fix clearing out the ctx->instance when used in for_all_instances()

----

 event-parse.c    |  43 ++++-
 trace-cmd.h      |  52 +++++-
 trace-input.c    |  27 ++++
 trace-listen.c   | 138 +++++++++++-----
 trace-local.h    |  15 +-
 trace-msg.c      | 486 ++++++++++++++++++++++++++++---------------------------
 trace-msg.h      |  10 --
 trace-output.c   |  38 ++++-
 trace-record.c   | 391 +++++++++++++++++++++++++++-----------------
 trace-recorder.c |   7 +-
 trace-stat.c     |   2 +-
 11 files changed, 741 insertions(+), 468 deletions(-)
#1 lore raw

PATCH 1/38 trace-cmd recorder: Check if pipe_size was modified by fcntl(F_GETPIPE_SZ)

From: "Steven Rostedt (VMware)" <[email protected]>

If fcntl() does not support F_GETPIPE_SZ, it may still return success, but not modify the page_size variable that was passed to it. Initialize the page_size variable to zero, and if it is not modified by fcntl() then set it to page_size as well.

---
 trace-recorder.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
trace-recorder.c +4 -3
index 08bd90528b7a..75290285d82f 100644
@@ -121,7 +121,7 @@ tracecmd_create_buffer_recorder_fd2(int fd, int fd2, int cpu, unsigned flags,
 {
 	struct tracecmd_recorder *recorder;
 	char *path = NULL;
-	int pipe_size;
+	int pipe_size = 0;
 	int ret;
 
 	recorder = malloc(sizeof(*recorder));
@@ -183,9 +183,10 @@ tracecmd_create_buffer_recorder_fd2(int fd, int fd2, int cpu, unsigned flags,
 		/*
 		 * F_GETPIPE_SZ was introduced in 2.6.35, ftrace was introduced
 		 * in 2.6.31. If we are running on an older kernel, just fall
-		 * back to using page_size for splice().
+		 * back to using page_size for splice(). It could also return
+		 * success, but not modify pipe_size.
 		 */
-		if (ret < 0)
+		if (ret < 0 || !pipe_size)
 			pipe_size = recorder->page_size;
 
 		recorder->pipe_size = pipe_size;
Signature · 1 line
2.13.2
#2 lore raw

PATCH 2/38 pevent: Simplify pointer print logic and fix %pF

In reply to Steven Rostedt

From: "Steven Rostedt (VMware)" <[email protected]>

When processing %pX in pretty_print(), simplify the logic slightly by incrementing the ptr to the format string if isalnum(ptr[1]) is true. This follows the logic a bit more closely to what is in the kernel.

Also, this fixes a small bug where %pF was not giving the offset of the function.

---
 event-parse.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
event-parse.c +9 -8
index 7ef66f853b75..2a6b9ffaa4aa 100644
@@ -4935,21 +4935,22 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
 				else
 					ls = 2;
 
-				if (*(ptr+1) == 'F' || *(ptr+1) == 'f' ||
-				    *(ptr+1) == 'S' || *(ptr+1) == 's') {
+				if (isalnum(ptr[1]))
 					ptr++;
+
+				if (*ptr == 'F' || *ptr == 'f' ||
+				    *ptr == 'S' || *ptr == 's') {
 					show_func = *ptr;
-				} else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') {
-					print_mac_arg(s, *(ptr+1), data, size, event, arg);
-					ptr++;
+				} else if (*ptr == 'M' || *ptr == 'm') {
+					print_mac_arg(s, *ptr, data, size, event, arg);
 					arg = arg->next;
 					break;
-				} else if (*(ptr+1) == 'I' || *(ptr+1) == 'i') {
+				} else if (*ptr == 'I' || *ptr == 'i') {
 					int n;
 
-					n = print_ip_arg(s, ptr+1, data, size, event, arg);
+					n = print_ip_arg(s, ptr, data, size, event, arg);
 					if (n > 0) {
-						ptr += n;
+						ptr += n - 1;
 						arg = arg->next;
 						break;
 					}
Signature · 1 line
2.13.2
#3 lore raw

PATCH 3/38 pevent: Handle new pointer processing of bprint strings

In reply to Steven Rostedt

From: "Steven Rostedt (VMware)" <[email protected]>

The Linux kernel printf() has some extended use cases that dereference the pointer. This is dangerouse for tracing because the pointer that is dereferenced can change or even be unmapped. It also causes issues when the trace data is extracted, because user space does not have access to the contents of the pointer even if it still exists.

To handle this, the kernel was updated to process these dereferenced pointers at the time they are recorded, and not post processed. Now they exist in the tracing buffer, and no dereference is needed at the time of reading the trace.

The event parsing library needs to handle this new case.

---
 event-parse.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
event-parse.c +26 -0
index 2a6b9ffaa4aa..bd288c184d20 100644
@@ -4279,6 +4279,26 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
 				goto process_again;
 			case 'p':
 				ls = 1;
+				if (isalnum(ptr[1])) {
+					ptr++;
+					/* Check for special pointers */
+					switch (*ptr) {
+					case 's':
+					case 'S':
+					case 'f':
+					case 'F':
+						break;
+					default:
+						/*
+						 * Older kernels do not process
+						 * dereferenced pointers.
+						 * Only process if the pointer
+						 * value is a printable.
+						 */
+						if (isprint(*(char *)bptr))
+							goto process_string;
+					}
+				}
 				/* fall through */
 			case 'd':
 			case 'u':
@@ -4331,6 +4351,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
 
 				break;
 			case 's':
+ process_string:
 				arg = alloc_arg();
 				if (!arg) {
 					do_warning_event(event, "%s(%d): not enough memory!",
@@ -4938,6 +4959,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
 				if (isalnum(ptr[1]))
 					ptr++;
 
+				if (arg->type == PRINT_BSTRING) {
+					trace_seq_puts(s, arg->string.string);
+					break;
+				}
+
 				if (*ptr == 'F' || *ptr == 'f' ||
 				    *ptr == 'S' || *ptr == 's') {
 					show_func = *ptr;
Signature · 1 line
2.13.2
#4 lore raw

PATCH 4/38 trace-cmd record: Fix clearing out the ctx->instance when used in for_all_instances()

In reply to Steven Rostedt

From: "Steven Rostedt (VMware)" <[email protected]>

The for_all_instances() macro takes the variable passed to it and uses it as an iterator descriptor. That is, it is set to each instance, and when the loop is complete, the variable will be NULL.

The ctx->instance is suppose to hold the main instance, and by using it as an iterator, it will be NULL at the end. Use a local variable instance.

---
 trace-record.c | 56 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 30 insertions(+), 26 deletions(-)
trace-record.c +30 -26
index f128257662b4..5088f7ae0852 100644
@@ -4784,6 +4784,8 @@ static enum trace_type get_trace_cmd_type(enum trace_cmd cmd)
 
 static void finalize_record_trace(struct common_record_context *ctx)
 {
+	struct buffer_instance *instance;
+
 	if (keep)
 		return;
 
@@ -4797,10 +4799,10 @@ static void finalize_record_trace(struct common_record_context *ctx)
 	tracecmd_remove_instances();
 
 	/* If tracing_on was enabled before we started, set it on now */
-	for_all_instances(ctx->instance) {
-		if (ctx->instance->keep)
-			write_tracing_on(ctx->instance,
-					 ctx->instance->tracing_on_init_val);
+	for_all_instances(instance) {
+		if (instance->keep)
+			write_tracing_on(instance,
+					 instance->tracing_on_init_val);
 	}
 
 	if (host)
@@ -4815,6 +4817,7 @@ static void record_trace(int argc, char **argv,
 			 struct common_record_context *ctx)
 {
 	enum trace_type type = get_trace_cmd_type(ctx->curr_cmd);
+	struct buffer_instance *instance;
 
 	/*
 	 * If top_instance doesn't have any plugins or events, then
@@ -4833,15 +4836,15 @@ static void record_trace(int argc, char **argv,
 		output_file = ctx->output;
 
 	/* Save the state of tracing_on before starting */
-	for_all_instances(ctx->instance) {
+	for_all_instances(instance) {
 
-		if (!ctx->manual && ctx->instance->profile)
-			enable_profile(ctx->instance);
+		if (!ctx->manual && instance->profile)
+			enable_profile(instance);
 
-		ctx->instance->tracing_on_init_val = read_tracing_on(ctx->instance);
+		instance->tracing_on_init_val = read_tracing_on(instance);
 		/* Some instances may not be created yet */
-		if (ctx->instance->tracing_on_init_val < 0)
-			ctx->instance->tracing_on_init_val = 1;
+		if (instance->tracing_on_init_val < 0)
+			instance->tracing_on_init_val = 1;
 	}
 
 	make_instances();
@@ -4854,21 +4857,21 @@ static void record_trace(int argc, char **argv,
 	fset = set_ftrace(!ctx->disable, ctx->total_disable);
 	tracecmd_disable_all_tracing(1);
 
-	for_all_instances(ctx->instance)
-		set_clock(ctx->instance);
+	for_all_instances(instance)
+		set_clock(instance);
 
 	/* Record records the date first */
 	if (IS_RECORD(ctx) && ctx->date)
 		ctx->date2ts = get_date_to_ts();
 
-	for_all_instances(ctx->instance) {
-		set_funcs(ctx->instance);
-		set_mask(ctx->instance);
+	for_all_instances(instance) {
+		set_funcs(instance);
+		set_mask(instance);
 	}
 
 	if (ctx->events) {
-		for_all_instances(ctx->instance)
-			enable_events(ctx->instance);
+		for_all_instances(instance)
+			enable_events(instance);
 	}
 
 	set_buffer_size();
@@ -4876,8 +4879,8 @@ static void record_trace(int argc, char **argv,
 	set_options();
 
 	if (ctx->max_graph_depth) {
-		for_all_instances(ctx->instance)
-			set_max_graph_depth(ctx->instance, ctx->max_graph_depth);
+		for_all_instances(instance)
+			set_max_graph_depth(instance, ctx->max_graph_depth);
 		free(ctx->max_graph_depth);
 	}
 
@@ -4938,6 +4941,7 @@ void trace_start(int argc, char **argv)
 void trace_extract(int argc, char **argv)
 {
 	struct common_record_context ctx;
+	struct buffer_instance *instance;
 	enum trace_type type;
 
 	parse_record_options(argc, argv, CMD_extract, &ctx);
@@ -4951,15 +4955,15 @@ void trace_extract(int argc, char **argv)
 		output_file = ctx.output;
 
 	/* Save the state of tracing_on before starting */
-	for_all_instances(ctx.instance) {
+	for_all_instances(instance) {
 
-		if (!ctx.manual && ctx.instance->profile)
+		if (!ctx.manual && instance->profile)
 			enable_profile(ctx.instance);
 
-		ctx.instance->tracing_on_init_val = read_tracing_on(ctx.instance);
+		instance->tracing_on_init_val = read_tracing_on(instance);
 		/* Some instances may not be created yet */
-		if (ctx.instance->tracing_on_init_val < 0)
-			ctx.instance->tracing_on_init_val = 1;
+		if (instance->tracing_on_init_val < 0)
+			instance->tracing_on_init_val = 1;
 	}
 
 	/* Extracting data records all events in the system. */
@@ -4974,8 +4978,8 @@ void trace_extract(int argc, char **argv)
 	set_options();
 
 	if (ctx.max_graph_depth) {
-		for_all_instances(ctx.instance)
-			set_max_graph_depth(ctx.instance, ctx.max_graph_depth);
+		for_all_instances(instance)
+			set_max_graph_depth(instance, ctx.max_graph_depth);
 		free(ctx.max_graph_depth);
 	}
 
Signature · 1 line
2.13.2
#5 lore raw

PATCH 5/38 trace-cmd: Remove the creating of msg out of tracecmd_msg_send()

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

The creation of different types is getting confusing within the tracecmd_msg_send(). In order to split it up, we first must take the creation of the msg out of it. This will allow us to create specific msg types where they are used, instead of having tracecmd_msg_send() and other functions do the multiplexing.

---
 trace-msg.c | 56 +++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 37 insertions(+), 19 deletions(-)
trace-msg.c +37 -19
index a171179c3606..df45526600c5 100644
@@ -224,6 +224,11 @@ static int tracecmd_msg_create(u32 cmd, struct tracecmd_msg *msg)
 {
 	int ret = 0;
 
+	if (cmd > MSG_FINMETA) {
+		plog("Unsupported command: %d\n", cmd);
+		return -EINVAL;
+	}
+
 	memset(msg, 0, sizeof(*msg));
 	msg->cmd = htonl(cmd);
 
@@ -258,25 +263,15 @@ static void msg_free(struct tracecmd_msg *msg)
 	}
 }
 
-static int tracecmd_msg_send(int fd, u32 cmd)
+static int tracecmd_msg_send(int fd, struct tracecmd_msg *msg)
 {
-	struct tracecmd_msg msg;
 	int ret = 0;
 
-	if (cmd > MSG_FINMETA) {
-		plog("Unsupported command: %d\n", cmd);
-		return -EINVAL;
-	}
-
-	ret = tracecmd_msg_create(cmd, &msg);
-	if (ret < 0)
-		return ret;
-
-	ret = msg_do_write_check(fd, &msg);
+	ret = msg_do_write_check(fd, msg);
 	if (ret < 0)
 		ret = -ECOMM;
 
-	msg_free(&msg);
+	msg_free(msg);
 
 	return ret;
 }
@@ -426,15 +421,21 @@ static int tracecmd_msg_wait_for_msg(int fd, struct tracecmd_msg *msg)
 	return 0;
 }
 
-static int tracecmd_msg_send_and_wait_for_msg(int fd, u32 cmd, struct tracecmd_msg *msg)
+static int tracecmd_msg_send_and_wait_for_msg(int fd, u32 cmd,
+					      struct tracecmd_msg *recv_msg)
 {
+	struct tracecmd_msg msg;
 	int ret;
 
-	ret = tracecmd_msg_send(fd, cmd);
+	ret = tracecmd_msg_create(cmd, &msg);
 	if (ret < 0)
 		return ret;
 
-	ret = tracecmd_msg_wait_for_msg(fd, msg);
+	ret = tracecmd_msg_send(fd, &msg);
+	if (ret < 0)
+		return ret;
+
+	ret = tracecmd_msg_wait_for_msg(fd, recv_msg);
 	if (ret < 0)
 		return ret;
 
@@ -560,12 +561,17 @@ error:
 
 int tracecmd_msg_send_port_array(int fd, int total_cpus, int *ports)
 {
+	struct tracecmd_msg msg;
 	int ret;
 
 	cpu_count = total_cpus;
 	port_array = ports;
 
-	ret = tracecmd_msg_send(fd, MSG_RINIT);
+	ret = tracecmd_msg_create(MSG_RINIT, &msg);
+	if (ret < 0)
+		return ret;
+
+	ret = tracecmd_msg_send(fd, &msg);
 	if (ret < 0)
 		return ret;
 
@@ -574,7 +580,14 @@ int tracecmd_msg_send_port_array(int fd, int total_cpus, int *ports)
 
 void tracecmd_msg_send_close_msg(void)
 {
-	tracecmd_msg_send(psfd, MSG_CLOSE);
+	struct tracecmd_msg msg;
+	int ret;
+
+	ret = tracecmd_msg_create(MSG_CLOSE, &msg);
+	if (ret < 0)
+		return;
+
+	tracecmd_msg_send(psfd, &msg);
 }
 
 int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
@@ -618,9 +631,14 @@ int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
 
 int tracecmd_msg_finish_sending_metadata(int fd)
 {
+	struct tracecmd_msg msg;
 	int ret;
 
-	ret = tracecmd_msg_send(fd, MSG_FINMETA);
+	ret = tracecmd_msg_create(MSG_FINMETA, &msg);
+	if (ret < 0)
+		return ret;
+
+	ret = tracecmd_msg_send(fd, &msg);
 	if (ret < 0)
 		return ret;
 
Signature · 1 line
2.13.2
#6 lore raw

PATCH 6/38 trace-cmd: Move tracecmd_msg_send_and_wait_for_msg() into its only user

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

tracecmd_msg_send_and_wait_for_msg() is a static function that is only used once. Since multiplexing the send code is complex and really each msg type should be processed at where it is used instead of a multiplexer, open code this send function in its only user.

---
 trace-msg.c | 30 +++++++++---------------------
 1 file changed, 9 insertions(+), 21 deletions(-)
trace-msg.c +9 -21
index df45526600c5..4d462f999a4d 100644
@@ -421,41 +421,29 @@ static int tracecmd_msg_wait_for_msg(int fd, struct tracecmd_msg *msg)
 	return 0;
 }
 
-static int tracecmd_msg_send_and_wait_for_msg(int fd, u32 cmd,
-					      struct tracecmd_msg *recv_msg)
+int tracecmd_msg_send_init_data(int fd)
 {
-	struct tracecmd_msg msg;
+	struct tracecmd_msg send_msg;
+	struct tracecmd_msg recv_msg;
+	int i, cpus;
 	int ret;
 
-	ret = tracecmd_msg_create(cmd, &msg);
-	if (ret < 0)
-		return ret;
-
-	ret = tracecmd_msg_send(fd, &msg);
+	ret = tracecmd_msg_create(MSG_TINIT, &send_msg);
 	if (ret < 0)
 		return ret;
 
-	ret = tracecmd_msg_wait_for_msg(fd, recv_msg);
+	ret = tracecmd_msg_send(fd, &send_msg);
 	if (ret < 0)
 		return ret;
 
-	return 0;
-}
-
-int tracecmd_msg_send_init_data(int fd)
-{
-	struct tracecmd_msg msg;
-	int i, cpus;
-	int ret;
-
-	ret = tracecmd_msg_send_and_wait_for_msg(fd, MSG_TINIT, &msg);
+	ret = tracecmd_msg_wait_for_msg(fd, &recv_msg);
 	if (ret < 0)
 		return ret;
 
-	cpus = ntohl(msg.data.rinit.cpus);
+	cpus = ntohl(recv_msg.data.rinit.cpus);
 	client_ports = malloc_or_die(sizeof(int) * cpus);
 	for (i = 0; i < cpus; i++)
-		client_ports[i] = ntohl(msg.data.rinit.port_array[i]);
+		client_ports[i] = ntohl(recv_msg.data.rinit.port_array[i]);
 
 	/* Next, send meta data */
 	send_metadata = true;
Signature · 1 line
2.13.2
#7 lore raw

PATCH 7/38 trace-cmd: Turn tracecmd_msg data into an anonymous union

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

The data union in the tracecmd_msg structure does not need a name. Turn it into an anonymous union, and this will simplify the code.

---
 trace-msg.c | 76 ++++++++++++++++++++++++++++++-------------------------------
 1 file changed, 38 insertions(+), 38 deletions(-)
trace-msg.c +38 -38
index 4d462f999a4d..5e941ed9829e 100644
@@ -53,12 +53,12 @@ typedef __be32 be32;
 #define MSG_META_MAX_LEN		(MSG_MAX_LEN - MIN_META_SIZE)
 
 
-#define MIN_TINIT_SIZE	offsetof(struct tracecmd_msg, data.tinit.opt)
+#define MIN_TINIT_SIZE	offsetof(struct tracecmd_msg, tinit.opt)
 
 /* Not really the minimum, but I couldn't think of a better name */
-#define MIN_RINIT_SIZE offsetof(struct tracecmd_msg, data.rinit.port_array)
+#define MIN_RINIT_SIZE offsetof(struct tracecmd_msg, rinit.port_array)
 
-#define MIN_META_SIZE 	offsetof(struct tracecmd_msg, data.meta.buf)
+#define MIN_META_SIZE 	offsetof(struct tracecmd_msg, meta.buf)
 
 /* for both client and server */
 bool use_tcp;
@@ -123,7 +123,7 @@ struct tracecmd_msg {
 		struct tracecmd_msg_rinit rinit;
 		struct tracecmd_msg_meta meta;
 		struct tracecmd_msg_error err;
-	} data;
+	};
 } __attribute__((packed));
 
 struct tracecmd_msg *errmsg;
@@ -146,13 +146,13 @@ static ssize_t msg_do_write_check(int fd, struct tracecmd_msg *msg)
 
 	switch (ntohl(msg->cmd)) {
 	case MSG_TINIT:
-		ret = msg_write(fd, msg, MIN_TINIT_SIZE, msg->data.tinit.opt);
+		ret = msg_write(fd, msg, MIN_TINIT_SIZE, msg->tinit.opt);
 		break;
 	case MSG_RINIT:
-		ret = msg_write(fd, msg, MIN_RINIT_SIZE, msg->data.rinit.port_array);
+		ret = msg_write(fd, msg, MIN_RINIT_SIZE, msg->rinit.port_array);
 		break;
 	case MSG_SENDMETA:
-		ret = msg_write(fd, msg, MIN_META_SIZE, msg->data.meta.buf);
+		ret = msg_write(fd, msg, MIN_META_SIZE, msg->meta.buf);
 		break;
 	default:
 		ret = __do_write_check(fd, msg, ntohl(msg->size));
@@ -178,13 +178,13 @@ static int make_tinit(struct tracecmd_msg *msg)
 			return -ENOMEM;
 		opt->size = htonl(sizeof(*opt));
 		opt->opt_cmd = htonl(MSGOPT_USETCP);
-		msg->data.tinit.opt = opt;
+		msg->tinit.opt = opt;
 		size += sizeof(*opt);
 	}
 
-	msg->data.tinit.cpus = htonl(cpu_count);
-	msg->data.tinit.page_size = htonl(page_size);
-	msg->data.tinit.opt_num = htonl(opt_num);
+	msg->tinit.cpus = htonl(cpu_count);
+	msg->tinit.page_size = htonl(page_size);
+	msg->tinit.opt_num = htonl(opt_num);
 
 	msg->size = htonl(size);
 
@@ -198,15 +198,15 @@ static int make_rinit(struct tracecmd_msg *msg)
 	be32 port;
 	int i;
 
-	msg->data.rinit.cpus = htonl(cpu_count);
+	msg->rinit.cpus = htonl(cpu_count);
 
-	msg->data.rinit.port_array = malloc(sizeof(*port_array) * cpu_count);
-	if (!msg->data.rinit.port_array)
+	msg->rinit.port_array = malloc(sizeof(*port_array) * cpu_count);
+	if (!msg->rinit.port_array)
 		return -ENOMEM;
 
 	size += sizeof(*port_array) * cpu_count;
 
-	ptr = msg->data.rinit.port_array;
+	ptr = msg->rinit.port_array;
 
 	for (i = 0; i < cpu_count; i++) {
 		/* + rrqports->cpus or rrqports->port_array[i] */
@@ -252,13 +252,13 @@ static void msg_free(struct tracecmd_msg *msg)
 {
 	switch (ntohl(msg->cmd)) {
 	case MSG_TINIT:
-		free(msg->data.tinit.opt);
+		free(msg->tinit.opt);
 		break;
 	case MSG_RINIT:
-		free(msg->data.rinit.port_array);
+		free(msg->rinit.port_array);
 		break;
 	case MSG_SENDMETA:
-		free(msg->data.meta.buf);
+		free(msg->meta.buf);
 		break;
 	}
 }
@@ -323,7 +323,7 @@ static int tracecmd_msg_read_extra(int fd, struct tracecmd_msg *msg, int *n)
 
 	switch (ntohl(msg->cmd)) {
 	case MSG_TINIT:
-		msg->data.tinit.opt = NULL;
+		msg->tinit.opt = NULL;
 
 		rsize = MIN_TINIT_SIZE - *n;
 
@@ -333,19 +333,19 @@ static int tracecmd_msg_read_extra(int fd, struct tracecmd_msg *msg, int *n)
 
 		if (size > *n) {
 			size -= *n;
-			msg->data.tinit.opt = malloc(size);
-			if (!msg->data.tinit.opt)
+			msg->tinit.opt = malloc(size);
+			if (!msg->tinit.opt)
 				return -ENOMEM;
 			*n = 0;
-			return msg_read(fd, msg->data.tinit.opt, size, n);
+			return msg_read(fd, msg->tinit.opt, size, n);
 		}
 		return 0;
 	case MSG_RINIT:
 		return msg_read_extra(fd, msg, n, size, MIN_RINIT_SIZE,
-				      (void **)&msg->data.rinit.port_array);
+				      (void **)&msg->rinit.port_array);
 	case MSG_SENDMETA:
 		return msg_read_extra(fd, msg, n, size, MIN_META_SIZE,
-				      (void **)&msg->data.meta.buf);
+				      (void **)&msg->meta.buf);
 	}
 
 	return msg_read(fd, msg, size - MSG_HDR_LEN, n);
@@ -440,10 +440,10 @@ int tracecmd_msg_send_init_data(int fd)
 	if (ret < 0)
 		return ret;
 
-	cpus = ntohl(recv_msg.data.rinit.cpus);
+	cpus = ntohl(recv_msg.rinit.cpus);
 	client_ports = malloc_or_die(sizeof(int) * cpus);
 	for (i = 0; i < cpus; i++)
-		client_ports[i] = ntohl(recv_msg.data.rinit.port_array[i]);
+		client_ports[i] = ntohl(recv_msg.rinit.port_array[i]);
 
 	/* Next, send meta data */
 	send_metadata = true;
@@ -495,28 +495,28 @@ int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize)
 		goto error;
 	}
 
-	*cpus = ntohl(msg.data.tinit.cpus);
+	*cpus = ntohl(msg.tinit.cpus);
 	plog("cpus=%d\n", *cpus);
 	if (*cpus < 0) {
 		ret = -EINVAL;
 		goto error;
 	}
 
-	*pagesize = ntohl(msg.data.tinit.page_size);
+	*pagesize = ntohl(msg.tinit.page_size);
 	plog("pagesize=%d\n", *pagesize);
 	if (*pagesize <= 0) {
 		ret = -EINVAL;
 		goto error;
 	}
 
-	options = ntohl(msg.data.tinit.opt_num);
+	options = ntohl(msg.tinit.opt_num);
 	for (i = 0; i < options; i++) {
 		if (size + sizeof(*opt) > ntohl(msg.size)) {
 			plog("Not enough message for options\n");
 			ret = -EINVAL;
 			goto error;
 		}
-		opt = (void *)msg.data.tinit.opt + offset;
+		opt = (void *)msg.tinit.opt + offset;
 		offset += ntohl(opt->size);
 		size += ntohl(opt->size);
 		if (ntohl(msg.size) < size) {
@@ -589,23 +589,23 @@ int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
 	if (ret < 0)
 		return ret;
 
-	msg.data.meta.buf = malloc(MSG_META_MAX_LEN);
-	if (!msg.data.meta.buf)
+	msg.meta.buf = malloc(MSG_META_MAX_LEN);
+	if (!msg.meta.buf)
 		return -ENOMEM;
 
-	msg.data.meta.size = htonl(MSG_META_MAX_LEN);
+	msg.meta.size = htonl(MSG_META_MAX_LEN);
 	msg.size = htonl(MIN_META_SIZE + MSG_META_MAX_LEN);
 
 	n = size;
 	do {
 		if (n > MSG_META_MAX_LEN) {
-			memcpy(msg.data.meta.buf, buf+count, MSG_META_MAX_LEN);
+			memcpy(msg.meta.buf, buf+count, MSG_META_MAX_LEN);
 			n -= MSG_META_MAX_LEN;
 			count += MSG_META_MAX_LEN;
 		} else {
 			msg.size = htonl(MIN_META_SIZE + n);
-			msg.data.meta.size = htonl(n);
-			memcpy(msg.data.meta.buf, buf+count, n);
+			msg.meta.size = htonl(n);
+			memcpy(msg.meta.buf, buf+count, n);
 			n = 0;
 		}
 		ret = msg_do_write_check(fd, &msg);
@@ -659,11 +659,11 @@ int tracecmd_msg_collect_metadata(int ifd, int ofd)
 		} else if (cmd != MSG_SENDMETA)
 			goto error;
 
-		n = ntohl(msg.data.meta.size);
+		n = ntohl(msg.meta.size);
 		t = n;
 		s = 0;
 		do {
-			s = write(ofd, msg.data.meta.buf+s, t);
+			s = write(ofd, msg.meta.buf+s, t);
 			if (s < 0) {
 				if (errno == EINTR)
 					continue;
Signature · 1 line
2.13.2
#8 lore raw

PATCH 8/38 trace-cmd: Remove unused structure tracecmd_msg_error

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

The structure tracecmd_msg_error is not used, remove it.

---
 trace-msg.c | 11 -----------
 1 file changed, 11 deletions(-)
trace-msg.c +0 -11
index 5e941ed9829e..09202d930ace 100644
@@ -97,16 +97,6 @@ struct tracecmd_msg_meta {
 	void *buf;
 } __attribute__((packed));
 
-struct tracecmd_msg_error {
-	be32 size;
-	be32 cmd;
-	union {
-		struct tracecmd_msg_tinit tinit;
-		struct tracecmd_msg_rinit rinit;
-		struct tracecmd_msg_meta meta;
-	} data;
-} __attribute__((packed));
-
 enum tracecmd_msg_cmd {
 	MSG_CLOSE	= 1,
 	MSG_TINIT	= 4,
@@ -122,7 +112,6 @@ struct tracecmd_msg {
 		struct tracecmd_msg_tinit tinit;
 		struct tracecmd_msg_rinit rinit;
 		struct tracecmd_msg_meta meta;
-		struct tracecmd_msg_error err;
 	};
 } __attribute__((packed));
 
Signature · 1 line
2.13.2
#9 lore raw

PATCH 9/38 trace-cmd: Move size and cmd in tracecmd_msg into its own header struct

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Move the size and cmd fields of the structure tracecmd_msg into its own header. This will allow us to remove the individual pointers that exist in the anonymous union of the tracecmd_msg structure into their own union. But that will require the individual msg types size defines changing. That change will be simplified if the header is separate.

---
 trace-msg.c | 63 ++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 33 insertions(+), 30 deletions(-)
trace-msg.c +33 -30
index 09202d930ace..2e4a9bfb1d64 100644
@@ -44,8 +44,7 @@ typedef __be32 be32;
 /* Two (4k) pages is the max transfer for now */
 #define MSG_MAX_LEN			8192
 
-					/* size + cmd */
-#define MSG_HDR_LEN			((sizeof(be32)) + (sizeof(be32)))
+#define MSG_HDR_LEN			sizeof(struct tracecmd_msg_header)
 
 #define MSG_DATA_LEN			(MSG_MAX_LEN - MSG_HDR_LEN)
 
@@ -105,13 +104,17 @@ enum tracecmd_msg_cmd {
 	MSG_FINMETA	= 7,
 };
 
+struct tracecmd_msg_header {
+	be32	size;
+	be32	cmd;
+} __attribute__((packed));
+
 struct tracecmd_msg {
-	be32 size;
-	be32 cmd;
+	struct tracecmd_msg_header		hdr;
 	union {
-		struct tracecmd_msg_tinit tinit;
-		struct tracecmd_msg_rinit rinit;
-		struct tracecmd_msg_meta meta;
+		struct tracecmd_msg_tinit	tinit;
+		struct tracecmd_msg_rinit	rinit;
+		struct tracecmd_msg_meta	meta;
 	};
 } __attribute__((packed));
 
@@ -124,16 +127,16 @@ static int msg_write(int fd, struct tracecmd_msg *msg, int size, void *addr)
 	ret = __do_write_check(fd, msg, size);
 	if (ret < 0)
 		return ret;
-	if (ntohl(msg->size) <= size)
+	if (ntohl(msg->hdr.size) <= size)
 		return 0;
-	return __do_write_check(fd, addr, ntohl(msg->size) - size);
+	return __do_write_check(fd, addr, ntohl(msg->hdr.size) - size);
 }
 
 static ssize_t msg_do_write_check(int fd, struct tracecmd_msg *msg)
 {
 	int ret;
 
-	switch (ntohl(msg->cmd)) {
+	switch (ntohl(msg->hdr.cmd)) {
 	case MSG_TINIT:
 		ret = msg_write(fd, msg, MIN_TINIT_SIZE, msg->tinit.opt);
 		break;
@@ -144,7 +147,7 @@ static ssize_t msg_do_write_check(int fd, struct tracecmd_msg *msg)
 		ret = msg_write(fd, msg, MIN_META_SIZE, msg->meta.buf);
 		break;
 	default:
-		ret = __do_write_check(fd, msg, ntohl(msg->size));
+		ret = __do_write_check(fd, msg, ntohl(msg->hdr.size));
 	}
 
 	return ret;
@@ -175,7 +178,7 @@ static int make_tinit(struct tracecmd_msg *msg)
 	msg->tinit.page_size = htonl(page_size);
 	msg->tinit.opt_num = htonl(opt_num);
 
-	msg->size = htonl(size);
+	msg->hdr.size = htonl(size);
 
 	return 0;
 }
@@ -204,7 +207,7 @@ static int make_rinit(struct tracecmd_msg *msg)
 		ptr++;
 	}
 
-	msg->size = htonl(size);
+	msg->hdr.size = htonl(size);
 
 	return 0;
 }
@@ -219,7 +222,7 @@ static int tracecmd_msg_create(u32 cmd, struct tracecmd_msg *msg)
 	}
 
 	memset(msg, 0, sizeof(*msg));
-	msg->cmd = htonl(cmd);
+	msg->hdr.cmd = htonl(cmd);
 
 	switch (cmd) {
 	case MSG_TINIT:
@@ -232,14 +235,14 @@ static int tracecmd_msg_create(u32 cmd, struct tracecmd_msg *msg)
 		break;
 	}
 
-	msg->size = htonl(MSG_HDR_LEN);
+	msg->hdr.size = htonl(MSG_HDR_LEN);
 
 	return ret;
 }
 
 static void msg_free(struct tracecmd_msg *msg)
 {
-	switch (ntohl(msg->cmd)) {
+	switch (ntohl(msg->hdr.cmd)) {
 	case MSG_TINIT:
 		free(msg->tinit.opt);
 		break;
@@ -306,11 +309,11 @@ static int msg_read_extra(int fd, void *buf, int *n,
 
 static int tracecmd_msg_read_extra(int fd, struct tracecmd_msg *msg, int *n)
 {
-	int size = ntohl(msg->size);
+	int size = ntohl(msg->hdr.size);
 	int rsize;
 	int ret;
 
-	switch (ntohl(msg->cmd)) {
+	switch (ntohl(msg->hdr.cmd)) {
 	case MSG_TINIT:
 		msg->tinit.opt = NULL;
 
@@ -353,7 +356,7 @@ static int tracecmd_msg_recv(int fd, struct tracecmd_msg *msg)
 	if (ret < 0)
 		return ret;
 
-	size = ntohl(msg->size);
+	size = ntohl(msg->hdr.size);
 	if (size > MSG_MAX_LEN)
 		/* too big */
 		goto error;
@@ -403,7 +406,7 @@ static int tracecmd_msg_wait_for_msg(int fd, struct tracecmd_msg *msg)
 		return ret;
 	}
 
-	cmd = ntohl(msg->cmd);
+	cmd = ntohl(msg->hdr.cmd);
 	if (cmd == MSG_CLOSE)
 		return -ECONNABORTED;
 
@@ -454,9 +457,9 @@ static void error_operation_for_server(struct tracecmd_msg *msg)
 {
 	u32 cmd;
 
-	cmd = ntohl(msg->cmd);
+	cmd = ntohl(msg->hdr.cmd);
 
-	warning("Message: cmd=%d size=%d\n", cmd, ntohl(msg->size));
+	warning("Message: cmd=%d size=%d\n", cmd, ntohl(msg->hdr.size));
 }
 
 #define MAX_OPTION_SIZE 4096
@@ -478,7 +481,7 @@ int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize)
 		return ret;
 	}
 
-	cmd = ntohl(msg.cmd);
+	cmd = ntohl(msg.hdr.cmd);
 	if (cmd != MSG_TINIT) {
 		ret = -EINVAL;
 		goto error;
@@ -500,7 +503,7 @@ int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize)
 
 	options = ntohl(msg.tinit.opt_num);
 	for (i = 0; i < options; i++) {
-		if (size + sizeof(*opt) > ntohl(msg.size)) {
+		if (size + sizeof(*opt) > ntohl(msg.hdr.size)) {
 			plog("Not enough message for options\n");
 			ret = -EINVAL;
 			goto error;
@@ -508,7 +511,7 @@ int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize)
 		opt = (void *)msg.tinit.opt + offset;
 		offset += ntohl(opt->size);
 		size += ntohl(opt->size);
-		if (ntohl(msg.size) < size) {
+		if (ntohl(msg.hdr.size) < size) {
 			plog("Not enough message for options\n");
 			ret = -EINVAL;
 			goto error;
@@ -583,7 +586,7 @@ int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
 		return -ENOMEM;
 
 	msg.meta.size = htonl(MSG_META_MAX_LEN);
-	msg.size = htonl(MIN_META_SIZE + MSG_META_MAX_LEN);
+	msg.hdr.size = htonl(MIN_META_SIZE + MSG_META_MAX_LEN);
 
 	n = size;
 	do {
@@ -592,7 +595,7 @@ int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
 			n -= MSG_META_MAX_LEN;
 			count += MSG_META_MAX_LEN;
 		} else {
-			msg.size = htonl(MIN_META_SIZE + n);
+			msg.hdr.size = htonl(MIN_META_SIZE + n);
 			msg.meta.size = htonl(n);
 			memcpy(msg.meta.buf, buf+count, n);
 			n = 0;
@@ -641,7 +644,7 @@ int tracecmd_msg_collect_metadata(int ifd, int ofd)
 			return ret;
 		}
 
-		cmd = ntohl(msg.cmd);
+		cmd = ntohl(msg.hdr.cmd);
 		if (cmd == MSG_FINMETA) {
 			/* Finish receiving meta data */
 			break;
@@ -672,12 +675,12 @@ int tracecmd_msg_collect_metadata(int ifd, int ofd)
 			return ret;
 		}
 
-		cmd = ntohl(msg.cmd);
+		cmd = ntohl(msg.hdr.cmd);
 		if (cmd == MSG_CLOSE)
 			/* Finish this connection */
 			break;
 		else {
-			warning("Not accept the message %d", ntohl(msg.cmd));
+			warning("Not accept the message %d", ntohl(msg.hdr.cmd));
 			ret = -EINVAL;
 			goto error;
 		}
Signature · 1 line
2.13.2
#10 lore raw

PATCH 10/38 trace-cmd: Move the tracecmd_msg pointers into their own union

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Move out the pointers in the tracecmd_msg individual type structures into their own union. This will simplify the msg management, as sending and freeing the extra pointers can be done the same for all types of messages.

---
 trace-msg.c | 63 +++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 34 insertions(+), 29 deletions(-)
trace-msg.c +34 -29
index 2e4a9bfb1d64..2e61b297151f 100644
@@ -52,12 +52,15 @@ typedef __be32 be32;
 #define MSG_META_MAX_LEN		(MSG_MAX_LEN - MIN_META_SIZE)
 
 
-#define MIN_TINIT_SIZE	offsetof(struct tracecmd_msg, tinit.opt)
+#define MIN_TINIT_SIZE	(sizeof(struct tracecmd_msg_header) + \
+			 sizeof(struct tracecmd_msg_tinit))
 
 /* Not really the minimum, but I couldn't think of a better name */
-#define MIN_RINIT_SIZE offsetof(struct tracecmd_msg, rinit.port_array)
+#define MIN_RINIT_SIZE	(sizeof(struct tracecmd_msg_header) + \
+			 sizeof(struct tracecmd_msg_rinit))
 
-#define MIN_META_SIZE 	offsetof(struct tracecmd_msg, meta.buf)
+#define MIN_META_SIZE	(sizeof(struct tracecmd_msg_header) + \
+			 sizeof(struct tracecmd_msg_meta))
 
 /* for both client and server */
 bool use_tcp;
@@ -83,17 +86,14 @@ struct tracecmd_msg_tinit {
 	be32 cpus;
 	be32 page_size;
 	be32 opt_num;
-	struct tracecmd_msg_opt *opt;
 } __attribute__((packed));
 
 struct tracecmd_msg_rinit {
 	be32 cpus;
-	be32 *port_array;
 } __attribute__((packed));
 
 struct tracecmd_msg_meta {
 	be32 size;
-	void *buf;
 } __attribute__((packed));
 
 enum tracecmd_msg_cmd {
@@ -116,6 +116,11 @@ struct tracecmd_msg {
 		struct tracecmd_msg_rinit	rinit;
 		struct tracecmd_msg_meta	meta;
 	};
+	union {
+		struct tracecmd_msg_opt		*opt;
+		be32				*port_array;
+		void				*buf;
+	};
 } __attribute__((packed));
 
 struct tracecmd_msg *errmsg;
@@ -138,13 +143,13 @@ static ssize_t msg_do_write_check(int fd, struct tracecmd_msg *msg)
 
 	switch (ntohl(msg->hdr.cmd)) {
 	case MSG_TINIT:
-		ret = msg_write(fd, msg, MIN_TINIT_SIZE, msg->tinit.opt);
+		ret = msg_write(fd, msg, MIN_TINIT_SIZE, msg->opt);
 		break;
 	case MSG_RINIT:
-		ret = msg_write(fd, msg, MIN_RINIT_SIZE, msg->rinit.port_array);
+		ret = msg_write(fd, msg, MIN_RINIT_SIZE, msg->port_array);
 		break;
 	case MSG_SENDMETA:
-		ret = msg_write(fd, msg, MIN_META_SIZE, msg->meta.buf);
+		ret = msg_write(fd, msg, MIN_META_SIZE, msg->buf);
 		break;
 	default:
 		ret = __do_write_check(fd, msg, ntohl(msg->hdr.size));
@@ -170,7 +175,7 @@ static int make_tinit(struct tracecmd_msg *msg)
 			return -ENOMEM;
 		opt->size = htonl(sizeof(*opt));
 		opt->opt_cmd = htonl(MSGOPT_USETCP);
-		msg->tinit.opt = opt;
+		msg->opt = opt;
 		size += sizeof(*opt);
 	}
 
@@ -192,13 +197,13 @@ static int make_rinit(struct tracecmd_msg *msg)
 
 	msg->rinit.cpus = htonl(cpu_count);
 
-	msg->rinit.port_array = malloc(sizeof(*port_array) * cpu_count);
-	if (!msg->rinit.port_array)
+	msg->port_array = malloc(sizeof(*port_array) * cpu_count);
+	if (!msg->port_array)
 		return -ENOMEM;
 
 	size += sizeof(*port_array) * cpu_count;
 
-	ptr = msg->rinit.port_array;
+	ptr = msg->port_array;
 
 	for (i = 0; i < cpu_count; i++) {
 		/* + rrqports->cpus or rrqports->port_array[i] */
@@ -244,13 +249,13 @@ static void msg_free(struct tracecmd_msg *msg)
 {
 	switch (ntohl(msg->hdr.cmd)) {
 	case MSG_TINIT:
-		free(msg->tinit.opt);
+		free(msg->opt);
 		break;
 	case MSG_RINIT:
-		free(msg->rinit.port_array);
+		free(msg->port_array);
 		break;
 	case MSG_SENDMETA:
-		free(msg->meta.buf);
+		free(msg->buf);
 		break;
 	}
 }
@@ -315,7 +320,7 @@ static int tracecmd_msg_read_extra(int fd, struct tracecmd_msg *msg, int *n)
 
 	switch (ntohl(msg->hdr.cmd)) {
 	case MSG_TINIT:
-		msg->tinit.opt = NULL;
+		msg->opt = NULL;
 
 		rsize = MIN_TINIT_SIZE - *n;
 
@@ -325,19 +330,19 @@ static int tracecmd_msg_read_extra(int fd, struct tracecmd_msg *msg, int *n)
 
 		if (size > *n) {
 			size -= *n;
-			msg->tinit.opt = malloc(size);
-			if (!msg->tinit.opt)
+			msg->opt = malloc(size);
+			if (!msg->opt)
 				return -ENOMEM;
 			*n = 0;
-			return msg_read(fd, msg->tinit.opt, size, n);
+			return msg_read(fd, msg->opt, size, n);
 		}
 		return 0;
 	case MSG_RINIT:
 		return msg_read_extra(fd, msg, n, size, MIN_RINIT_SIZE,
-				      (void **)&msg->rinit.port_array);
+				      (void **)&msg->port_array);
 	case MSG_SENDMETA:
 		return msg_read_extra(fd, msg, n, size, MIN_META_SIZE,
-				      (void **)&msg->meta.buf);
+				      (void **)&msg->buf);
 	}
 
 	return msg_read(fd, msg, size - MSG_HDR_LEN, n);
@@ -435,7 +440,7 @@ int tracecmd_msg_send_init_data(int fd)
 	cpus = ntohl(recv_msg.rinit.cpus);
 	client_ports = malloc_or_die(sizeof(int) * cpus);
 	for (i = 0; i < cpus; i++)
-		client_ports[i] = ntohl(recv_msg.rinit.port_array[i]);
+		client_ports[i] = ntohl(recv_msg.port_array[i]);
 
 	/* Next, send meta data */
 	send_metadata = true;
@@ -508,7 +513,7 @@ int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize)
 			ret = -EINVAL;
 			goto error;
 		}
-		opt = (void *)msg.tinit.opt + offset;
+		opt = (void *)msg.opt + offset;
 		offset += ntohl(opt->size);
 		size += ntohl(opt->size);
 		if (ntohl(msg.hdr.size) < size) {
@@ -581,8 +586,8 @@ int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
 	if (ret < 0)
 		return ret;
 
-	msg.meta.buf = malloc(MSG_META_MAX_LEN);
-	if (!msg.meta.buf)
+	msg.buf = malloc(MSG_META_MAX_LEN);
+	if (!msg.buf)
 		return -ENOMEM;
 
 	msg.meta.size = htonl(MSG_META_MAX_LEN);
@@ -591,13 +596,13 @@ int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
 	n = size;
 	do {
 		if (n > MSG_META_MAX_LEN) {
-			memcpy(msg.meta.buf, buf+count, MSG_META_MAX_LEN);
+			memcpy(msg.buf, buf+count, MSG_META_MAX_LEN);
 			n -= MSG_META_MAX_LEN;
 			count += MSG_META_MAX_LEN;
 		} else {
 			msg.hdr.size = htonl(MIN_META_SIZE + n);
 			msg.meta.size = htonl(n);
-			memcpy(msg.meta.buf, buf+count, n);
+			memcpy(msg.buf, buf+count, n);
 			n = 0;
 		}
 		ret = msg_do_write_check(fd, &msg);
@@ -655,7 +660,7 @@ int tracecmd_msg_collect_metadata(int ifd, int ofd)
 		t = n;
 		s = 0;
 		do {
-			s = write(ofd, msg.meta.buf+s, t);
+			s = write(ofd, msg.buf+s, t);
 			if (s < 0) {
 				if (errno == EINTR)
 					continue;
Signature · 1 line
2.13.2
#11 lore raw

PATCH 11/38 trace-cmd: Just use the buf field for sending pointers

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Now that all the pointers in the tracemd_msg structure are in the same location, we can use the generic void *buf field to send out all the data in msg_write(). No need to use different fields.

---
 trace-msg.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
trace-msg.c +5 -5
index 2e61b297151f..b265947027ce 100644
@@ -125,7 +125,7 @@ struct tracecmd_msg {
 
 struct tracecmd_msg *errmsg;
 
-static int msg_write(int fd, struct tracecmd_msg *msg, int size, void *addr)
+static int msg_write(int fd, struct tracecmd_msg *msg, int size)
 {
 	int ret;
 
@@ -134,7 +134,7 @@ static int msg_write(int fd, struct tracecmd_msg *msg, int size, void *addr)
 		return ret;
 	if (ntohl(msg->hdr.size) <= size)
 		return 0;
-	return __do_write_check(fd, addr, ntohl(msg->hdr.size) - size);
+	return __do_write_check(fd, msg->buf, ntohl(msg->hdr.size) - size);
 }
 
 static ssize_t msg_do_write_check(int fd, struct tracecmd_msg *msg)
@@ -143,13 +143,13 @@ static ssize_t msg_do_write_check(int fd, struct tracecmd_msg *msg)
 
 	switch (ntohl(msg->hdr.cmd)) {
 	case MSG_TINIT:
-		ret = msg_write(fd, msg, MIN_TINIT_SIZE, msg->opt);
+		ret = msg_write(fd, msg, MIN_TINIT_SIZE);
 		break;
 	case MSG_RINIT:
-		ret = msg_write(fd, msg, MIN_RINIT_SIZE, msg->port_array);
+		ret = msg_write(fd, msg, MIN_RINIT_SIZE);
 		break;
 	case MSG_SENDMETA:
-		ret = msg_write(fd, msg, MIN_META_SIZE, msg->buf);
+		ret = msg_write(fd, msg, MIN_META_SIZE);
 		break;
 	default:
 		ret = __do_write_check(fd, msg, ntohl(msg->hdr.size));
Signature · 1 line
2.13.2
#12 lore raw

PATCH 12/38 trace-cmd: Use an array to map msg types and min sizes

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Instead of using a switch statement, use an array to map the msg types to the min sizes they have. If they do not have dynamically allocated data to send, the size is simply zero, and the msg->size is used.

This incorporates a macro tuple to map the types and sizes, and will be extended in the future for anything else that needs to be done.

---
 trace-msg.c | 53 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 21 deletions(-)
trace-msg.c +32 -21
index b265947027ce..2583660a7496 100644
@@ -96,19 +96,33 @@ struct tracecmd_msg_meta {
 	be32 size;
 } __attribute__((packed));
 
-enum tracecmd_msg_cmd {
-	MSG_CLOSE	= 1,
-	MSG_TINIT	= 4,
-	MSG_RINIT	= 5,
-	MSG_SENDMETA	= 6,
-	MSG_FINMETA	= 7,
-};
-
 struct tracecmd_msg_header {
 	be32	size;
 	be32	cmd;
 } __attribute__((packed));
 
+#define MSG_MAP						\
+	C(UNUSED_0,	0,	-1),			\
+	C(CLOSE,	1,	0),			\
+	C(USUSED_2,	2,	-1),			\
+	C(UNUSED_3,	3,	-1),			\
+	C(TINIT,	4,	MIN_TINIT_SIZE),	\
+	C(RINIT,	5,	MIN_RINIT_SIZE),	\
+	C(SENDMETA,	6,	MIN_META_SIZE),		\
+	C(FINMETA,	7,	0),
+
+#undef C
+#define C(a,b,c)	MSG_##a = b
+
+enum tracecmd_msg_cmd {
+	MSG_MAP
+};
+
+#undef C
+#define C(a,b,c)	c
+
+static be32 msg_min_sizes[] = { MSG_MAP };
+
 struct tracecmd_msg {
 	struct tracecmd_msg_header		hdr;
 	union {
@@ -139,21 +153,18 @@ static int msg_write(int fd, struct tracecmd_msg *msg, int size)
 
 static ssize_t msg_do_write_check(int fd, struct tracecmd_msg *msg)
 {
+	int size;
 	int ret;
+	int cmd = ntohl(msg->hdr.cmd);
 
-	switch (ntohl(msg->hdr.cmd)) {
-	case MSG_TINIT:
-		ret = msg_write(fd, msg, MIN_TINIT_SIZE);
-		break;
-	case MSG_RINIT:
-		ret = msg_write(fd, msg, MIN_RINIT_SIZE);
-		break;
-	case MSG_SENDMETA:
-		ret = msg_write(fd, msg, MIN_META_SIZE);
-		break;
-	default:
-		ret = __do_write_check(fd, msg, ntohl(msg->hdr.size));
-	}
+	if (cmd > MSG_FINMETA)
+		return -EINVAL;
+
+	size = msg_min_sizes[cmd];
+	if (!size)
+		size = ntohl(msg->hdr.size);
+
+	ret = msg_write(fd, msg, size);
 
 	return ret;
 }
Signature · 1 line
2.13.2
#13 lore raw

PATCH 13/38 trace-cmd: Merge msg_do_write_check() into msg_write()

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

msg_do_write_check() is the only caller of msg_write(). They are small enough not to be two separate functions. As msg_write() is a easier name, merge msg_do_write_check() into msg_write() and have all the callers of msg_do_write_check() call msg_write() instead.

---
 trace-msg.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)
trace-msg.c +10 -19
index 2583660a7496..943eaa5bf15c 100644
@@ -139,23 +139,11 @@ struct tracecmd_msg {
 
 struct tracecmd_msg *errmsg;
 
-static int msg_write(int fd, struct tracecmd_msg *msg, int size)
-{
-	int ret;
-
-	ret = __do_write_check(fd, msg, size);
-	if (ret < 0)
-		return ret;
-	if (ntohl(msg->hdr.size) <= size)
-		return 0;
-	return __do_write_check(fd, msg->buf, ntohl(msg->hdr.size) - size);
-}
-
-static ssize_t msg_do_write_check(int fd, struct tracecmd_msg *msg)
+static int msg_write(int fd, struct tracecmd_msg *msg)
 {
+	int cmd = ntohl(msg->hdr.cmd);
 	int size;
 	int ret;
-	int cmd = ntohl(msg->hdr.cmd);
 
 	if (cmd > MSG_FINMETA)
 		return -EINVAL;
@@ -164,9 +152,12 @@ static ssize_t msg_do_write_check(int fd, struct tracecmd_msg *msg)
 	if (!size)
 		size = ntohl(msg->hdr.size);
 
-	ret = msg_write(fd, msg, size);
-
-	return ret;
+	ret = __do_write_check(fd, msg, size);
+	if (ret < 0)
+		return ret;
+	if (ntohl(msg->hdr.size) <= size)
+		return 0;
+	return __do_write_check(fd, msg->buf, ntohl(msg->hdr.size) - size);
 }
 
 enum msg_opt_command {
@@ -275,7 +266,7 @@ static int tracecmd_msg_send(int fd, struct tracecmd_msg *msg)
 {
 	int ret = 0;
 
-	ret = msg_do_write_check(fd, msg);
+	ret = msg_write(fd, msg);
 	if (ret < 0)
 		ret = -ECOMM;
 
@@ -616,7 +607,7 @@ int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
 			memcpy(msg.buf, buf+count, n);
 			n = 0;
 		}
-		ret = msg_do_write_check(fd, &msg);
+		ret = msg_write(fd, &msg);
 		if (ret < 0)
 			break;
 	} while (n);
Signature · 1 line
2.13.2
#14 lore raw

PATCH 14/38 trace-cmd: Simplify msg_free() by using min sizes

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

msg_free() only needs to free the extra data pointer if the min_size for the command is something greater than zero.

---
 trace-msg.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)
trace-msg.c +4 -10
index 943eaa5bf15c..406f44105470 100644
@@ -249,17 +249,11 @@ static int tracecmd_msg_create(u32 cmd, struct tracecmd_msg *msg)
 
 static void msg_free(struct tracecmd_msg *msg)
 {
-	switch (ntohl(msg->hdr.cmd)) {
-	case MSG_TINIT:
-		free(msg->opt);
-		break;
-	case MSG_RINIT:
-		free(msg->port_array);
-		break;
-	case MSG_SENDMETA:
+	int cmd = ntohl(msg->hdr.cmd);
+
+	/* If a min size is defined, then the buf needs to be freed */
+	if (cmd < MSG_FINMETA && (msg_min_sizes[cmd] > 0))
 		free(msg->buf);
-		break;
-	}
 }
 
 static int tracecmd_msg_send(int fd, struct tracecmd_msg *msg)
Signature · 1 line
2.13.2
#15 lore raw

PATCH 15/38 trace-cmd: Add tracecmd_msg_init() helper function

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

We will eventually be getting rid of tracecmd_msg_create() multiplexer and having separate functions for creating different msg types. This will require having a generic tracecmd_msg_init() to initialize the msg to a default state.

---
 trace-msg.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
trace-msg.c +8 -4
index 406f44105470..5c55eae8f4b3 100644
@@ -219,6 +219,13 @@ static int make_rinit(struct tracecmd_msg *msg)
 	return 0;
 }
 
+static void tracecmd_msg_init(u32 cmd, struct tracecmd_msg *msg)
+{
+	memset(msg, 0, sizeof(*msg));
+	msg->hdr.cmd = htonl(cmd);
+	msg->hdr.size = htonl(MSG_HDR_LEN);
+}
+
 static int tracecmd_msg_create(u32 cmd, struct tracecmd_msg *msg)
 {
 	int ret = 0;
@@ -228,8 +235,7 @@ static int tracecmd_msg_create(u32 cmd, struct tracecmd_msg *msg)
 		return -EINVAL;
 	}
 
-	memset(msg, 0, sizeof(*msg));
-	msg->hdr.cmd = htonl(cmd);
+	tracecmd_msg_init(cmd, msg);
 
 	switch (cmd) {
 	case MSG_TINIT:
@@ -242,8 +248,6 @@ static int tracecmd_msg_create(u32 cmd, struct tracecmd_msg *msg)
 		break;
 	}
 
-	msg->hdr.size = htonl(MSG_HDR_LEN);
-
 	return ret;
 }
 
Signature · 1 line
2.13.2
#16 lore raw

PATCH 16/38 trace-cmd: Remove mulitplexer tracecmd_msg_create()

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

The multiplexer function tracecmd_msg_create() was confusing, as it required all creation of messages to go through it, instead of being created where they are used. By removing this function and creating each msg where they are used, it will allow the msg protocol to scale.

---
 trace-msg.c | 46 +++++++---------------------------------------
 1 file changed, 7 insertions(+), 39 deletions(-)
trace-msg.c +7 -39
index 5c55eae8f4b3..69d1cd19f0ac 100644
@@ -226,31 +226,6 @@ static void tracecmd_msg_init(u32 cmd, struct tracecmd_msg *msg)
 	msg->hdr.size = htonl(MSG_HDR_LEN);
 }
 
-static int tracecmd_msg_create(u32 cmd, struct tracecmd_msg *msg)
-{
-	int ret = 0;
-
-	if (cmd > MSG_FINMETA) {
-		plog("Unsupported command: %d\n", cmd);
-		return -EINVAL;
-	}
-
-	tracecmd_msg_init(cmd, msg);
-
-	switch (cmd) {
-	case MSG_TINIT:
-		return make_tinit(msg);
-	case MSG_RINIT:
-		return make_rinit(msg);
-	case MSG_CLOSE:
-	case MSG_SENDMETA: /* meta data is not stored here. */
-	case MSG_FINMETA:
-		break;
-	}
-
-	return ret;
-}
-
 static void msg_free(struct tracecmd_msg *msg)
 {
 	int cmd = ntohl(msg->hdr.cmd);
@@ -425,7 +400,8 @@ int tracecmd_msg_send_init_data(int fd)
 	int i, cpus;
 	int ret;
 
-	ret = tracecmd_msg_create(MSG_TINIT, &send_msg);
+	tracecmd_msg_init(MSG_TINIT, &send_msg);
+	ret = make_tinit(&send_msg);
 	if (ret < 0)
 		return ret;
 
@@ -552,7 +528,8 @@ int tracecmd_msg_send_port_array(int fd, int total_cpus, int *ports)
 	cpu_count = total_cpus;
 	port_array = ports;
 
-	ret = tracecmd_msg_create(MSG_RINIT, &msg);
+	tracecmd_msg_init(MSG_RINIT, &msg);
+	ret = make_rinit(&msg);
 	if (ret < 0)
 		return ret;
 
@@ -566,12 +543,8 @@ int tracecmd_msg_send_port_array(int fd, int total_cpus, int *ports)
 void tracecmd_msg_send_close_msg(void)
 {
 	struct tracecmd_msg msg;
-	int ret;
-
-	ret = tracecmd_msg_create(MSG_CLOSE, &msg);
-	if (ret < 0)
-		return;
 
+	tracecmd_msg_init(MSG_CLOSE, &msg);
 	tracecmd_msg_send(psfd, &msg);
 }
 
@@ -582,9 +555,7 @@ int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
 	int ret;
 	int count = 0;
 
-	ret = tracecmd_msg_create(MSG_SENDMETA, &msg);
-	if (ret < 0)
-		return ret;
+	tracecmd_msg_init(MSG_SENDMETA, &msg);
 
 	msg.buf = malloc(MSG_META_MAX_LEN);
 	if (!msg.buf)
@@ -619,10 +590,7 @@ int tracecmd_msg_finish_sending_metadata(int fd)
 	struct tracecmd_msg msg;
 	int ret;
 
-	ret = tracecmd_msg_create(MSG_FINMETA, &msg);
-	if (ret < 0)
-		return ret;
-
+	tracecmd_msg_init(MSG_FINMETA, &msg);
 	ret = tracecmd_msg_send(fd, &msg);
 	if (ret < 0)
 		return ret;
Signature · 1 line
2.13.2
#17 lore raw

PATCH 17/38 trace-cmd: Simplify msg_read_extra()

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

With the extra data pointers all in the same location in tracecmd_msg structure, and with the min_size command mapping, there's no reason to multiplex the receiving of messages. Read the header first, then determine by the cmd the min size to read. If more is needed, then allocate to the generic buffer which will fill in all the other pointers.

This allows us to remove tracecmd_msg_read_extra() and use just msg_read_extra() in its stead.

---
 trace-msg.c | 67 +++++++++++++++++++------------------------------------------
 1 file changed, 21 insertions(+), 46 deletions(-)
trace-msg.c +21 -46
index 69d1cd19f0ac..ff89c4478f6f 100644
@@ -267,60 +267,35 @@ static int msg_read(int fd, void *buf, u32 size, int *n)
 	return 0;
 }
 
-static int msg_read_extra(int fd, void *buf, int *n,
-			  int size, int min_size, void **addr)
+static int msg_read_extra(int fd, struct tracecmd_msg *msg,
+			  int *n, int size)
 {
+	u32 cmd;
 	int rsize;
 	int ret;
 
-	rsize = min_size - *n;
-	ret = msg_read(fd, buf, rsize, n);
-	if (ret < 0)
-		return ret;
-	size -= *n;
-	if (size < 0)
-		return -ENOMSG;
-	*addr = malloc(size);
-	if (!*addr)
-		return -ENOMEM;
-	*n = 0;
-	return msg_read(fd, *addr, size, n);
-}
-
-static int tracecmd_msg_read_extra(int fd, struct tracecmd_msg *msg, int *n)
-{
-	int size = ntohl(msg->hdr.size);
-	int rsize;
-	int ret;
-
-	switch (ntohl(msg->hdr.cmd)) {
-	case MSG_TINIT:
-		msg->opt = NULL;
+	cmd = ntohl(msg->hdr.cmd);
+	if (cmd > MSG_FINMETA)
+		return -EINVAL;
 
-		rsize = MIN_TINIT_SIZE - *n;
+	rsize = msg_min_sizes[cmd] - *n;
+	if (rsize <= 0)
+		return 0;
 
-		ret = msg_read(fd, msg, rsize, n);
-		if (ret < 0)
-			return ret;
+	ret = msg_read(fd, msg, rsize, n);
+	if (ret < 0)
+		return ret;
 
-		if (size > *n) {
-			size -= *n;
-			msg->opt = malloc(size);
-			if (!msg->opt)
-				return -ENOMEM;
-			*n = 0;
-			return msg_read(fd, msg->opt, size, n);
-		}
-		return 0;
-	case MSG_RINIT:
-		return msg_read_extra(fd, msg, n, size, MIN_RINIT_SIZE,
-				      (void **)&msg->port_array);
-	case MSG_SENDMETA:
-		return msg_read_extra(fd, msg, n, size, MIN_META_SIZE,
-				      (void **)&msg->buf);
+	if (size > *n) {
+		size -= *n;
+		msg->buf = malloc(size);
+		if (!msg->buf)
+			return -ENOMEM;
+		*n = 0;
+		return msg_read(fd, msg->buf, size, n);
 	}
 
-	return msg_read(fd, msg, size - MSG_HDR_LEN, n);
+	return 0;
 }
 
 /*
@@ -344,7 +319,7 @@ static int tracecmd_msg_recv(int fd, struct tracecmd_msg *msg)
 		/* too small */
 		goto error;
 	else if (size > MSG_HDR_LEN)
-		return tracecmd_msg_read_extra(fd, msg, &n);
+		return msg_read_extra(fd, msg, &n, size);
 
 	return 0;
 error:
Signature · 1 line
2.13.2
#18 lore raw

PATCH 18/38 trace-cmd: Have msg_free() zero out msg contents

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

When msg_free() is called, the msg contents should never be used after that. To ensure that it does not contain residual data, have msg_free() zero out the msg before returning.

---
 trace-msg.c | 2 ++
 1 file changed, 2 insertions(+)
trace-msg.c +2 -0
index ff89c4478f6f..e1abbbb99bb4 100644
@@ -233,6 +233,8 @@ static void msg_free(struct tracecmd_msg *msg)
 	/* If a min size is defined, then the buf needs to be freed */
 	if (cmd < MSG_FINMETA && (msg_min_sizes[cmd] > 0))
 		free(msg->buf);
+
+	memset(msg, 0, sizeof(*msg));
 }
 
 static int tracecmd_msg_send(int fd, struct tracecmd_msg *msg)
Signature · 1 line
2.13.2
#19 lore raw

PATCH 19/38 trace-cmd: Verify RINIT was received after TINIT msg sent

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

After the init data is sent to the server, make sure that it is a RINIT that is received before processing the ports.

---
 trace-msg.c | 3 +++
 1 file changed, 3 insertions(+)
trace-msg.c +3 -0
index e1abbbb99bb4..453901981c90 100644
@@ -390,6 +390,9 @@ int tracecmd_msg_send_init_data(int fd)
 	if (ret < 0)
 		return ret;
 
+	if (ntohl(recv_msg.hdr.cmd) != MSG_RINIT)
+		return -EINVAL;
+
 	cpus = ntohl(recv_msg.rinit.cpus);
 	client_ports = malloc_or_die(sizeof(int) * cpus);
 	for (i = 0; i < cpus; i++)
Signature · 1 line
2.13.2
#20 lore raw

PATCH 20/38 trace-cmd: Make send_metadata a flag in the output handle

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Instead of having a global variable called "send_metadata", have the network setup pass in a flag to enabled sending the meta data via messages instead of just writing to the file descriptor.

---
 trace-cmd.h    |  2 +-
 trace-msg.c    |  4 ----
 trace-msg.h    |  1 -
 trace-output.c | 20 ++++++++++++++------
 trace-record.c |  3 ++-
 5 files changed, 17 insertions(+), 13 deletions(-)
trace-cmd.h +1 -1
index 6fd34d7fbd21..37177a6b6c3e 100644
@@ -244,7 +244,7 @@ tracecmd_create_init_file_glob(const char *output_file,
 			       struct tracecmd_event_list *list);
 struct tracecmd_output *tracecmd_create_init_fd(int fd);
 struct tracecmd_output *
-tracecmd_create_init_fd_glob(int fd, struct tracecmd_event_list *list);
+tracecmd_create_init_fd_glob(int fd, struct tracecmd_event_list *list, bool send_meta);
 struct tracecmd_output *tracecmd_create_init_file(const char *output_file);
 struct tracecmd_output *tracecmd_create_init_file_override(const char *output_file,
 							   const char *tracing_dir,
trace-msg.c +0 -4
index 453901981c90..ab64f3f28f5e 100644
@@ -70,7 +70,6 @@ int cpu_count;
 static int psfd;
 unsigned int page_size;
 int *client_ports;
-bool send_metadata;
 
 /* for server */
 static int *port_array;
@@ -398,9 +397,6 @@ int tracecmd_msg_send_init_data(int fd)
 	for (i = 0; i < cpus; i++)
 		client_ports[i] = ntohl(recv_msg.port_array[i]);
 
-	/* Next, send meta data */
-	send_metadata = true;
-
 	return 0;
 }
 
trace-msg.h +0 -1
index 0cc972cadc55..feae24ff4fd6 100644
@@ -17,7 +17,6 @@ extern int cpu_count;
 /* for client */
 extern unsigned int page_size;
 extern int *client_ports;
-extern bool send_metadata;
 
 /* for server */
 extern bool done;
trace-output.c +14 -6
index 9d7707f7ba79..d04c4019640f 100644
@@ -57,10 +57,15 @@ struct tracecmd_option {
 	struct list_head list;
 };
 
+enum {
+	OUTPUT_FL_SEND_META	= (1 << 0),
+};
+
 struct tracecmd_output {
 	int		fd;
 	int		page_size;
 	int		cpus;
+	int		flags;
 	struct pevent	*pevent;
 	char		*tracing_dir;
 	int		options_written;
@@ -83,7 +88,7 @@ struct list_event_system {
 static stsize_t
 do_write_check(struct tracecmd_output *handle, const void *data, tsize_t size)
 {
-	if (send_metadata)
+	if (handle->flags & OUTPUT_FL_SEND_META)
 		return tracecmd_msg_metadata_send(handle->fd, data, size);
 
 	return __do_write_check(handle->fd, data, size);
@@ -777,7 +782,7 @@ static struct tracecmd_output *
 create_file_fd(int fd, struct tracecmd_input *ihandle,
 	       const char *tracing_dir,
 	       const char *kallsyms,
-	       struct tracecmd_event_list *list)
+	       struct tracecmd_event_list *list, bool send_meta)
 {
 	struct tracecmd_output *handle;
 	struct pevent *pevent;
@@ -789,6 +794,9 @@ create_file_fd(int fd, struct tracecmd_input *ihandle,
 		return NULL;
 	memset(handle, 0, sizeof(*handle));
 
+	if (send_meta)
+		handle->flags |= OUTPUT_FL_SEND_META;
+
 	handle->fd = fd;
 	if (tracing_dir) {
 		handle->tracing_dir = strdup(tracing_dir);
@@ -880,7 +888,7 @@ static struct tracecmd_output *create_file(const char *output_file,
 	if (fd < 0)
 		return NULL;
 
-	handle = create_file_fd(fd, ihandle, tracing_dir, kallsyms, list);
+	handle = create_file_fd(fd, ihandle, tracing_dir, kallsyms, list, false);
 	if (!handle) {
 		close(fd);
 		unlink(output_file);
@@ -1310,13 +1318,13 @@ struct tracecmd_output *tracecmd_create_file(const char *output_file,
 
 struct tracecmd_output *tracecmd_create_init_fd(int fd)
 {
-	return create_file_fd(fd, NULL, NULL, NULL, &all_event_list);
+	return create_file_fd(fd, NULL, NULL, NULL, &all_event_list, false);
 }
 
 struct tracecmd_output *
-tracecmd_create_init_fd_glob(int fd, struct tracecmd_event_list *list)
+tracecmd_create_init_fd_glob(int fd, struct tracecmd_event_list *list, bool send_meta)
 {
-	return create_file_fd(fd, NULL, NULL, NULL, list);
+	return create_file_fd(fd, NULL, NULL, NULL, list, send_meta);
 }
 
 struct tracecmd_output *
trace-record.c +2 -1
index 5088f7ae0852..48640af8acac 100644
@@ -2865,7 +2865,8 @@ again:
 		communicate_with_listener_v1(sfd);
 
 	/* Now create the handle through this socket */
-	network_handle = tracecmd_create_init_fd_glob(sfd, listed_events);
+	network_handle = tracecmd_create_init_fd_glob(sfd, listed_events,
+						      proto_ver == V2_PROTOCOL);
 
 	if (proto_ver == V2_PROTOCOL)
 		tracecmd_msg_finish_sending_metadata(sfd);
Signature · 1 line
2.13.2
#21 lore raw

PATCH 21/38 trace-cmd: Pass cpu count and port array to make_rinit()

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Instead of having a global variable for the port arrays, pass it to make_rinit() directly. Then we can remove the static port array variable.

Also pass cpu_count, as that will help in removing cpu_count as a global as well.

---
 trace-msg.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)
trace-msg.c +7 -11
index ab64f3f28f5e..0402a069ff21 100644
@@ -72,7 +72,6 @@ unsigned int page_size;
 int *client_ports;
 
 /* for server */
-static int *port_array;
 bool done;
 
 struct tracecmd_msg_opt {
@@ -189,26 +188,26 @@ static int make_tinit(struct tracecmd_msg *msg)
 	return 0;
 }
 
-static int make_rinit(struct tracecmd_msg *msg)
+static int make_rinit(struct tracecmd_msg *msg, int total_cpus, int *ports)
 {
 	int size = MIN_RINIT_SIZE;
 	be32 *ptr;
 	be32 port;
 	int i;
 
-	msg->rinit.cpus = htonl(cpu_count);
+	msg->rinit.cpus = htonl(total_cpus);
 
-	msg->port_array = malloc(sizeof(*port_array) * cpu_count);
+	msg->port_array = malloc(sizeof(*ports) * total_cpus);
 	if (!msg->port_array)
 		return -ENOMEM;
 
-	size += sizeof(*port_array) * cpu_count;
+	size += sizeof(*ports) * total_cpus;
 
 	ptr = msg->port_array;
 
-	for (i = 0; i < cpu_count; i++) {
+	for (i = 0; i < total_cpus; i++) {
 		/* + rrqports->cpus or rrqports->port_array[i] */
-		port = htonl(port_array[i]);
+		port = htonl(ports[i]);
 		*ptr = port;
 		ptr++;
 	}
@@ -501,11 +500,8 @@ int tracecmd_msg_send_port_array(int fd, int total_cpus, int *ports)
 	struct tracecmd_msg msg;
 	int ret;
 
-	cpu_count = total_cpus;
-	port_array = ports;
-
 	tracecmd_msg_init(MSG_RINIT, &msg);
-	ret = make_rinit(&msg);
+	ret = make_rinit(&msg, total_cpus, ports);
 	if (ret < 0)
 		return ret;
 
Signature · 1 line
2.13.2
#22 lore raw

PATCH 22/38 trace-cmd: Pass cpu_count instead of having it as a global

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Pass in the cpu_count to the msg code from trace record instead of using a global variable.

---
 trace-cmd.h    | 2 +-
 trace-msg.c    | 9 ++++-----
 trace-msg.h    | 1 -
 trace-record.c | 3 ++-
 4 files changed, 7 insertions(+), 8 deletions(-)
trace-cmd.h +1 -1
index 37177a6b6c3e..5a5b6bf88574 100644
@@ -297,7 +297,7 @@ void tracecmd_disable_tracing(void);
 void tracecmd_enable_tracing(void);
 
 /* for clients */
-int tracecmd_msg_send_init_data(int fd);
+int tracecmd_msg_send_init_data(int fd, int total_cpus);
 int tracecmd_msg_metadata_send(int fd, const char *buf, int size);
 int tracecmd_msg_finish_sending_metadata(int fd);
 void tracecmd_msg_send_close_msg(void);
trace-msg.c +4 -5
index 0402a069ff21..9fefe22753d9 100644
@@ -64,7 +64,6 @@ typedef __be32 be32;
 
 /* for both client and server */
 bool use_tcp;
-int cpu_count;
 
 /* for client */
 static int psfd;
@@ -162,7 +161,7 @@ enum msg_opt_command {
 	MSGOPT_USETCP = 1,
 };
 
-static int make_tinit(struct tracecmd_msg *msg)
+static int make_tinit(struct tracecmd_msg *msg, int total_cpus)
 {
 	struct tracecmd_msg_opt *opt;
 	int opt_num = 0;
@@ -179,7 +178,7 @@ static int make_tinit(struct tracecmd_msg *msg)
 		size += sizeof(*opt);
 	}
 
-	msg->tinit.cpus = htonl(cpu_count);
+	msg->tinit.cpus = htonl(total_cpus);
 	msg->tinit.page_size = htonl(page_size);
 	msg->tinit.opt_num = htonl(opt_num);
 
@@ -368,7 +367,7 @@ static int tracecmd_msg_wait_for_msg(int fd, struct tracecmd_msg *msg)
 	return 0;
 }
 
-int tracecmd_msg_send_init_data(int fd)
+int tracecmd_msg_send_init_data(int fd, int total_cpus)
 {
 	struct tracecmd_msg send_msg;
 	struct tracecmd_msg recv_msg;
@@ -376,7 +375,7 @@ int tracecmd_msg_send_init_data(int fd)
 	int ret;
 
 	tracecmd_msg_init(MSG_TINIT, &send_msg);
-	ret = make_tinit(&send_msg);
+	ret = make_tinit(&send_msg, total_cpus);
 	if (ret < 0)
 		return ret;
 
trace-msg.h +0 -1
index feae24ff4fd6..fe72c9d76829 100644
@@ -12,7 +12,6 @@
 
 /* for both client and server */
 extern bool use_tcp;
-extern int cpu_count;
 
 /* for client */
 extern unsigned int page_size;
trace-record.c +2 -1
index 48640af8acac..396050bbaae7 100644
@@ -79,6 +79,7 @@ static const char *output_file = "trace.dat";
 
 static int latency;
 static int sleep_time = 1000;
+static int cpu_count;
 static int recorder_threads;
 static struct pid_record_data *pids;
 static int buffers;
@@ -2755,7 +2756,7 @@ static void communicate_with_listener_v1(int fd)
 
 static void communicate_with_listener_v2(int fd)
 {
-	if (tracecmd_msg_send_init_data(fd) < 0)
+	if (tracecmd_msg_send_init_data(fd, cpu_count) < 0)
 		die("Cannot communicate with server");
 }
 
Signature · 1 line
2.13.2
#23 lore raw

PATCH 23/38 trace-cmd: Pass in client_ports instead of using a global variable

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Instead of using a globla variable for passing around client_ports, just pass it to the trace-msg code via a parameter.

---
 trace-cmd.h    |  2 +-
 trace-msg.c    | 12 ++++++++----
 trace-msg.h    |  1 -
 trace-record.c |  3 ++-
 4 files changed, 11 insertions(+), 7 deletions(-)
trace-cmd.h +1 -1
index 5a5b6bf88574..635b5a58dfe9 100644
@@ -297,7 +297,7 @@ void tracecmd_disable_tracing(void);
 void tracecmd_enable_tracing(void);
 
 /* for clients */
-int tracecmd_msg_send_init_data(int fd, int total_cpus);
+int tracecmd_msg_send_init_data(int fd, int total_cpus, int **client_ports);
 int tracecmd_msg_metadata_send(int fd, const char *buf, int size);
 int tracecmd_msg_finish_sending_metadata(int fd);
 void tracecmd_msg_send_close_msg(void);
trace-msg.c +8 -4
index 9fefe22753d9..4c564eb28f31 100644
@@ -68,7 +68,6 @@ bool use_tcp;
 /* for client */
 static int psfd;
 unsigned int page_size;
-int *client_ports;
 
 /* for server */
 bool done;
@@ -367,13 +366,16 @@ static int tracecmd_msg_wait_for_msg(int fd, struct tracecmd_msg *msg)
 	return 0;
 }
 
-int tracecmd_msg_send_init_data(int fd, int total_cpus)
+int tracecmd_msg_send_init_data(int fd, int total_cpus, int **client_ports)
 {
 	struct tracecmd_msg send_msg;
 	struct tracecmd_msg recv_msg;
+	int *ports;
 	int i, cpus;
 	int ret;
 
+	*client_ports = NULL;
+
 	tracecmd_msg_init(MSG_TINIT, &send_msg);
 	ret = make_tinit(&send_msg, total_cpus);
 	if (ret < 0)
@@ -391,9 +393,11 @@ int tracecmd_msg_send_init_data(int fd, int total_cpus)
 		return -EINVAL;
 
 	cpus = ntohl(recv_msg.rinit.cpus);
-	client_ports = malloc_or_die(sizeof(int) * cpus);
+	ports = malloc_or_die(sizeof(int) * cpus);
 	for (i = 0; i < cpus; i++)
-		client_ports[i] = ntohl(recv_msg.port_array[i]);
+		ports[i] = ntohl(recv_msg.port_array[i]);
+
+	*client_ports = ports;
 
 	return 0;
 }
trace-msg.h +0 -1
index fe72c9d76829..7f6a146aeb10 100644
@@ -15,7 +15,6 @@ extern bool use_tcp;
 
 /* for client */
 extern unsigned int page_size;
-extern int *client_ports;
 
 /* for server */
 extern bool done;
trace-record.c +2 -1
index 396050bbaae7..6b8bb89e4e0d 100644
@@ -88,6 +88,7 @@ static int buffers;
 static int clear_function_filters;
 
 static char *host;
+static int *client_ports;
 static int sfd;
 static struct tracecmd_output *network_handle;
 
@@ -2756,7 +2757,7 @@ static void communicate_with_listener_v1(int fd)
 
 static void communicate_with_listener_v2(int fd)
 {
-	if (tracecmd_msg_send_init_data(fd, cpu_count) < 0)
+	if (tracecmd_msg_send_init_data(fd, cpu_count, &client_ports) < 0)
 		die("Cannot communicate with server");
 }
 
Signature · 1 line
2.13.2
#24 lore raw

PATCH 24/38 trace-cmd msg: Add debug prints of messages sent and received

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

When debug is enabled, show send and recevied messages of trace-cmd listen and record as they communicate with each other.

---
 trace-msg.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
trace-msg.c +30 -0
index 4c564eb28f31..94004f4641be 100644
@@ -29,6 +29,7 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <unistd.h>
 #include <arpa/inet.h>
 #include <sys/types.h>
@@ -41,6 +42,18 @@
 typedef __u32 u32;
 typedef __be32 be32;
 
+static inline void dprint(const char *fmt, ...)
+{
+	va_list ap;
+
+	if (!debug)
+		return;
+
+	va_start(ap, fmt);
+	vprintf(fmt, ap);
+	va_end(ap);
+}
+
 /* Two (4k) pages is the max transfer for now */
 #define MSG_MAX_LEN			8192
 
@@ -119,6 +132,18 @@ enum tracecmd_msg_cmd {
 
 static be32 msg_min_sizes[] = { MSG_MAP };
 
+#undef C
+#define C(a,b,c)	#a
+
+static const char *msg_names[] = { MSG_MAP };
+
+static const char *cmd_to_name(int cmd)
+{
+	if (cmd <= MSG_FINMETA)
+		return msg_names[cmd];
+	return "Unkown";
+}
+
 struct tracecmd_msg {
 	struct tracecmd_msg_header		hdr;
 	union {
@@ -144,6 +169,8 @@ static int msg_write(int fd, struct tracecmd_msg *msg)
 	if (cmd > MSG_FINMETA)
 		return -EINVAL;
 
+	dprint("msg send: %d (%s)\n", cmd, cmd_to_name(cmd));
+
 	size = msg_min_sizes[cmd];
 	if (!size)
 		size = ntohl(msg->hdr.size);
@@ -309,6 +336,9 @@ static int tracecmd_msg_recv(int fd, struct tracecmd_msg *msg)
 	if (ret < 0)
 		return ret;
 
+	dprint("msg received: %d (%s)\n",
+	       ntohl(msg->hdr.cmd), cmd_to_name(ntohl(msg->hdr.cmd)));
+
 	size = ntohl(msg->hdr.size);
 	if (size > MSG_MAX_LEN)
 		/* too big */
Signature · 1 line
2.13.2
#25 lore raw

PATCH 25/38 trace-cmd msg: Move the saved closing fd to the caller

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Instead of having a static variable that gets set to whatever file descriptor is passed to tracecmd_msg_finish_sending_metadata() to be closed with tracecmd_send_close_msg(), have that saved by the caller. As I can imagine lots of nasty bugs happening later on with this side effect fd saving. If the caller controls what file descriptor gets closed, it will be more transparent for later development.

---
 trace-cmd.h    | 2 +-
 trace-msg.c    | 8 ++------
 trace-record.c | 7 +++++--
 3 files changed, 8 insertions(+), 9 deletions(-)
trace-cmd.h +1 -1
index 635b5a58dfe9..7e182779e78b 100644
@@ -300,7 +300,7 @@ void tracecmd_enable_tracing(void);
 int tracecmd_msg_send_init_data(int fd, int total_cpus, int **client_ports);
 int tracecmd_msg_metadata_send(int fd, const char *buf, int size);
 int tracecmd_msg_finish_sending_metadata(int fd);
-void tracecmd_msg_send_close_msg(void);
+void tracecmd_msg_send_close_msg(int fd);
 
 /* for server */
 int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize);
trace-msg.c +2 -6
index 94004f4641be..aaeec06b82e3 100644
@@ -79,7 +79,6 @@ static inline void dprint(const char *fmt, ...)
 bool use_tcp;
 
 /* for client */
-static int psfd;
 unsigned int page_size;
 
 /* for server */
@@ -545,12 +544,12 @@ int tracecmd_msg_send_port_array(int fd, int total_cpus, int *ports)
 	return 0;
 }
 
-void tracecmd_msg_send_close_msg(void)
+void tracecmd_msg_send_close_msg(int fd)
 {
 	struct tracecmd_msg msg;
 
 	tracecmd_msg_init(MSG_CLOSE, &msg);
-	tracecmd_msg_send(psfd, &msg);
+	tracecmd_msg_send(fd, &msg);
 }
 
 int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
@@ -599,9 +598,6 @@ int tracecmd_msg_finish_sending_metadata(int fd)
 	ret = tracecmd_msg_send(fd, &msg);
 	if (ret < 0)
 		return ret;
-
-	/* psfd will be used for closing */
-	psfd = fd;
 	return 0;
 }
 
trace-record.c +5 -2
index 6b8bb89e4e0d..e9e2976f1a94 100644
@@ -90,6 +90,7 @@ static int clear_function_filters;
 static char *host;
 static int *client_ports;
 static int sfd;
+static int psfd;
 static struct tracecmd_output *network_handle;
 
 /* Max size to let a per cpu file get */
@@ -2870,8 +2871,10 @@ again:
 	network_handle = tracecmd_create_init_fd_glob(sfd, listed_events,
 						      proto_ver == V2_PROTOCOL);
 
-	if (proto_ver == V2_PROTOCOL)
+	if (proto_ver == V2_PROTOCOL) {
+		psfd = sfd; /* used for closing */
 		tracecmd_msg_finish_sending_metadata(sfd);
+	}
 
 	/* OK, we are all set, let'r rip! */
 }
@@ -2879,7 +2882,7 @@ again:
 static void finish_network(void)
 {
 	if (proto_ver == V2_PROTOCOL)
-		tracecmd_msg_send_close_msg();
+		tracecmd_msg_send_close_msg(psfd);
 	close(sfd);
 	free(host);
 }
Signature · 1 line
2.13.2
#26 lore raw

PATCH 26/38 trace-cmd listen: Add better output on error of connections

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Some of the errors that happen when a client connects to a server have ambiguous error messages. Clean them up a little.

---
 trace-listen.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
trace-listen.c +4 -2
index bd4c2734f181..cfb0f146244d 100644
@@ -240,7 +240,7 @@ static int process_udp_child(int sfd, const char *host, const char *port,
 		if (r < 0) {
 			if (errno == EINTR)
 				break;
-			pdie("reading client");
+			pdie("reading pages from client");
 		}
 		if (!r)
 			break;
@@ -558,8 +558,10 @@ static int *create_all_readers(int cpus, const char *node, const char *port,
 
 	if (proto_ver == V2_PROTOCOL) {
 		/* send set of port numbers to the client */
-		if (tracecmd_msg_send_port_array(fd, cpus, port_array) < 0)
+		if (tracecmd_msg_send_port_array(fd, cpus, port_array) < 0) {
+			plog("Failed sending port array\n");
 			goto out_free;
+		}
 	} else {
 		/* send the client a comma deliminated set of port numbers */
 		for (cpu = 0; cpu < cpus; cpu++) {
Signature · 1 line
2.13.2
#27 lore raw

PATCH 27/38 trace-cmd msg: Create a msg_handle to pass around for saved state

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Instead of just passing around a file descriptor, create a msg_handle descriptor that can save state of the msg connection. This will be used to localize more variables as well as to add new features.

---
 trace-cmd.h    | 46 ++++++++++++++++++++++-----
 trace-listen.c | 52 +++++++++++++++++++++++--------
 trace-msg.c    | 32 +++++++++++--------
 trace-output.c | 29 ++++++++++-------
 trace-record.c | 98 +++++++++++++++++++++++++++++++++++-----------------------
 5 files changed, 174 insertions(+), 83 deletions(-)
trace-cmd.h +38 -8
index 7e182779e78b..0fce54baea5b 100644
@@ -231,6 +231,7 @@ struct tracecmd_event_list {
 };
 
 struct tracecmd_option;
+struct tracecmd_msg_handle;
 
 struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, int cpus);
 struct tracecmd_output *tracecmd_create_file(const char *output_file,
@@ -244,7 +245,10 @@ tracecmd_create_init_file_glob(const char *output_file,
 			       struct tracecmd_event_list *list);
 struct tracecmd_output *tracecmd_create_init_fd(int fd);
 struct tracecmd_output *
-tracecmd_create_init_fd_glob(int fd, struct tracecmd_event_list *list, bool send_meta);
+tracecmd_create_init_fd_glob(int fd, struct tracecmd_event_list *list);
+struct tracecmd_output *
+tracecmd_create_init_fd_msg(struct tracecmd_msg_handle *msg_handle,
+			    struct tracecmd_event_list *list);
 struct tracecmd_output *tracecmd_create_init_file(const char *output_file);
 struct tracecmd_output *tracecmd_create_init_file_override(const char *output_file,
 							   const char *tracing_dir,
@@ -296,16 +300,42 @@ void tracecmd_disable_all_tracing(int disable_tracer);
 void tracecmd_disable_tracing(void);
 void tracecmd_enable_tracing(void);
 
+enum tracecmd_msg_bits {
+	TRACECMD_MSG_BIT_CLIENT		= 0,
+	TRACECMD_MSG_BIT_SERVER		= 1,
+};
+
+enum tracecmd_msg_flags {
+	TRACECMD_MSG_FL_CLIENT		= (1 << TRACECMD_MSG_BIT_CLIENT),
+	TRACECMD_MSG_FL_SERVER		= (1 << TRACECMD_MSG_BIT_SERVER),
+};
+
+/* for both client and server */
+struct tracecmd_msg_handle {
+	unsigned long		flags;
+	int			fd;
+};
+
+struct tracecmd_msg_handle *
+  tracecmd_msg_handle_alloc(int fd, unsigned long flags);
+
+/* Closes the socket and frees the handle */
+void tracecmd_msg_handle_close(struct tracecmd_msg_handle *msg_handle);
+
 /* for clients */
-int tracecmd_msg_send_init_data(int fd, int total_cpus, int **client_ports);
-int tracecmd_msg_metadata_send(int fd, const char *buf, int size);
-int tracecmd_msg_finish_sending_metadata(int fd);
-void tracecmd_msg_send_close_msg(int fd);
+int tracecmd_msg_send_init_data(struct tracecmd_msg_handle *msg_handle,
+				int total_cpus, int **client_ports);
+int tracecmd_msg_metadata_send(struct tracecmd_msg_handle *msg_handle,
+			       const char *buf, int size);
+int tracecmd_msg_finish_sending_metadata(struct tracecmd_msg_handle *msg_handle);
+void tracecmd_msg_send_close_msg(struct tracecmd_msg_handle *msg_handle);
 
 /* for server */
-int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize);
-int tracecmd_msg_send_port_array(int fd, int total_cpus, int *ports);
-int tracecmd_msg_collect_metadata(int ifd, int ofd);
+int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
+				 int *cpus, int *pagesize);
+int tracecmd_msg_send_port_array(struct tracecmd_msg_handle *msg_handle,
+				 int total_cpus, int *ports);
+int tracecmd_msg_collect_metadata(struct tracecmd_msg_handle *msg_handle, int ofd);
 
 /* --- Plugin handling --- */
 extern struct pevent_plugin_option trace_ftrace_options[];
trace-listen.c +39 -13

138 lines not on this page · raw message

trace-msg.c +19 -13
index aaeec06b82e3..7c93ff3b3ff3 100644
@@ -395,10 +395,12 @@ static int tracecmd_msg_wait_for_msg(int fd, struct tracecmd_msg *msg)
 	return 0;
 }
 
-int tracecmd_msg_send_init_data(int fd, int total_cpus, int **client_ports)
+int tracecmd_msg_send_init_data(struct tracecmd_msg_handle *msg_handle,
+				int total_cpus, int **client_ports)
 {
 	struct tracecmd_msg send_msg;
 	struct tracecmd_msg recv_msg;
+	int fd = msg_handle->fd;
 	int *ports;
 	int i, cpus;
 	int ret;
@@ -452,7 +454,8 @@ static void error_operation_for_server(struct tracecmd_msg *msg)
 
 #define MAX_OPTION_SIZE 4096
 
-int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize)
+int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
+				 int *cpus, int *pagesize)
 {
 	struct tracecmd_msg_opt *opt;
 	struct tracecmd_msg msg;
@@ -462,7 +465,7 @@ int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize)
 	u32 size = MIN_TINIT_SIZE;
 	u32 cmd;
 
-	ret = tracecmd_msg_recv_wait(fd, &msg);
+	ret = tracecmd_msg_recv_wait(msg_handle->fd, &msg);
 	if (ret < 0) {
 		if (ret == -ETIMEDOUT)
 			warning("Connection timed out\n");
@@ -527,7 +530,8 @@ error:
 	return ret;
 }
 
-int tracecmd_msg_send_port_array(int fd, int total_cpus, int *ports)
+int tracecmd_msg_send_port_array(struct tracecmd_msg_handle *msg_handle,
+				 int total_cpus, int *ports)
 {
 	struct tracecmd_msg msg;
 	int ret;
@@ -537,24 +541,26 @@ int tracecmd_msg_send_port_array(int fd, int total_cpus, int *ports)
 	if (ret < 0)
 		return ret;
 
-	ret = tracecmd_msg_send(fd, &msg);
+	ret = tracecmd_msg_send(msg_handle->fd, &msg);
 	if (ret < 0)
 		return ret;
 
 	return 0;
 }
 
-void tracecmd_msg_send_close_msg(int fd)
+void tracecmd_msg_send_close_msg(struct tracecmd_msg_handle *msg_handle)
 {
 	struct tracecmd_msg msg;
 
 	tracecmd_msg_init(MSG_CLOSE, &msg);
-	tracecmd_msg_send(fd, &msg);
+	tracecmd_msg_send(msg_handle->fd, &msg);
 }
 
-int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
+int tracecmd_msg_metadata_send(struct tracecmd_msg_handle *msg_handle,
+			       const char *buf, int size)
 {
 	struct tracecmd_msg msg;
+	int fd = msg_handle->fd;
 	int n;
 	int ret;
 	int count = 0;
@@ -589,19 +595,19 @@ int tracecmd_msg_metadata_send(int fd, const char *buf, int size)
 	return ret;
 }
 
-int tracecmd_msg_finish_sending_metadata(int fd)
+int tracecmd_msg_finish_sending_metadata(struct tracecmd_msg_handle *msg_handle)
 {
 	struct tracecmd_msg msg;
 	int ret;
 
 	tracecmd_msg_init(MSG_FINMETA, &msg);
-	ret = tracecmd_msg_send(fd, &msg);
+	ret = tracecmd_msg_send(msg_handle->fd, &msg);
 	if (ret < 0)
 		return ret;
 	return 0;
 }
 
-int tracecmd_msg_collect_metadata(int ifd, int ofd)
+int tracecmd_msg_collect_metadata(struct tracecmd_msg_handle *msg_handle, int ofd)
 {
 	struct tracecmd_msg msg;
 	u32 t, n, cmd;
@@ -609,7 +615,7 @@ int tracecmd_msg_collect_metadata(int ifd, int ofd)
 	int ret;
 
 	do {
-		ret = tracecmd_msg_recv_wait(ifd, &msg);
+		ret = tracecmd_msg_recv_wait(msg_handle->fd, &msg);
 		if (ret < 0) {
 			if (ret == -ETIMEDOUT)
 				warning("Connection timed out\n");
@@ -643,7 +649,7 @@ int tracecmd_msg_collect_metadata(int ifd, int ofd)
 
 	/* check the finish message of the client */
 	while (!done) {
-		ret = tracecmd_msg_recv(ifd, &msg);
+		ret = tracecmd_msg_recv(msg_handle->fd, &msg);
 		if (ret < 0) {
 			warning("reading client");
 			return ret;
trace-output.c +18 -11
index d04c4019640f..cbacd5426963 100644
@@ -65,12 +65,12 @@ struct tracecmd_output {
 	int		fd;
 	int		page_size;
 	int		cpus;
-	int		flags;
 	struct pevent	*pevent;
 	char		*tracing_dir;
 	int		options_written;
 	int		nr_options;
 	struct list_head options;
+	struct tracecmd_msg_handle *msg_handle;
 };
 
 struct list_event {
@@ -88,8 +88,8 @@ struct list_event_system {
 static stsize_t
 do_write_check(struct tracecmd_output *handle, const void *data, tsize_t size)
 {
-	if (handle->flags & OUTPUT_FL_SEND_META)
-		return tracecmd_msg_metadata_send(handle->fd, data, size);
+	if (handle->msg_handle)
+		return tracecmd_msg_metadata_send(handle->msg_handle, data, size);
 
 	return __do_write_check(handle->fd, data, size);
 }
@@ -782,7 +782,8 @@ static struct tracecmd_output *
 create_file_fd(int fd, struct tracecmd_input *ihandle,
 	       const char *tracing_dir,
 	       const char *kallsyms,
-	       struct tracecmd_event_list *list, bool send_meta)
+	       struct tracecmd_event_list *list,
+	       struct tracecmd_msg_handle *msg_handle)
 {
 	struct tracecmd_output *handle;
 	struct pevent *pevent;
@@ -794,9 +795,6 @@ create_file_fd(int fd, struct tracecmd_input *ihandle,
 		return NULL;
 	memset(handle, 0, sizeof(*handle));
 
-	if (send_meta)
-		handle->flags |= OUTPUT_FL_SEND_META;
-
 	handle->fd = fd;
 	if (tracing_dir) {
 		handle->tracing_dir = strdup(tracing_dir);
@@ -804,6 +802,8 @@ create_file_fd(int fd, struct tracecmd_input *ihandle,
 			goto out_free;
 	}
 
+	handle->msg_handle = msg_handle;
+
 	list_head_init(&handle->options);
 
 	buf[0] = 23;
@@ -888,7 +888,7 @@ static struct tracecmd_output *create_file(const char *output_file,
 	if (fd < 0)
 		return NULL;
 
-	handle = create_file_fd(fd, ihandle, tracing_dir, kallsyms, list, false);
+	handle = create_file_fd(fd, ihandle, tracing_dir, kallsyms, list, NULL);
 	if (!handle) {
 		close(fd);
 		unlink(output_file);
@@ -1318,13 +1318,20 @@ struct tracecmd_output *tracecmd_create_file(const char *output_file,
 
 struct tracecmd_output *tracecmd_create_init_fd(int fd)
 {
-	return create_file_fd(fd, NULL, NULL, NULL, &all_event_list, false);
+	return create_file_fd(fd, NULL, NULL, NULL, &all_event_list, NULL);
+}
+
+struct tracecmd_output *
+tracecmd_create_init_fd_msg(struct tracecmd_msg_handle *msg_handle,
+			    struct tracecmd_event_list *list)
+{
+	return create_file_fd(msg_handle->fd, NULL, NULL, NULL, list, msg_handle);
 }
 
 struct tracecmd_output *
-tracecmd_create_init_fd_glob(int fd, struct tracecmd_event_list *list, bool send_meta)
+tracecmd_create_init_fd_glob(int fd, struct tracecmd_event_list *list)
 {
-	return create_file_fd(fd, NULL, NULL, NULL, list, send_meta);
+	return create_file_fd(fd, NULL, NULL, NULL, list, NULL);
 }
 
 struct tracecmd_output *
trace-record.c +60 -38

246 lines not on this page · raw message

Signature · 1 line
2.13.2
#28 lore raw

PATCH 28/38 trace-cmd msg: Add server structure of msg_handler

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Have a server descriptor that is passed around. Currently, it only holds the "done" variable to tell when the server is finished.

---
 trace-cmd.h    |  2 ++
 trace-listen.c | 20 +++++++++++++++++---
 trace-msg.c    | 32 +++++++++++++++++++++++++++++---
 trace-msg.h    |  3 ---
 4 files changed, 48 insertions(+), 9 deletions(-)
trace-cmd.h +2 -0
index 0fce54baea5b..2fe4b208c561 100644
@@ -336,6 +336,8 @@ int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
 int tracecmd_msg_send_port_array(struct tracecmd_msg_handle *msg_handle,
 				 int total_cpus, int *ports);
 int tracecmd_msg_collect_metadata(struct tracecmd_msg_handle *msg_handle, int ofd);
+bool tracecmd_msg_done(struct tracecmd_msg_handle *msg_handle);
+void tracecmd_msg_set_done(struct tracecmd_msg_handle *msg_handle);
 
 /* --- Plugin handling --- */
 extern struct pevent_plugin_option trace_ftrace_options[];
trace-listen.c +17 -3
index d5379b36a85e..2e17839cffec 100644
@@ -55,6 +55,10 @@ static int proto_ver;
 
 static int do_daemon;
 
+/* Used for signaling INT to finish */
+static struct tracecmd_msg_handle *stop_msg_handle;
+static bool done;
+
 #define  TEMP_FILE_STR "%s.%s:%s.cpu%d", output_file, host, port, cpu
 static char *get_temp_file(const char *host, const char *port, int cpu)
 {
@@ -140,6 +144,8 @@ void tracecmd_msg_handle_close(struct tracecmd_msg_handle *msg_handle)
 
 static void finish(int sig)
 {
+	if (stop_msg_handle)
+		tracecmd_msg_set_done(stop_msg_handle);
 	done = true;
 }
 
@@ -602,10 +608,13 @@ static int *create_all_readers(int cpus, const char *node, const char *port,
 	return NULL;
 }
 
-static void collect_metadata_from_client(int ifd, int ofd)
+static void
+collect_metadata_from_client(struct tracecmd_msg_handle *msg_handle,
+			     int ofd)
 {
 	char buf[BUFSIZ];
 	int n, s, t;
+	int ifd = msg_handle->fd;
 
 	do {
 		n = read(ifd, buf, BUFSIZ);
@@ -626,7 +635,7 @@ static void collect_metadata_from_client(int ifd, int ofd)
 			t -= s;
 			s = n - t;
 		} while (t);
-	} while (n > 0 && !done);
+	} while (n > 0 && !tracecmd_msg_done(msg_handle));
 }
 
 static void stop_all_readers(int cpus, int *pid_array)
@@ -686,11 +695,16 @@ static int process_client(struct tracecmd_msg_handle *msg_handle,
 	if (!pid_array)
 		return -ENOMEM;
 
+	/* on signal stop this msg */
+	stop_msg_handle = msg_handle;
+
 	/* Now we are ready to start reading data from the client */
 	if (proto_ver == V2_PROTOCOL)
 		tracecmd_msg_collect_metadata(msg_handle, ofd);
 	else
-		collect_metadata_from_client(msg_handle->fd, ofd);
+		collect_metadata_from_client(msg_handle, ofd);
+
+	stop_msg_handle = NULL;
 
 	/* wait a little to let our readers finish reading */
 	sleep(1);
trace-msg.c +29 -3
index 7c93ff3b3ff3..9b01197574da 100644
@@ -81,8 +81,20 @@ bool use_tcp;
 /* for client */
 unsigned int page_size;
 
-/* for server */
-bool done;
+struct tracecmd_msg_server {
+	struct tracecmd_msg_handle handle;
+	int			done;
+};
+
+static struct tracecmd_msg_server *
+make_server(struct tracecmd_msg_handle *msg_handle)
+{
+	if (!(msg_handle->flags & TRACECMD_MSG_FL_SERVER)) {
+		plog("Message handle not of type server\n");
+		return NULL;
+	}
+	return (struct tracecmd_msg_server *)msg_handle;
+}
 
 struct tracecmd_msg_opt {
 	be32 size;
@@ -357,6 +369,20 @@ error:
 #define MSG_WAIT_MSEC	5000
 static int msg_wait_to = MSG_WAIT_MSEC;
 
+bool tracecmd_msg_done(struct tracecmd_msg_handle *msg_handle)
+{
+	struct tracecmd_msg_server *msg_server = make_server(msg_handle);
+
+	return (volatile int)msg_server->done;
+}
+
+void tracecmd_msg_set_done(struct tracecmd_msg_handle *msg_handle)
+{
+	struct tracecmd_msg_server *msg_server = make_server(msg_handle);
+
+	msg_server->done = true;
+}
+
 /*
  * A return value of 0 indicates time-out
  */
@@ -648,7 +674,7 @@ int tracecmd_msg_collect_metadata(struct tracecmd_msg_handle *msg_handle, int of
 	} while (cmd == MSG_SENDMETA);
 
 	/* check the finish message of the client */
-	while (!done) {
+	while (!tracecmd_msg_done(msg_handle)) {
 		ret = tracecmd_msg_recv(msg_handle->fd, &msg);
 		if (ret < 0) {
 			warning("reading client");
trace-msg.h +0 -3
index 7f6a146aeb10..da563ea55c85 100644
@@ -16,9 +16,6 @@ extern bool use_tcp;
 /* for client */
 extern unsigned int page_size;
 
-/* for server */
-extern bool done;
-
 void plog(const char *fmt, ...);
 void pdie(const char *fmt, ...);
 
Signature · 1 line
2.13.2
#29 lore raw

PATCH v2 28/38 trace-cmd msg: Add server structure of msg_handler

[ This wasn't backported properly ]

From: "Steven Rostedt (Red Hat)" <[email protected]>

Have a server descriptor that is passed around. Currently, it only holds the "done" variable to tell when the server is finished.

---
 trace-cmd.h    |  2 ++
 trace-listen.c | 40 +++++++++++++++++-----------------------
 trace-msg.c    | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 trace-msg.h    |  3 ---
 4 files changed, 74 insertions(+), 29 deletions(-)
trace-cmd.h +2 -0
index 0fce54b..2fe4b20 100644
@@ -336,6 +336,8 @@ int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
 int tracecmd_msg_send_port_array(struct tracecmd_msg_handle *msg_handle,
 				 int total_cpus, int *ports);
 int tracecmd_msg_collect_metadata(struct tracecmd_msg_handle *msg_handle, int ofd);
+bool tracecmd_msg_done(struct tracecmd_msg_handle *msg_handle);
+void tracecmd_msg_set_done(struct tracecmd_msg_handle *msg_handle);
 
 /* --- Plugin handling --- */
 extern struct pevent_plugin_option trace_ftrace_options[];
trace-listen.c +17 -23
index d5379b3..92f6561 100644
@@ -55,6 +55,10 @@ static int proto_ver;
 
 static int do_daemon;
 
+/* Used for signaling INT to finish */
+static struct tracecmd_msg_handle *stop_msg_handle;
+static bool done;
+
 #define  TEMP_FILE_STR "%s.%s:%s.cpu%d", output_file, host, port, cpu
 static char *get_temp_file(const char *host, const char *port, int cpu)
 {
@@ -118,28 +122,10 @@ static int process_option(char *option)
 	return 0;
 }
 
-struct tracecmd_msg_handle *
-tracecmd_msg_handle_alloc(int fd, unsigned long flags)
-{
-	struct tracecmd_msg_handle *handle;
-
-	handle = calloc(1, sizeof(struct tracecmd_msg_handle));
-	if (!handle)
-		return NULL;
-
-	handle->fd = fd;
-	handle->flags = flags;
-	return handle;
-}
-
-void tracecmd_msg_handle_close(struct tracecmd_msg_handle *msg_handle)
-{
-	close(msg_handle->fd);
-	free(msg_handle);
-}
-
 static void finish(int sig)
 {
+	if (stop_msg_handle)
+		tracecmd_msg_set_done(stop_msg_handle);
 	done = true;
 }
 
@@ -602,10 +588,13 @@ static int *create_all_readers(int cpus, const char *node, const char *port,
 	return NULL;
 }
 
-static void collect_metadata_from_client(int ifd, int ofd)
+static void
+collect_metadata_from_client(struct tracecmd_msg_handle *msg_handle,
+			     int ofd)
 {
 	char buf[BUFSIZ];
 	int n, s, t;
+	int ifd = msg_handle->fd;
 
 	do {
 		n = read(ifd, buf, BUFSIZ);
@@ -626,7 +615,7 @@ static void collect_metadata_from_client(int ifd, int ofd)
 			t -= s;
 			s = n - t;
 		} while (t);
-	} while (n > 0 && !done);
+	} while (n > 0 && !tracecmd_msg_done(msg_handle));
 }
 
 static void stop_all_readers(int cpus, int *pid_array)
@@ -686,11 +675,16 @@ static int process_client(struct tracecmd_msg_handle *msg_handle,
 	if (!pid_array)
 		return -ENOMEM;
 
+	/* on signal stop this msg */
+	stop_msg_handle = msg_handle;
+
 	/* Now we are ready to start reading data from the client */
 	if (proto_ver == V2_PROTOCOL)
 		tracecmd_msg_collect_metadata(msg_handle, ofd);
 	else
-		collect_metadata_from_client(msg_handle->fd, ofd);
+		collect_metadata_from_client(msg_handle, ofd);
+
+	stop_msg_handle = NULL;
 
 	/* wait a little to let our readers finish reading */
 	sleep(1);
trace-msg.c +55 -3

82 lines not on this page · raw message

trace-msg.h +0 -3
index 7f6a146..da563ea 100644
@@ -16,9 +16,6 @@ extern bool use_tcp;
 /* for client */
 extern unsigned int page_size;
 
-/* for server */
-extern bool done;
-
 void plog(const char *fmt, ...);
 void pdie(const char *fmt, ...);
 
Signature · 1 line
2.13.6
#30 lore raw

PATCH 29/38 trace-cmd: Remove global use_tcp variable

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

In order to have trace-listen be able to do a handshake before the fork, it can not have a use_tcp variables. Turn use_tcp as a flag in msg_handle.

---
 trace-cmd.h    |  2 ++
 trace-listen.c | 25 +++++++++++++------------
 trace-msg.c    | 18 ++++++++----------
 trace-msg.h    |  4 ----
 trace-record.c |  6 ++++++
 5 files changed, 29 insertions(+), 26 deletions(-)
trace-cmd.h +2 -0
index 2fe4b208c561..30badbd47cc6 100644
@@ -303,11 +303,13 @@ void tracecmd_enable_tracing(void);
 enum tracecmd_msg_bits {
 	TRACECMD_MSG_BIT_CLIENT		= 0,
 	TRACECMD_MSG_BIT_SERVER		= 1,
+	TRACECMD_MSG_BIT_USE_TCP	= 2,
 };
 
 enum tracecmd_msg_flags {
 	TRACECMD_MSG_FL_CLIENT		= (1 << TRACECMD_MSG_BIT_CLIENT),
 	TRACECMD_MSG_FL_SERVER		= (1 << TRACECMD_MSG_BIT_SERVER),
+	TRACECMD_MSG_FL_USE_TCP		= (1 << TRACECMD_MSG_BIT_USE_TCP),
 };
 
 /* for both client and server */
trace-listen.c +13 -12
index 2e17839cffec..a1e35ef19761 100644
@@ -112,11 +112,11 @@ static int read_string(int fd, char *buf, size_t size)
 	return i;
 }
 
-static int process_option(char *option)
+static int process_option(struct tracecmd_msg_handle *msg_handle, char *option)
 {
 	/* currently the only option we have is to us TCP */
 	if (strcmp(option, "TCP") == 0) {
-		use_tcp = 1;
+		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
 		return 1;
 	}
 	return 0;
@@ -225,7 +225,7 @@ void pdie(const char *fmt, ...)
 }
 
 static int process_udp_child(int sfd, const char *host, const char *port,
-			     int cpu, int page_size)
+			     int cpu, int page_size, int use_tcp)
 {
 	struct sockaddr_storage peer_addr;
 	socklen_t peer_addr_len;
@@ -292,7 +292,7 @@ static int process_udp_child(int sfd, const char *host, const char *port,
 #define START_PORT_SEARCH 1500
 #define MAX_PORT_SEARCH 6000
 
-static int udp_bind_a_port(int start_port, int *sfd)
+static int udp_bind_a_port(int start_port, int *sfd, int use_tcp)
 {
 	struct addrinfo hints;
 	struct addrinfo *result, *rp;
@@ -337,7 +337,7 @@ static int udp_bind_a_port(int start_port, int *sfd)
 }
 
 static void fork_udp_reader(int sfd, const char *node, const char *port,
-			    int *pid, int cpu, int pagesize)
+			    int *pid, int cpu, int pagesize, int use_tcp)
 {
 	int ret;
 
@@ -347,7 +347,7 @@ static void fork_udp_reader(int sfd, const char *node, const char *port,
 		pdie("creating udp reader");
 
 	if (!*pid) {
-		ret = process_udp_child(sfd, node, port, cpu, pagesize);
+		ret = process_udp_child(sfd, node, port, cpu, pagesize, use_tcp);
 		if (ret < 0)
 			pdie("Problem with udp reader %d", ret);
 	}
@@ -356,7 +356,7 @@ static void fork_udp_reader(int sfd, const char *node, const char *port,
 }
 
 static int open_udp(const char *node, const char *port, int *pid,
-		    int cpu, int pagesize, int start_port)
+		    int cpu, int pagesize, int start_port, int use_tcp)
 {
 	int sfd;
 	int num_port;
@@ -365,11 +365,11 @@ static int open_udp(const char *node, const char *port, int *pid,
 	 * udp_bind_a_port() currently does not return an error, but if that
 	 * changes in the future, we have a check for it now.
 	 */
-	num_port = udp_bind_a_port(start_port, &sfd);
+	num_port = udp_bind_a_port(start_port, &sfd, use_tcp);
 	if (num_port < 0)
 		return num_port;
 
-	fork_udp_reader(sfd, node, port, pid, cpu, pagesize);
+	fork_udp_reader(sfd, node, port, pid, cpu, pagesize, use_tcp);
 
 	return num_port;
 }
@@ -495,7 +495,7 @@ static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
 				s = size - t;
 			} while (t);
 
-			s = process_option(option);
+			s = process_option(msg_handle, option);
 			free(option);
 			/* do we understand this option? */
 			ret = -EINVAL;
@@ -504,7 +504,7 @@ static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
 		}
 	}
 
-	if (use_tcp)
+	if (msg_handle->flags & TRACECMD_MSG_FL_USE_TCP)
 		plog("Using TCP for live connection\n");
 
 	ret = 0;
@@ -547,6 +547,7 @@ static void destroy_all_readers(int cpus, int *pid_array, const char *node,
 static int *create_all_readers(int cpus, const char *node, const char *port,
 			       int pagesize, struct tracecmd_msg_handle *msg_handle)
 {
+	int use_tcp = msg_handle->flags & TRACECMD_MSG_FL_USE_TCP;
 	char buf[BUFSIZ];
 	int *port_array;
 	int *pid_array;
@@ -572,7 +573,7 @@ static int *create_all_readers(int cpus, const char *node, const char *port,
 	/* Now create a UDP port for each CPU */
 	for (cpu = 0; cpu < cpus; cpu++) {
 		udp_port = open_udp(node, port, &pid, cpu,
-				    pagesize, start_port);
+				    pagesize, start_port, use_tcp);
 		if (udp_port < 0)
 			goto out_free;
 		port_array[cpu] = udp_port;
trace-msg.c +8 -10
index 9b01197574da..0d564c4aee32 100644
@@ -75,10 +75,6 @@ static inline void dprint(const char *fmt, ...)
 #define MIN_META_SIZE	(sizeof(struct tracecmd_msg_header) + \
 			 sizeof(struct tracecmd_msg_meta))
 
-/* for both client and server */
-bool use_tcp;
-
-/* for client */
 unsigned int page_size;
 
 struct tracecmd_msg_server {
@@ -198,13 +194,14 @@ enum msg_opt_command {
 	MSGOPT_USETCP = 1,
 };
 
-static int make_tinit(struct tracecmd_msg *msg, int total_cpus)
+static int make_tinit(struct tracecmd_msg_handle *msg_handle,
+		      struct tracecmd_msg *msg, int total_cpus)
 {
 	struct tracecmd_msg_opt *opt;
 	int opt_num = 0;
 	int size = MIN_TINIT_SIZE;
 
-	if (use_tcp) {
+	if (msg_handle->flags & TRACECMD_MSG_FL_USE_TCP) {
 		opt_num++;
 		opt = malloc(sizeof(*opt));
 		if (!opt)
@@ -434,7 +431,7 @@ int tracecmd_msg_send_init_data(struct tracecmd_msg_handle *msg_handle,
 	*client_ports = NULL;
 
 	tracecmd_msg_init(MSG_TINIT, &send_msg);
-	ret = make_tinit(&send_msg, total_cpus);
+	ret = make_tinit(msg_handle, &send_msg, total_cpus);
 	if (ret < 0)
 		return ret;
 
@@ -459,11 +456,12 @@ int tracecmd_msg_send_init_data(struct tracecmd_msg_handle *msg_handle,
 	return 0;
 }
 
-static bool process_option(struct tracecmd_msg_opt *opt)
+static bool process_option(struct tracecmd_msg_handle *msg_handle,
+			   struct tracecmd_msg_opt *opt)
 {
 	/* currently the only option we have is to us TCP */
 	if (ntohl(opt->opt_cmd) == MSGOPT_USETCP) {
-		use_tcp = true;
+		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
 		return true;
 	}
 	return false;
@@ -539,7 +537,7 @@ int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
 			ret = -EINVAL;
 			goto error;
 		}
-		s = process_option(opt);
+		s = process_option(msg_handle, opt);
 		/* do we understand this option? */
 		if (!s) {
 			plog("Cannot understand(%d:%d:%d)\n",
trace-msg.h +0 -4
index da563ea55c85..bfd065c06324 100644
@@ -10,10 +10,6 @@
 #define V1_PROTOCOL	1
 #define V2_PROTOCOL	2
 
-/* for both client and server */
-extern bool use_tcp;
-
-/* for client */
 extern unsigned int page_size;
 
 void plog(const char *fmt, ...);
trace-record.c +6 -0
index 3decb57a9a6c..9512fd9853ad 100644
@@ -95,6 +95,8 @@ static struct tracecmd_output *network_handle;
 /* Max size to let a per cpu file get */
 static int max_kb;
 
+static bool use_tcp;
+
 static int do_ptrace;
 
 static int filter_task;
@@ -2719,6 +2721,7 @@ static void communicate_with_listener_v1(struct tracecmd_msg_handle *msg_handle)
 	if (page_size >= UDP_MAX_PACKET) {
 		warning("page size too big for UDP using TCP in live read");
 		use_tcp = 1;
+		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
 	}
 
 	if (use_tcp) {
@@ -2859,6 +2862,9 @@ again:
 	if (!msg_handle)
 		die("Failed to allocate message handle");
 
+	if (use_tcp)
+		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
+
 	if (proto_ver == V2_PROTOCOL) {
 		check_protocol_version(msg_handle);
 		if (proto_ver == V1_PROTOCOL) {
Signature · 1 line
2.13.2
#31 lore raw

PATCH 30/38 trace-cmd: Move protocol version into msg_handler

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

In order to have trace-listen be able to perform the handshake with the client before forking, the protocol version can not be global. Move it to the msg_handler.

---
 trace-cmd.h    |  3 ++-
 trace-listen.c |  8 +++-----
 trace-record.c | 27 ++++++++++++++++-----------
 3 files changed, 21 insertions(+), 17 deletions(-)
trace-cmd.h +2 -1
index 30badbd47cc6..526634fd674b 100644
@@ -314,8 +314,9 @@ enum tracecmd_msg_flags {
 
 /* for both client and server */
 struct tracecmd_msg_handle {
-	unsigned long		flags;
 	int			fd;
+	int			version;	/* Current protocol version */
+	unsigned long		flags;
 };
 
 struct tracecmd_msg_handle *
trace-listen.c +3 -5
index a1e35ef19761..93cae4c793fa 100644
@@ -51,8 +51,6 @@ static FILE *logfp;
 
 static int backlog = 5;
 
-static int proto_ver;
-
 static int do_daemon;
 
 /* Used for signaling INT to finish */
@@ -436,7 +434,7 @@ static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
 		/* We're off! */
 		write(fd, "OK", 2);
 
-		proto_ver = V2_PROTOCOL;
+		msg_handle->version = V2_PROTOCOL;
 
 		/* read the CPU count, the page size, and options */
 		if (tracecmd_msg_initial_setting(msg_handle, cpus, pagesize) < 0)
@@ -585,7 +583,7 @@ static int *create_all_readers(int cpus, const char *node, const char *port,
 		start_port = udp_port + 1;
 	}
 
-	if (proto_ver == V2_PROTOCOL) {
+	if (msg_handle->version == V2_PROTOCOL) {
 		/* send set of port numbers to the client */
 		if (tracecmd_msg_send_port_array(msg_handle, cpus, port_array) < 0) {
 			plog("Failed sending port array\n");
@@ -700,7 +698,7 @@ static int process_client(struct tracecmd_msg_handle *msg_handle,
 	stop_msg_handle = msg_handle;
 
 	/* Now we are ready to start reading data from the client */
-	if (proto_ver == V2_PROTOCOL)
+	if (msg_handle->version == V2_PROTOCOL)
 		tracecmd_msg_collect_metadata(msg_handle, ofd);
 	else
 		collect_metadata_from_client(msg_handle, ofd);
trace-record.c +16 -11
index 9512fd9853ad..90e344d5c0c8 100644
@@ -112,7 +112,6 @@ static unsigned recorder_flags;
 /* Try a few times to get an accurate date */
 static int date2ts_tries = 5;
 
-static int proto_ver = V2_PROTOCOL;
 static struct func_list *graph_funcs;
 
 static int func_stack;
@@ -2791,7 +2790,7 @@ static void check_protocol_version(struct tracecmd_msg_handle *msg_handle)
 
 	if (n < 0 || !buf[0]) {
 		/* the server uses the v1 protocol, so we'll use it */
-		proto_ver = V1_PROTOCOL;
+		msg_handle->version = V1_PROTOCOL;
 		plog("Use the v1 protocol\n");
 	} else {
 		if (memcmp(buf, "V2", n) != 0)
@@ -2811,7 +2810,7 @@ static void check_protocol_version(struct tracecmd_msg_handle *msg_handle)
 
 static struct tracecmd_msg_handle *setup_network(void)
 {
-	struct tracecmd_msg_handle *msg_handle;
+	struct tracecmd_msg_handle *msg_handle = NULL;
 	struct addrinfo hints;
 	struct addrinfo *result, *rp;
 	int sfd, s;
@@ -2858,16 +2857,22 @@ again:
 
 	freeaddrinfo(result);
 
-	msg_handle = tracecmd_msg_handle_alloc(sfd, TRACECMD_MSG_FL_CLIENT);
-	if (!msg_handle)
-		die("Failed to allocate message handle");
+	if (msg_handle) {
+		msg_handle->fd = sfd;
+	} else {
+		msg_handle = tracecmd_msg_handle_alloc(sfd, TRACECMD_MSG_FL_CLIENT);
+		if (!msg_handle)
+			die("Failed to allocate message handle");
+
+		msg_handle->version = V2_PROTOCOL;
+	}
 
 	if (use_tcp)
 		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
 
-	if (proto_ver == V2_PROTOCOL) {
+	if (msg_handle->version == V2_PROTOCOL) {
 		check_protocol_version(msg_handle);
-		if (proto_ver == V1_PROTOCOL) {
+		if (msg_handle->version == V1_PROTOCOL) {
 			/* reconnect to the server for using the v1 protocol */
 			close(sfd);
 			goto again;
@@ -2875,7 +2880,7 @@ again:
 		communicate_with_listener_v2(msg_handle);
 	}
 
-	if (proto_ver == V1_PROTOCOL)
+	if (msg_handle->version == V1_PROTOCOL)
 		communicate_with_listener_v1(msg_handle);
 
 	return msg_handle;
@@ -2888,7 +2893,7 @@ static struct tracecmd_msg_handle *setup_connection(void)
 	msg_handle = setup_network();
 
 	/* Now create the handle through this socket */
-	if (proto_ver == V2_PROTOCOL) {
+	if (msg_handle->version == V2_PROTOCOL) {
 		network_handle = tracecmd_create_init_fd_msg(msg_handle, listed_events);
 		tracecmd_msg_finish_sending_metadata(msg_handle);
 	} else
@@ -2901,7 +2906,7 @@ static struct tracecmd_msg_handle *setup_connection(void)
 
 static void finish_network(struct tracecmd_msg_handle *msg_handle)
 {
-	if (proto_ver == V2_PROTOCOL)
+	if (msg_handle->version == V2_PROTOCOL)
 		tracecmd_msg_send_close_msg(msg_handle);
 	tracecmd_msg_handle_close(msg_handle);
 	free(host);
Signature · 1 line
2.13.2
#32 lore raw

PATCH 31/38 tracecmd: Clean up handling of cpu_count

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Instead of passing around a pointer to a cpus variable, have the msg_handle->cpu_count set up when the total cpus are discovered.

---
 trace-cmd.h    |  7 ++++---
 trace-listen.c | 26 ++++++++++++++++----------
 trace-msg.c    | 15 +++++++++------
 3 files changed, 29 insertions(+), 19 deletions(-)
trace-cmd.h +4 -3
index 526634fd674b..1204bb307431 100644
@@ -315,7 +315,8 @@ enum tracecmd_msg_flags {
 /* for both client and server */
 struct tracecmd_msg_handle {
 	int			fd;
-	int			version;	/* Current protocol version */
+	short			cpu_count;
+	short			version;	/* Current protocol version */
 	unsigned long		flags;
 };
 
@@ -335,9 +336,9 @@ void tracecmd_msg_send_close_msg(struct tracecmd_msg_handle *msg_handle);
 
 /* for server */
 int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
-				 int *cpus, int *pagesize);
+				 int *pagesize);
 int tracecmd_msg_send_port_array(struct tracecmd_msg_handle *msg_handle,
-				 int total_cpus, int *ports);
+				 int *ports);
 int tracecmd_msg_collect_metadata(struct tracecmd_msg_handle *msg_handle, int ofd);
 bool tracecmd_msg_done(struct tracecmd_msg_handle *msg_handle);
 void tracecmd_msg_set_done(struct tracecmd_msg_handle *msg_handle);
trace-listen.c +16 -10
index 93cae4c793fa..c7c0afc5bbee 100644
@@ -373,13 +373,14 @@ static int open_udp(const char *node, const char *port, int *pid,
 }
 
 static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
-				   int *cpus, int *pagesize)
+				   int *pagesize)
 {
 	char *last_proto = NULL;
 	char buf[BUFSIZ];
 	char *option;
 	int options;
 	int size;
+	int cpus;
 	int n, s, t, i;
 	int ret = -EINVAL;
 	int fd = msg_handle->fd;
@@ -394,10 +395,10 @@ static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
 		/** ERROR **/
 		return -EINVAL;
 
-	*cpus = atoi(buf);
+	cpus = atoi(buf);
 
 	/* Is the client using the new protocol? */
-	if (*cpus == -1) {
+	if (cpus == -1) {
 		if (memcmp(buf, V2_CPU, n) != 0) {
 			/* If it did not send a version, then bail */
 			if (memcmp(buf, "-1V", 3)) {
@@ -437,15 +438,17 @@ static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
 		msg_handle->version = V2_PROTOCOL;
 
 		/* read the CPU count, the page size, and options */
-		if (tracecmd_msg_initial_setting(msg_handle, cpus, pagesize) < 0)
+		if (tracecmd_msg_initial_setting(msg_handle, pagesize) < 0)
 			goto out;
 	} else {
 		/* The client is using the v1 protocol */
 
-		plog("cpus=%d\n", *cpus);
-		if (*cpus < 0)
+		plog("cpus=%d\n", cpus);
+		if (cpus < 0)
 			goto out;
 
+		msg_handle->cpu_count = cpus;
+
 		/* next read the page size */
 		n = read_string(fd, buf, BUFSIZ);
 		if (n == BUFSIZ)
@@ -542,7 +545,7 @@ static void destroy_all_readers(int cpus, int *pid_array, const char *node,
 	free(pid_array);
 }
 
-static int *create_all_readers(int cpus, const char *node, const char *port,
+static int *create_all_readers(const char *node, const char *port,
 			       int pagesize, struct tracecmd_msg_handle *msg_handle)
 {
 	int use_tcp = msg_handle->flags & TRACECMD_MSG_FL_USE_TCP;
@@ -551,6 +554,7 @@ static int *create_all_readers(int cpus, const char *node, const char *port,
 	int *pid_array;
 	int start_port;
 	int udp_port;
+	int cpus = msg_handle->cpu_count;
 	int cpu;
 	int pid;
 
@@ -585,7 +589,7 @@ static int *create_all_readers(int cpus, const char *node, const char *port,
 
 	if (msg_handle->version == V2_PROTOCOL) {
 		/* send set of port numbers to the client */
-		if (tracecmd_msg_send_port_array(msg_handle, cpus, port_array) < 0) {
+		if (tracecmd_msg_send_port_array(msg_handle, port_array) < 0) {
 			plog("Failed sending port array\n");
 			goto out_free;
 		}
@@ -684,13 +688,13 @@ static int process_client(struct tracecmd_msg_handle *msg_handle,
 	int ofd;
 	int ret;
 
-	ret = communicate_with_client(msg_handle, &cpus, &pagesize);
+	ret = communicate_with_client(msg_handle, &pagesize);
 	if (ret < 0)
 		return ret;
 
 	ofd = create_client_file(node, port);
 
-	pid_array = create_all_readers(cpus, node, port, pagesize, msg_handle);
+	pid_array = create_all_readers(node, port, pagesize, msg_handle);
 	if (!pid_array)
 		return -ENOMEM;
 
@@ -708,6 +712,8 @@ static int process_client(struct tracecmd_msg_handle *msg_handle,
 	/* wait a little to let our readers finish reading */
 	sleep(1);
 
+	cpus = msg_handle->cpu_count;
+
 	/* stop our readers */
 	stop_all_readers(cpus, pid_array);
 
trace-msg.c +9 -6
index 0d564c4aee32..55fb2e8baabb 100644
@@ -479,11 +479,12 @@ static void error_operation_for_server(struct tracecmd_msg *msg)
 #define MAX_OPTION_SIZE 4096
 
 int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
-				 int *cpus, int *pagesize)
+				 int *pagesize)
 {
 	struct tracecmd_msg_opt *opt;
 	struct tracecmd_msg msg;
 	int options, i, s;
+	int cpus;
 	int ret;
 	int offset = 0;
 	u32 size = MIN_TINIT_SIZE;
@@ -502,13 +503,15 @@ int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
 		goto error;
 	}
 
-	*cpus = ntohl(msg.tinit.cpus);
-	plog("cpus=%d\n", *cpus);
-	if (*cpus < 0) {
+	cpus = ntohl(msg.tinit.cpus);
+	plog("cpus=%d\n", cpus);
+	if (cpus < 0) {
 		ret = -EINVAL;
 		goto error;
 	}
 
+	msg_handle->cpu_count = cpus;
+
 	*pagesize = ntohl(msg.tinit.page_size);
 	plog("pagesize=%d\n", *pagesize);
 	if (*pagesize <= 0) {
@@ -555,13 +558,13 @@ error:
 }
 
 int tracecmd_msg_send_port_array(struct tracecmd_msg_handle *msg_handle,
-				 int total_cpus, int *ports)
+				 int *ports)
 {
 	struct tracecmd_msg msg;
 	int ret;
 
 	tracecmd_msg_init(MSG_RINIT, &msg);
-	ret = make_rinit(&msg, total_cpus, ports);
+	ret = make_rinit(&msg, msg_handle->cpu_count, ports);
 	if (ret < 0)
 		return ret;
 
Signature · 1 line
2.13.2
#33 lore raw

PATCH 32/38 tracecmd listen: Have pagesize passed as return not parameter

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Return pagesize as the return function and not as a pointer that is passed by reference. This will simplify the modification of the process_client() code to let the listener do a handshake before forking.

---
 trace-cmd.h    |  3 +--
 trace-listen.c | 23 +++++++++++++----------
 trace-msg.c    | 12 ++++++------
 3 files changed, 20 insertions(+), 18 deletions(-)
trace-cmd.h +1 -2
index 1204bb307431..ca030fc0df01 100644
@@ -335,8 +335,7 @@ int tracecmd_msg_finish_sending_metadata(struct tracecmd_msg_handle *msg_handle)
 void tracecmd_msg_send_close_msg(struct tracecmd_msg_handle *msg_handle);
 
 /* for server */
-int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
-				 int *pagesize);
+int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle);
 int tracecmd_msg_send_port_array(struct tracecmd_msg_handle *msg_handle,
 				 int *ports);
 int tracecmd_msg_collect_metadata(struct tracecmd_msg_handle *msg_handle, int ofd);
trace-listen.c +13 -10
index c7c0afc5bbee..52021af9e574 100644
@@ -372,12 +372,12 @@ static int open_udp(const char *node, const char *port, int *pid,
 	return num_port;
 }
 
-static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
-				   int *pagesize)
+static int communicate_with_client(struct tracecmd_msg_handle *msg_handle)
 {
 	char *last_proto = NULL;
 	char buf[BUFSIZ];
 	char *option;
+	int pagesize = 0;
 	int options;
 	int size;
 	int cpus;
@@ -438,7 +438,7 @@ static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
 		msg_handle->version = V2_PROTOCOL;
 
 		/* read the CPU count, the page size, and options */
-		if (tracecmd_msg_initial_setting(msg_handle, pagesize) < 0)
+		if ((pagesize = tracecmd_msg_initial_setting(msg_handle)) < 0)
 			goto out;
 	} else {
 		/* The client is using the v1 protocol */
@@ -455,10 +455,10 @@ static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
 			/** ERROR **/
 			goto out;
 
-		*pagesize = atoi(buf);
+		pagesize = atoi(buf);
 
-		plog("pagesize=%d\n", *pagesize);
-		if (*pagesize <= 0)
+		plog("pagesize=%d\n", pagesize);
+		if (pagesize <= 0)
 			goto out;
 
 		/* Now the number of options */
@@ -508,7 +508,7 @@ static int communicate_with_client(struct tracecmd_msg_handle *msg_handle,
 	if (msg_handle->flags & TRACECMD_MSG_FL_USE_TCP)
 		plog("Using TCP for live connection\n");
 
-	ret = 0;
+	ret = pagesize;
  out:
 	free(last_proto);
 
@@ -558,6 +558,9 @@ static int *create_all_readers(const char *node, const char *port,
 	int cpu;
 	int pid;
 
+	if (!pagesize)
+		return NULL;
+
 	port_array = malloc(sizeof(int) * cpus);
 	if (!port_array)
 		return NULL;
@@ -688,9 +691,9 @@ static int process_client(struct tracecmd_msg_handle *msg_handle,
 	int ofd;
 	int ret;
 
-	ret = communicate_with_client(msg_handle, &pagesize);
-	if (ret < 0)
-		return ret;
+	pagesize = communicate_with_client(msg_handle);
+	if (pagesize < 0)
+		return pagesize;
 
 	ofd = create_client_file(node, port);
 
trace-msg.c +6 -6
index 55fb2e8baabb..a439c8f030a4 100644
@@ -478,11 +478,11 @@ static void error_operation_for_server(struct tracecmd_msg *msg)
 
 #define MAX_OPTION_SIZE 4096
 
-int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
-				 int *pagesize)
+int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle)
 {
 	struct tracecmd_msg_opt *opt;
 	struct tracecmd_msg msg;
+	int pagesize;
 	int options, i, s;
 	int cpus;
 	int ret;
@@ -512,9 +512,9 @@ int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
 
 	msg_handle->cpu_count = cpus;
 
-	*pagesize = ntohl(msg.tinit.page_size);
-	plog("pagesize=%d\n", *pagesize);
-	if (*pagesize <= 0) {
+	pagesize = ntohl(msg.tinit.page_size);
+	plog("pagesize=%d\n", pagesize);
+	if (pagesize <= 0) {
 		ret = -EINVAL;
 		goto error;
 	}
@@ -550,7 +550,7 @@ int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle,
 		}
 	}
 
-	return 0;
+	return pagesize;
 
 error:
 	error_operation_for_server(&msg);
Signature · 1 line
2.13.2
#34 lore raw

PATCH 33/38 trace-cmd: Have cpu_count reside in instances and not be global

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

In order to be able to record remote machines (virtual or network) and interleave it with the host traces, we need to support various amounts of cpu counts. Move the CPU count from being global, to being in the instance.

---
 trace-cmd.h    |   2 +-
 trace-local.h  |   3 +-
 trace-msg.c    |   9 +++--
 trace-record.c | 115 ++++++++++++++++++++++++++++++++-------------------------
 trace-stat.c   |   2 +-
 5 files changed, 73 insertions(+), 58 deletions(-)
trace-cmd.h +1 -1
index ca030fc0df01..a3d38ec27556 100644
@@ -328,7 +328,7 @@ void tracecmd_msg_handle_close(struct tracecmd_msg_handle *msg_handle);
 
 /* for clients */
 int tracecmd_msg_send_init_data(struct tracecmd_msg_handle *msg_handle,
-				int total_cpus, int **client_ports);
+				int **client_ports);
 int tracecmd_msg_metadata_send(struct tracecmd_msg_handle *msg_handle,
 			       const char *buf, int size);
 int tracecmd_msg_finish_sending_metadata(struct tracecmd_msg_handle *msg_handle);
trace-local.h +2 -1
index b03ce54e6cf4..0d85fda416e2 100644
@@ -194,6 +194,7 @@ struct buffer_instance {
 	int			keep;
 	int			buffer_size;
 	int			profile;
+	int			cpu_count;
 };
 
 extern struct buffer_instance top_instance;
@@ -205,7 +206,7 @@ extern struct buffer_instance *first_instance;
 				  i = i == &top_instance ? buffer_instances : (i)->next)
 
 struct buffer_instance *create_instance(const char *name);
-void add_instance(struct buffer_instance *instance);
+void add_instance(struct buffer_instance *instance, int cpu_count);
 char *get_instance_file(struct buffer_instance *instance, const char *file);
 void update_first_instance(struct buffer_instance *instance, int topt);
 
trace-msg.c +5 -4
index a439c8f030a4..fe9622a040f2 100644
@@ -195,9 +195,10 @@ enum msg_opt_command {
 };
 
 static int make_tinit(struct tracecmd_msg_handle *msg_handle,
-		      struct tracecmd_msg *msg, int total_cpus)
+		      struct tracecmd_msg *msg)
 {
 	struct tracecmd_msg_opt *opt;
+	int cpu_count = msg_handle->cpu_count;
 	int opt_num = 0;
 	int size = MIN_TINIT_SIZE;
 
@@ -212,7 +213,7 @@ static int make_tinit(struct tracecmd_msg_handle *msg_handle,
 		size += sizeof(*opt);
 	}
 
-	msg->tinit.cpus = htonl(total_cpus);
+	msg->tinit.cpus = htonl(cpu_count);
 	msg->tinit.page_size = htonl(page_size);
 	msg->tinit.opt_num = htonl(opt_num);
 
@@ -419,7 +420,7 @@ static int tracecmd_msg_wait_for_msg(int fd, struct tracecmd_msg *msg)
 }
 
 int tracecmd_msg_send_init_data(struct tracecmd_msg_handle *msg_handle,
-				int total_cpus, int **client_ports)
+				int **client_ports)
 {
 	struct tracecmd_msg send_msg;
 	struct tracecmd_msg recv_msg;
@@ -431,7 +432,7 @@ int tracecmd_msg_send_init_data(struct tracecmd_msg_handle *msg_handle,
 	*client_ports = NULL;
 
 	tracecmd_msg_init(MSG_TINIT, &send_msg);
-	ret = make_tinit(msg_handle, &send_msg, total_cpus);
+	ret = make_tinit(msg_handle, &send_msg);
 	if (ret < 0)
 		return ret;
 
trace-record.c +64 -51

370 lines not on this page · raw message

trace-stat.c +1 -1
index fd1635470142..0fc510ab895f 100644
@@ -907,7 +907,7 @@ void trace_stat (int argc, char **argv)
 			instance = create_instance(optarg);
 			if (!instance)
 				die("Failed to create instance");
-			add_instance(instance);
+			add_instance(instance, count_cpus());
 			/* top instance requires direct access */
 			if (!topt && is_top_instance(first_instance))
 				first_instance = instance;
Signature · 1 line
2.13.2
#35 lore raw

PATCH 34/38 trace-cmd: Add option CPUCOUNT to buffer instance options

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Add a new trace.dat option that allows buffer instances to have a different number of CPUS than what the top level buffers have.

---
 trace-cmd.h    |  3 ++-
 trace-input.c  | 27 +++++++++++++++++++++++++++
 trace-output.c | 11 ++++++++++-
 trace-record.c | 55 +++++++++++++++++++++++++++++++++++++++++--------------
 4 files changed, 80 insertions(+), 16 deletions(-)
trace-cmd.h +2 -1
index a3d38ec27556..a5409887e6dd 100644
@@ -93,6 +93,7 @@ enum {
 	TRACECMD_OPTION_UNAME,
 	TRACECMD_OPTION_HOOK,
 	TRACECMD_OPTION_OFFSET,
+	TRACECMD_OPTION_CPUCOUNT,
 };
 
 enum {
@@ -257,7 +258,7 @@ struct tracecmd_option *tracecmd_add_option(struct tracecmd_output *handle,
 					    unsigned short id, int size,
 					    const void *data);
 struct tracecmd_option *tracecmd_add_buffer_option(struct tracecmd_output *handle,
-						   const char *name);
+						   const char *name, int cpus);
 int tracecmd_update_option(struct tracecmd_output *handle,
 			   struct tracecmd_option *option, int size,
 			   const void *data);
trace-input.c +27 -0
index 15d8c1b0b6d6..30b16bab43d7 100644
@@ -2102,6 +2102,7 @@ static int handle_options(struct tracecmd_input *handle)
 	struct input_buffer_instance *buffer;
 	struct hook_list *hook;
 	char *buf;
+	int cpus;
 
 	for (;;) {
 		if (do_read_check(handle, &option, 2))
@@ -2183,6 +2184,10 @@ static int handle_options(struct tracecmd_input *handle)
 			hook->next = handle->hooks;
 			handle->hooks = hook;
 			break;
+		case TRACECMD_OPTION_CPUCOUNT:
+			cpus = *(int *)buf;
+			handle->cpus = __data2host4(handle->pevent, cpus);
+			break;
 		default:
 			warning("unknown option %d", option);
 			break;
@@ -2206,11 +2211,14 @@ static int read_cpu_data(struct tracecmd_input *handle)
 	unsigned long long max_size = 0;
 	unsigned long long pages;
 	char buf[10];
+	int cpus;
 	int cpu;
 
 	if (do_read_check(handle, buf, 10))
 		return -1;
 
+	cpus = handle->cpus;
+
 	/* check if this handles options */
 	if (strncmp(buf, "options", 7) == 0) {
 		if (handle_options(handle) < 0)
@@ -2293,6 +2301,25 @@ static int read_cpu_data(struct tracecmd_input *handle)
 			goto out_free;
 	}
 
+	/*
+	 * It is possible that an option changed the number of CPUs.
+	 * If that happened, then there's "empty" cpu data saved for
+	 * backward compatibility.
+	 */
+	if (cpus < handle->cpus) {
+		unsigned long long ignore;
+		int once = 0;
+
+		read8(handle, &ignore); /* offset */
+		read8(handle, &ignore); /* size */
+		if (ignore != 0) {
+			if (!once) {
+				warning("ignored CPU data not zero size");
+				once++;
+			}
+		}
+	}
+
 	return 0;
 
  out_free:
trace-output.c +10 -1
index cbacd5426963..02efeeb669d6 100644
@@ -1029,7 +1029,8 @@ int tracecmd_update_option(struct tracecmd_output *handle,
 }
 
 struct tracecmd_option *
-tracecmd_add_buffer_option(struct tracecmd_output *handle, const char *name)
+tracecmd_add_buffer_option(struct tracecmd_output *handle, const char *name,
+			   int cpus)
 {
 	struct tracecmd_option *option;
 	char *buf;
@@ -1046,6 +1047,14 @@ tracecmd_add_buffer_option(struct tracecmd_output *handle, const char *name)
 	option = tracecmd_add_option(handle, TRACECMD_OPTION_BUFFER, size, buf);
 	free(buf);
 
+	/*
+	 * In case a buffer instance has different number of CPUs as the
+	 * local machine.
+	 */
+	if (cpus)
+		tracecmd_add_option(handle, TRACECMD_OPTION_CPUCOUNT,
+				    sizeof(int), &cpus);
+
 	return option;
 }
 
trace-record.c +41 -14

85 lines not on this page · raw message

Signature · 1 line
2.13.2
#36 lore raw

PATCH 35/38 trace-cmd: Have msg_handle part of the buffer instance

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

To allow for recording of the host as well as for the network, we need to have the msg_handle associated to the buffer instance and not global. This also will allow for recording buffer instances to network and host, as well as sending data to multiple hosts.

---
 trace-local.h  |  2 ++
 trace-record.c | 56 +++++++++++++++++++++++++++++++++-----------------------
 2 files changed, 35 insertions(+), 23 deletions(-)
trace-local.h +2 -0
index 0d85fda416e2..0665ec3c11c5 100644
@@ -189,6 +189,8 @@ struct buffer_instance {
 
 	struct tracecmd_input	*handle;
 
+	struct tracecmd_msg_handle *msg_handle;
+
 	int			tracing_on_init_val;
 	int			tracing_on_fd;
 	int			keep;
trace-record.c +33 -23

159 lines not on this page · raw message

Signature · 1 line
2.13.2
#37 lore raw

PATCH 36/38 trace-cmd record: Allow instances to be recorded over the network

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Allow buffer instances to be used when recording to another machine.

---
 trace-record.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
trace-record.c +11 -5
index 5f7231b0fda2..e0dd5570a536 100644
@@ -2629,10 +2629,6 @@ static int create_recorder(struct buffer_instance *instance, int cpu,
 	char *file;
 	int pid;
 
-	/* network for buffer instances not supported yet */
-	if (client_ports && instance->name)
-		return 0;
-
 	if (type != TRACE_TYPE_EXTRACT) {
 		signal(SIGUSR1, flush);
 
@@ -2651,8 +2647,18 @@ static int create_recorder(struct buffer_instance *instance, int cpu,
 	}
 
 	if (client_ports) {
+		char *path;
+
 		connect_port(cpu);
-		recorder = tracecmd_create_recorder_fd(client_ports[cpu], cpu, recorder_flags);
+		if (instance->name)
+			path = get_instance_dir(instance);
+		else
+			path = tracecmd_find_tracing_dir();
+		recorder = tracecmd_create_buffer_recorder_fd(client_ports[cpu],
+							      cpu, recorder_flags,
+							      path);
+		if (instance->name)
+			tracecmd_put_tracing_file(path);
 	} else {
 		file = get_temp_file(instance, cpu);
 		recorder = create_recorder_instance(instance, file, cpu, brass);
Signature · 1 line
2.13.2
#38 lore raw

PATCH 37/38 trace-cmd: Have keep and profile be flags of buffer instance

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

Instead of having separate ints for true or false fields in the buffer instance, have them be flags. This will allow us to easily add new ones.

---
 trace-local.h  |  9 +++++++--
 trace-record.c | 29 +++++++++++++++--------------
 2 files changed, 22 insertions(+), 16 deletions(-)
trace-local.h +7 -2
index 0665ec3c11c5..d45c66c31dca 100644
@@ -160,6 +160,12 @@ char *strstrip(char *str);
 
 /* --- instance manipulation --- */
 
+enum buffer_instance_flags {
+	BUFFER_FL_KEEP		= 1 << 0,
+	BUFFER_FL_PROFILE	= 1 << 1,
+	BUFFER_FL_GUEST		= 1 << 2,
+};
+
 struct func_list {
 	struct func_list *next;
 	const char *func;
@@ -191,11 +197,10 @@ struct buffer_instance {
 
 	struct tracecmd_msg_handle *msg_handle;
 
+	int			flags;
 	int			tracing_on_init_val;
 	int			tracing_on_fd;
-	int			keep;
 	int			buffer_size;
-	int			profile;
 	int			cpu_count;
 };
 
trace-record.c +15 -14
index e0dd5570a536..814c7e112285 100644
@@ -177,7 +177,7 @@ static struct reset_file *reset_files;
 /* Triggers need to be cleared in a special way */
 static struct reset_file *reset_triggers;
 
-struct buffer_instance top_instance = { .keep = 1 };
+struct buffer_instance top_instance = { .flags = BUFFER_FL_KEEP };
 struct buffer_instance *buffer_instances;
 struct buffer_instance *first_instance;
 
@@ -3806,7 +3806,7 @@ static void make_instances(void)
 				die("mkdir %s", path);
 		} else
 			/* Don't delete instances that already exist */
-			instance->keep = 1;
+			instance->flags |= BUFFER_FL_KEEP;
 		tracecmd_put_tracing_file(path);
 	}
 }
@@ -3819,7 +3819,7 @@ void tracecmd_remove_instances(void)
 
 	for_each_instance(instance) {
 		/* Only delete what we created */
-		if (instance->keep)
+		if (instance->flags & BUFFER_FL_KEEP)
 			continue;
 		if (instance->tracing_on_fd > 0) {
 			close(instance->tracing_on_fd);
@@ -3901,7 +3901,8 @@ static void check_function_plugin(void)
 
 static int __check_doing_something(struct buffer_instance *instance)
 {
-	return instance->profile || instance->plugin || instance->events;
+	return (instance->flags & BUFFER_FL_PROFILE) ||
+		instance->plugin || instance->events;
 }
 
 static void check_doing_something(void)
@@ -4429,7 +4430,7 @@ void trace_reset(int argc, char **argv)
 				die("Failed to create instance");
 			add_instance(instance, local_cpu_count);
 			/* -d will remove keep */
-			instance->keep = 1;
+			instance->flags |= BUFFER_FL_KEEP;
 			break;
 		case 't':
 			/* Force to use top instance */
@@ -4441,18 +4442,18 @@ void trace_reset(int argc, char **argv)
 			last_specified_all = 1;
 			add_all_instances();
 			for_each_instance(instance) {
-				instance->keep = 1;
+				instance->flags |= BUFFER_FL_KEEP;
 			}
 			break;
 		case 'd':
 			if (last_specified_all) {
 				for_each_instance(inst) {
-					inst->keep = 0;
+					instance->flags &= ~BUFFER_FL_KEEP;
 				}
 			} else {
 				if (is_top_instance(instance))
 					die("Can not delete top level buffer");
-				instance->keep = 0;
+				instance->flags &= ~BUFFER_FL_KEEP;
 			}
 			break;
 		}
@@ -4769,7 +4770,7 @@ static void parse_record_options(int argc,
 				die("Failed to create instance");
 			add_instance(ctx->instance, local_cpu_count);
 			if (IS_PROFILE(ctx))
-				ctx->instance->profile = 1;
+				ctx->instance->flags |= BUFFER_FL_PROFILE;
 			break;
 		case 'k':
 			keep = 1;
@@ -4791,7 +4792,7 @@ static void parse_record_options(int argc,
 			break;
 		case OPT_profile:
 			handle_init = trace_init_profile;
-			ctx->instance->profile = 1;
+			ctx->instance->flags |= BUFFER_FL_PROFILE;
 			ctx->events = 1;
 			break;
 		case OPT_stderr:
@@ -4895,7 +4896,7 @@ static void finalize_record_trace(struct common_record_context *ctx)
 
 	/* If tracing_on was enabled before we started, set it on now */
 	for_all_instances(instance) {
-		if (instance->keep)
+		if (instance->flags & BUFFER_FL_KEEP)
 			write_tracing_on(instance,
 					 instance->tracing_on_init_val);
 	}
@@ -4933,7 +4934,7 @@ static void record_trace(int argc, char **argv,
 	/* Save the state of tracing_on before starting */
 	for_all_instances(instance) {
 
-		if (!ctx->manual && instance->profile)
+		if (!ctx->manual && instance->flags & BUFFER_FL_PROFILE)
 			enable_profile(instance);
 
 		instance->tracing_on_init_val = read_tracing_on(instance);
@@ -5052,7 +5053,7 @@ void trace_extract(int argc, char **argv)
 	/* Save the state of tracing_on before starting */
 	for_all_instances(instance) {
 
-		if (!ctx.manual && instance->profile)
+		if (!ctx.manual && instance->flags & BUFFER_FL_PROFILE)
 			enable_profile(ctx.instance);
 
 		instance->tracing_on_init_val = read_tracing_on(instance);
@@ -5124,7 +5125,7 @@ void trace_profile(int argc, char **argv)
 	 * If no instances were set, then enable profiling on the top instance.
 	 */
 	if (!buffer_instances)
-		top_instance.profile = 1;
+		top_instance.flags |= BUFFER_FL_PROFILE;
 
 	record_trace(argc, argv, &ctx);
 	do_trace_profile();
Signature · 1 line
2.13.2
#39 lore raw

PATCH 38/38 trace-cmd: Add network handle into buffer instance

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

To allow each instance to have its own network connection, move the network_handle into the buffer instance structure.

---
 trace-local.h  |  1 +
 trace-record.c | 11 +++++++----
 2 files changed, 8 insertions(+), 4 deletions(-)
trace-local.h +1 -0
index d45c66c31dca..ffdd726af0fc 100644
@@ -196,6 +196,7 @@ struct buffer_instance {
 	struct tracecmd_input	*handle;
 
 	struct tracecmd_msg_handle *msg_handle;
+	struct tracecmd_output *network_handle;
 
 	int			flags;
 	int			tracing_on_init_val;
trace-record.c +7 -4
index 814c7e112285..9479f5f8073c 100644
@@ -89,7 +89,6 @@ static int clear_function_filters;
 static char *host;
 static int *client_ports;
 static int sfd;
-static struct tracecmd_output *network_handle;
 
 /* Max size to let a per cpu file get */
 static int max_kb;
@@ -2892,9 +2891,11 @@ again:
 	return msg_handle;
 }
 
-static struct tracecmd_msg_handle *setup_connection(void)
+static struct tracecmd_msg_handle *
+setup_connection(struct buffer_instance *instance)
 {
 	struct tracecmd_msg_handle *msg_handle;
+	struct tracecmd_output *network_handle;
 
 	msg_handle = setup_network();
 
@@ -2906,6 +2907,8 @@ static struct tracecmd_msg_handle *setup_connection(void)
 		network_handle = tracecmd_create_init_fd_glob(msg_handle->fd,
 							      listed_events);
 
+	instance->network_handle = network_handle;
+
 	/* OK, we are all set, let'r rip! */
 	return msg_handle;
 }
@@ -2940,7 +2943,7 @@ void start_threads(enum trace_type type, int global)
 		int x, pid;
 
 		if (host) {
-			instance->msg_handle = setup_connection();
+			instance->msg_handle = setup_connection(instance);
 			if (!instance->msg_handle)
 				die("Failed to make connection");
 		}
@@ -4902,7 +4905,7 @@ static void finalize_record_trace(struct common_record_context *ctx)
 	}
 
 	if (host)
-		tracecmd_output_close(network_handle);
+		tracecmd_output_close(ctx->instance->network_handle);
 }
 
 /*
Signature · 1 line
2.13.2