From 27eac2a03a69274cb7b77136e471b1374019df1e Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Sun, 24 May 2026 10:30:11 +0800 Subject: [PATCH 1/2] testing/sd_stress: Handle stale temporary directories Fix #3205 by removing stale sdstress work directories left by previous interrupted or failed runs before starting a new test. The cleanup only removes entries matching the generated tmpNNN file pattern. If the directory contains any unexpected entry, the test fails instead of deleting user data. Also make create_dir() and remove_dir() use their path argument instead of the fixed temporary directory names. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- testing/drivers/sd_stress/sd_stress_main.c | 100 ++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/testing/drivers/sd_stress/sd_stress_main.c b/testing/drivers/sd_stress/sd_stress_main.c index 39c3e563e6e..882bec362ea 100644 --- a/testing/drivers/sd_stress/sd_stress_main.c +++ b/testing/drivers/sd_stress/sd_stress_main.c @@ -47,12 +47,14 @@ * Included Files ****************************************************************************/ +#include #include #include #include #include #include #include +#include #include #include @@ -94,7 +96,7 @@ static void usage(void) static bool create_dir(const char *path) { - int ret = mkdir(TEMPDIR, S_IRWXU | S_IRWXG | S_IRWXO); + int ret = mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO); if (ret < 0) { @@ -108,7 +110,7 @@ static bool create_dir(const char *path) static bool remove_dir(const char *path) { - int ret = rmdir(TEMPDIR2); + int ret = rmdir(path); if (ret < 0) { @@ -120,6 +122,94 @@ static bool remove_dir(const char *path) return true; } +static bool is_temp_file(const char *name, const char *prefix) +{ + size_t prefix_len = strlen(prefix); + int i; + + if (strncmp(name, prefix, prefix_len) != 0) + { + return false; + } + + for (i = 0; i < 3; i++) + { + char ch = name[prefix_len + i]; + + if (ch < '0' || ch > '9') + { + return false; + } + } + + return name[prefix_len + i] == '\0'; +} + +static bool cleanup_dir(const char *path, const char *name) +{ + FAR DIR *dir; + FAR struct dirent *entry; + char filepath[MAX_PATH_LEN]; + int ret; + + dir = opendir(path); + if (dir == NULL) + { + if (errno == ENOENT) + { + return true; + } + + printf("opendir %s failed, errno: %d -> %s\n", + path, errno, strerror(errno)); + return false; + } + + while ((entry = readdir(dir)) != NULL) + { + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) + { + continue; + } + + if (!is_temp_file(entry->d_name, name)) + { + printf("%s contains unexpected entry %s\n", path, entry->d_name); + closedir(dir); + return false; + } + + ret = snprintf(filepath, sizeof(filepath), "%s/%s", + path, entry->d_name); + if (ret < 0 || (size_t)ret >= sizeof(filepath)) + { + printf("path name too long\n"); + closedir(dir); + return false; + } + + ret = unlink(filepath); + if (ret < 0) + { + printf("unlink %s failed, ret: %d, errno %d -> %s\n", + filepath, ret, errno, strerror(errno)); + closedir(dir); + return false; + } + } + + ret = closedir(dir); + if (ret < 0) + { + printf("closedir %s failed, ret: %d, errno %d -> %s\n", + path, ret, errno, strerror(errno)); + return false; + } + + return remove_dir(path); +} + static bool create_files(const char *dir, const char *name, size_t num_files, char *bytes, size_t num_bytes) { @@ -372,6 +462,12 @@ int main(int argc, char *argv[]) total_time = 0; + if (!cleanup_dir(TEMPDIR, TEMPFILE) || !cleanup_dir(TEMPDIR2, TEMPFILE)) + { + free(bytes); + return -1; + } + for (size_t i = 0; i < num_runs; ++i) { start = get_abs_time(); From b563694ab79d3d20008c4999c5c09d0121521843 Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Sun, 24 May 2026 10:30:56 +0800 Subject: [PATCH 2/2] testing/sd_stress: Harden file creation cleanup Close the temporary file descriptor when create_files() fails after open(), and release the read buffer before returning from the path-length failure branch. This is logically separable from the #3205 stale-directory fix: it does not change how existing /sd/stress is handled, but keeps the same failure paths from leaking resources while the stress test exits after an error. The scope intentionally stays within sd_stress failure cleanup and does not touch SD/MMC transfer behavior or other testing drivers. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- testing/drivers/sd_stress/sd_stress_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/testing/drivers/sd_stress/sd_stress_main.c b/testing/drivers/sd_stress/sd_stress_main.c index 882bec362ea..dffdd16c5c9 100644 --- a/testing/drivers/sd_stress/sd_stress_main.c +++ b/testing/drivers/sd_stress/sd_stress_main.c @@ -233,6 +233,7 @@ static bool create_files(const char *dir, const char *name, if (path_len + 5 >= MAX_PATH_LEN) { printf("path name too long\n"); + free(read_bytes); return false; } @@ -267,7 +268,7 @@ static bool create_files(const char *dir, const char *name, printf("write %s failed, ret: %d, errno %d -> %s\n", path, ret, errno, strerror(errno)); passed = false; - break; + goto close_file; } ret = lseek(fd, 0, SEEK_SET); @@ -277,7 +278,7 @@ static bool create_files(const char *dir, const char *name, printf("lseek %s failed, ret: %d, errno %d -> %s\n", path, ret, errno, strerror(errno)); passed = false; - break; + goto close_file; } ret = read(fd, read_bytes, num_bytes); @@ -287,16 +288,17 @@ static bool create_files(const char *dir, const char *name, printf("read %s failed, ret: %d, errno %d -> %s\n", path, ret, errno, strerror(errno)); passed = false; - break; + goto close_file; } if (memcmp(read_bytes, bytes, num_bytes) != 0) { printf("read and write buffers are not the same\n"); passed = false; - break; + goto close_file; } +close_file: ret = close(fd); if (ret < 0) @@ -306,6 +308,11 @@ static bool create_files(const char *dir, const char *name, passed = false; break; } + + if (!passed) + { + break; + } } free(read_bytes);