diff options
author | tradke <tradke@b32723a9-ab3a-4a60-88e2-2e5d99d7c17a> | 2002-07-17 15:44:46 +0000 |
---|---|---|
committer | tradke <tradke@b32723a9-ab3a-4a60-88e2-2e5d99d7c17a> | 2002-07-17 15:44:46 +0000 |
commit | 3f75a6b2a79f897a47197749601db157d3ae8138 (patch) | |
tree | b2ab7a05be03cf6abec36361117e793e964ca6ce | |
parent | 7c371bf82d354f62c99a47f3dc81a53956a4abdb (diff) |
Overwrite an existing parfile unless
- it is identical with the original parfile
- this is a recovery run
This closes PR CactusBase/884.
git-svn-id: http://svn.cactuscode.org/arrangements/CactusBase/IOUtil/trunk@177 b32723a9-ab3a-4a60-88e2-2e5d99d7c17a
-rw-r--r-- | doc/documentation.tex | 7 | ||||
-rw-r--r-- | src/Startup.c | 181 |
2 files changed, 104 insertions, 84 deletions
diff --git a/doc/documentation.tex b/doc/documentation.tex index 93f7b30..39e3cb4 100644 --- a/doc/documentation.tex +++ b/doc/documentation.tex @@ -192,8 +192,11 @@ This is controlled by the {\tt IO::parfile\_write} parameter: \end{itemize} The name of the new parameter file defaults to the original filename, unless the -parameter {\tt IO::parfile\_name} is set. Note that if a file already exists -with the chosen name it will not be overwritten. +parameter {\tt IO::parfile\_name} is set. Note that an already existing file +with the chosen name will be overwritten unless it is identical with the +original parameter file, or if Cactus was recovered from a checkpoint (in which +case you don't want to overwrite an existing parameter file with your recovery +parameter file). \section{I/O Modes} diff --git a/src/Startup.c b/src/Startup.c index 1359d0e..92cd526 100644 --- a/src/Startup.c +++ b/src/Startup.c @@ -62,8 +62,8 @@ typedef struct t_param_list ********************** Static Routines ********************* ********************************************************************/ static void *SetupGH (tFleshConfig *config, int convergence_level, cGH *GH); -static int CopyParFile (const char *new_parfilename, const char *out_dir); -static int GenerateParFile (const char *new_parfilename, const char *out_dir); +static int CopyParFile (int recovered); +static int GenerateParFile (int recovered); static int DumpParameters (FILE *outfile); @@ -669,11 +669,11 @@ static void *SetupGH (tFleshConfig *config, int convergence_level, cGH *GH) { if (CCTK_Equals (parfile_write, "copy")) { - CopyParFile (parfile_name, out_dir); + CopyParFile (newGH->recovered); } else if (CCTK_Equals (parfile_write, "generate")) { - GenerateParFile (parfile_name, out_dir); + GenerateParFile (newGH->recovered); } } @@ -687,23 +687,13 @@ static void *SetupGH (tFleshConfig *config, int convergence_level, cGH *GH) @author Thomas Radke @desc Copies the original parameter file to a new one in 'IO::out_dir'. - Note that the new parameter file is only written if no such - file existed before. + Note that the new parameter file will usually overwrite an + existing file unless + - the new parameter file is identical with the original one + - this is a recovery run @enddesc @calls CCTK_ParameterFilename - @var parfile_name - @vdesc name of the new parfile (or empty string if the original - parfile name should be used) - @vtype const char * - @vio in - @endvar - @var out_dir - @vdesc directory to write the new parfile to - @vtype const char * - @vio in - @endvar - @returntype int @returndesc 0 for success, or<BR> @@ -711,11 +701,12 @@ static void *SetupGH (tFleshConfig *config, int convergence_level, cGH *GH) -2 if new parameter file couldn't be opened for writing<BR> @endreturndesc @@*/ -static int CopyParFile (const char *parfile_name, const char *out_dir) +static int CopyParFile (int recovered) { - int in_parfile, out_parfile, bytes; + int in_parfile, out_parfile, bytes, flags; char *out_parfilename, buffer[256]; - struct stat stat_buf; + struct stat in_stat_buf, out_stat_buf; + DECLARE_CCTK_PARAMETERS /* get the name of the original parfile and open it for reading */ @@ -729,9 +720,9 @@ static int CopyParFile (const char *parfile_name, const char *out_dir) return (-1); } /* use the file mode of the original parfile to create the new one */ - if (fstat (in_parfile, &stat_buf)) + if (fstat (in_parfile, &in_stat_buf)) { - stat_buf.st_mode = 0644; + in_stat_buf.st_mode = 0644; } /* build the name of the output parfile */ @@ -751,22 +742,39 @@ static int CopyParFile (const char *parfile_name, const char *out_dir) out_parfilename = (char *) malloc (strlen(out_dir) + strlen(parfile_name)+2); sprintf (out_parfilename, "%s/%s", out_dir, parfile_name); - /* binary-copy the input parfile to the output parfile */ - out_parfile = open (out_parfilename, O_CREAT | O_WRONLY | O_EXCL, - stat_buf.st_mode); - if (out_parfile >= 0) + /* check whether input and output files are identical */ + if (! stat (out_parfilename, &out_stat_buf) && + in_stat_buf.st_ino == out_stat_buf.st_ino) { - while ((bytes = read (in_parfile, buffer, sizeof (buffer))) > 0) - { - write (out_parfile, buffer, bytes); - } - close (out_parfile); + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Parameter file '%s' to be written into directory '%s' is " + "identical with original parameter file. Parameter file will " + "not be copied.", parfile_name, out_dir); + out_parfile = 0; } else { - CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, - "Couldn't write parameter file '%s' (%s)", - out_parfilename, strerror (errno)); + /* binary-copy the input parfile to the output parfile */ + flags = O_CREAT | O_WRONLY; + if (recovered) + { + flags |= O_EXCL; + } + out_parfile = open (out_parfilename, flags, in_stat_buf.st_mode); + if (out_parfile >= 0) + { + while ((bytes = read (in_parfile, buffer, sizeof (buffer))) > 0) + { + write (out_parfile, buffer, bytes); + } + close (out_parfile); + } + else + { + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Couldn't write parameter file '%s' (%s)", + out_parfilename, strerror (errno)); + } } /* clean up */ @@ -785,20 +793,16 @@ static int CopyParFile (const char *parfile_name, const char *out_dir) Generates a new parameter file in 'IO::out_dir' with an ActiveThorns list and a sorted list of all active parameters which have been set in the original parameter file.<BR> - Note that the new parameter file is only written if no such - file existed before. + Note that the new parameter file will usually overwrite an + existing file unless + - the new parameter file is identical with the original one + - this is a recovery run @enddesc @calls CCTK_ParameterFilename - @var parfile_name - @vdesc name of the new parfile (or empty string if the original - parfile name should be used) - @vtype const char * - @vio in - @endvar - @var out_dir - @vdesc directory to write the new parfile to - @vtype const char * + @var recovered + @vdesc flag indicating whether this is a recovery run + @vtype int @vio in @endvar @@ -809,28 +813,24 @@ static int CopyParFile (const char *parfile_name, const char *out_dir) -2 if new parameter file couldn't be opened for writing<BR> @endreturndesc @@*/ -static int GenerateParFile (const char *parfile_name, const char *out_dir) +static int GenerateParFile (int recovered) { FILE *outfile; - int out_parfile; + int out_parfile, flags; char *out_parfilename, buffer[256]; - struct stat stat_buf; + struct stat in_stat_buf, out_stat_buf; + DECLARE_CCTK_PARAMETERS /* get the name of the original parfile and stat(2) it */ CCTK_ParameterFilename (sizeof (buffer), buffer); - if (stat (buffer, &stat_buf)) + if (stat (buffer, &in_stat_buf)) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "Couldn't stat(2) original parameter file '%s' (%s)", buffer, strerror (errno)); return (-1); } - /* use the file mode of the original parfile to create the new one */ - if (stat (buffer, &stat_buf)) - { - stat_buf.st_mode = 0644; - } /* build the name of the output parfile */ if (! *parfile_name) @@ -849,37 +849,54 @@ static int GenerateParFile (const char *parfile_name, const char *out_dir) out_parfilename = (char *) malloc (strlen(out_dir) + strlen(parfile_name)+2); sprintf (out_parfilename, "%s/%s", out_dir, parfile_name); - /* open the output parfile for writing */ - out_parfile = open (out_parfilename, O_CREAT | O_WRONLY | O_EXCL, - stat_buf.st_mode); - if (out_parfile >= 0) - { - outfile = fdopen (out_parfile, "w"); - } - if (out_parfile >= 0 && outfile) + /* check whether input and output files are identical */ + if (! stat (out_parfilename, &out_stat_buf) && + in_stat_buf.st_ino == out_stat_buf.st_ino) { - fprintf (outfile, "# '%s' automatically generated by Cactus version %s\n", - out_parfilename, CCTK_FullVersion ()); - fprintf (outfile, "# Original parameter file was '%s'\n", buffer); - Util_CurrentTime (sizeof (buffer), buffer); - fprintf (outfile, "# Run time/date was %s ", buffer); - Util_CurrentDate (sizeof (buffer), buffer); - fprintf (outfile, "%s ", buffer); - Util_GetHostName (buffer, sizeof (buffer)); - fprintf (outfile, "on host '%s' with %d processor(s)\n\n", - buffer, CCTK_nProcs (NULL)); - DumpParameters (outfile); - fclose (outfile); + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Parameter file '%s' to be written into directory '%s' is " + "identical with original parameter file. Parameter file will " + "not be generated.", parfile_name, out_dir); + out_parfile = 0; } else { - CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, - "Couldn't write parameter file '%s' (%s)", - out_parfilename, strerror (errno)); - } - if (out_parfile >= 0) - { - close (out_parfile); + flags = O_CREAT | O_WRONLY; + if (recovered) + { + flags |= O_EXCL; + } + + out_parfile = open (out_parfilename, flags, in_stat_buf.st_mode); + if (out_parfile >= 0) + { + outfile = fdopen (out_parfile, "w"); + } + if (out_parfile >= 0 && outfile) + { + fprintf (outfile, "# '%s' automatically generated by Cactus version %s\n", + out_parfilename, CCTK_FullVersion ()); + fprintf (outfile, "# Original parameter file was '%s'\n", buffer); + Util_CurrentTime (sizeof (buffer), buffer); + fprintf (outfile, "# Run time/date was %s ", buffer); + Util_CurrentDate (sizeof (buffer), buffer); + fprintf (outfile, "%s ", buffer); + Util_GetHostName (buffer, sizeof (buffer)); + fprintf (outfile, "on host '%s' with %d processor(s)\n\n", + buffer, CCTK_nProcs (NULL)); + DumpParameters (outfile); + fclose (outfile); + } + else + { + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Couldn't write parameter file '%s' (%s)", + out_parfilename, strerror (errno)); + } + if (out_parfile >= 0) + { + close (out_parfile); + } } /* clean up */ |