[ccache] patch: workaround for NFS issues
John Coiner
john.coiner at amd.com
Sat Mar 24 16:47:49 GMT 2007
Hi all,
Here's a patch, for ccache 2.4, which works around the NFS bug. From the
ccache man page:
"BUGS. When the cache is stored on an NFS filesystem, the filesystem
must be exported with the no_subtree_check option to make renames
between directories reliable."
I have seen corrupt object files when doing parallel builds. At my
company, I am a mere user, so I asked someone in the IT department about
enabling no_subtree_check. He says our fileserver doesn't support it.
This patch provides another option, when no_subtree_check isn't available.
How it works: when CCACHE_NFS_WORKAROUND is set, ccache won't rename
files across directories. Instead, it copies the file to its destination
directory, and then renames it. This is inefficient, but it's more
efficient than not using ccache. The cost of the extra copy is only
incurred on a cache miss.
To test this, I set up a testbench which starts 12 parallel builds on
different machines simultaneously. Each build compiles the same .c file
into a .o, and then links the .o into an executable. They all use the
same ccache. Without the workaround, this produces a linker failure in
about 50% of trials; with the workaround, I have not seen a failure in
>15 trials. So it might actually work.
- John
--- ccache-2.4/ccache.c 2004-09-13 06:38:30.000000000 -0400
+++ ccache-2.4-fix/ccache.c 2007-03-24 10:40:46.000000000 -0500
@@ -157,6 +157,7 @@
char *tmp_stdout, *tmp_stderr, *tmp_hashname;
struct stat st1, st2;
int status;
+ char *workaround = getenv("CCACHE_NFS_WORKAROUND");
x_asprintf(&tmp_stdout, "%s/tmp.stdout.%s", temp_dir,
tmp_string());
x_asprintf(&tmp_stderr, "%s/tmp.stderr.%s", temp_dir,
tmp_string());
@@ -232,7 +233,8 @@
if (stat(tmp_stderr, &st1) != 0 ||
stat(tmp_hashname, &st2) != 0 ||
- rename(tmp_hashname, hashname) != 0 ||
+ ( workaround && ( copy_file(tmp_hashname, hashname) != 0 ) ) ||
+ ( !workaround && ( rename (tmp_hashname, hashname) != 0 ) ) ||
rename(tmp_stderr, path_stderr) != 0) {
cc_log("failed to rename tmp files - %s\n",
strerror(errno));
stats_update(STATS_ERROR);
diff -u ccache-2.4/util.c ccache-2.4-fix/util.c
--- ccache-2.4/util.c 2004-09-13 06:38:30.000000000 -0400
+++ ccache-2.4-fix/util.c 2007-03-24 10:46:15.000000000 -0500
@@ -68,7 +68,16 @@
char *tmp_name;
mode_t mask;
- x_asprintf(&tmp_name, "%s.XXXXXX", dest);
+ if( getenv("CCACHE_NFS_WORKAROUND") )
+ {
+ /* hostname and pid means this filename is unique. */
+ x_asprintf( &tmp_name, "%s.XXXXXX.%s.%d", dest,
+ getenv("HOSTNAME"), getpid() );
+ }
+ else
+ {
+ x_asprintf( &tmp_name, "%s.XXXXXX", dest );
+ }
fd1 = open(src, O_RDONLY|O_BINARY);
if (fd1 == -1) {
More information about the ccache
mailing list