summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetri Latvala <petri.latvala@intel.com>2018-04-19 15:20:35 +0300
committerPetri Latvala <petri.latvala@intel.com>2018-04-19 15:20:35 +0300
commit5ae5066599778b94dc8b39df2ee7d12b63369c95 (patch)
treee7e27870039d55e5c861254427fa9a3450922695
parent0f2e7c684eed7429768489dc3451dcd224d0e05e (diff)
Implement --sync and --overwrite
-rw-r--r--runner/executor.c89
-rw-r--r--runner/job_list.c21
-rw-r--r--runner/settings.c29
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;