Commit 1ba3366a authored by Peter W. Draper's avatar Peter W. Draper
Browse files

Store the length of the packet written into the stream and add a label

The lenghts are checked against the expected values and cause an error, the labels are not currently used (would need to add API to return the headers so that these could be speculatively queried and the stream rolled back, so maybe not a great idea).
parent dc0aaaa6
......@@ -63,7 +63,7 @@ void cooling_print(const struct cooling_function_data* cooling) {
void cooling_struct_dump(const struct cooling_function_data* cooling,
FILE* stream) {
restart_write_blocks((void*)cooling, sizeof(struct cooling_function_data), 1,
stream, "cooling function");
stream, "cooling", "cooling function");
}
/**
......@@ -76,5 +76,5 @@ void cooling_struct_dump(const struct cooling_function_data* cooling,
void cooling_struct_restore(const struct cooling_function_data* cooling,
FILE* stream) {
restart_read_blocks((void*)cooling, sizeof(struct cooling_function_data), 1,
stream, "cooling function");
stream, NULL, "cooling function");
}
......@@ -5797,7 +5797,7 @@ void engine_struct_dump(struct engine *e, FILE *stream) {
/* Dump the engine. Save the current tasks_per_cell estimate. */
e->restart_max_tasks = engine_estimate_nr_tasks(e);
restart_write_blocks(e, sizeof(struct engine), 1, stream, "engine struct");
restart_write_blocks(e, sizeof(struct engine), 1, stream, "engine", "engine struct");
/* And all the engine pointed data, these use their own dump functions. */
space_struct_dump(e->s, stream);
......@@ -5827,7 +5827,7 @@ void engine_struct_dump(struct engine *e, FILE *stream) {
void engine_struct_restore(struct engine *e, FILE *stream) {
/* Read the engine. */
restart_read_blocks(e, sizeof(struct engine), 1, stream, "engine struct");
restart_read_blocks(e, sizeof(struct engine), 1, stream, NULL, "engine struct");
/* Re-initializations as necessary for our struct and its members. */
e->sched.tasks = NULL;
......
......@@ -105,7 +105,7 @@ void gravity_props_print_snapshot(hid_t h_grpgrav,
*/
void gravity_props_struct_dump(const struct gravity_props *p, FILE *stream) {
restart_write_blocks((void *)p, sizeof(struct gravity_props), 1, stream,
"gravity props");
"gravity", "gravity props");
}
/**
......@@ -117,5 +117,5 @@ void gravity_props_struct_dump(const struct gravity_props *p, FILE *stream) {
*/
void gravity_props_struct_restore(const struct gravity_props *p, FILE *stream) {
restart_read_blocks((void *)p, sizeof(struct gravity_props), 1, stream,
"gravity props");
NULL, "gravity props");
}
......@@ -136,7 +136,7 @@ void hydro_props_print_snapshot(hid_t h_grpsph, const struct hydro_props *p) {
*/
void hydro_props_struct_dump(const struct hydro_props *p, FILE *stream) {
restart_write_blocks((void *)p, sizeof(struct hydro_props), 1, stream,
"hydro props");
"hydroprops", "hydro props");
}
/**
......@@ -148,5 +148,5 @@ void hydro_props_struct_dump(const struct hydro_props *p, FILE *stream) {
*/
void hydro_props_struct_restore(const struct hydro_props *p, FILE *stream) {
restart_read_blocks((void *)p, sizeof(struct hydro_props), 1, stream,
"hydro props");
NULL, "hydro props");
}
......@@ -794,7 +794,7 @@ void parser_write_params_to_hdf5(const struct swift_params *params, hid_t grp) {
*/
void parser_struct_dump(const struct swift_params *params, FILE *stream) {
restart_write_blocks((void *)params, sizeof(struct swift_params), 1, stream,
"parameters");
"parameters", "parameters");
}
/**
......@@ -806,5 +806,5 @@ void parser_struct_dump(const struct swift_params *params, FILE *stream) {
*/
void parser_struct_restore(const struct swift_params *params, FILE *stream) {
restart_read_blocks((void *)params, sizeof(struct swift_params), 1, stream,
"parameters");
NULL, "parameters");
}
......@@ -1309,13 +1309,13 @@ void partition_restore_celllist(struct space *s, struct repartition *reparttype)
*/
void partition_struct_dump(struct repartition *reparttype, FILE *stream) {
restart_write_blocks(reparttype, sizeof(struct repartition), 1, stream,
"repartition params");
"repartition", "repartition params");
/* Also save the celllist, if we have one. */
if (reparttype->ncelllist > 0)
restart_write_blocks(reparttype->celllist,
sizeof(int) * reparttype->ncelllist, 1, stream,
"repartition celllist");
"celllist", "repartition celllist");
}
/**
......@@ -1327,7 +1327,7 @@ void partition_struct_dump(struct repartition *reparttype, FILE *stream) {
*/
void partition_struct_restore(struct repartition *reparttype, FILE *stream) {
restart_read_blocks(reparttype, sizeof(struct repartition), 1, stream,
"repartition params");
NULL, "repartition params");
/* Also restore the celllist, if we have one. */
if (reparttype->ncelllist > 0) {
......@@ -1335,6 +1335,6 @@ void partition_struct_restore(struct repartition *reparttype, FILE *stream) {
if (reparttype->celllist == NULL) error("Failed to allocate celllist");
restart_read_blocks(reparttype->celllist,
sizeof(int) * reparttype->ncelllist, 1, stream,
"repartition celllist");
NULL, "repartition celllist");
}
}
......@@ -132,7 +132,7 @@ void phys_const_print(struct phys_const *internal_const) {
void phys_const_struct_dump(const struct phys_const *internal_const,
FILE *stream) {
restart_write_blocks((void *)internal_const, sizeof(struct phys_const), 1,
stream, "phys_const params");
stream, "physconst", "phys_const params");
}
/**
......@@ -145,5 +145,5 @@ void phys_const_struct_dump(const struct phys_const *internal_const,
void phys_const_struct_restore(const struct phys_const *internal_const,
FILE *stream) {
restart_read_blocks((void *)internal_const, sizeof(struct phys_const), 1,
stream, "phys_const params");
stream, NULL, "phys_const params");
}
......@@ -63,7 +63,7 @@ void potential_print(const struct external_potential* potential) {
void potential_struct_dump(const struct external_potential* potential,
FILE* stream) {
restart_write_blocks((void*)potential, sizeof(struct external_potential), 1,
stream, "external potential");
stream, "externalpotential", "external potential");
}
/**
......@@ -76,5 +76,5 @@ void potential_struct_dump(const struct external_potential* potential,
void potential_struct_restore(const struct external_potential* potential,
FILE* stream) {
restart_read_blocks((void*)potential, sizeof(struct external_potential), 1,
stream, "external potential");
stream, NULL, "external potential");
}
......@@ -39,7 +39,17 @@
#include "restart.h"
#include "version.h"
/* The signature for restart files. */
#define SWIFT_RESTART_SIGNATURE "SWIFT-restart-file"
#define FNAMELEN 200
#define LABLEN 20
/* Structure for a dumped header. */
struct header {
size_t len; /* Total length of data in bytes. */
char label[LABLEN+1]; /* A label for data */
};
/**
* @brief generate a name for a restart file.
......@@ -122,9 +132,9 @@ void restart_write(struct engine *e, const char *filename) {
/* Dump our signature and version. */
restart_write_blocks(SWIFT_RESTART_SIGNATURE, strlen(SWIFT_RESTART_SIGNATURE),
1, stream, "SWIFT signature");
1, stream, "signature", "SWIFT signature");
restart_write_blocks((void *)package_version(), strlen(package_version()), 1,
stream, "SWIFT version");
stream, "version", "SWIFT version");
engine_struct_dump(e, stream);
fclose(stream);
......@@ -145,24 +155,24 @@ void restart_read(struct engine *e, const char *filename) {
/* Get our version and signature back. These should match. */
char signature[strlen(SWIFT_RESTART_SIGNATURE) + 1];
int len = strlen(SWIFT_RESTART_SIGNATURE);
restart_read_blocks(signature, len, 1, stream, "SWIFT signature");
restart_read_blocks(signature, len, 1, stream, NULL, "SWIFT signature");
signature[len] = '\0';
if (strncmp(signature, SWIFT_RESTART_SIGNATURE, len) != 0)
error(
"Do not recognise this as a SWIFT restart file, found %s "
"expected %s",
"Do not recognise this as a SWIFT restart file, found '%s' "
"expected '%s'",
signature, SWIFT_RESTART_SIGNATURE);
char version[FNAMELEN];
len = strlen(package_version());
restart_read_blocks(version, len, 1, stream, "SWIFT version");
restart_read_blocks(version, len, 1, stream, NULL, "SWIFT version");
version[len] = '\0';
/* It might work! */
if (strncmp(version, package_version(), len) != 0)
message(
"WARNING: restoring from a different version of SWIFT.\n You have:"
" %s and the restarts files are from: %s. This may fail"
" '%s' and the restarts files are from: '%s'. This may fail"
" badly.",
package_version(), version);
......@@ -172,22 +182,38 @@ void restart_read(struct engine *e, const char *filename) {
/**
* @brief Read blocks of memory from a file stream into a memory location.
* Exits the application if the read fails and does nothing
* if the size is zero.
* Exits the application if the read fails and does nothing if the
* size is zero.
*
* @param ptr pointer to the memory
* @param size size of a block
* @param nblocks number of blocks to read
* @param stream the file stream
* @param label the label recovered for the block, needs to be at least 20
* characters, set to NULL if not required
* @param errstr a context string to qualify any errors.
*/
void restart_read_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream,
const char *errstr) {
char *label, const char *errstr) {
if (size > 0) {
size_t nread = fread(ptr, size, nblocks, stream);
if (nread != nblocks)
error("Failed to restore %s from restart file (%s)", errstr,
ferror(stream) ? strerror(errno) : "unexpected end of file");
struct header head;
size_t nread = fread(&head, sizeof(struct header), 1, stream);
if (nread != 1)
error("Failed to read the %s header from restart file (%s)", errstr, strerror(errno));
/* Check that the stored length is the same as the expected one. */
if (head.len != nblocks * size)
error("Mismatched data length in restart file for %s (%zu != %zu)",
errstr, head.len, nblocks * size);
/* Return label, if required. */
if (label != NULL)
strncpy(label, head.label, LABLEN);
nread = fread(ptr, size, nblocks, stream);
if (nread != nblocks)
error("Failed to restore %s from restart file (%s)", errstr,
ferror(stream) ? strerror(errno) : "unexpected end of file");
}
}
......@@ -200,15 +226,28 @@ void restart_read_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream,
* @param size the blocks
* @param nblocks number of blocks to write
* @param stream the file stream
* @param label a label for the content, can only be 20 characters.
* @param errstr a context string to qualify any errors.
*/
void restart_write_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream,
const char *errstr) {
if (size > 0) {
size_t nwrite = fwrite(ptr, size, nblocks, stream);
if (nwrite != nblocks)
error("Failed to save %s to restart file (%s)", errstr, strerror(errno));
}
const char *label, const char *errstr) {
if (size > 0) {
/* Add a preamble header. */
struct header head;
head.len = nblocks * size;
strncpy(head.label, label, LABLEN);
head.label[LABLEN] = '\0';
/* Now dump it and the data. */
size_t nwrite = fwrite(&head, sizeof(struct header), 1, stream);
if (nwrite != 1)
error("Failed to save %s header to restart file (%s)", errstr, strerror(errno));
nwrite = fwrite(ptr, size, nblocks, stream);
if (nwrite != nblocks)
error("Failed to save %s to restart file (%s)", errstr, strerror(errno));
}
}
/**
......
......@@ -23,11 +23,6 @@
struct engine;
/* The signature for restart files. */
#ifndef SWIFT_RESTART_SIGNATURE
#define SWIFT_RESTART_SIGNATURE "SWIFT-restart-file"
#endif
void restart_write(struct engine *e, const char *filename);
void restart_read(struct engine *e, const char *filename);
......@@ -37,10 +32,10 @@ int restart_genname(const char *dir, const char *basename, int nodeID,
char *name, int size);
void restart_read_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream,
const char *errstr);
char *label, const char *errstr);
void restart_write_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream,
const char *errstr);
const char *label, const char *errstr);
int restart_stop_now(const char *dir, int cleanup);
......
......@@ -68,7 +68,7 @@ void sourceterms_print(struct sourceterms *source) {
void sourceterms_struct_dump(const struct sourceterms *sourceterms,
FILE *stream) {
restart_write_blocks((void *)sourceterms, sizeof(struct sourceterms), 1,
stream, "sourceterms");
stream, "sourceterms", "sourceterms");
}
/**
......@@ -81,5 +81,5 @@ void sourceterms_struct_dump(const struct sourceterms *sourceterms,
void sourceterms_struct_restore(const struct sourceterms *sourceterms,
FILE *stream) {
restart_read_blocks((void *)sourceterms, sizeof(struct sourceterms), 1,
stream, "sourceterms");
stream, NULL, "sourceterms");
}
......@@ -3249,22 +3249,22 @@ void space_clean(struct space *s) {
*/
void space_struct_dump(struct space *s, FILE *stream) {
restart_write_blocks(s, sizeof(struct space), 1, stream, "space struct");
restart_write_blocks(s, sizeof(struct space), 1, stream, "space", "space struct");
/* More things to write. */
if (s->nr_parts > 0) {
restart_write_blocks(s->parts, s->nr_parts, sizeof(struct part), stream,
"parts");
"parts", "parts");
restart_write_blocks(s->xparts, s->nr_parts, sizeof(struct xpart), stream,
"xparts");
"xparts", "xparts");
}
if (s->nr_gparts > 0)
restart_write_blocks(s->gparts, s->nr_gparts, sizeof(struct gpart), stream,
"gparts");
"gparts", "gparts");
if (s->nr_sparts > 0)
restart_write_blocks(s->sparts, s->nr_sparts, sizeof(struct spart), stream,
"sparts");
"sparts", "sparts");
}
/**
......@@ -3276,7 +3276,7 @@ void space_struct_dump(struct space *s, FILE *stream) {
*/
void space_struct_restore(struct space *s, FILE *stream) {
restart_read_blocks(s, sizeof(struct space), 1, stream, "space struct");
restart_read_blocks(s, sizeof(struct space), 1, stream, NULL, "space struct");
/* Things that should be reconstructed in a rebuild. */
s->cells_top = NULL;
......@@ -3308,9 +3308,9 @@ void space_struct_restore(struct space *s, FILE *stream) {
error("Failed to allocate restore xpart array.");
restart_read_blocks(s->parts, s->nr_parts, sizeof(struct part), stream,
"parts");
NULL, "parts");
restart_read_blocks(s->xparts, s->nr_parts, sizeof(struct xpart), stream,
"xparts");
NULL, "xparts");
}
s->gparts = NULL;
if (s->nr_gparts > 0) {
......@@ -3319,7 +3319,7 @@ void space_struct_restore(struct space *s, FILE *stream) {
error("Failed to allocate restore gpart array.");
restart_read_blocks(s->gparts, s->nr_gparts, sizeof(struct gpart), stream,
"gparts");
NULL, "gparts");
}
s->sparts = NULL;
......@@ -3329,7 +3329,7 @@ void space_struct_restore(struct space *s, FILE *stream) {
error("Failed to allocate restore spart array.");
restart_read_blocks(s->sparts, s->nr_sparts, sizeof(struct spart), stream,
"sparts");
NULL, "sparts");
}
/* Need to reconnect the gravity parts to their hydro and star particles. */
......
......@@ -612,7 +612,7 @@ void units_print(const struct unit_system* us) {
*/
void units_struct_dump(const struct unit_system* us, FILE* stream) {
restart_write_blocks((void*)us, sizeof(struct unit_system), 1, stream,
"units");
"units", "units");
}
/**
......@@ -622,6 +622,6 @@ void units_struct_dump(const struct unit_system* us, FILE* stream) {
* @param stream the file stream
*/
void units_struct_restore(const struct unit_system* us, FILE* stream) {
restart_read_blocks((void*)us, sizeof(struct unit_system), 1, stream,
"units");
restart_read_blocks((void*)us, sizeof(struct unit_system), 1, stream,
NULL, "units");
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment