示例#1
0
文件: diskscan.c 项目: jdn06/diskscan
static bool disk_scan_latency_stride(disk_t *disk, struct scan_state *state, uint64_t base_offset, uint64_t data_size, uint32_t *scan_order)
{
	unsigned i;
	uint64_t stride_end = base_offset + state->latency_stride * disk->sector_size;
	if (stride_end > disk->num_bytes)
		stride_end = disk->num_bytes;

	for (i = 0; disk->run && scan_order[i] != UINT32_MAX; i++) {
		uint64_t offset = base_offset + scan_order[i];

		progress_calc(disk, state, data_size);

		VVVERBOSE("Scanning at offset %"PRIu64" index %u", offset, i);
		int64_t remainder = stride_end - offset;
		if (remainder < (int64_t)data_size) {
			data_size = remainder;
			VERBOSE("Last part scanning size %"PRIu64, data_size);
		}
		if (offset > disk->num_bytes || (offset+remainder) > disk->num_bytes)
			continue;
		if (!disk_scan_part(disk, offset, state->data, data_size, state))
			return false;
	}

	return true;
}
示例#2
0
文件: cli.c 项目: Mc128k/diskscan
static void print_header(void)
{
	printf("diskscan version %s\n\n", VERSION);
	VERBOSE("Verbosity set");
	VVERBOSE("High verbosity set");
	VVVERBOSE("Very high verbosity set");
}
示例#3
0
文件: diskscan.c 项目: jdn06/diskscan
int disk_scan(disk_t *disk, enum scan_mode mode, unsigned data_size)
{
	disk->run = 1;
	void *data = allocate_buffer(data_size);
	uint32_t *scan_order = NULL;
	int result = 0;
	struct scan_state state = {.latency = NULL, .progress_bytes = 0, .progress_full = 1000};
	struct timespec ts_start;
	struct timespec ts_end;
	time_t scan_time;

	disk->conclusion = CONCLUSION_SCAN_PROBLEM;

	if (data_size % disk->sector_size != 0) {
		data_size -= data_size % disk->sector_size;
		if (data_size == 0)
			data_size = disk->sector_size;
		ERROR("Cannot scan data not in multiples of the sector size, adjusted scan size to %u", data_size);
	}

	set_realtime(true);
	clock_gettime(CLOCK_MONOTONIC, &ts_start);

	INFO("Scanning disk %s in %u byte steps", disk->path, data_size);
	scan_time = time(NULL);
	INFO("Scan started at: %s", ctime(&scan_time));
	VVVERBOSE("Using buffer of size %d", data_size);

	if (data == NULL) {
		ERROR("Failed to allocate data buffer, errno=%d: %s", errno, strerror(errno));
		result = 1;
		goto Exit;
	}

	uint64_t offset;
	const uint64_t disk_size_bytes = disk->num_bytes;
	const uint64_t latency_stride = calc_latency_stride(disk);
	VVERBOSE("latency stride is %"PRIu64, latency_stride);

	state.latency_bucket = 0;
	state.latency_stride = latency_stride;
	state.latency_count = 0;
	state.latency = malloc(sizeof(uint32_t) * latency_stride);
	state.data = data;

	scan_order = calc_scan_order(disk, mode, latency_stride, data_size);
	if (!scan_order) {
		result = 1;
		ERROR("Failed to generate scan order");
		goto Exit;
	}

	verbose_extra_newline = 1;
	for (offset = 0; disk->run && offset < disk_size_bytes; offset += latency_stride * disk->sector_size) {
		VERBOSE("Scanning stride starting at %"PRIu64" done %"PRIu64"%%", offset, offset*100/disk_size_bytes);
		progress_calc(disk, &state, 0);
		latency_bucket_prepare(disk, &state, offset);
		if (!disk_scan_latency_stride(disk, &state, offset, data_size, scan_order))
			break;
		latency_bucket_finish(disk, &state, offset + latency_stride * disk->sector_size);

		if (disk->is_ata)
			disk_ata_monitor(disk);
		else
			disk_scsi_monitor(disk);
	}
	verbose_extra_newline = 0;

	if (!disk->run) {
		INFO("Disk scan interrupted");
		disk->conclusion = CONCLUSION_ABORTED;
	} else {
		disk->conclusion = conclusion_calc(disk);
	}
	report_scan_done(disk);

Exit:
	clock_gettime(CLOCK_MONOTONIC, &ts_end);
	set_realtime(false);
	free(scan_order);
	free_buffer(data, data_size);
	free(state.latency);
	disk->run = 0;
	scan_time = time(NULL);
	INFO("Scan ended at: %s", ctime(&scan_time));
	INFO("Scan took %d second", (int)(ts_end.tv_sec - ts_start.tv_sec));
	return result;
}