aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Rostedt (Google) <rostedt@goodmis.org>2022-04-20 11:26:30 -0400
committerSteven Rostedt (Google) <rostedt@goodmis.org>2022-04-26 20:50:18 -0400
commit35e0ea22bc5a8b4a377133bf72cf7be683aa9b8e (patch)
tree525a86ed4f846de55a1775a81bd76553e5988a10
parent6af3a104a3a868ec9e98fddc6567fe7fc21eae6d (diff)
downloadtrace-cmd-35e0ea22bc5a8b4a377133bf72cf7be683aa9b8e.tar.gz
trace-cmd agent: Allow for ip connections from the agent
Add a -N option to trace-cmd agent to listen on a network socket that can be used by trace-cmd record -A to connect with. Link: https://lore.kernel.org/linux-trace-devel/20220420152637.13105-5-rostedt@goodmis.org Link: https://lore.kernel.org/linux-trace-devel/20220417184538.1044417-5-rostedt@goodmis.org Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-rw-r--r--tracecmd/include/trace-local.h6
-rw-r--r--tracecmd/trace-agent.c89
-rw-r--r--tracecmd/trace-listen.c58
3 files changed, 113 insertions, 40 deletions
diff --git a/tracecmd/include/trace-local.h b/tracecmd/include/trace-local.h
index 5ffd2912..77d531d5 100644
--- a/tracecmd/include/trace-local.h
+++ b/tracecmd/include/trace-local.h
@@ -306,6 +306,12 @@ extern struct buffer_instance *first_instance;
#define is_guest(instance) ((instance)->flags & BUFFER_FL_GUEST)
#define is_network(instance) ((instance)->flags & BUFFER_FL_NETWORK)
+#define START_PORT_SEARCH 1500
+#define MAX_PORT_SEARCH 6000
+
+int trace_net_make(int port, enum port_type type);
+int trace_net_search(int start_port, int *sfd, enum port_type type);
+
struct buffer_instance *allocate_instance(const char *name);
void add_instance(struct buffer_instance *instance, int cpu_count);
void update_first_instance(struct buffer_instance *instance, int topt);
diff --git a/tracecmd/trace-agent.c b/tracecmd/trace-agent.c
index 719d7126..cd201ad9 100644
--- a/tracecmd/trace-agent.c
+++ b/tracecmd/trace-agent.c
@@ -41,6 +41,32 @@ static void make_vsocks(int nr, int *fds, unsigned int *ports)
}
}
+static void make_net(int nr, int *fds, unsigned int *ports)
+{
+ int port;
+ int i, fd;
+ int start_port = START_PORT_SEARCH;
+
+ for (i = 0; i < nr; i++) {
+ port = trace_net_search(start_port, &fd, USE_TCP);
+ if (port < 0)
+ die("Failed to open socket");
+ if (listen(fd, 5) < 0)
+ die("Failed to listen on port %d\n", port);
+ fds[i] = fd;
+ ports[i] = port;
+ start_port = port + 1;
+ }
+}
+
+static void make_sockets(int nr, int *fds, unsigned int *ports, bool network)
+{
+ if (network)
+ return make_net(nr, fds, ports);
+ else
+ return make_vsocks(nr, fds, ports);
+}
+
static int open_agent_fifos(int nr_cpus, int *fds)
{
char path[PATH_MAX];
@@ -80,7 +106,7 @@ static char *get_clock(int argc, char **argv)
return NULL;
}
-static void agent_handle(int sd, int nr_cpus, int page_size)
+static void agent_handle(int sd, int nr_cpus, int page_size, bool network)
{
struct tracecmd_tsync_protos *tsync_protos = NULL;
struct tracecmd_time_sync *tsync = NULL;
@@ -117,17 +143,31 @@ static void agent_handle(int sd, int nr_cpus, int page_size)
use_fifos = false;
if (!use_fifos)
- make_vsocks(nr_cpus, fds, ports);
+ make_sockets(nr_cpus, fds, ports, network);
if (tsync_protos && tsync_protos->names) {
- if (get_vsocket_params(msg_handle->fd, &local_id,
- &remote_id)) {
- warning("Failed to get local and remote ids");
- /* Just make something up */
- remote_id = -1;
- local_id = -2;
+ if (network) {
+ /* For now just use something */
+ remote_id = 2;
+ local_id = 1;
+ tsync_port = trace_net_search(START_PORT_SEARCH, &fd, USE_TCP);
+ if (listen(fd, 5) < 0)
+ die("Failed to listen on %d\n", tsync_port);
+ } else {
+ if (get_vsocket_params(msg_handle->fd, &local_id,
+ &remote_id)) {
+ warning("Failed to get local and remote ids");
+ /* Just make something up */
+ remote_id = -1;
+ local_id = -2;
+ }
+ fd = trace_vsock_make_any();
+ if (fd >= 0 &&
+ trace_vsock_get_port(fd, &tsync_port) < 0) {
+ close(fd);
+ fd = -1;
+ }
}
- fd = trace_vsock_make_any();
- if (fd >= 0 && trace_vsock_get_port(fd, &tsync_port) >= 0) {
+ if (fd >= 0) {
tsync = tracecmd_tsync_with_host(fd, tsync_protos,
get_clock(argc, argv),
remote_id, local_id);
@@ -193,7 +233,7 @@ static pid_t do_fork()
return fork();
}
-static void agent_serve(unsigned int port, bool do_daemon)
+static void agent_serve(unsigned int port, bool do_daemon, bool network)
{
int sd, cd, nr_cpus;
unsigned int cid;
@@ -204,14 +244,21 @@ static void agent_serve(unsigned int port, bool do_daemon)
nr_cpus = tracecmd_count_cpus();
page_size = getpagesize();
- sd = trace_vsock_make(port);
+ if (network) {
+ sd = trace_net_make(port, USE_TCP);
+ if (listen(sd, 5) < 0)
+ die("Failed to listen on %d\n", port);
+ } else
+ sd = trace_vsock_make(port);
if (sd < 0)
- die("Failed to open vsocket");
+ die("Failed to open socket");
tracecmd_tsync_init();
- cid = trace_vsock_local_cid();
- if (cid >= 0)
- printf("listening on @%u:%u\n", cid, port);
+ if (!network) {
+ cid = trace_vsock_local_cid();
+ if (cid >= 0)
+ printf("listening on @%u:%u\n", cid, port);
+ }
if (do_daemon && daemon(1, 0))
die("daemon");
@@ -231,7 +278,7 @@ static void agent_serve(unsigned int port, bool do_daemon)
if (pid == 0) {
close(sd);
signal(SIGCHLD, SIG_DFL);
- agent_handle(cd, nr_cpus, page_size);
+ agent_handle(cd, nr_cpus, page_size, network);
}
if (pid > 0)
handler_pid = pid;
@@ -250,6 +297,7 @@ void trace_agent(int argc, char **argv)
{
bool do_daemon = false;
unsigned int port = TRACE_AGENT_DEFAULT_PORT;
+ bool network = false;
if (argc < 2)
usage(argv);
@@ -267,7 +315,7 @@ void trace_agent(int argc, char **argv)
{NULL, 0, NULL, 0}
};
- c = getopt_long(argc-1, argv+1, "+hp:D",
+ c = getopt_long(argc-1, argv+1, "+hp:DN",
long_options, &option_index);
if (c == -1)
break;
@@ -275,6 +323,9 @@ void trace_agent(int argc, char **argv)
case 'h':
usage(argv);
break;
+ case 'N':
+ network = true;
+ break;
case 'p':
port = atoi(optarg);
break;
@@ -296,5 +347,5 @@ void trace_agent(int argc, char **argv)
if (optind < argc-1)
usage(argv);
- agent_serve(port, do_daemon);
+ agent_serve(port, do_daemon, network);
}
diff --git a/tracecmd/trace-listen.c b/tracecmd/trace-listen.c
index 2338173f..8476fa51 100644
--- a/tracecmd/trace-listen.c
+++ b/tracecmd/trace-listen.c
@@ -234,52 +234,68 @@ static int setup_vsock_port(int start_port, int *sfd)
return start_port;
}
-#define START_PORT_SEARCH 1500
-#define MAX_PORT_SEARCH 6000
-
-static int bind_a_port(int start_port, int *sfd, enum port_type type)
+int trace_net_make(int port, enum port_type type)
{
struct addrinfo hints;
struct addrinfo *result, *rp;
char buf[BUFSIZ];
+ int sd;
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);
+ snprintf(buf, BUFSIZ, "%d", port);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = type == USE_TCP ? SOCK_STREAM : SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
+ switch (type) {
+ case USE_TCP:
+ hints.ai_socktype = SOCK_STREAM;
+ break;
+ case USE_UDP:
+ hints.ai_socktype = SOCK_DGRAM;
+ break;
+ default:
+ return -1;
+ }
+
s = getaddrinfo(NULL, buf, &hints, &result);
if (s != 0)
pdie("getaddrinfo: error opening socket");
for (rp = result; rp != NULL; rp = rp->ai_next) {
- *sfd = socket(rp->ai_family, rp->ai_socktype,
- rp->ai_protocol);
- if (*sfd < 0)
+ sd = socket(rp->ai_family, rp->ai_socktype,
+ rp->ai_protocol);
+ if (sd < 0)
continue;
- if (bind(*sfd, rp->ai_addr, rp->ai_addrlen) == 0)
+ if (bind(sd, rp->ai_addr, rp->ai_addrlen) == 0)
break;
- close(*sfd);
+ close(sd);
}
+ freeaddrinfo(result);
+
+ if (rp == NULL)
+ return -1;
+
+ return sd;
+}
+
+int trace_net_search(int start_port, int *sfd, enum port_type type)
+{
+ int num_port = start_port;
- if (rp == NULL) {
- freeaddrinfo(result);
+ if (type == USE_VSOCK)
+ return setup_vsock_port(start_port, sfd);
+ again:
+ *sfd = trace_net_make(num_port, type);
+ if (*sfd < 0) {
if (++num_port > MAX_PORT_SEARCH)
pdie("No available ports to bind");
goto again;
}
- freeaddrinfo(result);
-
return num_port;
}
@@ -309,10 +325,10 @@ static int open_port(const char *node, const char *port, int *pid,
int num_port;
/*
- * bind_a_port() currently does not return an error, but if that
+ * trace_net_search() 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, type);
+ num_port = trace_net_search(start_port, &sfd, type);
if (num_port < 0)
return num_port;