You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
5.4 KiB
186 lines
5.4 KiB
10 years ago
|
https://lists.samba.org/archive/ccache/2014q4/001246.html
|
||
|
|
||
|
From 5d0f507a4162ac89e05ca633dbc8056454b798f5 Mon Sep 17 00:00:00 2001
|
||
|
From: Mike Frysinger <vapier@gentoo.org>
|
||
|
Date: Mon, 15 Sep 2014 18:15:02 -0400
|
||
|
Subject: [PATCH] do not rely on pids being unique
|
||
|
|
||
|
Linux supports creating pid namespaces cheaply and running processes
|
||
|
inside of them. When you try to share a single cache among multiple
|
||
|
such runs, the fact that the code relies on pid numbers as globally
|
||
|
unique values quickly fails. Instead, switch to standard mkstemp to
|
||
|
generate temp files for us.
|
||
|
|
||
|
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
|
||
|
---
|
||
|
ccache.c | 12 ++++++------
|
||
|
ccache.h | 2 +-
|
||
|
manifest.c | 2 +-
|
||
|
stats.c | 10 +++++++++-
|
||
|
util.c | 13 ++++++++-----
|
||
|
5 files changed, 25 insertions(+), 14 deletions(-)
|
||
|
|
||
|
diff --git a/ccache.c b/ccache.c
|
||
|
index 02dbdfa..1dc0a06 100644
|
||
|
--- a/ccache.c
|
||
|
+++ b/ccache.c
|
||
|
@@ -526,8 +526,11 @@ to_cache(struct args *args)
|
||
|
unsigned added_files = 0;
|
||
|
|
||
|
tmp_stdout = format("%s.tmp.stdout.%s", cached_obj, tmp_string());
|
||
|
+ create_empty_file(tmp_stdout);
|
||
|
tmp_stderr = format("%s.tmp.stderr.%s", cached_obj, tmp_string());
|
||
|
+ create_empty_file(tmp_stderr);
|
||
|
tmp_obj = format("%s.tmp.%s", cached_obj, tmp_string());
|
||
|
+ create_empty_file(tmp_obj);
|
||
|
|
||
|
args_add(args, "-o");
|
||
|
args_add(args, tmp_obj);
|
||
|
@@ -579,7 +582,7 @@ to_cache(struct args *args)
|
||
|
int fd_result;
|
||
|
char *tmp_stderr2;
|
||
|
|
||
|
- tmp_stderr2 = format("%s.tmp.stderr2.%s", cached_obj, tmp_string());
|
||
|
+ tmp_stderr2 = format("%s.2", tmp_stderr);
|
||
|
if (x_rename(tmp_stderr, tmp_stderr2)) {
|
||
|
cc_log("Failed to rename %s to %s: %s", tmp_stderr, tmp_stderr2,
|
||
|
strerror(errno));
|
||
|
@@ -808,6 +808,7 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash)
|
||
|
}
|
||
|
|
||
|
path_stderr = format("%s/tmp.cpp_stderr.%s", temp_dir, tmp_string());
|
||
|
+ create_empty_file(path_stderr);
|
||
|
add_pending_tmp_file(path_stderr);
|
||
|
|
||
|
time_of_compilation = time(NULL);
|
||
|
@@ -815,6 +816,7 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash)
|
||
|
if (!direct_i_file) {
|
||
|
path_stdout = format("%s/%s.tmp.%s.%s",
|
||
|
temp_dir, input_base, tmp_string(), i_extension);
|
||
|
+ create_empty_file(path_stdout);
|
||
|
add_pending_tmp_file(path_stdout);
|
||
|
|
||
|
/* run cpp on the input file to obtain the .i */
|
||
|
@@ -838,11 +843,6 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash)
|
||
|
can skip the cpp stage and directly form the
|
||
|
correct i_tmpfile */
|
||
|
path_stdout = input_file;
|
||
|
- if (create_empty_file(path_stderr) != 0) {
|
||
|
- cc_log("Failed to create %s: %s", path_stderr, strerror(errno));
|
||
|
- stats_update(STATS_ERROR);
|
||
|
- failed();
|
||
|
- }
|
||
|
status = 0;
|
||
|
}
|
||
|
|
||
|
diff --git a/ccache.h b/ccache.h
|
||
|
index 2bc7c87..43ef98d 100644
|
||
|
--- a/ccache.h
|
||
|
+++ b/ccache.h
|
||
|
@@ -130,7 +130,7 @@ size_t file_size(struct stat *st);
|
||
|
int safe_open(const char *fname);
|
||
|
char *x_realpath(const char *path);
|
||
|
char *gnu_getcwd(void);
|
||
|
-int create_empty_file(const char *fname);
|
||
|
+int create_empty_file(char *fname);
|
||
|
const char *get_home_directory(void);
|
||
|
char *get_cwd();
|
||
|
bool same_executable_name(const char *s1, const char *s2);
|
||
|
diff --git a/manifest.c b/manifest.c
|
||
|
index 7f02ede..47566d5 100644
|
||
|
--- a/manifest.c
|
||
|
+++ b/manifest.c
|
||
|
@@ -633,7 +633,7 @@ manifest_put(const char *manifest_path, struct file_hash *object_hash,
|
||
|
}
|
||
|
|
||
|
tmp_file = format("%s.tmp.%s", manifest_path, tmp_string());
|
||
|
- fd2 = safe_open(tmp_file);
|
||
|
+ fd2 = mkstemp(tmp_file);
|
||
|
if (fd2 == -1) {
|
||
|
cc_log("Failed to open %s", tmp_file);
|
||
|
goto out;
|
||
|
diff --git a/stats.c b/stats.c
|
||
|
index 2111b65..4ed39c2 100644
|
||
|
--- a/stats.c
|
||
|
+++ b/stats.c
|
||
|
@@ -126,11 +126,18 @@ stats_write(const char *path, struct counters *counters)
|
||
|
size_t i;
|
||
|
char *tmp_file;
|
||
|
FILE *f;
|
||
|
+ int fd;
|
||
|
|
||
|
tmp_file = format("%s.tmp.%s", path, tmp_string());
|
||
|
- f = fopen(tmp_file, "wb");
|
||
|
+ fd = mkstemp(tmp_file);
|
||
|
+ if (fd == -1) {
|
||
|
+ cc_log("Failed to open %s", tmp_file);
|
||
|
+ goto end;
|
||
|
+ }
|
||
|
+ f = fdopen(fd, "wb");
|
||
|
if (!f) {
|
||
|
cc_log("Failed to open %s", tmp_file);
|
||
|
+ close(fd);
|
||
|
goto end;
|
||
|
}
|
||
|
for (i = 0; i < counters->size; i++) {
|
||
|
@@ -138,6 +145,7 @@ stats_write(const char *path, struct counters *counters)
|
||
|
fatal("Failed to write to %s", tmp_file);
|
||
|
}
|
||
|
}
|
||
|
+ /* This also implicitly closes the fd. */
|
||
|
fclose(f);
|
||
|
x_rename(tmp_file, path);
|
||
|
|
||
|
diff --git a/util.c b/util.c
|
||
|
index 3b472de..cc630a6 100644
|
||
|
--- a/util.c
|
||
|
+++ b/util.c
|
||
|
@@ -195,7 +195,7 @@ copy_file(const char *src, const char *dest, int compress_dest)
|
||
|
struct stat st;
|
||
|
int errnum;
|
||
|
|
||
|
- tmp_name = format("%s.%s.XXXXXX", dest, tmp_string());
|
||
|
+ tmp_name = format("%s.%s", dest, tmp_string());
|
||
|
cc_log("Copying %s to %s via %s (%s)",
|
||
|
src, dest, tmp_name, compress_dest ? "compressed": "uncompressed");
|
||
|
|
||
|
@@ -427,7 +427,7 @@ tmp_string(void)
|
||
|
static char *ret;
|
||
|
|
||
|
if (!ret) {
|
||
|
- ret = format("%s.%u", get_hostname(), (unsigned)getpid());
|
||
|
+ ret = format("%s.%u.XXXXXX", get_hostname(), (unsigned)getpid());
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
@@ -884,12 +884,13 @@ gnu_getcwd(void)
|
||
|
|
||
|
/* create an empty file */
|
||
|
int
|
||
|
-create_empty_file(const char *fname)
|
||
|
+create_empty_file(char *fname)
|
||
|
{
|
||
|
int fd;
|
||
|
|
||
|
- fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
|
||
|
+ fd = mkstemp(fname);
|
||
|
if (fd == -1) {
|
||
|
+ cc_log("Failed to create %s: %s", fname, strerror(errno));
|
||
|
return -1;
|
||
|
}
|
||
|
close(fd);
|
||
|
@@ -1134,7 +1135,9 @@ x_unlink(const char *path)
|
||
|
goto out;
|
||
|
}
|
||
|
if (unlink(tmp_name) == -1) {
|
||
|
- result = -1;
|
||
|
+ /* If it was released in a race, that's OK. */
|
||
|
+ if (errno != ENOENT)
|
||
|
+ result = -1;
|
||
|
}
|
||
|
out:
|
||
|
free(tmp_name);
|
||
|
--
|
||
|
2.1.2
|
||
|
|