コード例 #1
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
docloseopen(void)
{
	char *name;
	int ret;

	if (testcalls <= simulatedopcount)
		return;

	name = strdup(ctx.name);

	if (debug)
		prt("%lu close/open\n", testcalls);

	ret = ops->close(&ctx);
	if (ret < 0) {
		prterrcode("docloseopen: ops->close", ret);
		report_failure(180);
	}

	ret = ops->open(name, &ctx);
	if (ret < 0) {
		prterrcode("docloseopen: ops->open", ret);
		report_failure(181);
	}

	free(name);
}
コード例 #2
0
ファイル: fsx.c プロジェクト: BillTheBest/ceph
void
dowrite(unsigned offset, unsigned size)
{
	ssize_t ret;
	off_t newsize;

	offset -= offset % writebdy;
	if (o_direct)
		size -= size % writebdy;
	if (size == 0) {
		if (!quiet && testcalls > simulatedopcount && !o_direct)
			prt("skipping zero size write\n");
		log4(OP_SKIPPED, OP_WRITE, offset, size);
		return;
	}

	log4(OP_WRITE, offset, size, file_size);

	gendata(original_buf, good_buf, offset, size);
	if (file_size < offset + size) {
		newsize = ceil(((double)offset + size) / truncbdy) * truncbdy;
		if (file_size < newsize)
			memset(good_buf + file_size, '\0', newsize - file_size);
		file_size = newsize;
		if (lite) {
			warn("Lite file size bug in fsx!");
			report_failure(149);
		}
		ret = rbd_resize(image, newsize);
		if (ret < 0) {
			prterrcode("dowrite: resize", ret);
			report_failure(150);
		}
	}

	if (testcalls <= simulatedopcount)
		return;

	if (!quiet &&
		((progressinterval && testcalls % progressinterval == 0) ||
		       (debug &&
		       (monitorstart == -1 ||
			(offset + size > monitorstart &&
			(monitorend == -1 || offset <= monitorend))))))
		prt("%lu write\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
		    offset, offset + size - 1, size);

	ret = rbd_write(image, offset, size, good_buf + offset);
	if (ret != size) {
		if (ret < 0)
			prterrcode("dowrite: rbd_write", ret);
		else
			prt("short write: 0x%x bytes instead of 0x%x\n",
			    ret, size);
		report_failure(151);
	}
	if (flush) {
		doflush(offset, size);
	}
}
コード例 #3
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
check_trunc_hack(void)
{
	uint64_t size;
	int ret;

	ret = ops->resize(&ctx, 0ULL);
	if (ret < 0)
		prterrcode("check_trunc_hack: ops->resize pre", ret);

	ret = ops->resize(&ctx, TRUNC_HACK_SIZE);
	if (ret < 0)
		prterrcode("check_trunc_hack: ops->resize actual", ret);

	ret = ops->get_size(&ctx, &size);
	if (ret < 0)
		prterrcode("check_trunc_hack: ops->get_size", ret);

	if (size != TRUNC_HACK_SIZE) {
		prt("no extend on truncate! not posix!\n");
		exit(130);
	}

	ret = ops->resize(&ctx, 0ULL);
	if (ret < 0)
		prterrcode("check_trunc_hack: ops->resize post", ret);
}
コード例 #4
0
ファイル: fsx.c プロジェクト: BillTheBest/ceph
void
dotruncate(unsigned size)
{
	int oldsize = file_size;
	int ret;

	size -= size % truncbdy;
	if (size > biggest) {
		biggest = size;
		if (!quiet && testcalls > simulatedopcount)
			prt("truncating to largest ever: 0x%x\n", size);
	}

	log4(OP_TRUNCATE, size, (unsigned)file_size, 0);

	if (size > file_size)
		memset(good_buf + file_size, '\0', size - file_size);
	else if (size < file_size)
		memset(good_buf + size, '\0', file_size - size);
	file_size = size;

	if (testcalls <= simulatedopcount)
		return;
	
	if ((progressinterval && testcalls % progressinterval == 0) ||
	    (debug && (monitorstart == -1 || monitorend == -1 ||
		      size <= monitorend)))
		prt("%lu trunc\tfrom 0x%x to 0x%x\n", testcalls, oldsize, size);
	if ((ret = rbd_resize(image, size)) < 0) {
		prt("rbd_resize: %x\n", size);
		prterrcode("dotruncate: ftruncate", ret);
		report_failure(160);
	}
}
コード例 #5
0
ファイル: fsx.c プロジェクト: BillTheBest/ceph
void
docloseopen(void)
{
	int ret;

	if (testcalls <= simulatedopcount)
		return;

	if (debug)
		prt("%lu close/open\n", testcalls);
	if ((ret = rbd_close(image)) < 0) {
		prterrcode("docloseopen: close", ret);
		report_failure(180);
	}
	ret = rbd_open(ioctx, iname, &image, NULL);
	if (ret < 0) {
		prterrcode("docloseopen: open", ret);
		report_failure(181);
	}
}
コード例 #6
0
ファイル: fsx.c プロジェクト: BillTheBest/ceph
void
writefileimage()
{
	ssize_t ret;

	ret = rbd_write(image, 0, file_size, good_buf);
	if (ret != file_size) {
		if (ret < 0)
			prterrcode("writefileimage: write", ret);
		else
			prt("short write: 0x%x bytes instead of 0x%llx\n",
			    ret, (unsigned long long)file_size);
		report_failure(172);
	}
	if (lite ? 0 : (ret = rbd_resize(image, file_size)) < 0) {
		prt("rbd_resize: %llx\n", (unsigned long long)file_size);
		prterrcode("writefileimage: rbd_resize", ret);
		report_failure(173);
	}
}
コード例 #7
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
static bool rbd_image_has_parent(struct rbd_ctx *ctx)
{
	int ret;

	ret = rbd_get_parent_info(ctx->image, NULL, 0, NULL, 0, NULL, 0);
	if (ret < 0 && ret != -ENOENT) {
		prterrcode("rbd_get_parent_info", ret);
		exit(1);
	}

	return !ret;
}
コード例 #8
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
doflush(unsigned offset, unsigned size)
{
	int ret;

	if (o_direct)
		return;

	ret = ops->flush(&ctx);
	if (ret < 0)
		prterrcode("doflush: ops->flush", ret);
}
コード例 #9
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
writefileimage()
{
	ssize_t ret;

	ret = ops->write(&ctx, 0, file_size, good_buf);
	if (ret != file_size) {
		if (ret < 0)
			prterrcode("writefileimage: ops->write", ret);
		else
			prt("short write: 0x%x bytes instead of 0x%llx\n",
			    ret, (unsigned long long)file_size);
		report_failure(172);
	}

	if (!lite) {
		ret = ops->resize(&ctx, file_size);
		if (ret < 0) {
			prterrcode("writefileimage: ops->resize", ret);
			report_failure(173);
		}
	}
}
コード例 #10
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
do_punch_hole(unsigned offset, unsigned length)
{
	unsigned end_offset;
	int max_offset = 0;
	int max_len = 0;
	int ret;

	offset -= offset % holebdy;
	length -= length % holebdy;
	if (length == 0) {
		if (!quiet && testcalls > simulatedopcount)
			prt("skipping zero length punch hole\n");
		log4(OP_SKIPPED, OP_PUNCH_HOLE, offset, length);
		return;
	}

	if (file_size <= (loff_t)offset) {
		if (!quiet && testcalls > simulatedopcount)
			prt("skipping hole punch off the end of the file\n");
		log4(OP_SKIPPED, OP_PUNCH_HOLE, offset, length);
		return;
	}

	end_offset = offset + length;

	log4(OP_PUNCH_HOLE, offset, length, 0);

	if (testcalls <= simulatedopcount)
		return;

	if ((progressinterval && testcalls % progressinterval == 0) ||
	    (debug && (monitorstart == -1 || monitorend == -1 ||
		      end_offset <= monitorend))) {
		prt("%lu punch\tfrom 0x%x to 0x%x, (0x%x bytes)\n", testcalls,
			offset, offset+length, length);
	}

	ret = ops->discard(&ctx, (unsigned long long)offset,
			   (unsigned long long)length);
	if (ret < 0) {
		prterrcode("do_punch_hole: ops->discard", ret);
		report_failure(161);
	}

	max_offset = offset < file_size ? offset : file_size;
	max_len = max_offset + length <= file_size ? length :
			file_size - max_offset;
	memset(good_buf + max_offset, '\0', max_len);
}
コード例 #11
0
ファイル: fsx.c プロジェクト: BillTheBest/ceph
void
check_size(void)
{
	rbd_image_info_t statbuf;
	int ret;

	if ((ret = rbd_stat(image, &statbuf, sizeof(statbuf))) < 0) {
		prterrcode("check_size: fstat", ret);
	}
	if ((uint64_t)file_size != statbuf.size) {
		prt("Size error: expected 0x%llx stat 0x%llx\n",
		    (unsigned long long)file_size,
		    (unsigned long long)statbuf.size);
		report_failure(120);
	}
}
コード例 #12
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
doread(unsigned offset, unsigned size)
{
	int ret;

	offset -= offset % readbdy;
	if (o_direct)
		size -= size % readbdy;
	if (size == 0) {
		if (!quiet && testcalls > simulatedopcount && !o_direct)
			prt("skipping zero size read\n");
		log4(OP_SKIPPED, OP_READ, offset, size);
		return;
	}
	if (size + offset > file_size) {
		if (!quiet && testcalls > simulatedopcount)
			prt("skipping seek/read past end of file\n");
		log4(OP_SKIPPED, OP_READ, offset, size);
		return;
	}

	log4(OP_READ, offset, size, 0);

	if (testcalls <= simulatedopcount)
		return;

	if (!quiet &&
		((progressinterval && testcalls % progressinterval == 0)  ||
		(debug &&
		       (monitorstart == -1 ||
			(offset + size > monitorstart &&
			(monitorend == -1 || offset <= monitorend))))))
		prt("%lu read\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
		    offset, offset + size - 1, size);

	ret = ops->read(&ctx, offset, size, temp_buf);
	if (ret != (int)size) {
		if (ret < 0)
			prterrcode("doread: ops->read", ret);
		else
			prt("short read: 0x%x bytes instead of 0x%x\n",
			    ret, size);
		report_failure(141);
	}

	check_buffers(good_buf, temp_buf, offset, size);
}
コード例 #13
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
check_size(void)
{
	uint64_t size;
	int ret;

	ret = ops->get_size(&ctx, &size);
	if (ret < 0)
		prterrcode("check_size: ops->get_size", ret);

	if ((uint64_t)file_size != size) {
		prt("Size error: expected 0x%llx stat 0x%llx\n",
		    (unsigned long long)file_size,
		    (unsigned long long)size);
		report_failure(120);
	}
}
コード例 #14
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
do_flatten()
{
	int ret;

	if (!rbd_image_has_parent(&ctx)) {
		log4(OP_SKIPPED, OP_FLATTEN, 0, 0);
		return;
	}
	log4(OP_FLATTEN, 0, 0, 0);
	prt("%lu flatten\n", testcalls);

	ret = ops->flatten(&ctx);
	if (ret < 0) {
		prterrcode("writefileimage: ops->flatten", ret);
		exit(177);
	}
}
コード例 #15
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
check_clone(int clonenum)
{
	char filename[128];
	char imagename[128];
	int ret, fd;
	struct rbd_ctx cur_ctx = RBD_CTX_INIT;
	struct stat file_info;
	char *good_buf, *temp_buf;

	clone_imagename(imagename, sizeof(imagename), clonenum);
	if ((ret = ops->open(imagename, &cur_ctx)) < 0) {
		prterrcode("check_clone: ops->open", ret);
		exit(167);
	}

	clone_filename(filename, sizeof(filename), clonenum + 1);
	if ((fd = open(filename, O_RDONLY)) < 0) {
		simple_err("check_clone: open", -errno);
		exit(168);
	}

	prt("checking clone #%d, image %s against file %s\n",
	    clonenum, imagename, filename);
	if ((ret = fstat(fd, &file_info)) < 0) {
		simple_err("check_clone: fstat", -errno);
		exit(169);
	}

	good_buf = NULL;
	ret = posix_memalign((void **)&good_buf,
			     MAX(writebdy, (int)sizeof(void *)),
			     file_info.st_size);
	if (ret > 0) {
		prterrcode("check_clone: posix_memalign(good_buf)", -ret);
		exit(96);
	}

	temp_buf = NULL;
	ret = posix_memalign((void **)&temp_buf,
			     MAX(readbdy, (int)sizeof(void *)),
			     file_info.st_size);
	if (ret > 0) {
		prterrcode("check_clone: posix_memalign(temp_buf)", -ret);
		exit(97);
	}

	if ((ret = pread(fd, good_buf, file_info.st_size, 0)) < 0) {
		simple_err("check_clone: pread", -errno);
		exit(170);
	}
	if ((ret = ops->read(&cur_ctx, 0, file_info.st_size, temp_buf)) < 0) {
		prterrcode("check_clone: ops->read", ret);
		exit(171);
	}
	close(fd);
	if ((ret = ops->close(&cur_ctx)) < 0) {
		prterrcode("check_clone: ops->close", ret);
		exit(174);
	}
	check_buffers(good_buf, temp_buf, 0, file_info.st_size);

	unlink(filename);

	free(good_buf);
	free(temp_buf);
}
コード例 #16
0
ファイル: fsx.c プロジェクト: CzBiX/ceph
void
do_clone()
{
	char filename[1024];
	char imagename[1024];
	char lastimagename[1024];
	int ret, fd;
	int order = 0, stripe_unit = 0, stripe_count = 0;
	uint64_t newsize = file_size;

	log4(OP_CLONE, 0, 0, 0);
	++num_clones;

	if (randomize_striping) {
		order = 18 + get_random() % 8;
		stripe_unit = 1ull << (order - 1 - (get_random() % 8));
		stripe_count = 2 + get_random() % 14;
	}

	prt("%lu clone\t%d order %d su %d sc %d\n", testcalls, num_clones,
	    order, stripe_unit, stripe_count);

	clone_imagename(imagename, sizeof(imagename), num_clones);
	clone_imagename(lastimagename, sizeof(lastimagename),
			num_clones - 1);
	assert(strcmp(lastimagename, ctx.name) == 0);

	ret = ops->clone(&ctx, "snap", imagename, &order, stripe_unit,
			 stripe_count);
	if (ret < 0) {
		prterrcode("do_clone: ops->clone", ret);
		exit(165);
	}

	if (randomize_parent_overlap && rbd_image_has_parent(&ctx)) {
		int rand = get_random() % 16 + 1; // [1..16]

		if (rand < 13) {
			uint64_t overlap;

			ret = rbd_get_overlap(ctx.image, &overlap);
			if (ret < 0) {
				prterrcode("do_clone: rbd_get_overlap", ret);
				exit(1);
			}

			if (rand < 10) {	// 9/16
				newsize = overlap * ((double)rand / 10);
				newsize -= newsize % truncbdy;
			} else {		// 3/16
				newsize = 0;
			}

			assert(newsize != (uint64_t)file_size);
			prt("truncating image %s from 0x%llx (overlap 0x%llx) to 0x%llx\n",
			    ctx.name, file_size, overlap, newsize);

			ret = ops->resize(&ctx, newsize);
			if (ret < 0) {
				prterrcode("do_clone: ops->resize", ret);
				exit(1);
			}
		} else if (rand < 15) {		// 2/16
			prt("flattening image %s\n", ctx.name);

			ret = ops->flatten(&ctx);
			if (ret < 0) {
				prterrcode("do_clone: ops->flatten", ret);
				exit(1);
			}
		} else {			// 2/16
			prt("leaving image %s intact\n", ctx.name);
		}
	}

	clone_filename(filename, sizeof(filename), num_clones);
	if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) {
		simple_err("do_clone: open", -errno);
		exit(162);
	}
	save_buffer(good_buf, newsize, fd);
	if ((ret = close(fd)) < 0) {
		simple_err("do_clone: close", -errno);
		exit(163);
	}

	/*
	 * Close parent.
	 */
	if ((ret = ops->close(&ctx)) < 0) {
		prterrcode("do_clone: ops->close", ret);
		exit(174);
	}

	/*
	 * Open freshly made clone.
	 */
	if ((ret = ops->open(imagename, &ctx)) < 0) {
		prterrcode("do_clone: ops->open", ret);
		exit(166);
	}

	if (num_clones > 1)
		check_clone(num_clones - 2);
}