Changeset: ef54a80893ed for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ef54a80893ed
Modified Files:
sql/storage/bat/bat_logger.c
sql/storage/store.c
Branch: hot-snapshot
Log Message:
Copy the file contents
diffs (194 lines):
diff --git a/sql/storage/bat/bat_logger.c b/sql/storage/bat/bat_logger.c
--- a/sql/storage/bat/bat_logger.c
+++ b/sql/storage/bat/bat_logger.c
@@ -391,9 +391,15 @@ snapshot_bbp(stream *plan)
snapshot_heap(plan, b->tvheap);
if (b->torderidx)
snapshot_heap(plan, b->torderidx);
- if (b->thash)
- snapshot_heap(plan, &b->thash->heap);
- // HMMM.. definition of b->timprints not available here
so
+ //
+ // UH OH.. even if b->thash exists, there may not
+ // be a corresponding heap file.
+ // Let's skip it, the target system can probably build
+ // its own hash tables if it needs them.
+ // if (b->thash)
+ // snapshot_heap(plan, &b->thash->heap);
+ //
+ // UH OH.. definition of b->timprints not available
here so
// b->timprints->heap unreachable. Hopefully the system
can
//reconstruct them.
}
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -1836,11 +1836,126 @@ snapshot_prepare_target(const char *dest
return NULL;
}
+static const char *
+snapshot_copy_file(const char *src_file, const char *dest_file, size_t bytes)
+{
+ const char *err = NULL;
+ FILE *src = NULL;
+ FILE *dest = NULL;
+ char *buf = NULL;
+ const size_t bufsize = 64 * 1024;
+ size_t bytes_read;
+ size_t bytes_written;
+
+ // there are many ways to make this more efficient.
+ if (GDKcreatedir(dest_file) != GDK_SUCCEED) {
+ err = "can't create directory";
+ goto end;
+ }
+
+ src = fopen(src_file, "rb");
+ if (!src) {
+ err = strerror(errno);
+ goto end;
+ }
+ dest = fopen(dest_file, "wb");
+ if (!dest) {
+ err = strerror(errno);
+ goto end;
+ }
+
+ buf = malloc(bufsize);
+ if (!buf) {
+ err = "malloc(buf)";
+ goto end;
+ }
+
+ while (bytes > 0) {
+ size_t to_read = (bytes > bufsize) ? bufsize : bytes;
+ bytes_read = fread(buf, 1, to_read, src);
+ if (bytes_read < to_read) {
+ if (ferror(src))
+ err = strerror(errno);
+ else if (feof(src))
+ err = "source file shorter than expected";
+ else
+ err = "unexplainable short read";
+ goto end;
+ }
+ bytes_written = fwrite(buf, 1, bytes_read, dest);
+ if (bytes_read < to_read) {
+ err = strerror(errno);
+ goto end;
+ }
+ bytes -= bytes_written;
+ }
+
+end:
+ free(buf);
+ if (src)
+ fclose(src);
+ if (dest)
+ fclose(dest);
+ return err;
+}
+
+static const char *
+snapshot_copy_data(const char *plan, const char *dest_dir)
+{
+ const char *p = plan;
+ int len;
+ char abs_src[2 * FILENAME_MAX];
+ char abs_dest[2 * FILENAME_MAX];
+ int scanned;
+ char command;
+ long size;
+ char *src;
+ char *dest;
+
+ strncpy(abs_dest, dest_dir, sizeof(abs_dest));
+ dest = abs_dest + strlen(abs_dest);
+ *dest++ = DIR_SEP;
+
+ if (sscanf(p, "%[^\n]\n%n", abs_src, &len) == 1) {
+ p += len;
+ } else {
+ return "no dest!";
+ }
+ src = abs_src + strlen(abs_src);
+ *src++ = DIR_SEP;
+
+ while ((scanned = sscanf(p, "%c %ld %200s\n%n", &command, &size, src,
&len)) == 3) {
+ const char *err;
+
+ p += len;
+ strcpy(dest, src);
+ if (size < 0)
+ return "malformed plan: size < 0";
+ err = snapshot_copy_file(abs_src, abs_dest, size);
+ if (err) {
+ fprintf(stderr, "#snapshot: %s[%ld] %s\n", src, size,
err);
+ return err;
+ }
+ }
+ if (scanned != EOF) {
+ return "malformed plan";
+ }
+
+ *src = *dest = '\0';
+ fprintf(stderr, "ALL THIS FROM %s TO %s\n", abs_src, abs_dest);
+
+ len = strlen(plan);
+ assert(len == p - plan);
+
+ return NULL;
+}
+
const char *
store_hot_snapshot(const char *dir)
{
buffer *plan_buf = NULL;
stream *plan_stream = NULL;
+ char *final_plan = NULL;
const char *err;
int reenable_logging = 0;
@@ -1849,6 +1964,16 @@ store_hot_snapshot(const char *dir)
goto end;
}
+ if (strlen(dir) >= FILENAME_MAX) {
+ // The path in `dir` may not be normalized and
+ // might contain /../../../blaaaaaaaaaaaaaaaaaaaa/bla/bla
+ // or similar.
+ // We must catch this because we use `char path[FILENAME_MAX]`
+ // all over the place.
+ err = "destdir path too long";
+ goto end;
+ }
+
plan_buf = buffer_create(16 * 1024);
if (!plan_buf) {
err = "buffer_create()";
@@ -1888,7 +2013,14 @@ store_hot_snapshot(const char *dir)
err = snapshot_prepare_target(dir);
if (err)
goto end;
- fprintf(stderr, "%s", buffer_get_buf(plan_buf));
+ final_plan = buffer_get_buf(plan_buf);
+ if (!final_plan) {
+ err = "buffer_get_buf";
+ goto end;
+ }
+ err = snapshot_copy_data(final_plan, dir);
+ if (err)
+ goto end;
fprintf(stderr, "#end execute hot_snapshot %s\n", dir);
end:
@@ -1902,6 +2034,8 @@ end:
close_stream(plan_stream);
if (plan_buf)
buffer_destroy(plan_buf);
+ if (final_plan)
+ free(final_plan);
if (err)
fprintf(stderr, "#abort hot_snapshot: %s\n", err);
return err;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list