void destor_shutdown() { sds stat_file = sdsdup(destor.working_directory); stat_file = sdscat(stat_file, "/destor.stat"); FILE *fp; if ((fp = fopen(stat_file, "w")) == 0) { destor_log(DESTOR_WARNING, "Fatal error, can not open destor.stat!"); exit(1); } fwrite(&destor.chunk_num, 8, 1, fp); fwrite(&destor.stored_chunk_num, 8, 1, fp); fwrite(&destor.data_size, 8, 1, fp); fwrite(&destor.stored_data_size, 8, 1, fp); fwrite(&destor.zero_chunk_num, 8, 1, fp); fwrite(&destor.zero_chunk_size, 8, 1, fp); fwrite(&destor.rewritten_chunk_num, 8, 1, fp); fwrite(&destor.rewritten_chunk_size, 8, 1, fp); fwrite(&destor.index_memory_footprint, 4, 1, fp); fwrite(&destor.live_container_num, 4, 1, fp); fwrite(&destor.backup_retention_time, 4, 1, fp); fwrite(&destor.simulation_level, 4, 1, fp); fclose(fp); sdsfree(stat_file); }
void make_trace(char* path) { init_jcr(path); sds trace_file = sdsnew(path); char *p = trace_file + sdslen(trace_file) - 1; while (*p == '/') --p; *(p + 1) = 0; sdsupdatelen(trace_file); trace_file = sdscat(trace_file, ".trace"); NOTICE("output to %s", trace_file); start_read_phase(); start_chunk_phase(); start_hash_phase(); unsigned char code[41]; FILE *fp = fopen(trace_file, "w"); while (1) { struct chunk *c = sync_queue_pop(hash_queue); if (c == NULL) { break; } if (CHECK_CHUNK(c, CHUNK_FILE_START)) { destor_log(DESTOR_NOTICE, c->data); fprintf(fp, "file start %zd\n", strlen(c->data)); fprintf(fp, "%s\n", c->data); } else if (CHECK_CHUNK(c, CHUNK_FILE_END)) { fprintf(fp, "file end\n"); } else { hash2code(c->fp, code); code[40] = 0; fprintf(fp, "%s %d\n", code, c->size); } free_chunk(c); } fprintf(fp, "stream end"); fclose(fp); }
void load_config() { sds config = sdsempty(); char buf[DESTOR_CONFIGLINE_MAX + 1]; FILE *fp; if ((fp = fopen("destor.config", "r")) == 0) { destor_log(DESTOR_WARNING, "No destor.config file!"); return; } while (fgets(buf, DESTOR_CONFIGLINE_MAX + 1, fp) != NULL) config = sdscat(config, buf); fclose(fp); load_config_from_string(config); sdsfree(config); }
void do_restore(int revision, char *path) { init_recipe_store(); init_container_store(); init_restore_jcr(revision, path); destor_log(DESTOR_NOTICE, "job id: %d", jcr.id); destor_log(DESTOR_NOTICE, "backup path: %s", jcr.bv->path); destor_log(DESTOR_NOTICE, "restore to: %s", jcr.path); restore_chunk_queue = sync_queue_new(100); restore_recipe_queue = sync_queue_new(100); TIMER_DECLARE(1); TIMER_BEGIN(1); puts("==== restore begin ===="); pthread_t recipe_t, read_t; pthread_create(&recipe_t, NULL, read_recipe_thread, NULL); if (destor.restore_cache[0] == RESTORE_CACHE_LRU) { destor_log(DESTOR_NOTICE, "restore cache is LRU"); pthread_create(&read_t, NULL, lru_restore_thread, NULL); } else if (destor.restore_cache[0] == RESTORE_CACHE_OPT) { destor_log(DESTOR_NOTICE, "restore cache is OPT"); pthread_create(&read_t, NULL, optimal_restore_thread, NULL); } else if (destor.restore_cache[0] == RESTORE_CACHE_ASM) { destor_log(DESTOR_NOTICE, "restore cache is ASM"); pthread_create(&read_t, NULL, assembly_restore_thread, NULL); } else { fprintf(stderr, "Invalid restore cache.\n"); exit(1); } write_restore_data(); assert(sync_queue_size(restore_chunk_queue) == 0); assert(sync_queue_size(restore_recipe_queue) == 0); free_backup_version(jcr.bv); TIMER_END(1, jcr.total_time); puts("==== restore end ===="); printf("job id: %d\n", jcr.id); printf("restore path: %s\n", jcr.path); printf("number of files: %d\n", jcr.file_num); printf("number of chunks: %d\n", jcr.chunk_num); printf("total size(B): %ld\n", jcr.data_size); printf("total time(s): %.3f\n", jcr.total_time / 1000000); printf("throughput(MB/s): %.2f\n", jcr.data_size * 1000000 / (1024.0 * 1024 * jcr.total_time)); printf("speed factor: %.2f\n", jcr.data_size / (1024.0 * 1024 * jcr.read_container_num)); printf("read_recipe_time : %.3fs, %.2fMB/s\n", jcr.read_recipe_time / 1000000, jcr.data_size * 1000000 / jcr.read_recipe_time / 1024 / 1024); printf("read_chunk_time : %.3fs, %.2fMB/s\n", jcr.read_chunk_time / 1000000, jcr.data_size * 1000000 / jcr.read_chunk_time / 1024 / 1024); printf("write_chunk_time : %.3fs, %.2fMB/s\n", jcr.write_chunk_time / 1000000, jcr.data_size * 1000000 / jcr.write_chunk_time / 1024 / 1024); char logfile[] = "restore.log"; FILE *fp = fopen(logfile, "a"); /* * job id, * chunk num, * data size, * actually read container number, * speed factor, * throughput */ fprintf(fp, "%d %lld %d %.4f %.4f\n", jcr.id, jcr.data_size, jcr.read_container_num, jcr.data_size / (1024.0 * 1024 * jcr.read_container_num), jcr.data_size * 1000000 / (1024 * 1024 * jcr.total_time)); fclose(fp); close_container_store(); close_recipe_store(); }