[lttng-dev] [PATCH lttng-tools 1/2] Fix: d_type validity is not guaranteed on all nfs versions

Jonathan Rajotte Julien Jonathan.rajotte-julien at efficios.com
Fri Mar 18 21:02:32 UTC 2016


Those two patches can also be backported to stable-2.7 with the 
condition that commit
c4b765f0d3892d57bb7e8828c324d304e9c4d5e9 [1] is also backported since it 
fix the
d_type problem in src/common/utils.c.

Thanks

[1]
commit c4b765f0d3892d57bb7e8828c324d304e9c4d5e9
Author: Michael Jeanson <mjeanson at efficios.com>
Date:   Wed Oct 14 16:02:45 2015 -0400

     Port: Replace dirent->d_type by stat

     dirent->d_type is Linux specific while 'stat' is part of POSIX

     Signed-off-by: Michael Jeanson <mjeanson at efficios.com>
     Signed-off-by: J<C3><A9>r<C3><A9>mie Galarneau 
<jeremie.galarneau at efficios.com>



On 2016-03-18 01:20 PM, Jonathan Rajotte wrote:
> When using lttng-crash on files mounted on a nfs mount the d_type from the dirent
> struct is not necessarily set and result in DT_UNKNOWN d_type.
>
> stat() provide the valid information on an nfs mount.
>
> Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien at efficios.com>
> ---
>   src/bin/lttng-crash/lttng-crash.c | 80 +++++++++++++++++++++++++++++----------
>   1 file changed, 61 insertions(+), 19 deletions(-)
>
> diff --git a/src/bin/lttng-crash/lttng-crash.c b/src/bin/lttng-crash/lttng-crash.c
> index 653e4d0..8eddbd9 100644
> --- a/src/bin/lttng-crash/lttng-crash.c
> +++ b/src/bin/lttng-crash/lttng-crash.c
> @@ -976,6 +976,7 @@ int extract_trace_recursive(const char *output_path,
>   	DIR *dir;
>   	int dir_fd, ret = 0, closeret;
>   	struct dirent *entry;
> +	size_t path_len;
>   	int has_warning = 0;
>   
>   	/* Open directory */
> @@ -984,6 +985,9 @@ int extract_trace_recursive(const char *output_path,
>   		PERROR("Cannot open '%s' path", input_path);
>   		return -1;
>   	}
> +
> +	path_len = strlen(input_path);
> +
>   	dir_fd = dirfd(dir);
>   	if (dir_fd < 0) {
>   		PERROR("dirfd");
> @@ -991,13 +995,34 @@ int extract_trace_recursive(const char *output_path,
>   	}
>   
>   	while ((entry = readdir(dir))) {
> +		struct stat st;
> +		size_t name_len;
> +		char filename[PATH_MAX];
> +
>   		if (!strcmp(entry->d_name, ".")
>   				|| !strcmp(entry->d_name, "..")) {
>   			continue;
>   		}
> -		switch (entry->d_type) {
> -		case DT_DIR:
> -		{
> +
> +		name_len = strlen(entry->d_name);
> +		if (path_len + name_len + 2 > sizeof(filename)) {
> +			ERR("Failed to remove file: path name too long (%s/%s)",
> +				input_path, entry->d_name);
> +			continue;
> +		}
> +
> +		if (snprintf(filename, sizeof(filename), "%s/%s",
> +				input_path, entry->d_name) < 0) {
> +			ERR("Failed to format path.");
> +			continue;
> +		}
> +
> +		if (stat(filename, &st)) {
> +			PERROR("stat");
> +			continue;
> +		}
> +
> +		if (S_ISDIR(st.st_mode)) {
>   			char output_subpath[PATH_MAX];
>   			char input_subpath[PATH_MAX];
>   
> @@ -1029,22 +1054,17 @@ int extract_trace_recursive(const char *output_path,
>   			if (ret) {
>   				has_warning = 1;
>   			}
> -			break;
> -		}
> -		case DT_REG:
> -		case DT_LNK:
> +		} else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
>   			if (!strcmp(entry->d_name, "metadata")) {
>   				ret = extract_one_trace(output_path,
>   					input_path);
>   				if (ret) {
>   					WARN("Error extracting trace '%s', continuing anyway.",
>   						input_path);
> -					has_warning = 1;
> +					has_warning = 2;
>   				}
>   			}
> -			/* Ignore other files */
> -			break;
> -		default:
> +		} else {
>   			has_warning = 1;
>   			goto end;
>   		}
> @@ -1062,6 +1082,7 @@ int delete_dir_recursive(const char *path)
>   {
>   	DIR *dir;
>   	int dir_fd, ret = 0, closeret;
> +	size_t path_len;
>   	struct dirent *entry;
>   
>   	/* Open trace directory */
> @@ -1071,6 +1092,9 @@ int delete_dir_recursive(const char *path)
>   		ret = -errno;
>   	        goto end;
>   	}
> +
> +	path_len = strlen(path);
> +
>   	dir_fd = dirfd(dir);
>   	if (dir_fd < 0) {
>   		PERROR("dirfd");
> @@ -1079,13 +1103,34 @@ int delete_dir_recursive(const char *path)
>   	}
>   
>   	while ((entry = readdir(dir))) {
> +		struct stat st;
> +		size_t name_len;
> +		char filename[PATH_MAX];
> +
>   		if (!strcmp(entry->d_name, ".")
>   				|| !strcmp(entry->d_name, "..")) {
>   			continue;
>   		}
> -		switch (entry->d_type) {
> -		case DT_DIR:
> -		{
> +
> +		name_len = strlen(entry->d_name);
> +		if (path_len + name_len + 2 > sizeof(filename)) {
> +			ERR("Failed to remove file: path name too long (%s/%s)",
> +				path, entry->d_name);
> +			continue;
> +		}
> +
> +		if (snprintf(filename, sizeof(filename), "%s/%s",
> +				path, entry->d_name) < 0) {
> +			ERR("Failed to format path.");
> +			continue;
> +		}
> +
> +		if (stat(filename, &st)) {
> +			PERROR("stat");
> +			continue;
> +		}
> +
> +		if (S_ISDIR(st.st_mode)) {
>   			char *subpath = zmalloc(PATH_MAX);
>   
>   			if (!subpath) {
> @@ -1106,16 +1151,13 @@ int delete_dir_recursive(const char *path)
>   				/* Error occured, abort traversal. */
>   				goto end;
>   			}
> -			break;
> -		}
> -		case DT_REG:
> +		} else if (S_ISREG(st.st_mode)) {
>   			ret = unlinkat(dir_fd, entry->d_name, 0);
>   			if (ret) {
>   				PERROR("Unlinking '%s'", entry->d_name);
>   				goto end;
>   			}
> -			break;
> -		default:
> +		} else {
>   			ret = -EINVAL;
>   			goto end;
>   		}

-- 
Jonathan R. Julien
Efficios



More information about the lttng-dev mailing list