@@ -65,7 +65,18 @@ int tracecmd_tsync_proto_register(const char *proto_name, int accuracy, int role
long long *, unsigned int));
int tracecmd_tsync_proto_unregister(char *proto_name);
+#ifdef VSOCK
int ptp_clock_sync_register(void);
int kvm_clock_sync_register(void);
+#else
+static inline int ptp_clock_sync_register(void)
+{
+ return 0;
+}
+static inline int kvm_clock_sync_register(void)
+{
+ return 0;
+}
+#endif
#endif /* _TRACE_TSYNC_LOCAL_H */
@@ -8,7 +8,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
-#include <linux/vm_sockets.h>
#include <sys/types.h>
#include <linux/types.h>
#include <time.h>
@@ -8,9 +8,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
-#ifdef VSOCK
-#include <linux/vm_sockets.h>
-#endif
#include <linux/limits.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -65,10 +62,8 @@ static struct tsync_proto *tsync_proto_find(const char *proto_name)
*/
void tracecmd_tsync_init(void)
{
-#ifdef VSOCK
ptp_clock_sync_register();
kvm_clock_sync_register();
-#endif
}
int tracecmd_tsync_proto_register(const char *proto_name, int accuracy, int roles,
@@ -37,6 +37,7 @@ TRACE_CMD_OBJS += trace-dump.o
TRACE_CMD_OBJS += trace-clear.o
TRACE_CMD_OBJS += trace-vm.o
TRACE_CMD_OBJS += trace-convert.o
+TRACE_CMD_OBJS += trace-vsock.o
ifeq ($(VSOCK_DEFINED), 1)
TRACE_CMD_OBJS += trace-agent.o
@@ -9,6 +9,7 @@
#include <sys/types.h>
#include <dirent.h> /* for DIR */
#include <ctype.h> /* for isdigit() */
+#include <errno.h>
#include <limits.h>
#include "trace-cmd-private.h"
@@ -339,6 +340,53 @@ int trace_open_vsock(unsigned int cid, unsigned int port);
char *trace_get_guest_file(const char *file, const char *guest);
+#ifdef VSOCK
+int trace_vsock_open(unsigned int cid, unsigned int port);
+int trace_vsock_make(unsigned int port);
+int trace_vsock_make_any(void);
+int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid);
+int trace_vsock_get_port(int sd, unsigned int *port);
+bool trace_vsock_can_splice_read(void);
+int trace_vsock_local_cid(void);
+#else
+static inline int trace_vsock_open(unsigned int cid, unsigned int port)
+{
+ return -ENOTSUP;
+}
+
+static inline int trace_vsock_make(unsigned int port)
+{
+ return -ENOTSUP;
+
+}
+
+static inline int trace_vsock_make_any(void)
+{
+ return -ENOTSUP;
+
+}
+
+static inline int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid)
+{
+ return -ENOTSUP;
+}
+
+static inline int trace_vsock_get_port(int sd, unsigned int *port)
+{
+ return -ENOTSUP;
+}
+
+static inline bool trace_vsock_can_splice_read(void)
+{
+ return false;
+}
+
+static inline int trace_vsock_local_cid(void)
+{
+ return -ENOTSUP;
+}
+#endif /* VSOCK */
+
/* No longer in event-utils.h */
__printf(1,2)
void __noreturn die(const char *fmt, ...); /* Can be overriden */
@@ -14,85 +14,25 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
-#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
-#include <linux/vm_sockets.h>
#include <pthread.h>
#include "trace-local.h"
#include "trace-msg.h"
-#define GET_LOCAL_CID 0x7b9
-
-static int get_local_cid(unsigned int *cid)
-{
- int fd, ret = 0;
-
- fd = open("/dev/vsock", O_RDONLY);
- if (fd < 0)
- return -errno;
-
- if (ioctl(fd, GET_LOCAL_CID, cid))
- ret = -errno;
-
- close(fd);
- return ret;
-}
-
-int trace_make_vsock(unsigned int port)
-{
- struct sockaddr_vm addr = {
- .svm_family = AF_VSOCK,
- .svm_cid = VMADDR_CID_ANY,
- .svm_port = port,
- };
- int sd;
-
- sd = socket(AF_VSOCK, SOCK_STREAM, 0);
- if (sd < 0)
- return -errno;
-
- setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
-
- if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)))
- return -errno;
-
- if (listen(sd, SOMAXCONN))
- return -errno;
-
- return sd;
-}
-
-int trace_get_vsock_port(int sd, unsigned int *port)
-{
- struct sockaddr_vm addr;
- socklen_t addr_len = sizeof(addr);
-
- if (getsockname(sd, (struct sockaddr *)&addr, &addr_len))
- return -errno;
-
- if (addr.svm_family != AF_VSOCK)
- return -EINVAL;
-
- if (port)
- *port = addr.svm_port;
-
- return 0;
-}
-
static void make_vsocks(int nr, int *fds, unsigned int *ports)
{
unsigned int port;
int i, fd, ret;
for (i = 0; i < nr; i++) {
- fd = trace_make_vsock(VMADDR_PORT_ANY);
+ fd = trace_vsock_make_any();
if (fd < 0)
die("Failed to open vsocket");
- ret = trace_get_vsock_port(fd, &port);
+ ret = trace_vsock_get_port(fd, &port);
if (ret < 0)
die("Failed to get vsocket address");
@@ -140,98 +80,6 @@ static char *get_clock(int argc, char **argv)
return NULL;
}
-#ifdef VSOCK
-
-static int vsock_make(void)
-{
- struct sockaddr_vm addr = {
- .svm_family = AF_VSOCK,
- .svm_cid = VMADDR_CID_ANY,
- .svm_port = VMADDR_PORT_ANY,
- };
- int sd;
-
- sd = socket(AF_VSOCK, SOCK_STREAM, 0);
- if (sd < 0)
- return -errno;
-
- setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
-
- if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)))
- return -errno;
-
- if (listen(sd, SOMAXCONN))
- return -errno;
-
- return sd;
-}
-
-static int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid)
-{
- struct sockaddr_vm addr;
- socklen_t addr_len = sizeof(addr);
-
- memset(&addr, 0, sizeof(addr));
- if (getsockname(fd, (struct sockaddr *)&addr, &addr_len))
- return -1;
- if (addr.svm_family != AF_VSOCK)
- return -1;
- *lcid = addr.svm_cid;
-
- memset(&addr, 0, sizeof(addr));
- addr_len = sizeof(addr);
- if (getpeername(fd, (struct sockaddr *)&addr, &addr_len))
- return -1;
- if (addr.svm_family != AF_VSOCK)
- return -1;
- *rcid = addr.svm_cid;
-
- return 0;
-}
-
-static int vsock_get_port(int sd, unsigned int *port)
-{
- struct sockaddr_vm addr;
- socklen_t addr_len = sizeof(addr);
-
- if (getsockname(sd, (struct sockaddr *)&addr, &addr_len))
- return -errno;
-
- if (addr.svm_family != AF_VSOCK)
- return -EINVAL;
-
- if (port)
- *port = addr.svm_port;
-
- return 0;
-}
-#else
-static inline bool can_splice_read_vsock(void)
-{
- return false;
-}
-
-static inline int vsock_make(void)
-{
- return -ENOTSUP;
-
-}
-
-static inline int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid) {
- return -1;
-}
-
-static inline int vsock_get_port(int sd, unsigned int *port)
-{
- return -1;
-}
-
-static int vsock_get_port(int sd, unsigned int *port)
-{
- return -ENOTSUP;
-}
-#endif
-
static void agent_handle(int sd, int nr_cpus, int page_size)
{
struct tracecmd_tsync_protos *tsync_protos = NULL;
@@ -278,8 +126,8 @@ static void agent_handle(int sd, int nr_cpus, int page_size)
remote_id = -1;
local_id = -2;
}
- fd = vsock_make();
- if (fd >= 0 && vsock_get_port(fd, &tsync_port) >= 0) {
+ fd = trace_vsock_make_any();
+ if (fd >= 0 && trace_vsock_get_port(fd, &tsync_port) >= 0) {
tsync = tracecmd_tsync_with_host(fd, tsync_protos,
get_clock(argc, argv),
remote_id, local_id);
@@ -356,12 +204,13 @@ static void agent_serve(unsigned int port, bool do_daemon)
nr_cpus = tracecmd_count_cpus();
page_size = getpagesize();
- sd = trace_make_vsock(port);
+ sd = trace_vsock_make(port);
if (sd < 0)
die("Failed to open vsocket");
tracecmd_tsync_init();
- if (!get_local_cid(&cid))
+ cid = trace_vsock_local_cid();
+ if (cid >= 0)
printf("listening on @%u:%u\n", cid, port);
if (do_daemon && daemon(1, 0))
@@ -37,9 +37,6 @@
#include <poll.h>
#include <pwd.h>
#include <grp.h>
-#ifdef VSOCK
-#include <linux/vm_sockets.h>
-#endif
#include "tracefs.h"
#include "version.h"
@@ -3159,81 +3156,6 @@ static int connect_port(const char *host, unsigned int port)
return sfd;
}
-#ifdef VSOCK
-int trace_open_vsock(unsigned int cid, unsigned int port)
-{
- struct sockaddr_vm addr = {
- .svm_family = AF_VSOCK,
- .svm_cid = cid,
- .svm_port = port,
- };
- int sd;
-
- sd = socket(AF_VSOCK, SOCK_STREAM, 0);
- if (sd < 0)
- return -errno;
-
- if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)))
- return -errno;
-
- return sd;
-}
-
-static int try_splice_read_vsock(void)
-{
- int ret, sd, brass[2];
-
- sd = socket(AF_VSOCK, SOCK_STREAM, 0);
- if (sd < 0)
- return -errno;
-
- ret = pipe(brass);
- if (ret < 0)
- goto out_close_sd;
-
- /*
- * On kernels that don't support splice reading from vsockets
- * this will fail with EINVAL, or ENOTCONN otherwise.
- * Technically, it should never succeed but if it does, claim splice
- * reading is supported.
- */
- ret = splice(sd, NULL, brass[1], NULL, 10, 0);
- if (ret < 0)
- ret = errno != EINVAL;
- else
- ret = 1;
-
- close(brass[0]);
- close(brass[1]);
-out_close_sd:
- close(sd);
- return ret;
-}
-
-static bool can_splice_read_vsock(void)
-{
- static bool initialized, res;
-
- if (initialized)
- return res;
-
- res = try_splice_read_vsock() > 0;
- initialized = true;
- return res;
-}
-
-#else
-int trace_open_vsock(unsigned int cid, unsigned int port)
-{
- die("vsock is not supported");
- return -1;
-}
-static inline bool can_splice_read_vsock(void)
-{
- return false;
-}
-#endif
-
static int do_accept(int sd)
{
int cd;
@@ -3366,14 +3288,14 @@ create_recorder_instance(struct buffer_instance *instance, const char *file, int
if (instance->use_fifos)
fd = instance->fds[cpu];
else
- fd = trace_open_vsock(instance->cid, instance->client_ports[cpu]);
+ fd = trace_vsock_open(instance->cid, instance->client_ports[cpu]);
if (fd < 0)
die("Failed to connect to agent");
flags = recorder_flags;
if (instance->use_fifos)
flags |= TRACECMD_RECORD_NOBRASS;
- else if (!can_splice_read_vsock())
+ else if (!trace_vsock_can_splice_read())
flags |= TRACECMD_RECORD_NOSPLICE;
return tracecmd_create_recorder_virt(file, cpu, flags, fd);
}
@@ -3988,7 +3910,7 @@ static int host_tsync(struct common_record_context *ctx,
guest_pid = guest->pid;
start_mapping_vcpus(guest);
- fd = trace_open_vsock(instance->cid, tsync_port);
+ fd = trace_vsock_open(instance->cid, tsync_port);
instance->tsync = tracecmd_tsync_with_guest(top_instance.trace_id,
instance->tsync_loop_interval,
fd, guest_pid,
@@ -4019,7 +3941,7 @@ static void connect_to_agent(struct common_record_context *ctx,
use_fifos = nr_fifos > 0;
}
- sd = trace_open_vsock(instance->cid, instance->port);
+ sd = trace_vsock_open(instance->cid, instance->port);
if (sd < 0)
die("Failed to connect to vsocket @%u:%u",
instance->cid, instance->port);
@@ -284,7 +284,7 @@ static void find_pid_by_cid(struct trace_guest *guest)
int fd;
instance = start_trace_connect();
- fd = trace_open_vsock(guest->cid, -1);
+ fd = trace_vsock_open(guest->cid, -1);
guest->pid = stop_trace_connect(instance);
/* Just in case! */
if (fd >= 0)
new file mode 100644
@@ -0,0 +1,156 @@
+#include <unistd.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <linux/vm_sockets.h>
+
+#include "trace-cmd-private.h"
+
+int __hidden trace_vsock_open(unsigned int cid, unsigned int port)
+{
+ struct sockaddr_vm addr = {
+ .svm_family = AF_VSOCK,
+ .svm_cid = cid,
+ .svm_port = port,
+ };
+ int sd;
+
+ sd = socket(AF_VSOCK, SOCK_STREAM, 0);
+ if (sd < 0)
+ return -errno;
+
+ if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)))
+ return -errno;
+
+ return sd;
+}
+
+int __hidden trace_vsock_make(unsigned int port)
+{
+ struct sockaddr_vm addr = {
+ .svm_family = AF_VSOCK,
+ .svm_cid = VMADDR_CID_ANY,
+ .svm_port = port,
+ };
+ int sd;
+
+ sd = socket(AF_VSOCK, SOCK_STREAM, 0);
+ if (sd < 0)
+ return -errno;
+
+ setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
+
+ if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)))
+ return -errno;
+
+ if (listen(sd, SOMAXCONN))
+ return -errno;
+
+ return sd;
+}
+
+int __hidden trace_vsock_make_any(void)
+{
+ return trace_vsock_make(VMADDR_PORT_ANY);
+}
+
+int __hidden trace_vsock_get_port(int sd, unsigned int *port)
+{
+ struct sockaddr_vm addr;
+ socklen_t addr_len = sizeof(addr);
+
+ if (getsockname(sd, (struct sockaddr *)&addr, &addr_len))
+ return -errno;
+
+ if (addr.svm_family != AF_VSOCK)
+ return -EINVAL;
+
+ if (port)
+ *port = addr.svm_port;
+
+ return 0;
+}
+
+int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid)
+{
+ struct sockaddr_vm addr;
+ socklen_t addr_len = sizeof(addr);
+
+ memset(&addr, 0, sizeof(addr));
+ if (getsockname(fd, (struct sockaddr *)&addr, &addr_len))
+ return -1;
+ if (addr.svm_family != AF_VSOCK)
+ return -1;
+ *lcid = addr.svm_cid;
+
+ memset(&addr, 0, sizeof(addr));
+ addr_len = sizeof(addr);
+ if (getpeername(fd, (struct sockaddr *)&addr, &addr_len))
+ return -1;
+ if (addr.svm_family != AF_VSOCK)
+ return -1;
+ *rcid = addr.svm_cid;
+
+ return 0;
+}
+
+static int try_splice_read_vsock(void)
+{
+ int ret, sd, brass[2];
+
+ sd = socket(AF_VSOCK, SOCK_STREAM, 0);
+ if (sd < 0)
+ return -errno;
+
+ ret = pipe(brass);
+ if (ret < 0)
+ goto out_close_sd;
+
+ /*
+ * On kernels that don't support splice reading from vsockets
+ * this will fail with EINVAL, or ENOTCONN otherwise.
+ * Technically, it should never succeed but if it does, claim splice
+ * reading is supported.
+ */
+ ret = splice(sd, NULL, brass[1], NULL, 10, 0);
+ if (ret < 0)
+ ret = errno != EINVAL;
+ else
+ ret = 1;
+
+ close(brass[0]);
+ close(brass[1]);
+out_close_sd:
+ close(sd);
+ return ret;
+}
+
+bool __hidden trace_vsock_can_splice_read(void)
+{
+ static bool initialized, res;
+
+ if (initialized)
+ return res;
+
+ res = try_splice_read_vsock() > 0;
+ initialized = true;
+ return res;
+}
+
+#define GET_LOCAL_CID 0x7b9
+
+int __hidden trace_vsock_local_cid(void)
+{
+ int cid;
+ int fd;
+
+ fd = open("/dev/vsock", O_RDONLY);
+ if (fd < 0)
+ return -errno;
+
+ if (ioctl(fd, GET_LOCAL_CID, &cid))
+ cid = -errno;
+
+ close(fd);
+ return cid;
+}