Changeset: c0776e55e13c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c0776e55e13c Modified Files: sql/storage/store.c Branch: hot-snapshot Log Message:
Snapshots were not being compressed Because the streams library compresses based on the file extension and our temporary files had extension .tmp. diffs (91 lines): diff --git a/sql/storage/store.c b/sql/storage/store.c --- a/sql/storage/store.c +++ b/sql/storage/store.c @@ -2567,13 +2567,50 @@ end: return ret; } +/* Pick a name for the temporary tar file. Make sure it has the same extension + * so as not to confuse the streams library. + * + * This function is not entirely safe as compare to for example mkstemp. + */ +static str pick_tmp_name(str filename) +{ + str name = GDKmalloc(strlen(filename) + 10); + if (name == NULL) { + GDKerror("malloc failed"); + return NULL; + } + strcpy(name, filename); + + // Look for an extension. + // Make sure it's part of the basename + + char *ext = strrchr(name, '.'); + char *sep = strrchr(name, DIR_SEP); + char *slash = strrchr(name, '/'); // on Windows, / and \ both work + if (ext != NULL && sep != NULL && sep > ext) + ext = NULL; + else if (ext != NULL && slash != NULL && slash > ext) + ext = NULL; + + if (ext == NULL) { + return strcat(name, "..tmp"); + } else { + char *tmp = "..tmp."; + size_t tmplen = strlen(tmp); + memmove(ext + tmplen, ext, strlen(ext) + 1); + memmove(ext, tmp, tmplen); + } + + return name; +} + extern lng store_hot_snapshot(str tarfile) { int locked = 0; lng result = 0; - char tmppath[FILENAME_MAX]; - char dirpath[FILENAME_MAX]; + char *tmppath = NULL; + char *dirpath = NULL; int do_remove = 0; int dir_fd = -1; stream *tar_stream = NULL; @@ -2586,7 +2623,10 @@ store_hot_snapshot(str tarfile) goto end; } - snprintf(tmppath, sizeof(tmppath), "%s.tmp", tarfile); + tmppath = pick_tmp_name(tarfile); + if (tmppath == NULL) { + goto end; + } tar_stream = open_wstream(tmppath); if (!tar_stream) { GDKerror("Failed to open %s for writing", tmppath); @@ -2604,7 +2644,12 @@ store_hot_snapshot(str tarfile) // Call realpath(2) to make the path absolute so it has at least // one DIR_SEP in it. Realpath requires the file to exist so // we feed it tmppath rather than tarfile. - if (realpath(tmppath, dirpath) == NULL) { // ERROR no realpath + dirpath = GDKmalloc(PATH_MAX); + if (dirpath == NULL) { + GDKerror("malloc failed"); + goto end; + } + if (realpath(tmppath, dirpath) == NULL) { GDKerror("couldn't resolve path %s: %s", tarfile, strerror(errno)); goto end; } @@ -2682,6 +2727,8 @@ store_hot_snapshot(str tarfile) result = 42; end: + GDKfree(tmppath); + GDKfree(dirpath); if (dir_fd >= 0) close(dir_fd); if (locked) _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list