예제 #1
0
파일: gc.c 프로젝트: MichaelBlume/git
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;
}
예제 #2
0
파일: main.c 프로젝트: jvirkki/dupd
/** ***************************************************************************
 * 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;
}