static int need_to_gc(void) { /* * Setting gc.auto to 0 or negative can disable the * automatic gc. */ if (gc_auto_threshold <= 0) return 0; /* * If there are too many loose objects, but not too many * packs, we run "repack -d -l". If there are too many packs, * we run "repack -A -d -l". Otherwise we tell the caller * there is no need. */ if (too_many_packs()) { struct string_list keep_pack = STRING_LIST_INIT_NODUP; if (big_pack_threshold) { find_base_packs(&keep_pack, big_pack_threshold); if (keep_pack.nr >= gc_auto_pack_limit) { big_pack_threshold = 0; string_list_clear(&keep_pack, 0); find_base_packs(&keep_pack, 0); } } else { struct packed_git *p = find_base_packs(&keep_pack, 0); uint64_t mem_have, mem_want; mem_have = total_ram(); mem_want = estimate_repack_memory(p); /* * Only allow 1/2 of memory for pack-objects, leave * the rest for the OS and other processes in the * system. */ if (!mem_have || mem_want < mem_have / 2) string_list_clear(&keep_pack, 0); } add_repack_all_option(&keep_pack); string_list_clear(&keep_pack, 0); } else if (too_many_loose_objects()) add_repack_incremental_option(); else return 0; if (run_hook_le(NULL, "pre-auto-gc", NULL)) return 0; return 1; }
/** *************************************************************************** * Process command line arguments and set corresponding globals. * Shows usage and exits if errors are detected in argument usage. * */ static int process_args(int argc, char * argv[]) { char * options[COUNT_OPTIONS]; uint64_t user_ram_limit = 0; #ifdef USE_FIEMAP using_fiemap = 1; #endif int rv = optgen_parse(argc, argv, &operation, options); if (options[OPT_help]) { show_help(); return 1; } if (rv == OPTGEN_NONE) { show_banner(); printf("\n"); printf("Run 'dupd help' for a summary of available options.\n"); printf("Run 'dupd usage' for more documentation.\n"); return 1; } if (rv != OPTGEN_OK) { // LCOV_EXCL_START printf("error parsing command line arguments\n"); return 2; } // LCOV_EXCL_STOP if (options[OPT_x_small_buffers]) { x_small_buffers = 1; } if (options[OPT_x_testing]) { only_testing = 1; } if (options[OPT_quiet]) { log_level = -99; } log_level = opt_int(options[OPT_verbose_level], log_level); log_level += opt_count(options[OPT_verbose]); if (log_level > L_MAX_LOG_LEVEL) { log_level = L_MAX_LOG_LEVEL; } if (options[OPT_log_only]) { log_only = 1; } if (start_path_state == START_PATH_NULL) { start_path[0] = (char *)malloc(DUPD_PATH_MAX); getcwd(start_path[0], DUPD_PATH_MAX); start_path_count = 1; LOG(L_INFO, "Defaulting --path to [%s]\n", start_path[0]); } if (options[OPT_file] != NULL) { file_path = options[OPT_file]; // file path can be relative, normalize in that case if (file_path[0] != '/') { file_path = (char *)malloc(DUPD_PATH_MAX); free_file_path = 1; getcwd(file_path, DUPD_PATH_MAX); strcat(file_path, "/"); strcat(file_path, options[OPT_file]); } } db_path = options[OPT_db]; if (db_path == NULL) { db_path = (char *)malloc(DUPD_PATH_MAX); free_db_path = 1; snprintf(db_path, DUPD_PATH_MAX, "%s/.dupd_sqlite", getenv("HOME")); } cache_db_path = options[OPT_cache]; if (cache_db_path == NULL) { cache_db_path = (char *)malloc(DUPD_PATH_MAX); free_cache_db_path = 1; snprintf(cache_db_path, DUPD_PATH_MAX, "%s/.dupd_cache", getenv("HOME")); } if (options[OPT_link]) { rmsh_link = RMSH_LINK_SOFT; } if (options[OPT_hardlink]) { rmsh_link = RMSH_LINK_HARD; } if (options[OPT_hidden]) { scan_hidden = 1; } if (options[OPT_no_thread_scan]) { threaded_sizetree = 0; } if (options[OPT_hardlink_is_unique]) { hardlink_is_unique = 1; } if (options[OPT_one_file_system]) { one_file_system = 1; } if (options[OPT_x_no_cache]) { use_hash_cache = 0; } cache_min_size = (uint64_t)opt_int(options[OPT_x_cache_min_size], cache_min_size); hash_one_block_size = opt_int(options[OPT_firstblocksize], hash_one_block_size); hash_block_size = opt_int(options[OPT_blocksize], hash_block_size); filecmp_block_size = opt_int(options[OPT_fileblocksize], filecmp_block_size); hash_one_max_blocks = opt_int(options[OPT_firstblocks], hash_one_max_blocks); cut_path = options[OPT_cut]; exclude_path = options[OPT_exclude_path]; if (exclude_path != NULL && exclude_path[0] != '/') { printf("error: --exclude-path must be absolute\n"); return 2; } stats_file = options[OPT_stats_file]; minimum_file_size = opt_int(options[OPT_minsize], minimum_file_size); if (minimum_file_size < 1) { minimum_file_size = 1; } path_sep_string = (char *)malloc(2); path_sep_string[0] = (char)path_separator; path_sep_string[1] = 0; char * hash_name = opt_string(options[OPT_hash], "xxhash"); if (!strcmp("md5", hash_name)) { hash_function = HASH_FN_MD5; } else if (!strcmp("sha1", hash_name)) { hash_function = HASH_FN_SHA1; } else if (!strcmp("sha512", hash_name)) { hash_function = HASH_FN_SHA512; } else if (!strcmp("xxhash", hash_name)) { hash_function = HASH_FN_XXHASH; } else { printf("error: unknown hash %s\n", hash_name); return 2; } hash_bufsize = hash_get_bufsize(hash_function); char * report_format_name = opt_string(options[OPT_format], "text"); if (!strcmp("text", report_format_name)) { report_format = REPORT_FORMAT_TEXT; } else if (!strcmp("csv", report_format_name)) { report_format = REPORT_FORMAT_CSV; } else if (!strcmp("json", report_format_name)) { report_format = REPORT_FORMAT_JSON; } else { printf("error: unknown report format %s\n", report_format_name); return 2; } char * buflimstr = opt_string(options[OPT_buflimit], "0"); if (strcmp("0", buflimstr)) { int len = strlen(buflimstr); if (buflimstr[len-1] == 'M') { user_ram_limit = MB1; buflimstr[len-1] = 0; } else if (buflimstr[len-1] == 'G') { user_ram_limit = GB1; buflimstr[len-1] = 0; } else { user_ram_limit = 1; } long c = atol(buflimstr); user_ram_limit *= c; if (user_ram_limit < MB8) { user_ram_limit = MB8; } } if (options[OPT_cmp_two]) { opt_compare_two = 1; } if (hash_one_block_size == 0) { hash_one_block_size = DEF_HDD_hash_one_block_size; } round1_max_bytes = hash_one_block_size * hash_one_max_blocks; // If user hasn't provided a cache_min_size, do something reasonable if (cache_min_size == 0) { if (round1_max_bytes < K512) { cache_min_size = K512; } else { cache_min_size = round1_max_bytes; } } char * sortby = opt_string(options[OPT_sort_by], "def"); if (!strcmp("inode", sortby)) { sort_bypass = SORT_BY_INODE; } else if (!strcmp("block", sortby)) { sort_bypass = SORT_BY_BLOCK; } else if (!strcmp("none", sortby)) { sort_bypass = SORT_BY_NONE; } if (sort_bypass != 0) { LOG(L_INFO, "Sort bypass set to %s\n", sortby); if (hardlink_is_unique) { printf("Don't do that..\n"); return 2; } } if (sort_bypass != 0 && sort_bypass != SORT_BY_BLOCK) { using_fiemap = 0; } if (options[OPT_x_nofie]) { using_fiemap = 0; } LOG(L_INFO, "Will be using_fiemap (if available): %d\n", using_fiemap); uint64_t ram = total_ram(); if (user_ram_limit > 0) { if (user_ram_limit > ram) { buffer_limit = 0.9 * ram; } else { buffer_limit = user_ram_limit; } } if (buffer_limit == 0) { buffer_limit = 0.5 * ram; if (x_small_buffers) { buffer_limit = MB1; } } int ramm = ram / (1024 * 1024); int blim = buffer_limit / (1024 * 1024); LOG(L_INFO, "Reported RAM: %dMB buffer limit: %dMB\n", ramm, blim); return 0; }