We were having problems with cfexecd mailing out the same outputs
file contents after each run, rather than suppressing the duplicate mail.
I traced the problem to a problem with the way the
'outputs/previous' symlink was handled. In 2.0.7p3, the symlink
isn't recreated at each run. This can create a situation where
the symlink points to a file that's so old that the target gets
tidied. At that point, the symlink points nowhere, and every run
of cfexecd creates output that appears to be different (since
there's no target of the symlink to compare it to).
Does this make sense?
We re-wrote CompareResult() in cfexecd.c to unlink the
'outputs/previous' symlink and re-link it during each run so
that the symlink always points to the most 'previous' file, rather
than a old one.
I'm attaching a unified diff, plus another file with just the
function in it since it's not very big and the diff's a bit hard
to read.
I hope this fix can make it into the next release. I've been
running my patched version for a week now and I've not seen any
problems.
-j
------------------------------------------------------------------------
/*
* HvB: Bas van der Vlies
* This function compare the current result with the previous run
* and returns:
* 0 : if the files are the same
* 1 : if the files differ
*/
int CompareResult(filename, prev_file)
char *filename, *prev_file;
{ int i;
char digest1[EVP_MAX_MD_SIZE+1];
char digest2[EVP_MAX_MD_SIZE+1];
int md_len1, md_len2;
FILE *fp;
int rtn = 0;
Verbose("Comparing files %s with %s\n", prev_file, filename);
if ((fp=fopen(prev_file,"r")) != NULL) {
fclose(fp);
md_len1 = FileChecksum(prev_file, digest1, 'm');
md_len2 = FileChecksum(filename, digest2, 'm');
if (md_len1 != md_len2) {
rtn = 1;
} else {
for (i = 0; i < md_len1; i++) {
if (digest1[i] != digest2[i]) {
rtn = 1;
break;
}
}
}
} else {
rtn = 1;
}
/* always update the symlink. */
unlink(prev_file);
if (symlink(filename, prev_file) == -1 ) {
snprintf(OUTPUT,bufsize,"Could not link %s and %s",filename,prev_file);
CfLog(cfinform,OUTPUT,"symlink");
rtn = 1;
}
return(rtn);
}
------------------------------------------------------------------------
Index: cfexecd.c
===================================================================
RCS file: /net/scully/cvs/is-cvs/os-apps/cfengine/src/cfexecd.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- cfexecd.c 28 Jul 2003 20:50:43 -0000 1.2
+++ cfexecd.c 18 Aug 2003 20:43:04 -0000 1.3
@@ -699,49 +699,38 @@
char digest2[EVP_MAX_MD_SIZE+1];
int md_len1, md_len2;
FILE *fp;
+ int rtn = 0;
-Verbose("Comparing files %s with %s\n", prev_file, filename);
+ Verbose("Comparing files %s with %s\n", prev_file, filename);
-if ((fp=fopen(prev_file,"r")) != NULL)
- {
- fclose(fp);
+ if ((fp=fopen(prev_file,"r")) != NULL) {
+ fclose(fp);
- md_len1 = FileChecksum(prev_file, digest1, 'm');
- md_len2 = FileChecksum(filename, digest2, 'm');
-
- if (md_len1 != md_len2)
- {
- return(1);
- }
-
- for (i = 0; i < md_len1; i++)
- {
- if (digest1[i] != digest2[i])
- {
- /* Current file will now be the previous result */
- unlink(prev_file);
- if (symlink(filename, prev_file) == -1)
- {
- snprintf(OUTPUT,bufsize,"Could not link %s and
%s",filename,prev_file);
- CfLog(cfinform,OUTPUT,"symlink");
- }
-
- return(1);
- }
+ md_len1 = FileChecksum(prev_file, digest1, 'm');
+ md_len2 = FileChecksum(filename, digest2, 'm');
+
+ if (md_len1 != md_len2) {
+ rtn = 1;
+ } else {
+ for (i = 0; i < md_len1; i++) {
+ if (digest1[i] != digest2[i]) {
+ rtn = 1;
+ break;
+ }
+ }
}
-
- return(0);
- }
-else
- {
- /* no previous file */
- if ( symlink(filename, prev_file) == -1 )
- {
+ } else {
+ rtn = 1;
+ }
+
+ /* always update the symlink. */
+ unlink(prev_file);
+ if (symlink(filename, prev_file) == -1 ) {
snprintf(OUTPUT,bufsize,"Could not link %s and %s",filename,prev_file);
CfLog(cfinform,OUTPUT,"symlink");
- }
- return(1);
- }
+ rtn = 1;
+ }
+ return(rtn);
}
/***********************************************************************/
------------------------------------------------------------------------
_______________________________________________
Help-cfengine mailing list
Help-cfengine@gnu.org
http://mail.gnu.org/mailman/listinfo/help-cfengine