diff options
author | Petri Latvala <petri.latvala@intel.com> | 2018-04-19 15:20:35 +0300 |
---|---|---|
committer | Petri Latvala <petri.latvala@intel.com> | 2018-04-19 15:20:35 +0300 |
commit | 5ae5066599778b94dc8b39df2ee7d12b63369c95 (patch) | |
tree | e7e27870039d55e5c861254427fa9a3450922695 | |
parent | 0f2e7c684eed7429768489dc3451dcd224d0e05e (diff) |
Implement --sync and --overwrite
-rw-r--r-- | runner/executor.c | 89 | ||||
-rw-r--r-- | runner/job_list.c | 21 | ||||
-rw-r--r-- | runner/settings.c | 29 |
3 files changed, 124 insertions, 15 deletions
diff --git a/runner/executor.c b/runner/executor.c index fedc3ee9..5ea8bbd7 100644 --- a/runner/executor.c +++ b/runner/executor.c @@ -204,6 +204,9 @@ static void monitor_output(pid_t child, } write(outputs[_F_OUT], outbuf, outbufpos); + if (settings->sync) { + fdatasync(outputs[_F_OUT]); + } outbufpos = 0; close(outfd); outfd = -1; @@ -235,6 +238,9 @@ static void monitor_output(pid_t child, outbuf + subtest_result_len, subtestlen); write(outputs[_F_JOURNAL], "\n", 1); + if (settings->sync) { + fdatasync(outputs[_F_JOURNAL]); + } current_subtest[0] = '\0'; } if (settings->log_level >= LOG_LEVEL_VERBOSE) { @@ -243,6 +249,9 @@ static void monitor_output(pid_t child, } } write(outputs[_F_OUT], outbuf, linelen); + if (settings->sync) { + fdatasync(outputs[_F_OUT]); + } memmove(outbuf, newline + 1, outbufpos - linelen); outbufpos -= linelen; @@ -261,6 +270,9 @@ static void monitor_output(pid_t child, errfd = -1; } else { write(outputs[_F_ERR], buf, s); + if (settings->sync) { + fdatasync(outputs[_F_ERR]); + } } } @@ -275,6 +287,9 @@ static void monitor_output(pid_t child, } } else { write(outputs[_F_DMESG], buf, s); + if (settings->sync) { + fdatasync(outputs[_F_DMESG]); + } } } @@ -297,6 +312,9 @@ static void monitor_output(pid_t child, status = 9999; } dprintf(outputs[_F_JOURNAL], "exit:%d\n", status); + if (settings->sync) { + fdatasync(outputs[_F_JOURNAL]); + } close(sigfd); sigfd = -1; child = 0; @@ -304,6 +322,9 @@ static void monitor_output(pid_t child, } write(outputs[_F_OUT], outbuf, outbufpos); + if (settings->sync) { + fdatasync(outputs[_F_JOURNAL]); + } outbufpos = 0; close(outfd); @@ -396,6 +417,11 @@ static bool execute_entry(size_t idx, return false; } + if (settings->sync) { + fsync(dirfd); + fsync(resdirfd); + } + if (pipe(outpipe) || pipe(errpipe)) { close_outputs(outputs); close(dirfd); @@ -476,6 +502,65 @@ static bool execute_entry(size_t idx, return true; } +static bool clear_test_result_directory(int dirfd) +{ + if (unlinkat(dirfd, "out.txt", 0) || + unlinkat(dirfd, "err.txt", 0) || + unlinkat(dirfd, "dmesg.txt", 0) || + unlinkat(dirfd, "journal.txt", 0)) { + if (errno != ENOENT) { + fprintf(stderr, "Error clearing test result directories: %s\n", + strerror(errno)); + return false; + } + } + + return true; +} + +static bool clear_old_results(char *path) +{ + int dirfd; + size_t i; + + if ((dirfd = open(path, O_DIRECTORY | O_RDONLY)) < 0) { + if (errno == ENOENT) { + /* Successfully cleared if it doesn't even exist */ + return true; + } + + fprintf(stderr, "Error clearing old results: %s\n", strerror(errno)); + return false; + } + + if (unlinkat(dirfd, "uname.txt", 0) && errno != ENOENT) { + close(dirfd); + fprintf(stderr, "Error clearing old results: %s\n", strerror(errno)); + return false; + } + + for (i = 0; true; i++) { + char name[32]; + int resdirfd; + + snprintf(name, 32, "%zd", i); + if ((resdirfd = openat(dirfd, name, O_DIRECTORY | O_RDONLY)) < 0) + break; + + if (!clear_test_result_directory(resdirfd)) { + close(resdirfd); + close(dirfd); + return false; + } + close(resdirfd); + unlinkat(dirfd, name, AT_REMOVEDIR); + } + + close(dirfd); + + return true; +} + static bool initialize_execute_from_resume(struct execute_state *state, struct settings *orig_settings, struct job_list *orig_job_list) @@ -550,6 +635,10 @@ bool initialize_execute_state(struct execute_state *state, if (!validate_settings(settings)) return false; + if (settings->overwrite && + !clear_old_results(settings->results_path)) + return false; + if (!serialize_settings(settings) || !serialize_job_list(job_list, settings)) return initialize_execute_from_resume(state, settings, job_list); diff --git a/runner/job_list.c b/runner/job_list.c index 8931ad34..212850d8 100644 --- a/runner/job_list.c +++ b/runner/job_list.c @@ -370,10 +370,20 @@ bool serialize_job_list(struct job_list *job_list, struct settings *settings) } if ((fd = openat(dirfd, joblist_filename, O_RDONLY)) >= 0) { - /* Serialization data already exists, not overwriting. */ close(fd); - close(dirfd); - return false; + + if (!settings->overwrite) { + /* Serialization data already exists, not overwriting. */ + close(fd); + close(dirfd); + return false; + } + + if (unlinkat(dirfd, joblist_filename, 0) != 0) { + fprintf(stderr, "Error overwriting old job list\n"); + close(dirfd); + return false; + } } if ((fd = openat(dirfd, joblist_filename, O_CREAT | O_EXCL | O_WRONLY, 0666)) < 0) { @@ -406,6 +416,11 @@ bool serialize_job_list(struct job_list *job_list, struct settings *settings) fprintf(f, "\n"); } + if (settings->sync) { + fsync(fd); + fsync(dirfd); + } + fclose(f); close(dirfd); return true; diff --git a/runner/settings.c b/runner/settings.c index 8d313665..2d97cd2b 100644 --- a/runner/settings.c +++ b/runner/settings.c @@ -278,7 +278,6 @@ bool parse_options(int argc, char **argv, bool validate_settings(struct settings *settings) { - char *dir, *results_path; int dirfd, fd; if (settings->test_list && !readable_file(settings->test_list)) { @@ -312,14 +311,6 @@ bool validate_settings(struct settings *settings) close(fd); close(dirfd); - results_path = strdup(settings->results_path); - dir = dirname(results_path); - if (access(dir, W_OK) != 0) { - usage("Cannot create result directory", true); - return false; - } - free(results_path); - return true; } @@ -373,10 +364,19 @@ bool serialize_settings(struct settings *settings) } if ((fd = openat(dirfd, settings_filename, O_RDONLY)) >= 0) { - /* Serialization data already exists, not overwriting */ close(fd); - close(dirfd); - return false; + + if (!settings->overwrite) { + /* Serialization data already exists, not overwriting */ + close(dirfd); + return false; + } + + if (unlinkat(dirfd, settings_filename, 0) != 0) { + usage("Error overwriting old settings metadata", true); + close(dirfd); + return false; + } } if ((fd = openat(dirfd, settings_filename, O_CREAT | O_EXCL | O_WRONLY, 0666)) < 0) { @@ -406,6 +406,11 @@ bool serialize_settings(struct settings *settings) SERIALIZE_LINE(f, settings, test_root, "%s"); SERIALIZE_LINE(f, settings, results_path, "%s"); + if (settings->sync) { + fsync(fd); + fsync(dirfd); + } + fclose(f); close(dirfd); return true; |