@@ -488,7 +488,8 @@ void tracecmd_tsync_init(void);
int tracecmd_tsync_proto_getall(struct tracecmd_tsync_protos **protos, const char *clock, int role);
bool tsync_proto_is_supported(const char *proto_name);
struct tracecmd_time_sync *
-tracecmd_tsync_with_host(const struct tracecmd_tsync_protos *tsync_protos,
+tracecmd_tsync_with_host(int fd,
+ const struct tracecmd_tsync_protos *tsync_protos,
const char *clock, int remote_id, int local_id);
int tracecmd_tsync_with_host_stop(struct tracecmd_time_sync *tsync);
struct tracecmd_time_sync *
@@ -629,7 +629,8 @@ static int flush_cache(struct tracecmd_msg_handle *msg_handle)
void tracecmd_msg_handle_close(struct tracecmd_msg_handle *msg_handle)
{
- close(msg_handle->fd);
+ if (msg_handle->fd >= 0)
+ close(msg_handle->fd);
if (msg_handle->cfd >= 0)
close(msg_handle->cfd);
free(msg_handle);
@@ -344,61 +344,6 @@ error:
return -1;
}
-#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 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 int vsock_make(void)
-{
- return -ENOTSUP;
-
-}
-
-static int vsock_get_port(int sd, unsigned int *port)
-{
- return -ENOTSUP;
-}
-#endif /* VSOCK */
-
static struct tracefs_instance *
clock_synch_create_instance(const char *clock, unsigned int cid)
{
@@ -1005,6 +950,7 @@ out:
/**
* tracecmd_tsync_with_host - Synchronize timestamps with host
+ * @fd: File descriptor connecting with the host
* @tsync_protos: List of tsync protocols, supported by the host
* @clock: Trace clock, used for that session
* @port: returned, VSOCKET port, on which the guest listens for tsync requests
@@ -1018,17 +964,16 @@ out:
* until tracecmd_tsync_with_host_stop() is called.
*/
struct tracecmd_time_sync *
-tracecmd_tsync_with_host(const struct tracecmd_tsync_protos *tsync_protos,
+tracecmd_tsync_with_host(int fd,
+ const struct tracecmd_tsync_protos *tsync_protos,
const char *clock, int remote_id, int local_id)
{
struct tracecmd_time_sync *tsync;
cpu_set_t *pin_mask = NULL;
pthread_attr_t attrib;
size_t mask_size = 0;
- unsigned int port;
const char *proto;
int ret;
- int fd;
tsync = calloc(1, sizeof(struct tracecmd_time_sync));
if (!tsync)
@@ -1039,12 +984,6 @@ tracecmd_tsync_with_host(const struct tracecmd_tsync_protos *tsync_protos,
if (!proto)
goto error;
tsync->proto_name = strdup(proto);
- fd = vsock_make();
- if (fd < 0)
- goto error;
-
- if (vsock_get_port(fd, &port) < 0)
- goto error;
tsync->msg_handle = tracecmd_msg_handle_alloc(fd, 0);
if (clock)
tsync->clock_str = strdup(clock);
@@ -1072,10 +1011,11 @@ tracecmd_tsync_with_host(const struct tracecmd_tsync_protos *tsync_protos,
error:
if (tsync) {
- if (tsync->msg_handle)
+ if (tsync->msg_handle) {
+ /* Do not close the fd that was passed it */
+ tsync->msg_handle->fd = -1;
tracecmd_msg_handle_close(tsync->msg_handle);
- else if (fd >= 0)
- close(fd);
+ }
free(tsync->clock_str);
free(tsync);
}
@@ -141,6 +141,31 @@ static char *get_clock(int argc, char **argv)
}
#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;
@@ -181,7 +206,22 @@ static int vsock_get_port(int sd, unsigned int *port)
return 0;
}
#else
-static inline int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid) {
+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;
}
@@ -207,6 +247,7 @@ static void agent_handle(int sd, int nr_cpus, int page_size)
bool use_fifos;
int *fds;
int ret;
+ int fd;
fds = calloc(nr_cpus, sizeof(*fds));
ports = calloc(nr_cpus, sizeof(*ports));
@@ -236,17 +277,19 @@ static void agent_handle(int sd, int nr_cpus, int page_size)
remote_id = -1;
local_id = -2;
}
- if (vsock_get_port(msg_handle->fd, &tsync_port) >= 0) {
- tsync = tracecmd_tsync_with_host(tsync_protos,
+ fd = vsock_make();
+ if (fd >= 0 && vsock_get_port(fd, &tsync_port) >= 0) {
+ tsync = tracecmd_tsync_with_host(fd, tsync_protos,
get_clock(argc, argv),
remote_id, local_id);
- } else {
- tsync = NULL;
}
- if (tsync)
+ if (tsync) {
tracecmd_tsync_get_selected_proto(tsync, &tsync_proto);
- else
+ } else {
warning("Failed to negotiate timestamps synchronization with the host");
+ if (fd >= 0)
+ close(fd);
+ }
}
trace_id = tracecmd_generate_traceid();
ret = tracecmd_msg_send_trace_resp(msg_handle, nr_cpus, page_size,
@@ -3228,8 +3228,7 @@ int trace_open_vsock(unsigned int cid, unsigned int port)
die("vsock is not supported");
return -1;
}
-
-static bool can_splice_read_vsock(void)
+static inline bool can_splice_read_vsock(void)
{
return false;
}
@@ -3976,6 +3975,7 @@ static int host_tsync(struct common_record_context *ctx,
unsigned int tsync_port, char *proto)
{
struct trace_guest *guest;
+ int guest_pid = -1;
int fd;
if (!proto)
@@ -3985,12 +3985,13 @@ static int host_tsync(struct common_record_context *ctx,
if (guest == NULL)
return -1;
+ guest_pid = guest->pid;
start_mapping_vcpus(guest);
fd = trace_open_vsock(instance->cid, tsync_port);
instance->tsync = tracecmd_tsync_with_guest(top_instance.trace_id,
instance->tsync_loop_interval,
- fd, guest->pid,
+ fd, guest_pid,
instance->cpu_count,
proto, ctx->clock);
stop_mapping_vcpus(instance, guest);