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
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to