[ltt-dev] [UST PATCH] Make libustctl list only online pids v3

Nils Carlson nils.carlson at ericsson.com
Tue May 17 05:00:52 EDT 2011


And merged.

/Nils

On 05/17/2011 11:10 AM, Nils Carlson wrote:
> Changes since v2:
> Botox.
>
> Changes since v1:
> Cosmetic surgery at a european cost
>
> Previously libustctl would list all pids. This patch changes this
> so only online pids are listed. This is done by appending on each
> socket name the mtime from the proc/<pid>  directory. This way a
> socket can be checked to see if the appended mtime matches the
> mtime of the proc dir for the current pid, thus allowing us to
> distinguish between old and new socket files.
>
> Signed-off-by: Nils Carlson<nils.carlson at ericsson.com>
> Acked-by: Mathieu Desnoyers<mathieu.desnoyers at efficios.com>
> ---
>   libust/tracectl.c     |    9 +++-
>   libustcomm/ustcomm.c  |  151 ++++++++++++++++++++++++++++++++++++++++++++-----
>   libustcomm/ustcomm.h  |    7 ++
>   libustctl/libustctl.c |   18 +-----
>   4 files changed, 154 insertions(+), 31 deletions(-)
>
> diff --git a/libust/tracectl.c b/libust/tracectl.c
> index bc0a07c..2f45d6b 100644
> --- a/libust/tracectl.c
> +++ b/libust/tracectl.c
> @@ -1228,12 +1228,19 @@ static struct ustcomm_sock * init_app_socket(int epoll_fd)
>   	char *dir_name, *sock_name;
>   	int result;
>   	struct ustcomm_sock *sock = NULL;
> +	time_t mtime;
>
>   	dir_name = ustcomm_user_sock_dir();
>   	if (!dir_name)
>   		return NULL;
>
> -	result = asprintf(&sock_name, "%s/%d", dir_name, (int)getpid());
> +	mtime = ustcomm_pid_st_mtime(getpid());
> +	if (!mtime) {
> +		goto free_dir_name;
> +	}
> +
> +	result = asprintf(&sock_name, "%s/%d.%ld", dir_name,
> +			  (int) getpid(), (long) mtime);
>   	if (result<  0) {
>   		ERR("string overflow allocating socket name, "
>   		    "UST thread bailing");
> diff --git a/libustcomm/ustcomm.c b/libustcomm/ustcomm.c
> index ed6d8f1..3c7c0bb 100644
> --- a/libustcomm/ustcomm.c
> +++ b/libustcomm/ustcomm.c
> @@ -22,6 +22,7 @@
>   #include<sys/types.h>
>   #include<signal.h>
>   #include<errno.h>
> +#include<limits.h>
>   #include<sys/socket.h>
>   #include<sys/un.h>
>   #include<unistd.h>
> @@ -550,6 +551,127 @@ char *ustcomm_user_sock_dir(void)
>   	return sock_dir;
>   }
>
> +static int time_and_pid_from_socket_name(char *sock_name, unsigned long *time,
> +					 pid_t *pid)
> +{
> +	char *saveptr, *pid_m_time_str;
> +	char *sock_basename = strdup(basename(sock_name));
> +
> +	if (!sock_basename) {
> +		return -1;
> +	}
> +
> +	/* This is the pid */
> +	pid_m_time_str = strtok_r(sock_basename, ".",&saveptr);
> +	if (!pid_m_time_str) {
> +		goto out_err;
> +	}
> +
> +	errno = 0;
> +	*pid = (pid_t)strtoul(pid_m_time_str, NULL, 10);
> +	if (errno) {
> +		goto out_err;
> +	}
> +
> +	/* This should be the time-stamp */
> +	pid_m_time_str = strtok_r(NULL, ".",&saveptr);
> +	if (!pid_m_time_str) {
> +		goto out_err;
> +	}
> +
> +	errno = 0;
> +	*time = strtoul(pid_m_time_str, NULL, 10);
> +	if (errno) {
> +		goto out_err;
> +	}
> +
> +	return 0;
> +
> +out_err:
> +	free(sock_basename);
> +	return -1;
> +}
> +
> +time_t ustcomm_pid_st_mtime(pid_t pid)
> +{
> +	struct stat proc_stat;
> +	char proc_name[PATH_MAX];
> +
> +	if (snprintf(proc_name, PATH_MAX - 1, "/proc/%ld", (long) pid)<  0) {
> +		return 0;
> +	}
> +
> +	if (stat(proc_name,&proc_stat)) {
> +		return 0;
> +	}
> +
> +	return proc_stat.st_mtime;
> +}
> +
> +int ustcomm_is_socket_live(char *sock_name, pid_t *read_pid)
> +{
> +	time_t time_from_pid;
> +	unsigned long time_from_sock;
> +	pid_t pid;
> +
> +	if (time_and_pid_from_socket_name(sock_name,&time_from_sock,&pid)) {
> +		return 0;
> +	}
> +
> +	if (read_pid) {
> +		*read_pid = pid;
> +	}
> +
> +	time_from_pid = ustcomm_pid_st_mtime(pid);
> +	if (!time_from_pid) {
> +		return 0;
> +	}
> +
> +	if ((unsigned long) time_from_pid == time_from_sock) {
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +
> +#define MAX_SOCK_PATH_BASE_LEN 100
> +
> +static int ustcomm_get_sock_name(char *dir_name, pid_t pid, char *sock_name)
> +{
> +	struct dirent *dirent;
> +	char sock_path_base[MAX_SOCK_PATH_BASE_LEN];
> +	int len;
> +	DIR *dir = opendir(dir_name);
> +
> +	snprintf(sock_path_base, MAX_SOCK_PATH_BASE_LEN - 1,
> +		 "%ld.", (long) pid);
> +	len = strlen(sock_path_base);
> +
> +	while ((dirent = readdir(dir))) {
> +		if (!strcmp(dirent->d_name, ".") ||
> +		    !strcmp(dirent->d_name, "..") ||
> +		    !strcmp(dirent->d_name, "ust-consumer") ||
> +		    dirent->d_type == DT_DIR ||
> +		    strncmp(dirent->d_name, sock_path_base, len)) {
> +			continue;
> +		}
> +
> +		if (ustcomm_is_socket_live(dirent->d_name, NULL)) {
> +			if (snprintf(sock_name, PATH_MAX - 1, "%s/%s",
> +				     dir_name, dirent->d_name)<  0) {
> +				PERROR("path longer than PATH_MAX?");
> +				goto out_err;
> +			}
> +			closedir(dir);
> +			return 0;
> +		}
> +	}
> +
> +out_err:
> +	closedir(dir);
> +	return -1;
> +}
> +
>   /* Open a connection to a traceable app.
>    *
>    * Return value:
> @@ -561,16 +683,15 @@ static int connect_app_non_root(pid_t pid, int *app_fd)
>   {
>   	int result;
>   	int retval = 0;
> -	char *dir_name, *sock_name;
> +	char *dir_name;
> +	char sock_name[PATH_MAX];
>
>   	dir_name = ustcomm_user_sock_dir();
>   	if (!dir_name)
>   		return -ENOMEM;
>
> -	result = asprintf(&sock_name, "%s/%d", dir_name, pid);
> -	if (result<  0) {
> -		ERR("failed to allocate socket name");
> -		retval = -1;
> +	if (ustcomm_get_sock_name(dir_name, pid, sock_name)) {
> +		retval = -ENOENT;
>   		goto free_dir_name;
>   	}
>
> @@ -578,11 +699,9 @@ static int connect_app_non_root(pid_t pid, int *app_fd)
>   	if (result<  0) {
>   		ERR("failed to connect to app");
>   		retval = -1;
> -		goto free_sock_name;
> +		goto free_dir_name;
>   	}
>
> -free_sock_name:
> -	free(sock_name);
>   free_dir_name:
>   	free(dir_name);
>
> @@ -595,8 +714,8 @@ static int connect_app_root(pid_t pid, int *app_fd)
>   {
>   	DIR *tmp_dir;
>   	struct dirent *dirent;
> -	char *sock_name;
> -	int result;
> +	char dir_name[PATH_MAX], sock_name[PATH_MAX];
> +	int result = -1;
>
>   	tmp_dir = opendir(USER_TMP_DIR);
>   	if (!tmp_dir) {
> @@ -607,14 +726,16 @@ static int connect_app_root(pid_t pid, int *app_fd)
>   		if (!strncmp(dirent->d_name, USER_SOCK_DIR_BASE,
>   			     strlen(USER_SOCK_DIR_BASE))) {
>
> -			if (asprintf(&sock_name, USER_TMP_DIR "/%s/%u",
> -				     dirent->d_name, pid)<  0) {
> -				goto close_tmp_dir;
> +			if (snprintf(dir_name, PATH_MAX - 1, "%s/%s", USER_TMP_DIR,
> +				     dirent->d_name)<  0) {
> +				continue;
>   			}
>
> -			result = ustcomm_connect_path(sock_name, app_fd);
> +			if (ustcomm_get_sock_name(dir_name, pid, sock_name)) {
> +				continue;
> +			}
>
> -			free(sock_name);
> +			result = ustcomm_connect_path(sock_name, app_fd);
>
>   			if (result == 0) {
>   				goto close_tmp_dir;
> diff --git a/libustcomm/ustcomm.h b/libustcomm/ustcomm.h
> index a91c111..4706b72 100644
> --- a/libustcomm/ustcomm.h
> +++ b/libustcomm/ustcomm.h
> @@ -162,6 +162,13 @@ extern int ustcomm_request_consumer(pid_t pid, const char *channel);
>
>   /* Returns the current users socket directory, must be freed */
>   extern char *ustcomm_user_sock_dir(void);
> +
> +/* Get the st_m_time from proc*/
> +extern time_t ustcomm_pid_st_mtime(pid_t pid);
> +
> +/* Check that a socket is live */
> +extern int ustcomm_is_socket_live(char *sock_name, pid_t *read_pid);
> +
>   extern int ustcomm_connect_app(pid_t pid, int *app_fd);
>   extern int ustcomm_connect_path(const char *path, int *connection_fd);
>
> diff --git a/libustctl/libustctl.c b/libustctl/libustctl.c
> index 8b0dfc1..4e6c495 100644
> --- a/libustctl/libustctl.c
> +++ b/libustctl/libustctl.c
> @@ -110,7 +110,7 @@ static int get_pids_in_dir(DIR *dir, pid_t **pid_list,
>   			    unsigned int *pid_list_size)
>   {
>   	struct dirent *dirent;
> -	long read_pid;
> +	pid_t read_pid;
>
>   	while ((dirent = readdir(dir))) {
>   		if (!strcmp(dirent->d_name, ".") ||
> @@ -121,21 +121,9 @@ static int get_pids_in_dir(DIR *dir, pid_t **pid_list,
>   			continue;
>   		}
>
> -		errno = 0;
> -		read_pid = strtol(dirent->d_name, NULL, 10);
> -		if (errno) {
> -			continue;
> -		}
> -
> -		/*
> -		 * FIXME: Here we previously called pid_is_online, which
> -		 * always returned 1, now I replaced it with just 1.
> -		 * We need to figure out an intelligent way of solving
> -		 * this, maybe connect-disconnect.
> -		 */
> -		if (1) {
> +		if (ustcomm_is_socket_live(dirent->d_name,&read_pid)) {
>
> -			(*pid_list)[(*pid_list_index)++] = read_pid;
> +			(*pid_list)[(*pid_list_index)++] = (long) read_pid;
>
>   			if (*pid_list_index == *pid_list_size) {
>   				if (realloc_pid_list(pid_list, pid_list_size)) {





More information about the lttng-dev mailing list