int main(int argc, char *argv[]) { fsp_link *link; fs_query_state *qs; fs_query *qr; raptor_uri *bu; int i; #ifdef LINUX mtrace(); #endif link = fsp_open_link("ukgov_finances_cra", NULL, FS_OPEN_HINT_RW); raptor_init(); fs_hash_init(fsp_hash_type(link)); bu = raptor_new_uri((unsigned char *)"local:"); fsp_no_op(link, 0); qs = fs_query_init(link); for (i=0;i<atoi(argv[1]);i++) { //printf("--------- %d ----------\n", i); qr = fs_query_execute(qs, link, bu, QUERY, 0, 3, 0); fs_query_free(qr); fs_query_cache_flush(qs, 0); } fs_query_fini(qs); raptor_free_uri(bu); raptor_finish(); fsp_close_link(link); #ifdef LINUX muntrace(); #endif }
EAPI int eina_shutdown(void) { if (_eina_main_count <= 0) { ERR("Init count not greater than 0 in shutdown."); return 0; } _eina_main_count--; if (EINA_UNLIKELY(_eina_main_count == 0)) { _eina_shutdown_from_desc(_eina_desc_setup + _eina_desc_setup_len); #ifdef EINA_HAVE_DEBUG_THREADS pthread_mutex_destroy(&_eina_tracking_lock); #endif #ifdef MT if (_mt_enabled) { muntrace(); _mt_enabled = 0; } #endif } return _eina_main_count; }
extern int log4c_fini(void) { /* Some acceptable use of goto here to avoid lots of nested ifs * when we need a quick exit */ sd_debug("log4c_fini["); if (log4c_rc->config.nocleanup){ sd_debug("not cleaning up--nocleanup specified in conf"); goto log4c_fini_exit; } if (!log4c_is_init){ sd_debug("not cleaning up--log4c not initialized"); goto log4c_fini_exit; } log4c_is_init--; sd_debug("cleaning up category, appender, layout and" "rollingpolicy instances"); if (log4c_category_factory) { sd_factory_delete(log4c_category_factory); log4c_category_factory = NULL; } if (log4c_appender_factory) { sd_factory_delete(log4c_appender_factory); log4c_appender_factory = NULL; } log4c_appender_types_free(); if (log4c_layout_factory) { sd_factory_delete(log4c_layout_factory); log4c_layout_factory = NULL; } log4c_layout_types_free(); #ifdef WITH_ROLLINGFILE if (log4c_rollingpolicy_factory) { sd_factory_delete(log4c_rollingpolicy_factory); log4c_rollingpolicy_factory = NULL; } log4c_rollingpolicy_types_free(); #endif #ifdef __SD_DEBUG__ if( getenv("SD_DEBUG")){ sd_debug("Instance dump after cleanup:"); log4c_dump_all_instances(stderr); } #endif #if defined(__LOG4C_DEBUG__) && defined(__GLIBC__) muntrace(); #endif log4c_fini_exit: sd_debug("]"); return 0; }
int do_test (void) { mtrace (); glob_t gl; memset (&gl, 0, sizeof (gl)); init_glob_altdirfuncs (&gl); if (glob ("dir/*able/*", GLOB_ERR | GLOB_ALTDIRFUNC, NULL, &gl) != GLOB_ABORTED) { puts ("glob did not fail with GLOB_ABORTED"); exit (EXIT_FAILURE); } globfree (&gl); memset (&gl, 0, sizeof (gl)); init_glob_altdirfuncs (&gl); gl.gl_offs = 3; if (glob ("dir2/*", GLOB_DOOFFS, NULL, &gl) != GLOB_NOMATCH) { puts ("glob did not fail with GLOB_NOMATCH"); exit (EXIT_FAILURE); } globfree (&gl); muntrace (); return 0; }
/* 从文件中读取数据,存入数组中 * 文件中的数据是按照每行一个数字存放的 */ int main(int argc, char *argv[]){ setenv("MALLOC_TRACE", "memoryTraceResult.txt", 1);//trace_result是保存检测结果的文件 mtrace(); if(argc < 2){ printf("Usage : %s <filename>\n", argv[0]); exit(EXIT_SUCCESS); } char *filename = argv[1]; FILE *fp; fp = fopen_file(filename, "r"); int data_length = cal_data_length(fp); int *arr = malloc_space(data_length*sizeof(int)); assign_arr(fp, arr); fclose(fp); bucket_sort(arr, data_length); int i; for(i = 0; i < data_length; i++){ printf("%d, ", arr[i]); } printf("\n"); free(arr); muntrace(); return 0; }
int main(int argc, char **argv) { int ret; #if defined(__linux__) char *ev; #endif #ifdef MTRACE mtrace(); /* Turn on mtrace function */ #endif #if defined(__linux__) if ((ev = getenv("CHILLI_PRIORITY")) != NULL) { if (setpriority(PRIO_PROCESS, getpid(), atoi(ev))) { perror("setpriority"); } } #ifdef __NR_ioprio_set if ((ev = getenv("CHILLI_IOPRIO_RT")) != NULL) { if (syscall(__NR_ioprio_set, IOPRIO_WHO_PROCESS, getpid(), atoi(ev) | IOPRIO_CLASS_RT << IOPRIO_CLASS_SHIFT) == -1) { perror("ioprio_set"); } } #endif #endif ret = chilli_main(argc, argv); #ifdef MTRACE muntrace(); /* Turn off mtrace function */ #endif return ret; }
int main(int argc, char **argv) { mtrace(); dbgout("START -> %s\n", *argv); bo_log("TEST"); dbgout("END\n"); muntrace(); return 0; }
/******************************************************************** * * * FUNCTION main * * * *********************************************************************/ int main (int argc, char *argv[]) { status_t res; boolean showver = FALSE; boolean done = FALSE; help_mode_t showhelpmode; #ifdef MEMORY_DEBUG mtrace(); #endif /* this loop is used to implement the restart command the sw image is not * reloaded; instead everything is cleaned up and re-initialized from * scratch. If the shutdown operation (or Ctl-C exit) is used instead of * restart, then the loop will only be executed once */ while (!done) { res = cmn_init( argc, argv, &showver, &showhelpmode ); if (res != NO_ERR) { log_error( "\nnetconfd: init returned (%s)", get_error_string(res) ); agt_request_shutdown(NCX_SHUT_EXIT); } else { if (showver) { show_version(); } else if (showhelpmode != HELP_MODE_NONE) { help_program_module( NETCONFD_MOD, NETCONFD_CLI, showhelpmode ); agt_request_shutdown(NCX_SHUT_EXIT); } else { res = netconfd_run(); if (res != NO_ERR) { agt_request_shutdown(NCX_SHUT_EXIT); } } } netconfd_cleanup(); print_error_count(); if ( NCX_SHUT_EXIT == agt_shutdown_mode_requested() ) { done = TRUE; } } print_errors(); print_error_count(); if ( !log_is_open() ) { printf("\n"); } #ifdef MEMORY_DEBUG muntrace(); #endif return 0; } /* main */
int main(int argc, char** argv) { #ifdef mtrace_active mtrace(); #endif printf("testing arrqueue\n"); // Test bare alloc and del arrqueue* q = new_arrqueue(0,10); del_arrqueue(q,(DEL_STRUCT|DEL_DATA)); //* int i; char* arr[] = {"Articulate","Breathe","Circulate","Diaphragm","Esophagus"}; q = new_arrqueue(arr,5); // Straight-up insertion printf("size before: %i\n", arrqueue_size(q)); for (i=0; i < q->arrsize; ++i) arrqueue_nq(q,arr[i]); for (i=0; i < q->arrsize; ++i) printf("%s ",q->arr[i]); printf("\n"); printf("size after: %i\n", arrqueue_size(q)); // void* a; void* b; int it; char* s; a = arrqueue_dq(q); b = arrqueue_dq(q); iter_arrqueue(q,&it); while (s = iter_arrqueue_next(q,&it)) printf("%s ",s); printf("\n"); arrqueue_nq(q,b); arrqueue_nq(q,a); iter_arrqueue(q,&it); while (s = iter_arrqueue_next(q,&it)) printf("%s ",s); printf("\n"); del_arrqueue(q,0); //*/ #ifdef mtrace_active printf("\nMTRACE OUTPUT:\n"); muntrace(); #endif return 0; }
int main(int argc, char *argv[]) { int total; int n, i, t0, t1, t2, t3; node_t root; if (argc < 2) { printf("Arguments not sufficient, use default values\n"); } else { G_MAX_DEPTH = atoi(argv[1]); if (argc >= 3) G_ITERATION = atoi(argv[2]); if (argc >= 4) G_TRACEITER = atoi(argv[3]); else G_TRACEITER = 0.8 * G_ITERATION; } total = (pow(N_CHILD, G_MAX_DEPTH + 1) - 1) / (N_CHILD - 1); G_NODES_ARR = xmalloc(sizeof(node_t) * total); memset(G_NODES_ARR, 0x0, sizeof(node_t) * total); printf("Depth: %d, Iter: %d (mtrace the %dth), Nodes: %d\n", G_MAX_DEPTH, G_ITERATION, G_TRACEITER, total); root.dep = 0; root.off = 0; root.idx = 0; root.nchild = 0; for (G_ITER = 0; G_ITER < G_ITERATION; G_ITER++) { t0 = curr_time_micro(); if (G_ITER == G_TRACEITER) mtrace(); tree_build(&root); if (G_ITER == G_TRACEITER) muntrace(); t1 = curr_time_micro(); /* for (i = 0; i < total; i++) { node_t *p = G_NODES_ARR + i; printf("%d: %d %d %d %d\n", i, p->dep, p->off, p->idx, p->nchild); } */ n = 0; tree_traversal(&root, &n); if (n != total) printf("Tree check failed! (%d vs. %d)\n", total, n); t2 = curr_time_micro(); tree_free(); t3 = curr_time_micro(); printf("[%02d] Build: %d Traversal: %d Free: %d\n", G_ITER, t1-t0, t2-t1, t3-t2); } return 0; }
int main() { char *ptr1; char *ptr2; mtrace(); ptr1 = (char *)malloc(sizeof(char)); ptr2 = (char *)malloc(sizeof(char)); free(ptr2); muntrace(); gc(); }
/* - Function: void muntrace (void) * The muntrace function can be called after mtrace was used to enable tracing the malloc calls. * If no (successful) call of mtrace was made muntrace does nothing. * Otherwise it deinstalls the handlers for malloc, realloc, and free and then closes the protocol file. * No calls are protocolled anymore and the program runs again at full speed. * Please note that not only the application uses the traced functions, also libraries (including the C library itself) * use these functions. * * It is no good idea to call muntrace before the program terminated. The libraries are informed about * the termination of the program only after the program returns from main or calls exit and so cannot * free the memory they use before this time. * * So the best thing one can do is to call mtrace as the very first function in the program and never call muntrace. * So the program traces almost all uses of the malloc functions (except those calls which are executed by * constructors of the program or used libraries). * * This function is a GNU extension and generally not available on other systems. The prototype can be found in mcheck.h. */ void FC_FUNC_(CLIB_muntrace,CLIB_MUNTRACE) (int* ierr) { #ifdef HAVE_MCHECK_H muntrace(); *ierr=0; #else *ierr=1; #endif }
static void CacheDestroy(ENGINE_HANDLE* handle, const bool force) { sem_wait(readSem); sem_wait(writeSem); ReleaseBitArray(); ReleaseMemoryTable(); ReleaseDataRegion(); free(handle); munlockall(); muntrace(); free(handle); sem_post(readSem); sem_post(writeSem); }
void dockapp_exit( int signal_received ) { #ifdef USE_MTRACE muntrace(); #endif /* USE_MTRACE */ #ifdef DEBUG fprintf( stderr, "%s: Exiting cleanly with signal %d\n", DOCKAPP_NAME, signal_received ); #endif /* DEBUG */ exit( 0 ); }
int main ( int argc, char * * argv ) { int rc = -1; char * psz = NULL; mtrace(); do { psz = strdup("Hello World \n \t "); rtrim(psz); fprintf(stderr, "d: \"%s\"\n", psz); rc = 0; } while (0); if (psz) { free(psz); } muntrace(); return (rc); }
void OnDestroy(AG_Event *event) { // 20120610 GUI関連処理 bEventRunFlag = FALSE; #ifdef _WITH_DEBUGGER Detach_DebugMenu(); #endif /* * サウンド停止 */ StopSnd(); SaveCfg(); AG_ConfigSave(); /* * コンポーネント クリーンアップ */ #ifdef FDDSND CleanFDDSnd(); #endif /* */ CleanSch(); CleanKbd(); CleanSnd(); CleanDraw(); DestroyStatus(); /* * 仮想マシン クリーンアップ */ system_cleanup(); if(pCpuID != NULL) { detachCpuID(pCpuID); pCpuID = NULL; } AG_MutexDestroy(&VMMutex); // AG_Destroy(); #if 0 muntrace(); #endif DiscardTextures(1, &uVramTextureID); DiscardTextures(1, &uNullTextureID); uVramTextureID = 0; XM7_DebugLog(XM7_LOG_INFO, "All resources allocated by VM were freed."); // AG_Destroy(); }
int main(void) { mtrace(); /* Starts the recording of memory allocations and releases */ int* a = NULL; a = malloc(sizeof(int)); /* allocate memory and assign it to the pointer */ if (a == NULL) { return 1; /* error */ } free(a); /* we free the memory we allocated so we don't have leaks */ muntrace(); return 0; /* exit */ }
int main() { char* ptr=NULL; mtrace(); /* mtrace */ if( NULL == (ptr = malloc(sizeof(*ptr))) ){ perror( "Allocation failed!" ); } // free( ptr ); ptr = NULL; muntrace(); /* mtrace */ puts("READY."); return 0; }
int main() { char *hello; setenv("MALLOC_TRACE", "output", 1); mtrace(); if ((hello = (char *) malloc(sizeof(char))) == NULL) { perror("Cannot allocate memory."); return -1; } free(hello); if ((hello = (char *) malloc(sizeof(char))) == NULL) { perror("Cannot allocate memory."); return -1; } muntrace(); return 0; }
void leak_test(void) { bsc_hist_t *H; int i; struct mallinfo mi_start, mi_end; mtrace(); mi_start= mallinfo(); printf("Testing for leaks in bsc_hist_destroy()..."); fflush(stdout); for(i= 0; i < 10; i++) { H= bsc_random(RC_NROWS, RC_NCOLS, RC_NENT, 1); bsc_hist_destroy(H); } printf(" done.\n"); mi_end= mallinfo(); assert(mi_start.uordblks == mi_end.uordblks); muntrace(); }
int main() { mtrace(); char *data1, *data2; int i; do { data1 = malloc (SIZE); printf ("Please input your eos username: "******"%s", data1); if (!strcmp (data1, "quit")) break; data2 = malloc (SIZE); for (i=0; i<SIZE; i++) data2[i] = data1[i]; free (data1); printf ("data2 :%s:\n", data2); free (data2); muntrace(); } while (1); return 0; }
static void _destructor death( void ) { if( is_set ) { static char const msg[] = "$ /usr/bin/mtrace "; size_t const qty = sizeof(msg) - 1; muntrace(); if( write( fileno( stderr ), msg, qty ) != (ssize_t) qty ) { /* Hm */ } if( write( fileno( stderr ), where, strlen(where) ) == -1 ) { /* Hm */ } if( write( fileno( stderr ), "\n", 1 ) == -1 ) { /* Hm */ } abort(); } }
int main(int argc, char **argv) { char * leak = NULL; /* trace starts */ mtrace(); leak = (char*)malloc(10); strcpy(leak,"Data1"); printf("test: %s\n",leak); /* THIS IS LEAK - now we are unable to free first malloc() data ! */ leak = (char*)malloc(10); strcpy(leak,"Data2"); printf("test: %s\n",leak); /* this frees only second allocation */ free(leak); /* trace ends */ muntrace(); return 0; }
// ************************************************************ // main // ************************************************************ int main(int argc,char **argv) { globals_t::command_line_string = dfxml_writer::make_command_line(argc, argv); #ifdef HAVE_MCHECK mtrace(); #endif // manage error condition of no arguments if(argc==1) { usage(); exit(1); } // parse options int option_index; // not used while (1) { const struct option long_options[] = { // basic {"help", no_argument, 0, 'h'}, {"Help", no_argument, 0, 'H'}, {"version", no_argument, 0, 'v'}, {"Version", no_argument, 0, 'V'}, {"quiet", no_argument, 0, 'q'}, // options {"byte_alignment", required_argument, 0, 'a'}, {"hash_truncation", required_argument, 0, 't'}, {"hash_block_size", required_argument, 0, 'p'}, {"max", required_argument, 0, 'm'}, {"repository", required_argument, 0, 'r'}, {"sector_size", required_argument, 0, 's'}, // bloom filter settings {"bloom", required_argument, 0, 'A'}, {"bloom_n", required_argument, 0, 'B'}, {"bloom_kM", required_argument, 0, 'C'}, // end {0,0,0,0} }; int ch = getopt_long(argc, argv, "hHvVqa:t:p:m:r:s:A:B:C:", long_options, &option_index); if (ch == -1) { // no more arguments break; } if (ch == 0) { // command options set flags and use ch==0 continue; } switch (ch) { case 'h': { // help usage(); exit(0); break; } case 'H': { // Help usage(); detailed_usage(); exit(0); break; } case 'v': { // version std::cout << "hashdb " << PACKAGE_VERSION << "\n"; exit(0); break; } case 'V': { // Version std::cout << "hashdb " << PACKAGE_VERSION << "\n"; exit(0); break; } case 'q': { // quiet mode globals_t::quiet_mode = true; break; } case 'a': { // byte alignment has_byte_alignment = true; optional_byte_alignment = std::atoi(optarg); break; } case 't': { // hash truncation has_hash_truncation = true; optional_hash_truncation = std::atoi(optarg); break; } case 'p': { // hash block size has_hash_block_size = true; optional_hash_block_size = std::atoi(optarg); break; } case 'm': { // maximum has_max = true; optional_max = std::atoi(optarg); break; } // repository name option case 'r': { // repository name has_repository_name = true; repository_name_string = std::string(optarg); break; } // sector size option case 's': { // sector size has_sector_size = true; optional_sector_size = std::atoi(optarg); break; } // bloom filter settings case 'A': { // bloom <state> has_bloom = true; bool is_ok_bloom_state = string_to_bloom_state(optarg, bloom_is_used); if (!is_ok_bloom_state) { std::cerr << "Invalid value for bloom filter state: '" << optarg << "'. " << see_usage << "\n"; exit(1); } break; } case 'B': { // bloom_n <n> expected total number of hashes has_bloom_n = true; uint64_t n = std::atol(optarg); bloom_k_hash_functions = 3; bloom_M_hash_size = bloom_filter_manager_t::approximate_n_to_M(n); break; } case 'C': { // bloom_kM <k:M> k hash functions and M hash size has_bloom_kM = true; std::vector<std::string> params = split(std::string(optarg), ':'); if (params.size() == 2) { bloom_k_hash_functions = std::atoi(params[0].c_str()); bloom_M_hash_size = std::atoi(params[1].c_str()); } else { // bad input std::cerr << "Invalid value for bloom filter k:M: '" << optarg << "'. " << see_usage << "\n"; exit(1); } break; } default: // std::cerr << "unexpected command character " << ch << "\n"; exit(1); } } // check that input is compatible uint32_t temp_hash_block_size = (has_hash_block_size) ? optional_hash_block_size : globals_t::default_hash_block_size; uint32_t temp_byte_alignment = (has_byte_alignment) ? optional_byte_alignment : globals_t::default_byte_alignment; // make sure hash block size is valid if (temp_hash_block_size % temp_byte_alignment != 0) { std::cerr << "Incompatible values for hash block size: " << temp_hash_block_size << " and byte alignment: " << temp_byte_alignment << ". hash block size must be divisible by byte alignment.\n" << see_usage << "\n"; exit(1); } // ************************************************************ // parse the command // ************************************************************ // parse the remaining tokens that were not consumed by options argc -= optind; argv += optind; // get the command if (argc < 1) { std::cerr << "Error: a command must be provided.\n"; exit(1); } command = argv[0]; argc--; argv++; // get any arguments parameter_count = argc; hashdb_arg1 = (argc>=1) ? argv[0] : ""; hashdb_arg2 = (argc>=2) ? argv[1] : ""; hashdb_arg3 = (argc>=3) ? argv[2] : ""; // run the command run_command(); #ifdef HAVE_MCHECK muntrace(); #endif // done return 0; }
int main(int argc, char **argv) { int flag; int argerr = 0; const char *xml_file = NULL; crm_data_t *xml_graph = NULL; set_crm_log_level(0); /* crm_log_init("ttest"); */ g_log_set_handler(NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL, cl_glib_msg_handler, NULL); /* and for good measure... - this enum is a bit field (!) */ g_log_set_always_fatal((GLogLevelFlags)0); /*value out of range*/ set_crm_log_level(LOG_WARNING); transition_trigger = G_main_add_TriggerHandler( G_PRIORITY_LOW, te_graph_trigger, NULL, NULL); set_graph_functions(&ttest_graph_fns); while (1) { flag = getopt(argc, argv, OPTARGS); if (flag == -1) break; switch(flag) { case 'X': xml_file = crm_strdup(optarg); break; case 'V': cl_log_enable_stderr(TRUE); alter_debug(DEBUG_INC); break; default: printf("?? getopt returned character code 0%o ??\n", flag); ++argerr; break; } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); } if (optind > argc) { ++argerr; } if (argerr) { crm_err("%d errors in option parsing", argerr); } crm_debug("=#=#=#=#= Getting XML =#=#=#=#="); if(xml_file != NULL) { FILE *xml_strm = fopen(xml_file, "r"); if(xml_strm) { xml_graph = file2xml(xml_strm, FALSE); fclose(xml_strm); } else { cl_perror("Could not open %s for reading", xml_file); xml_file = NULL; } } if(xml_file == NULL) { xml_graph = stdin2xml(); } #ifdef MTRACE mtrace(); #endif transition_graph = unpack_graph(xml_graph); trigger_graph(); print_graph(LOG_DEBUG, transition_graph); transition_graph->completion_action = tg_shutdown; mainloop = g_main_new(FALSE); g_main_run(mainloop); crm_info("Exiting ttest"); #ifdef MTRACE muntrace(); #endif crm_debug_4("Transition complete..."); return 0; }
int main(void) { struct hash_entry *e; int key = 5; char key2 = 'd'; struct dummy d1, d2, d3, d4, d5; mtrace(); d1.i = 1; d1.c = 'a'; strcpy(d1.str, "d1"); d2.i = 2; d2.c = 'b'; strcpy(d2.str, "d2"); d3.i = 3; d3.c = 'c'; strcpy(d3.str, "d3"); d4.i = 4; d4.c = 'd'; strcpy(d4.str, "d4"); d5.i = 5; d5.c = 'e'; strcpy(d5.str, "d5"); /* initialization */ init_hash_table_INT(); init_hash_table_CHR(); init_hash_group(&h, 2, &hash_table_INT, &hash_table_CHR); /* adding entries */ add_entry_hash_group(h, &d1); add_entry_hash_group(h, &d2); add_entry_hash_group(h, &d3); add_entry_hash_group(h, &d4); add_entry_hash_group(h, &d5); print_hash_group(h, print_dummy); /* lookup */ e = lookup_hash_group_INT(h, &key); printf("\n+++\n"); print_dummy(e->data); printf("\n---\n"); /* delete entry */ del_entry_hash_group(h, e); print_hash_group(h, print_dummy); /* lookup */ e = lookup_hash_group_CHR(h, &key2); printf("\n§§§\n"); print_dummy(e->data); printf("\n$$$\n"); /* delete entry */ del_entry_hash_group(h, e); print_hash_group(h, print_dummy); /* clean up the whole crap */ cleanup_hash_group(h, NULL); muntrace(); return 0; }
int main () { int i = 0; int res = 0; char *pres = NULL; hashtab_node * node = NULL; struct test_node *p = NULL; hashtab *h = NULL; #ifdef MEMORY_TEST setenv("MALLOC_TRACE","1.txt",1); mtrace(); #endif h = hashtab_create(5,hashtab_hvalue,hashtab_keycmp,hashtab_node_free); assert(h!= NULL); while(1) { p = (struct test_node*)malloc(sizeof(struct test_node)); assert(p != NULL); printf("\r\n 请输入key 和value,当可以等于\"quit\"时退出"); scanf("%s",p->key); scanf("%s",p->data); if(strcmp(p->key,"quit") == 0) { free(p); break; } res = hashtab_insert(h,p->key,p->data); if (res != 0) { free(p); printf("\r\n key[%s],data[%s] insert failed %d",p->key,p->data,res); } else { printf("\r\n key[%s],data[%s] insert success %d",p->key,p->data,res); } } hashtab_dump(h); while(1) { p = (struct test_node*)malloc(sizeof(struct test_node)); assert(p != NULL); printf("\r\n 请输入key 查询value的数值,当可以等于\"quit\"时退出"); scanf("%s",p->key); if(strcmp(p->key,"quit") == 0) { free(p); break; } pres = hashtab_search(h,p->key); if (pres == NULL) { printf("\r\n key[%s] search data failed",p->key); } else { printf("\r\n key[%s],search data[%s] success",p->key,pres); } free(p); } hashtab_dump(h); while(1) { p = (struct test_node*)malloc(sizeof(struct test_node)); assert(p != NULL); printf("\r\n 请输入key 删除节点的数值,当可以等于\"quit\"时退出"); scanf("%s",p->key); if(strcmp(p->key,"quit") == 0) { free(p); break; } node = hashtab_delete(h,p->key); if (node == NULL) { printf("\r\n key[%s] delete node failed ",p->key); } else { printf("\r\n key[%s],delete data[%s] success",node->key,node->data); h->hash_node_free(node); } free(p); hashtab_dump(h); } hashtab_destory(h); #ifdef MEMORY_TEST muntrace(); #endif return 0; }
int main() { MUT_CLASS(interval)* o1,*o2, *o3; MUT_CLASS(intervalSum)* s1,*s2,*s3; char * c1,*c2,*c3; #ifdef HAVE_MCHECK_H mtrace(); #endif fprintf(stderr,"o1\n"); o1=MUT_NEW(interval); assert(o1); fprintf(stderr,"o1->copy_name\n"); MUTABOR_CLASS_FUNCTION(interval,copy_name) (o1, "id1"); fprintf(stderr,"o1->set_factor\n"); MUTABOR_CLASS_FUNCTION(interval,set_factor) (o1, 3.0); fprintf(stderr,"o2\n"); o2 = MUT_NEW(intervalStretch); assert(o2); fprintf(stderr,"o2->copy_name\n"); MUTABOR_CLASS_FUNCTION(identifier,copy_name)(o2,"Id2"); fprintf(stderr,"o2->setstretch\n"); MUTABOR_CLASS_FUNCTION(intervalStretch,setstretch)(o2,2.9); MUTABOR_CLASS_FUNCTION(intervalStretch,setright)(o2,o1); fprintf(stderr,"o3\n"); o3 = MUT_NEW(intervalStretch); assert(o3); fprintf(stderr,"o3->copy_name\n"); MUTABOR_CLASS_FUNCTION(identifier,copy_name)(o3,"Id2"); fprintf(stderr,"o3->setright\n"); MUTABOR_CLASS_FUNCTION(intervalStretch,setright)(o3,o2); printf("%s\n%s\n%s\n",c1=MUT_VIRTCALL(identifier,o1,tostring)(o1), c2=MUT_VIRTCALL(object,o2,tostring)(o2), c3=MUT_VIRTCALL(object,o3,tostring)(o3)); free(c1);free(c2);free(c3); fprintf(stderr,"Compare: %d\n",(*(MUT_VIRTTABLE(object)**) o1)->compare(o1,o2)); s1 = MUT_NEW(intervalSum); MUTABOR_CLASS_FUNCTION(identifier,copy_name)(s1,"Summe 1"); printf("%s\n",c1=MUT_VIRTCALL(identifier,s1,tostring)(s1)); free(c1); MUTABOR_CLASS_FUNCTION(intervalSum,setleft)(s1,o1); MUTABOR_CLASS_FUNCTION(intervalSum,setright)(s1,o2); printf("%s\n",c1=MUT_VIRTCALL(identifier,s1,tostring)(s1)); free(c1); s2 = MUT_NEW(intervalSum); MUTABOR_CLASS_FUNCTION (identifier, copy_name) (s2, "Summe 2"); printf ("%s\n",c1=MUT_VIRTCALL(identifier, s2, tostring) (s2)); free(c1); MUTABOR_CLASS_FUNCTION (intervalSum, setleft) (s2, s1); MUTABOR_CLASS_FUNCTION (intervalSum, setright) (s2, o2); printf ("%s\n",c1= MUT_VIRTCALL (identifier, s2, tostring) (s2)); free(c1); s3=MUT_NEW(intervalDiff); MUTABOR_CLASS_FUNCTION(identifier,copy_name)(s3,"Differenz"); printf("%s\n",c1=MUT_VIRTCALL(identifier,s3,tostring)(s3)); free(c1); MUTABOR_CLASS_FUNCTION(intervalSum,setright)(s3,s1); MUTABOR_CLASS_FUNCTION(intervalSum,setleft)(s3,s2); printf("%s\n",c1=MUT_VIRTCALL(identifier,s3,tostring)(s3)); free(c1); fprintf(stderr,"Deleting s1...\n"); mutabor_delete(s1); fprintf(stderr,"Deleting s2...\n"); mutabor_delete(s2); fprintf(stderr,"Deleting s3...\n"); mutabor_delete(s3); fprintf(stderr,"Deleting o1...\n"); mutabor_delete(o1); fprintf(stderr,"Deleting o2...\n"); mutabor_delete(o2); #ifdef HAVE_MCHECK_H muntrace(); #endif return 0; }
int main(int argc, const char ** argv) /*@globals pass2, fileSystem, internalState @*/ /*@modifies pass2, fileSystem, internalState @*/ { int rc; int ec = 0; poptContext optCon; const char ** rest; int help = 0; int usage = 0; #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE) /*@-moduncon -noeffectuncon@*/ mtrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */ /*@=moduncon =noeffectuncon@*/ #endif /*@-modobserver@*/ resetVars(); /*@=modobserver@*/ /*@-temptrans@*/ optCon = poptGetContext("test1", argc, argv, options, 0); /*@=temptrans@*/ (void) poptReadConfigFile(optCon, "./test-poptrc"); #if 1 while ((rc = poptGetNextOpt(optCon)) > 0) /* Read all the options ... */ {}; poptResetContext(optCon); /* ... and then start over. */ /*@-modobserver@*/ resetVars(); /*@=modobserver@*/ #endif pass2 = 1; if ((rc = poptGetNextOpt(optCon)) < -1) { fprintf(stderr, "test1: bad argument %s: %s\n", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); ec = 2; goto exit; } if (help) { poptPrintHelp(optCon, stdout, 0); goto exit; } if (usage) { poptPrintUsage(optCon, stdout, 0); goto exit; } fprintf(stdout, "arg1: %d arg2: %s", arg1, arg2); if (arg3) fprintf(stdout, " arg3: %d", arg3); if (inc) fprintf(stdout, " inc: %d", inc); if (shortopt) fprintf(stdout, " short: %d", shortopt); if (aVal != bVal) fprintf(stdout, " aVal: %d", aVal); if (aFlag != bFlag) fprintf(stdout, " aFlag: %d", aFlag); if (aInt != bInt) fprintf(stdout, " aInt: %d", aInt); if (aLong != bLong) fprintf(stdout, " aLong: %ld", aLong); /*@-realcompare@*/ if (aFloat != bFloat) fprintf(stdout, " aFloat: %g", (double)aFloat); if (aDouble != bDouble) fprintf(stdout, " aDouble: %g", aDouble); /*@=realcompare@*/ if (oStr != (char *)-1) fprintf(stdout, " oStr: %s", (oStr ? oStr : "(none)")); if (singleDash) fprintf(stdout, " -"); rest = poptGetArgs(optCon); if (rest) { fprintf(stdout, " rest:"); while (*rest) { fprintf(stdout, " %s", *rest); rest++; } } fprintf(stdout, "\n"); exit: optCon = poptFreeContext(optCon); #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE) /*@-moduncon -noeffectuncon@*/ muntrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */ /*@=moduncon =noeffectuncon@*/ #endif return ec; }
/** * main function - for clone or restore data */ int main(int argc, char **argv) { #ifdef MEMTRACE setenv("MALLOC_TRACE", "partclone_mtrace.log", 1); mtrace(); #endif char* source; /// source data char* target; /// target data int dfr, dfw; /// file descriptor for source and target int r_size, w_size; /// read and write size unsigned cs_size = 0; /// checksum_size int cs_reseed = 1; int start, stop; /// start, range, stop number for progress bar unsigned long *bitmap = NULL; /// the point for bitmap data int debug = 0; /// debug level int tui = 0; /// text user interface int pui = 0; /// progress mode(default text) int flag; int pres = 0; pthread_t prog_thread; void *p_result; static const char *const bad_sectors_warning_msg = "*************************************************************************\n" "* WARNING: The disk has bad sectors. This means physical damage on the *\n" "* disk surface caused by deterioration, manufacturing faults, or *\n" "* another reason. The reliability of the disk may remain stable or *\n" "* degrade quickly. Use the --rescue option to efficiently save as much *\n" "* data as possible! *\n" "*************************************************************************\n"; file_system_info fs_info; /// description of the file system image_options img_opt; init_fs_info(&fs_info); init_image_options(&img_opt); /** * get option and assign to opt structure * check parameter and read from argv */ parse_options(argc, argv, &opt); /** * if "-d / --debug" given * open debug file in "/var/log/partclone.log" for log message */ memset(&fs_opt, 0, sizeof(fs_cmd_opt)); debug = opt.debug; fs_opt.debug = debug; fs_opt.ignore_fschk = opt.ignore_fschk; //if(opt.debug) open_log(opt.logfile); /** * using Text User Interface */ if (opt.ncurses) { pui = NCURSES; log_mesg(1, 0, 0, debug, "Using Ncurses User Interface mode.\n"); } else pui = TEXT; tui = open_pui(pui, opt.fresh); if ((opt.ncurses) && (!tui)) { opt.ncurses = 0; pui = TEXT; log_mesg(1, 0, 0, debug, "Open Ncurses User Interface Error.\n"); } /// print partclone info print_partclone_info(opt); #ifndef CHKIMG if (geteuid() != 0) log_mesg(0, 1, 1, debug, "You are not logged as root. You may have \"access denied\" errors when working.\n"); else log_mesg(1, 0, 0, debug, "UID is root.\n"); #endif /// ignore crc check if (opt.ignore_crc) log_mesg(1, 0, 1, debug, "Ignore CRC errors\n"); /** * open source and target * clone mode, source is device and target is image file/stdout * restore mode, source is image file/stdin and target is device * dd mode, source is device and target is device !!not complete */ source = opt.source; target = opt.target; log_mesg(1, 0, 0, debug, "source=%s, target=%s \n", source, target); dfr = open_source(source, &opt); if (dfr == -1) { log_mesg(0, 1, 1, debug, "Error exit\n"); } #ifndef CHKIMG dfw = open_target(target, &opt); if (dfw == -1) { log_mesg(0, 1, 1, debug, "Error exit\n"); } #else dfw = -1; #endif /** * get partition information like super block, bitmap from device or image file. */ if (opt.clone) { log_mesg(1, 0, 0, debug, "Initiate image options - version %s\n", IMAGE_VERSION_CURRENT); img_opt.checksum_mode = opt.checksum_mode; img_opt.checksum_size = get_checksum_size(opt.checksum_mode, opt.debug); img_opt.blocks_per_checksum = opt.blocks_per_checksum; img_opt.reseed_checksum = opt.reseed_checksum; cs_size = img_opt.checksum_size; cs_reseed = img_opt.reseed_checksum; log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n"); log_mesg(0, 0, 1, debug, "Reading Super Block\n"); /// get Super Block information from partition read_super_blocks(source, &fs_info); if (img_opt.checksum_mode != CSM_NONE && img_opt.blocks_per_checksum == 0) { const unsigned int buffer_capacity = opt.buffer_size > fs_info.block_size ? opt.buffer_size / fs_info.block_size : 1; // in blocks img_opt.blocks_per_checksum = buffer_capacity; } log_mesg(1, 0, 0, debug, "%u blocks per checksum\n", img_opt.blocks_per_checksum); check_mem_size(fs_info, img_opt, opt); /// alloc a memory to store bitmap bitmap = pc_alloc_bitmap(fs_info.totalblock); if (bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from partition log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... \n"); read_bitmap(source, fs_info, bitmap, pui); update_used_blocks_count(&fs_info, bitmap); if (opt.check) { unsigned long long needed_space = 0; needed_space += sizeof(image_head) + sizeof(file_system_info) + sizeof(image_options); needed_space += get_bitmap_size_on_disk(&fs_info, &img_opt, &opt); needed_space += cnv_blocks_to_bytes(0, fs_info.usedblocks, fs_info.block_size, &img_opt); check_free_space(&dfw, needed_space); } log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Writing super block and bitmap...\n"); write_image_desc(&dfw, fs_info, img_opt, &opt); write_image_bitmap(&dfw, fs_info, img_opt, bitmap, &opt); log_mesg(0, 0, 1, debug, "done!\n"); } else if (opt.restore) { image_head_v2 img_head; log_mesg(1, 0, 0, debug, "restore image hdr - get information from image file\n"); log_mesg(1, 0, 1, debug, "Reading Super Block\n"); /// get image information from image file load_image_desc(&dfr, &opt, &img_head, &fs_info, &img_opt); cs_size = img_opt.checksum_size; cs_reseed = img_opt.reseed_checksum; check_mem_size(fs_info, img_opt, opt); /// alloc a memory to restore bitmap bitmap = pc_alloc_bitmap(fs_info.totalblock); if (bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from image file log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait...\n"); load_image_bitmap(&dfr, opt, fs_info, img_opt, bitmap); #ifndef CHKIMG /// check the dest partition size. if (opt.restore_raw_file) check_free_space(&dfw, fs_info.device_size); else if (opt.check) check_size(&dfw, fs_info.device_size); #endif log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); } else if (opt.dd || opt.domain) { log_mesg(1, 0, 0, debug, "Initiate image options - version %s\n", IMAGE_VERSION_CURRENT); img_opt.checksum_mode = opt.checksum_mode; img_opt.checksum_size = get_checksum_size(opt.checksum_mode, opt.debug); img_opt.blocks_per_checksum = opt.blocks_per_checksum; img_opt.reseed_checksum = opt.reseed_checksum; log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n"); log_mesg(1, 0, 1, debug, "Reading Super Block\n"); /// get Super Block information from partition read_super_blocks(source, &fs_info); check_mem_size(fs_info, img_opt, opt); /// alloc a memory to restore bitmap bitmap = pc_alloc_bitmap(fs_info.totalblock); if (bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from partition log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... "); read_bitmap(source, fs_info, bitmap, pui); /// check the dest partition size. if (opt.dd && opt.check) { check_size(&dfw, fs_info.device_size); } log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); } else if (opt.ddd){ if (dfr != 0) read_super_blocks(source, &fs_info); else read_super_blocks(target, &fs_info); img_opt.checksum_mode = opt.checksum_mode; img_opt.checksum_size = get_checksum_size(opt.checksum_mode, opt.debug); img_opt.blocks_per_checksum = opt.blocks_per_checksum; check_mem_size(fs_info, img_opt, opt); /// alloc a memory to restore bitmap bitmap = pc_alloc_bitmap(fs_info.totalblock); if (bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from partition log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... "); read_bitmap(source, fs_info, bitmap, pui); /// check the dest partition size. if (opt.check) { struct stat target_stat; if ((stat(opt.target, &target_stat) != -1) && (strcmp(opt.target, "-") != 0)) { if (S_ISBLK(target_stat.st_mode)) check_size(&dfw, fs_info.device_size); else { unsigned long long needed_space = 0; needed_space += sizeof(image_head) + sizeof(file_system_info) + sizeof(image_options); needed_space += get_bitmap_size_on_disk(&fs_info, &img_opt, &opt); needed_space += cnv_blocks_to_bytes(0, fs_info.usedblocks, fs_info.block_size, &img_opt); check_free_space(&dfw, needed_space); } } } log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); } log_mesg(1, 0, 0, debug, "print image information\n"); /// print option to log file if (debug) print_opt(opt); print_file_system_info(fs_info, opt); /** * initial progress bar */ start = 0; /// start number of progress bar stop = (fs_info.usedblocks); /// get the end of progress number, only used block log_mesg(1, 0, 0, debug, "Initial Progress bar\n"); /// Initial progress bar if (opt.no_block_detail) flag = NO_BLOCK_DETAIL; else flag = IO; progress_init(&prog, start, stop, fs_info.totalblock, flag, fs_info.block_size); copied = 0; /// initial number is 0 /** * thread to print progress */ pres = pthread_create(&prog_thread, NULL, thread_update_pui, NULL); if(pres) log_mesg(0, 1, 1, debug, "%s, %i, thread create error\n", __func__, __LINE__); /** * start read and write data between source and destination */ if (opt.clone) { const unsigned long long blocks_total = fs_info.totalblock; const unsigned int block_size = fs_info.block_size; const unsigned int buffer_capacity = opt.buffer_size > block_size ? opt.buffer_size / block_size : 1; // in blocks unsigned char checksum[cs_size]; unsigned int blocks_in_cs, blocks_per_cs, write_size; char *read_buffer, *write_buffer; blocks_per_cs = img_opt.blocks_per_checksum; log_mesg(1, 0, 0, debug, "#\nBuffer capacity = %u, Blocks per cs = %u\n#\n", buffer_capacity, blocks_per_cs); write_size = cnv_blocks_to_bytes(0, buffer_capacity, block_size, &img_opt); read_buffer = (char*)malloc(buffer_capacity * block_size); write_buffer = (char*)malloc(write_size + cs_size); if (read_buffer == NULL || write_buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } /// read data from the first block if (lseek(dfr, 0, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "source seek ERROR:%s\n", strerror(errno)); log_mesg(0, 0, 0, debug, "Total block %llu\n", blocks_total); /// start clone partition to image file log_mesg(1, 0, 0, debug, "start backup data...\n"); blocks_in_cs = 0; init_checksum(img_opt.checksum_mode, checksum, debug); block_id = 0; do { /// scan bitmap unsigned long long i, blocks_skip, blocks_read; unsigned int cs_added = 0, write_offset = 0; off_t offset; /// skip unused blocks for (blocks_skip = 0; block_id + blocks_skip < blocks_total && !pc_test_bit(block_id + blocks_skip, bitmap); blocks_skip++); if (block_id + blocks_skip == blocks_total) break; if (blocks_skip) block_id += blocks_skip; /// read blocks for (blocks_read = 0; block_id + blocks_read < blocks_total && blocks_read < buffer_capacity && pc_test_bit(block_id + blocks_read, bitmap); ++blocks_read); if (!blocks_read) break; offset = (off_t)(block_id * block_size); if (lseek(dfr, offset, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "source seek ERROR:%s\n", strerror(errno)); r_size = read_all(&dfr, read_buffer, blocks_read * block_size, &opt); if (r_size != (int)(blocks_read * block_size)) { if ((r_size == -1) && (errno == EIO)) { if (opt.rescue) { memset(read_buffer, 0, blocks_read * block_size); for (r_size = 0; r_size < blocks_read * block_size; r_size += PART_SECTOR_SIZE) rescue_sector(&dfr, offset + r_size, read_buffer + r_size, &opt); } else log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg); } else log_mesg(0, 1, 1, debug, "read error: %s\n", strerror(errno)); } /// calculate checksum log_mesg(2, 0, 0, debug, "blocks_read = %i\n", blocks_read); for (i = 0; i < blocks_read; ++i) { memcpy(write_buffer + write_offset, read_buffer + i * block_size, block_size); write_offset += block_size; update_checksum(checksum, read_buffer + i * block_size, block_size); if (blocks_per_cs > 0 && ++blocks_in_cs == blocks_per_cs) { log_mesg(3, 0, 0, debug, "CRC = %x%x%x%x \n", checksum[0], checksum[1], checksum[2], checksum[3]); memcpy(write_buffer + write_offset, checksum, cs_size); ++cs_added; write_offset += cs_size; blocks_in_cs = 0; if (cs_reseed) init_checksum(img_opt.checksum_mode, checksum, debug); } } /// write buffer to target w_size = write_all(&dfw, write_buffer, write_offset, &opt); if (w_size != write_offset) log_mesg(0, 1, 1, debug, "image write ERROR:%s\n", strerror(errno)); /// count copied block copied += blocks_read; log_mesg(2, 0, 0, debug, "copied = %lld\n", copied); /// next block block_id += blocks_read; /// read or write error if (r_size + cs_added * cs_size != w_size) log_mesg(0, 1, 1, debug, "read(%i) and write(%i) different\n", r_size, w_size); } while (1); if (blocks_in_cs > 0) { // Write the checksum for the latest blocks log_mesg(1, 0, 0, debug, "Write the checksum for the latest blocks. size = %i\n", cs_size); log_mesg(3, 0, 0, debug, "CRC = %x%x%x%x \n", checksum[0], checksum[1], checksum[2], checksum[3]); w_size = write_all(&dfw, (char*)checksum, cs_size, &opt); if (w_size != cs_size) log_mesg(0, 1, 1, debug, "image write ERROR:%s\n", strerror(errno)); } free(write_buffer); free(read_buffer); // check only the size when the image does not contains checksums and does not // comes from a pipe } else if (opt.chkimg && img_opt.checksum_mode == CSM_NONE && strcmp(opt.source, "-") != 0) { unsigned long long total_offset = (fs_info.usedblocks - 1) * fs_info.block_size; char last_block[fs_info.block_size]; off_t partial_offset = INT32_MAX; while (total_offset) { if (partial_offset > total_offset) partial_offset = total_offset; if (lseek(dfr, partial_offset, SEEK_CUR) == (off_t)-1) log_mesg(0, 1, 1, debug, "source seek ERROR: %s\n", strerror(errno)); total_offset -= partial_offset; } if (read_all(&dfr, last_block, fs_info.block_size, &opt) != fs_info.block_size) log_mesg(0, 1, 1, debug, "ERROR: source image too short\n"); } else if (opt.restore) { const unsigned long long blocks_total = fs_info.totalblock; const unsigned int block_size = fs_info.block_size; const unsigned int buffer_capacity = opt.buffer_size > block_size ? opt.buffer_size / block_size : 1; // in blocks const unsigned int blocks_per_cs = img_opt.blocks_per_checksum; unsigned long long blocks_used = fs_info.usedblocks; unsigned int blocks_in_cs, buffer_size, read_offset; unsigned char checksum[cs_size]; char *read_buffer, *write_buffer; unsigned long long blocks_used_fix = 0, test_block = 0; log_mesg(1, 0, 0, debug, "#\nBuffer capacity = %u, Blocks per cs = %u\n#\n", buffer_capacity, blocks_per_cs); // fix some super block record incorrect for (test_block = 0; test_block < blocks_total; ++test_block) if (pc_test_bit(test_block, bitmap)) blocks_used_fix++; if (blocks_used_fix != blocks_used) { blocks_used = blocks_used_fix; log_mesg(1, 0, 0, debug, "info: fixed used blocks count\n"); } buffer_size = cnv_blocks_to_bytes(0, buffer_capacity, block_size, &img_opt); if (img_opt.image_version != 0x0001) read_buffer = (char*)malloc(buffer_size); else { // Allocate more memory in case the image is affected by the 64 bits bug read_buffer = (char*)malloc(buffer_size + buffer_capacity * cs_size); } write_buffer = (char*)malloc(buffer_capacity * block_size); if (read_buffer == NULL || write_buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } #ifndef CHKIMG /// seek to the first if (lseek(dfw, opt.offset, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", strerror(errno)); #endif /// start restore image file to partition log_mesg(1, 0, 0, debug, "start restore data...\n"); blocks_in_cs = 0; if (!opt.ignore_crc) init_checksum(img_opt.checksum_mode, checksum, debug); block_id = 0; do { unsigned int i; unsigned long long blocks_written, bytes_skip; unsigned int read_size; // max chunk to read using one read(2) syscall int blocks_read = copied + buffer_capacity < blocks_used ? buffer_capacity : blocks_used - copied; if (!blocks_read) break; log_mesg(1, 0, 0, debug, "blocks_read = %d and copied = %lld\n", blocks_read, copied); read_size = cnv_blocks_to_bytes(copied, blocks_read, block_size, &img_opt); // increase read_size to make room for the oversized checksum if (blocks_per_cs && blocks_read < buffer_capacity && (blocks_read % blocks_per_cs) && (blocks_used % blocks_per_cs)) { /// it is the last read and there is a partial chunk at the end log_mesg(1, 0, 0, debug, "# PARTIAL CHUNK\n"); read_size += cs_size; } // read chunk from image log_mesg(1, 0, 0, debug, "read more: "); r_size = read_all(&dfr, read_buffer, read_size, &opt); if (r_size != read_size) log_mesg(0, 1, 1, debug, "read ERROR:%s\n", strerror(errno)); // read buffer is the follows: // <blocks_per_cs><cs1><blocks_per_cs><cs2>... // write buffer should be the following: // <block1><block2>... read_offset = 0; for (i = 0; i < blocks_read; ++i) { memcpy(write_buffer + i * block_size, read_buffer + read_offset, block_size); if (opt.ignore_crc) { read_offset += block_size; if (++blocks_in_cs == blocks_per_cs) read_offset += cs_size; continue; } update_checksum(checksum, read_buffer + read_offset, block_size); if (++blocks_in_cs == blocks_per_cs) { unsigned char checksum_orig[cs_size]; memcpy(checksum_orig, read_buffer + read_offset + block_size, cs_size); log_mesg(3, 0, 0, debug, "CRC = %x%x%x%x \n", checksum[0], checksum[1], checksum[2], checksum[3]); log_mesg(3, 0, 0, debug, "CRC.orig = %x%x%x%x \n", checksum_orig[0], checksum_orig[1], checksum_orig[2], checksum_orig[3]); if (memcmp(read_buffer + read_offset + block_size, checksum, cs_size)) { log_mesg(0, 1, 1, debug, "CRC error, block_id=%llu...\n ", block_id + i); } read_offset += cs_size; blocks_in_cs = 0; if (cs_reseed) init_checksum(img_opt.checksum_mode, checksum, debug); } read_offset += block_size; } if (blocks_in_cs && blocks_per_cs && blocks_read < buffer_capacity && (blocks_read % blocks_per_cs)) { log_mesg(1, 0, 0, debug, "check latest chunk's checksum covering %u blocks\n", blocks_in_cs); if (memcmp(read_buffer + read_offset, checksum, cs_size)){ unsigned char checksum_orig[cs_size]; memcpy(checksum_orig, read_buffer + read_offset, cs_size); log_mesg(1, 0, 0, debug, "CRC = %x%x%x%x \n", checksum[0], checksum[1], checksum[2], checksum[3]); log_mesg(1, 0, 0, debug, "CRC.orig = %x%x%x%x \n", checksum_orig[0], checksum_orig[1], checksum_orig[2], checksum_orig[3]); log_mesg(0, 1, 1, debug, "CRC error, block_id=%llu...\n ", block_id + i); } } blocks_written = 0; do { int blocks_write; /// count bytes to skip for (bytes_skip = 0; block_id < blocks_total && !pc_test_bit(block_id, bitmap); block_id++, bytes_skip += block_size); #ifndef CHKIMG /// skip empty blocks if (bytes_skip > 0 && lseek(dfw, (off_t)bytes_skip, SEEK_CUR) == (off_t)-1) log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", strerror(errno)); #endif /// blocks to write for (blocks_write = 0; block_id + blocks_write < blocks_total && blocks_written + blocks_write < blocks_read && pc_test_bit(block_id + blocks_write, bitmap); blocks_write++); #ifndef CHKIMG // write blocks if (blocks_write > 0) { w_size = write_all(&dfw, write_buffer + blocks_written * block_size, blocks_write * block_size, &opt); if (w_size != blocks_write * block_size) { if (!opt.skip_write_error) log_mesg(0, 1, 1, debug, "write block %llu ERROR:%s\n", block_id + blocks_written, strerror(errno)); else log_mesg(0, 0, 1, debug, "skip write block %llu error:%s\n", block_id + blocks_written, strerror(errno)); } } #endif blocks_written += blocks_write; block_id += blocks_write; copied += blocks_write; } while (blocks_written < blocks_read); } while(1); free(write_buffer); free(read_buffer); #ifndef CHKIMG /// restore_raw_file option if (opt.restore_raw_file && !pc_test_bit(blocks_total - 1, bitmap)) { if (ftruncate(dfw, (off_t)(blocks_total * block_size)) == -1) log_mesg(0, 0, 1, debug, "ftruncate ERROR:%s\n", strerror(errno)); } #endif } else if (opt.dd) { char *buffer; int block_size = fs_info.block_size; unsigned long long blocks_total = fs_info.totalblock; int buffer_capacity = block_size < opt.buffer_size ? opt.buffer_size / block_size : 1; buffer = (char*)malloc(buffer_capacity * block_size); if (buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } block_id = 0; if (lseek(dfr, 0, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "source seek ERROR:%d\n", strerror(errno)); log_mesg(0, 0, 0, debug, "Total block %llu\n", blocks_total); /// start clone partition to partition log_mesg(1, 0, 0, debug, "start backup data device-to-device...\n"); do { /// scan bitmap unsigned long long blocks_skip, blocks_read; off_t offset; /// skip unused blocks for (blocks_skip = 0; block_id + blocks_skip < blocks_total && !pc_test_bit(block_id + blocks_skip, bitmap); blocks_skip++); if (block_id + blocks_skip == blocks_total) break; if (blocks_skip) block_id += blocks_skip; /// read chunk from source for (blocks_read = 0; block_id + blocks_read < blocks_total && blocks_read < buffer_capacity && pc_test_bit(block_id + blocks_read, bitmap); ++blocks_read); if (!blocks_read) break; offset = (off_t)(block_id * block_size); if (lseek(dfr, offset, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "source seek ERROR:%s\n", strerror(errno)); if (lseek(dfw, offset + opt.offset, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", strerror(errno)); r_size = read_all(&dfr, buffer, blocks_read * block_size, &opt); if (r_size != (int)(blocks_read * block_size)) { if ((r_size == -1) && (errno == EIO)) { if (opt.rescue) { memset(buffer, 0, blocks_read * block_size); for (r_size = 0; r_size < blocks_read * block_size; r_size += PART_SECTOR_SIZE) rescue_sector(&dfr, offset + r_size, buffer + r_size, &opt); } else log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg); } else log_mesg(0, 1, 1, debug, "source read ERROR %s\n", strerror(errno)); } /// write buffer to target w_size = write_all(&dfw, buffer, blocks_read * block_size, &opt); if (w_size != (int)(blocks_read * block_size)) { if (opt.skip_write_error) log_mesg(0, 0, 1, debug, "skip write block %lli error:%s\n", block_id, strerror(errno)); else log_mesg(0, 1, 1, debug, "write block %lli ERROR:%s\n", block_id, strerror(errno)); } /// count copied block copied += blocks_read; /// next block block_id += blocks_read; /// read or write error if (r_size != w_size) { if (opt.skip_write_error) log_mesg(0, 0, 1, debug, "read and write different\n"); else log_mesg(0, 1, 1, debug, "read and write different\n"); } } while (1); free(buffer); /// restore_raw_file option if (opt.restore_raw_file && !pc_test_bit(blocks_total - 1, bitmap)) { if (ftruncate(dfw, (off_t)(blocks_total * block_size)) == -1) log_mesg(0, 0, 1, debug, "ftruncate ERROR:%s\n", strerror(errno)); } } else if (opt.domain) { int cmp, nx_current = 0; unsigned long long next_block_id = 0; log_mesg(0, 0, 0, debug, "Total block %i\n", fs_info.totalblock); log_mesg(1, 0, 0, debug, "start writing domain log...\n"); // write domain log comment and status line dprintf(dfw, "# Domain logfile created by %s v%s\n", get_exec_name(), VERSION); dprintf(dfw, "# Source: %s\n", opt.source); dprintf(dfw, "# Offset: 0x%08llX\n", opt.offset_domain); dprintf(dfw, "# current_pos current_status\n"); dprintf(dfw, "0x%08llX ?\n", opt.offset_domain + (fs_info.totalblock * fs_info.block_size)); dprintf(dfw, "# pos size status\n"); // start logging the used/unused areas cmp = pc_test_bit(0, bitmap); for (block_id = 0; block_id <= fs_info.totalblock; block_id++) { if (block_id < fs_info.totalblock) { nx_current = pc_test_bit(block_id, bitmap); if (nx_current) copied++; } else nx_current = -1; if (nx_current != cmp) { dprintf(dfw, "0x%08llX 0x%08llX %c\n", opt.offset_domain + (next_block_id * fs_info.block_size), (block_id - next_block_id) * fs_info.block_size, cmp ? '+' : '?'); next_block_id = block_id; cmp = nx_current; } // don't bother updating progress } /// end of for } else if (opt.ddd) { char *buffer; int block_size = fs_info.block_size; unsigned long long blocks_total = fs_info.totalblock; int blocks_in_buffer = block_size < opt.buffer_size ? opt.buffer_size / block_size : 1; buffer = (char*)malloc(blocks_in_buffer * block_size); if (buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } block_id = 0; log_mesg(0, 0, 0, debug, "Total block %llu\n", blocks_total); /// start clone partition to partition log_mesg(1, 0, 0, debug, "start backup data device-to-device...\n"); do { /// scan bitmap unsigned long long blocks_read; /// read chunk from source for (blocks_read = 0; block_id + blocks_read < blocks_total && blocks_read < blocks_in_buffer && pc_test_bit(block_id + blocks_read, bitmap); blocks_read++); if (!blocks_read) break; r_size = read_all(&dfr, buffer, blocks_read * block_size, &opt); if (r_size != (int)(blocks_read * block_size)) { if ((r_size == -1) && (errno == EIO)) { if (opt.rescue) { memset(buffer, 0, blocks_read * block_size); for (r_size = 0; r_size < blocks_read * block_size; r_size += PART_SECTOR_SIZE) rescue_sector(&dfr, r_size, buffer + r_size, &opt); } else log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg); } else if (r_size == 0){ // done for ddd /// write buffer to target w_size = write_all(&dfw, buffer, rescue_write_size, &opt); break; } else log_mesg(0, 1, 1, debug, "source read ERROR %s\n", strerror(errno)); } /// write buffer to target w_size = write_all(&dfw, buffer, blocks_read * block_size, &opt); if (w_size != (int)(blocks_read * block_size)) { if (opt.skip_write_error) log_mesg(0, 0, 1, debug, "skip write block %lli error:%s\n", block_id, strerror(errno)); else log_mesg(0, 1, 1, debug, "write block %lli ERROR:%s\n", block_id, strerror(errno)); } /// count copied block copied += blocks_read; /// next block block_id += blocks_read; /// read or write error if (r_size != w_size) { if (opt.skip_write_error) log_mesg(0, 0, 1, debug, "read and write different\n"); else log_mesg(0, 1, 1, debug, "read and write different\n"); } } while (1); free(buffer); /// restore_raw_file option if (opt.restore_raw_file && !pc_test_bit(blocks_total - 1, bitmap)) { if (ftruncate(dfw, (off_t)(blocks_total * block_size)) == -1) log_mesg(0, 0, 1, debug, "ftruncate ERROR:%s\n", strerror(errno)); } } done = 1; pres = pthread_join(prog_thread, &p_result); if(pres) log_mesg(0, 1, 1, debug, "%s, %i, thread join error\n", __func__, __LINE__); update_pui(&prog, copied, block_id, done); #ifndef CHKIMG sync_data(dfw, &opt); #endif print_finish_info(opt); /// close source close(dfr); /// close target if (dfw != -1) close(dfw); /// free bitmp free(bitmap); close_pui(pui); #ifndef CHKIMG fprintf(stderr, "Cloned successfully.\n"); #else printf("Checked successfully.\n"); #endif if (opt.debug) close_log(); #ifdef MEMTRACE muntrace(); #endif return 0; /// finish }