All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/5] trace-cmd: Have trace-cmd listen work with vsockets
@ 2022-04-17 18:33 Steven Rostedt
  2022-04-17 18:33 ` [PATCH v3 1/5] trace-cmd listen: Remove UDP from function names Steven Rostedt
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Steven Rostedt @ 2022-04-17 18:33 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (Google)

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>


We have a use case where the host is very minimal (like an embedded device)
and does not even have networking enabled. But it does have vsockets. We
need to trace this host and have it send its data to the guest. By running
trace-cmd listen on the guest and have the host use vsockets instead of
networking, can allow this host to be traced.

Depends on: https://patchwork.kernel.org/project/linux-trace-devel/list/?series=632868
  https://lore.kernel.org/r/20220417182154.1041513-1-rostedt@goodmis.org

Changes since v2: https://lore.kernel.org/all/20220415011023.938663-1-rostedt@goodmis.org/

 - Fixed freeing of host variable that was not allocated

Changes since v1: https://lore.kernel.org/all/20220412042739.836516-1-rostedt@goodmis.org/

 - Rebased on top of: https://lore.kernel.org/all/20220415010007.938408-1-rostedt@goodmis.org/

 - Added the documentation patch


Steven Rostedt (Google) (5):
  trace-cmd listen: Remove UDP from function names
  trace-cmd listen: Replace bool use_tcp with enum type
  trace-cmd record: Replace bool use_tcp with enum type
  trace-cmd listen: Add vsocket usage
  trace-cmd listen: Add documentation on vsocket usage

 .../trace-cmd/trace-cmd-listen.1.txt          |   4 +
 .../trace-cmd/trace-cmd-record.1.txt          |   8 +
 .../include/private/trace-cmd-private.h       |   1 +
 lib/trace-cmd/trace-msg.c                     |  15 +-
 tracecmd/include/trace-local.h                |   8 +
 tracecmd/trace-listen.c                       | 196 +++++++++++++-----
 tracecmd/trace-record.c                       |  93 +++++++--
 tracecmd/trace-usage.c                        |   2 +
 8 files changed, 256 insertions(+), 71 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3 1/5] trace-cmd listen: Remove UDP from function names
  2022-04-17 18:33 [PATCH v3 0/5] trace-cmd: Have trace-cmd listen work with vsockets Steven Rostedt
@ 2022-04-17 18:33 ` Steven Rostedt
  2022-04-17 18:33 ` [PATCH v3 2/5] trace-cmd listen: Replace bool use_tcp with enum type Steven Rostedt
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2022-04-17 18:33 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (Google)

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

Several functions have "udp" in their name when they also handle TCP. As
we are going to also add vsocket connections, it makes even less sense
to have these names with "udp". Make the names of the functions (and
some variables) more generic.

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 tracecmd/trace-listen.c | 42 ++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/tracecmd/trace-listen.c b/tracecmd/trace-listen.c
index 874ecd61d98a..b2ab05bc3068 100644
--- a/tracecmd/trace-listen.c
+++ b/tracecmd/trace-listen.c
@@ -137,8 +137,8 @@ static void remove_pid_file(void)
 	unlink(buf);
 }
 
-static int process_udp_child(int sfd, const char *host, const char *port,
-			     int cpu, int page_size, int use_tcp)
+static int process_child(int sfd, const char *host, const char *port,
+			 int cpu, int page_size, int use_tcp)
 {
 	struct sockaddr_storage peer_addr;
 	socklen_t peer_addr_len;
@@ -205,7 +205,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, int use_tcp)
+static int bind_a_port(int start_port, int *sfd, int use_tcp)
 {
 	struct addrinfo hints;
 	struct addrinfo *result, *rp;
@@ -223,7 +223,7 @@ static int udp_bind_a_port(int start_port, int *sfd, int use_tcp)
 
 	s = getaddrinfo(NULL, buf, &hints, &result);
 	if (s != 0)
-		pdie("getaddrinfo: error opening udp socket");
+		pdie("getaddrinfo: error opening socket");
 
 	for (rp = result; rp != NULL; rp = rp->ai_next) {
 		*sfd = socket(rp->ai_family, rp->ai_socktype,
@@ -249,40 +249,40 @@ static int udp_bind_a_port(int start_port, int *sfd, int use_tcp)
 	return num_port;
 }
 
-static void fork_udp_reader(int sfd, const char *node, const char *port,
-			    int *pid, int cpu, int pagesize, int use_tcp)
+static void fork_reader(int sfd, const char *node, const char *port,
+			int *pid, int cpu, int pagesize, int use_tcp)
 {
 	int ret;
 
 	*pid = fork();
 
 	if (*pid < 0)
-		pdie("creating udp reader");
+		pdie("creating reader");
 
 	if (!*pid) {
-		ret = process_udp_child(sfd, node, port, cpu, pagesize, use_tcp);
+		ret = process_child(sfd, node, port, cpu, pagesize, use_tcp);
 		if (ret < 0)
-			pdie("Problem with udp reader %d", ret);
+			pdie("Problem with reader %d", ret);
 	}
 
 	close(sfd);
 }
 
-static int open_udp(const char *node, const char *port, int *pid,
-		    int cpu, int pagesize, int start_port, int use_tcp)
+static int open_port(const char *node, const char *port, int *pid,
+		     int cpu, int pagesize, int start_port, int use_tcp)
 {
 	int sfd;
 	int num_port;
 
 	/*
-	 * udp_bind_a_port() currently does not return an error, but if that
+	 * 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, use_tcp);
+	num_port = bind_a_port(start_port, &sfd, use_tcp);
 	if (num_port < 0)
 		return num_port;
 
-	fork_udp_reader(sfd, node, port, pid, cpu, pagesize, use_tcp);
+	fork_reader(sfd, node, port, pid, cpu, pagesize, use_tcp);
 
 	return num_port;
 }
@@ -468,7 +468,7 @@ static int *create_all_readers(const char *node, const char *port,
 	unsigned int *port_array;
 	int *pid_array;
 	unsigned int start_port;
-	unsigned int udp_port;
+	unsigned int connect_port;
 	int cpus = msg_handle->cpu_count;
 	int cpu;
 	int pid;
@@ -490,19 +490,19 @@ static int *create_all_readers(const char *node, const char *port,
 
 	start_port = START_PORT_SEARCH;
 
-	/* Now create a UDP port for each CPU */
+	/* Now create a port for each CPU */
 	for (cpu = 0; cpu < cpus; cpu++) {
-		udp_port = open_udp(node, port, &pid, cpu,
-				    pagesize, start_port, use_tcp);
-		if (udp_port < 0)
+		connect_port = open_port(node, port, &pid, cpu,
+					 pagesize, start_port, use_tcp);
+		if (connect_port < 0)
 			goto out_free;
-		port_array[cpu] = udp_port;
+		port_array[cpu] = connect_port;
 		pid_array[cpu] = pid;
 		/*
 		 * Due to some bugging finding ports,
 		 * force search after last port
 		 */
-		start_port = udp_port + 1;
+		start_port = connect_port + 1;
 	}
 
 	if (msg_handle->version == V3_PROTOCOL) {
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 2/5] trace-cmd listen: Replace bool use_tcp with enum type
  2022-04-17 18:33 [PATCH v3 0/5] trace-cmd: Have trace-cmd listen work with vsockets Steven Rostedt
  2022-04-17 18:33 ` [PATCH v3 1/5] trace-cmd listen: Remove UDP from function names Steven Rostedt
@ 2022-04-17 18:33 ` Steven Rostedt
  2022-04-17 18:33 ` [PATCH v3 3/5] trace-cmd record: " Steven Rostedt
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2022-04-17 18:33 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (Google)

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

To allow listen to use vsockets as a connection interface, using a
boolean "use_tcp" is not flexible enough, as now there are three kinds
of connections. In preparation for adding vsockets have trace-cmd listen
use an enum instead of a boolean.

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 tracecmd/include/trace-local.h |  5 +++++
 tracecmd/trace-listen.c        | 27 +++++++++++++++------------
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/tracecmd/include/trace-local.h b/tracecmd/include/trace-local.h
index 863635886769..d23cbf24cc06 100644
--- a/tracecmd/include/trace-local.h
+++ b/tracecmd/include/trace-local.h
@@ -42,6 +42,11 @@ extern int show_status;
 
 int trace_set_verbose(char *level);
 
+enum port_type {
+	USE_UDP,
+	USE_TCP,
+};
+
 struct pid_record_data {
 	int			pid;
 	int			brass[2];
diff --git a/tracecmd/trace-listen.c b/tracecmd/trace-listen.c
index b2ab05bc3068..a5d4ec64f77c 100644
--- a/tracecmd/trace-listen.c
+++ b/tracecmd/trace-listen.c
@@ -138,7 +138,7 @@ static void remove_pid_file(void)
 }
 
 static int process_child(int sfd, const char *host, const char *port,
-			 int cpu, int page_size, int use_tcp)
+			 int cpu, int page_size, enum port_type type)
 {
 	struct sockaddr_storage peer_addr;
 	socklen_t peer_addr_len;
@@ -160,7 +160,7 @@ static int process_child(int sfd, const char *host, const char *port,
 	if (fd < 0)
 		pdie("creating %s", tempfile);
 
-	if (use_tcp) {
+	if (type == USE_TCP) {
 		if (listen(sfd, backlog) < 0)
 			pdie("listen");
 		peer_addr_len = sizeof(peer_addr);
@@ -184,7 +184,7 @@ static int process_child(int sfd, const char *host, const char *port,
 		if (!r)
 			break;
 		/* UDP requires that we get the full size in one go */
-		if (!use_tcp && r < page_size && !once) {
+		if (type == USE_UDP && r < page_size && !once) {
 			once = 1;
 			warning("read %d bytes, expected %d", r, page_size);
 		}
@@ -205,7 +205,7 @@ static int process_child(int sfd, const char *host, const char *port,
 #define START_PORT_SEARCH 1500
 #define MAX_PORT_SEARCH 6000
 
-static int bind_a_port(int start_port, int *sfd, int use_tcp)
+static int bind_a_port(int start_port, int *sfd, enum port_type type)
 {
 	struct addrinfo hints;
 	struct addrinfo *result, *rp;
@@ -218,7 +218,7 @@ static int bind_a_port(int start_port, int *sfd, int use_tcp)
 
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = AF_UNSPEC;
-	hints.ai_socktype = use_tcp ? SOCK_STREAM : SOCK_DGRAM;
+	hints.ai_socktype = type == USE_TCP ? SOCK_STREAM : SOCK_DGRAM;
 	hints.ai_flags = AI_PASSIVE;
 
 	s = getaddrinfo(NULL, buf, &hints, &result);
@@ -250,7 +250,7 @@ static int bind_a_port(int start_port, int *sfd, int use_tcp)
 }
 
 static void fork_reader(int sfd, const char *node, const char *port,
-			int *pid, int cpu, int pagesize, int use_tcp)
+			int *pid, int cpu, int pagesize, enum port_type type)
 {
 	int ret;
 
@@ -260,7 +260,7 @@ static void fork_reader(int sfd, const char *node, const char *port,
 		pdie("creating reader");
 
 	if (!*pid) {
-		ret = process_child(sfd, node, port, cpu, pagesize, use_tcp);
+		ret = process_child(sfd, node, port, cpu, pagesize, type);
 		if (ret < 0)
 			pdie("Problem with reader %d", ret);
 	}
@@ -269,7 +269,7 @@ static void fork_reader(int sfd, const char *node, const char *port,
 }
 
 static int open_port(const char *node, const char *port, int *pid,
-		     int cpu, int pagesize, int start_port, int use_tcp)
+		     int cpu, int pagesize, int start_port, enum port_type type)
 {
 	int sfd;
 	int num_port;
@@ -278,11 +278,11 @@ static int open_port(const char *node, const char *port, int *pid,
 	 * 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 = bind_a_port(start_port, &sfd, use_tcp);
+	num_port = bind_a_port(start_port, &sfd, type);
 	if (num_port < 0)
 		return num_port;
 
-	fork_reader(sfd, node, port, pid, cpu, pagesize, use_tcp);
+	fork_reader(sfd, node, port, pid, cpu, pagesize, type);
 
 	return num_port;
 }
@@ -463,7 +463,7 @@ static void destroy_all_readers(int cpus, int *pid_array, const char *node,
 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;
+	enum port_type port_type = USE_UDP;
 	char buf[BUFSIZ];
 	unsigned int *port_array;
 	int *pid_array;
@@ -476,6 +476,9 @@ static int *create_all_readers(const char *node, const char *port,
 	if (!pagesize)
 		return NULL;
 
+	if (msg_handle->flags & TRACECMD_MSG_FL_USE_TCP)
+		port_type = USE_TCP;
+
 	port_array = malloc(sizeof(*port_array) * cpus);
 	if (!port_array)
 		return NULL;
@@ -493,7 +496,7 @@ static int *create_all_readers(const char *node, const char *port,
 	/* Now create a port for each CPU */
 	for (cpu = 0; cpu < cpus; cpu++) {
 		connect_port = open_port(node, port, &pid, cpu,
-					 pagesize, start_port, use_tcp);
+					 pagesize, start_port, port_type);
 		if (connect_port < 0)
 			goto out_free;
 		port_array[cpu] = connect_port;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 3/5] trace-cmd record: Replace bool use_tcp with enum type
  2022-04-17 18:33 [PATCH v3 0/5] trace-cmd: Have trace-cmd listen work with vsockets Steven Rostedt
  2022-04-17 18:33 ` [PATCH v3 1/5] trace-cmd listen: Remove UDP from function names Steven Rostedt
  2022-04-17 18:33 ` [PATCH v3 2/5] trace-cmd listen: Replace bool use_tcp with enum type Steven Rostedt
@ 2022-04-17 18:33 ` Steven Rostedt
  2022-04-17 18:33 ` [PATCH v3 4/5] trace-cmd listen: Add vsocket usage Steven Rostedt
  2022-04-17 18:33 ` [PATCH v3 5/5] trace-cmd listen: Add documentation on " Steven Rostedt
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2022-04-17 18:33 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (Google)

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

To allow trace-cmd record to communicate with trace-cmd listen with
vsockets as a connection interface, using a boolean "use_tcp" is not
flexible enough, as now there are three kinds of connections. In
preparation for adding vsockets have trace-cmd record/listen use an enum
instead of a boolean.

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 tracecmd/trace-record.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index ac6fb7e98892..022a024c665b 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -90,7 +90,7 @@ static bool fork_process;
 /* Max size to let a per cpu file get */
 static int max_kb;
 
-static bool use_tcp;
+static enum port_type port_type;
 
 static int do_ptrace;
 
@@ -3130,12 +3130,12 @@ static int connect_port(const char *host, unsigned int port)
 
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = AF_UNSPEC;
-	hints.ai_socktype = use_tcp ? SOCK_STREAM : SOCK_DGRAM;
+	hints.ai_socktype = port_type == USE_TCP ? SOCK_STREAM : SOCK_DGRAM;
 
 	s = getaddrinfo(host, buf, &hints, &results);
 	if (s != 0)
 		die("connecting to %s server %s:%s",
-		    use_tcp ? "TCP" : "UDP", host, buf);
+		    port_type == USE_TCP ? "TCP" : "UDP", host, buf);
 
 	for (rp = results; rp != NULL; rp = rp->ai_next) {
 		sfd = socket(rp->ai_family, rp->ai_socktype,
@@ -3149,7 +3149,7 @@ static int connect_port(const char *host, unsigned int port)
 
 	if (rp == NULL)
 		die("Can not connect to %s server %s:%s",
-		    use_tcp ? "TCP" : "UDP", host, buf);
+		    port_type == USE_TCP ? "TCP" : "UDP", host, buf);
 
 	freeaddrinfo(results);
 
@@ -3439,11 +3439,11 @@ static void communicate_with_listener_v1(struct tracecmd_msg_handle *msg_handle,
 	/* TODO, test for ipv4 */
 	if (page_size >= UDP_MAX_PACKET) {
 		warning("page size too big for UDP using TCP in live read");
-		use_tcp = 1;
+		port_type = USE_TCP;
 		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
 	}
 
-	if (use_tcp) {
+	if (port_type == USE_TCP) {
 		/* Send one option */
 		write(msg_handle->fd, "1", 2);
 		/* Size 4 */
@@ -3591,7 +3591,7 @@ again:
 		msg_handle->version = V3_PROTOCOL;
 	}
 
-	if (use_tcp)
+	if (port_type == USE_TCP)
 		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
 
 	if (msg_handle->version == V3_PROTOCOL) {
@@ -6467,7 +6467,7 @@ static void parse_record_options(int argc,
 			if (IS_EXTRACT(ctx))
 				ctx->topt = 1; /* Extract top instance also */
 			else
-				use_tcp = 1;
+				port_type = USE_TCP;
 			break;
 		case 'b':
 			check_instance_die(ctx->instance, "-b");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 4/5] trace-cmd listen: Add vsocket usage
  2022-04-17 18:33 [PATCH v3 0/5] trace-cmd: Have trace-cmd listen work with vsockets Steven Rostedt
                   ` (2 preceding siblings ...)
  2022-04-17 18:33 ` [PATCH v3 3/5] trace-cmd record: " Steven Rostedt
@ 2022-04-17 18:33 ` Steven Rostedt
  2022-04-17 18:33 ` [PATCH v3 5/5] trace-cmd listen: Add documentation on " Steven Rostedt
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2022-04-17 18:33 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (Google)

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

As vsockets are slightly faster than TCP connections, and act the same,
there's no reason to not use them for the listen command.

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 .../include/private/trace-cmd-private.h       |   1 +
 lib/trace-cmd/trace-msg.c                     |  15 +-
 tracecmd/include/trace-local.h                |   3 +
 tracecmd/trace-listen.c                       | 143 ++++++++++++++----
 tracecmd/trace-record.c                       |  79 +++++++++-
 5 files changed, 202 insertions(+), 39 deletions(-)

diff --git a/lib/trace-cmd/include/private/trace-cmd-private.h b/lib/trace-cmd/include/private/trace-cmd-private.h
index 45ae1dded66d..f68d17bb8e1d 100644
--- a/lib/trace-cmd/include/private/trace-cmd-private.h
+++ b/lib/trace-cmd/include/private/trace-cmd-private.h
@@ -374,6 +374,7 @@ long tracecmd_flush_recording(struct tracecmd_recorder *recorder);
 
 enum tracecmd_msg_flags {
 	TRACECMD_MSG_FL_USE_TCP		= 1 << 0,
+	TRACECMD_MSG_FL_USE_VSOCK	= 1 << 1,
 };
 
 /* for both client and server */
diff --git a/lib/trace-cmd/trace-msg.c b/lib/trace-cmd/trace-msg.c
index 726e9424c8fd..6cf74f9b1c99 100644
--- a/lib/trace-cmd/trace-msg.c
+++ b/lib/trace-cmd/trace-msg.c
@@ -214,10 +214,14 @@ static int make_tinit(struct tracecmd_msg_handle *msg_handle,
 	int opt_num = 0;
 	int data_size = 0;
 
-	if (msg_handle->flags & TRACECMD_MSG_FL_USE_TCP) {
+	if (msg_handle->flags & (TRACECMD_MSG_FL_USE_TCP |
+				 TRACECMD_MSG_FL_USE_VSOCK)) {
+		msg->buf = msg_handle->flags & TRACECMD_MSG_FL_USE_TCP ?
+			strdup("tcp") : strdup("vsock");
+		if (!msg->buf)
+			return -1;
 		opt_num++;
-		msg->buf = strdup("tcp");
-		data_size += 4;
+		data_size += strlen(msg->buf) + 1;
 	}
 
 	msg->tinit.cpus = htonl(cpu_count);
@@ -566,11 +570,14 @@ out:
 static bool process_option(struct tracecmd_msg_handle *msg_handle,
 			   const char *opt)
 {
-	/* currently the only option we have is to use TCP */
 	if (strcmp(opt, "tcp") == 0) {
 		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
 		return true;
 	}
+	if (strcmp(opt, "vsock") == 0) {
+		msg_handle->flags |= TRACECMD_MSG_FL_USE_VSOCK;
+		return true;
+	}
 	return false;
 }
 
diff --git a/tracecmd/include/trace-local.h b/tracecmd/include/trace-local.h
index d23cbf24cc06..aa1cb8d939bd 100644
--- a/tracecmd/include/trace-local.h
+++ b/tracecmd/include/trace-local.h
@@ -45,6 +45,7 @@ int trace_set_verbose(char *level);
 enum port_type {
 	USE_UDP,
 	USE_TCP,
+	USE_VSOCK
 };
 
 struct pid_record_data {
@@ -343,6 +344,8 @@ int trace_make_vsock(unsigned int port);
 int trace_get_vsock_port(int sd, unsigned int *port);
 int trace_open_vsock(unsigned int cid, unsigned int port);
 
+int get_local_cid(unsigned int *cid);
+
 char *trace_get_guest_file(const char *file, const char *guest);
 
 #ifdef VSOCK
diff --git a/tracecmd/trace-listen.c b/tracecmd/trace-listen.c
index a5d4ec64f77c..2338173fc8a6 100644
--- a/tracecmd/trace-listen.c
+++ b/tracecmd/trace-listen.c
@@ -19,6 +19,10 @@
 #include <signal.h>
 #include <errno.h>
 
+#ifdef VSOCK
+#include <linux/vm_sockets.h>
+#endif
+
 #include "trace-local.h"
 #include "trace-msg.h"
 
@@ -34,6 +38,8 @@ static char *output_dir;
 static char *default_output_file = "trace";
 static char *output_file;
 
+static bool use_vsock;
+
 static int backlog = 5;
 
 static int do_daemon;
@@ -141,7 +147,11 @@ static int process_child(int sfd, const char *host, const char *port,
 			 int cpu, int page_size, enum port_type type)
 {
 	struct sockaddr_storage peer_addr;
-	socklen_t peer_addr_len;
+#ifdef VSOCK
+	struct sockaddr_vm vm_addr;
+#endif
+	struct sockaddr *addr;
+	socklen_t addr_len;
 	char buf[page_size];
 	char *tempfile;
 	int left;
@@ -161,10 +171,20 @@ static int process_child(int sfd, const char *host, const char *port,
 		pdie("creating %s", tempfile);
 
 	if (type == USE_TCP) {
+		addr = (struct sockaddr *)&peer_addr;
+		addr_len = sizeof(peer_addr);
+#ifdef VSOCK
+	} else if (type == USE_VSOCK) {
+		addr = (struct sockaddr *)&vm_addr;
+		addr_len = sizeof(vm_addr);
+#endif
+	}
+
+	if (type == USE_TCP || type == USE_VSOCK) {
 		if (listen(sfd, backlog) < 0)
 			pdie("listen");
-		peer_addr_len = sizeof(peer_addr);
-		cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len);
+
+		cfd = accept(sfd, addr, &addr_len);
 		if (cfd < 0 && errno == EINTR)
 			goto done;
 		if (cfd < 0)
@@ -202,6 +222,18 @@ static int process_child(int sfd, const char *host, const char *port,
 	exit(0);
 }
 
+static int setup_vsock_port(int start_port, int *sfd)
+{
+	int sd;
+
+	sd = trace_vsock_make(start_port);
+	if (sd < 0)
+		return -errno;
+	*sfd = sd;
+
+	return start_port;
+}
+
 #define START_PORT_SEARCH 1500
 #define MAX_PORT_SEARCH 6000
 
@@ -213,6 +245,8 @@ static int bind_a_port(int start_port, int *sfd, enum port_type type)
 	int s;
 	int num_port = start_port;
 
+	if (type == USE_VSOCK)
+		return setup_vsock_port(start_port, sfd);
  again:
 	snprintf(buf, BUFSIZ, "%d", num_port);
 
@@ -478,6 +512,8 @@ static int *create_all_readers(const char *node, const char *port,
 
 	if (msg_handle->flags & TRACECMD_MSG_FL_USE_TCP)
 		port_type = USE_TCP;
+	else if (msg_handle->flags & TRACECMD_MSG_FL_USE_VSOCK)
+		port_type = USE_VSOCK;
 
 	port_array = malloc(sizeof(*port_array) * cpus);
 	if (!port_array)
@@ -700,8 +736,8 @@ static int do_fork(int cfd)
 	return 0;
 }
 
-static int do_connection(int cfd, struct sockaddr_storage *peer_addr,
-			  socklen_t peer_addr_len)
+static int do_connection(int cfd, struct sockaddr *addr,
+			  socklen_t addr_len)
 {
 	struct tracecmd_msg_handle *msg_handle;
 	char host[NI_MAXHOST], service[NI_MAXSERV];
@@ -714,17 +750,25 @@ static int do_connection(int cfd, struct sockaddr_storage *peer_addr,
 
 	msg_handle = tracecmd_msg_handle_alloc(cfd, 0);
 
-	s = getnameinfo((struct sockaddr *)peer_addr, peer_addr_len,
-			host, NI_MAXHOST,
-			service, NI_MAXSERV, NI_NUMERICSERV);
-
-	if (s == 0)
-		tracecmd_plog("Connected with %s:%s\n", host, service);
-	else {
-		tracecmd_plog("Error with getnameinfo: %s\n", gai_strerror(s));
-		close(cfd);
-		tracecmd_msg_handle_close(msg_handle);
-		return -1;
+	if (use_vsock) {
+#ifdef VSOCK
+		struct sockaddr_vm *vm_addr = (struct sockaddr_vm *)addr;
+		snprintf(host, NI_MAXHOST, "V%d", vm_addr->svm_cid);
+		snprintf(service, NI_MAXSERV, "%d", vm_addr->svm_port);
+#endif
+	} else {
+		s = getnameinfo((struct sockaddr *)addr, addr_len,
+				host, NI_MAXHOST,
+				service, NI_MAXSERV, NI_NUMERICSERV);
+
+		if (s == 0)
+			tracecmd_plog("Connected with %s:%s\n", host, service);
+		else {
+			tracecmd_plog("Error with getnameinfo: %s\n", gai_strerror(s));
+			close(cfd);
+			tracecmd_msg_handle_close(msg_handle);
+			return -1;
+		}
 	}
 
 	process_client(msg_handle, host, service);
@@ -816,14 +860,25 @@ static void clean_up(void)
 static void do_accept_loop(int sfd)
 {
 	struct sockaddr_storage peer_addr;
-	socklen_t peer_addr_len;
+#ifdef VSOCK
+	struct sockaddr_vm vm_addr;
+#endif
+	struct sockaddr *addr;
+	socklen_t addr_len;
 	int cfd, pid;
 
-	peer_addr_len = sizeof(peer_addr);
+	if (use_vsock) {
+#ifdef VSOCK
+		addr = (struct sockaddr *)&vm_addr;
+		addr_len = sizeof(vm_addr);
+#endif
+	} else {
+		addr = (struct sockaddr *)&peer_addr;
+		addr_len = sizeof(peer_addr);
+	}
 
 	do {
-		cfd = accept(sfd, (struct sockaddr *)&peer_addr,
-			     &peer_addr_len);
+		cfd = accept(sfd, addr, &addr_len);
 		if (cfd < 0 && errno == EINTR) {
 			clean_up();
 			continue;
@@ -831,7 +886,7 @@ static void do_accept_loop(int sfd)
 		if (cfd < 0)
 			pdie("connecting");
 
-		pid = do_connection(cfd, &peer_addr, peer_addr_len);
+		pid = do_connection(cfd, addr, addr_len);
 		if (pid > 0)
 			add_process(pid);
 
@@ -866,17 +921,28 @@ static void sigstub(int sig)
 {
 }
 
-static void do_listen(char *port)
+static int get_vsock(const char *port)
+{
+	unsigned int cid;
+	int sd;
+
+	sd = trace_vsock_make(atoi(port));
+	if (sd < 0)
+		return sd;
+
+	cid = trace_vsock_local_cid();
+	if (cid >= 0)
+		printf("listening on @%u:%s\n", cid, port);
+
+	return sd;
+}
+
+static int get_network(char *port)
 {
 	struct addrinfo hints;
 	struct addrinfo *result, *rp;
 	int sfd, s;
 
-	if (!tracecmd_get_debug())
-		signal_setup(SIGCHLD, sigstub);
-
-	make_pid_file();
-
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = AF_UNSPEC;
 	hints.ai_socktype = SOCK_STREAM;
@@ -903,6 +969,24 @@ static void do_listen(char *port)
 
 	freeaddrinfo(result);
 
+	return sfd;
+}
+
+static void do_listen(char *port)
+{
+	int sfd;
+
+	if (!tracecmd_get_debug())
+		signal_setup(SIGCHLD, sigstub);
+
+	make_pid_file();
+
+	if (use_vsock)
+		sfd = get_vsock(port);
+	else
+		sfd = get_network(port);
+
+
 	if (listen(sfd, backlog) < 0)
 		pdie("listen");
 
@@ -949,7 +1033,7 @@ void trace_listen(int argc, char **argv)
 			{NULL, 0, NULL, 0}
 		};
 
-		c = getopt_long (argc-1, argv+1, "+hp:o:d:l:D",
+		c = getopt_long (argc-1, argv+1, "+hp:Vo:d:l:D",
 			long_options, &option_index);
 		if (c == -1)
 			break;
@@ -963,6 +1047,9 @@ void trace_listen(int argc, char **argv)
 		case 'd':
 			output_dir = optarg;
 			break;
+		case 'V':
+			use_vsock = true;
+			break;
 		case 'o':
 			output_file = optarg;
 			break;
diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index 022a024c665b..674ec2c3ba65 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -3128,6 +3128,9 @@ static int connect_port(const char *host, unsigned int port)
 
 	snprintf(buf, BUFSIZ, "%u", port);
 
+	if (port_type == USE_VSOCK)
+		return trace_vsock_open(atoi(host), port);
+
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = AF_UNSPEC;
 	hints.ai_socktype = port_type == USE_TCP ? SOCK_STREAM : SOCK_DGRAM;
@@ -3531,9 +3534,30 @@ static void check_protocol_version(struct tracecmd_msg_handle *msg_handle)
 	}
 }
 
-static struct tracecmd_msg_handle *setup_network(struct buffer_instance *instance)
+static int connect_vsock(char *vhost)
+{
+	char *cid;
+	char *port;
+	char *p;
+	int sd;
+
+	host = strdup(vhost);
+	if (!host)
+		die("alloctating server");
+
+	cid = strtok_r(host, ":", &p);
+	port = strtok_r(NULL, "", &p);
+
+	if (!port)
+		die("vsocket must have format of 'CID:PORT'");
+
+	sd = trace_vsock_open(atoi(cid), atoi(port));
+
+	return sd;
+}
+
+static int connect_ip(char *thost)
 {
-	struct tracecmd_msg_handle *msg_handle = NULL;
 	struct addrinfo hints;
 	struct addrinfo *result, *rp;
 	int sfd, s;
@@ -3545,10 +3569,10 @@ static struct tracecmd_msg_handle *setup_network(struct buffer_instance *instanc
 		server = strdup("localhost");
 		if (!server)
 			die("alloctating server");
-		port = host;
+		port = thost;
 		host = server;
 	} else {
-		host = strdup(host);
+		host = strdup(thost);
 		if (!host)
 			die("alloctating server");
 		server = strtok_r(host, ":", &p);
@@ -3559,7 +3583,6 @@ static struct tracecmd_msg_handle *setup_network(struct buffer_instance *instanc
 	hints.ai_family = AF_UNSPEC;
 	hints.ai_socktype = SOCK_STREAM;
 
-again:
 	s = getaddrinfo(server, port, &hints, &result);
 	if (s != 0)
 		die("getaddrinfo: %s", gai_strerror(s));
@@ -3580,6 +3603,26 @@ again:
 
 	freeaddrinfo(result);
 
+	return sfd;
+}
+
+static struct tracecmd_msg_handle *setup_network(struct buffer_instance *instance)
+{
+	struct tracecmd_msg_handle *msg_handle = NULL;
+	int sfd;
+
+again:
+	switch (port_type) {
+	case USE_VSOCK:
+		sfd = connect_vsock(host);
+		break;
+	default:
+		sfd = connect_ip(host);
+	}
+
+	if (sfd < 0)
+		return NULL;
+
 	if (msg_handle) {
 		msg_handle->fd = sfd;
 	} else {
@@ -3591,14 +3634,23 @@ again:
 		msg_handle->version = V3_PROTOCOL;
 	}
 
-	if (port_type == USE_TCP)
+	switch (port_type) {
+	case USE_TCP:
 		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
+		break;
+	case USE_VSOCK:
+		msg_handle->flags |= TRACECMD_MSG_FL_USE_VSOCK;
+		break;
+	default:
+		break;
+	}
 
 	if (msg_handle->version == V3_PROTOCOL) {
 		check_protocol_version(msg_handle);
 		if (msg_handle->version == V1_PROTOCOL) {
 			/* reconnect to the server for using the v1 protocol */
 			close(sfd);
+			free(host);
 			goto again;
 		}
 		communicate_with_listener_v3(msg_handle, &instance->client_ports);
@@ -3649,6 +3701,8 @@ setup_connection(struct buffer_instance *instance, struct common_record_context
 	int ret;
 
 	msg_handle = setup_network(instance);
+	if (!msg_handle)
+		die("Failed to make connection");
 
 	/* Now create the handle through this socket */
 	if (msg_handle->version == V3_PROTOCOL) {
@@ -6159,7 +6213,7 @@ static void parse_record_options(int argc,
 		if (IS_EXTRACT(ctx))
 			opts = "+haf:Fp:co:O:sr:g:l:n:P:N:tb:B:ksiT";
 		else
-			opts = "+hae:f:FA:p:cC:dDGo:O:s:r:vg:l:n:P:N:tb:R:B:ksSiTm:M:H:q";
+			opts = "+hae:f:FA:p:cC:dDGo:O:s:r:V:vg:l:n:P:N:tb:R:B:ksSiTm:M:H:q";
 		c = getopt_long (argc-1, argv+1, opts, long_options, &option_index);
 		if (c == -1)
 			break;
@@ -6451,6 +6505,17 @@ static void parse_record_options(int argc,
 				die("-N incompatible with -o");
 			host = optarg;
 			break;
+		case 'V':
+			cmd_check_die(ctx, CMD_set, *(argv+1), "-V");
+			if (!IS_RECORD(ctx))
+				die("-V only available with record");
+			if (IS_RECORD_AGENT(ctx))
+				die("-V incompatible with agent recording");
+			if (ctx->output)
+				die("-V incompatible with -o");
+			host = optarg;
+			port_type = USE_VSOCK;
+			break;
 		case 'm':
 			if (max_kb)
 				die("-m can only be specified once");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 5/5] trace-cmd listen: Add documentation on vsocket usage
  2022-04-17 18:33 [PATCH v3 0/5] trace-cmd: Have trace-cmd listen work with vsockets Steven Rostedt
                   ` (3 preceding siblings ...)
  2022-04-17 18:33 ` [PATCH v3 4/5] trace-cmd listen: Add vsocket usage Steven Rostedt
@ 2022-04-17 18:33 ` Steven Rostedt
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2022-04-17 18:33 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (Google)

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

Document the -V option for trace-cmd listen/record in both the usage and the
man pages.

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 Documentation/trace-cmd/trace-cmd-listen.1.txt | 4 ++++
 Documentation/trace-cmd/trace-cmd-record.1.txt | 8 ++++++++
 tracecmd/trace-usage.c                         | 2 ++
 3 files changed, 14 insertions(+)

diff --git a/Documentation/trace-cmd/trace-cmd-listen.1.txt b/Documentation/trace-cmd/trace-cmd-listen.1.txt
index aa6a307ff3b7..7c6093ba5354 100644
--- a/Documentation/trace-cmd/trace-cmd-listen.1.txt
+++ b/Documentation/trace-cmd/trace-cmd-listen.1.txt
@@ -26,6 +26,10 @@ OPTIONS
     This options causes trace-cmd listen to go into a daemon mode and run in
     the background.
 
+*-V*::
+    Listen on a vsocket instead. This is useful for tracing between host and
+    guest VMs.
+
 *-d* 'dir'::
     This option specifies a directory to write the data files into.
 
diff --git a/Documentation/trace-cmd/trace-cmd-record.1.txt b/Documentation/trace-cmd/trace-cmd-record.1.txt
index 426e856bf74a..6b8e3b4ad364 100644
--- a/Documentation/trace-cmd/trace-cmd-record.1.txt
+++ b/Documentation/trace-cmd/trace-cmd-record.1.txt
@@ -259,6 +259,14 @@ OPTIONS
     Note: This option is not supported with latency tracer plugins:
       wakeup, wakeup_rt, irqsoff, preemptoff and preemptirqsoff
 
+*-V* 'cid:port'::
+    If recording on a guest VM and the host is running *trace-cmd listen* with
+    the *-V* option as well, or if this is recording on the host, and a guest
+    in running *trace-cmd listen* with the *-V* option, then connect to the
+    listener (the same as connecting with the *-N* option via the network).
+    This has the same limitations as the *-N* option above with respect to
+    latency tracer plugins.
+
 *-t*::
     This option is used with *-N*, when there's a need to send the live data
     with TCP packets instead of UDP. Although TCP is not nearly as fast as
diff --git a/tracecmd/trace-usage.c b/tracecmd/trace-usage.c
index 20995fabed73..ec6376557394 100644
--- a/tracecmd/trace-usage.c
+++ b/tracecmd/trace-usage.c
@@ -44,6 +44,7 @@ static struct usage_help usage_help[] = {
 		"          -s sleep interval between recording (in usecs) [default: 1000]\n"
 		"          -S used with --profile, to enable only events in command line\n"
 		"          -N host:port to connect to (see listen)\n"
+		"          -V cid:port to connect to via vsocket (see listen)\n"
 		"          -t used with -N, forces use of tcp in live trace\n"
 		"          -b change kernel buffersize (in kilobytes per CPU)\n"
 		"          -B create sub buffer and following events will be enabled here\n"
@@ -318,6 +319,7 @@ static struct usage_help usage_help[] = {
 		"          Creates a socket to listen for clients.\n"
 		"          -p port number to listen on.\n"
 		"          -D run in daemon mode.\n"
+		"          -V listen on a vsocket instead.\n"
 		"          -o file name to use for clients.\n"
 		"          -d directory to store client files.\n"
 		"          -l logfile to write messages to.\n"
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-04-17 18:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-17 18:33 [PATCH v3 0/5] trace-cmd: Have trace-cmd listen work with vsockets Steven Rostedt
2022-04-17 18:33 ` [PATCH v3 1/5] trace-cmd listen: Remove UDP from function names Steven Rostedt
2022-04-17 18:33 ` [PATCH v3 2/5] trace-cmd listen: Replace bool use_tcp with enum type Steven Rostedt
2022-04-17 18:33 ` [PATCH v3 3/5] trace-cmd record: " Steven Rostedt
2022-04-17 18:33 ` [PATCH v3 4/5] trace-cmd listen: Add vsocket usage Steven Rostedt
2022-04-17 18:33 ` [PATCH v3 5/5] trace-cmd listen: Add documentation on " Steven Rostedt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.